diff options
| author | Sam Wilkins <samwilkins333@gmail.com> | 2019-12-03 01:46:36 -0500 |
|---|---|---|
| committer | Sam Wilkins <samwilkins333@gmail.com> | 2019-12-03 01:46:36 -0500 |
| commit | ef94ad7df2a087141ddb8d347d3e3c484ff7609b (patch) | |
| tree | a7c16be04ff4050da1ff03e02f59df6da4f5f7e2 /src/client/util | |
| parent | 62c888ad25c5580441eaf947a1a0f1638939b868 (diff) | |
const linter rule and restored google docs push, fixed routing
Diffstat (limited to 'src/client/util')
| -rw-r--r-- | src/client/util/DictationManager.ts | 75 | ||||
| -rw-r--r-- | src/client/util/DocumentManager.ts | 28 | ||||
| -rw-r--r-- | src/client/util/DragManager.ts | 91 | ||||
| -rw-r--r-- | src/client/util/DropConverter.ts | 10 | ||||
| -rw-r--r-- | src/client/util/History.ts | 6 | ||||
| -rw-r--r-- | src/client/util/Import & Export/DirectoryImportBox.tsx | 58 | ||||
| -rw-r--r-- | src/client/util/Import & Export/ImportMetadataEntry.tsx | 6 | ||||
| -rw-r--r-- | src/client/util/InteractionUtils.ts | 18 | ||||
| -rw-r--r-- | src/client/util/LinkManager.ts | 62 | ||||
| -rw-r--r-- | src/client/util/ProsemirrorExampleTransfer.ts | 50 | ||||
| -rw-r--r-- | src/client/util/RichTextRules.ts | 78 | ||||
| -rw-r--r-- | src/client/util/RichTextSchema.tsx | 86 | ||||
| -rw-r--r-- | src/client/util/Scripting.ts | 38 | ||||
| -rw-r--r-- | src/client/util/SearchUtil.ts | 24 | ||||
| -rw-r--r-- | src/client/util/SerializationHelper.ts | 9 | ||||
| -rw-r--r-- | src/client/util/SharingManager.tsx | 13 | ||||
| -rw-r--r-- | src/client/util/TooltipLinkingMenu.tsx | 22 | ||||
| -rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 332 | ||||
| -rw-r--r-- | src/client/util/TypedEvent.ts | 62 | ||||
| -rw-r--r-- | src/client/util/UndoManager.ts | 16 |
20 files changed, 538 insertions, 546 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 6bbd3d0ed..3d8f2d234 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -11,7 +11,6 @@ import { Cast, CastCtor } from "../../new_fields/Types"; import { listSpec } from "../../new_fields/Schema"; import { AudioField, ImageField } from "../../new_fields/URLField"; import { HistogramField } from "../northstar/dash-fields/HistogramField"; -import { MainView } from "../views/MainView"; import { Utils } from "../../Utils"; import { RichTextField } from "../../new_fields/RichTextField"; import { DictationOverlay } from "../views/DictationOverlay"; @@ -48,7 +47,7 @@ export namespace DictationManager { export const Infringed = "unable to process: dictation manager still involved in previous session"; const browser = (() => { - let identifier = navigator.userAgent.toLowerCase(); + const identifier = navigator.userAgent.toLowerCase(); if (identifier.indexOf("safari") >= 0) { return "Safari"; } @@ -90,7 +89,7 @@ export namespace DictationManager { export const listen = async (options?: Partial<ListeningOptions>) => { let results: string | undefined; - let overlay = options !== undefined && options.useOverlay; + const overlay = options !== undefined && options.useOverlay; if (overlay) { DictationOverlay.Instance.dictationOverlayVisible = true; DictationOverlay.Instance.isListening = { interim: false }; @@ -102,7 +101,7 @@ export namespace DictationManager { Utils.CopyText(results); if (overlay) { DictationOverlay.Instance.isListening = false; - let execute = options && options.tryExecute; + const execute = options && options.tryExecute; DictationOverlay.Instance.dictatedPhrase = execute ? results.toLowerCase() : results; DictationOverlay.Instance.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true; } @@ -131,12 +130,12 @@ export namespace DictationManager { } isListening = true; - let handler = options ? options.interimHandler : undefined; - let continuous = options ? options.continuous : undefined; - let indefinite = continuous && continuous.indefinite; - let language = options ? options.language : undefined; - let intra = options && options.delimiters ? options.delimiters.intra : undefined; - let inter = options && options.delimiters ? options.delimiters.inter : undefined; + const handler = options ? options.interimHandler : undefined; + const continuous = options ? options.continuous : undefined; + const indefinite = continuous && continuous.indefinite; + const language = options ? options.language : undefined; + const intra = options && options.delimiters ? options.delimiters.intra : undefined; + const inter = options && options.delimiters ? options.delimiters.inter : undefined; recognizer.onstart = () => console.log("initiating speech recognition session..."); recognizer.interimResults = handler !== undefined; @@ -177,7 +176,7 @@ export namespace DictationManager { recognizer.start(); }; - let complete = () => { + const complete = () => { if (indefinite) { current && sessionResults.push(current); sessionResults.length && resolve(sessionResults.join(inter || interSession)); @@ -213,8 +212,8 @@ export namespace DictationManager { }; const synthesize = (e: SpeechRecognitionEvent, delimiter?: string) => { - let results = e.results; - let transcripts: string[] = []; + const results = e.results; + const transcripts: string[] = []; for (let i = 0; i < results.length; i++) { transcripts.push(results.item(i).item(0).transcript.trim()); } @@ -238,18 +237,18 @@ export namespace DictationManager { export const execute = async (phrase: string) => { return UndoManager.RunInBatch(async () => { - let targets = SelectionManager.SelectedDocuments(); + const targets = SelectionManager.SelectedDocuments(); if (!targets || !targets.length) { return; } phrase = phrase.toLowerCase(); - let entry = Independent.get(phrase); + const entry = Independent.get(phrase); if (entry) { let success = false; - let restrictTo = entry.restrictTo; - for (let target of targets) { + const restrictTo = entry.restrictTo; + for (const target of targets) { if (!restrictTo || validate(target, restrictTo)) { await entry.action(target); success = true; @@ -258,14 +257,14 @@ export namespace DictationManager { return success; } - for (let entry of Dependent) { - let regex = entry.expression; - let matches = regex.exec(phrase); + for (const entry of Dependent) { + const regex = entry.expression; + const matches = regex.exec(phrase); regex.lastIndex = 0; if (matches !== null) { let success = false; - let restrictTo = entry.restrictTo; - for (let target of targets) { + const restrictTo = entry.restrictTo; + for (const target of targets) { if (!restrictTo || validate(target, restrictTo)) { await entry.action(target, matches); success = true; @@ -289,7 +288,7 @@ export namespace DictationManager { ]); const tryCast = (view: DocumentView, type: DocumentType) => { - let ctor = ConstructorMap.get(type); + const ctor = ConstructorMap.get(type); if (!ctor) { return false; } @@ -297,7 +296,7 @@ export namespace DictationManager { }; const validate = (target: DocumentView, types: DocumentType[]) => { - for (let type of types) { + for (const type of types) { if (tryCast(target, type)) { return true; } @@ -306,11 +305,11 @@ export namespace DictationManager { }; const interpretNumber = (number: string) => { - let initial = parseInt(number); + const initial = parseInt(number); if (!isNaN(initial)) { return initial; } - let converted = interpreter.wordsToNumbers(number, { fuzzy: true }); + const converted = interpreter.wordsToNumbers(number, { fuzzy: true }); if (converted === null) { return NaN; } @@ -326,20 +325,20 @@ export namespace DictationManager { ["open fields", { action: (target: DocumentView) => { - let kvp = Docs.Create.KVPDocument(target.props.Document, { width: 300, height: 300 }); + const kvp = Docs.Create.KVPDocument(target.props.Document, { width: 300, height: 300 }); target.props.addDocTab(kvp, target.props.DataDoc, "onRight"); } }], ["new outline", { action: (target: DocumentView) => { - let newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" }); + const newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" }); newBox.autoHeight = true; - let proto = newBox.proto!; - let prompt = "Press alt + r to start dictating here..."; - let head = 3; - let anchor = head + prompt.length; - let proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`; + const proto = newBox.proto!; + const prompt = "Press alt + r to start dictating here..."; + const head = 3; + const anchor = head + prompt.length; + const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`; proto.data = new RichTextField(proseMirrorState); proto.backgroundColor = "#eeffff"; target.props.addDocTab(newBox, proto, "onRight"); @@ -353,10 +352,10 @@ export namespace DictationManager { { expression: /create (\w+) documents of type (image|nested collection)/g, action: (target: DocumentView, matches: RegExpExecArray) => { - let count = interpretNumber(matches[1]); - let what = matches[2]; - let dataDoc = Doc.GetProto(target.props.Document); - let fieldKey = "data"; + const count = interpretNumber(matches[1]); + const what = matches[2]; + const dataDoc = Doc.GetProto(target.props.Document); + const fieldKey = "data"; if (isNaN(count)) { return; } @@ -379,7 +378,7 @@ export namespace DictationManager { { expression: /view as (freeform|stacking|masonry|schema|tree)/g, action: (target: DocumentView, matches: RegExpExecArray) => { - let mode = CollectionViewType.valueOf(matches[1]); + const mode = CollectionViewType.valueOf(matches[1]); mode && (target.props.Document.viewType = mode); }, restrictTo: [DocumentType.COL] diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 346e88f40..d491cd1b1 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -33,7 +33,7 @@ export class DocumentManager { //gets all views public getDocumentViewsById(id: string) { - let toReturn: DocumentView[] = []; + const toReturn: DocumentView[] = []; DocumentManager.Instance.DocumentViews.map(view => { if (view.props.Document[Id] === id) { toReturn.push(view); @@ -41,7 +41,7 @@ export class DocumentManager { }); if (toReturn.length === 0) { DocumentManager.Instance.DocumentViews.map(view => { - let doc = view.props.Document.proto; + const doc = view.props.Document.proto; if (doc && doc[Id] && doc[Id] === id) { toReturn.push(view); } @@ -57,9 +57,9 @@ export class DocumentManager { public getDocumentViewById(id: string, preferredCollection?: CollectionView): DocumentView | undefined { let toReturn: DocumentView | undefined; - let passes = preferredCollection ? [preferredCollection, undefined] : [undefined]; + const passes = preferredCollection ? [preferredCollection, undefined] : [undefined]; - for (let pass of passes) { + for (const pass of passes) { DocumentManager.Instance.DocumentViews.map(view => { if (view.props.Document[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) { toReturn = view; @@ -68,7 +68,7 @@ export class DocumentManager { }); if (!toReturn) { DocumentManager.Instance.DocumentViews.map(view => { - let doc = view.props.Document.proto; + const doc = view.props.Document.proto; if (doc && doc[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) { toReturn = view; } @@ -90,7 +90,7 @@ export class DocumentManager { return views.length ? views[0] : undefined; } public getDocumentViews(toFind: Doc): DocumentView[] { - let toReturn: DocumentView[] = []; + const toReturn: DocumentView[] = []; DocumentManager.Instance.DocumentViews.map(view => Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view)); @@ -100,17 +100,17 @@ export class DocumentManager { @computed public get LinkedDocumentViews() { - let pairs = DocumentManager.Instance.DocumentViews.filter(dv => + const pairs = DocumentManager.Instance.DocumentViews.filter(dv => (dv.isSelected() || Doc.IsBrushed(dv.props.Document)) // draw links from DocumentViews that are selected or brushed OR || DocumentManager.Instance.DocumentViews.some(dv2 => { // Documentviews which - let rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors - let init = (dv2.isSelected() || Doc.IsBrushed(dv2.props.Document)) && dv2.Document.type !== DocumentType.AUDIO; // on a view that is selected or brushed + const rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors + const init = (dv2.isSelected() || Doc.IsBrushed(dv2.props.Document)) && dv2.Document.type !== DocumentType.AUDIO; // on a view that is selected or brushed return init && rest; }) ).reduce((pairs, dv) => { - let linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document); + const linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document); pairs.push(...linksList.reduce((pairs, link) => { - let linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document); + const linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document); linkToDoc && DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => { if (dv.props.Document.type !== DocumentType.LINK || dv.props.layoutKey !== docView1.props.layoutKey) { pairs.push({ a: dv, b: docView1, l: link }); @@ -125,7 +125,7 @@ export class DocumentManager { } public jumpToDocument = async (targetDoc: Doc, willZoom: boolean, dockFunc?: (doc: Doc) => void, docContext?: Doc, linkId?: string, closeContextIfNotFound: boolean = false): Promise<void> => { - let highlight = () => { + const highlight = () => { const finalDocView = DocumentManager.Instance.getFirstDocumentView(targetDoc); finalDocView && (finalDocView.Document.scrollToLinkID = linkId); finalDocView && Doc.linkFollowHighlight(finalDocView.props.Document); @@ -199,12 +199,12 @@ export class DocumentManager { @action zoomIntoScale = (docDelegate: Doc, scale: number) => { - let docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate)); + const docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate)); docView && docView.props.zoomToScale(scale); } getScaleOfDocView = (docDelegate: Doc) => { - let doc = Doc.GetProto(docDelegate); + const doc = Doc.GetProto(docDelegate); const docView = DocumentManager.Instance.getDocumentView(doc); if (docView) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index bbc29585c..b681387d1 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,7 +1,6 @@ import { action, runInAction } from "mobx"; import { Doc, Field } from "../../new_fields/Doc"; -import { Cast, StrCast, ScriptCast } from "../../new_fields/Types"; -import { URLField } from "../../new_fields/URLField"; +import { Cast, ScriptCast } from "../../new_fields/Types"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import * as globalCssVariables from "../views/globalCssVariables.scss"; @@ -27,14 +26,14 @@ export function SetupDrag( dontHideOnDrop?: boolean, dragStarted?: () => void ) { - let onRowMove = async (e: PointerEvent) => { + const onRowMove = async (e: PointerEvent) => { e.stopPropagation(); e.preventDefault(); document.removeEventListener("pointermove", onRowMove); document.removeEventListener('pointerup', onRowUp); - let doc = await docFunc(); - var dragData = new DragManager.DocumentDragData([doc]); + const doc = await docFunc(); + const dragData = new DragManager.DocumentDragData([doc]); dragData.dropAction = dropAction; dragData.moveDocument = moveFunc; dragData.options = options; @@ -42,11 +41,11 @@ export function SetupDrag( DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y); dragStarted && dragStarted(); }; - let onRowUp = (): void => { + const onRowUp = (): void => { document.removeEventListener("pointermove", onRowMove); document.removeEventListener('pointerup', onRowUp); }; - let onItemDown = async (e: React.PointerEvent) => { + const onItemDown = async (e: React.PointerEvent) => { if (e.button === 0) { e.stopPropagation(); if (e.shiftKey && CollectionDockingView.Instance) { @@ -74,11 +73,11 @@ function moveLinkedDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: } export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: number, linkDoc: Doc, sourceDoc: Doc) { - let draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc); + const draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc); if (draggeddoc) { - let moddrag = await Cast(draggeddoc.annotationOn, Doc); - let dragdocs = moddrag ? [moddrag] : [draggeddoc]; - let dragData = new DragManager.DocumentDragData(dragdocs); + const moddrag = await Cast(draggeddoc.annotationOn, Doc); + const dragdocs = moddrag ? [moddrag] : [draggeddoc]; + const dragData = new DragManager.DocumentDragData(dragdocs); dragData.moveDocument = moveLinkedDocument; DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, { handlers: { @@ -90,26 +89,26 @@ export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: num } export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc, singleLink?: Doc) { - let srcTarg = sourceDoc.proto; + const srcTarg = sourceDoc.proto; let draggedDocs: Doc[] = []; if (srcTarg) { - let linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg); + const linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg); if (linkDocs) { draggedDocs = linkDocs.map(link => { - let opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc); + const opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc); if (opp) return opp; }) as Doc[]; } } if (draggedDocs.length) { - let moddrag: Doc[] = []; + const moddrag: Doc[] = []; for (const draggedDoc of draggedDocs) { - let doc = await Cast(draggedDoc.annotationOn, Doc); + const doc = await Cast(draggedDoc.annotationOn, Doc); if (doc) moddrag.push(doc); } - let dragdocs = moddrag.length ? moddrag : draggedDocs; - let dragData = new DragManager.DocumentDragData(dragdocs); + const dragdocs = moddrag.length ? moddrag : draggedDocs; + const dragData = new DragManager.DocumentDragData(dragdocs); dragData.moveDocument = moveLinkedDocument; DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, { handlers: { @@ -254,11 +253,11 @@ export namespace DragManager { } export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { - let dragData = new DragManager.DocumentDragData([]); + const dragData = new DragManager.DocumentDragData([]); runInAction(() => StartDragFunctions.map(func => func())); StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag : (dropData: { [id: string]: any }) => { - let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title }); + const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title }); bd.onClick = ScriptField.MakeScript(script); params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc))); initialize && initialize(bd); @@ -273,11 +272,11 @@ export namespace DragManager { runInAction(() => StartDragFunctions.map(func => func())); StartDrag(eles, dragData, downX, downY, options, (dropData: { [id: string]: any }) => { - let droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => { - let dvs = DocumentManager.Instance.getDocumentViews(d); + const droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => { + const dvs = DocumentManager.Instance.getDocumentViews(d); if (dvs.length) { - let containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined; - let inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView); + const containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined; + const inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView); if (inContext.length) { inContext.forEach(dv => droppedDocs.push(dv.props.Document)); } else { @@ -336,26 +335,26 @@ export namespace DragManager { DragManager.Root().appendChild(dragDiv); } SelectionManager.SetIsDragging(true); - let scaleXs: number[] = []; - let scaleYs: number[] = []; - let xs: number[] = []; - let ys: number[] = []; + const scaleXs: number[] = []; + const scaleYs: number[] = []; + const xs: number[] = []; + const ys: number[] = []; const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnnotationDragData ? [dragData.dragDocument] : []; - let dragElements = eles.map(ele => { + const dragElements = eles.map(ele => { const w = ele.offsetWidth, h = ele.offsetHeight; const rect = ele.getBoundingClientRect(); const scaleX = rect.width / w, scaleY = rect.height / h; - let x = rect.left, + const x = rect.left, y = rect.top; xs.push(x); ys.push(y); scaleXs.push(scaleX); scaleYs.push(scaleY); - let dragElement = ele.cloneNode(true) as HTMLElement; + const dragElement = ele.cloneNode(true) as HTMLElement; dragElement.style.opacity = "0.7"; dragElement.style.borderRadius = getComputedStyle(ele).borderRadius; dragElement.style.position = "absolute"; @@ -372,25 +371,25 @@ export namespace DragManager { dragElement.style.height = `${rect.height / scaleY}px`; if (docs.length) { - var pdfBox = dragElement.getElementsByTagName("canvas"); - var pdfBoxSrc = ele.getElementsByTagName("canvas"); + const pdfBox = dragElement.getElementsByTagName("canvas"); + const pdfBoxSrc = ele.getElementsByTagName("canvas"); Array.from(pdfBox).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0)); - var pdfView = dragElement.getElementsByClassName("pdfViewer-viewer"); - var pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer"); - let tops = Array.from(pdfViewSrc).map(p => p.scrollTop); - let oldopacity = dragElement.style.opacity; + const pdfView = dragElement.getElementsByClassName("pdfViewer-viewer"); + const pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer"); + const tops = Array.from(pdfViewSrc).map(p => p.scrollTop); + const oldopacity = dragElement.style.opacity; dragElement.style.opacity = "0"; setTimeout(() => { dragElement.style.opacity = oldopacity; Array.from(pdfView).map((v, i) => v.scrollTo({ top: tops[i] })); }, 0); } - let set = dragElement.getElementsByTagName('*'); + const set = dragElement.getElementsByTagName('*'); if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none"; // tslint:disable-next-line: prefer-for-of for (let i = 0; i < set.length; i++) { if (set[i].hasAttribute("style")) { - let s = set[i]; + const s = set[i]; (s as any).style.pointerEvents = "none"; } } @@ -429,8 +428,8 @@ export namespace DragManager { }, dragData.droppedDocuments); } //TODO: Why can't we use e.movementX and e.movementY? - let moveX = e.pageX - lastX; - let moveY = e.pageY - lastY; + const moveX = e.pageX - lastX; + const moveY = e.pageY - lastY; lastX = e.pageX; lastY = e.pageY; dragElements.map((dragElement, i) => (dragElement.style.transform = @@ -438,11 +437,11 @@ export namespace DragManager { ); }; - let hideDragShowOriginalElements = () => { + const hideDragShowOriginalElements = () => { dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); eles.map(ele => ele.hidden = false); }; - let endDrag = () => { + const endDrag = () => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); if (options) { @@ -466,17 +465,17 @@ export namespace DragManager { } function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) { - let removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => { + const removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => { // let parent = dragEle.parentElement; // if (parent) parent.removeChild(dragEle); - let ret = [dragEle, dragEle.style.width, dragEle.style.height]; + const ret = [dragEle, dragEle.style.width, dragEle.style.height]; dragEle.style.width = "0"; dragEle.style.height = "0"; return ret; }); const target = document.elementFromPoint(e.x, e.y); removed.map(r => { - let dragEle = r[0] as HTMLElement; + const dragEle = r[0] as HTMLElement; dragEle.style.width = r[1] as string; dragEle.style.height = r[2] as string; // let parent = r[1]; diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 6b53333d7..b2c720d5d 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -9,10 +9,10 @@ import { ScriptField } from "../../new_fields/ScriptField"; function makeTemplate(doc: Doc): boolean { - let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; - let layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0]; - let fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, ""); - let docs = DocListCast(layoutDoc[fieldKey]); + const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; + const layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0]; + const fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, ""); + const docs = DocListCast(layoutDoc[fieldKey]); let any = false; docs.map(d => { if (!StrCast(d.title).startsWith("-")) { @@ -28,7 +28,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { data && data.draggedDocuments.map((doc, i) => { let dbox = doc; if (!doc.onDragStart && !doc.onClick && doc.viewType !== CollectionViewType.Linear) { - let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; + const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc; if (layoutDoc.type === DocumentType.COL) { layoutDoc.isTemplateDoc = makeTemplate(layoutDoc); } else { diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 1c51236cb..545e8acb4 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -1,4 +1,4 @@ -import { Doc, Opt, Field } from "../../new_fields/Doc"; +import { Doc } from "../../new_fields/Doc"; import { DocServer } from "../DocServer"; import { MainView } from "../views/MainView"; import * as qs from 'query-string'; @@ -53,7 +53,7 @@ export namespace HistoryUtil { } export function getState(): ParsedUrl { - let state = copyState(history.state); + const state = copyState(history.state); state.initializers = state.initializers || {}; return state; } @@ -160,7 +160,7 @@ export namespace HistoryUtil { const pathname = location.pathname.substring(1); const search = location.search; const opts = search.length ? qs.parse(search, { sort: false }) : {}; - let pathnameSplit = pathname.split("/"); + const pathnameSplit = pathname.split("/"); const type = pathnameSplit[0]; diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 104d9e099..e6a215b2c 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -1,7 +1,7 @@ import "fs"; import React = require("react"); import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc"; -import { action, observable, autorun, runInAction, computed, reaction, IReactionDisposer } from "mobx"; +import { action, observable, runInAction, computed, reaction, IReactionDisposer } from "mobx"; import { FieldViewProps, FieldView } from "../../views/nodes/FieldView"; import Measure, { ContentRect } from "react-measure"; import { library } from '@fortawesome/fontawesome-svg-core'; @@ -48,7 +48,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> constructor(props: FieldViewProps) { super(props); library.add(faTag, faPlus); - let doc = this.props.Document; + const doc = this.props.Document; this.editingMetadata = this.editingMetadata || false; this.persistent = this.persistent || false; !Cast(doc.data, listSpec(Doc)) && (doc.data = new List<Doc>()); @@ -78,16 +78,16 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> this.phase = "Initializing download..."; }); - let docs: Doc[] = []; + const docs: Doc[] = []; - let files = e.target.files; + const files = e.target.files; if (!files || files.length === 0) return; - let directory = (files.item(0) as any).webkitRelativePath.split("/", 1)[0]; + const directory = (files.item(0) as any).webkitRelativePath.split("/", 1)[0]; - let validated: File[] = []; + const validated: File[] = []; for (let i = 0; i < files.length; i++) { - let file = files.item(i); + const file = files.item(i); if (file && !unsupported.includes(file.type)) { const ext = path.extname(file.name).toLowerCase(); if (AcceptibleMedia.imageFormats.includes(ext)) { @@ -101,8 +101,8 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> this.completed = 0; }); - let sizes: number[] = []; - let modifiedDates: number[] = []; + const sizes: number[] = []; + const modifiedDates: number[] = []; runInAction(() => this.phase = `Internal: uploading ${this.quota - this.completed} files to Dash...`); @@ -136,26 +136,26 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> })); for (let i = 0; i < docs.length; i++) { - let doc = docs[i]; + const doc = docs[i]; doc.size = sizes[i]; doc.modified = modifiedDates[i]; this.entries.forEach(entry => { - let target = entry.onDataDoc ? Doc.GetProto(doc) : doc; + const target = entry.onDataDoc ? Doc.GetProto(doc) : doc; target[entry.key] = entry.value; }); } - let doc = this.props.Document; - let height: number = NumCast(doc.height) || 0; - let offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0; - let options: DocumentOptions = { + const doc = this.props.Document; + const height: number = NumCast(doc.height) || 0; + const offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0; + const options: DocumentOptions = { title: `Import of ${directory}`, width: 1105, height: 500, x: NumCast(doc.x), y: NumCast(doc.y) + offset }; - let parent = this.props.ContainingCollectionView; + const parent = this.props.ContainingCollectionView; if (parent) { let importContainer: Doc; if (docs.length < 50) { @@ -194,18 +194,18 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> @action preserveCentering = (rect: ContentRect) => { - let bounds = rect.offset!; + const bounds = rect.offset!; if (bounds.width === 0 || bounds.height === 0) { return; } - let offset = this.dimensions / 2; + const offset = this.dimensions / 2; this.left = bounds.width / 2 - offset; this.top = bounds.height / 2 - offset; } @action addMetadataEntry = async () => { - let entryDoc = new Doc(); + const entryDoc = new Doc(); entryDoc.checked = false; entryDoc.key = keyPlaceholder; entryDoc.value = valuePlaceholder; @@ -214,7 +214,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> @action remove = async (entry: ImportMetadataEntry) => { - let metadata = await DocListCastAsync(this.props.Document.data); + const metadata = await DocListCastAsync(this.props.Document.data); if (metadata) { let index = this.entries.indexOf(entry); if (index !== -1) { @@ -228,18 +228,18 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> } render() { - let dimensions = 50; - let entries = DocListCast(this.props.Document.data); - let isEditing = this.editingMetadata; - let completed = this.completed; - let quota = this.quota; - let uploading = this.uploading; - let showRemoveLabel = this.removeHover; - let persistent = this.persistent; + const dimensions = 50; + const entries = DocListCast(this.props.Document.data); + const isEditing = this.editingMetadata; + const completed = this.completed; + const quota = this.quota; + const uploading = this.uploading; + const showRemoveLabel = this.removeHover; + const persistent = this.persistent; let percent = `${completed / quota * 100}`; percent = percent.split(".")[0]; percent = percent.startsWith("100") ? "99" : percent; - let marginOffset = (percent.length === 1 ? 5 : 0) - 1.6; + const marginOffset = (percent.length === 1 ? 5 : 0) - 1.6; const message = <span className={"phase"}>{this.phase}</span>; const centerPiece = this.phase.includes("Google Photos") ? <img src={"/assets/google_photos.png"} style={{ diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx index f5198c39b..8e1c50bea 100644 --- a/src/client/util/Import & Export/ImportMetadataEntry.tsx +++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx @@ -1,11 +1,11 @@ import React = require("react"); import { observer } from "mobx-react"; import { EditableView } from "../../views/EditableView"; -import { observable, action, computed } from "mobx"; +import { action, computed } from "mobx"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; import { library } from '@fortawesome/fontawesome-svg-core'; -import { Opt, Doc } from "../../../new_fields/Doc"; +import { Doc } from "../../../new_fields/Doc"; import { StrCast, BoolCast } from "../../../new_fields/Types"; interface KeyValueProps { @@ -85,7 +85,7 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps> } render() { - let keyValueStyle: React.CSSProperties = { + const keyValueStyle: React.CSSProperties = { paddingLeft: 10, width: "50%", opacity: this.valid ? 1 : 0.5, diff --git a/src/client/util/InteractionUtils.ts b/src/client/util/InteractionUtils.ts index b7738e862..0c3de66ed 100644 --- a/src/client/util/InteractionUtils.ts +++ b/src/client/util/InteractionUtils.ts @@ -29,8 +29,8 @@ export namespace InteractionUtils { * @param pts - n-arbitrary long list of points */ export function CenterPoint(pts: React.Touch[]): { X: number, Y: number } { - let centerX = pts.map(pt => pt.clientX).reduce((a, b) => a + b, 0) / pts.length; - let centerY = pts.map(pt => pt.clientY).reduce((a, b) => a + b, 0) / pts.length; + const centerX = pts.map(pt => pt.clientX).reduce((a, b) => a + b, 0) / pts.length; + const centerY = pts.map(pt => pt.clientY).reduce((a, b) => a + b, 0) / pts.length; return { X: centerX, Y: centerY }; } @@ -42,9 +42,9 @@ export namespace InteractionUtils { * @param oldPoint2 - previous point 2 */ export function Pinching(pt1: React.Touch, pt2: React.Touch, oldPoint1: React.Touch, oldPoint2: React.Touch): number { - let threshold = 4; - let oldDist = TwoPointEuclidist(oldPoint1, oldPoint2); - let newDist = TwoPointEuclidist(pt1, pt2); + const threshold = 4; + const oldDist = TwoPointEuclidist(oldPoint1, oldPoint2); + const newDist = TwoPointEuclidist(pt1, pt2); /** if they have the same sign, then we are either pinching in or out. * threshold it by 10 (it has to be pinching by at least threshold to be a valid pinch) @@ -64,12 +64,12 @@ export namespace InteractionUtils { * @param oldPoint2 - previous point 2 */ export function Pinning(pt1: React.Touch, pt2: React.Touch, oldPoint1: React.Touch, oldPoint2: React.Touch): number { - let threshold = 4; + const threshold = 4; - let pt1Dist = TwoPointEuclidist(oldPoint1, pt1); - let pt2Dist = TwoPointEuclidist(oldPoint2, pt2); + const pt1Dist = TwoPointEuclidist(oldPoint1, pt1); + const pt2Dist = TwoPointEuclidist(oldPoint2, pt2); - let pinching = Pinching(pt1, pt2, oldPoint1, oldPoint2); + const pinching = Pinching(pt1, pt2, oldPoint1, oldPoint2); if (pinching !== 0) { if ((pt1Dist < threshold && pt2Dist > threshold) || (pt1Dist > threshold && pt2Dist < threshold)) { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index eedc4967d..fb6f27478 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -38,16 +38,16 @@ export class LinkManager { } public getAllLinks(): Doc[] { - let ldoc = LinkManager.Instance.LinkManagerDoc; + const ldoc = LinkManager.Instance.LinkManagerDoc; if (ldoc) { - let docs = DocListCast(ldoc.allLinks); + const docs = DocListCast(ldoc.allLinks); return docs; } return []; } public addLink(linkDoc: Doc): boolean { - let linkList = LinkManager.Instance.getAllLinks(); + const linkList = LinkManager.Instance.getAllLinks(); linkList.push(linkDoc); if (LinkManager.Instance.LinkManagerDoc) { LinkManager.Instance.LinkManagerDoc.allLinks = new List<Doc>(linkList); @@ -57,8 +57,8 @@ export class LinkManager { } public deleteLink(linkDoc: Doc): boolean { - let linkList = LinkManager.Instance.getAllLinks(); - let index = LinkManager.Instance.getAllLinks().indexOf(linkDoc); + const linkList = LinkManager.Instance.getAllLinks(); + const index = LinkManager.Instance.getAllLinks().indexOf(linkDoc); if (index > -1) { linkList.splice(index, 1); if (LinkManager.Instance.LinkManagerDoc) { @@ -71,23 +71,23 @@ export class LinkManager { // finds all links that contain the given anchor public getAllRelatedLinks(anchor: Doc): Doc[] {//List<Doc> { - let related = LinkManager.Instance.getAllLinks().filter(link => { - let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null)); - let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null)); + const related = LinkManager.Instance.getAllLinks().filter(link => { + const protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null)); + const protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null)); return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor); }); return related; } public deleteAllLinksOnAnchor(anchor: Doc) { - let related = LinkManager.Instance.getAllRelatedLinks(anchor); + const related = LinkManager.Instance.getAllRelatedLinks(anchor); related.forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } public addGroupType(groupType: string): boolean { if (LinkManager.Instance.LinkManagerDoc) { LinkManager.Instance.LinkManagerDoc[groupType] = new List<string>([]); - let groupTypes = LinkManager.Instance.getAllGroupTypes(); + const groupTypes = LinkManager.Instance.getAllGroupTypes(); groupTypes.push(groupType); LinkManager.Instance.LinkManagerDoc.allGroupTypes = new List<string>(groupTypes); return true; @@ -99,8 +99,8 @@ export class LinkManager { public deleteGroupType(groupType: string): boolean { if (LinkManager.Instance.LinkManagerDoc) { if (LinkManager.Instance.LinkManagerDoc[groupType]) { - let groupTypes = LinkManager.Instance.getAllGroupTypes(); - let index = groupTypes.findIndex(type => type.toUpperCase() === groupType.toUpperCase()); + const groupTypes = LinkManager.Instance.getAllGroupTypes(); + const index = groupTypes.findIndex(type => type.toUpperCase() === groupType.toUpperCase()); if (index > -1) groupTypes.splice(index, 1); LinkManager.Instance.LinkManagerDoc.allGroupTypes = new List<string>(groupTypes); LinkManager.Instance.LinkManagerDoc[groupType] = undefined; @@ -146,8 +146,8 @@ export class LinkManager { } public addGroupToAnchor(linkDoc: Doc, anchor: Doc, groupDoc: Doc, replace: boolean = false) { - let groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor); - let index = groups.findIndex(gDoc => { + const groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor); + const index = groups.findIndex(gDoc => { return StrCast(groupDoc.type).toUpperCase() === StrCast(gDoc.type).toUpperCase(); }); if (index > -1 && replace) { @@ -161,32 +161,32 @@ export class LinkManager { // removes group doc of given group type only from given anchor on given link public removeGroupFromAnchor(linkDoc: Doc, anchor: Doc, groupType: string) { - let groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor); - let newGroups = groups.filter(groupDoc => StrCast(groupDoc.type).toUpperCase() !== groupType.toUpperCase()); + const groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor); + const newGroups = groups.filter(groupDoc => StrCast(groupDoc.type).toUpperCase() !== groupType.toUpperCase()); LinkManager.Instance.setAnchorGroups(linkDoc, anchor, newGroups); } // returns map of group type to anchor's links in that group type public getRelatedGroupedLinks(anchor: Doc): Map<string, Array<Doc>> { - let related = this.getAllRelatedLinks(anchor); - let anchorGroups = new Map<string, Array<Doc>>(); + const related = this.getAllRelatedLinks(anchor); + const anchorGroups = new Map<string, Array<Doc>>(); related.forEach(link => { - let groups = LinkManager.Instance.getAnchorGroups(link, anchor); + const groups = LinkManager.Instance.getAnchorGroups(link, anchor); if (groups.length > 0) { groups.forEach(groupDoc => { - let groupType = StrCast(groupDoc.type); + const groupType = StrCast(groupDoc.type); if (groupType === "") { - let group = anchorGroups.get("*"); + const group = anchorGroups.get("*"); anchorGroups.set("*", group ? [...group, link] : [link]); } else { - let group = anchorGroups.get(groupType); + const group = anchorGroups.get(groupType); anchorGroups.set(groupType, group ? [...group, link] : [link]); } }); } else { // if link is in no groups then put it in default group - let group = anchorGroups.get("*"); + const group = anchorGroups.get("*"); anchorGroups.set("*", group ? [...group, link] : [link]); } @@ -212,11 +212,11 @@ export class LinkManager { // returns a list of all metadata docs associated with the given group type public getAllMetadataDocsInGroup(groupType: string): Array<Doc> { - let md: Doc[] = []; - let allLinks = LinkManager.Instance.getAllLinks(); + const md: Doc[] = []; + const allLinks = LinkManager.Instance.getAllLinks(); allLinks.forEach(linkDoc => { - let anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, null)); - let anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, null)); + const anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, null)); + const anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, null)); anchor1Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } }); anchor2Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } }); }); @@ -225,8 +225,8 @@ export class LinkManager { // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { - let allLinks = LinkManager.Instance.getAllLinks(); - let index = allLinks.findIndex(linkDoc => { + const allLinks = LinkManager.Instance.getAllLinks(); + const index = allLinks.findIndex(linkDoc => { return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1)); }); @@ -237,8 +237,8 @@ export class LinkManager { //TODO This should probably return undefined if there isn't an opposite anchor //TODO This should also await the return value of the anchor so we don't filter out promises public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined { - let a1 = Cast(linkDoc.anchor1, Doc, null); - let a2 = Cast(linkDoc.anchor2, Doc, null); + const a1 = Cast(linkDoc.anchor1, Doc, null); + const a2 = Cast(linkDoc.anchor2, Doc, null); if (Doc.AreProtosEqual(anchor, a1)) return a2; if (Doc.AreProtosEqual(anchor, a2)) return a1; if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc; diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 003ff6272..f1fa6f11d 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -4,7 +4,7 @@ import { undoInputRule } from "prosemirror-inputrules"; import { Schema } from "prosemirror-model"; import { liftListItem, sinkListItem } from "./prosemirrorPatches.js"; import { splitListItem, wrapInList, } from "prosemirror-schema-list"; -import { EditorState, Transaction, TextSelection, NodeSelection } from "prosemirror-state"; +import { EditorState, Transaction, TextSelection } from "prosemirror-state"; import { TooltipTextMenu } from "./TooltipTextMenu"; const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; @@ -15,22 +15,22 @@ export let updateBullets = (tx2: Transaction, schema: Schema, mapStyle?: string) let fontSize: number | undefined = undefined; tx2.doc.descendants((node: any, offset: any, index: any) => { if (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item) { - let path = (tx2.doc.resolve(offset) as any).path; + const path = (tx2.doc.resolve(offset) as any).path; let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && c.type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) depth++; fontSize = depth === 1 && node.attrs.setFontSize ? Number(node.attrs.setFontSize) : fontSize; - let fsize = fontSize && node.type === schema.nodes.ordered_list ? Math.max(6, fontSize - (depth - 1) * 4) : undefined; + const fsize = fontSize && node.type === schema.nodes.ordered_list ? Math.max(6, fontSize - (depth - 1) * 4) : undefined; tx2.setNodeMarkup(offset, node.type, { ...node.attrs, mapStyle: mapStyle ? mapStyle : node.attrs.mapStyle, bulletStyle: depth, inheritedFontSize: fsize }, node.marks); } }); return tx2; }; export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: KeyMap): KeyMap { - let keys: { [key: string]: any } = {}, type; + const keys: { [key: string]: any } = {}; function bind(key: string, cmd: any) { if (mapKeys) { - let mapped = mapKeys[key]; + const mapped = mapKeys[key]; if (mapped === false) return; if (mapped) key = mapped; } @@ -79,7 +79,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: // }); - let cmd = chainCommands(exitCode, (state, dispatch) => { + const cmd = chainCommands(exitCode, (state, dispatch) => { if (dispatch) { dispatch(state.tr.replaceSelectionWith(schema.nodes.hard_break.create()).scrollIntoView()); return true; @@ -99,7 +99,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: bind("Shift-Ctrl-" + i, setBlockType(schema.nodes.heading, { level: i })); } - let hr = schema.nodes.horizontal_rule; + const hr = schema.nodes.horizontal_rule; bind("Mod-_", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); return true; @@ -108,18 +108,18 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: bind("Mod-s", TooltipTextMenu.insertStar); bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - var ref = state.selection; - var range = ref.$from.blockRange(ref.$to); - var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + const ref = state.selection; + const range = ref.$from.blockRange(ref.$to); + const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { - let tx3 = updateBullets(tx2, schema); + const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); dispatch(tx3); })) { // couldn't sink into an existing list, so wrap in a new one - let newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end))); + const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end))); if (!wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => { - let tx3 = updateBullets(tx2, schema); + const tx3 = updateBullets(tx2, schema); // when promoting to a list, assume list will format things so don't copy the stored marks. marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); @@ -131,10 +131,10 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: }); bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); if (!liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => { - let tx3 = updateBullets(tx2, schema); + const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); dispatch(tx3); @@ -143,14 +143,14 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: } }); - let splitMetadata = (marks: any, tx: Transaction) => { + const splitMetadata = (marks: any, tx: Transaction) => { marks && tx.ensureMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal)); marks && tx.setStoredMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal)); return tx; }; - bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - if (!splitListItem(schema.nodes.list_item)(state, (tx3: Transaction) => dispatch(tx3))) { + bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => { + const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + if (!splitListItem(schema.nodes.list_item)(state, dispatch)) { if (!splitBlockKeepMarks(state, (tx3: Transaction) => { splitMetadata(marks, tx3); if (!liftListItem(schema.nodes.list_item)(tx3, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) { @@ -163,18 +163,18 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: return true; }); bind("Space", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); + const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); dispatch(splitMetadata(marks, state.tr)); return false; }); bind(":", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - let range = state.selection.$from.blockRange(state.selection.$to, (node: any) => { + const range = state.selection.$from.blockRange(state.selection.$to, (node: any) => { return !node.marks || !node.marks.find((m: any) => m.type === schema.marks.metadata); }); - let path = (state.doc.resolve(state.selection.from - 1) as any).path; - let spaceSeparator = path[path.length - 3].childCount > 1 ? 0 : -1; - let textsel = TextSelection.create(state.doc, range!.end - path[path.length - 3].lastChild.nodeSize + spaceSeparator, range!.end); - let text = range ? state.doc.textBetween(textsel.from, textsel.to) : ""; + const path = (state.doc.resolve(state.selection.from - 1) as any).path; + const spaceSeparator = path[path.length - 3].childCount > 1 ? 0 : -1; + const textsel = TextSelection.create(state.doc, range!.end - path[path.length - 3].lastChild.nodeSize + spaceSeparator, range!.end); + const text = range ? state.doc.textBetween(textsel.from, textsel.to) : ""; let whitespace = text.length - 1; for (; whitespace >= 0 && text[whitespace] !== " "; whitespace--) { } if (text.endsWith(":")) { diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index f4c44e5ce..1a637df32 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -62,109 +62,109 @@ export const inpRules = { new InputRule( new RegExp(/^#([0-9]+)\s$/), (state, match, start, end) => { - let size = Number(match[1]); - let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; - let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); + const size = Number(match[1]); + const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; + const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { - (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = Number(match[1]); + (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = size; return state.tr.deleteRange(start, end); } - return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: Number(match[1]) })); + return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size })); }), new InputRule( new RegExp(/t/), (state, match, start, end) => { if (state.selection.to === state.selection.from) return null; - let node = (state.doc.resolve(start) as any).nodeAfter; + const node = (state.doc.resolve(start) as any).nodeAfter; return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "todo", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr; }), new InputRule( new RegExp(/i/), (state, match, start, end) => { if (state.selection.to === state.selection.from) return null; - let node = (state.doc.resolve(start) as any).nodeAfter; + const node = (state.doc.resolve(start) as any).nodeAfter; return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "ignore", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr; }), new InputRule( new RegExp(/\!/), (state, match, start, end) => { if (state.selection.to === state.selection.from) return null; - let node = (state.doc.resolve(start) as any).nodeAfter; + const node = (state.doc.resolve(start) as any).nodeAfter; return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "important", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr; }), new InputRule( new RegExp(/\x/), (state, match, start, end) => { if (state.selection.to === state.selection.from) return null; - let node = (state.doc.resolve(start) as any).nodeAfter; + const node = (state.doc.resolve(start) as any).nodeAfter; return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "disagree", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr; }), new InputRule( new RegExp(/^\^\^\s$/), (state, match, start, end) => { - let node = (state.doc.resolve(start) as any).nodeAfter; - let sm = state.storedMarks || undefined; - let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; - let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); + const node = (state.doc.resolve(start) as any).nodeAfter; + const sm = state.storedMarks || undefined; + const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; + const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "center"; return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; } - let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "center" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : + const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "center" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2))); }), new InputRule( new RegExp(/^\[\[\s$/), (state, match, start, end) => { - let node = (state.doc.resolve(start) as any).nodeAfter; - let sm = state.storedMarks || undefined; - let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; - let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); + const node = (state.doc.resolve(start) as any).nodeAfter; + const sm = state.storedMarks || undefined; + const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; + const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "left"; return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; } - let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "left" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : + const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "left" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2))); }), new InputRule( new RegExp(/^\]\]\s$/), (state, match, start, end) => { - let node = (state.doc.resolve(start) as any).nodeAfter; - let sm = state.storedMarks || undefined; - let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; - let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); + const node = (state.doc.resolve(start) as any).nodeAfter; + const sm = state.storedMarks || undefined; + const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider; + const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleAlign_" + heading] = "right"; return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; } - let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "right" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : + const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "right" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2))); }), new InputRule( new RegExp(/##\s$/), (state, match, start, end) => { - let target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" }); - let node = (state.doc.resolve(start) as any).nodeAfter; - let newNode = schema.nodes.dashComment.create({ docid: target[Id] }); - let dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" }); - let sm = state.storedMarks || undefined; - let replaced = node ? state.tr.insert(start, newNode).replaceRangeWith(start + 1, end + 1, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : + const target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" }); + const node = (state.doc.resolve(start) as any).nodeAfter; + const newNode = schema.nodes.dashComment.create({ docid: target[Id] }); + const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" }); + const sm = state.storedMarks || undefined; + const replaced = node ? state.tr.insert(start, newNode).replaceRangeWith(start + 1, end + 1, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; return replaced;//.setSelection(new NodeSelection(replaced.doc.resolve(end))); }), new InputRule( new RegExp(/\(\(/), (state, match, start, end) => { - let node = (state.doc.resolve(start) as any).nodeAfter; - let sm = state.storedMarks || undefined; - let mark = state.schema.marks.highlight.create(); - let selected = state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).addMark(start, end, mark); - let content = selected.selection.content(); - let replaced = node ? selected.replaceRangeWith(start, start, + const node = (state.doc.resolve(start) as any).nodeAfter; + const sm = state.storedMarks || undefined; + const mark = state.schema.marks.highlight.create(); + const selected = state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).addMark(start, end, mark); + const content = selected.selection.content(); + const replaced = node ? selected.replaceRangeWith(start, start, schema.nodes.star.create({ visibility: true, text: content, textslice: content.toJSON() })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; return replaced.setSelection(new TextSelection(replaced.doc.resolve(end + 1))); @@ -172,14 +172,14 @@ export const inpRules = { new InputRule( new RegExp(/\)\)/), (state, match, start, end) => { - let mark = state.schema.marks.highlight.create(); + const mark = state.schema.marks.highlight.create(); return state.tr.removeStoredMark(mark); }), new InputRule( new RegExp(/\^f\s$/), (state, match, start, end) => { - let newNode = schema.nodes.footnote.create({}); - let tr = state.tr; + const newNode = schema.nodes.footnote.create({}); + const tr = state.tr; tr.deleteRange(start, end).replaceSelectionWith(newNode); // replace insertion with a footnote. return tr.setSelection(new NodeSelection( // select the footnote node to open its display tr.doc.resolve( // get the location of the footnote node by subtracting the nodesize of the footnote from the current insertion point anchor (which will be immediately after the footnote node) diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 522232e9f..cb03892f3 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -1,4 +1,4 @@ -import { action, observable, runInAction, reaction, IReactionDisposer } from "mobx"; +import { reaction, IReactionDisposer } from "mobx"; import { baseKeymap, toggleMark } from "prosemirror-commands"; import { redo, undo } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; @@ -257,9 +257,9 @@ export const nodes: { [index: string]: NodeSpec } = { if (node.attrs.mapStyle === "bullet") return ['ul', 0]; const decMap = bs ? "decimal" + bs : ""; const multiMap = bs === 1 ? "decimal1" : bs === 2 ? "upper-alpha" : bs === 3 ? "lower-roman" : bs === 4 ? "lower-alpha" : ""; - let map = node.attrs.mapStyle === "decimal" ? decMap : multiMap; - let fsize = node.attrs.setFontSize ? node.attrs.setFontSize : node.attrs.inheritedFontSize; - let ffam = node.attrs.setFontFamily; + const map = node.attrs.mapStyle === "decimal" ? decMap : multiMap; + const fsize = node.attrs.setFontSize ? node.attrs.setFontSize : node.attrs.inheritedFontSize; + const ffam = node.attrs.setFontFamily; return node.attrs.visibility ? ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}` }, 0] : ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}` }]; } @@ -287,7 +287,7 @@ export const nodes: { [index: string]: NodeSpec } = { const bs = node.attrs.bulletStyle; const decMap = bs ? "decimal" + bs : ""; const multiMap = bs === 1 ? "decimal1" : bs === 2 ? "upper-alpha" : bs === 3 ? "lower-roman" : bs === 4 ? "lower-alpha" : ""; - let map = node.attrs.mapStyle === "decimal" ? decMap : node.attrs.mapStyle === "multi" ? multiMap : ""; + const map = node.attrs.mapStyle === "decimal" ? decMap : node.attrs.mapStyle === "multi" ? multiMap : ""; return node.attrs.visibility ? ["li", { class: `${map}` }, 0] : ["li", { class: `${map}` }, "..."]; //return ["li", { class: `${map}` }, 0]; } @@ -432,7 +432,7 @@ export const marks: { [index: string]: MarkSpec } = { tag: "span", getAttrs: (p: any) => { if (typeof (p) !== "string") { - let style = getComputedStyle(p); + const style = getComputedStyle(p); if (style.textDecoration === "underline") return null; if (p.parentElement.outerHTML.indexOf("text-decoration: underline") !== -1 && p.parentElement.outerHTML.indexOf("text-decoration-style: dotted") !== -1) { @@ -457,7 +457,7 @@ export const marks: { [index: string]: MarkSpec } = { tag: "span", getAttrs: (p: any) => { if (typeof (p) !== "string") { - let style = getComputedStyle(p); + const style = getComputedStyle(p); if (style.textDecoration === "underline" || p.parentElement.outerHTML.indexOf("text-decoration-style:line") !== -1) { return null; } @@ -493,11 +493,11 @@ export const marks: { [index: string]: MarkSpec } = { }, group: "inline", toDOM(node: any) { - let uid = node.attrs.userid.replace(".", "").replace("@", ""); - let min = Math.round(node.attrs.modified / 12); - let hr = Math.round(min / 60); - let day = Math.round(hr / 60 / 24); - let remote = node.attrs.userid !== Doc.CurrentUserEmail ? " userMark-remote" : ""; + const uid = node.attrs.userid.replace(".", "").replace("@", ""); + const min = Math.round(node.attrs.modified / 12); + const hr = Math.round(min / 60); + const day = Math.round(hr / 60 / 24); + const remote = node.attrs.userid !== Doc.CurrentUserEmail ? " userMark-remote" : ""; return node.attrs.opened ? ['span', { class: "userMark-" + uid + remote + " userMark-min-" + min + " userMark-hr-" + hr + " userMark-day-" + day }, 0] : ['span', { class: "userMark-" + uid + remote + " userMark-min-" + min + " userMark-hr-" + hr + " userMark-day-" + day }, ['span', 0]]; @@ -513,7 +513,7 @@ export const marks: { [index: string]: MarkSpec } = { }, group: "inline", toDOM(node: any) { - let uid = node.attrs.userid.replace(".", "").replace("@", ""); + const uid = node.attrs.userid.replace(".", "").replace("@", ""); return node.attrs.opened ? ['span', { class: "userTag-" + uid + " userTag-" + node.attrs.tag }, 0] : ['span', { class: "userTag-" + uid + " userTag-" + node.attrs.tag }, ['span', 0]]; @@ -534,7 +534,7 @@ export const marks: { [index: string]: MarkSpec } = { }, parseDOM: [{ tag: "span", getAttrs(dom: any) { - let cstyle = getComputedStyle(dom); + const cstyle = getComputedStyle(dom); if (cstyle.font) { if (cstyle.font.indexOf("Times New Roman") !== -1) return { family: "Times New Roman" }; if (cstyle.font.indexOf("Arial") !== -1) return { family: "Arial" }; @@ -599,7 +599,7 @@ export class ImageResizeView { this._handle.style.display = "none"; this._handle.style.bottom = "-10px"; this._handle.style.right = "-10px"; - let self = this; + const self = this; this._img.onclick = function (e: any) { e.stopPropagation(); e.preventDefault(); @@ -620,8 +620,8 @@ export class ImageResizeView { this._handle.onpointerdown = function (e: any) { e.preventDefault(); e.stopPropagation(); - let wid = Number(getComputedStyle(self._img).width.replace(/px/, "")); - let hgt = Number(getComputedStyle(self._img).height.replace(/px/, "")); + const wid = Number(getComputedStyle(self._img).width.replace(/px/, "")); + const hgt = Number(getComputedStyle(self._img).height.replace(/px/, "")); const startX = e.pageX; const startWidth = parseFloat(node.attrs.width); const onpointermove = (e: any) => { @@ -634,7 +634,7 @@ export class ImageResizeView { const onpointerup = () => { document.removeEventListener("pointermove", onpointermove); document.removeEventListener("pointerup", onpointerup); - let pos = view.state.selection.from; + const pos = view.state.selection.from; view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: self._outer.style.width, height: self._outer.style.height })); view.dispatch(view.state.tr.setSelection(new NodeSelection(view.state.doc.resolve(pos)))); }; @@ -671,19 +671,19 @@ export class DashDocCommentView { this._collapsed.id = "DashDocCommentView-" + node.attrs.docid; this._view = view; this._collapsed.onpointerdown = (e: any) => { - let node = view.state.doc.nodeAt(getPos() + 1); + const node = view.state.doc.nodeAt(getPos() + 1); view.dispatch(view.state.tr. setNodeMarkup(getPos() + 1, undefined, { ...node.attrs, hidden: node.attrs.hidden ? false : true })); // update the attrs setTimeout(() => node.attrs.hidden && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)), 100); - } + }; this._collapsed.onpointerenter = (e: any) => { - let node = view.state.doc.nodeAt(getPos() + 1); + const node = view.state.doc.nodeAt(getPos() + 1); DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); e.preventDefault(); e.stopPropagation(); }; this._collapsed.onpointerleave = (e: any) => { - let node = view.state.doc.nodeAt(getPos() + 1); + const node = view.state.doc.nodeAt(getPos() + 1); DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); e.preventDefault(); e.stopPropagation(); @@ -701,7 +701,7 @@ export class DashDocView { _textBox: FormattedTextBox; getDocTransform = () => { - let { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer); + const { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer); return new Transform(-translateX, -translateY, 1).scale(1 / this.contentScaling() / scale); } contentScaling = () => NumCast(this._dashDoc!.nativeWidth) > 0 && !this._dashDoc!.ignoreAspect ? this._dashDoc![WidthSym]() / NumCast(this._dashDoc!.nativeWidth) : 1; @@ -721,24 +721,24 @@ export class DashDocView { this._dashSpan.style.position = "absolute"; this._dashSpan.style.display = "inline-block"; this._dashSpan.style.borderWidth = "4"; - let removeDoc = () => { - let pos = getPos(); - let ns = new NodeSelection(view.state.doc.resolve(pos)); + const removeDoc = () => { + const pos = getPos(); + const ns = new NodeSelection(view.state.doc.resolve(pos)); view.dispatch(view.state.tr.setSelection(ns).deleteSelection()); return true; }; this._dashSpan.onpointerleave = () => { - let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); + const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); if (ele) { (ele as HTMLDivElement).style.backgroundColor = ""; } - } + }; this._dashSpan.onpointerenter = () => { - let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); + const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); if (ele) { (ele as HTMLDivElement).style.backgroundColor = "orange"; } - } + }; DocServer.GetRefField(node.attrs.docid).then(async dashDoc => { if (dashDoc instanceof Doc) { self._dashDoc = dashDoc; @@ -777,7 +777,7 @@ export class DashDocView { />, this._dashSpan); } }); - let self = this; + const self = this; this._dashSpan.onkeydown = function (e: any) { e.stopPropagation(); }; this._dashSpan.onkeypress = function (e: any) { e.stopPropagation(); }; this._dashSpan.onwheel = function (e: any) { e.preventDefault(); }; @@ -830,7 +830,7 @@ export class FootnoteView { } open() { // Append a tooltip to the outer node - let tooltip = this.dom.appendChild(document.createElement("div")); + const tooltip = this.dom.appendChild(document.createElement("div")); tooltip.className = "footnote-tooltip"; // And put a sub-ProseMirror into that this.innerView = new EditorView(tooltip, { @@ -885,14 +885,14 @@ export class FootnoteView { this.dom.textContent = ""; } dispatchInner(tr: any) { - let { state, transactions } = this.innerView.state.applyTransaction(tr); + const { state, transactions } = this.innerView.state.applyTransaction(tr); this.innerView.updateState(state); if (!tr.getMeta("fromOutside")) { - let outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1); - for (let transaction of transactions) { - let steps = transaction.steps; - for (let step of steps) { + const outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1); + for (const transaction of transactions) { + const steps = transaction.steps; + for (const step of steps) { outerTr.step(step.map(offsetMap)); } } @@ -903,11 +903,11 @@ export class FootnoteView { if (!node.sameMarkup(this.node)) return false; this.node = node; if (this.innerView) { - let state = this.innerView.state; - let start = node.content.findDiffStart(state.doc.content); + const state = this.innerView.state; + const start = node.content.findDiffStart(state.doc.content); if (start !== null) { let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); - let overlap = start - Math.min(endA, endB); + const overlap = start - Math.min(endA, endB); if (overlap > 0) { endA += overlap; endB += overlap; } this.innerView.dispatch( state.tr @@ -967,10 +967,10 @@ export class SummarizedView { className = (visible: boolean) => "formattedTextBox-summarizer" + (visible ? "" : "-collapsed"); updateSummarizedText(start?: any) { - let mark = this._view.state.schema.marks.highlight.create(); + const mark = this._view.state.schema.marks.highlight.create(); let endPos = start; - let visited = new Set(); + const visited = new Set(); for (let i: number = start + 1; i < this._view.state.doc.nodeSize - 1; i++) { let skip = false; this._view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => { @@ -999,7 +999,7 @@ export const schema = new Schema({ nodes, marks }); const fromJson = schema.nodeFromJSON; schema.nodeFromJSON = (json: any) => { - let node = fromJson(json); + const node = fromJson(json); if (json.type === "star") { node.attrs.text = Slice.fromJSON(schema, node.attrs.textslice); } diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index ff4451824..0fa96963e 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -94,16 +94,16 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an return { compiled: false, errors: diagnostics }; } - let paramNames = Object.keys(scriptingGlobals); - let params = paramNames.map(key => scriptingGlobals[key]); + const paramNames = Object.keys(scriptingGlobals); + const params = paramNames.map(key => scriptingGlobals[key]); // let fieldTypes = [Doc, ImageField, PdfField, VideoField, AudioField, List, RichTextField, ScriptField, ComputedField, CompileScript]; // let paramNames = ["Docs", ...fieldTypes.map(fn => fn.name)]; // let params: any[] = [Docs, ...fieldTypes]; - let compiledFunction = new Function(...paramNames, `return ${script}`); - let { capturedVariables = {} } = options; - let run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => { - let argsArray: any[] = []; - for (let name of customParams) { + const compiledFunction = new Function(...paramNames, `return ${script}`); + const { capturedVariables = {} } = options; + const run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => { + const argsArray: any[] = []; + for (const name of customParams) { if (name === "this") { continue; } @@ -113,7 +113,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an argsArray.push(capturedVariables[name]); } } - let thisParam = args.this || capturedVariables.this; + const thisParam = args.this || capturedVariables.this; let batch: { end(): void } | undefined = undefined; try { if (!options.editable) { @@ -146,7 +146,7 @@ class ScriptingCompilerHost { // getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): ts.SourceFile | undefined { getSourceFile(fileName: string, languageVersion: any, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): any | undefined { - let contents = this.readFile(fileName); + const contents = this.readFile(fileName); if (contents !== undefined) { return ts.createSourceFile(fileName, contents, languageVersion, true); } @@ -180,7 +180,7 @@ class ScriptingCompilerHost { return this.files.some(file => file.fileName === fileName); } readFile(fileName: string): string | undefined { - let file = this.files.find(file => file.fileName === fileName); + const file = this.files.find(file => file.fileName === fileName); if (file) { return file.content; } @@ -218,7 +218,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp if (options.globals) { Scripting.setScriptingGlobals(options.globals); } - let host = new ScriptingCompilerHost; + const host = new ScriptingCompilerHost; if (options.traverser) { const sourceFile = ts.createSourceFile('script.ts', script, ts.ScriptTarget.ES2015, true); const onEnter = typeof options.traverser === "object" ? options.traverser.onEnter : options.traverser; @@ -240,7 +240,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp script = printer.printFile(transformed[0]); result.dispose(); } - let paramNames: string[] = []; + const paramNames: string[] = []; if ("this" in params || "this" in capturedVariables) { paramNames.push("this"); } @@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp if (key === "this") continue; paramNames.push(key); } - let paramList = paramNames.map(key => { + const paramList = paramNames.map(key => { const val = params[key]; return `${key}: ${val}`; }); @@ -258,18 +258,18 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp paramNames.push(key); paramList.push(`${key}: ${typeof val === "object" ? Object.getPrototypeOf(val).constructor.name : typeof val}`); } - let paramString = paramList.join(", "); - let funcScript = `(function(${paramString})${requiredType ? `: ${requiredType}` : ''} { + const paramString = paramList.join(", "); + const funcScript = `(function(${paramString})${requiredType ? `: ${requiredType}` : ''} { ${addReturn ? `return ${script};` : script} })`; host.writeFile("file.ts", funcScript); if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); - let program = ts.createProgram(["file.ts"], {}, host); - let testResult = program.emit(); - let outputText = host.readFile("file.js"); + const program = ts.createProgram(["file.ts"], {}, host); + const testResult = program.emit(); + const outputText = host.readFile("file.js"); - let diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics); + const diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics); const result = Run(outputText, paramNames, diagnostics, script, options); diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 2cf13680a..7a9176bec 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -34,36 +34,36 @@ export namespace SearchUtil { export function Search(query: string, returnDocs: false, options?: SearchParams): Promise<IdSearchResult>; export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) { query = query || "*"; //If we just have a filter query, search for * as the query - let result: IdSearchResult = JSON.parse(await rp.get(Utils.prepend("/search"), { + const result: IdSearchResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: query }, })); if (!returnDocs) { return result; } - let { ids, numFound, highlighting } = result; + const { ids, highlighting } = result; - let txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), { + const txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), { qs: { ...options, q: query }, })); - let fileids = txtresult ? txtresult.ids : []; - let newIds: string[] = []; - let newLines: string[][] = []; + const fileids = txtresult ? txtresult.ids : []; + const newIds: string[] = []; + const newLines: string[][] = []; await Promise.all(fileids.map(async (tr: string, i: number) => { - let docQuery = "fileUpload_t:" + tr.substr(0, 7); //If we just have a filter query, search for * as the query - let docResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: docQuery } })); + const docQuery = "fileUpload_t:" + tr.substr(0, 7); //If we just have a filter query, search for * as the query + const docResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: docQuery } })); newIds.push(...docResult.ids); newLines.push(...docResult.ids.map((dr: any) => txtresult.lines[i])); })); - let theDocs: Doc[] = []; - let theLines: string[][] = []; + const theDocs: Doc[] = []; + const theLines: string[][] = []; const textDocMap = await DocServer.GetRefFields(newIds); const textDocs = newIds.map((id: string) => textDocMap[id]).map(doc => doc as Doc); for (let i = 0; i < textDocs.length; i++) { - let testDoc = textDocs[i]; + const testDoc = textDocs[i]; if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1) { theDocs.push(Doc.GetProto(testDoc)); theLines.push(newLines[i].map(line => line.replace(query, query.toUpperCase()))); @@ -73,7 +73,7 @@ export namespace SearchUtil { const docMap = await DocServer.GetRefFields(ids); const docs = ids.map((id: string) => docMap[id]).map(doc => doc as Doc); for (let i = 0; i < ids.length; i++) { - let testDoc = docs[i]; + const testDoc = docs[i]; if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && (options.allowAliases || theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1)) { theDocs.push(testDoc); theLines.push([]); diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index ff048f647..1f6b939d3 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -1,7 +1,6 @@ -import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr"; -import { Field, Doc } from "../../new_fields/Doc"; +import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from "serializr"; +import { Field } from "../../new_fields/Doc"; import { ClientUtils } from "./ClientUtils"; -import { emptyFunction } from "../../Utils"; let serializing = 0; export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) { @@ -65,8 +64,8 @@ export namespace SerializationHelper { } } -let serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void | Promise<any> } } = {}; -let reverseMap: { [ctor: string]: string } = {}; +const serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void | Promise<any> } } = {}; +const reverseMap: { [ctor: string]: string } = {}; export interface DeserializableOpts { (constructor: { new(...args: any[]): any }): void; diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index cc1d628b1..7496ac73c 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -9,7 +9,6 @@ import { Utils } from "../../Utils"; import "./SharingManager.scss"; import { Id } from "../../new_fields/FieldSymbols"; import { observer } from "mobx-react"; -import { MainView } from "../views/MainView"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { library } from '@fortawesome/fontawesome-svg-core'; import * as fa from '@fortawesome/free-solid-svg-icons'; @@ -103,10 +102,10 @@ export default class SharingManager extends React.Component<{}> { } populateUsers = async () => { - let userList = await RequestPromise.get(Utils.prepend("/getUsers")); + const userList = await RequestPromise.get(Utils.prepend("/getUsers")); const raw = JSON.parse(userList) as User[]; const evaluating = raw.map(async user => { - let isCandidate = user.email !== Doc.CurrentUserEmail; + const isCandidate = user.email !== Doc.CurrentUserEmail; if (isCandidate) { const userDocument = await DocServer.GetRefField(user.userDocumentId); if (userDocument instanceof Doc) { @@ -130,7 +129,7 @@ export default class SharingManager extends React.Component<{}> { if (state === SharingPermissions.None) { const metadata = (await DocCastAsync(manager[key])); if (metadata) { - let sharedAlias = (await DocCastAsync(metadata.sharedAlias))!; + const sharedAlias = (await DocCastAsync(metadata.sharedAlias))!; Doc.RemoveDocFromList(notificationDoc, storage, sharedAlias); manager[key] = undefined; } @@ -145,7 +144,7 @@ export default class SharingManager extends React.Component<{}> { } private setExternalSharing = (state: string) => { - let sharingDoc = this.sharingDoc; + const sharingDoc = this.sharingDoc; if (!sharingDoc) { return; } @@ -156,7 +155,7 @@ export default class SharingManager extends React.Component<{}> { if (!this.targetDoc) { return undefined; } - let baseUrl = Utils.prepend("/doc/" + this.targetDoc[Id]); + const baseUrl = Utils.prepend("/doc/" + this.targetDoc[Id]); return `${baseUrl}?sharing=true`; } @@ -178,7 +177,7 @@ export default class SharingManager extends React.Component<{}> { } private focusOn = (contents: string) => { - let title = this.targetDoc ? StrCast(this.targetDoc.title) : ""; + const title = this.targetDoc ? StrCast(this.targetDoc.title) : ""; return ( <span className={"focus-span"} diff --git a/src/client/util/TooltipLinkingMenu.tsx b/src/client/util/TooltipLinkingMenu.tsx index e6d6c471f..b46675a04 100644 --- a/src/client/util/TooltipLinkingMenu.tsx +++ b/src/client/util/TooltipLinkingMenu.tsx @@ -2,10 +2,6 @@ import { EditorState } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { FieldViewProps } from "../views/nodes/FieldView"; import "./TooltipTextMenu.scss"; -import React = require("react"); -const { toggleMark, setBlockType, wrapIn } = require("prosemirror-commands"); - -const SVG = "http://www.w3.org/2000/svg"; //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc. export class TooltipLinkingMenu { @@ -23,9 +19,9 @@ export class TooltipLinkingMenu { //add the div which is the tooltip view.dom.parentNode!.parentNode!.appendChild(this.tooltip); - let target = "https://www.google.com"; + const target = "https://www.google.com"; - let link = document.createElement("a"); + const link = document.createElement("a"); link.href = target; link.textContent = target; link.target = "_blank"; @@ -37,7 +33,7 @@ export class TooltipLinkingMenu { //updates the tooltip menu when the selection changes update(view: EditorView, lastState: EditorState | undefined) { - let state = view.state; + 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)) return; @@ -53,16 +49,16 @@ export class TooltipLinkingMenu { // Otherwise, reposition it and update its content this.tooltip.style.display = ""; - let { from, to } = state.selection; - let start = view.coordsAtPos(from), end = view.coordsAtPos(to); + const { from, to } = state.selection; + const start = view.coordsAtPos(from), end = view.coordsAtPos(to); // The box in which the tooltip is positioned, to use as base - let box = this.tooltip.offsetParent!.getBoundingClientRect(); + const box = this.tooltip.offsetParent!.getBoundingClientRect(); // Find a center-ish x position from the selection endpoints (when // crossing lines, end may be more to the left) - let left = Math.max((start.left + end.left) / 2, start.left + 3); + const left = Math.max((start.left + end.left) / 2, start.left + 3); this.tooltip.style.left = (left - box.left) * this.editorProps.ScreenToLocalTransform().Scale + "px"; - let width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale; - let mid = Math.min(start.left, end.left) + width; + const width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale; + const mid = Math.min(start.left, end.left) + width; this.tooltip.style.width = "auto"; this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px"; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 5136089b3..5e777cef9 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -2,7 +2,7 @@ import { action } from "mobx"; import { Dropdown, icons, MenuItem } from "prosemirror-menu"; //no import css import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos, Schema } from "prosemirror-model"; import { wrapInList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, TextSelection, Transaction } from "prosemirror-state"; +import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc, Field, Opt } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; @@ -86,7 +86,7 @@ export class TooltipTextMenu { this.basicTools.className = "basic-tools"; // init buttons to the tooltip -- paths to svgs are obtained from fontawesome - let items = [ + const items = [ { command: toggleMark(schema.marks.strong), dom: this.svgIcon("strong", "Bold", "M333.49 238a122 122 0 0 0 27-65.21C367.87 96.49 308 32 233.42 32H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h31.87v288H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h209.32c70.8 0 134.14-51.75 141-122.4 4.74-48.45-16.39-92.06-50.83-119.6zM145.66 112h87.76a48 48 0 0 1 0 96h-87.76zm87.76 288h-87.76V288h87.76a56 56 0 0 1 0 112z") }, { command: toggleMark(schema.marks.em), dom: this.svgIcon("em", "Italic", "M320 48v32a16 16 0 0 1-16 16h-62.76l-80 320H208a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h62.76l80-320H112a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16z") }, { command: toggleMark(schema.marks.underline), dom: this.svgIcon("underline", "Underline", "M32 64h32v160c0 88.22 71.78 160 160 160s160-71.78 160-160V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H272a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32v160a80 80 0 0 1-160 0V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm400 384H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z") }, @@ -145,7 +145,7 @@ export class TooltipTextMenu { // link menu this.updateLinkMenu(); - let dropdown = await this.createLinkDropdown(); + const dropdown = await this.createLinkDropdown(); this._linkDropdownDom = dropdown.render(this.view).dom; this.tooltip.appendChild(this._linkDropdownDom); @@ -209,17 +209,17 @@ export class TooltipTextMenu { // creates dragger element that allows dragging and collapsing (on double click) // of editor and appends it to the wrapper createDragger() { - let draggerWrapper = document.createElement("div"); + const draggerWrapper = document.createElement("div"); draggerWrapper.className = "dragger-wrapper"; - let dragger = document.createElement("div"); + const dragger = document.createElement("div"); dragger.className = "dragger"; - let line1 = document.createElement("span"); + const line1 = document.createElement("span"); line1.className = "dragger-line"; - let line2 = document.createElement("span"); + const line2 = document.createElement("span"); line2.className = "dragger-line"; - let line3 = document.createElement("span"); + const line3 = document.createElement("span"); line3.className = "dragger-line"; dragger.appendChild(line1); @@ -293,12 +293,12 @@ export class TooltipTextMenu { //label of dropdown will change to given label updateFontSizeDropdown(label: string) { //font SIZES - let fontSizeBtns: MenuItem[] = []; + const fontSizeBtns: MenuItem[] = []; this.fontSizes.forEach(mark => { fontSizeBtns.push(this.dropdownFontSizeBtn(String(mark.attrs.fontSize), "color: black; width: 50px;", mark, this.view, this.changeToFontSize)); }); - let newfontSizeDom = (new Dropdown(fontSizeBtns, { + const newfontSizeDom = (new Dropdown(fontSizeBtns, { label: label, css: "color:black; min-width: 60px;" }) as MenuItem).render(this.view).dom; @@ -312,12 +312,12 @@ export class TooltipTextMenu { //label of dropdown will change to given label updateFontStyleDropdown(label: string) { //font STYLES - let fontBtns: MenuItem[] = []; + const fontBtns: MenuItem[] = []; this.fontStyles.forEach((mark) => { fontBtns.push(this.dropdownFontFamilyBtn(mark.attrs.family, "color: black; font-family: " + mark.attrs.family + ", sans-serif; width: 125px;", mark, this.view, this.changeToFontFamily)); }); - let newfontStyleDom = (new Dropdown(fontBtns, { + const newfontStyleDom = (new Dropdown(fontBtns, { label: label, css: "color:black; width: 125px;" }) as MenuItem).render(this.view).dom; @@ -339,19 +339,19 @@ export class TooltipTextMenu { this.linkText.style.overflow = "hidden"; this.linkText.style.color = "white"; this.linkText.onpointerdown = (e: PointerEvent) => { e.stopPropagation(); }; - let linkBtn = document.createElement("div"); + const linkBtn = document.createElement("div"); linkBtn.textContent = ">>"; linkBtn.style.width = "10px"; linkBtn.style.height = "10px"; linkBtn.style.color = "white"; linkBtn.style.cssFloat = "left"; linkBtn.onpointerdown = (e: PointerEvent) => { - let node = this.view.state.selection.$from.nodeAfter; - let link = node && node.marks.find(m => m.type.name === "link"); + const node = this.view.state.selection.$from.nodeAfter; + const link = node && node.marks.find(m => m.type.name === "link"); if (link) { - let href: string = link.attrs.href; + const href: string = link.attrs.href; if (href.indexOf(Utils.prepend("/doc/")) === 0) { - let docid = href.replace(Utils.prepend("/doc/"), ""); + const docid = href.replace(Utils.prepend("/doc/"), ""); DocServer.GetRefField(docid).then(action((f: Opt<Field>) => { if (f instanceof Doc) { if (DocumentManager.Instance.getDocumentView(f)) { @@ -374,23 +374,23 @@ export class TooltipTextMenu { this.linkDrag.id = "link-drag"; this.linkDrag.onpointerdown = (e: PointerEvent) => { if (!this.editorProps) return; - let dragData = new DragManager.LinkDragData(this.editorProps.Document); + const dragData = new DragManager.LinkDragData(this.editorProps.Document); dragData.dontClearTextBox = true; // hack to get source context -sy - let docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document); + const docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document); e.stopPropagation(); - let ctrlKey = e.ctrlKey; + const ctrlKey = e.ctrlKey; DragManager.StartLinkDrag(this.linkDrag!, dragData, e.clientX, e.clientY, { handlers: { dragComplete: action(() => { if (dragData.linkDocument) { - let linkDoc = dragData.linkDocument; - let proto = Doc.GetProto(linkDoc); + const linkDoc = dragData.linkDocument; + const proto = Doc.GetProto(linkDoc); if (proto && docView) { proto.sourceContext = docView.props.ContainingCollectionDoc; } - let text = this.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), ctrlKey ? "onRight" : "inTab"); + const text = this.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), ctrlKey ? "onRight" : "inTab"); if (linkDoc instanceof Doc && linkDoc.anchor2 instanceof Doc) { proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODODO open to more descriptive descriptions of following in text link } @@ -406,8 +406,8 @@ export class TooltipTextMenu { this.tooltip.appendChild(this.linkEditor); } - let node = this.view.state.selection.$from.nodeAfter; - let link = node && node.marks.find(m => m.type.name === "link"); + const node = this.view.state.selection.$from.nodeAfter; + const link = node && node.marks.find(m => m.type.name === "link"); this.linkText.textContent = link ? link.attrs.href : "-empty-"; this.linkText.onkeydown = (e: KeyboardEvent) => { @@ -420,19 +420,19 @@ export class TooltipTextMenu { } async getTextLinkTargetTitle() { - let node = this.view.state.selection.$from.nodeAfter; - let link = node && node.marks.find(m => m.type.name === "link"); + const node = this.view.state.selection.$from.nodeAfter; + const link = node && node.marks.find(m => m.type.name === "link"); if (link) { - let href = link.attrs.href; + const href = link.attrs.href; if (href) { if (href.indexOf(Utils.prepend("/doc/")) === 0) { const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; if (linkclicked) { - let linkDoc = await DocServer.GetRefField(linkclicked); + const linkDoc = await DocServer.GetRefField(linkclicked); if (linkDoc instanceof Doc) { - let anchor1 = await Cast(linkDoc.anchor1, Doc); - let anchor2 = await Cast(linkDoc.anchor2, Doc); - let currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document; + const anchor1 = await Cast(linkDoc.anchor1, Doc); + const anchor2 = await Cast(linkDoc.anchor2, Doc); + const currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document; if (currentDoc && anchor1 && anchor2) { if (Doc.AreProtosEqual(currentDoc, anchor1)) { return StrCast(anchor2.title); @@ -453,18 +453,18 @@ export class TooltipTextMenu { } async createLinkDropdown() { - let targetTitle = await this.getTextLinkTargetTitle(); - let input = document.createElement("input"); + const targetTitle = await this.getTextLinkTargetTitle(); + const input = document.createElement("input"); // menu item for input for hyperlink url // TODO: integrate search to allow users to search for a doc to link to - let linkInfo = new MenuItem({ + const linkInfo = new MenuItem({ title: "", execEvent: "", class: "button-setting-disabled", css: "", render() { - let p = document.createElement("p"); + const p = document.createElement("p"); p.textContent = "Linked to:"; input.type = "text"; @@ -475,7 +475,7 @@ export class TooltipTextMenu { input.focus(); }; - let div = document.createElement("div"); + const div = document.createElement("div"); div.appendChild(p); div.appendChild(input); return div; @@ -487,13 +487,13 @@ export class TooltipTextMenu { }); // menu item to update/apply the hyperlink to the selected text - let linkApply = new MenuItem({ + const linkApply = new MenuItem({ title: "", execEvent: "", class: "", css: "", render() { - let button = document.createElement("button"); + const button = document.createElement("button"); button.className = "link-url-button"; button.textContent = "Apply hyperlink"; return button; @@ -507,17 +507,17 @@ export class TooltipTextMenu { // menu item to remove the link // TODO: allow this to be undoable - let self = this; - let deleteLink = new MenuItem({ + const self = this; + const deleteLink = new MenuItem({ title: "Delete link", execEvent: "", class: "separated-button", css: "", render() { - let button = document.createElement("button"); + const button = document.createElement("button"); button.textContent = "Remove link"; - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); wrapper.appendChild(button); return wrapper; }, @@ -525,15 +525,15 @@ export class TooltipTextMenu { async run() { self.deleteLink(); // update link dropdown - let dropdown = await self.createLinkDropdown(); - let newLinkDropdowndom = dropdown.render(self.view).dom; + const dropdown = await self.createLinkDropdown(); + const newLinkDropdowndom = dropdown.render(self.view).dom; self._linkDropdownDom && self.tooltip.replaceChild(newLinkDropdowndom, self._linkDropdownDom); self._linkDropdownDom = newLinkDropdowndom; } }); - let linkDropdown = new Dropdown(targetTitle ? [linkInfo, linkApply, deleteLink] : [linkInfo, linkApply], { class: "buttonSettings-dropdown" }) as MenuItem; + const linkDropdown = new Dropdown(targetTitle ? [linkInfo, linkApply, deleteLink] : [linkInfo, linkApply], { class: "buttonSettings-dropdown" }) as MenuItem; return linkDropdown; } @@ -542,10 +542,10 @@ export class TooltipTextMenu { // } makeLink = (targetDoc: Doc, title: string, location: string): string => { - let link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + targetDoc[Id]), title: title, location: location }); + const link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + targetDoc[Id]), title: title, location: location }); this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link). addMark(this.view.state.selection.from, this.view.state.selection.to, link)); - let node = this.view.state.selection.$from.nodeAfter; + const node = this.view.state.selection.$from.nodeAfter; if (node && node.text) { return node.text; } @@ -562,9 +562,9 @@ export class TooltipTextMenu { } deleteLink = () => { - let node = this.view.state.selection.$from.nodeAfter; - let link = node && node.marks.find(m => m.type === this.view.state.schema.marks.link); - let href = link!.attrs.href; + const node = this.view.state.selection.$from.nodeAfter; + const link = node && node.marks.find(m => m.type === this.view.state.schema.marks.link); + const href = link!.attrs.href; if (href) { if (href.indexOf(Utils.prepend("/doc/")) === 0) { const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; @@ -599,7 +599,7 @@ export class TooltipTextMenu { } createLink() { - let markType = schema.marks.link; + const markType = schema.marks.link; return new MenuItem({ title: "Add or remove link", label: "Add or remove link", @@ -613,8 +613,8 @@ export class TooltipTextMenu { let curLink = ""; if (this.markActive(state, markType)) { - let { from, $from, to, empty } = state.selection; - let node = state.doc.nodeAt(from); + const { from, $from, to, empty } = state.selection; + const node = state.doc.nodeAt(from); node && node.marks.map(m => { m.type === markType && (curLink = m.attrs.href); }); @@ -649,7 +649,7 @@ export class TooltipTextMenu { if (listTypeBtn) { this.tooltip.removeChild(listTypeBtn); } //Make a dropdown of all list types - let toAdd: MenuItem[] = []; + const toAdd: MenuItem[] = []; this.listTypeToIcon.forEach((icon, type) => { toAdd.push(this.dropdownNodeBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeToNodeType)); }); @@ -683,22 +683,22 @@ export class TooltipTextMenu { public static insertStar(state: EditorState<any>, dispatch: any) { if (state.selection.empty) return false; - let mark = state.schema.marks.highlight.create(); - let tr = state.tr; + const mark = state.schema.marks.highlight.create(); + const tr = state.tr; tr.addMark(state.selection.from, state.selection.to, mark); - let content = tr.selection.content(); - let newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() }); + const content = tr.selection.content(); + const newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() }); dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark)); return true; } public static insertComment(state: EditorState<any>, dispatch: any) { if (state.selection.empty) return false; - let mark = state.schema.marks.highlight.create(); - let tr = state.tr; + const mark = state.schema.marks.highlight.create(); + const tr = state.tr; tr.addMark(state.selection.from, state.selection.to, mark); - let content = tr.selection.content(); - let newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() }); + const content = tr.selection.content(); + const newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() }); dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark)); return true; } @@ -710,17 +710,17 @@ export class TooltipTextMenu { class: "menuicon", execEvent: "", render() { - let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", "-100 -100 650 650"); - let path = document.createElementNS('http://www.w3.org/2000/svg', "path"); + const path = document.createElementNS('http://www.w3.org/2000/svg', "path"); path.setAttributeNS(null, "d", "M0 479.98L99.92 512l35.45-35.45-67.04-67.04L0 479.98zm124.61-240.01a36.592 36.592 0 0 0-10.79 38.1l13.05 42.83-50.93 50.94 96.23 96.23 50.86-50.86 42.74 13.08c13.73 4.2 28.65-.01 38.15-10.78l35.55-41.64-173.34-173.34-41.52 35.44zm403.31-160.7l-63.2-63.2c-20.49-20.49-53.38-21.52-75.12-2.35L190.55 183.68l169.77 169.78L530.27 154.4c19.18-21.74 18.15-54.63-2.35-75.13z"); svg.appendChild(path); - let color = document.createElement("div"); + const color = document.createElement("div"); color.className = "buttonColor"; color.style.backgroundColor = TooltipTextMenuManager.Instance.highlight.toString(); - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); wrapper.id = "colorPicker"; wrapper.appendChild(svg); wrapper.appendChild(color); @@ -735,26 +735,26 @@ export class TooltipTextMenu { public static insertHighlight(color: String, state: EditorState<any>, dispatch: any) { if (state.selection.empty) return false; - let highlightMark = state.schema.mark(state.schema.marks.marker, { highlight: color }); + const highlightMark = state.schema.mark(state.schema.marks.marker, { highlight: color }); dispatch(state.tr.addMark(state.selection.from, state.selection.to, highlightMark)); } createHighlightDropdown() { // menu item for color picker - let self = this; - let colors = new MenuItem({ + const self = this; + const colors = new MenuItem({ title: "", execEvent: "", class: "button-setting-disabled", css: "", render() { - let p = document.createElement("p"); + const p = document.createElement("p"); p.textContent = "Change highlight:"; - let colorsWrapper = document.createElement("div"); + const colorsWrapper = document.createElement("div"); colorsWrapper.className = "colorPicker-wrapper"; - let colors = [ + const colors = [ PastelSchemaPalette.get("pink2"), PastelSchemaPalette.get("purple4"), PastelSchemaPalette.get("bluegreen1"), @@ -768,7 +768,7 @@ export class TooltipTextMenu { ]; colors.forEach(color => { - let button = document.createElement("button"); + const button = document.createElement("button"); button.className = color === TooltipTextMenuManager.Instance.highlight ? "colorPicker active" : "colorPicker"; if (color) { button.style.backgroundColor = color; @@ -779,8 +779,8 @@ export class TooltipTextMenu { TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlight, self.view.state, self.view.dispatch); // update color menu - let highlightDom = self.createHighlightTool().render(self.view).dom; - let highlightDropdownDom = self.createHighlightDropdown().render(self.view).dom; + const highlightDom = self.createHighlightTool().render(self.view).dom; + const highlightDropdownDom = self.createHighlightDropdown().render(self.view).dom; self.highlightDom && self.tooltip.replaceChild(highlightDom, self.highlightDom); self.highlightDropdownDom && self.tooltip.replaceChild(highlightDropdownDom, self.highlightDropdownDom); self.highlightDom = highlightDom; @@ -790,7 +790,7 @@ export class TooltipTextMenu { colorsWrapper.appendChild(button); }); - let div = document.createElement("div"); + const div = document.createElement("div"); div.appendChild(p); div.appendChild(colorsWrapper); return div; @@ -801,7 +801,7 @@ export class TooltipTextMenu { } }); - let colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem; + const colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem; return colorDropdown; } @@ -812,17 +812,17 @@ export class TooltipTextMenu { class: "menuicon", execEvent: "", render() { - let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", "-100 -100 650 650"); - let path = document.createElementNS('http://www.w3.org/2000/svg', "path"); + const path = document.createElementNS('http://www.w3.org/2000/svg', "path"); path.setAttributeNS(null, "d", "M204.3 5C104.9 24.4 24.8 104.3 5.2 203.4c-37 187 131.7 326.4 258.8 306.7 41.2-6.4 61.4-54.6 42.5-91.7-23.1-45.4 9.9-98.4 60.9-98.4h79.7c35.8 0 64.8-29.6 64.9-65.3C511.5 97.1 368.1-26.9 204.3 5zM96 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm32-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128-64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z"); svg.appendChild(path); - let color = document.createElement("div"); + const color = document.createElement("div"); color.className = "buttonColor"; color.style.backgroundColor = TooltipTextMenuManager.Instance.color.toString(); - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); wrapper.id = "colorPicker"; wrapper.appendChild(svg); wrapper.appendChild(color); @@ -837,26 +837,26 @@ export class TooltipTextMenu { public static insertColor(color: String, state: EditorState<any>, dispatch: any) { if (state.selection.empty) return false; - let colorMark = state.schema.mark(state.schema.marks.color, { color: color }); + const colorMark = state.schema.mark(state.schema.marks.color, { color: color }); dispatch(state.tr.addMark(state.selection.from, state.selection.to, colorMark)); } createColorDropdown() { // menu item for color picker - let self = this; - let colors = new MenuItem({ + const self = this; + const colors = new MenuItem({ title: "", execEvent: "", class: "button-setting-disabled", css: "", render() { - let p = document.createElement("p"); + const p = document.createElement("p"); p.textContent = "Change color:"; - let colorsWrapper = document.createElement("div"); + const colorsWrapper = document.createElement("div"); colorsWrapper.className = "colorPicker-wrapper"; - let colors = [ + const colors = [ DarkPastelSchemaPalette.get("pink2"), DarkPastelSchemaPalette.get("purple4"), DarkPastelSchemaPalette.get("bluegreen1"), @@ -870,7 +870,7 @@ export class TooltipTextMenu { ]; colors.forEach(color => { - let button = document.createElement("button"); + const button = document.createElement("button"); button.className = color === TooltipTextMenuManager.Instance.color ? "colorPicker active" : "colorPicker"; if (color) { button.style.backgroundColor = color; @@ -880,8 +880,8 @@ export class TooltipTextMenu { TooltipTextMenu.insertColor(TooltipTextMenuManager.Instance.color, self.view.state, self.view.dispatch); // update color menu - let colorDom = self.createColorTool().render(self.view).dom; - let colorDropdownDom = self.createColorDropdown().render(self.view).dom; + const colorDom = self.createColorTool().render(self.view).dom; + const colorDropdownDom = self.createColorDropdown().render(self.view).dom; self.colorDom && self.tooltip.replaceChild(colorDom, self.colorDom); self.colorDropdownDom && self.tooltip.replaceChild(colorDropdownDom, self.colorDropdownDom); self.colorDom = colorDom; @@ -891,7 +891,7 @@ export class TooltipTextMenu { colorsWrapper.appendChild(button); }); - let div = document.createElement("div"); + const div = document.createElement("div"); div.appendChild(p); div.appendChild(colorsWrapper); return div; @@ -902,7 +902,7 @@ export class TooltipTextMenu { } }); - let colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem; + const colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem; return colorDropdown; } @@ -911,7 +911,7 @@ export class TooltipTextMenu { height: 32, width: 32, path: "M30.828 1.172c-1.562-1.562-4.095-1.562-5.657 0l-5.379 5.379-3.793-3.793-4.243 4.243 3.326 3.326-14.754 14.754c-0.252 0.252-0.358 0.592-0.322 0.921h-0.008v5c0 0.552 0.448 1 1 1h5c0 0 0.083 0 0.125 0 0.288 0 0.576-0.11 0.795-0.329l14.754-14.754 3.326 3.326 4.243-4.243-3.793-3.793 5.379-5.379c1.562-1.562 1.562-4.095 0-5.657zM5.409 30h-3.409v-3.409l14.674-14.674 3.409 3.409-14.674 14.674z" }; - let self = this; + const self = this; return new MenuItem({ title: "Brush tool", label: "Brush tool", @@ -923,7 +923,7 @@ export class TooltipTextMenu { this.brush_function(state, dispatch); // update dropdown with marks - let newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom; + const newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom; self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom); self._brushDropdownDom = newBrushDropdowndom; }, @@ -947,7 +947,7 @@ export class TooltipTextMenu { } } else { - let { from, to, $from } = this.view.state.selection; + const { from, to, $from } = this.view.state.selection; if (this._brushdom) { if (!this.view.state.selection.empty && $from && $from.nodeAfter) { if (TooltipTextMenuManager.Instance._brushMarks && to - from > 0) { @@ -982,7 +982,7 @@ export class TooltipTextMenu { } - let brushInfo = new MenuItem({ + const brushInfo = new MenuItem({ title: "", label: label, execEvent: "", @@ -994,17 +994,17 @@ export class TooltipTextMenu { } }); - let self = this; - let clearBrush = new MenuItem({ + const self = this; + const clearBrush = new MenuItem({ title: "Clear brush", execEvent: "", class: "separated-button", css: "", render() { - let button = document.createElement("button"); + const button = document.createElement("button"); button.textContent = "Clear brush"; - let wrapper = document.createElement("div"); + const wrapper = document.createElement("div"); wrapper.appendChild(button); return wrapper; }, @@ -1015,24 +1015,24 @@ export class TooltipTextMenu { // update brush tool // TODO: this probably isn't very clean - let newBrushdom = self.createBrush().render(self.view).dom; + const newBrushdom = self.createBrush().render(self.view).dom; self._brushdom && self.tooltip.replaceChild(newBrushdom, self._brushdom); self._brushdom = newBrushdom; - let newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom; + const newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom; self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom); self._brushDropdownDom = newBrushDropdowndom; } }); - let hasMarks = TooltipTextMenuManager.Instance._brushMarks && TooltipTextMenuManager.Instance._brushMarks.size > 0; - let brushDom = new Dropdown(hasMarks ? [brushInfo, clearBrush] : [brushInfo], { class: "buttonSettings-dropdown" }) as MenuItem; + const hasMarks = TooltipTextMenuManager.Instance._brushMarks && TooltipTextMenuManager.Instance._brushMarks.size > 0; + const brushDom = new Dropdown(hasMarks ? [brushInfo, clearBrush] : [brushInfo], { class: "buttonSettings-dropdown" }) as MenuItem; return brushDom; } //for a specific grouping of marks (passed in), remove all and apply the passed-in one to the selected textchangeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => { changeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => { - let { $cursor, ranges } = view.state.selection as TextSelection; - let state = view.state; - let dispatch = view.dispatch; + const { $cursor, ranges } = view.state.selection as TextSelection; + const state = view.state; + const dispatch = view.dispatch; //remove all other active font marks fontMarks.forEach((type) => { @@ -1044,10 +1044,10 @@ export class TooltipTextMenu { } else { let has = false; for (let i = 0; !has && i < ranges.length; i++) { - let { $from, $to } = ranges[i]; + const { $from, $to } = ranges[i]; has = state.doc.rangeHasMark($from.pos, $to.pos, type); } - for (let i of ranges) { + for (const i of ranges) { if (has) { toggleMark(type)(view.state, view.dispatch, view); } @@ -1059,7 +1059,7 @@ export class TooltipTextMenu { if (markType) { //actually apply font if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) { - let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, + const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: markType.name, setFontSize: Number(markType.name.replace(/p/, "")) }), view.state.schema); view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from)))); } @@ -1068,9 +1068,9 @@ export class TooltipTextMenu { } changeToFontFamily = (mark: Mark, view: EditorView) => { - let { $cursor, ranges } = view.state.selection as TextSelection; - let state = view.state; - let dispatch = view.dispatch; + const { $cursor, ranges } = view.state.selection as TextSelection; + const state = view.state; + const dispatch = view.dispatch; //remove all other active font marks if ($cursor) { @@ -1080,28 +1080,28 @@ export class TooltipTextMenu { } else { let has = false; for (let i = 0; !has && i < ranges.length; i++) { - let { $from, $to } = ranges[i]; + const { $from, $to } = ranges[i]; has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontFamily); } - for (let i of ranges) { + for (const i of ranges) { if (has) { toggleMark(view.state.schema.marks.pFontFamily)(view.state, view.dispatch, view); } } } - let fontName = mark.attrs.family; + const fontName = mark.attrs.family; if (fontName) { this.updateFontStyleDropdown(fontName); } if (this.editorProps) { - let ruleProvider = this.editorProps.ruleProvider; - let heading = NumCast(this.editorProps.Document.heading); + const ruleProvider = this.editorProps.ruleProvider; + const heading = NumCast(this.editorProps.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleFont_" + heading] = fontName; } } //actually apply font if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) { - let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, + const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: fontName }), view.state.schema); view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from)))); } @@ -1110,9 +1110,9 @@ export class TooltipTextMenu { } changeToFontSize = (mark: Mark, view: EditorView) => { - let { $cursor, ranges } = view.state.selection as TextSelection; - let state = view.state; - let dispatch = view.dispatch; + const { $cursor, ranges } = view.state.selection as TextSelection; + const state = view.state; + const dispatch = view.dispatch; //remove all other active font marks if ($cursor) { @@ -1122,28 +1122,28 @@ export class TooltipTextMenu { } else { let has = false; for (let i = 0; !has && i < ranges.length; i++) { - let { $from, $to } = ranges[i]; + const { $from, $to } = ranges[i]; has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontSize); } - for (let i of ranges) { + for (const i of ranges) { if (has) { toggleMark(view.state.schema.marks.pFontSize)(view.state, view.dispatch, view); } } } - let size = mark.attrs.fontSize; + const size = mark.attrs.fontSize; if (size) { this.updateFontSizeDropdown(String(size) + " pt"); } if (this.editorProps) { - let ruleProvider = this.editorProps.ruleProvider; - let heading = NumCast(this.editorProps.Document.heading); + const ruleProvider = this.editorProps.ruleProvider; + const heading = NumCast(this.editorProps.Document.heading); if (ruleProvider && heading) { ruleProvider["ruleSize_" + heading] = size; } } //actually apply font if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) { - let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, + const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type, { ...(view.state.selection as NodeSelection).node.attrs, setFontSize: size }), view.state.schema); view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from)))); } @@ -1154,20 +1154,20 @@ export class TooltipTextMenu { //remove all node typeand apply the passed-in one to the selected text changeToNodeType = (nodeType: NodeType | undefined) => { //remove oldif (nodeType) { //add new - let view = this.view; + const view = this.view; if (nodeType === schema.nodes.bullet_list) { wrapInList(nodeType)(view.state, view.dispatch); } else { - var marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks()); + const marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks()); if (!wrapInList(schema.nodes.ordered_list)(view.state, (tx2: any) => { - let tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle); + const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); view.dispatch(tx2); })) { - let tx2 = view.state.tr; - let tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle); + const tx2 = view.state.tr; + const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); @@ -1223,15 +1223,15 @@ export class TooltipTextMenu { }); } - markActive = function(state: EditorState<any>, type: MarkType<Schema<string, string>>) { - let { from, $from, to, empty } = state.selection; + markActive = function (state: EditorState<any>, type: MarkType<Schema<string, string>>) { + const { from, $from, to, empty } = state.selection; if (empty) return type.isInSet(state.storedMarks || $from.marks()); else return state.doc.rangeHasMark(from, to, type); }; // Helper function to create menu icons icon(text: string, name: string, title: string = name) { - let span = document.createElement("span"); + const span = document.createElement("span"); span.className = name + " menuicon"; span.title = title; span.textContent = text; @@ -1240,13 +1240,13 @@ export class TooltipTextMenu { } svgIcon(name: string, title: string = name, dpath: string) { - let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", "-100 -100 650 650"); - let path = document.createElementNS('http://www.w3.org/2000/svg', "path"); + const path = document.createElementNS('http://www.w3.org/2000/svg', "path"); path.setAttributeNS(null, "d", dpath); svg.appendChild(path); - let span = document.createElement("span"); + const span = document.createElement("span"); span.className = name + " menuicon"; span.title = title; span.appendChild(svg); @@ -1256,9 +1256,9 @@ export class TooltipTextMenu { //method for checking whether node can be inserted canInsert(state: EditorState, nodeType: NodeType<Schema<string, string>>) { - let $from = state.selection.$from; + const $from = state.selection.$from; for (let d = $from.depth; d >= 0; d--) { - let index = $from.index(d); + const index = $from.index(d); if ($from.node(d).canReplaceWith(index, index, nodeType)) return true; } return false; @@ -1267,13 +1267,13 @@ export class TooltipTextMenu { //adapted this method - use it to check if block has a tag (ie bulleting) blockActive(type: NodeType<Schema<string, string>>, state: EditorState) { - let attrs = {}; + const attrs = {}; if (state.selection instanceof NodeSelection) { const sel: NodeSelection = state.selection; - let $from = sel.$from; - let to = sel.to; - let node = sel.node; + const $from = sel.$from; + const to = sel.to; + const node = sel.node; if (node) { return node.hasMarkup(type, attrs); @@ -1292,10 +1292,10 @@ export class TooltipTextMenu { } getMarksInSelection(state: EditorState<any>) { - let found = new Set<Mark>(); - let { from, to } = state.selection as TextSelection; + const found = new Set<Mark>(); + const { from, to } = state.selection as TextSelection; state.doc.nodesBetween(from, to, (node) => { - let marks = node.marks; + const marks = node.marks; if (marks) { marks.forEach(m => { found.add(m); @@ -1306,7 +1306,7 @@ export class TooltipTextMenu { } reset_mark_doms() { - let iterator = this._marksToDoms.values(); + const iterator = this._marksToDoms.values(); let next = iterator.next(); while (!next.done) { next.value.style.color = "white"; @@ -1322,7 +1322,7 @@ export class TooltipTextMenu { return; } this.view = view; - let state = view.state; + const state = view.state; DocumentDecorations.Instance.showTextBar(); props && (this.editorProps = props); // Don't do anything if the document/selection didn't change @@ -1338,13 +1338,13 @@ export class TooltipTextMenu { } // update link dropdown - let linkDropdown = await this.createLinkDropdown(); - let newLinkDropdowndom = linkDropdown.render(this.view).dom; + const linkDropdown = await this.createLinkDropdown(); + const newLinkDropdowndom = linkDropdown.render(this.view).dom; this._linkDropdownDom && this.tooltip.replaceChild(newLinkDropdowndom, this._linkDropdownDom); this._linkDropdownDom = newLinkDropdowndom; //UPDATE FONT STYLE DROPDOWN - let activeStyles = this.activeFontFamilyOnSelection(); + const activeStyles = this.activeFontFamilyOnSelection(); if (activeStyles !== undefined) { if (activeStyles.length === 1) { console.log("updating font style dropdown", activeStyles[0]); @@ -1353,7 +1353,7 @@ export class TooltipTextMenu { } //UPDATE FONT SIZE DROPDOWN - let activeSizes = this.activeFontSizeOnSelection(); + const activeSizes = this.activeFontSizeOnSelection(); if (activeSizes !== undefined) { if (activeSizes.length === 1) { //if there's only one active font size activeSizes[0] && this.updateFontSizeDropdown(String(activeSizes[0]) + " pt"); @@ -1366,7 +1366,7 @@ export class TooltipTextMenu { this.reset_mark_doms(); this._activeMarks.forEach((mark) => { if (this._marksToDoms.has(mark)) { - let dom = this._marksToDoms.get(mark); + const dom = this._marksToDoms.get(mark); if (dom) dom.style.color = "greenyellow"; } }); @@ -1385,8 +1385,8 @@ export class TooltipTextMenu { //finds fontSize at start of selection activeFontSizeOnSelection() { //current selection - let state = this.view.state; - let activeSizes: number[] = []; + const state = this.view.state; + const activeSizes: number[] = []; const pos = this.view.state.selection.$from; const ref_node: ProsNode = this.reference_node(pos); if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) { @@ -1397,8 +1397,8 @@ export class TooltipTextMenu { //finds fontSize at start of selection activeFontFamilyOnSelection() { //current selection - let state = this.view.state; - let activeFamilies: string[] = []; + const state = this.view.state; + const activeFamilies: string[] = []; const pos = this.view.state.selection.$from; const ref_node: ProsNode = this.reference_node(pos); if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) { @@ -1409,15 +1409,15 @@ export class TooltipTextMenu { //finds all active marks on selection in given group activeMarksOnSelection(markGroup: MarkType[]) { //current selection - let { empty, ranges, $to } = this.view.state.selection as TextSelection; - let state = this.view.state; - let dispatch = this.view.dispatch; + const { empty, ranges, $to } = this.view.state.selection as TextSelection; + const state = this.view.state; + const dispatch = this.view.dispatch; let activeMarks: MarkType[]; if (!empty) { activeMarks = markGroup.filter(mark => { - let has = false; + const has = false; for (let i = 0; !has && i < ranges.length; i++) { - let { $from, $to } = ranges[i]; + const { $from, $to } = ranges[i]; return state.doc.rangeHasMark($from.pos, $to.pos, mark); } return false; @@ -1440,7 +1440,7 @@ export class TooltipTextMenu { if (mark_type === state.schema.marks.pFontSize) { return ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name); } - let mark = state.schema.mark(mark_type); + const mark = state.schema.mark(mark_type); return ref_node.marks.includes(mark); return false; }); diff --git a/src/client/util/TypedEvent.ts b/src/client/util/TypedEvent.ts index 532ba78eb..90fd299c1 100644 --- a/src/client/util/TypedEvent.ts +++ b/src/client/util/TypedEvent.ts @@ -1,40 +1,40 @@ export interface Listener<T> { - (event: T): any; + (event: T): any; } export interface Disposable { - dispose(): void; + dispose(): void; } /** passes through events as they happen. You will not get events from before you start listening */ export class TypedEvent<T> { - private listeners: Listener<T>[] = []; - private listenersOncer: Listener<T>[] = []; - - on = (listener: Listener<T>): Disposable => { - this.listeners.push(listener); - return { - dispose: () => this.off(listener) - }; - } - - once = (listener: Listener<T>): void => { - this.listenersOncer.push(listener); - } - - off = (listener: Listener<T>) => { - var callbackIndex = this.listeners.indexOf(listener); - if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1); - } - - emit = (event: T) => { - /** Update any general listeners */ - this.listeners.forEach((listener) => listener(event)); - - /** Clear the `once` queue */ - this.listenersOncer.forEach((listener) => listener(event)); - this.listenersOncer = []; - } - - pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e)); + private listeners: Listener<T>[] = []; + private listenersOncer: Listener<T>[] = []; + + on = (listener: Listener<T>): Disposable => { + this.listeners.push(listener); + return { + dispose: () => this.off(listener) + }; + } + + once = (listener: Listener<T>): void => { + this.listenersOncer.push(listener); + } + + off = (listener: Listener<T>) => { + const callbackIndex = this.listeners.indexOf(listener); + if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1); + } + + emit = (event: T) => { + /** Update any general listeners */ + this.listeners.forEach((listener) => listener(event)); + + /** Clear the `once` queue */ + this.listenersOncer.forEach((listener) => listener(event)); + this.listenersOncer = []; + } + + pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e)); }
\ No newline at end of file diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts index 472afac1d..314b52bf3 100644 --- a/src/client/util/UndoManager.ts +++ b/src/client/util/UndoManager.ts @@ -3,7 +3,7 @@ import 'source-map-support/register'; import { Without } from "../../Utils"; function getBatchName(target: any, key: string | symbol): string { - let keyName = key.toString(); + const keyName = key.toString(); if (target && target.constructor && target.constructor.name) { return `${target.constructor.name}.${keyName}`; } @@ -23,7 +23,7 @@ function propertyDecorator(target: any, key: string | symbol) { writable: true, configurable: true, value: function (...args: any[]) { - let batch = UndoManager.StartBatch(getBatchName(target, key)); + const batch = UndoManager.StartBatch(getBatchName(target, key)); try { return value.apply(this, args); } finally { @@ -40,7 +40,7 @@ export function undoBatch(fn: (...args: any[]) => any): (...args: any[]) => any; export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any { if (!key) { return function () { - let batch = UndoManager.StartBatch(""); + const batch = UndoManager.StartBatch(""); try { return target.apply(undefined, arguments); } finally { @@ -55,7 +55,7 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed const oldFunction = descriptor.value; descriptor.value = function (...args: any[]) { - let batch = UndoManager.StartBatch(getBatchName(target, key)); + const batch = UndoManager.StartBatch(getBatchName(target, key)); try { return oldFunction.apply(this, args); } finally { @@ -98,7 +98,7 @@ export namespace UndoManager { GetOpenBatches().forEach(batch => console.log(batch.batchName)); } - let openBatches: Batch[] = []; + const openBatches: Batch[] = []; export function GetOpenBatches(): Without<Batch, 'end'>[] { return openBatches; } @@ -146,7 +146,7 @@ export namespace UndoManager { //TODO Make this return the return value export function RunInBatch<T>(fn: () => T, batchName: string) { - let batch = StartBatch(batchName); + const batch = StartBatch(batchName); try { return runInAction(fn); } finally { @@ -159,7 +159,7 @@ export namespace UndoManager { return; } - let commands = undoStack.pop(); + const commands = undoStack.pop(); if (!commands) { return; } @@ -178,7 +178,7 @@ export namespace UndoManager { return; } - let commands = redoStack.pop(); + const commands = redoStack.pop(); if (!commands) { return; } |
