aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields/RichTextUtils.ts
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2019-09-14 21:00:37 -0400
committerSam Wilkins <samwilkins333@gmail.com>2019-09-14 21:00:37 -0400
commitc2f749238e9db63b81c3bec08a14dd6006ab876f (patch)
tree021211ba6c070c307344deee6199c4eba9ef4833 /src/new_fields/RichTextUtils.ts
parent037098aca0993bee6f986b592c17aa54a7225905 (diff)
sharing routine for docs and final formatting fixes
Diffstat (limited to 'src/new_fields/RichTextUtils.ts')
-rw-r--r--src/new_fields/RichTextUtils.ts153
1 files changed, 98 insertions, 55 deletions
diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts
index 84744db2f..555c41b67 100644
--- a/src/new_fields/RichTextUtils.ts
+++ b/src/new_fields/RichTextUtils.ts
@@ -4,7 +4,7 @@ import { RichTextField } from "./RichTextField";
import { docs_v1 } from "googleapis";
import { GoogleApiClientUtils } from "../client/apis/google_docs/GoogleApiClientUtils";
import { FormattedTextBox } from "../client/views/nodes/FormattedTextBox";
-import { Opt } from "./Doc";
+import { Opt, Doc } from "./Doc";
import Color = require('color');
import { sinkListItem } from "prosemirror-schema-list";
import { Utils, PostToServer } from "../Utils";
@@ -12,6 +12,11 @@ import { RouteStore } from "../server/RouteStore";
import { Docs } from "../client/documents/Documents";
import { schema } from "../client/util/RichTextSchema";
import { GooglePhotos } from "../client/apis/google_docs/GooglePhotosClientUtils";
+import { SchemaHeaderField } from "./SchemaHeaderField";
+import { DocServer } from "../client/DocServer";
+import { Cast } from "./Types";
+import { Id } from "./FieldSymbols";
+import { DocumentView } from "../client/views/nodes/DocumentView";
export namespace RichTextUtils {
@@ -91,9 +96,15 @@ export namespace RichTextUtils {
export namespace GoogleDocs {
export const Export = async (state: EditorState): Promise<GoogleApiClientUtils.Docs.Content> => {
- const nodes: Node<any>[] = [];
+ const nodes: (Node<any> | null)[] = [];
let text = ToPlainText(state);
- state.doc.content.forEach(node => node.content.forEach(child => nodes.push(child)));
+ state.doc.content.forEach(node => {
+ if (!node.childCount) {
+ nodes.push(null);
+ } else {
+ node.content.forEach(child => nodes.push(child));
+ }
+ });
const requests = await marksToStyle(nodes);
return { text, requests };
};
@@ -223,30 +234,11 @@ export namespace RichTextUtils {
const StyleToMark = new Map<keyof docs_v1.Schema$TextStyle, keyof typeof schema.marks>([
["bold", "strong"],
["italic", "em"],
- ["foregroundColor", "pFontColor"]
- ]);
-
- const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([
- ["strong", "bold"],
- ["em", "italic"],
- ["pFontColor", "foregroundColor"],
- ["timesNewRoman", "weightedFontFamily"],
- ["georgia", "weightedFontFamily"],
- ["comicSans", "weightedFontFamily"],
- ["tahoma", "weightedFontFamily"],
- ["impact", "weightedFontFamily"]
+ ["foregroundColor", "pFontColor"],
+ ["fontSize", "pFontSize"]
]);
- const FontFamilyMapping = new Map<string, string>([
- ["timesNewRoman", "Times New Roman"],
- ["arial", "Arial"],
- ["georgia", "Georgia"],
- ["comicSans", "Comic Sans MS"],
- ["tahoma", "Tahoma"],
- ["impact", "Impact"]
- ]);
-
- const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle): Opt<Mark[]> => {
+ const styleToMarks = (schema: any, textStyle?: docs_v1.Schema$TextStyle) => {
if (!textStyle) {
return undefined;
}
@@ -263,20 +255,53 @@ export namespace RichTextUtils {
let object = value.color.rgbColor;
attributes.color = Color.rgb(["red", "green", "blue"].map(color => object[color] * 255 || 0)).hex();
}
+ if (value.magnitude) {
+ attributes.fontSize = value.magnitude;
+ }
- let mark = schema.mark(schema.marks[converted], attributes);
+ let mapped = schema.marks[converted];
+ if (!mapped) {
+ alert(`No mapping found for ${converted}!`);
+ return;
+ }
+
+ let mark = schema.mark(mapped, attributes);
mark && marks.push(mark);
}
});
return marks;
};
+ const MarkToStyle = new Map<keyof typeof schema.marks, keyof docs_v1.Schema$TextStyle>([
+ ["strong", "bold"],
+ ["em", "italic"],
+ ["pFontColor", "foregroundColor"],
+ ["timesNewRoman", "weightedFontFamily"],
+ ["georgia", "weightedFontFamily"],
+ ["comicSans", "weightedFontFamily"],
+ ["tahoma", "weightedFontFamily"],
+ ["impact", "weightedFontFamily"]
+ ]);
+
+ const FontFamilyMapping = new Map<string, string>([
+ ["timesNewRoman", "Times New Roman"],
+ ["arial", "Arial"],
+ ["georgia", "Georgia"],
+ ["comicSans", "Comic Sans MS"],
+ ["tahoma", "Tahoma"],
+ ["impact", "Impact"]
+ ]);
+
const ignored = ["user_mark"];
- const marksToStyle = async (nodes: Node<any>[]): Promise<docs_v1.Schema$Request[]> => {
+ const marksToStyle = async (nodes: (Node<any> | null)[]): Promise<docs_v1.Schema$Request[]> => {
let requests: docs_v1.Schema$Request[] = [];
let position = 1;
for (let node of nodes) {
+ if (node === null) {
+ position += 2;
+ continue;
+ }
const { marks, attrs, nodeSize } = node;
const textStyle: docs_v1.Schema$TextStyle = {};
const information: LinkInformation = {
@@ -284,37 +309,55 @@ export namespace RichTextUtils {
endIndex: position + nodeSize,
textStyle
};
- if (marks.length) {
- let mark: Mark<any>;
- const markMap = BuildMarkMap(marks);
- Object.keys(schema.marks).map(markName => {
- if (!ignored.includes(markName) && (mark = markMap[markName])) {
- const converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle;
- let value: any = true;
- if (converted) {
- const { attrs } = mark;
- switch (converted) {
- case "link":
- value = { url: attrs.href };
- textStyle.foregroundColor = fromRgb.blue;
- textStyle.bold = true;
- break;
- case "fontSize":
- value = attrs.fontSize;
- break;
- case "foregroundColor":
- value = fromHex(attrs.color);
- break;
- case "weightedFontFamily":
- value = { fontFamily: FontFamilyMapping.get(markName) };
+ let mark: Mark<any>;
+ const markMap = BuildMarkMap(marks);
+ for (let markName of Object.keys(schema.marks)) {
+ if (ignored.includes(markName) || !(mark = markMap[markName])) {
+ continue;
+ }
+ let converted = MarkToStyle.get(markName) || markName as keyof docs_v1.Schema$TextStyle;
+ let value: any = true;
+ if (!converted) {
+ continue;
+ }
+ const { attrs } = mark;
+ switch (converted) {
+ case "link":
+ let url = attrs.href;
+ const delimiter = "/doc/";
+ const alreadyShared = "?sharing=true";
+ if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) {
+ const linkDoc = await DocServer.GetRefField(url.split(delimiter)[1]);
+ if (linkDoc instanceof Doc) {
+ const target = (await Cast(linkDoc.anchor2, Doc))!;
+ const exported = Doc.MakeAlias(target);
+ DocumentView.makeCustomViewClicked(exported);
+ target && (url = Utils.shareUrl(exported[Id]));
+ linkDoc.anchor2 = exported;
}
- textStyle[converted] = value;
}
- }
- });
- if (Object.keys(textStyle).length) {
- requests.push(EncodeStyleUpdate(information));
+ value = { url };
+ textStyle.foregroundColor = fromRgb.blue;
+ textStyle.bold = true;
+ break;
+ case "fontSize":
+ value = attrs.fontSize;
+ break;
+ case "foregroundColor":
+ value = fromHex(attrs.color);
+ break;
+ case "weightedFontFamily":
+ value = { fontFamily: FontFamilyMapping.get(markName) };
+ }
+ let matches: RegExpExecArray | null;
+ if ((matches = /p(\d+)/g.exec(markName)) !== null) {
+ converted = "fontSize";
+ value = { magnitude: parseInt(matches[1]), unit: "PT" };
}
+ textStyle[converted] = value;
+ }
+ if (Object.keys(textStyle).length) {
+ requests.push(EncodeStyleUpdate(information));
}
if (node.type.name === "image") {
requests.push(await EncodeImage({