diff options
| author | eeng5 <eleanor.eng5@gmail.com> | 2019-11-19 17:47:13 -0500 |
|---|---|---|
| committer | eeng5 <eleanor.eng5@gmail.com> | 2019-11-19 17:47:13 -0500 |
| commit | 7d89d10a3d43755c267fd48e18701d457ae7aa1c (patch) | |
| tree | 059312d4d2dfeaa96b5e272abc7608b0d68b96b4 /src/new_fields | |
| parent | ab285371f6fb2a4f1e64888bafbc84b602f23416 (diff) | |
| parent | 667d196a2cbc8e237de5be9a6f7ec4ecca9d2bb5 (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into server_refactor
Diffstat (limited to 'src/new_fields')
| -rw-r--r-- | src/new_fields/Doc.ts | 166 | ||||
| -rw-r--r-- | src/new_fields/InkField.ts | 22 | ||||
| -rw-r--r-- | src/new_fields/RichTextField.ts | 10 | ||||
| -rw-r--r-- | src/new_fields/RichTextUtils.ts | 2 | ||||
| -rw-r--r-- | src/new_fields/SchemaHeaderField.ts | 11 | ||||
| -rw-r--r-- | src/new_fields/URLField.ts | 2 | ||||
| -rw-r--r-- | src/new_fields/documentSchemas.ts | 62 |
7 files changed, 177 insertions, 98 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 4bed113e3..bae7f6a91 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -378,8 +378,9 @@ export namespace Doc { else list.splice(before ? ind : ind + 1, 0, doc); } } + return true; } - return true; + return false; } // @@ -397,40 +398,6 @@ export namespace Doc { return bounds; } - // - // Resolves a reference to a field by returning 'doc' if no field extension is specified, - // otherwise, it returns the extension document stored in doc.<fieldKey>_ext. - // This mechanism allows any fields to be extended with an extension document that can - // be used to capture field-specific metadata. For example, an image field can be extended - // to store annotations, ink, and other data. - // - export function fieldExtensionDoc(doc: Doc, fieldKey: string, fieldExt: string = "yes") { - return fieldExt && doc[fieldKey + "_ext"] instanceof Doc ? doc[fieldKey + "_ext"] as Doc : doc; - } - - export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) { - let docExtensionForField = new Doc(doc[Id] + fieldKey, true); - docExtensionForField.title = fieldKey + ".ext"; - docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends. - docExtensionForField.type = DocumentType.EXTENSION; - let proto: Doc | undefined = doc; - while (proto && !Doc.IsPrototype(proto) && proto.proto) { - proto = proto.proto; - } - (proto ? proto : doc)[fieldKey + "_ext"] = new PrefetchProxy(docExtensionForField); - return docExtensionForField; - } - - export function UpdateDocumentExtensionForField(doc: Doc, fieldKey: string, immediate: boolean = false) { - let docExtensionForField = doc[fieldKey + "_ext"] as Doc; - if (docExtensionForField === undefined) { - if (immediate) CreateDocumentExtensionForField(doc, fieldKey); - else setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0); - } else if (doc instanceof Doc) { // backward compatibility -- add fields for docs that don't have them already - docExtensionForField.extendsDoc === undefined && setTimeout(() => docExtensionForField.extendsDoc = doc, 0); - docExtensionForField.type === undefined && setTimeout(() => docExtensionForField.type = DocumentType.EXTENSION, 0); - } - } export function MakeTitled(title: string) { let doc = new Doc(); doc.title = title; @@ -453,7 +420,7 @@ export namespace Doc { // for individual layout properties to be overridden in the expanded layout. // export function WillExpandTemplateLayout(layoutDoc: Doc, dataDoc?: Doc) { - return BoolCast(layoutDoc.isTemplate) && dataDoc && layoutDoc !== dataDoc && !(layoutDoc.layout instanceof Doc); + return BoolCast(layoutDoc.isTemplateField) && dataDoc && layoutDoc !== dataDoc && !(layoutDoc[StrCast(layoutDoc.layoutKey, "layout")] instanceof Doc); } // @@ -469,15 +436,8 @@ export namespace Doc { // ... which means we change the layout to be an expanded view of the template layout. // This allows the view override the template's properties and be referenceable as its own document. - let expandedTemplateLayout = dataDoc[templateLayoutDoc[Id]]; - if (expandedTemplateLayout instanceof Doc) { - return expandedTemplateLayout; - } - if (expandedTemplateLayout instanceof Promise) { - return undefined; - } let expandedLayoutFieldKey = "Layout[" + templateLayoutDoc[Id] + "]"; - expandedTemplateLayout = dataDoc[expandedLayoutFieldKey]; + let expandedTemplateLayout = dataDoc[expandedLayoutFieldKey]; if (expandedTemplateLayout instanceof Doc) { return expandedTemplateLayout; } @@ -490,15 +450,41 @@ export namespace Doc { export function GetLayoutDataDocPair(doc: Doc, dataDoc: Doc | undefined, fieldKey: string, childDocLayout: Doc) { let layoutDoc: Doc | undefined = childDocLayout; - let resolvedDataDoc = !doc.isTemplate && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined; + let resolvedDataDoc = !doc.isTemplateField && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined; if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) { - Doc.UpdateDocumentExtensionForField(resolvedDataDoc, fieldKey); - let fieldExtensionDoc = Doc.fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)), "dummy"); - layoutDoc = Doc.expandTemplateLayout(childDocLayout, fieldExtensionDoc !== resolvedDataDoc ? fieldExtensionDoc : undefined); - } else layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc); + let extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title))); + layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined); + } else layoutDoc = childDocLayout; return { layout: layoutDoc, data: resolvedDataDoc }; } + // + // Resolves a reference to a field by returning 'doc' if no field extension is specified, + // otherwise, it returns the extension document stored in doc.<fieldKey>_ext. + // This mechanism allows any fields to be extended with an extension document that can + // be used to capture field-specific metadata. For example, an image field can be extended + // to store annotations, ink, and other data. + // + export function fieldExtensionDoc(doc: Doc, fieldKey: string) { + let extension = doc[fieldKey + "_ext"] as Doc; + (extension === undefined) && setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0); + return extension ? extension : undefined; + } + + export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) { + let docExtensionForField = new Doc(doc[Id] + fieldKey, true); + docExtensionForField.title = fieldKey + ".ext"; // courtesy field--- shouldn't be needed except maybe for debugging + docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends. + docExtensionForField.extendsField = fieldKey; // this can be used by search to map matches on the extension doc back to the field that was extended. + docExtensionForField.type = DocumentType.EXTENSION; + let proto: Doc | undefined = doc; + while (proto && !Doc.IsPrototype(proto) && proto.proto) { + proto = proto.proto; + } + (proto ? proto : doc)[fieldKey + "_ext"] = new PrefetchProxy(docExtensionForField); + return docExtensionForField; + } + export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc { Object.keys(doc).forEach(key => { const field = ProxyField.WithoutProxy(() => doc[key]); @@ -525,6 +511,7 @@ export namespace Doc { export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string): Doc { const copy = new Doc(copyProtoId, true); Object.keys(doc).forEach(key => { + let cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); const field = ProxyField.WithoutProxy(() => doc[key]); if (key === "proto" && copyProto) { if (doc[key] instanceof Doc) { @@ -533,6 +520,8 @@ export namespace Doc { } 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) { copy[key] = ObjectField.MakeCopy(field); } else if (field instanceof Promise) { @@ -560,9 +549,14 @@ export namespace Doc { let _applyCount: number = 0; export function ApplyTemplate(templateDoc: Doc) { - return !templateDoc ? undefined : ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), templateDoc.title + "(..." + _applyCount++ + ")"); + if (templateDoc) { + let applied = ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), "layoutCustom", templateDoc.title + "(..." + _applyCount++ + ")"); + applied && (Doc.GetProto(applied).layout = applied.layout); + return applied; + } + return undefined; } - export function ApplyTemplateTo(templateDoc: Doc, target: Doc, titleTarget: string | undefined = undefined) { + export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined = undefined) { if (!templateDoc) { target.layout = undefined; target.nativeWidth = undefined; @@ -572,41 +566,28 @@ export namespace Doc { return; } - let layoutCustom = Doc.MakeTitled("layoutCustom"); let layoutCustomLayout = Doc.MakeDelegate(templateDoc); - titleTarget && (target.title = titleTarget); - target.type = DocumentType.TEMPLATE; - target.width = templateDoc.width; - target.height = templateDoc.height; - target.nativeWidth = templateDoc.nativeWidth ? templateDoc.nativeWidth : 0; - target.nativeHeight = templateDoc.nativeHeight ? templateDoc.nativeHeight : 0; - target.ignoreAspect = templateDoc.nativeWidth ? true : false; + titleTarget && (Doc.GetProto(target).title = titleTarget); + Doc.GetProto(target).type = DocumentType.TEMPLATE; target.onClick = templateDoc.onClick instanceof ObjectField && templateDoc.onClick[Copy](); - target.layout = layoutCustomLayout; - target.backgroundLayout = layoutCustomLayout.backgroundLayout; - target.layoutNative = Cast(templateDoc.layoutNative, Doc) as Doc; - target.layoutCustom = layoutCustom; + Doc.GetProto(target)[targetKey] = layoutCustomLayout; + target.layoutKey = targetKey; return target; } - export function MakeMetadataFieldTemplate(fieldTemplate: Doc, templateDataDoc: Doc, suppressTitle: boolean = false) { + export function MakeMetadataFieldTemplate(fieldTemplate: Doc, templateDataDoc: Doc, suppressTitle: boolean = false): boolean { // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??) let metadataFieldName = StrCast(fieldTemplate.title).replace(/^-/, ""); - let backgroundLayout = StrCast(fieldTemplate.backgroundLayout); let fieldLayoutDoc = fieldTemplate; if (fieldTemplate.layout instanceof Doc) { fieldLayoutDoc = Doc.MakeDelegate(fieldTemplate.layout); } - if (backgroundLayout) { - backgroundLayout = backgroundLayout.replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metadataFieldName}"}`); - } fieldTemplate.templateField = metadataFieldName; fieldTemplate.title = metadataFieldName; - fieldTemplate.isTemplate = true; - fieldTemplate.backgroundLayout = backgroundLayout; + fieldTemplate.isTemplateField = true; /* move certain layout properties from the original data doc to the template layout to avoid inheriting them from the template's data doc which may also define these fields for its own use. */ @@ -614,6 +595,7 @@ export namespace Doc { fieldTemplate.singleColumn = BoolCast(fieldTemplate.singleColumn); fieldTemplate.nativeWidth = Cast(fieldTemplate.nativeWidth, "number"); fieldTemplate.nativeHeight = Cast(fieldTemplate.nativeHeight, "number"); + fieldTemplate.type = fieldTemplate.type; fieldTemplate.panX = 0; fieldTemplate.panY = 0; fieldTemplate.scale = 1; @@ -622,24 +604,27 @@ export namespace Doc { setTimeout(action(() => { !templateDataDoc[metadataFieldName] && data instanceof ObjectField && (Doc.GetProto(templateDataDoc)[metadataFieldName] = ObjectField.MakeCopy(data)); let layout = StrCast(fieldLayoutDoc.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metadataFieldName}"}`); - let layoutDelegate = fieldTemplate.layout instanceof Doc ? fieldLayoutDoc : fieldTemplate; + let layoutDelegate = Doc.Layout(fieldTemplate); layoutDelegate.layout = layout; fieldTemplate.layout = layoutDelegate !== fieldTemplate ? layoutDelegate : layout; if (fieldTemplate.backgroundColor !== templateDataDoc.defaultBackgroundColor) fieldTemplate.defaultBackgroundColor = fieldTemplate.backgroundColor; fieldTemplate.proto = templateDataDoc; }), 0); + return true; } - export function overlapping(doc: Doc, doc2: Doc, clusterDistance: number) { + export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) { + let doc2Layout = Doc.Layout(doc2); + let doc1Layout = Doc.Layout(doc1); var x2 = NumCast(doc2.x) - clusterDistance; var y2 = NumCast(doc2.y) - clusterDistance; - var w2 = NumCast(doc2.width) + clusterDistance; - var h2 = NumCast(doc2.height) + clusterDistance; - var x = NumCast(doc.x) - clusterDistance; - var y = NumCast(doc.y) - clusterDistance; - var w = NumCast(doc.width) + clusterDistance; - var h = NumCast(doc.height) + clusterDistance; - return doc.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 }); + var w2 = NumCast(doc2Layout.width) + clusterDistance; + var h2 = NumCast(doc2Layout.height) + clusterDistance; + var x = NumCast(doc1.x) - clusterDistance; + var y = NumCast(doc1.y) - clusterDistance; + var w = NumCast(doc1Layout.width) + clusterDistance; + var h = NumCast(doc1Layout.height) + clusterDistance; + return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 }); } export function isBrushedHighlightedDegree(doc: Doc) { @@ -660,6 +645,11 @@ export namespace Doc { @observable _user_doc: Doc = undefined!; @observable BrushedDoc: ObservableMap<Doc, boolean> = new ObservableMap(); } + + // the document containing the view layout information - will be the Document itself unless the Document has + // a layout field. In that case, all layout information comes from there unless overriden by Document + export function Layout(doc: Doc) { return Doc.LayoutField(doc) instanceof Doc ? doc[StrCast(doc.layoutKey, "layout")] as Doc : doc; } + export function LayoutField(doc: Doc) { return doc[StrCast(doc.layoutKey, "layout")]; } const manager = new DocData(); export function UserDoc(): Doc { return manager._user_doc; } export function SetUserDoc(doc: Doc) { manager._user_doc = doc; } @@ -667,7 +657,7 @@ export namespace Doc { return brushManager.BrushedDoc.has(doc) || brushManager.BrushedDoc.has(Doc.GetDataDoc(doc)); } export function IsBrushedDegree(doc: Doc) { - return brushManager.BrushedDoc.has(Doc.GetDataDoc(doc)) ? 2 : brushManager.BrushedDoc.has(doc) ? 1 : 0; + return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetDataDoc(doc)) ? 1 : 0; } export function BrushDoc(doc: Doc) { brushManager.BrushedDoc.set(doc, true); @@ -680,6 +670,8 @@ export namespace Doc { return doc; } + + export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } export function linkFollowUnhighlight() { Doc.UnhighlightAll(); document.removeEventListener("pointerdown", linkFollowUnhighlight); @@ -725,15 +717,25 @@ export namespace Doc { } export function UnBrushAllDocs() { - manager.BrushedDoc.clear(); + brushManager.BrushedDoc.clear(); + } + + export function setChildLayout(target: Doc, source?: Doc) { + target.childLayout = source && source.isTemplateDoc ? source : source && + source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory : + source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined; } } + + Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; }); Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); }); +Scripting.addGlobal(function setChildLayout(target: any, source: any) { Doc.setChildLayout(target, source); }); Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); }); -Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return Doc.MakeCopy(doc, copyProto); }); +Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); }); Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); }); Scripting.addGlobal(function aliasDocs(field: any) { return new List<Doc>(field.map((d: any) => Doc.MakeAlias(d))); }); Scripting.addGlobal(function docList(field: any) { return DocListCast(field); }); +Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); }); Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); Scripting.addGlobal(function redo() { return UndoManager.Redo(); });
\ No newline at end of file diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts index e381d0218..2d8bb582a 100644 --- a/src/new_fields/InkField.ts +++ b/src/new_fields/InkField.ts @@ -8,18 +8,16 @@ export enum InkTool { None, Pen, Highlighter, - Eraser + Eraser, + Scrubber } -export interface StrokeData { - pathData: Array<{ x: number, y: number }>; - color: string; - width: string; - tool: InkTool; - displayTimecode: number; +export interface PointData { + x: number; + y: number; } -export type InkData = Map<string, StrokeData>; +export type InkData = Array<PointData>; const pointSchema = createSimpleSchema({ x: true, y: true @@ -32,16 +30,16 @@ const strokeDataSchema = createSimpleSchema({ @Deserializable("ink") export class InkField extends ObjectField { - @serializable(map(object(strokeDataSchema))) + @serializable(list(object(strokeDataSchema))) readonly inkData: InkData; - constructor(data?: InkData) { + constructor(data: InkData) { super(); - this.inkData = data || new Map; + this.inkData = data; } [Copy]() { - return new InkField(DeepCopy(this.inkData)); + return new InkField(this.inkData); } [ToScriptString]() { diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index d2f76c969..fd5459876 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -10,17 +10,21 @@ export class RichTextField extends ObjectField { @serializable(true) readonly Data: string; - constructor(data: string) { + @serializable(true) + readonly Text: string; + + constructor(data: string, text: string = "") { super(); this.Data = data; + this.Text = text; } [Copy]() { - return new RichTextField(this.Data); + return new RichTextField(this.Data, this.Text); } [ToScriptString]() { - return `new RichTextField("${this.Data}")`; + return `new RichTextField("${this.Data}", "${this.Text}")`; } }
\ No newline at end of file diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts index 238b27439..dc5574782 100644 --- a/src/new_fields/RichTextUtils.ts +++ b/src/new_fields/RichTextUtils.ts @@ -51,7 +51,7 @@ export namespace RichTextUtils { }; export const Synthesize = (plainText: string, oldState?: RichTextField) => { - return new RichTextField(ToProsemirrorState(plainText, oldState)); + return new RichTextField(ToProsemirrorState(plainText, oldState), plainText); }; export const ToPlainText = (state: EditorState) => { diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts index 92d0aec9a..42a8485ac 100644 --- a/src/new_fields/SchemaHeaderField.ts +++ b/src/new_fields/SchemaHeaderField.ts @@ -41,6 +41,17 @@ export const PastelSchemaPalette = new Map<string, string>([ export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * PastelSchemaPalette.size)]; +export const DarkPastelSchemaPalette = new Map<string, string>([ + ["pink2", "#c932b0"], + ["purple4", "#913ad6"], + ["bluegreen1", "#3978ed"], + ["bluegreen7", "#2adb3e"], + ["bluegreen5", "#21b0eb"], + ["yellow4", "#edcc0c"], + ["red2", "#eb3636"], + ["orange1", "#f2740f"], +]); + @scriptingGlobal @Deserializable("schemaheader") export class SchemaHeaderField extends ObjectField { diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts index b9ad96450..35ef6dd02 100644 --- a/src/new_fields/URLField.ts +++ b/src/new_fields/URLField.ts @@ -38,6 +38,8 @@ export abstract class URLField extends ObjectField { } } +export const nullAudio = "https://actions.google.com/sounds/v1/alarms/beep_short.ogg"; + @scriptingGlobal @Deserializable("audio") export class AudioField extends URLField { } @scriptingGlobal @Deserializable("image") export class ImageField extends URLField { } @scriptingGlobal @Deserializable("video") export class VideoField extends URLField { } diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts new file mode 100644 index 000000000..7592cdaa3 --- /dev/null +++ b/src/new_fields/documentSchemas.ts @@ -0,0 +1,62 @@ +import { makeInterface, createSchema, listSpec } from "./Schema"; +import { ScriptField } from "./ScriptField"; +import { Doc } from "./Doc"; +import { DateField } from "./DateField"; + +export const documentSchema = createSchema({ + layout: "string", // this is the native layout string for the document. templates can be added using other fields and setting layoutKey below (see layoutCustom as an example) + layoutKey: "string", // holds the field key for the field that actually holds the current lyoat + layoutCustom: Doc, // used to hold a custom layout (there's nothing special about this field .. any field could hold a custom layout that can be selected by setting 'layoutKey') + title: "string", // document title (can be on either data document or layout) + nativeWidth: "number", // native width of document which determines how much document contents are scaled when the document's width is set + nativeHeight: "number", // " + width: "number", // width of document in its container's coordinate system + height: "number", // " + color: "string", // foreground color of document + backgroundColor: "string", // background color of document + opacity: "number", // opacity of document + creationDate: DateField, // when the document was created + links: listSpec(Doc), // computed (readonly) list of links associated with this document + dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias" or "copy") + removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped + onClick: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop) + onDragStart: ScriptField, // script to run when document is dragged (without being selected). the script should return the Doc to be dropped. + dragFactory: Doc, // the document that serves as the "template" for the onDragStart script. ie, to drag out copies of the dragFactory document. + ignoreAspect: "boolean", // whether aspect ratio should be ignored when laying out or manipulating the document + autoHeight: "boolean", // whether the height of the document should be computed automatically based on its contents + isTemplateField: "boolean", // whether this document acts as a template layout for describing how other documents should be displayed + isBackground: "boolean", // whether document is a background element and ignores input events (can only selet with marquee) + type: "string", // enumerated type of document + currentTimecode: "number", // current play back time of a temporal document (video / audio) + summarizedDocs: listSpec(Doc), // documents that are summarized by this document (and which will typically be opened by clicking this document) + maximizedDocs: listSpec(Doc), // documents to maximize when clicking this document (generally this document will be an icon) + maximizeLocation: "string", // flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab) + lockedPosition: "boolean", // whether the document can be moved (dragged) + lockedTransform: "boolean", // whether the document can be panned/zoomed + inOverlay: "boolean", // whether the document is rendered in an OverlayView which handles selection/dragging differently + borderRounding: "string", // border radius rounding of document + searchFields: "string", // the search fields to display when this document matches a search in its metadata + heading: "number", // the logical layout 'heading' of this document (used by rule provider to stylize h1 header elements, from h2, etc) + showCaption: "string", // whether editable caption text is overlayed at the bottom of the document + showTitle: "string", // whether an editable title banner is displayed at tht top of the document + isButton: "boolean", // whether document functions as a button (overiding native interactions of its content) + ignoreClick: "boolean", // whether documents ignores input clicks (but does not ignore manipulation and other events) + isAnimating: "boolean", // whether the document is in the midst of animating between two layouts (used by icons to de/iconify documents). + animateToDimensions: listSpec("number"), // layout information about the target rectangle a document is animating towards + scrollToLinkID: "string", // id of link being traversed. allows this doc to scroll/highlight/etc its link anchor. scrollToLinkID should be set to undefined by this doc after it sets up its scroll,etc. + strokeWidth: "number", + fontSize: "string" +}); + +export const positionSchema = createSchema({ + zIndex: "number", + x: "number", + y: "number", + z: "number", +}); + +export type Document = makeInterface<[typeof documentSchema]>; +export const Document = makeInterface(documentSchema); + +export type PositionDocument = makeInterface<[typeof documentSchema, typeof positionSchema]>; +export const PositionDocument = makeInterface(documentSchema, positionSchema); |
