aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-12-11 17:00:58 -0500
committerBob Zeleznik <zzzman@gmail.com>2019-12-11 17:00:58 -0500
commit9d8845fb64c08729b446f12206aa5ed215228f4e (patch)
tree1506f2318c815449b283a36bcdd06d55965d929e
parentad079a088ae9262a4a40a2f0d2a2c5d948140492 (diff)
cleaned up toottipmenu and richtextschema a bit. fixed some problems with text styles. fixed warnings.
-rw-r--r--logs/npm-2-Wed, 11 Dec 2019 08:44:28 GMT.log274
-rw-r--r--logs/server_pids.txt1
-rw-r--r--src/client/util/ProsemirrorExampleTransfer.ts2
-rw-r--r--src/client/util/RichTextRules.ts162
-rw-r--r--src/client/util/RichTextSchema.tsx68
-rw-r--r--src/client/util/TooltipTextMenu.tsx414
-rw-r--r--src/client/views/DocumentDecorations.tsx4
-rw-r--r--src/client/views/EditableView.tsx2
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx32
12 files changed, 228 insertions, 741 deletions
diff --git a/logs/npm-2-Wed, 11 Dec 2019 08:44:28 GMT.log b/logs/npm-2-Wed, 11 Dec 2019 08:44:28 GMT.log
deleted file mode 100644
index 37e232d48..000000000
--- a/logs/npm-2-Wed, 11 Dec 2019 08:44:28 GMT.log
+++ /dev/null
@@ -1,274 +0,0 @@
-
-> dash@1.0.0 start-spawn /Users/swilkinss2012/Documents/GitHub/Dash-Web
-> cross-env SPAWNED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts
-
-Using ts-node version 7.0.1, typescript version 3.7.2
-objc[9678]: Class GNotificationCenterDelegate is implemented in both /Users/swilkinss2012/Documents/GitHub/Dash-Web/node_modules/sharp/vendor/lib/libgio-2.0.0.dylib (0x10838d578) and /Users/swilkinss2012/Documents/GitHub/Dash-Web/node_modules/canvas/build/Release/libgio-2.0.0.dylib (0x10afd9578). One of the two will be used. Which one is undefined.
-
-starting execution of preliminary functions...
-(node:9678) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
-completed preliminary functions
-.
-Starting type checking and linting service...
-Using 1 worker with 2048MB memory limit
-
-running server in development mode
-
-registering server routes...
-all server routes have been successfully registered:
-/
-/activity
-/buxton
-/delete
-/deleteAll
-/deleteWithAux
-/deleteWithGoogleCredentials
-/doc/:docId
-/downloadId/:docId
-/environment/:key
-/getCurrentUser
-/getUserDocumentId
-/getUsers
-/googleDocs/:sector/:action
-/googlePhotosMediaDownload
-/googlePhotosMediaUpload
-/home
-/imageHierarchyExport/:docId
-/inspectImage
-/persist
-/pull
-/readGoogleAccessToken
-/search
-/serializeDoc/:docId
-/serverHeartbeat
-/shutdown
-/solr/:action
-/textsearch
-/thumbnail/:filename
-/upload
-/uploadDoc
-/uploadURI
-/version
-/writeGoogleAccessToken
-
-websocket listening on port 4321
-server listening on port 1050
-
-ℹ 「wdm」: wait until bundle finished: /serverHeartbeat
-user samuel_wilkins@brown.edu has connected to the web socket
-user samuel_wilkins@brown.edu has connected to the web socket
-ℹ 「wdm」: wait until bundle finished: /serverHeartbeat
-ℹ 「wdm」: wait until bundle finished: /serverHeartbeat
-ℹ 「wdm」: wait until bundle finished: /serverHeartbeat
-ℹ 「wdm」: wait until bundle finished: /serverHeartbeat
-user samuel_wilkins@brown.edu has connected to the web socket
-user samuel_wilkins@brown.edu has connected to the web socket
-Type checking and linting in progress...
-webpack built 8f6b743d91fd3862683b in 47419ms
-⚠ 「wdm」: Hash: 8f6b743d91fd3862683b
-Version: webpack 4.36.1
-Time: 47419ms
-Built at: 12/11/2019 3:45:31 AM
- Asset Size Chunks  Chunk Names
-275711e56bd1bc79fdff544a3d7dbfae.png 289 bytes  [emitted]
-32f1593298e6e7bee5673bf647328d72.png 429 bytes  [emitted]
-718c914a99a2136c01c84e01f63e505a.png 829 bytes  [emitted]
-906f1a1816c2a03b5c7612f6aa2ceece.png 281 bytes  [emitted]
- assets/downarrow.png 3.28 KiB  [emitted]
- assets/env.json 360 bytes  [emitted]
- assets/google_photos.png 114 KiB  [emitted]
- assets/google_tags.png 7.9 KiB  [emitted]
- assets/loading.gif 112 KiB  [emitted]
- assets/pdf.worker.js 1.55 MiB  [emitted]
- bundle.js 20.8 MiB bundle [emitted] bundle
- bundle.js.map 23.3 MiB bundle [emitted] bundle
- debug/repl.html 348 bytes  [emitted]
- debug/test.html 245 bytes  [emitted]
- debug/viewer.html 357 bytes  [emitted]
-e7a34b49f3c49ca0c25c76b30cd09e12.png 445 bytes  [emitted]
- imageUpload.js 20.8 MiB imageUpload [emitted] imageUpload
- imageUpload.js.map 23.3 MiB imageUpload [emitted] imageUpload
- index.html 593 bytes  [emitted]
- inkControls.js 116 KiB inkControls [emitted] inkControls
- inkControls.js.map 122 KiB inkControls [emitted] inkControls
- mobile/image.html 333 bytes  [emitted]
- mobile/ink.html 252 bytes  [emitted]
- repl.js 9.31 MiB repl [emitted] repl
- repl.js.map 10.5 MiB repl [emitted] repl
- test.js 1.2 MiB test [emitted] test
- test.js.map 1.42 MiB test [emitted] test
- test.pdf 53.6 KiB  [emitted]
- vendors~pdfjsWorker.js 1.55 MiB vendors~pdfjsWorker [emitted] vendors~pdfjsWorker
- vendors~pdfjsWorker.js.map 1.87 MiB vendors~pdfjsWorker [emitted] vendors~pdfjsWorker
- viewer.js 9.47 MiB viewer [emitted] viewer
- viewer.js.map 10.7 MiB viewer [emitted] viewer
-Entrypoint bundle = bundle.js bundle.js.map
-Entrypoint viewer = viewer.js viewer.js.map
-Entrypoint repl = repl.js repl.js.map
-Entrypoint test = test.js test.js.map
-Entrypoint inkControls = inkControls.js inkControls.js.map
-Entrypoint imageUpload = imageUpload.js imageUpload.js.map
-[19] multi ./src/client/views/Main.tsx webpack-hot-middleware/client?reload=true 40 bytes {bundle} [built]
-[20] multi ./src/debug/Viewer.tsx webpack-hot-middleware/client?reload=true 40 bytes {viewer} [built]
-[21] multi ./src/debug/Repl.tsx webpack-hot-middleware/client?reload=true 40 bytes {repl} [built]
-[22] multi ./src/debug/Test.tsx webpack-hot-middleware/client?reload=true 40 bytes {test} [built]
-[23] multi ./src/mobile/InkControls.tsx webpack-hot-middleware/client?reload=true 40 bytes {inkControls} [built]
-[24] multi ./src/mobile/ImageUpload.tsx webpack-hot-middleware/client?reload=true 40 bytes {imageUpload} [built]
- [./node_modules/mobx-react/index.module.js] 48.8 KiB {bundle} {viewer} {repl} {imageUpload} [built]
- [./node_modules/mobx/lib/mobx.module.js] 175 KiB {bundle} {viewer} {repl} {imageUpload} [built]
- [./node_modules/webpack-hot-middleware/client.js?reload=true] (webpack)-hot-middleware/client.js?reload=true 7.68 KiB {bundle} {viewer} {repl} {test} {inkControls} {imageUpload} [built]
- [./src/client/views/Main.tsx] 4.03 KiB {bundle} [built]
- [./src/debug/Repl.tsx] 6.87 KiB {repl} [built]
- [./src/debug/Test.tsx] 1.02 KiB {test} [built]
- [./src/debug/Viewer.tsx] 12.1 KiB {viewer} [built]
- [./src/mobile/ImageUpload.tsx] 9.97 KiB {imageUpload} [built]
- [./src/mobile/InkControls.tsx] 14 bytes {inkControls} [built]
- + 1494 hidden modules
-
-WARNING in ./node_modules/typescript/lib/typescript.js 5121:41-60
-Critical dependency: the request of a dependency is an expression
- @ ./src/client/util/Scripting.ts
- @ ./src/debug/Viewer.tsx
- @ multi ./src/debug/Viewer.tsx webpack-hot-middleware/client?reload=true
-ℹ 「wdm」: Compiled with warnings.
-ℹ 「wdm」: Compiling...
-webpack building...
-ℹ 「wdm」: wait until bundle finished: /login
-ℹ 「wdm」: wait until bundle finished: /login
-ℹ 「wdm」: wait until bundle finished: /login
-ℹ 「wdm」: wait until bundle finished: /login
-ℹ 「wdm」: wait until bundle finished: /login
-Type checking and linting in progress...
-webpack built 8f6b743d91fd3862683b in 615ms
-⚠ 「wdm」: Hash: 8f6b743d91fd3862683b
-Version: webpack 4.36.1
-Time: 615ms
-Built at: 12/11/2019 3:45:33 AM
- Asset Size Chunks Chunk Names
-275711e56bd1bc79fdff544a3d7dbfae.png 289 bytes  
-32f1593298e6e7bee5673bf647328d72.png 429 bytes  
-718c914a99a2136c01c84e01f63e505a.png 829 bytes  
-906f1a1816c2a03b5c7612f6aa2ceece.png 281 bytes  
- bundle.js 20.8 MiB bundle bundle
- bundle.js.map 23.3 MiB bundle bundle
-e7a34b49f3c49ca0c25c76b30cd09e12.png 445 bytes  
- imageUpload.js 20.8 MiB imageUpload imageUpload
- imageUpload.js.map 23.3 MiB imageUpload imageUpload
- inkControls.js 116 KiB inkControls inkControls
- inkControls.js.map 122 KiB inkControls inkControls
- repl.js 9.31 MiB repl repl
- repl.js.map 10.5 MiB repl repl
- test.js 1.2 MiB test test
- test.js.map 1.42 MiB test test
- vendors~pdfjsWorker.js 1.55 MiB vendors~pdfjsWorker vendors~pdfjsWorker
- vendors~pdfjsWorker.js.map 1.87 MiB vendors~pdfjsWorker vendors~pdfjsWorker
- viewer.js 9.47 MiB viewer viewer
- viewer.js.map 10.7 MiB viewer viewer
-Entrypoint bundle = bundle.js bundle.js.map
-Entrypoint viewer = viewer.js viewer.js.map
-Entrypoint repl = repl.js repl.js.map
-Entrypoint test = test.js test.js.map
-Entrypoint inkControls = inkControls.js inkControls.js.map
-Entrypoint imageUpload = imageUpload.js imageUpload.js.map
-[19] multi ./src/client/views/Main.tsx webpack-hot-middleware/client?reload=true 40 bytes {bundle}
-[20] multi ./src/debug/Viewer.tsx webpack-hot-middleware/client?reload=true 40 bytes {viewer}
-[21] multi ./src/debug/Repl.tsx webpack-hot-middleware/client?reload=true 40 bytes {repl}
-[22] multi ./src/debug/Test.tsx webpack-hot-middleware/client?reload=true 40 bytes {test}
-[23] multi ./src/mobile/InkControls.tsx webpack-hot-middleware/client?reload=true 40 bytes {inkControls}
-[24] multi ./src/mobile/ImageUpload.tsx webpack-hot-middleware/client?reload=true 40 bytes {imageUpload}
- [./node_modules/mobx-react/index.module.js] 48.8 KiB {bundle} {viewer} {repl} {imageUpload}
- [./node_modules/mobx/lib/mobx.module.js] 175 KiB {bundle} {viewer} {repl} {imageUpload}
- [./node_modules/webpack-hot-middleware/client.js?reload=true] (webpack)-hot-middleware/client.js?reload=true 7.68 KiB {bundle} {viewer} {repl} {test} {inkControls} {imageUpload}
- [./src/client/views/Main.tsx] 4.03 KiB {bundle}
- [./src/debug/Repl.tsx] 6.87 KiB {repl}
- [./src/debug/Test.tsx] 1.02 KiB {test}
- [./src/debug/Viewer.tsx] 12.1 KiB {viewer}
- [./src/mobile/ImageUpload.tsx] 9.97 KiB {imageUpload}
- [./src/mobile/InkControls.tsx] 14 bytes {inkControls}
- + 1494 hidden modules
-
-WARNING in ./node_modules/typescript/lib/typescript.js 5121:41-60
-Critical dependency: the request of a dependency is an expression
- @ ./src/client/util/Scripting.ts
- @ ./src/debug/Viewer.tsx
- @ multi ./src/debug/Viewer.tsx webpack-hot-middleware/client?reload=true
-ℹ 「wdm」: Compiled with warnings.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(81,21):
-prefer-const: Identifier 'marks' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(83,25):
-prefer-const: Identifier 'tr' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(86,21):
-prefer-const: Identifier 'isValidColor' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(87,25):
-prefer-const: Identifier 's' is never reassigned; use 'const' instead of 'var'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(89,36):
-triple-equals: == should be ===
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(90,18):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(99,21):
-prefer-const: Identifier 'tr' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(100,21):
-prefer-const: Identifier 'marks' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(126,25):
-prefer-const: Identifier 'node' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(141,25):
-prefer-const: Identifier 'node' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(154,66):
-no-unnecessary-type-assertion: This assertion is unnecessary since it does not change the type of the expression.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(155,25):
-prefer-const: Identifier 'node' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(155,33):
-no-unnecessary-type-assertion: This assertion is unnecessary since it does not change the type of the expression.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(160,25):
-prefer-const: Identifier 'node' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextRules.ts(192,29):
-prefer-const: Identifier 'doc' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextSchema.tsx(640,134):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextSchema.tsx(649,21):
-prefer-const: Identifier 'expand' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextSchema.tsx(650,21):
-prefer-const: Identifier 'tr' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextSchema.tsx(654,138):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/util/RichTextSchema.tsx(658,10):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/collections/CollectionView.tsx(243,13):
-prefer-const: Identifier 'main' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/collections/CollectionView.tsx(244,13):
-prefer-const: Identifier 'next' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/collections/CollectionView.tsx(245,13):
-prefer-const: Identifier 'prev' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/DocumentDecorations.tsx(88,21):
-prefer-const: Identifier 'selectionTitleFieldKey' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/DocumentDecorations.tsx(95,8):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/EditableView.tsx(123,13):
-prefer-const: Identifier 'wasFocused' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/MainView.tsx(289,11):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/DocumentView.tsx(151,25):
-prefer-const: Identifier 'any' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(910,13):
-prefer-const: Identifier 'prosediv' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(911,13):
-prefer-const: Identifier 'keeplocation' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(913,13):
-prefer-const: Identifier 'pos' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(928,17):
-prefer-const: Identifier 'pcords' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(929,17):
-prefer-const: Identifier 'node' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(935,21):
-prefer-const: Identifier 'lastNode' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(976,71):
-semicolon: Missing semicolon
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(987,17):
-prefer-const: Identifier '$pos' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(1001,25):
-prefer-const: Identifier '$olist_pos' is never reassigned; use 'const' instead of 'let'.
-WARNING in /Users/swilkinss2012/Documents/GitHub/Dash-Web/src/client/views/nodes/FormattedTextBox.tsx(1103,17):
-prefer-const: Identifier 'newHeight' is never reassigned; use 'const' instead of 'let'.
-No type errors found
-Version: typescript 3.7.2, tslint 5.18.0
-Time: 5473ms
diff --git a/logs/server_pids.txt b/logs/server_pids.txt
deleted file mode 100644
index 2aa143f24..000000000
--- a/logs/server_pids.txt
+++ /dev/null
@@ -1 +0,0 @@
-9675 created at Wed, 11 Dec 2019 08:44:28 GMT
diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts
index f1fa6f11d..3324d8abe 100644
--- a/src/client/util/ProsemirrorExampleTransfer.ts
+++ b/src/client/util/ProsemirrorExampleTransfer.ts
@@ -105,7 +105,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
return true;
});
- bind("Mod-s", TooltipTextMenu.insertStar);
+ bind("Mod-s", TooltipTextMenu.insertSummarizer);
bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
const ref = state.selection;
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index 22b2a8204..364c85165 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -62,8 +62,9 @@ export const inpRules = {
}
),
+ // set the font size using #<font-size>
new InputRule(
- new RegExp(/^#([0-9]+)\s$/),
+ new RegExp(/^%([0-9]+)\s$/),
(state, match, start, end) => {
const size = Number(match[1]);
const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
@@ -74,131 +75,123 @@ export const inpRules = {
}
return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size }));
}),
+
+ // make current selection a hyperlink portal (assumes % was used to initiate an EnteringStyle mode)
+ new InputRule(
+ new RegExp(/@$/),
+ (state, match, start, end) => {
+ if (state.selection.to === state.selection.from || !(schema as any).EnteringStyle) return null;
+
+ const value = state.doc.textBetween(start, end);
+ if (value) {
+ DocServer.GetRefField(value).then(docx => {
+ const doc = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
+ DocUtils.Publish(doc, value, returnFalse, returnFalse);
+ });
+ const link = state.schema.marks.link.create({ href: Utils.prepend("/doc/" + value), location: "onRight", title: value });
+ return state.tr.addMark(start, end, link);
+ }
+ return state.tr;
+ }),
+
+ // activate a style by name using prefix '%'
new InputRule(
new RegExp(/%[a-z]+$/),
(state, match, start, end) => {
const color = match[0].substring(1, match[0].length);
- let marks = TooltipTextMenuManager.Instance._brushMap.get(color);
+ const marks = TooltipTextMenuManager.Instance._brushMap.get(color);
if (marks) {
- let tr = state.tr.deleteRange(start, end);
+ const tr = state.tr.deleteRange(start, end);
return marks ? Array.from(marks).reduce((tr, m) => tr.addStoredMark(m), tr) : tr;
}
- let isValidColor = (strColor: string) => {
- var s = new Option().style;
+ const isValidColor = (strColor: string) => {
+ const s = new Option().style;
s.color = strColor;
- return s.color == strColor.toLowerCase(); // 'false' if color wasn't assigned
- }
+ return s.color === strColor.toLowerCase(); // 'false' if color wasn't assigned
+ };
if (isValidColor(color)) {
return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontColor.create({ color: color }));
}
return null;
}),
+ // stop using active style
new InputRule(
new RegExp(/%%$/),
(state, match, start, end) => {
- let tr = state.tr.deleteRange(start, end);
- let marks = state.tr.selection.$anchor.nodeBefore?.marks;
+ const tr = state.tr.deleteRange(start, end);
+ const marks = state.tr.selection.$anchor.nodeBefore?.marks;
return marks ? Array.from(marks).filter(m => m !== state.schema.marks.user_mark).reduce((tr, m) => tr.removeStoredMark(m), tr) : tr;
}),
+
+ // set the Todo user-tag on the current selection (assumes % was used to initiate an EnteringStyle mode)
new InputRule(
- new RegExp(/t$/),
- (state, match, start, end) => {
- if (state.selection.to === state.selection.from && !(state as any).EnteringStyle) return null;
- const node = (state.doc.resolve(start) as any).nodeAfter;
- if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
- 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$/),
+ new RegExp(/[ti!x]$/),
(state, match, start, end) => {
- if (state.selection.to === state.selection.from && !(state as any).EnteringStyle) return null;
+ if (state.selection.to === state.selection.from || !(schema as any).EnteringStyle) return null;
+ const tag = match[0] === "t" ? "todo" : match[0] === "i" ? "ignore" : match[0] === "x" ? "disagree" : match[0] === "!" ? "important" : "??";
const node = (state.doc.resolve(start) as any).nodeAfter;
if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
- 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;
+ return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: tag, modified: Math.round(Date.now() / 1000 / 60) })) : state.tr;
}),
+
+ // set the First-line indent node type for the selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
new InputRule(
- new RegExp(/d$/),
+ new RegExp(/(%d|d)$/),
(state, match, start, end) => {
- if (state.selection.to === state.selection.from) return null;
+ if (!match[0].startsWith("%") && !(schema as any).EnteringStyle) return null;
const pos = (state.doc.resolve(start) as any);
- let depth = pos.path.length / 3 - 1;
- for (; depth >= 0; depth--) {
- let node = pos.node(depth);
+ for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+ const node = pos.node(depth);
if (node.type === schema.nodes.paragraph) {
const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === 25 ? undefined : 25 });
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
+ const result = replaced.setSelection(new TextSelection(replaced.doc.resolve(start)));
+ return match[0].startsWith("%") ? result.deleteRange(start, end) : result;
}
}
return null;
}),
+
+ // set the Hanging indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
new InputRule(
- new RegExp(/h$/),
+ new RegExp(/(%h|h)$/),
(state, match, start, end) => {
- if (state.selection.to === state.selection.from) return null;
+ if (!match[0].startsWith("%") && !(schema as any).EnteringStyle) return null;
const pos = (state.doc.resolve(start) as any);
- let depth = pos.path.length / 3 - 1;
- for (; depth >= 0; depth--) {
- let node = pos.node(depth);
+ for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+ const node = pos.node(depth);
if (node.type === schema.nodes.paragraph) {
const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === -25 ? undefined : -25 });
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
+ const result = replaced.setSelection(new TextSelection(replaced.doc.resolve(start)));
+ return match[0].startsWith("%") ? result.deleteRange(start, end) : result;
}
}
return null;
}),
+ // set the Quoted indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
new InputRule(
- new RegExp(/q$/),
+ new RegExp(/(%q|q)$/),
(state, match, start, end) => {
- if (state.selection.to === state.selection.from) return null;
+ if (!match[0].startsWith("%") && !(schema as any).EnteringStyle) return null;
const pos = (state.doc.resolve(start) as any);
- if (state.selection instanceof NodeSelection && (state.selection as NodeSelection).node.type === schema.nodes.ordered_list) {
- let node = (state.selection as NodeSelection).node;
+ if (state.selection instanceof NodeSelection && state.selection.node.type === schema.nodes.ordered_list) {
+ const node = state.selection.node;
return state.tr.setNodeMarkup(pos.pos, node.type, { ...node.attrs, indent: node.attrs.indent === 30 ? undefined : 30 });
}
- let depth = pos.path.length / 3 - 1;
- for (; depth >= 0; depth--) {
- let node = pos.node(depth);
+ for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+ const node = pos.node(depth);
if (node.type === schema.nodes.paragraph) {
const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, inset: node.attrs.inset === 30 ? undefined : 30 });
- return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
+ const result = replaced.setSelection(new TextSelection(replaced.doc.resolve(start)));
+ return match[0].startsWith("%") ? result.deleteRange(start, end) : result;
}
}
return null;
}),
- new InputRule(
- new RegExp(/!$/),
- (state, match, start, end) => {
- if (state.selection.to === state.selection.from && !(state as any).EnteringStyle) return null;
- const node = (state.doc.resolve(start) as any).nodeAfter;
- if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
- 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 && !(state as any).EnteringStyle) return null;
- const node = (state.doc.resolve(start) as any).nodeAfter;
- if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
- 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(/@$/),
- (state, match, start, end) => {
- if (state.selection.to === state.selection.from) return null;
- const value = state.doc.textBetween(start, end);
- if (value) {
- DocServer.GetRefField(value).then(docx => {
- let doc = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
- DocUtils.Publish(doc, value, returnFalse, returnFalse);
- });
- const link = state.schema.marks.link.create({ href: Utils.prepend("/doc/" + value), location: "onRight", title: value });
- return state.tr.addMark(start, end, link);
- }
- return state.tr;
- }),
+
+ // center justify text
new InputRule(
- new RegExp(/^\^\^\s$/),
+ new RegExp(/%\^$/),
(state, match, start, end) => {
const node = (state.doc.resolve(start) as any).nodeAfter;
const sm = state.storedMarks || undefined;
@@ -212,8 +205,9 @@ export const inpRules = {
state.tr;
return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
+ // left justify text
new InputRule(
- new RegExp(/^\[\[\s$/),
+ new RegExp(/%\[$/),
(state, match, start, end) => {
const node = (state.doc.resolve(start) as any).nodeAfter;
const sm = state.storedMarks || undefined;
@@ -227,8 +221,9 @@ export const inpRules = {
state.tr;
return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
+ // right justify text
new InputRule(
- new RegExp(/^\]\]\s$/),
+ new RegExp(/%\]$/),
(state, match, start, end) => {
const node = (state.doc.resolve(start) as any).nodeAfter;
const sm = state.storedMarks || undefined;
@@ -243,7 +238,7 @@ export const inpRules = {
return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
}),
new InputRule(
- new RegExp(/##\s$/),
+ new RegExp(/%#$/),
(state, match, start, end) => {
const target = Docs.Create.TextDocument({ width: 75, height: 35, backgroundColor: "yellow", autoHeight: true, fontSize: 9, title: "inline comment" });
const node = (state.doc.resolve(start) as any).nodeAfter;
@@ -255,26 +250,25 @@ export const inpRules = {
return replaced;//.setSelection(new NodeSelection(replaced.doc.resolve(end)));
}),
new InputRule(
- new RegExp(/\(\(/),
+ new RegExp(/%\(/),
(state, match, start, end) => {
const node = (state.doc.resolve(start) as any).nodeAfter;
const sm = state.storedMarks || undefined;
- const mark = state.schema.marks.highlight.create();
+ const mark = state.schema.marks.summarizeInclusive.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 : [])]) :
+ schema.nodes.summary.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)));
}),
new InputRule(
- new RegExp(/\)\)/),
+ new RegExp(/%\)/),
(state, match, start, end) => {
- const mark = state.schema.marks.highlight.create();
- return state.tr.removeStoredMark(mark);
+ return state.tr.removeStoredMark(state.schema.marks.summarizeInclusive.create());
}),
new InputRule(
- new RegExp(/\^f\s$/),
+ new RegExp(/%f\$/),
(state, match, start, end) => {
const newNode = schema.nodes.footnote.create({});
const tr = state.tr;
@@ -283,9 +277,5 @@ export const inpRules = {
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)
tr.selection.anchor - tr.selection.$anchor.nodeBefore!.nodeSize)));
}),
- // let newNode = schema.nodes.footnote.create({});
- // if (dispatch && state.selection.from === state.selection.to) {
- // return true;
- // }
]
};
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index f9251fb7e..543f45731 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -109,7 +109,7 @@ export const nodes: { [index: string]: NodeSpec } = {
},
},
- star: {
+ summary: {
inline: true,
attrs: {
visibility: { default: false },
@@ -121,15 +121,6 @@ export const nodes: { [index: string]: NodeSpec } = {
const attrs = { style: `width: 40px` };
return ["span", { ...node.attrs, ...attrs }];
},
- // parseDOM: [{
- // tag: "star", getAttrs(dom: any) {
- // return {
- // visibility: dom.getAttribute("visibility"),
- // oldtext: dom.getAttribute("oldtext"),
- // oldtextlen: dom.getAttribute("oldtextlen"),
- // }
- // }
- // }]
},
// :: NodeSpec An inline image (`<img>`) node. Supports `src`,
@@ -228,6 +219,7 @@ export const nodes: { [index: string]: NodeSpec } = {
mapStyle: { default: "decimal" },
setFontSize: { default: undefined },
setFontFamily: { default: "inherit" },
+ setFontColor: { default: "inherit" },
inheritedFontSize: { default: undefined },
visibility: { default: true },
indent: { default: undefined }
@@ -237,8 +229,10 @@ export const nodes: { [index: string]: NodeSpec } = {
const map = node.attrs.bulletStyle ? node.attrs.mapStyle + node.attrs.bulletStyle : "";
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}; margin-left: ${node.attrs.indent}` }, 0] :
- ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}` }];
+ const color = node.attrs.setFontColor;
+ return node.attrs.visibility ?
+ ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}; color:${color}; margin-left: ${node.attrs.indent}` }, 0] :
+ ['ol', { class: `${map}-ol`, style: `list-style: none;` }];
}
},
@@ -318,7 +312,7 @@ export const marks: { [index: string]: MarkSpec } = {
attrs: {
highlight: { default: "transparent" }
},
- inclusive: false,
+ inclusive: true,
parseDOM: [{
tag: "span", getAttrs(dom: any) {
return { highlight: dom.getAttribute("backgroundColor") };
@@ -401,7 +395,7 @@ export const marks: { [index: string]: MarkSpec } = {
}
},
- highlight: {
+ summarizeInclusive: {
parseDOM: [
{
tag: "span",
@@ -410,7 +404,7 @@ export const marks: { [index: string]: MarkSpec } = {
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) {
+ p.parentElement.outerHTML.indexOf("text-decoration-style: solid") !== -1) {
return null;
}
}
@@ -421,6 +415,31 @@ export const marks: { [index: string]: MarkSpec } = {
inclusive: true,
toDOM() {
return ['span', {
+ style: 'text-decoration: underline; text-decoration-style: solid; text-decoration-color: rgba(204, 206, 210, 0.92)'
+ }];
+ }
+ },
+
+ summarize: {
+ inclusive: false,
+ parseDOM: [
+ {
+ tag: "span",
+ getAttrs: (p: any) => {
+ if (typeof (p) !== "string") {
+ 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) {
+ return null;
+ }
+ }
+ return false;
+ }
+ },
+ ],
+ toDOM() {
+ return ['span', {
style: 'text-decoration: underline; text-decoration-style: dotted; text-decoration-color: rgba(204, 206, 210, 0.92)'
}];
}
@@ -637,7 +656,7 @@ export class DashDocCommentView {
}
const dashDoc = view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: node.attrs.docid, float: "right" });
view.dispatch(view.state.tr.insert(getPos() + 1, dashDoc));
- setTimeout(() => { try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + 2))) } catch (e) { } }, 0);
+ setTimeout(() => { try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + 2))); } catch (e) { } }, 0);
return undefined;
};
this._collapsed.onpointerdown = (e: any) => {
@@ -646,16 +665,16 @@ export class DashDocCommentView {
this._collapsed.onpointerup = (e: any) => {
const target = targetNode();
if (target) {
- let expand = target.hidden;
- let tr = view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
+ const expand = target.hidden;
+ const tr = view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
view.dispatch(tr.setSelection(TextSelection.create(tr.doc, getPos() + (expand ? 2 : 1)))); // update the attrs
setTimeout(() => {
expand && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
- try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + (expand ? 2 : 1)))) } catch (e) { }
+ try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + (expand ? 2 : 1)))); } catch (e) { }
}, 0);
}
e.stopPropagation();
- }
+ };
this._collapsed.onpointerenter = (e: any) => {
DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
e.preventDefault();
@@ -908,7 +927,7 @@ export class FootnoteView {
ignoreMutation() { return true; }
}
-export class SummarizedView {
+export class SummaryView {
_collapsed: HTMLElement;
_view: any;
constructor(node: any, view: any, getPos: any) {
@@ -946,7 +965,8 @@ export class SummarizedView {
className = (visible: boolean) => "formattedTextBox-summarizer" + (visible ? "" : "-collapsed");
updateSummarizedText(start?: any) {
- const mark = this._view.state.schema.marks.highlight.create();
+ const mtype = this._view.state.schema.marks.summarize;
+ const mtypeInc = this._view.state.schema.marks.summarizeInclusive;
let endPos = start;
const visited = new Set();
@@ -954,7 +974,7 @@ export class SummarizedView {
let skip = false;
this._view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
if (node.isLeaf && !visited.has(node) && !skip) {
- if (node.marks.find((m: any) => m.type === mark.type)) {
+ if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) {
visited.add(node);
endPos = i + node.nodeSize - 1;
}
@@ -979,7 +999,7 @@ const fromJson = schema.nodeFromJSON;
schema.nodeFromJSON = (json: any) => {
const node = fromJson(json);
- if (json.type === "star") {
+ if (json.type === schema.marks.summarize.name) {
node.attrs.text = Slice.fromJSON(schema, node.attrs.textslice);
}
return node;
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index f29dbf2e4..483ab40a7 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -1,4 +1,3 @@
-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';
@@ -10,8 +9,6 @@ import { Utils } from "../../Utils";
import { DocServer } from "../DocServer";
import { FieldViewProps } from "../views/nodes/FieldView";
import { FormattedTextBoxProps } from "../views/nodes/FormattedTextBox";
-import { DocumentManager } from "./DocumentManager";
-import { DragManager } from "./DragManager";
import { LinkManager } from "./LinkManager";
import { schema } from "./RichTextSchema";
import "./TooltipTextMenu.scss";
@@ -20,13 +17,11 @@ import { updateBullets } from './ProsemirrorExampleTransfer';
import { DocumentDecorations } from '../views/DocumentDecorations';
import { SelectionManager } from './SelectionManager';
import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../new_fields/SchemaHeaderField';
-import { Keys } from "../views/search/FilterBox";
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 {
-
public static Toolbar: HTMLDivElement | undefined;
// editor state properties
@@ -48,10 +43,9 @@ export class TooltipTextMenu {
// editor button doms
private colorDom?: Node;
private colorDropdownDom?: Node;
- private highlightDom?: Node;
- private highlightDropdownDom?: Node;
+ private highighterDom?: Node;
+ private highlighterDropdownDom?: Node;
private linkEditor?: HTMLDivElement;
- private linkText?: HTMLDivElement;
private linkDrag?: HTMLImageElement;
private _linkDropdownDom?: Node;
private _brushdom?: Node;
@@ -94,7 +88,6 @@ export class TooltipTextMenu {
{ command: toggleMark(schema.marks.strikethrough), dom: this.svgIcon("strikethrough", "Strikethrough", "M496 224H293.9l-87.17-26.83A43.55 43.55 0 0 1 219.55 112h66.79A49.89 49.89 0 0 1 331 139.58a16 16 0 0 0 21.46 7.15l42.94-21.47a16 16 0 0 0 7.16-21.46l-.53-1A128 128 0 0 0 287.51 32h-68a123.68 123.68 0 0 0-123 135.64c2 20.89 10.1 39.83 21.78 56.36H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h480a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-180.24 96A43 43 0 0 1 336 356.45 43.59 43.59 0 0 1 292.45 400h-66.79A49.89 49.89 0 0 1 181 372.42a16 16 0 0 0-21.46-7.15l-42.94 21.47a16 16 0 0 0-7.16 21.46l.53 1A128 128 0 0 0 224.49 480h68a123.68 123.68 0 0 0 123-135.64 114.25 114.25 0 0 0-5.34-24.36z") },
{ command: toggleMark(schema.marks.superscript), dom: this.svgIcon("superscript", "Superscript", "M496 160h-16V16a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 400 64h16v96h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM336 64h-67a16 16 0 0 0-13.14 6.87l-79.9 115-79.9-115A16 16 0 0 0 83 64H16A16 16 0 0 0 0 80v48a16 16 0 0 0 16 16h33.48l77.81 112-77.81 112H16a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h67a16 16 0 0 0 13.14-6.87l79.9-115 79.9 115A16 16 0 0 0 269 448h67a16 16 0 0 0 16-16v-48a16 16 0 0 0-16-16h-33.48l-77.81-112 77.81-112H336a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16z") },
{ command: toggleMark(schema.marks.subscript), dom: this.svgIcon("subscript", "Subscript", "M496 448h-16V304a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 400 352h16v96h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM336 64h-67a16 16 0 0 0-13.14 6.87l-79.9 115-79.9-115A16 16 0 0 0 83 64H16A16 16 0 0 0 0 80v48a16 16 0 0 0 16 16h33.48l77.81 112-77.81 112H16a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h67a16 16 0 0 0 13.14-6.87l79.9-115 79.9 115A16 16 0 0 0 269 448h67a16 16 0 0 0 16-16v-48a16 16 0 0 0-16-16h-33.48l-77.81-112 77.81-112H336a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16z") },
- // { command: toggleMark(schema.marks.highlight), dom: this.icon("H", 'blue', 'Blue') }
];
// add menu items
@@ -123,20 +116,15 @@ export class TooltipTextMenu {
if (dom.contains(e.target as Node)) {
e.stopPropagation();
command(this.view.state, this.view.dispatch, this.view);
- // if (this.view.state.selection.empty) {
- // if (dom.style.color === "white") { dom.style.color = "greenyellow"; }
- // else { dom.style.color = "white"; }
- // }
}
});
-
});
- // highlight menu
- this.highlightDom = this.createHighlightTool().render(this.view).dom;
- this.highlightDropdownDom = this.createHighlightDropdown().render(this.view).dom;
- this.tooltip.appendChild(this.highlightDom);
- this.tooltip.appendChild(this.highlightDropdownDom);
+ // summarize menu
+ this.highighterDom = this.createHighlightTool().render(this.view).dom;
+ this.highlighterDropdownDom = this.createHighlightDropdown().render(this.view).dom;
+ this.tooltip.appendChild(this.highighterDom);
+ this.tooltip.appendChild(this.highlighterDropdownDom);
// color menu
this.colorDom = this.createColorTool().render(this.view).dom;
@@ -166,7 +154,7 @@ export class TooltipTextMenu {
this.tooltip.appendChild(this._brushDropdownDom);
// star
- this.tooltip.appendChild(this.createStar().render(this.view).dom);
+ this.tooltip.appendChild(this.createSummarizer().render(this.view).dom);
// list types dropdown
this.updateListItemDropdown(":", this.listTypeBtnDom);
@@ -289,8 +277,6 @@ export class TooltipTextMenu {
// stop moving when mouse button is released:
document.onpointerup = null;
document.onpointermove = null;
- //self.highlightSearchTerms(self.state, ["hello"]);
- //FormattedTextBox.Instance.unhighlightSearchTerms();
}
}
@@ -302,11 +288,10 @@ export class TooltipTextMenu {
fontSizeBtns.push(this.dropdownFontSizeBtn(String(mark.attrs.fontSize), "color: black; width: 50px;", mark, this.view, this.changeToFontSize));
});
- const newfontSizeDom = (new Dropdown(fontSizeBtns, {
- label: label,
- css: "color:black; min-width: 60px;"
- }) as MenuItem).render(this.view).dom;
- if (this.fontSizeDom) { this.tooltip.replaceChild(newfontSizeDom, this.fontSizeDom); }
+ const newfontSizeDom = (new Dropdown(fontSizeBtns, { label: label, css: "color:black; min-width: 60px;" }) as MenuItem).render(this.view).dom;
+ if (this.fontSizeDom) {
+ this.tooltip.replaceChild(newfontSizeDom, this.fontSizeDom);
+ }
else {
this.tooltip.appendChild(newfontSizeDom);
}
@@ -321,11 +306,10 @@ export class TooltipTextMenu {
fontBtns.push(this.dropdownFontFamilyBtn(mark.attrs.family, "color: black; font-family: " + mark.attrs.family + ", sans-serif; width: 125px;", mark, this.view, this.changeToFontFamily));
});
- const newfontStyleDom = (new Dropdown(fontBtns, {
- label: label,
- css: "color:black; width: 125px;"
- }) as MenuItem).render(this.view).dom;
- if (this.fontStyleDom) { this.tooltip.replaceChild(newfontStyleDom, this.fontStyleDom); }
+ const newfontStyleDom = (new Dropdown(fontBtns, { label: label, css: "color:black; width: 125px;" }) as MenuItem).render(this.view).dom;
+ if (this.fontStyleDom) {
+ this.tooltip.replaceChild(newfontStyleDom, this.fontStyleDom);
+ }
else {
this.tooltip.appendChild(newfontStyleDom);
}
@@ -333,94 +317,16 @@ export class TooltipTextMenu {
}
updateLinkMenu() {
- if (!this.linkEditor || !this.linkText) {
- this.linkEditor = document.createElement("div");
- this.linkEditor.className = "ProseMirror-icon menuicon";
- this.linkText = document.createElement("div");
- this.linkText.setAttribute("contenteditable", "true");
- this.linkText.style.whiteSpace = "nowrap";
- this.linkText.style.width = "150px";
- this.linkText.style.overflow = "hidden";
- this.linkText.style.color = "white";
- this.linkText.onpointerdown = (e: PointerEvent) => { e.stopPropagation(); };
- 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) => {
- const node = this.view.state.selection.$from.nodeAfter;
- const link = node && node.marks.find(m => m.type.name === "link");
- if (link) {
- const href: string = link.attrs.href;
- if (href.indexOf(Utils.prepend("/doc/")) === 0) {
- const docid = href.replace(Utils.prepend("/doc/"), "");
- DocServer.GetRefField(docid).then(action((f: Opt<Field>) => {
- if (f instanceof Doc) {
- if (DocumentManager.Instance.getDocumentView(f)) {
- DocumentManager.Instance.getDocumentView(f)!.props.focus(f, false);
- }
- else this.editorProps && this.editorProps.addDocTab(f, undefined, "onRight");
- }
- }));
- }
- // TODO This should have an else to handle external links
- e.stopPropagation();
- e.preventDefault();
- }
- };
- this.linkDrag = document.createElement("img");
- this.linkDrag.src = "https://seogurusnyc.com/wp-content/uploads/2016/12/link-1.png";
- this.linkDrag.style.width = "15px";
- this.linkDrag.style.height = "15px";
- this.linkDrag.title = "Drag to create link";
- this.linkDrag.id = "link-drag";
- this.linkDrag.onpointerdown = (e: PointerEvent) => {
- if (!this.editorProps) return;
- const dragData = new DragManager.LinkDragData(this.editorProps.Document);
- dragData.dontClearTextBox = true;
- // hack to get source context -sy
- const docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document);
- e.stopPropagation();
- const ctrlKey = e.ctrlKey;
- DragManager.StartLinkDrag(this.linkDrag!, dragData, e.clientX, e.clientY,
- {
- handlers: {
- dragComplete: action(() => {
- if (dragData.linkDocument) {
- const linkDoc = dragData.linkDocument;
- const proto = Doc.GetProto(linkDoc);
- if (proto && docView) {
- proto.sourceContext = docView.props.ContainingCollectionDoc;
- }
- 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
- }
- }
- }),
- },
- hideSource: false
- });
- e.stopPropagation();
- e.preventDefault();
- };
- this.linkEditor.appendChild(this.linkDrag);
- this.tooltip.appendChild(this.linkEditor);
- }
-
- 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) => {
- if (e.key === "Enter") {
- // this.makeLink(this.linkText!.textContent!);
- e.stopPropagation();
- e.preventDefault();
- }
- };
+ this.linkEditor = document.createElement("div");
+ this.linkEditor.className = "ProseMirror-icon menuicon";
+ this.linkDrag = document.createElement("img");
+ this.linkDrag.src = "https://seogurusnyc.com/wp-content/uploads/2016/12/link-1.png";
+ this.linkDrag.style.width = "15px";
+ this.linkDrag.style.height = "15px";
+ this.linkDrag.title = "Click to set link target";
+ this.linkDrag.id = "link-btn";
+ this.linkEditor.appendChild(this.linkDrag);
+ this.tooltip.appendChild(this.linkEditor);
}
async getTextLinkTargetTitle() {
@@ -485,9 +391,7 @@ export class TooltipTextMenu {
return div;
},
enable() { return false; },
- run(p1, p2, p3, event) {
- event.stopPropagation();
- }
+ run(p1, p2, p3, event) { event.stopPropagation(); }
});
// menu item to update/apply the hyperlink to the selected text
@@ -584,24 +488,6 @@ export class TooltipTextMenu {
}
}
- deleteLinkItem() {
- const icon = {
- height: 16, width: 16,
- path: "M15.898,4.045c-0.271-0.272-0.713-0.272-0.986,0l-4.71,4.711L5.493,4.045c-0.272-0.272-0.714-0.272-0.986,0s-0.272,0.714,0,0.986l4.709,4.711l-4.71,4.711c-0.272,0.271-0.272,0.713,0,0.986c0.136,0.136,0.314,0.203,0.492,0.203c0.179,0,0.357-0.067,0.493-0.203l4.711-4.711l4.71,4.711c0.137,0.136,0.314,0.203,0.494,0.203c0.178,0,0.355-0.067,0.492-0.203c0.273-0.273,0.273-0.715,0-0.986l-4.711-4.711l4.711-4.711C16.172,4.759,16.172,4.317,15.898,4.045z"
- };
- return new MenuItem({
- title: "Delete Link",
- label: "X",
- icon: icon,
- css: "color: red",
- class: "summarize",
- execEvent: "",
- run: (state, dispatch) => {
- this.deleteLink();
- }
- });
- }
-
createLink() {
const markType = schema.marks.link;
return new MenuItem({
@@ -655,22 +541,19 @@ export class TooltipTextMenu {
//Make a dropdown of all list types
const toAdd: MenuItem[] = [];
this.listTypeToIcon.forEach((icon, type) => {
- toAdd.push(this.dropdownNodeBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeToNodeType));
+ toAdd.push(this.dropdownBulletBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeBulletType));
});
//option to remove the list formatting
- toAdd.push(this.dropdownNodeBtn("X", "color: black; width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType));
+ toAdd.push(this.dropdownBulletBtn("X", "color: black; width: 40px;", undefined, this.view, this.listTypes, this.changeBulletType));
- listTypeBtn = (new Dropdown(toAdd, {
- label: label,
- css: "color:black; width: 40px;"
- }) as MenuItem).render(this.view).dom;
+ listTypeBtn = (new Dropdown(toAdd, { label: label, css: "color:black; width: 40px;" }) as MenuItem).render(this.view).dom;
//add this new button and return it
this.tooltip.appendChild(listTypeBtn);
return listTypeBtn;
}
- createStar() {
+ createSummarizer() {
return new MenuItem({
title: "Summarize",
label: "Summarize",
@@ -678,31 +561,17 @@ export class TooltipTextMenu {
css: "color:white;",
class: "menuicon",
execEvent: "",
- run: (state, dispatch) => {
- TooltipTextMenu.insertStar(this.view.state, this.view.dispatch);
- }
-
+ run: (state, dispatch) => TooltipTextMenu.insertSummarizer(state, dispatch)
});
}
- public static insertStar(state: EditorState<any>, dispatch: any) {
+ public static insertSummarizer(state: EditorState<any>, dispatch: any) {
if (state.selection.empty) return false;
- const mark = state.schema.marks.highlight.create();
+ const mark = state.schema.marks.summarize.create();
const tr = state.tr;
tr.addMark(state.selection.from, state.selection.to, mark);
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;
- const mark = state.schema.marks.highlight.create();
- const tr = state.tr;
- tr.addMark(state.selection.from, state.selection.to, mark);
- const content = tr.selection.content();
- const newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
+ const newNode = state.schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() });
dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark));
return true;
}
@@ -722,7 +591,7 @@ export class TooltipTextMenu {
const color = document.createElement("div");
color.className = "buttonColor";
- color.style.backgroundColor = TooltipTextMenuManager.Instance.highlight.toString();
+ color.style.backgroundColor = TooltipTextMenuManager.Instance.highlighter.toString();
const wrapper = document.createElement("div");
wrapper.id = "colorPicker";
@@ -730,17 +599,14 @@ export class TooltipTextMenu {
wrapper.appendChild(color);
return wrapper;
},
- run: (state, dispatch) => {
- TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlight, this.view.state, this.view.dispatch);
- }
+ run: (state, dispatch) => TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlighter, state, dispatch)
});
}
public static insertHighlight(color: String, state: EditorState<any>, dispatch: any) {
if (state.selection.empty) return false;
- const highlightMark = state.schema.mark(state.schema.marks.marker, { highlight: color });
- dispatch(state.tr.addMark(state.selection.from, state.selection.to, highlightMark));
+ toggleMark(state.schema.marks.marker, { highlight: color })(state, dispatch);
}
createHighlightDropdown() {
@@ -773,22 +639,22 @@ export class TooltipTextMenu {
colors.forEach(color => {
const button = document.createElement("button");
- button.className = color === TooltipTextMenuManager.Instance.highlight ? "colorPicker active" : "colorPicker";
+ button.className = color === TooltipTextMenuManager.Instance.highlighter ? "colorPicker active" : "colorPicker";
if (color) {
button.style.backgroundColor = color;
button.textContent = color === "transparent" ? "X" : "";
button.onclick = e => {
- TooltipTextMenuManager.Instance.highlight = color;
+ TooltipTextMenuManager.Instance.highlighter = color;
- TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlight, self.view.state, self.view.dispatch);
+ TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlighter, self.view.state, self.view.dispatch);
// update color menu
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;
- self.highlightDropdownDom = highlightDropdownDom;
+ self.highighterDom && self.tooltip.replaceChild(highlightDom, self.highighterDom);
+ self.highlighterDropdownDom && self.tooltip.replaceChild(highlightDropdownDom, self.highlighterDropdownDom);
+ self.highighterDom = highlightDom;
+ self.highlighterDropdownDom = highlightDropdownDom;
};
}
colorsWrapper.appendChild(button);
@@ -832,19 +698,18 @@ export class TooltipTextMenu {
wrapper.appendChild(color);
return wrapper;
},
- run: (state, dispatch) => {
- TooltipTextMenu.insertColor(TooltipTextMenuManager.Instance.color, this.view.state, this.view.dispatch);
- }
+ run: (state, dispatch) => this.insertColor(TooltipTextMenuManager.Instance.color, state, dispatch)
});
}
- public static insertColor(color: String, state: EditorState<any>, dispatch: any) {
+ public insertColor(color: String, state: EditorState<any>, dispatch: any) {
const colorMark = state.schema.mark(state.schema.marks.pFontColor, { color: color });
if (state.selection.empty) {
dispatch(state.tr.addStoredMark(colorMark));
return false;
}
- dispatch(state.tr.addMark(state.selection.from, state.selection.to, colorMark));
+ this.setMark(colorMark, state, dispatch);
+ toggleMark(colorMark.type, { color: color })(state, dispatch);
}
createColorDropdown() {
@@ -883,7 +748,7 @@ export class TooltipTextMenu {
button.onclick = e => {
TooltipTextMenuManager.Instance.color = color;
- TooltipTextMenu.insertColor(TooltipTextMenuManager.Instance.color, self.view.state, self.view.dispatch);
+ self.insertColor(TooltipTextMenuManager.Instance.color, self.view.state, self.view.dispatch);
// update color menu
const colorDom = self.createColorTool().render(self.view).dom;
@@ -903,13 +768,10 @@ export class TooltipTextMenu {
return div;
},
enable() { return false; },
- run(p1, p2, p3, event) {
- event.stopPropagation();
- }
+ run(p1, p2, p3, event) { event.stopPropagation(); }
});
- const colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
- return colorDropdown;
+ return new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
}
createBrush(active: boolean = false) {
@@ -933,9 +795,7 @@ export class TooltipTextMenu {
self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom);
self._brushDropdownDom = newBrushDropdowndom;
},
- active: (state) => {
- return true;
- }
+ active: (state) => true
});
}
@@ -959,8 +819,7 @@ export class TooltipTextMenu {
if (TooltipTextMenuManager.Instance._brushMarks && to - from > 0) {
this.view.dispatch(this.view.state.tr.removeMark(from, to));
Array.from(TooltipTextMenuManager.Instance._brushMarks).filter(m => m.type !== schema.marks.user_mark).forEach((mark: Mark) => {
- const markType = mark.type;
- this.changeToMarkInGroup(markType, this.view, []);
+ this.setMark(mark, this.view.state, this.view.dispatch);
});
}
}
@@ -995,9 +854,7 @@ export class TooltipTextMenu {
class: "button-setting-disabled",
css: "",
enable() { return false; },
- run(p1, p2, p3, event) {
- event.stopPropagation();
- }
+ run(p1, p2, p3, event) { event.stopPropagation(); }
});
const self = this;
@@ -1056,71 +913,26 @@ export class TooltipTextMenu {
});
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;
+ return new Dropdown(hasMarks ? [brushInfo, clearBrush] : [brushInfo], { class: "buttonSettings-dropdown" }) as MenuItem;
}
- //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[]) => {
- 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) => {
- if (dispatch) {
- if ($cursor) {
- if (type.isInSet(state.storedMarks || $cursor.marks())) {
- dispatch(state.tr.removeStoredMark(type));
- }
- } else {
- let has = false;
- for (let i = 0; !has && i < ranges.length; i++) {
- const { $from, $to } = ranges[i];
- has = state.doc.rangeHasMark($from.pos, $to.pos, type);
- }
- for (const i of ranges) {
- if (has) {
- toggleMark(type)(view.state, view.dispatch, view);
- }
- }
- }
- }
- });
- 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) {
- 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))));
+ setMark = (mark: Mark, state: EditorState<any>, dispatch: any) => {
+ if (mark) {
+ const node = (state.selection as NodeSelection).node;
+ if (node?.type === schema.nodes.ordered_list) {
+ let attrs = node.attrs;
+ if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, setFontFamily: mark.attrs.family };
+ if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, setFontSize: mark.attrs.fontSize };
+ if (mark.type === schema.marks.pFontColor) attrs = { ...attrs, setFontColor: mark.attrs.color };
+ const tr = updateBullets(state.tr.setNodeMarkup(state.selection.from, node.type, attrs), state.schema);
+ dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(state.selection.from))));
+ } else {
+ toggleMark(mark.type, mark.attrs)(state, dispatch);
}
- else toggleMark(markType)(view.state, view.dispatch, view);
}
}
changeToFontFamily = (mark: Mark, view: EditorView) => {
- const { $cursor, ranges } = view.state.selection as TextSelection;
- const state = view.state;
- const dispatch = view.dispatch;
-
- //remove all other active font marks
- if ($cursor) {
- if (view.state.schema.marks.pFontFamily.isInSet(state.storedMarks || $cursor.marks())) {
- dispatch(state.tr.removeStoredMark(view.state.schema.marks.pFontFamily));
- }
- } else {
- let has = false;
- for (let i = 0; !has && i < ranges.length; i++) {
- const { $from, $to } = ranges[i];
- has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontFamily);
- }
- for (const i of ranges) {
- if (has) {
- toggleMark(view.state.schema.marks.pFontFamily)(view.state, view.dispatch, view);
- }
- }
- }
-
const fontName = mark.attrs.family;
if (fontName) { this.updateFontStyleDropdown(fontName); }
if (this.editorProps) {
@@ -1130,39 +942,10 @@ export class TooltipTextMenu {
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) {
- 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))));
- }
- else view.dispatch(view.state.tr.addMark(view.state.selection.from, view.state.selection.to, view.state.schema.marks.pFontFamily.create({ family: fontName })));
- view.state.storedMarks = [...(view.state.storedMarks || []), view.state.schema.marks.pFontFamily.create({ family: fontName })];
+ this.setMark(view.state.schema.marks.pFontFamily.create({ family: fontName }), view.state, view.dispatch);
}
changeToFontSize = (mark: Mark, view: EditorView) => {
- const { $cursor, ranges } = view.state.selection as TextSelection;
- const state = view.state;
- const dispatch = view.dispatch;
-
- //remove all other active font marks
- if ($cursor) {
- if (view.state.schema.marks.pFontSize.isInSet(state.storedMarks || $cursor.marks())) {
- dispatch(state.tr.removeStoredMark(view.state.schema.marks.pFontSize));
- }
- } else {
- let has = false;
- for (let i = 0; !has && i < ranges.length; i++) {
- const { $from, $to } = ranges[i];
- has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontSize);
- }
- for (const i of ranges) {
- if (has) {
- toggleMark(view.state.schema.marks.pFontSize)(view.state, view.dispatch, view);
- }
- }
- }
-
const size = mark.attrs.fontSize;
if (size) { this.updateFontSizeDropdown(String(size) + " pt"); }
if (this.editorProps) {
@@ -1172,18 +955,11 @@ export class TooltipTextMenu {
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) {
- 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))));
- }
- else view.dispatch(view.state.tr.addMark(view.state.selection.from, view.state.selection.to, view.state.schema.marks.pFontSize.create({ fontSize: size })));
- view.state.storedMarks = [...(view.state.storedMarks || []), view.state.schema.marks.pFontSize.create({ fontSize: size })];
+ this.setMark(view.state.schema.marks.pFontSize.create({ fontSize: size }), view.state, view.dispatch);
}
//remove all node typeand apply the passed-in one to the selected text
- changeToNodeType = (nodeType: NodeType | undefined) => {
+ changeBulletType = (nodeType: NodeType | undefined) => {
//remove oldif (nodeType) { //add new
const view = this.view;
if (nodeType === schema.nodes.bullet_list) {
@@ -1211,46 +987,40 @@ export class TooltipTextMenu {
//css is the style you want applied to the button
dropdownFontFamilyBtn(label: string, css: string, mark: Mark, view: EditorView, changeFontFamily: (mark: Mark<any>, view: EditorView) => any) {
return new MenuItem({
- title: "",
+ title: "Set Font Family",
label: label,
execEvent: "",
class: "dropdown-item",
css: css,
enable() { return true; },
- run() {
- changeFontFamily(mark, view);
- }
+ run() { changeFontFamily(mark, view); }
});
}
//makes a button for the drop down FOR MARKS
//css is the style you want applied to the button
dropdownFontSizeBtn(label: string, css: string, mark: Mark, view: EditorView, changeFontSize: (markType: Mark<any>, view: EditorView) => any) {
return new MenuItem({
- title: "",
+ title: "Set Font Size",
label: label,
execEvent: "",
class: "dropdown-item",
css: css,
enable() { return true; },
- run() {
- changeFontSize(mark, view);
- }
+ run() { changeFontSize(mark, view); }
});
}
//makes a button for the drop down FOR NODE TYPES
//css is the style you want applied to the button
- dropdownNodeBtn(label: string, css: string, nodeType: NodeType | undefined, view: EditorView, groupNodes: NodeType[], changeToNodeInGroup: (nodeType: NodeType<any> | undefined, view: EditorView, groupNodes: NodeType[]) => any) {
+ dropdownBulletBtn(label: string, css: string, nodeType: NodeType | undefined, view: EditorView, groupNodes: NodeType[], changeToNodeInGroup: (nodeType: NodeType<any> | undefined, view: EditorView, groupNodes: NodeType[]) => any) {
return new MenuItem({
- title: "",
+ title: "Set Bullet Style",
label: label,
execEvent: "",
class: "dropdown-item",
css: css,
enable() { return true; },
- run() {
- changeToNodeInGroup(nodeType, view, groupNodes);
- }
+ run() { changeToNodeInGroup(nodeType, view, groupNodes); }
});
}
@@ -1325,14 +1095,7 @@ export class TooltipTextMenu {
getMarksInSelection(state: EditorState<any>) {
const found = new Set<Mark>();
const { from, to } = state.selection as TextSelection;
- state.doc.nodesBetween(from, to, (node) => {
- const marks = node.marks;
- if (marks) {
- marks.forEach(m => {
- found.add(m);
- });
- }
- });
+ state.doc.nodesBetween(from, to, (node) => node.marks?.forEach(m => found.add(m)));
return found;
}
@@ -1362,12 +1125,6 @@ export class TooltipTextMenu {
this.reset_mark_doms();
- // Hide the tooltip if the selection is empty
- if (state.selection.empty) {
- //this.tooltip.style.display = "none";
- //return;
- }
-
// update link dropdown
const linkDropdown = await this.createLinkDropdown();
const newLinkDropdowndom = linkDropdown.render(this.view).dom;
@@ -1473,7 +1230,6 @@ export class TooltipTextMenu {
}
const mark = state.schema.mark(mark_type);
return ref_node.marks.includes(mark);
- return false;
});
}
else {
@@ -1518,19 +1274,19 @@ export class TooltipTextMenu {
export class TooltipTextMenuManager {
private static _instance: TooltipTextMenuManager;
+ private _isPinned: boolean = false;
public pinnedX: number = 0;
public pinnedY: number = 0;
public unpinnedX: number = 0;
public unpinnedY: number = 0;
- private _isPinned: boolean = false;
public _brushMarks: Set<Mark> | undefined;
public _brushMap: Map<string, Set<Mark>> = new Map();
public _brushIsEmpty: boolean = true;
public color: String = "#000";
- public highlight: String = "transparent";
+ public highlighter: String = "transparent";
public activeMenu: TooltipTextMenu | undefined;
@@ -1541,11 +1297,7 @@ export class TooltipTextMenuManager {
return TooltipTextMenuManager._instance;
}
- public get isPinned() {
- return this._isPinned;
- }
+ public get isPinned() { return this._isPinned; }
- public toggleIsPinned() {
- this._isPinned = !this._isPinned;
- }
+ public toggleIsPinned() { this._isPinned = !this._isPinned; }
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index dd3b740fb..f366a3677 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -85,14 +85,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
if (this._accumulatedTitle.startsWith("#") || this._accumulatedTitle.startsWith("=")) {
this._titleControlString = this._accumulatedTitle;
} else if (this._titleControlString.startsWith("#")) {
- let selectionTitleFieldKey = this._titleControlString.substring(1);
+ const selectionTitleFieldKey = this._titleControlString.substring(1);
selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._accumulatedTitle.startsWith("-"));
selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d =>
Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle, true)
);
}
}
- }))
+ }));
@action titleEntered = (e: any) => {
const key = e.keyCode || e.which;
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index d0cecf03d..54def38b5 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -120,7 +120,7 @@ export class EditableView extends React.Component<EditableProps> {
@action
setIsFocused = (value: boolean) => {
- let wasFocused = this._editing;
+ const wasFocused = this._editing;
this._editing = value;
return wasFocused !== this._editing;
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 01cd7957c..25b7dc5ec 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -286,7 +286,7 @@ export class MainView extends React.Component {
ContainingCollectionDoc={undefined}
zoomToScale={emptyFunction}
getScale={returnOne}
- />
+ />;
}
@computed get dockingContent() {
TraceMobx();
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 411040332..15eec37de 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -240,9 +240,9 @@ export class CollectionView extends Touchable<FieldViewProps> {
const mainPath = path.extname(images[this._curLightboxImg]);
const nextPath = path.extname(images[(this._curLightboxImg + 1) % images.length]);
const prevPath = path.extname(images[(this._curLightboxImg + images.length - 1) % images.length]);
- let main = images[this._curLightboxImg].replace(mainPath, "_o" + mainPath);
- let next = images[(this._curLightboxImg + 1) % images.length].replace(nextPath, "_o" + nextPath);
- let prev = images[(this._curLightboxImg + images.length - 1) % images.length].replace(prevPath, "_o" + prevPath);
+ const main = images[this._curLightboxImg].replace(mainPath, "_o" + mainPath);
+ const next = images[(this._curLightboxImg + 1) % images.length].replace(nextPath, "_o" + nextPath);
+ const prev = images[(this._curLightboxImg + images.length - 1) % images.length].replace(prevPath, "_o" + prevPath);
return !this._isLightboxOpen ? (null) : (<Lightbox key="lightbox"
mainSrc={main}
nextSrc={next}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 24cc0b5ea..3620ccb34 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -148,7 +148,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text...
{
this._titleRef.current?.setIsFocused(false);
- let any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any);
+ const any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any);
any.keeplocation = true;
any?.focus();
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 9318142e2..ec9e0ce5b 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -27,7 +27,7 @@ import { DictationManager } from '../../util/DictationManager';
import { DragManager } from "../../util/DragManager";
import buildKeymap from "../../util/ProsemirrorExampleTransfer";
import { inpRules } from "../../util/RichTextRules";
-import { DashDocCommentView, FootnoteView, ImageResizeView, DashDocView, OrderedListView, schema, SummarizedView } from "../../util/RichTextSchema";
+import { DashDocCommentView, FootnoteView, ImageResizeView, DashDocView, OrderedListView, schema, SummaryView } from "../../util/RichTextSchema";
import { SelectionManager } from "../../util/SelectionManager";
import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
import { TooltipTextMenu } from "../../util/TooltipTextMenu";
@@ -822,7 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); },
dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); },
image(node, view, getPos) { return new ImageResizeView(node, view, getPos, self.props.addDocTab); },
- star(node, view, getPos) { return new SummarizedView(node, view, getPos); },
+ summary(node, view, getPos) { return new SummaryView(node, view, getPos); },
ordered_list(node, view, getPos) { return new OrderedListView(); },
footnote(node, view, getPos) { return new FootnoteView(node, view, getPos); }
},
@@ -907,10 +907,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
this.tryUpdateHeight();
// see if we need to preserve the insertion point
- let prosediv = this._proseRef?.children?.[0] as any;
- let keeplocation = prosediv?.keeplocation;
+ const prosediv = this._proseRef?.children?.[0] as any;
+ const keeplocation = prosediv?.keeplocation;
prosediv && (prosediv.keeplocation = undefined);
- let pos = this._editorView?.state.selection.$from.pos || 1;
+ const pos = this._editorView?.state.selection.$from.pos || 1;
keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos))));
}
onPointerWheel = (e: React.WheelEvent): void => {
@@ -925,14 +925,14 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
onClick = (e: React.MouseEvent): void => {
if ((this._editorView!.root as any).getSelection().isCollapsed) { // this is a hack to allow the cursor to be placed at the end of a document when the document ends in an inline dash comment. Apparently Chrome on Windows has a bug/feature which breaks this when clicking after the end of the text.
- let pcords = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
- let node = pcords && this._editorView!.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text)
+ const pcords = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
+ const node = pcords && this._editorView!.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text)
if (pcords && node?.type === this._editorView!.state.schema.nodes.dashComment) {
this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, pcords.pos + 2)));
e.preventDefault();
}
if (!node && this._proseRef) {
- let lastNode = this._proseRef.children[this._proseRef.children.length - 1].children[this._proseRef.children[this._proseRef.children.length - 1].children.length - 1]; // get the last prosemirror div
+ const lastNode = this._proseRef.children[this._proseRef.children.length - 1].children[this._proseRef.children[this._proseRef.children.length - 1].children.length - 1]; // get the last prosemirror div
if (e.clientY > lastNode.getBoundingClientRect().bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document
this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, this._editorView!.state.doc.content.size)));
}
@@ -973,7 +973,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
// }
// }
- this.hitBulletTargets(e.clientX, e.clientY, e.shiftKey, false)
+ this.hitBulletTargets(e.clientX, e.clientY, e.shiftKey, false);
if (this._recording) setTimeout(() => { this.stopDictation(true); setTimeout(() => this.recordDictation(), 500); }, 500);
}
@@ -984,7 +984,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
if (pos && this.props.isSelected(true)) {
// let beforeEle = document.querySelector("." + hit.className) as Element; // const before = hit ? window.getComputedStyle(hit, ':before') : undefined;
//const node = this._editorView!.state.doc.nodeAt(pos.pos);
- let $pos = this._editorView!.state.doc.resolve(pos.pos);
+ const $pos = this._editorView!.state.doc.resolve(pos.pos);
let list_node = $pos.node().type === schema.nodes.list_item ? $pos.node() : undefined;
if ($pos.node().type === schema.nodes.ordered_list) {
for (let off = 1; off < 100; off++) {
@@ -998,7 +998,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
}
if (list_node && pos.inside >= 0 && this._editorView!.state.doc.nodeAt(pos.inside)!.attrs.bulletStyle === list_node.attrs.bulletStyle) {
if (select) {
- let $olist_pos = this._editorView!.state.doc.resolve($pos.pos - $pos.parentOffset - 1);
+ const $olist_pos = this._editorView!.state.doc.resolve($pos.pos - $pos.parentOffset - 1);
if (!highlightOnly) {
this._editorView!.dispatch(this._editorView!.state.tr.setSelection(new NodeSelection($olist_pos)));
}
@@ -1064,14 +1064,14 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
return;
}
if (!this._editorView!.state.selection.empty && e.key === "%") {
- (this._editorView!.state as any).EnteringStyle = true;
+ this._editorView!.state.schema.EnteringStyle = true;
e.preventDefault();
e.stopPropagation();
return;
}
- if (this._editorView!.state.selection.empty || !(this._editorView!.state as any).EnteringStyle) {
- (this._editorView!.state as any).EnteringStyle = false;
+ if (this._editorView!.state.selection.empty || !this._editorView!.state.schema.EnteringStyle) {
+ this._editorView!.state.schema.EnteringStyle = false;
}
if (e.key === "Escape") {
SelectionManager.DeselectAll();
@@ -1080,7 +1080,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
if (e.key === "Tab" || e.key === "Enter") {
e.preventDefault();
}
- const mark = e.key !== " " && this._lastTimedMark ? this._lastTimedMark! : schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) });
+ const mark = e.key !== " " && this._lastTimedMark ? this._lastTimedMark : schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) });
this._lastTimedMark = mark;
this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark));
@@ -1100,7 +1100,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
getComputedStyle(this._ref.current!.parentElement!).top === "0px") { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
const nh = this.Document.isTemplateField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
const dh = NumCast(this.layoutDoc.height, 0);
- let newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
+ const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
if (Math.abs(newHeight - dh) > 1) { // bcz: Argh! without this, we get into a React crash if the same document is opened in a freeform view and in the treeview. no idea why, but after dragging the freeform document, selecting it, and selecting text, it will compute to 1 pixel higher than the treeview which causes a cycle
this.layoutDoc.height = newHeight;
this.dataDoc.nativeHeight = nh ? scrollHeight : undefined;