Make internal hyperlink declarative

This commit is contained in:
Dolan Miu
2019-12-21 03:31:09 +00:00
parent c68dc8c52a
commit 3fdbca939e
7 changed files with 52 additions and 27 deletions

View File

@ -2,10 +2,21 @@ import { XmlComponent } from "file/xml-components";
import { DocumentAttributes } from "../document/document-attributes";
import { INumberingOptions } from "../numbering";
import { Paragraph } from "../paragraph";
import { HyperlinkType, Paragraph } from "../paragraph";
import { IStylesOptions } from "../styles";
import { Created, Creator, Description, Keywords, LastModifiedBy, Modified, Revision, Subject, Title } from "./components";
export interface IInternalHyperlinkDefinition {
readonly text: string;
readonly type: HyperlinkType.INTERNAL;
}
export interface IExternalHyperlinkDefinition {
readonly link: string;
readonly text: string;
readonly type: HyperlinkType.EXTERNAL;
}
export interface IPropertiesOptions {
readonly title?: string;
readonly subject?: string;
@ -19,10 +30,7 @@ export interface IPropertiesOptions {
readonly numbering?: INumberingOptions;
readonly footnotes?: Paragraph[];
readonly hyperlinks?: {
readonly [key: string]: {
readonly link: string;
readonly text: string;
};
readonly [key: string]: IInternalHyperlinkDefinition | IExternalHyperlinkDefinition;
};
}

View File

@ -17,7 +17,7 @@ import { Footer, Header } from "./header";
import { HeaderWrapper, IDocumentHeader } from "./header-wrapper";
import { Media } from "./media";
import { Numbering } from "./numbering";
import { Bookmark, Hyperlink, HyperlinkRef, Paragraph } from "./paragraph";
import { Bookmark, Hyperlink, HyperlinkRef, HyperlinkType, Paragraph } from "./paragraph";
import { Relationships } from "./relationships";
import { TargetModeType } from "./relationships/relationship/relationship";
import { Settings } from "./settings";
@ -158,7 +158,13 @@ export class File {
continue;
}
const hyperlink = this.createHyperlink(options.hyperlinks[key].link, options.hyperlinks[key].text);
const hyperlinkRef = options.hyperlinks[key];
const hyperlink =
hyperlinkRef.type === HyperlinkType.EXTERNAL
? this.createHyperlink(hyperlinkRef.link, hyperlinkRef.text)
: this.createInternalHyperLink(key, hyperlinkRef.text);
cache[key] = hyperlink;
}
@ -166,14 +172,6 @@ export class File {
}
}
public createInternalHyperLink(anchor: string, text?: string): Hyperlink {
const newText = text === undefined ? anchor : text;
const hyperlink = new Hyperlink(newText, shortid.generate().toLowerCase(), anchor);
// NOTE: unlike File#createHyperlink(), since the link is to an internal bookmark
// we don't need to create a new relationship.
return hyperlink;
}
public createBookmark(name: string, text: string = name): Bookmark {
return new Bookmark(name, text, this.docRelationships.RelationshipCount);
}
@ -219,9 +217,8 @@ export class File {
}
}
private createHyperlink(link: string, text?: string): Hyperlink {
const newText = text === undefined ? link : text;
const hyperlink = new Hyperlink(newText, shortid.generate().toLowerCase());
private createHyperlink(link: string, text: string = link): Hyperlink {
const hyperlink = new Hyperlink(text, shortid.generate().toLowerCase());
this.docRelationships.createRelationship(
hyperlink.linkId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
@ -231,6 +228,13 @@ export class File {
return hyperlink;
}
private createInternalHyperLink(anchor: string, text: string = anchor): Hyperlink {
const hyperlink = new Hyperlink(text, shortid.generate().toLowerCase(), anchor);
// NOTE: unlike File#createHyperlink(), since the link is to an internal bookmark
// we don't need to create a new relationship.
return hyperlink;
}
private createHeader(header: Header): HeaderWrapper {
const wrapper = new HeaderWrapper(this.media, this.currentRelationshipId++);

View File

@ -3,6 +3,10 @@ import { XmlComponent } from "file/xml-components";
import { TextRun } from "../run";
import { BookmarkEndAttributes, BookmarkStartAttributes } from "./bookmark-attributes";
export class BookmarkRef {
constructor(public readonly name: string, public readonly text: string) {}
}
export class Bookmark {
public readonly linkId: number;
public readonly start: BookmarkStart;

View File

@ -3,6 +3,11 @@ import { XmlComponent } from "file/xml-components";
import { TextRun } from "../run";
import { HyperlinkAttributes, IHyperlinkAttributesProperties } from "./hyperlink-attributes";
export enum HyperlinkType {
INTERNAL = "INTERNAL",
EXTERNAL = "EXTERNAL",
}
export class HyperlinkRef {
constructor(public readonly id: string) {}
}

View File

@ -13,7 +13,7 @@ import { ContextualSpacing, ISpacingProperties, Spacing } from "./formatting/spa
import { HeadingLevel, Style } from "./formatting/style";
import { LeaderType, TabStop, TabStopPosition, TabStopType } from "./formatting/tab-stop";
import { NumberProperties } from "./formatting/unordered-list";
import { Bookmark, HyperlinkRef, OutlineLevel } from "./links";
import { Bookmark, BookmarkRef, HyperlinkRef, OutlineLevel } from "./links";
import { ParagraphProperties } from "./properties";
import { PictureRun, Run, SequentialIdentifier, SymbolRun, TextRun } from "./run";
@ -46,7 +46,7 @@ export interface IParagraphOptions {
readonly custom?: boolean;
};
readonly children?: Array<
TextRun | PictureRun | SymbolRun | Bookmark | PageBreak | SequentialIdentifier | FootnoteReferenceRun | HyperlinkRef
TextRun | PictureRun | SymbolRun | Bookmark | PageBreak | SequentialIdentifier | FootnoteReferenceRun | HyperlinkRef | BookmarkRef
>;
}