From 38a0f3f0b690599d72e52456ecfc14c081811e89 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 20 Apr 2020 19:05:05 -0400 Subject: fixed dragging off search result collection --- src/client/views/search/SearchBox.tsx | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'src/client/views/search') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 0947bff8d..f332104fc 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -167,15 +167,7 @@ export class SearchBox extends React.Component { } basicRequireWords(query: string): string { - const oldWords = query.split(" "); - const newWords: string[] = []; - oldWords.forEach(word => { - const newWrd = "+" + word; - newWords.push(newWrd); - }); - query = newWords.join(" "); - - return query; + return query.split(" ").join(" + ").replace(/ + /, ""); } @action @@ -316,10 +308,13 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = this.filterTypes; - const includeDeleted = this.getDataStatus() ? "" : " AND NOT deleted_b:true"; - const includeIcons = this.getDataStatus() ? "" : " AND NOT type_t:fonticonbox"; + const baseExpr = "NOT baseProto_b:true"; + const includeDeleted = this.getDataStatus() ? "" : " NOT deleted_b:true"; + const includeIcons = this.getDataStatus() ? "" : " NOT type_t:fonticonbox"; + const typeExpr = !types ? "" : ` (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})`; // fq: type_t:collection OR {!join from=id to=proto_i}type_t:collection q:text_t:hello - return "NOT baseProto_b:true" + includeDeleted + includeIcons + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); + const query = [baseExpr, includeDeleted, includeIcons, typeExpr].join(" AND ").replace(/AND $/, ""); + return query; } getDataStatus() { return this._deletedDocsStatus; } -- cgit v1.2.3-70-g09d2 From a9b6fba3a742f95815e2664770079bebd3b87d5f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 20 Apr 2020 22:34:29 -0400 Subject: fixed search to avoid server crashes by stripping off initial ?*+ characters. made search parameters persistent on queryBox --- src/client/documents/Documents.ts | 1 + src/client/util/SearchUtil.ts | 2 +- src/client/views/nodes/QueryBox.tsx | 13 +++++-- src/client/views/search/IconBar.tsx | 4 +-- src/client/views/search/SearchBox.tsx | 40 +++++++++++----------- src/server/ApiManagers/SearchManager.ts | 17 ++++----- .../authentication/models/current_user_utils.ts | 1 + 7 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/client/views/search') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e3cc8ccfe..5ff8f29ec 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -140,6 +140,7 @@ export interface DocumentOptions { icon?: string; sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script + searchFileTypes?: List; // file types allowed in a search query strokeWidth?: number; treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view treeViewHideTitle?: boolean; // whether to hide the title of a tree view diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 2026bf940..6501da34a 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -44,7 +44,7 @@ export namespace SearchUtil { const { ids, highlighting } = result; const txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), { - qs: { ...options, q: query }, + qs: { ...options, q: query.replace(/^[ \+\?\*\|]*/, "") }, // a leading '+' leads to a server crash since findInFiles doesn't handle regex failures })); const fileids = txtresult ? txtresult.ids : []; diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index 947167200..76885eada 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -3,13 +3,14 @@ import { IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from '../../../new_fields/FieldSymbols'; -import { makeInterface } from "../../../new_fields/Schema"; -import { StrCast } from "../../../new_fields/Types"; +import { makeInterface, listSpec } from "../../../new_fields/Schema"; +import { StrCast, Cast } from "../../../new_fields/Types"; import { SelectionManager } from "../../util/SelectionManager"; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./QueryBox.scss"; +import { List } from "../../../new_fields/List"; type QueryDocument = makeInterface<[typeof documentSchema]>; const QueryDocument = makeInterface(documentSchema); @@ -28,7 +29,13 @@ export class QueryBox extends ViewBoxAnnotatableComponent e.stopPropagation()} > - + this.dataDoc.searchQuery = q} + searchQuery={StrCast(this.dataDoc.searchQuery)} + setSearchFileTypes={q => this.dataDoc.searchFileTypes = new List(q)} + searchFileTypes={Cast(this.dataDoc.searchFileTypes, listSpec("string"), [])} + filterQquery={StrCast(this.dataDoc.filterQuery)} /> ; } } \ No newline at end of file diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx index 9cf5a9c87..9b7cf2fc6 100644 --- a/src/client/views/search/IconBar.tsx +++ b/src/client/views/search/IconBar.tsx @@ -25,7 +25,7 @@ library.add(faGlobeAsia); library.add(faBan); export interface IconBarProps { - setIcons: (icons: string[]) => {}; + setIcons: (icons: string[]) => void; } @@ -44,7 +44,7 @@ export class IconBar extends React.Component { @action.bound updateIcon(newArray: string[]) { - this._icons = newArray; + this._icons = newArray; this.props.setIcons?.(this._icons); } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index f332104fc..b0a49f750 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -19,13 +19,17 @@ import { FieldView } from '../nodes/FieldView'; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentView } from '../nodes/DocumentView'; import { SelectionManager } from '../../util/SelectionManager'; +import { listSpec } from '../../../new_fields/Schema'; library.add(faTimes); export interface SearchProps { id: string; - searchQuery?: string; + searchQuery: string; filterQquery?: string; + setSearchQuery: (q: string) => {}; + searchFileTypes: string[]; + setSearchFileTypes: (types: string[]) => {} } export enum Keys { @@ -37,7 +41,8 @@ export enum Keys { @observer export class SearchBox extends React.Component { - @observable private _searchString: string = ""; + private get _searchString() { return this.props.searchQuery; } + private set _searchString(value) { this.props.setSearchQuery(value); } @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; @observable private _results: [Doc, string[], string[]][] = []; @@ -72,20 +77,16 @@ export class SearchBox extends React.Component { this.resultsScrolled = this.resultsScrolled.bind(this); } - componentDidMount = () => { + componentDidMount = action(() => { if (this.inputRef.current) { this.inputRef.current.focus(); - runInAction(() => this._searchbarOpen = true); + this._searchbarOpen = true; } - if (this.props.searchQuery && this.props.filterQquery) { - console.log(this.props.searchQuery); - const sq = this.props.searchQuery; - runInAction(() => { - this._searchString = sq; - this.submitSearch(); - }); + if (this.props.searchQuery) { // bcz: why was this here? } && this.props.filterQquery) { + this._searchString = this.props.searchQuery; + this.submitSearch(); } - } + }) @action @@ -133,7 +134,10 @@ export class SearchBox extends React.Component { //this also serves as an indicator if the word status filter is applied @observable private _filterOpen: boolean = false; //if icons = all icons, then no icon filter is applied - @observable private _icons: string[] = this._allIcons; + get _icons() { return this.props.searchFileTypes; } + set _icons(value) { + this.props.setSearchFileTypes(value); + } //if all of these are true, no key filter is applied @observable private _titleFieldStatus: boolean = true; @observable private _authorFieldStatus: boolean = true; @@ -206,12 +210,6 @@ export class SearchBox extends React.Component { return this._icons.length === this._allIcons.length ? undefined : this._icons; } - @action.bound - updateIcon(newArray: string[]) { this._icons = newArray; } - - @action.bound - getIcons(): string[] { return this._icons; } - //TODO: basically all of this //gets all of the collections of all the docviews that are selected //if a collection is the only thing selected, search only in that collection (not its container) @@ -648,7 +646,9 @@ export class SearchBox extends React.Component {
- this._icons = icons} /> + { + this._icons = icons; + }} />
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts index 9e1cc120d..753c31fcf 100644 --- a/src/server/ApiManagers/SearchManager.ts +++ b/src/server/ApiManagers/SearchManager.ts @@ -45,16 +45,13 @@ export class SearchManager extends ApiManager { return; } const resObj: { ids: string[], numFound: number, lines: string[] } = { ids: [], numFound: 0, lines: [] }; - try { - const results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, pathToDirectory(Directory.text), ".txt$"); - for (const result in results) { - resObj.ids.push(path.basename(result, ".txt").replace(/upload_/, "")); - resObj.lines.push(results[result].line); - resObj.numFound++; - } - } - catch (e) { - console.error(e); + let results: any; + const dir = pathToDirectory(Directory.text); + results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, dir, ".txt$"); + for (const result in results) { + resObj.ids.push(path.basename(result, ".txt").replace(/upload_/, "")); + resObj.lines.push(results[result].line); + resObj.numFound++; } res.send(resObj); } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index e0ca5a468..3955f64fc 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -413,6 +413,7 @@ export class CurrentUserUtils { _width: 50, _height: 25, title: "Search", fontSize: 10, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc, + searchFileTypes: new List([DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.VID, DocumentType.WEB, DocumentType.SCRIPTING]), targetContainer: new PrefetchProxy(sidebarContainer) as any as Doc, lockedPosition: true, onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel") -- cgit v1.2.3-70-g09d2 From e091a465b860f0b205fbfa5ac6feedaf4f98e1dd Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 21 Apr 2020 01:15:17 -0400 Subject: added MakeClone to alias documents in a collection. fixed embedded custom templates. --- src/client/util/DragManager.ts | 2 +- src/client/util/RichTextSchema.tsx | 10 ++++---- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/search/SearchBox.scss | 3 ++- src/new_fields/Doc.ts | 43 +++++++++++++++++++++++++++++++-- 5 files changed, 50 insertions(+), 10 deletions(-) (limited to 'src/client/views/search') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 3ea030171..42a78a4bf 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -205,7 +205,7 @@ export namespace DragManager { e.docDragData && (e.docDragData.droppedDocuments = dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) : - dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d) + dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeClone(d) : d) ); e.docDragData?.droppedDocuments.forEach((drop: Doc, i: number) => (dragData?.removeDropProperties || []).concat(Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), [])).map(prop => drop[prop] = undefined) diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 0599b3ebe..1522f5e21 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -27,11 +27,11 @@ import ParagraphNodeSpec from "./ParagraphNodeSpec"; import { Transform } from "./Transform"; import React = require("react"); -const - blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], +const + blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], - preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], - brDOM: DOMOutputSpecArray = ["br"], + preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], + brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]; // :: Object @@ -853,7 +853,7 @@ export class DashDocView { this._renderDisposer?.(); this._renderDisposer = reaction(() => { if (!Doc.AreProtosEqual(finalLayout, dashDoc)) { - finalLayout.rootDocument = dashDoc.aliasOf; + finalLayout.rootDocument = dashDoc.aliasOf; // bcz: check on this ... why is it here? } const layoutKey = StrCast(finalLayout.layoutKey); const finalKey = layoutKey && StrCast(finalLayout[layoutKey]).split("'")?.[1]; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8a05cfb0d..286044ab2 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -561,7 +561,7 @@ export class DocumentView extends DocComponent(Docu static findTemplate(templateName: string, type: string, signature: string) { let docLayoutTemplate: Opt; const iconViews = DocListCast(Cast(Doc.UserDoc()["template-icons"], Doc, null)?.data); - const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data); + const templBtns = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data); const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data); const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data); const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index f0223ca76..bb62113a1 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -9,7 +9,8 @@ position: absolute; font-size: 10px; line-height: 1; - overflow: auto; + overflow-y: auto; + overflow-x: visible; background: lightgrey, } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 8e8f0928c..5f790f886 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -565,8 +565,9 @@ export namespace Doc { } else if (cfield instanceof ComputedField) { copy[key] = ComputedField.MakeFunction(cfield.script.originalScript); } else if (field instanceof ObjectField) { - copy[key] = key.includes("layout[") && doc[key] instanceof Doc ? Doc.MakeCopy(doc[key] as Doc, false) : - doc[key] instanceof Doc ? doc[key] : ObjectField.MakeCopy(field); + copy[key] = doc[key] instanceof Doc ? + key.includes("layout[") ? Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields + ObjectField.MakeCopy(field); } else if (field instanceof Promise) { debugger; //This shouldn't happend... } else { @@ -578,6 +579,44 @@ export namespace Doc { return copy; } + export function MakeClone(doc: Doc, cloneProto: boolean = true): Doc { + const copy = new Doc(undefined, true); + const exclude = Cast(doc.excludeFields, listSpec("string"), []); + Object.keys(doc).forEach(key => { + if (exclude.includes(key)) return; + const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); + const field = ProxyField.WithoutProxy(() => doc[key]); + if (key === "proto" && cloneProto) { + if (doc[key] instanceof Doc) { + copy[key] = Doc.MakeClone(doc[key]!, false); + } + } else { + if (field instanceof RefField) { + copy[key] = field; + } else if (cfield instanceof ComputedField) { + copy[key] = ComputedField.MakeFunction(cfield.script.originalScript); + } else if (field instanceof ObjectField) { + const list = Cast(doc[key], listSpec(Doc)); + if (list !== undefined && !(list instanceof Promise)) { + copy[key] = new List(list.filter(d => d instanceof Doc).map(d => Doc.MakeCopy(d as Doc, false))); + } else { + copy[key] = doc[key] instanceof Doc ? + key.includes("layout[") ? + Doc.MakeCopy(doc[key] as Doc, false) : doc[key] : // reference documents except copy documents that are expanded teplate fields + ObjectField.MakeCopy(field); + } + } else if (field instanceof Promise) { + debugger; //This shouldn't happend... + } else { + copy[key] = field; + } + } + }); + Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true); + copy.cloneOf = doc; + return copy; + } + export function MakeDelegate(doc: Doc, id?: string, title?: string): Doc; export function MakeDelegate(doc: Opt, id?: string, title?: string): Opt; export function MakeDelegate(doc: Opt, id?: string, title?: string): Opt { -- cgit v1.2.3-70-g09d2 From 682782a1337003de1694d1625d262a1efddcb02d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 21 Apr 2020 23:50:20 -0400 Subject: tweaked HTMLtag syntax slightly for onClick functions to be specified without quotes --- package-lock.json | 27 ++++++++++++++++++ package.json | 2 ++ .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - src/client/views/nodes/DocumentContentsView.tsx | 32 ++++++++++++++++------ src/client/views/search/SearchBox.tsx | 4 +-- 5 files changed, 54 insertions(+), 12 deletions(-) (limited to 'src/client/views/search') diff --git a/package-lock.json b/package-lock.json index 940321132..176d1f27e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,15 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/runtime-corejs3": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz", + "integrity": "sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA==", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, "@babel/types": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", @@ -1194,6 +1203,11 @@ "resolved": "https://registry.npmjs.org/@types/word-extractor/-/word-extractor-0.3.0.tgz", "integrity": "sha512-XcVsLXMpPT6Lv4Qvsc2yPoWg3zPVKEIyQ21eQ1ka58zZjtd7vUZ2kx0KydRbsNRNGopEIiwlemGzgo46dytR2Q==" }, + "@types/xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-3gJTS9gt27pS7U9q5IVqo4YvKSlkf2ck8ish6etuDj6LIRxkL/2Y8RMUtK/QzvE1Yv2zwWV5yemI2BS0GGGFnA==" + }, "@types/yargs": { "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", @@ -3456,6 +3470,11 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -18092,6 +18111,14 @@ "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-1.2.0.tgz", "integrity": "sha1-8u76wRRyyXHqO8RuVU60sSMhRuU=" }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index ed846fcff..f1b4be520 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,7 @@ "@types/uuid": "^3.4.6", "@types/webpack": "^4.41.3", "@types/word-extractor": "^0.3.0", + "@types/xregexp": "^4.3.0", "@types/youtube": "0.0.38", "adm-zip": "^0.4.13", "archiver": "^3.1.1", @@ -258,6 +259,7 @@ "word-extractor": "^0.3.0", "words-to-numbers": "^1.5.1", "xoauth2": "^1.2.0", + "xregexp": "^4.3.0", "youtube": "^0.1.0" } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d2106808e..3b5101a4d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -44,7 +44,6 @@ import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { CollectionViewType } from "../CollectionView"; -import { Script } from "vm"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index d577068b7..b5af68ba1 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -35,10 +35,10 @@ import { WebBox } from "./WebBox"; import { InkingStroke } from "../InkingStroke"; import React = require("react"); import { RecommendationsBox } from "../RecommendationsBox"; - import { TraceMobx } from "../../../new_fields/util"; import { ScriptField } from "../../../new_fields/ScriptField"; -import ReactTable from "react-table"; +import XRegExp = require("xregexp"); + const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without; @@ -59,13 +59,13 @@ const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any; interface HTMLtagProps { Document: Doc; htmltag: string; + onClick?: ScriptField; } -//" this.bannerColor=this.bannerColor==='red'?'green':'red'} width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)' backgroundColor='{this.bannerColor}'>{this.title}" -@observer +//"{this.title}"@observer export class HTMLtag extends React.Component { click = (e: React.MouseEvent) => { - const clickScript = (this.props as any).onClick; - ScriptField.MakeScript(clickScript, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }); + const clickScript = (this.props as any).onClick as Opt; + clickScript?.script.run({ this: this.props.Document }); } render() { const style: { [key: string]: any } = {}; @@ -129,11 +129,12 @@ export class DocumentContentsView extends React.Component): JsxBindings { const list = { ...OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit, Document: this.layoutDoc, DataDoc: this.dataDoc, + onClick: onClick }; return { props: list }; } @@ -141,6 +142,7 @@ export class DocumentContentsView extends React.Component{content}< as in {this.title} const replacer = (match: any, expr: string, offset: any, string: any) => { return ">" + (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }).result as string || "") + "<"; @@ -159,9 +161,21 @@ export class DocumentContentsView extends React.Component; + if (splits.length > 1) { + const code = XRegExp.matchRecursive(splits[1], "{", "}", "", { valueNames: ["between", "left", "match", "right", "between"] }); + layoutFrame = splits[0] + " onClick={props.onClick} " + splits[1].substring(code[1].end + 1); + onClick = ScriptField.MakeScript(code[1].value, { this: Doc.name, self: Doc.name }); + } + + const bindings = this.CreateBindings(onClick); + // layoutFrame = splits.length > 1 ? splits[0] + splits[1].replace(/{([^{}]|(?R))*}/, replacer4) : ""; // might have been more elegant if javascript supported recursive patterns + return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) : this.props.forceLayout === "FormattedTextBox" && this.props.forceFieldKey ? - + : {}; searchFileTypes: string[]; - setSearchFileTypes: (types: string[]) => {} + setSearchFileTypes: (types: string[]) => {}; } export enum Keys { @@ -86,7 +86,7 @@ export class SearchBox extends React.Component { this._searchString = this.props.searchQuery; this.submitSearch(); } - }) + }); @action -- cgit v1.2.3-70-g09d2