aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/GlobalKeyHandler.ts2
-rw-r--r--src/client/views/PreviewCursor.tsx10
-rw-r--r--src/fields/Doc.ts51
3 files changed, 32 insertions, 31 deletions
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 3fbf6e445..f849b21e3 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -372,7 +372,7 @@ export class KeyManager {
list.push(doc);
}
if (count === docids.length) {
- const added = await Promise.all(list.filter(d => !docList.includes(d)).map(async d => (clone ? (await Doc.MakeClone(d)).clone : d)));
+ const added = await Promise.all(list.filter(d => !docList.includes(d)).map(async d => (clone ? (await Doc.MakeClone(d, ['links'])).clone : d)));
if (added.length) {
added.map(doc => (doc.context = targetDataDoc));
undoBatch(() => {
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 3712fff58..95ae65d7a 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -81,14 +81,8 @@ export class PreviewCursor extends React.Component<{}> {
const batch = UndoManager.StartBatch('cloning');
{
- const docs = await Promise.all(
- docids
- .filter((did, i) => i)
- .map(async did => {
- const doc = Cast(await DocServer.GetRefField(did), Doc, null);
- return clone ? (await Doc.MakeClone(doc)).clone : doc;
- })
- );
+ const toCopy = await Promise.all(docids.slice(1).map(async did => Cast(await DocServer.GetRefField(did), Doc, null)));
+ const docs = clone ? (await Promise.all(Doc.MakeClones(toCopy, false))).map(res => res.clone) : toCopy;
const firstx = docs.length ? NumCast(docs[0].x) + ptx - newPoint[0] : 0;
const firsty = docs.length ? NumCast(docs[0].y) + pty - newPoint[1] : 0;
docs.map(doc => {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index deda8aa1f..3169031b4 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -702,28 +702,28 @@ export namespace Doc {
return bestAlias ?? Doc.MakeAlias(doc);
}
- export async function makeClone(doc: Doc, cloneMap: Map<string, Doc>, linkMap: Map<string, Doc>, rtfs: { copy: Doc; key: string; field: RichTextField }[], exclusions: string[], dontCreate: boolean, asBranch: boolean): Promise<Doc> {
+ export async function makeClone(doc: Doc, cloneMap: Map<string, Doc>, linkMap: Map<string, Doc>, rtfs: { copy: Doc; key: string; field: RichTextField }[], exclusions: string[], cloneLinks: boolean, asBranch: boolean): Promise<Doc> {
if (Doc.IsBaseProto(doc)) return doc;
if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!;
- const copy = dontCreate ? (asBranch ? Cast(doc.branchMaster, Doc, null) ?? doc : doc) : new Doc(undefined, true);
+ const copy = new Doc(undefined, true);
cloneMap.set(doc[Id], copy);
const filter = [...exclusions, ...Cast(doc.cloneFieldFilter, listSpec('string'), [])];
await Promise.all(
Object.keys(doc).map(async key => {
if (filter.includes(key)) return;
- const assignKey = (val: any) => !dontCreate && (copy[key] = val);
+ const assignKey = (val: any) => (copy[key] = val);
const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
const field = ProxyField.WithoutProxy(() => doc[key]);
const copyObjectField = async (field: ObjectField) => {
const list = await Cast(doc[key], listSpec(Doc));
const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc);
if (docs !== undefined && docs.length) {
- const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch)));
- !dontCreate && assignKey(new List<Doc>(clones));
+ const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch)));
+ assignKey(new List<Doc>(clones));
} else if (doc[key] instanceof Doc) {
- assignKey(key.includes('layout[') ? undefined : key.startsWith('layout') ? (doc[key] as Doc) : await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded template fields
+ assignKey(key.includes('layout[') ? undefined : key.startsWith('layout') ? (doc[key] as Doc) : await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch)); // reference documents except copy documents that are expanded template fields
} else {
- !dontCreate && assignKey(ObjectField.MakeCopy(field));
+ assignKey(ObjectField.MakeCopy(field));
if (field instanceof RichTextField) {
if (field.Data.includes('"audioId":') || field.Data.includes('"textId":') || field.Data.includes('"anchorId":')) {
rtfs.push({ copy, key, field });
@@ -734,7 +734,7 @@ export namespace Doc {
const docAtKey = doc[key];
if (docAtKey instanceof Doc) {
if (!Doc.IsSystem(docAtKey) && (key === 'annotationOn' || key === 'proto' || ((key === 'anchor1' || key === 'anchor2') && doc.author === Doc.CurrentUserEmail))) {
- assignKey(await Doc.makeClone(docAtKey, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch));
+ assignKey(await Doc.makeClone(docAtKey, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch));
} else {
assignKey(docAtKey);
}
@@ -742,7 +742,7 @@ export namespace Doc {
if (field instanceof RefField) {
assignKey(field);
} else if (cfield instanceof ComputedField) {
- !dontCreate && assignKey(cfield[Copy]());
+ assignKey(cfield[Copy]());
// ComputedField.MakeFunction(cfield.script.originalScript));
} else if (field instanceof ObjectField) {
await copyObjectField(field);
@@ -754,18 +754,21 @@ export namespace Doc {
}
})
);
- for (const link of Array.from(doc[DirectLinksSym])) {
- const linkClone = await Doc.makeClone(link, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch);
- linkMap.set(link[Id], linkClone);
- }
- Doc.SetInPlace(copy, 'title', (asBranch ? 'BRANCH: ' : 'CLONE: ') + doc.title, true);
- if (!dontCreate) {
- asBranch ? (copy.branchOf = doc) : (copy.cloneOf = doc);
- if (!Doc.IsPrototype(copy)) {
- Doc.AddDocToList(doc, 'branches', Doc.GetProto(copy));
+ Array.from(doc[DirectLinksSym]).forEach(async link => {
+ if (
+ cloneLinks ||
+ ((cloneMap.has(DocCast(link.anchor1)?.[Id]) || cloneMap.has(DocCast(DocCast(link.anchor1)?.annotationOn)?.[Id])) && (cloneMap.has(DocCast(link.anchor2)?.[Id]) || cloneMap.has(DocCast(DocCast(link.anchor2)?.annotationOn)?.[Id])))
+ ) {
+ linkMap.set(link[Id], await Doc.makeClone(link, cloneMap, linkMap, rtfs, exclusions, cloneLinks, asBranch));
}
- cloneMap.set(doc[Id], copy);
+ });
+ Doc.SetInPlace(copy, 'title', (asBranch ? 'BRANCH: ' : 'CLONE: ') + doc.title, true);
+ asBranch ? (copy.branchOf = doc) : (copy.cloneOf = doc);
+ if (!Doc.IsPrototype(copy)) {
+ Doc.AddDocToList(doc, 'branches', Doc.GetProto(copy));
}
+ cloneMap.set(doc[Id], copy);
+
Doc.AddFileOrphan(copy);
return copy;
}
@@ -787,10 +790,14 @@ export namespace Doc {
}
});
}
- export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false, cloneMap: Map<string, Doc> = new Map()) {
+ export function MakeClones(docs: Doc[], cloneLinks: boolean, asBranch = false, cloneMap: Map<string, Doc> = new Map()) {
+ return docs.map(doc => Doc.MakeClone(doc, cloneLinks, asBranch, cloneMap));
+ }
+
+ export async function MakeClone(doc: Doc, cloneLinks = true, asBranch = false, cloneMap: Map<string, Doc> = new Map()) {
const linkMap = new Map<string, Doc>();
const rtfMap: { copy: Doc; key: string; field: RichTextField }[] = [];
- const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ['cloneOf', 'branches', 'branchOf'], dontCreate, asBranch);
+ const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ['cloneOf', 'branches', 'branchOf'], cloneLinks, asBranch);
const repaired = new Set<Doc>();
const linkedDocs = Array.from(linkMap.values());
const clonedDocs = [...Array.from(cloneMap.values()), ...linkedDocs];
@@ -818,7 +825,7 @@ export namespace Doc {
// a.href = url;
// a.download = `DocExport-${this.props.Document[Id]}.zip`;
// a.click();
- const { clone, map, linkMap } = await Doc.MakeClone(doc, false);
+ const { clone, map, linkMap } = await Doc.MakeClone(doc);
clone.LINKS = new List<Doc>(Array.from(linkMap.values()));
const proms = [] as string[];
function replacer(key: any, value: any) {