aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/RichTextSchema.tsx16
-rw-r--r--src/client/util/TooltipTextMenu.tsx40
-rw-r--r--src/client/views/GlobalKeyHandler.ts6
-rw-r--r--src/client/views/Main.scss11
-rw-r--r--src/client/views/MainView.tsx25
-rw-r--r--src/client/views/collections/CollectionViewChromes.scss2
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx93
-rw-r--r--src/client/views/collections/KeyRestrictionRow.tsx6
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss8
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx3
-rw-r--r--src/client/views/nodes/WebBox.scss62
-rw-r--r--src/client/views/nodes/WebBox.tsx82
12 files changed, 277 insertions, 77 deletions
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index ce9e29b26..6d2abfaa2 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -1,11 +1,6 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType, Slice, Mark, Node } from "prosemirror-model";
-import { joinUp, lift, setBlockType, toggleMark, wrapIn, selectNodeForward, deleteSelection } from 'prosemirror-commands';
-import { redo, undo } from 'prosemirror-history';
-import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list';
-import { EditorState, Transaction, NodeSelection, TextSelection, Selection, } from "prosemirror-state";
-import { EditorView, } from "prosemirror-view";
-import { View } from '@react-pdf/renderer';
+import { DOMOutputSpecArray, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model";
+import { bulletList, listItem, orderedList } from 'prosemirror-schema-list';
+import { TextSelection } from "prosemirror-state";
const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0];
@@ -110,6 +105,7 @@ export const nodes: { [index: string]: NodeSpec } = {
// }
// }]
},
+
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
// `alt`, and `href` attributes. The latter two default to the empty
// string.
@@ -188,6 +184,7 @@ export const nodes: { [index: string]: NodeSpec } = {
// parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }],
// toDOM() { return ulDOM }
},
+
//bullet_list: {
// content: 'list_item+',
// group: 'block',
@@ -199,7 +196,8 @@ export const nodes: { [index: string]: NodeSpec } = {
list_item: {
...listItem,
content: 'paragraph block*'
- }
+ },
+
};
const emDOM: DOMOutputSpecArray = ["em", 0];
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 783492d74..4672dd246 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -1,32 +1,25 @@
-import { action, observable, observe } from "mobx";
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faTag, faPlus, faCloudUploadAlt } from '@fortawesome/free-solid-svg-icons';
-import { Dropdown, MenuItem, icons, } from "prosemirror-menu"; //no import css
-import { EditorState, NodeSelection, TextSelection, Transaction } from "prosemirror-state";
-import { EditorView } from "prosemirror-view";
-import { schema } from "./RichTextSchema";
-import { Schema, NodeType, MarkType, Mark, ResolvedPos } from "prosemirror-model";
-import { Node as ProsNode } from "prosemirror-model";
-import "./TooltipTextMenu.scss";
-const { toggleMark, setBlockType } = require("prosemirror-commands");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { wrapInList, liftListItem, } from 'prosemirror-schema-list';
import { faListUl } from '@fortawesome/free-solid-svg-icons';
-import { FieldViewProps } from "../views/nodes/FieldView";
-const { openPrompt, TextField } = require("./ProsemirrorCopy/prompt.js");
-import { DragManager } from "./DragManager";
-import { Doc, Opt, Field } from "../../new_fields/Doc";
+import { action, observable } 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 { liftListItem, wrapInList } from 'prosemirror-schema-list';
+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";
+import { Utils } from "../../Utils";
import { DocServer } from "../DocServer";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
+import { FieldViewProps } from "../views/nodes/FieldView";
+import { FormattedTextBoxProps } from "../views/nodes/FormattedTextBox";
import { DocumentManager } from "./DocumentManager";
-import { Id } from "../../new_fields/FieldSymbols";
-import { FormattedTextBoxProps, FormattedTextBox } from "../views/nodes/FormattedTextBox";
-import { typeAlias } from "babel-types";
-import React, { Children } from "react";
-import ReactDOM from "react-dom";
-import { Utils } from "../../Utils";
+import { DragManager } from "./DragManager";
import { LinkManager } from "./LinkManager";
-import { bool } from "prop-types";
+import { schema } from "./RichTextSchema";
+import "./TooltipTextMenu.scss";
+const { toggleMark, setBlockType } = require("prosemirror-commands");
+const { openPrompt, TextField } = require("./ProsemirrorCopy/prompt.js");
//appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc.
export class TooltipTextMenu {
@@ -179,6 +172,7 @@ export class TooltipTextMenu {
this.listTypeToIcon = new Map();
this.listTypeToIcon.set(schema.nodes.bullet_list, ":");
this.listTypeToIcon.set(schema.nodes.ordered_list, "1)");
+ // this.listTypeToIcon.set(schema.nodes.bullet_list, "⬜");
this.listTypes = Array.from(this.listTypeToIcon.keys());
//custom tools
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index e773014e3..833bacedb 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -194,6 +194,12 @@ export default class KeyManager {
};
});
+ async printClipboard() {
+ let text: string = await navigator.clipboard.readText();
+ console.log(text)
+ console.log(document.activeElement)
+ }
+
private ctrl_shift = action((keyname: string) => {
let stopPropagation = true;
let preventDefault = true;
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index a0b4b2f16..bc0975c86 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -297,4 +297,15 @@ ul#add-options-list {
z-index: 999;
transition: 0.5s all ease;
pointer-events: none;
+}
+
+.webpage-input {
+ display: none;
+ height: 60px;
+ width: 600px;
+ position: absolute;
+
+ .url-input {
+ width: 80%;
+ }
} \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 00a9c0950..84fdf13a1 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,29 +1,33 @@
import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faPlay, faPause, faCaretUp, faLongArrowAltRight, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat, faBolt } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, configure, observable, runInAction, reaction, trace, autorun } from 'mobx';
+import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import "normalize.css";
import * as React from 'react';
import { SketchPicker } from 'react-color';
import Measure from 'react-measure';
-import { Doc, DocListCast, Opt, HeightSym } from '../../new_fields/Doc';
+import { Doc, DocListCast, HeightSym, Opt } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { InkTool } from '../../new_fields/InkField';
import { List } from '../../new_fields/List';
import { listSpec } from '../../new_fields/Schema';
-import { Cast, FieldValue, NumCast, BoolCast, StrCast } from '../../new_fields/Types';
+import { SchemaHeaderField } from '../../new_fields/SchemaHeaderField';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../new_fields/Types';
import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
import { RouteStore } from '../../server/RouteStore';
-import { emptyFunction, returnOne, returnTrue, Utils, returnEmptyString } from '../../Utils';
+import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils';
import { DocServer } from '../DocServer';
import { Docs } from '../documents/Documents';
+import { ClientUtils } from '../util/ClientUtils';
+import { DictationManager } from '../util/DictationManager';
import { SetupDrag } from '../util/DragManager';
import { HistoryUtil } from '../util/History';
import { Transform } from '../util/Transform';
import { UndoManager } from '../util/UndoManager';
import { CollectionBaseView } from './collections/CollectionBaseView';
import { CollectionDockingView } from './collections/CollectionDockingView';
+import { CollectionTreeView } from './collections/CollectionTreeView';
import { ContextMenu } from './ContextMenu';
import { DocumentDecorations } from './DocumentDecorations';
import KeyManager from './GlobalKeyHandler';
@@ -36,11 +40,6 @@ import PDFMenu from './pdf/PDFMenu';
import { PresentationView } from './presentationview/PresentationView';
import { PreviewCursor } from './PreviewCursor';
import { FilterBox } from './search/FilterBox';
-import { CollectionTreeView } from './collections/CollectionTreeView';
-import { ClientUtils } from '../util/ClientUtils';
-import { SearchBox } from './search/SearchBox';
-import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
-import { DictationManager } from '../util/DictationManager';
@observer
export class MainView extends React.Component {
@@ -437,7 +436,6 @@ export class MainView extends React.Component {
}
}
-
@observable private _colorPickerDisplay = false;
/* for the expandable add nodes menu. Not included with the miscbuttons because once it expands it expands the whole div with it, making canvas interactions limited. */
nodesMenu() {
@@ -449,6 +447,7 @@ export class MainView extends React.Component {
//let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" }));
// let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy" }));
let addColNode = action(() => Docs.Create.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
+ let addWebNode = action(() => Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" }));
let addDragboxNode = action(() => Docs.Create.DragboxDocument({ width: 40, height: 40, title: "drag collection" }));
let addImageNode = action(() => Docs.Create.ImageDocument(imgurl, { width: 200, title: "an image of a cat" }));
let addButtonDocument = action(() => Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" }));
@@ -458,6 +457,7 @@ export class MainView extends React.Component {
let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
[React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
+ [React.createRef<HTMLDivElement>(), "globe-asia", "Add Website", addWebNode],
[React.createRef<HTMLDivElement>(), "bolt", "Add Button", addButtonDocument],
// [React.createRef<HTMLDivElement>(), "clone", "Add Docking Frame", addDockingNode],
[React.createRef<HTMLDivElement>(), "cloud-upload-alt", "Import Directory", addImportCollectionNode],
@@ -481,8 +481,9 @@ export class MainView extends React.Component {
DocServer.setFieldWriteMode("viewType", mode2);
};
return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 20, bottom: 20 }} >
+
<input type="checkbox" id="add-menu-toggle" ref={this.addMenuToggle} />
- <label htmlFor="add-menu-toggle" style={{ marginTop: 2 }} title="Add Node"><p>+</p></label>
+ <label htmlFor="add-menu-toggle" style={{ marginTop: 2 }} title="Close Menu"><p>+</p></label>
<div id="add-options-content">
<ul id="add-options-list">
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index a13de6df5..595f079d1 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -105,7 +105,7 @@
.collectionViewBaseChrome-viewSpecsMenu-lastRow {
display: grid;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 1fr 1fr 1fr;
grid-gap: 10px;
margin: 10px;
}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 470085932..6ea718330 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -5,7 +5,7 @@ import { CollectionViewType } from "./CollectionBaseView";
import { undoBatch } from "../../util/UndoManager";
import { action, observable, runInAction, computed, IObservable, IObservableValue, reaction, autorun } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { Doc, DocListCast, FieldResult } from "../../../new_fields/Doc";
import { DocLike } from "../MetadataEntryMenu";
import * as Autosuggest from 'react-autosuggest';
import { EditableView } from "../EditableView";
@@ -23,6 +23,8 @@ import { Id } from "../../../new_fields/FieldSymbols";
import { threadId } from "worker_threads";
import { DragManager } from "../../util/DragManager";
const datepicker = require('js-datepicker');
+import * as $ from 'jquery';
+import { firebasedynamiclinks } from "googleapis/build/src/apis/firebasedynamiclinks";
interface CollectionViewChromeProps {
CollectionView: CollectionView;
@@ -30,10 +32,18 @@ interface CollectionViewChromeProps {
collapse?: (value: boolean) => any;
}
+interface Filter {
+ key: string;
+ value: string;
+ contains: boolean;
+}
+
let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
@observer
export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
+ //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\)
+
@observable private _viewSpecsOpen: boolean = false;
@observable private _dateWithinValue: string = "";
@observable private _dateValue: Date | string = "";
@@ -43,6 +53,43 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
private _picker: any;
private _datePickerElGuid = Utils.GenerateGuid();
+ getFilters = (script: string) => {
+ let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
+ let arr: any[] = re.exec(script);
+ let toReturn: Filter[] = [];
+ if (arr !== null) {
+ let filter: Filter = {
+ key: arr[2],
+ value: arr[3],
+ contains: (arr[1] === "!") ? false : true,
+ };
+ toReturn.push(filter);
+ script = script.replace(arr[0], "");
+ if (re.exec(script) !== null) {
+ toReturn.push(...this.getFilters(script));
+ }
+ else { return toReturn; }
+ }
+ return toReturn;
+ }
+
+ addKeyRestrictions = (fields: Filter[]) => {
+
+ if (fields.length !== 0) {
+ for (let i = 0; i < fields.length; i++) {
+ this._keyRestrictions.push([<KeyRestrictionRow field={fields[i].key} value={fields[i].value} key={Utils.GenerateGuid()} contains={fields[i].contains} script={(value: string) => runInAction(() => this._keyRestrictions[i][1] = value)} />, ""]);
+
+ }
+ if (this._keyRestrictions.length === 1) {
+ this._keyRestrictions.push([<KeyRestrictionRow field="" value="" key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]);
+ }
+ }
+ else {
+ this._keyRestrictions.push([<KeyRestrictionRow field="" value="" key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]);
+ this._keyRestrictions.push([<KeyRestrictionRow field="" value="" key={Utils.GenerateGuid()} contains={false} script={(value: string) => runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]);
+ }
+ }
+
componentDidMount = () => {
setTimeout(() => this._picker = datepicker("#" + this._datePickerElGuid, {
disabler: (date: Date) => date > new Date(),
@@ -50,10 +97,14 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
dateSelected: new Date()
}), 1000);
- runInAction(() => {
- this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]);
- this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={false} script={(value: string) => runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]);
+ let fields: Filter[] = [];
+ if (this.filterValue) {
+ let string = this.filterValue.script.originalScript;
+ fields = this.getFilters(string);
+ }
+ runInAction(() => {
+ this.addKeyRestrictions(fields);
// chrome status is one of disabled, collapsed, or visible. this determines initial state from document
let chromeStatus = this.props.CollectionView.props.Document.chromeStatus;
if (chromeStatus) {
@@ -112,17 +163,19 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
@action
addKeyRestriction = (e: React.MouseEvent) => {
let index = this._keyRestrictions.length;
- this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[index][1] = value)} />, ""]);
+ this._keyRestrictions.push([<KeyRestrictionRow field="" value="" key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[index][1] = value)} />, ""]);
this.openViewSpecs(e);
}
- @action
+ @action.bound
applyFilter = (e: React.MouseEvent) => {
+
this.openViewSpecs(e);
- let keyRestrictionScript = `${this._keyRestrictions.map(i => i[1])
- .reduce((acc: string, value: string, i: number) => value ? `${acc} && ${value}` : acc)}`;
+ console.log(this._keyRestrictions)
+
+ let keyRestrictionScript = "(" + this._keyRestrictions.map(i => i[1]).filter(i => i.length > 0).join(" && ") + ")";
let yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0;
let monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0;
let weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0;
@@ -142,9 +195,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
let fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ?
- `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} ${keyRestrictionScript}` :
- `return ${keyRestrictionScript} ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
+ `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` :
+ `return (${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
"return true";
+
let compiled = CompileScript(fullScript, { params: { doc: Doc.name }, typecheck: false });
if (compiled.compiled) {
this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
@@ -222,6 +276,17 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
})} />);
}
+ @action.bound
+ clearFilter = () => {
+ let compiled = CompileScript("return true", { params: { doc: Doc.name }, typecheck: false });
+ if (compiled.compiled) {
+ this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
+ }
+
+ this._keyRestrictions = [];
+ this.addKeyRestrictions([]);
+ }
+
private dropDisposer?: DragManager.DragDropDisposer;
protected createDropTarget = (ele: HTMLDivElement) => {
this.dropDisposer && this.dropDisposer();
@@ -273,9 +338,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
<div className="collectionViewBaseChrome-viewSpecs" style={{ display: collapsed ? "none" : "grid" }}>
<input className="collectionViewBaseChrome-viewSpecsInput"
placeholder="FILTER DOCUMENTS"
- value={this.filterValue ? this.filterValue.script.originalScript : ""}
+ value={this.filterValue ? this.filterValue.script.originalScript === "return true" ? "" : this.filterValue.script.originalScript : ""}
onChange={(e) => { }}
- onPointerDown={this.openViewSpecs} />
+ onPointerDown={this.openViewSpecs}
+ id="viewSpecsInput" />
{this.getPivotInput()}
<div className="collectionViewBaseChrome-viewSpecsMenu"
onPointerDown={this.openViewSpecs}
@@ -315,6 +381,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
<button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
APPLY FILTER
</button>
+ <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.clearFilter}>
+ CLEAR
+ </button>
</div>
</div>
</div>
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 1b59547d8..e35b7d7d3 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -7,12 +7,14 @@ import { Doc } from "../../../new_fields/Doc";
interface IKeyRestrictionProps {
contains: boolean;
script: (value: string) => void;
+ field: string;
+ value: string;
}
@observer
export default class KeyRestrictionRow extends React.Component<IKeyRestrictionProps> {
- @observable private _key = "";
- @observable private _value = "";
+ @observable private _key = this.props.field;
+ @observable private _value = this.props.value;
@observable private _contains = this.props.contains;
render() {
diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index d86aab09c..1b537cc52 100644
--- a/src/client/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
@@ -33,12 +33,12 @@
}
.formattedTextBox-inner-rounded {
- height: calc(90%);
- width: calc(85%);
+ height: 70%;
+ width: 85%;
position: absolute;
overflow: auto;
- top: 15;
- left: 20;
+ top: 15%;
+ left: 10%;
}
.formattedTextBox-inner-rounded div,
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 330bd135d..9d6c6861e 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -167,6 +167,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
FormattedTextBox._toolTipTextMenu && (FormattedTextBox._toolTipTextMenu.HackToFixTextSelectionGlitch = false);
if (state.selection.empty && FormattedTextBox._toolTipTextMenu) {
const marks = tx.storedMarks;
+ console.log(marks)
if (marks) { FormattedTextBox._toolTipTextMenu.mark_key_pressed(marks); }
}
this._applyingChange = true;
@@ -433,7 +434,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
dispatchTransaction: this.dispatchTransaction,
nodeViews: {
image(node, view, getPos) { return new ImageResizeView(node, view, getPos); },
- star(node, view, getPos) { return new SummarizedView(node, view, getPos); }
+ star(node, view, getPos) { return new SummarizedView(node, view, getPos); },
},
clipboardTextSerializer: this.clipboardTextSerializer,
handlePaste: this.handlePaste,
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index eb09b0693..07774263c 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -1,16 +1,18 @@
-
-.webBox-cont, .webBox-cont-interactive{
+.webBox-cont,
+.webBox-cont-interactive {
padding: 0vw;
position: absolute;
top: 0;
- left:0;
+ left: 0;
width: 100%;
height: 100%;
overflow: auto;
- pointer-events: none ;
+ pointer-events: none;
}
+
.webBox-cont-interactive {
pointer-events: all;
+
span {
user-select: text !important;
}
@@ -18,8 +20,8 @@
#webBox-htmlSpan {
position: absolute;
- top:0;
- left:0;
+ top: 0;
+ left: 0;
}
.webBox-overlay {
@@ -29,8 +31,52 @@
}
.webBox-button {
- padding : 0vw;
+ padding: 0vw;
border: none;
- width : 100%;
+ width: 100%;
+ height: 100%;
+}
+
+.webView-urlEditor {
+ position: relative;
+ opacity: 0.9;
+ z-index: 9001;
+ transition: top .5s;
+ background: lightgrey;
+ padding: 10px;
+
+
+ .urlEditor {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ padding-bottom: 10px;
+ overflow: hidden;
+
+ .editorBase {
+ display: flex;
+
+ .editor-collapse {
+ transition: all .5s, opacity 0.3s;
+ position: absolute;
+ width: 40px;
+ transform-origin: top left;
+ }
+ }
+
+ button:hover {
+ transform: scale(1);
+ }
+ }
+}
+
+.webpage-urlInput {
+ padding: 12px 10px 11px 10px;
+ border: 0px;
+ color: grey;
+ letter-spacing: 2px;
+ outline-color: black;
+ background: rgb(238, 238, 238);
+ width: 100%;
+ margin-right: 10px;
height: 100%;
} \ No newline at end of file
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c8749b7cd..9b66b2431 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,19 +1,25 @@
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
+import { FieldResult } from "../../../new_fields/Doc";
import { HtmlField } from "../../../new_fields/HtmlField";
+import { InkTool } from "../../../new_fields/InkField";
+import { Cast, NumCast } from "../../../new_fields/Types";
import { WebField } from "../../../new_fields/URLField";
+import { Utils } from "../../../Utils";
import { DocumentDecorations } from "../DocumentDecorations";
import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from './FieldView';
+import { KeyValueBox } from "./KeyValueBox";
import "./WebBox.scss";
import React = require("react");
-import { InkTool } from "../../../new_fields/InkField";
-import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
-import { Utils } from "../../../Utils";
@observer
export class WebBox extends React.Component<FieldViewProps> {
public static LayoutString() { return FieldView.LayoutString(WebBox); }
+ @observable private collapsed: boolean = true;
+ @observable private url: string = "";
componentWillMount() {
@@ -28,6 +34,71 @@ export class WebBox extends React.Component<FieldViewProps> {
this.props.Document.height = NumCast(this.props.Document.width) / youtubeaspect;
}
}
+
+ this.setURL();
+ }
+
+ @action
+ onURLChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.url = e.target.value;
+ }
+
+ @action
+ submitURL = () => {
+ const script = KeyValueBox.CompileKVPScript(`new WebField("${this.url}")`);
+ if (!script) return;
+ KeyValueBox.ApplyKVPScript(this.props.Document, "data", script);
+ }
+
+ @action
+ setURL() {
+ let urlField: FieldResult<WebField> = Cast(this.props.Document.data, WebField);
+ if (urlField) this.url = urlField.url.toString();
+ else this.url = "";
+ }
+
+ onValueKeyDown = async (e: React.KeyboardEvent) => {
+ if (e.key === "Enter") {
+ e.stopPropagation();
+ this.submitURL();
+ }
+ }
+
+ urlEditor() {
+ return (
+ <div className="webView-urlEditor" style={{ top: this.collapsed ? -70 : 0 }}>
+ <div className="urlEditor">
+ <div className="editorBase">
+ <button className="editor-collapse"
+ style={{
+ top: this.collapsed ? 70 : 10,
+ transform: `rotate(${this.collapsed ? 180 : 0}deg) scale(${this.collapsed ? 0.5 : 1}) translate(${this.collapsed ? "-100%, -100%" : "0, 0"})`,
+ opacity: (this.collapsed && !this.props.isSelected()) ? 0 : 0.9,
+ left: (this.collapsed ? 0 : "unset"),
+ }}
+ title="Collapse Url Editor" onClick={this.toggleCollapse}>
+ <FontAwesomeIcon icon="caret-up" size="2x" />
+ </button>
+ <div style={{ marginLeft: 54, width: "100%", display: this.collapsed ? "none" : "flex" }}>
+ <input className="webpage-urlInput"
+ placeholder="ENTER URL"
+ value={this.url}
+ onChange={this.onURLChange}
+ onKeyDown={this.onValueKeyDown}
+ />
+ <button className="submitUrl" onClick={this.submitURL}>
+ SUBMIT URL
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+
+ @action
+ toggleCollapse = () => {
+ this.collapsed = !this.collapsed;
}
_ignore = 0;
@@ -53,12 +124,13 @@ export class WebBox extends React.Component<FieldViewProps> {
if (field instanceof HtmlField) {
view = <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
} else if (field instanceof WebField) {
- view = <iframe src={Utils.CorsProxy(field.url.href)} style={{ position: "absolute", width: "100%", height: "100%" }} />;
+ view = <iframe src={Utils.CorsProxy(field.url.href)} style={{ position: "absolute", width: "100%", height: "100%", top: 0 }} />;
} else {
- view = <iframe src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%" }} />;
+ view = <iframe src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%", top: 0 }} />;
}
let content =
<div style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+ {this.urlEditor()}
{view}
</div>;