ngx-notion
Version:
An Notion page renderer for Angular
86 lines • 11.9 kB
JavaScript
import { Component, Input } from '@angular/core';
import { BlockType } from '../../types';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "../blocks/block/block.component";
import * as i3 from "@angular/common";
export class RendererComponent {
constructor(route) {
this.route = route;
this.fullPage = false;
this.hideHeader = false;
}
set page(page) {
if (page.blocks) {
page.blocks = this.normalizeBlocks(page.blocks);
}
this._page = page;
}
get page() {
return this._page;
}
ngOnInit() {
this.route.fragment.subscribe(fragment => {
this.fragment = fragment;
if (this.fragment) {
this.scrollToFragment();
}
});
}
ngAfterViewInit() {
if (this.fragment) {
this.scrollToFragment();
}
}
getHeadings() {
const headings = [];
this.page.blocks.forEach((block) => {
if (block.type === BlockType.Heading1 ||
block.type === BlockType.Heading2 ||
block.type === BlockType.Heading3) {
headings.push(block);
}
});
return headings;
}
trackByFn(index, block) {
return block.id;
}
normalizeBlocks(blocks) {
let index = 0;
for (let i = 0; i < blocks.length; i++) {
if (i > 0) {
if (blocks[i].type === blocks[i - 1].type) {
index++;
}
else {
index = 0;
}
}
blocks[i]['index'] = index;
if (blocks[i].blocks.length) {
blocks[i].blocks = this.normalizeBlocks(blocks[i].blocks);
}
}
return blocks;
}
scrollToFragment() {
try {
document.getElementById(this.fragment).scrollIntoView();
}
catch (e) { }
}
}
RendererComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: RendererComponent, deps: [{ token: i1.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Component });
RendererComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: RendererComponent, selector: "notion-renderer", inputs: { page: "page", fullPage: "fullPage", hideHeader: "hideHeader" }, ngImport: i0, template: "<div class=\"notion\">\n <ng-container *ngFor=\"let block of page.blocks; let i = index; trackBy: trackByFn\">\n <block\n [class]=\"'type-' + block.type\"\n [block]=\"block\"\n [previousBlock]=\"i > 0 ? page.blocks[i - 1] : null\"\n [headings]=\"getHeadings()\"\n ></block>\n </ng-container>\n</div>\n", styles: [".notion{font-size:16px;line-height:1.5;color:#37352f;caret-color:#37352f;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,\"Apple Color Emoji\",Arial,sans-serif,\"Segoe UI Emoji\",Segoe UI Symbol}.notion ::ng-deep *{box-sizing:border-box;margin-block-start:0px;margin-block-end:0px}.notion ::ng-deep h1{margin-top:1.4em}.notion ::ng-deep h1:first-child{margin-top:0}.notion ::ng-deep h2{margin-top:1.1em}.notion ::ng-deep h3{margin-top:1em}.notion ::ng-deep table{margin-top:8px;margin-bottom:18px}\n"], components: [{ type: i2.BlockComponent, selector: "block", inputs: ["block", "previousBlock", "headings", "level"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: RendererComponent, decorators: [{
type: Component,
args: [{ selector: 'notion-renderer', template: "<div class=\"notion\">\n <ng-container *ngFor=\"let block of page.blocks; let i = index; trackBy: trackByFn\">\n <block\n [class]=\"'type-' + block.type\"\n [block]=\"block\"\n [previousBlock]=\"i > 0 ? page.blocks[i - 1] : null\"\n [headings]=\"getHeadings()\"\n ></block>\n </ng-container>\n</div>\n", styles: [".notion{font-size:16px;line-height:1.5;color:#37352f;caret-color:#37352f;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,\"Apple Color Emoji\",Arial,sans-serif,\"Segoe UI Emoji\",Segoe UI Symbol}.notion ::ng-deep *{box-sizing:border-box;margin-block-start:0px;margin-block-end:0px}.notion ::ng-deep h1{margin-top:1.4em}.notion ::ng-deep h1:first-child{margin-top:0}.notion ::ng-deep h2{margin-top:1.1em}.notion ::ng-deep h3{margin-top:1em}.notion ::ng-deep table{margin-top:8px;margin-bottom:18px}\n"] }]
}], ctorParameters: function () { return [{ type: i1.ActivatedRoute }]; }, propDecorators: { page: [{
type: Input
}], fullPage: [{
type: Input
}], hideHeader: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW5vdGlvbi9zcmMvbGliL2NvbXBvbmVudHMvcmVuZGVyZXIvcmVuZGVyZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW5vdGlvbi9zcmMvbGliL2NvbXBvbmVudHMvcmVuZGVyZXIvcmVuZGVyZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR2hFLE9BQU8sRUFBUyxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7O0FBTy9DLE1BQU0sT0FBTyxpQkFBaUI7SUF3QjFCLFlBQW9CLEtBQXFCO1FBQXJCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBVHpDLGFBQVEsR0FBWSxLQUFLLENBQUM7UUFHMUIsZUFBVSxHQUFZLEtBQUssQ0FBQztJQU1pQixDQUFDO0lBdkI5QyxJQUNJLElBQUksQ0FBQyxJQUFTO1FBQ2QsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUNuRDtRQUVELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQWNELFFBQVE7UUFDSixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDckMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7WUFFekIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2FBQzNCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsZUFBZTtRQUNYLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQzNCO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDUCxNQUFNLFFBQVEsR0FBVSxFQUFFLENBQUM7UUFFM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDcEMsSUFDSSxLQUFLLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxRQUFRO2dCQUNqQyxLQUFLLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxRQUFRO2dCQUNqQyxLQUFLLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxRQUFRLEVBQ25DO2dCQUNFLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sUUFBUSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYSxFQUFFLEtBQVk7UUFDakMsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTyxlQUFlLENBQUMsTUFBZTtRQUNuQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFFZCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ1AsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFO29CQUN2QyxLQUFLLEVBQUUsQ0FBQztpQkFDWDtxQkFBTTtvQkFDSCxLQUFLLEdBQUcsQ0FBQyxDQUFDO2lCQUNiO2FBQ0o7WUFFRCxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBRTNCLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0JBQ3pCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDN0Q7U0FDSjtRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFTyxnQkFBZ0I7UUFDcEIsSUFBSTtZQUNDLFFBQWdCLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUNwRTtRQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUc7SUFDbkIsQ0FBQzs7OEdBeEZRLGlCQUFpQjtrR0FBakIsaUJBQWlCLGlJQ1Y5QiwrV0FVQTsyRkRBYSxpQkFBaUI7a0JBTDdCLFNBQVM7K0JBQ0ksaUJBQWlCO3FHQU12QixJQUFJO3NCQURQLEtBQUs7Z0JBY04sUUFBUTtzQkFEUCxLQUFLO2dCQUlOLFVBQVU7c0JBRFQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHsgQmxvY2ssIEJsb2NrVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdub3Rpb24tcmVuZGVyZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9yZW5kZXJlci5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vcmVuZGVyZXIuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgUmVuZGVyZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcbiAgICBASW5wdXQoKVxuICAgIHNldCBwYWdlKHBhZ2U6IGFueSkge1xuICAgICAgICBpZiAocGFnZS5ibG9ja3MpIHtcbiAgICAgICAgICAgIHBhZ2UuYmxvY2tzID0gdGhpcy5ub3JtYWxpemVCbG9ja3MocGFnZS5ibG9ja3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gICAgfVxuXG4gICAgZ2V0IHBhZ2UoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gICAgfVxuXG4gICAgQElucHV0KClcbiAgICBmdWxsUGFnZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgQElucHV0KClcbiAgICBoaWRlSGVhZGVyOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBmcmFnbWVudDogYW55O1xuXG4gICAgcHJpdmF0ZSBfcGFnZTogYW55O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUpIHsgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMucm91dGUuZnJhZ21lbnQuc3Vic2NyaWJlKGZyYWdtZW50ID0+IHsgXG4gICAgICAgICAgICB0aGlzLmZyYWdtZW50ID0gZnJhZ21lbnQ7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmZyYWdtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxUb0ZyYWdtZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZnJhZ21lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9GcmFnbWVudCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0SGVhZGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IGhlYWRpbmdzOiBhbnlbXSA9IFtdO1xuXG4gICAgICAgIHRoaXMucGFnZS5ibG9ja3MuZm9yRWFjaCgoYmxvY2s6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGJsb2NrLnR5cGUgPT09IEJsb2NrVHlwZS5IZWFkaW5nMSB8fFxuICAgICAgICAgICAgICAgIGJsb2NrLnR5cGUgPT09IEJsb2NrVHlwZS5IZWFkaW5nMiB8fFxuICAgICAgICAgICAgICAgIGJsb2NrLnR5cGUgPT09IEJsb2NrVHlwZS5IZWFkaW5nM1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgaGVhZGluZ3MucHVzaChibG9jayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBoZWFkaW5ncztcbiAgICB9XG5cbiAgICB0cmFja0J5Rm4oaW5kZXg6IG51bWJlciwgYmxvY2s6IEJsb2NrKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGJsb2NrLmlkO1xuICAgIH1cblxuICAgIHByaXZhdGUgbm9ybWFsaXplQmxvY2tzKGJsb2NrczogQmxvY2tbXSk6IEJsb2NrW10ge1xuICAgICAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmxvY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoYmxvY2tzW2ldLnR5cGUgPT09IGJsb2Nrc1tpIC0gMV0udHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJsb2Nrc1tpXVsnaW5kZXgnXSA9IGluZGV4O1xuXG4gICAgICAgICAgICBpZiAoYmxvY2tzW2ldLmJsb2Nrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBibG9ja3NbaV0uYmxvY2tzID0gdGhpcy5ub3JtYWxpemVCbG9ja3MoYmxvY2tzW2ldLmJsb2Nrcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYmxvY2tzO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2Nyb2xsVG9GcmFnbWVudCgpOiB2b2lkIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIChkb2N1bWVudCBhcyBhbnkpLmdldEVsZW1lbnRCeUlkKHRoaXMuZnJhZ21lbnQpLnNjcm9sbEludG9WaWV3KCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJub3Rpb25cIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBibG9jayBvZiBwYWdlLmJsb2NrczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUZuXCI+XG4gICAgICAgIDxibG9ja1xuICAgICAgICAgICAgW2NsYXNzXT1cIid0eXBlLScgKyBibG9jay50eXBlXCJcbiAgICAgICAgICAgIFtibG9ja109XCJibG9ja1wiXG4gICAgICAgICAgICBbcHJldmlvdXNCbG9ja109XCJpID4gMCA/IHBhZ2UuYmxvY2tzW2kgLSAxXSA6IG51bGxcIlxuICAgICAgICAgICAgW2hlYWRpbmdzXT1cImdldEhlYWRpbmdzKClcIlxuICAgICAgICA+PC9ibG9jaz5cbiAgICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuIl19