@foblex/m-render 3.0.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
@
|
|
2
|
-
@
|
|
3
|
-
@
|
|
4
|
-
@
|
|
5
|
-
@
|
|
6
|
-
@
|
|
7
|
-
@
|
|
8
|
-
@
|
|
9
|
-
@
|
|
10
|
-
@
|
|
11
|
-
@
|
|
12
|
-
@
|
|
1
|
+
@use "./variables";
|
|
2
|
+
@use "./badge";
|
|
3
|
+
@use "./alert";
|
|
4
|
+
@use "./button";
|
|
5
|
+
@use "./fonts";
|
|
6
|
+
@use "./icons";
|
|
7
|
+
@use "./preview-group";
|
|
8
|
+
@use "./code-group";
|
|
9
|
+
@use "./code-view";
|
|
10
|
+
@use "./code-highlight";
|
|
11
|
+
@use "./doc-text";
|
|
12
|
+
@use "./table";
|
|
13
13
|
|
|
14
14
|
html {
|
|
15
15
|
height: 100%;
|
|
@@ -1351,8 +1351,10 @@ class MarkdownService {
|
|
|
1351
1351
|
_provider = inject(F_PREVIEW_NAVIGATION_PROVIDER, { optional: true });
|
|
1352
1352
|
_pageLayout = signal({ ...DEFAULT_MARKDOWN_PAGE_LAYOUT_OPTIONS }, ...(ngDevMode ? [{ debugName: "_pageLayout" }] : []));
|
|
1353
1353
|
_pageSeo = signal(null, ...(ngDevMode ? [{ debugName: "_pageSeo" }] : []));
|
|
1354
|
+
_pageOrigin = signal(null, ...(ngDevMode ? [{ debugName: "_pageOrigin" }] : []));
|
|
1354
1355
|
pageLayout = this._pageLayout.asReadonly();
|
|
1355
1356
|
pageSeo = this._pageSeo.asReadonly();
|
|
1357
|
+
pageOrigin = this._pageOrigin.asReadonly();
|
|
1356
1358
|
constructor() {
|
|
1357
1359
|
this._markdown
|
|
1358
1360
|
.use((x) => new ParseSingleCodeItem().render(x))
|
|
@@ -1425,15 +1427,17 @@ class MarkdownService {
|
|
|
1425
1427
|
_parseFrontMatterData(rawFrontMatter) {
|
|
1426
1428
|
const layout = { ...DEFAULT_MARKDOWN_PAGE_LAYOUT_OPTIONS };
|
|
1427
1429
|
const seo = {};
|
|
1430
|
+
const origin = { url: null, label: null };
|
|
1428
1431
|
rawFrontMatter
|
|
1429
1432
|
.split(/\r?\n/)
|
|
1430
|
-
.forEach((line) => this._parseFrontMatterLine(line, layout, seo));
|
|
1433
|
+
.forEach((line) => this._parseFrontMatterLine(line, layout, seo, origin));
|
|
1431
1434
|
return {
|
|
1432
1435
|
layout,
|
|
1433
1436
|
seo: Object.keys(seo).length ? seo : null,
|
|
1437
|
+
origin: this._resolveOrigin(origin),
|
|
1434
1438
|
};
|
|
1435
1439
|
}
|
|
1436
|
-
_parseFrontMatterLine(line, layout, seo) {
|
|
1440
|
+
_parseFrontMatterLine(line, layout, seo, origin) {
|
|
1437
1441
|
const normalizedLine = line.trim();
|
|
1438
1442
|
if (!normalizedLine || normalizedLine.startsWith('#')) {
|
|
1439
1443
|
return;
|
|
@@ -1450,6 +1454,7 @@ class MarkdownService {
|
|
|
1450
1454
|
const boolValue = this._parseBoolean(value);
|
|
1451
1455
|
this._applyLayoutKey(key, boolValue, layout);
|
|
1452
1456
|
this._applySeoKey(key, value, boolValue, seo);
|
|
1457
|
+
this._applyOriginKey(key, value, origin);
|
|
1453
1458
|
}
|
|
1454
1459
|
_normalizeFrontMatterValue(value) {
|
|
1455
1460
|
const trimmed = value.trim();
|
|
@@ -1574,6 +1579,71 @@ class MarkdownService {
|
|
|
1574
1579
|
return;
|
|
1575
1580
|
}
|
|
1576
1581
|
}
|
|
1582
|
+
_applyOriginKey(key, value, origin) {
|
|
1583
|
+
switch (key) {
|
|
1584
|
+
case 'origin':
|
|
1585
|
+
case 'originurl':
|
|
1586
|
+
case 'origin_url':
|
|
1587
|
+
case 'original':
|
|
1588
|
+
case 'originalurl':
|
|
1589
|
+
case 'original_url':
|
|
1590
|
+
case 'source':
|
|
1591
|
+
case 'sourceurl':
|
|
1592
|
+
case 'source_url': {
|
|
1593
|
+
const normalizedUrl = this._normalizeOriginUrl(value);
|
|
1594
|
+
if (normalizedUrl) {
|
|
1595
|
+
origin.url = normalizedUrl;
|
|
1596
|
+
}
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
case 'originlabel':
|
|
1600
|
+
case 'origin_label':
|
|
1601
|
+
case 'origintext':
|
|
1602
|
+
case 'origin_text':
|
|
1603
|
+
case 'sourcelabel':
|
|
1604
|
+
case 'source_label':
|
|
1605
|
+
origin.label = value;
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
_normalizeOriginUrl(value) {
|
|
1610
|
+
const trimmed = value.trim();
|
|
1611
|
+
if (!trimmed) {
|
|
1612
|
+
return null;
|
|
1613
|
+
}
|
|
1614
|
+
const candidate = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
1615
|
+
try {
|
|
1616
|
+
const url = new URL(candidate);
|
|
1617
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
1618
|
+
return null;
|
|
1619
|
+
}
|
|
1620
|
+
return url.toString();
|
|
1621
|
+
}
|
|
1622
|
+
catch {
|
|
1623
|
+
return null;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
_resolveOrigin(origin) {
|
|
1627
|
+
if (!origin.url) {
|
|
1628
|
+
return null;
|
|
1629
|
+
}
|
|
1630
|
+
return {
|
|
1631
|
+
url: origin.url,
|
|
1632
|
+
label: origin.label || this._getOriginLabel(origin.url),
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
_getOriginLabel(originUrl) {
|
|
1636
|
+
try {
|
|
1637
|
+
const hostname = new URL(originUrl).hostname.toLowerCase().replace(/^www\./, '');
|
|
1638
|
+
if (hostname === 'medium.com' || hostname.endsWith('.medium.com')) {
|
|
1639
|
+
return 'Originally published on Medium';
|
|
1640
|
+
}
|
|
1641
|
+
return `Originally published on ${hostname}`;
|
|
1642
|
+
}
|
|
1643
|
+
catch {
|
|
1644
|
+
return 'Originally published externally';
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1577
1647
|
_parseNumberOrDefault(value, fallback) {
|
|
1578
1648
|
const numericValue = Number(value);
|
|
1579
1649
|
if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
|
@@ -1584,6 +1654,7 @@ class MarkdownService {
|
|
|
1584
1654
|
_applyPageContext(data) {
|
|
1585
1655
|
this._pageLayout.set({ ...data.layout });
|
|
1586
1656
|
this._pageSeo.set(data.seo ? { ...data.seo } : null);
|
|
1657
|
+
this._pageOrigin.set(data.origin ? { ...data.origin } : null);
|
|
1587
1658
|
}
|
|
1588
1659
|
_resetPageContext() {
|
|
1589
1660
|
this._applyPageContext(this._getDefaultFrontMatterData());
|
|
@@ -1592,6 +1663,7 @@ class MarkdownService {
|
|
|
1592
1663
|
return {
|
|
1593
1664
|
layout: { ...DEFAULT_MARKDOWN_PAGE_LAYOUT_OPTIONS },
|
|
1594
1665
|
seo: null,
|
|
1666
|
+
origin: null,
|
|
1595
1667
|
};
|
|
1596
1668
|
}
|
|
1597
1669
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -3461,6 +3533,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
|
|
|
3461
3533
|
|
|
3462
3534
|
class MarkdownRenderer {
|
|
3463
3535
|
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
3536
|
+
origin = input(null, ...(ngDevMode ? [{ debugName: "origin" }] : []));
|
|
3464
3537
|
_hostElement = inject(ElementRef).nativeElement;
|
|
3465
3538
|
_router = inject(Router);
|
|
3466
3539
|
_injector = inject(Injector);
|
|
@@ -3507,14 +3580,14 @@ class MarkdownRenderer {
|
|
|
3507
3580
|
this._dynamicComponents.dispose();
|
|
3508
3581
|
}
|
|
3509
3582
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3510
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownRenderer, isStandalone: true, selector: "markdown-renderer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "_onDocumentClick($event)" }, classAttribute: "m-render" }, ngImport: i0, template: "<div [innerHTML]=\"value()\"></div>\n@if (value()) {\n <markdown-footer />\n}\n
|
|
3583
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: MarkdownRenderer, isStandalone: true, selector: "markdown-renderer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "_onDocumentClick($event)" }, classAttribute: "m-render" }, ngImport: i0, template: "@if (origin(); as pageOrigin) {\n <p class=\"origin-link\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}:</span>\n <a [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </p>\n}\n<div [innerHTML]=\"value()\"></div>\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding))}}@media(min-width:1280px){:host.expand-no-toc{width:100%}}:host.empty-navigation{margin:auto;max-width:900px}.origin-link{margin:0 0 16px;border-left:2px solid var(--divider-color);padding:8px 12px;background-color:var(--soft-background);line-height:20px;font-size:14px}.origin-link-label{margin-right:4px;font-weight:600}.origin-link a{overflow-wrap:anywhere}\n"], dependencies: [{ kind: "component", type: MarkdownFooter, selector: "markdown-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3511
3584
|
}
|
|
3512
3585
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRenderer, decorators: [{
|
|
3513
3586
|
type: Component,
|
|
3514
3587
|
args: [{ selector: 'markdown-renderer', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MarkdownFooter], host: {
|
|
3515
3588
|
class: 'm-render',
|
|
3516
|
-
}, template: "<div [innerHTML]=\"value()\"></div>\n@if (value()) {\n <markdown-footer />\n}\n
|
|
3517
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], _onDocumentClick: [{
|
|
3589
|
+
}, template: "@if (origin(); as pageOrigin) {\n <p class=\"origin-link\">\n <span class=\"origin-link-label\">{{ pageOrigin.label }}:</span>\n <a [href]=\"pageOrigin.url\"\n target=\"_blank\"\n rel=\"noopener noreferrer nofollow\">{{ pageOrigin.url }}</a>\n </p>\n}\n<div [innerHTML]=\"value()\"></div>\n@if (value()) {\n <markdown-footer />\n}\n", styles: [":host{display:block;width:100%}@media(min-width:1280px){:host{width:calc(100% - var(--on-page-navigation-width) - var(--page-padding))}}@media(min-width:1280px){:host.expand-no-toc{width:100%}}:host.empty-navigation{margin:auto;max-width:900px}.origin-link{margin:0 0 16px;border-left:2px solid var(--divider-color);padding:8px 12px;background-color:var(--soft-background);line-height:20px;font-size:14px}.origin-link-label{margin-right:4px;font-weight:600}.origin-link a{overflow-wrap:anywhere}\n"] }]
|
|
3590
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], origin: [{ type: i0.Input, args: [{ isSignal: true, alias: "origin", required: false }] }], _onDocumentClick: [{
|
|
3518
3591
|
type: HostListener,
|
|
3519
3592
|
args: ['click', ['$event']]
|
|
3520
3593
|
}] } });
|
|
@@ -3526,6 +3599,7 @@ class MarkdownRouter {
|
|
|
3526
3599
|
_dataProvider = inject(DocumentationStore);
|
|
3527
3600
|
_metaService = inject(FMetaService, { optional: true });
|
|
3528
3601
|
emptyNavigation = !this._dataProvider.getNavigation().length;
|
|
3602
|
+
pageOrigin = this._markdown.pageOrigin;
|
|
3529
3603
|
shouldExpandContent = computed(() => {
|
|
3530
3604
|
const layout = this._markdown.pageLayout();
|
|
3531
3605
|
return layout.hideTableOfContent && layout.expandContentWithoutTableOfContent;
|
|
@@ -3539,7 +3613,7 @@ class MarkdownRouter {
|
|
|
3539
3613
|
}), tap(() => this._metaService?.applyMarkdownSeo(this._markdown.pageSeo())));
|
|
3540
3614
|
})), { initialValue: undefined });
|
|
3541
3615
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRouter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3542
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: MarkdownRouter, isStandalone: true, selector: "markdown-router", host: { attributes: { "ngSkipHydration": "" }, properties: { "class.empty-navigation": "emptyNavigation" } }, ngImport: i0, template: "<markdown-renderer [value]=\"html()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"], dependencies: [{ kind: "component", type: MarkdownRenderer, selector: "markdown-renderer", inputs: ["value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3616
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: MarkdownRouter, isStandalone: true, selector: "markdown-router", host: { attributes: { "ngSkipHydration": "" }, properties: { "class.empty-navigation": "emptyNavigation" } }, ngImport: i0, template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"], dependencies: [{ kind: "component", type: MarkdownRenderer, selector: "markdown-renderer", inputs: ["value", "origin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3543
3617
|
}
|
|
3544
3618
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: MarkdownRouter, decorators: [{
|
|
3545
3619
|
type: Component,
|
|
@@ -3548,7 +3622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
|
|
|
3548
3622
|
'[class.empty-navigation]': 'emptyNavigation',
|
|
3549
3623
|
}, imports: [
|
|
3550
3624
|
MarkdownRenderer,
|
|
3551
|
-
], template: "<markdown-renderer [value]=\"html()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"] }]
|
|
3625
|
+
], template: "<markdown-renderer [value]=\"html()\"\n [origin]=\"pageOrigin()\"\n [class.empty-navigation]=\"emptyNavigation\"\n [class.expand-no-toc]=\"shouldExpandContent()\"/>\n", styles: [":host{display:block;width:100%;padding:48px var(--page-padding) 140px}@media(min-width:1280px){:host{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 4)}}@media(min-width:1280px){:host.empty-navigation{padding-right:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2);padding-left:max(var(--page-padding),(100vw - var(--layout-max-width)) / 2)}}\n"] }]
|
|
3552
3626
|
}] });
|
|
3553
3627
|
|
|
3554
3628
|
var index$2 = /*#__PURE__*/Object.freeze({
|