UNPKG

ngx-dynamic-hooks

Version:

Automatically insert live Angular components into a dynamic string of content (based on their selector or any pattern of your choice) and render the result in the DOM.

104 lines 16.3 kB
import { Injectable } from '@angular/core'; import { isAngularManagedElement, sortElements } from '../utils/utils'; import { anchorAttrHookId, anchorAttrParseToken } from '../../constants/core'; import * as i0 from "@angular/core"; import * as i1 from "../platform/autoPlatformService"; import * as i2 from "../utils/logger"; /** * The service responsible for finding element hooks in the content and marking them with anchor attrs */ export class ElementHookFinder { constructor(platformService, logger) { this.platformService = platformService; this.logger = logger; } /** * Finds all element hooks in an element and marks the corresponding anchor elements * * @param contentElement - The content element to parse * @param context - The current context object * @param parsers - The parsers to use * @param token - The current parse token * @param options - The current ParseOptions * @param hookIndex - The hookIndex object to fill */ find(contentElement, context, parsers, token, options, hookIndex) { // Collect all parser results let parserResults = []; for (const parser of parsers) { if (typeof parser.findHookElements === 'function') { for (const hookElement of parser.findHookElements(contentElement, context, options)) { parserResults.push({ parser, hookElement }); } } } parserResults = sortElements(parserResults, this.platformService.sortElements.bind(this.platformService), entry => entry.hookElement); // Validate parser results parserResults = this.validateHookElements(parserResults, contentElement, options); // Process parser results for (const pr of parserResults) { const hookId = Object.keys(hookIndex).length + 1; // Enter hook into index hookIndex[hookId] = { id: hookId, parser: pr.parser, value: { openingTag: this.platformService.getOpeningTag(pr.hookElement), closingTag: this.platformService.getClosingTag(pr.hookElement), element: pr.hookElement, elementSnapshot: this.platformService.cloneElement(pr.hookElement) }, data: null, isLazy: false, bindings: null, previousBindings: null, componentRef: null, dirtyInputs: new Set(), outputSubscriptions: {}, htmlEventSubscriptions: {} }; // Add anchor attrs this.platformService.setAttribute(pr.hookElement, anchorAttrHookId, hookId.toString()); this.platformService.setAttribute(pr.hookElement, anchorAttrParseToken, token); } return hookIndex; } /** * Checks the combined parserResults and validates them. Invalid ones are removed. * * @param parserResults - The parserResults to check * @param contentElement - The content element * @param options - The current ParseOptions */ validateHookElements(parserResults, contentElement, options) { const checkedParserResults = []; for (const [index, parserResult] of parserResults.entries()) { const previousCheckedParserResults = checkedParserResults.slice(0, index); const wasFoundAsElementHookAlready = previousCheckedParserResults.findIndex(entry => entry.hookElement === parserResult.hookElement) >= 0; // Must not already be a hook anchor (either from previous iteration of loop or text hook finder) if (wasFoundAsElementHookAlready || this.platformService.getAttributeNames(parserResult.hookElement).includes(anchorAttrHookId) || this.platformService.getAttributeNames(parserResult.hookElement).includes(anchorAttrParseToken)) { this.logger.warn(['An element hook tried to use an element that was found by another hook before. There may be multiple parsers looking for the same elements. Ignoring duplicates.', parserResult.hookElement], options); continue; } // Must not already be host or view element for an Angular component if (isAngularManagedElement(parserResult.hookElement)) { // this.logger.warn(['A hook element was found that is already a host or view element of an active Angular component. Ignoring.'], options); continue; } // If everything okay, add to result array checkedParserResults.push(parserResult); } return checkedParserResults; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ElementHookFinder, deps: [{ token: i1.AutoPlatformService }, { token: i2.Logger }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ElementHookFinder, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ElementHookFinder, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.AutoPlatformService }, { type: i2.Logger }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudEhvb2tGaW5kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHluYW1pYy1ob29rcy9zcmMvbGliL3NlcnZpY2VzL2NvcmUvZWxlbWVudEhvb2tGaW5kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7QUFZOUU7O0dBRUc7QUFJSCxNQUFNLE9BQU8saUJBQWlCO0lBRTVCLFlBQW9CLGVBQW9DLEVBQVUsTUFBYztRQUE1RCxvQkFBZSxHQUFmLGVBQWUsQ0FBcUI7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQ2hGLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSCxJQUFJLENBQUMsY0FBbUIsRUFBRSxPQUFZLEVBQUUsT0FBcUIsRUFBRSxLQUFhLEVBQUUsT0FBcUIsRUFBRSxTQUFvQjtRQUV2SCw2QkFBNkI7UUFDN0IsSUFBSSxhQUFhLEdBQW1DLEVBQUUsQ0FBQztRQUN2RCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzdCLElBQUksT0FBTyxNQUFNLENBQUMsZ0JBQWdCLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ2xELEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDcEYsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDO2dCQUM1QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFDRCxhQUFhLEdBQUcsWUFBWSxD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U0FBUztZQUNYLENBQUM7WUFFRCxvRUFBb0U7WUFDcEUsSUFBSSx1QkFBdUIsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDdEQsNElBQTRJO2dCQUM1SSxTQUFTO1lBQ1gsQ0FBQztZQUVELDBDQUEwQztZQUMxQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELE9BQU8sb0JBQW9CLENBQUM7SUFDOUIsQ0FBQzsrR0FsR1UsaUJBQWlCO21IQUFqQixpQkFBaUIsY0FGaEIsTUFBTTs7NEZBRVAsaUJBQWlCO2tCQUg3QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEhvb2tJbmRleCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXNQdWJsaWMnO1xuaW1wb3J0IHsgSG9va1BhcnNlciB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXNQdWJsaWMnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXV0b1BsYXRmb3JtU2VydmljZSB9IGZyb20gJy4uL3BsYXRmb3JtL2F1dG9QbGF0Zm9ybVNlcnZpY2UnO1xuaW1wb3J0IHsgaXNBbmd1bGFyTWFuYWdlZEVsZW1lbnQsIHNvcnRFbGVtZW50cyB9IGZyb20gJy4uL3V0aWxzL3V0aWxzJztcbmltcG9ydCB7IGFuY2hvckF0dHJIb29rSWQsIGFuY2hvckF0dHJQYXJzZVRva2VuIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL2NvcmUnO1xuaW1wb3J0IHsgUGFyc2VPcHRpb25zIH0gZnJvbSAnLi4vc2V0dGluZ3Mvb3B0aW9ucyc7XG5pbXBvcnQgeyBMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXInO1xuXG4vKipcbiAqIFN0b3JlcyBhIGhvb2sgZWxlbWVudCBhbG9uZyB3aXRoIHRoZSBwYXJzZXIgd2hvIGZvdW5kIGl0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VyRmluZEhvb2tFbGVtZW50c1Jlc3VsdCB7XG4gIHBhcnNlcjogSG9va1BhcnNlcjtcbiAgaG9va0VsZW1lbnQ6IGFueTtcbn1cblxuLyoqXG4gKiBUaGUgc2VydmljZSByZXNwb25zaWJsZSBmb3IgZmluZGluZyBlbGVtZW50IGhvb2tzIGluIHRoZSBjb250ZW50IGFuZCBtYXJraW5nIHRoZW0gd2l0aCBhbmNob3IgYXR0cnNcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgRWxlbWVudEhvb2tGaW5kZXIge1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcGxhdGZvcm1TZXJ2aWNlOiBBdXRvUGxhdGZvcm1TZXJ2aWNlLCBwcml2YXRlIGxvZ2dlcjogTG9nZ2VyKSB7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgYWxsIGVsZW1lbnQgaG9va3MgaW4gYW4gZWxlbWVudCBhbmQgbWFya3MgdGhlIGNvcnJlc3BvbmRpbmcgYW5jaG9yIGVsZW1lbnRzXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZW50RWxlbWVudCAtIFRoZSBjb250ZW50IGVsZW1lbnQgdG8gcGFyc2VcbiAgICogQHBhcmFtIGNvbnRleHQgLSBUaGUgY3VycmVudCBjb250ZXh0IG9iamVjdFxuICAgKiBAcGFyYW0gcGFyc2VycyAtIFRoZSBwYXJzZXJzIHRvIHVzZVxuICAgKiBAcGFyYW0gdG9rZW4gLSBUaGUgY3VycmVudCBwYXJzZSB0b2tlblxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBjdXJyZW50IFBhcnNlT3B0aW9uc1xuICAgKiBAcGFyYW0gaG9va0luZGV4IC0gVGhlIGhvb2tJbmRleCBvYmplY3QgdG8gZmlsbFxuICAgKi9cbiAgZmluZChjb250ZW50RWxlbWVudDogYW55LCBjb250ZXh0OiBhbnksIHBhcnNlcnM6IEhvb2tQYXJzZXJbXSwgdG9rZW46IHN0cmluZywgb3B0aW9uczogUGFyc2VPcHRpb25zLCBob29rSW5kZXg6IEhvb2tJbmRleCk6IEhvb2tJbmRleCB7XG5cbiAgICAvLyBDb2xsZWN0IGFsbCBwYXJzZXIgcmVzdWx0c1xuICAgIGxldCBwYXJzZXJSZXN1bHRzOiBQYXJzZXJGaW5kSG9va0VsZW1lbnRzUmVzdWx0W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhcnNlciBvZiBwYXJzZXJzKSB7XG4gICAgICBpZiAodHlwZW9mIHBhcnNlci5maW5kSG9va0VsZW1lbnRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZvciAoY29uc3QgaG9va0VsZW1lbnQgb2YgcGFyc2VyLmZpbmRIb29rRWxlbWVudHMoY29udGVudEVsZW1lbnQsIGNvbnRleHQsIG9wdGlvbnMpKSB7XG4gICAgICAgICAgcGFyc2VyUmVzdWx0cy5wdXNoKHtwYXJzZXIsIGhvb2tFbGVtZW50fSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcGFyc2VyUmVzdWx0cyA9IHNvcnRFbGVtZW50cyhwYXJzZXJSZXN1bHRzLCB0aGlzLnBsYXRmb3JtU2VydmljZS5zb3J0RWxlbWVudHMuYmluZCh0aGlzLnBsYXRmb3JtU2VydmljZSksIGVudHJ5ID0+IGVudHJ5Lmhvb2tFbGVtZW50KTtcblxuICAgIC8vIFZhbGlkYXRlIHBhcnNlciByZXN1bHRzXG4gICAgcGFyc2VyUmVzdWx0cyA9IHRoaXMudmFsaWRhdGVIb29rRWxlbWVudHMocGFyc2VyUmVzdWx0cywgY29udGVudEVsZW1lbnQsIG9wdGlvbnMpO1xuXG4gICAgLy8gUHJvY2VzcyBwYXJzZXIgcmVzdWx0c1xuICAgIGZvciAoY29uc3QgcHIgb2YgcGFyc2VyUmVzdWx0cykge1xuICAgICAgY29uc3QgaG9va0lkID0gT2JqZWN0LmtleXMoaG9va0luZGV4KS5sZW5ndGggKyAxO1xuXG4gICAgICAvLyBFbnRlciBob29rIGludG8gaW5kZXhcbiAgICAgIGhvb2tJbmRleFtob29rSWRdID0ge1xuICAgICAgICBpZDogaG9va0lkLFxuICAgICAgICBwYXJzZXI6IHByLnBhcnNlcixcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBvcGVuaW5nVGFnOiB0aGlzLnBsYXRmb3JtU2VydmljZS5nZXRPcGVuaW5nVGFnKHByLmhvb2tFbGVtZW50KSxcbiAgICAgICAgICBjbG9zaW5nVGFnOiB0aGlzLnBsYXRmb3JtU2VydmljZS5nZXRDbG9zaW5nVGFnKHByLmhvb2tFbGVtZW50KSxcbiAgICAgICAgICBlbGVtZW50OiBwci5ob29rRWxlbWVudCxcbiAgICAgICAgICBlbGVtZW50U25hcHNob3Q6IHRoaXMucGxhdGZvcm1TZXJ2aWNlLmNsb25lRWxlbWVudChwci5ob29rRWxlbWVudClcbiAgICAgICAgfSxcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgaXNMYXp5OiBmYWxzZSxcbiAgICAgICAgYmluZGluZ3M6IG51bGwsXG4gICAgICAgIHByZXZpb3VzQmluZGluZ3M6IG51bGwsXG4gICAgICAgIGNvbXBvbmVudFJlZjogbnVsbCxcbiAgICAgICAgZGlydHlJbnB1dHM6IG5ldyBTZXQoKSxcbiAgICAgICAgb3V0cHV0U3Vic2NyaXB0aW9uczoge30sXG4gICAgICAgIGh0bWxFdmVudFN1YnNjcmlwdGlvbnM6IHt9XG4gICAgICB9O1xuXG4gICAgICAvLyBBZGQgYW5jaG9yIGF0dHJzXG4gICAgICB0aGlzLnBsYXRmb3JtU2VydmljZS5zZXRBdHRyaWJ1dGUocHIuaG9va0VsZW1lbnQsIGFuY2hvckF0dHJIb29rSWQsIGhvb2tJZC50b1N0cmluZygpKTtcbiAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLnNldEF0dHJpYnV0ZShwci5ob29rRWxlbWVudCwgYW5jaG9yQXR0clBhcnNlVG9rZW4sIHRva2VuKTtcbiAgICB9XG5cbiAgICByZXR1cm4gaG9va0luZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyB0aGUgY29tYmluZWQgcGFyc2VyUmVzdWx0cyBhbmQgdmFsaWRhdGVzIHRoZW0uIEludmFsaWQgb25lcyBhcmUgcmVtb3ZlZC5cbiAgICpcbiAgICogQHBhcmFtIHBhcnNlclJlc3VsdHMgLSBUaGUgcGFyc2VyUmVzdWx0cyB0byBjaGVja1xuICAgKiBAcGFyYW0gY29udGVudEVsZW1lbnQgLSBUaGUgY29udGVudCBlbGVtZW50XG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGN1cnJlbnQgUGFyc2VPcHRpb25zXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlSG9va0VsZW1lbnRzKHBhcnNlclJlc3VsdHM6IFBhcnNlckZpbmRIb29rRWxlbWVudHNSZXN1bHRbXSwgY29udGVudEVsZW1lbnQ6IGFueSwgb3B0aW9uczogUGFyc2VPcHRpb25zKTogUGFyc2VyRmluZEhvb2tFbGVtZW50c1Jlc3VsdFtdIHtcbiAgICBjb25zdCBjaGVja2VkUGFyc2VyUmVzdWx0cyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbaW5kZXgsIHBhcnNlclJlc3VsdF0gb2YgcGFyc2VyUmVzdWx0cy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzQ2hlY2tlZFBhcnNlclJlc3VsdHMgPSBjaGVja2VkUGFyc2VyUmVzdWx0cy5zbGljZSgwLCBpbmRleCk7XG4gICAgICBjb25zdCB3YXNGb3VuZEFzRWxlbWVudEhvb2tBbHJlYWR5ID0gcHJldmlvdXNDaGVja2VkUGFyc2VyUmVzdWx0cy5maW5kSW5kZXgoZW50cnkgPT4gZW50cnkuaG9va0VsZW1lbnQgPT09IHBhcnNlclJlc3VsdC5ob29rRWxlbWVudCkgPj0gMDtcblxuICAgICAgLy8gTXVzdCBub3QgYWxyZWFkeSBiZSBhIGhvb2sgYW5jaG9yIChlaXRoZXIgZnJvbSBwcmV2aW91cyBpdGVyYXRpb24gb2YgbG9vcCBvciB0ZXh0IGhvb2sgZmluZGVyKVxuICAgICAgaWYgKFxuICAgICAgICB3YXNGb3VuZEFzRWxlbWVudEhvb2tBbHJlYWR5IHx8XG4gICAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLmdldEF0dHJpYnV0ZU5hbWVzKHBhcnNlclJlc3VsdC5ob29rRWxlbWVudCkuaW5jbHVkZXMoYW5jaG9yQXR0ckhvb2tJZCkgfHwgXG4gICAgICAgIHRoaXMucGxhdGZvcm1TZXJ2aWNlLmdldEF0dHJpYnV0ZU5hbWVzKHBhcnNlclJlc3VsdC5ob29rRWxlbWVudCkuaW5jbHVkZXMoYW5jaG9yQXR0clBhcnNlVG9rZW4pXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybihbJ0FuIGVsZW1lbnQgaG9vayB0cmllZCB0byB1c2UgYW4gZWxlbWVudCB0aGF0IHdhcyBmb3VuZCBieSBhbm90aGVyIGhvb2sgYmVmb3JlLiBUaGVyZSBtYXkgYmUgbXVsdGlwbGUgcGFyc2VycyBsb29raW5nIGZvciB0aGUgc2FtZSBlbGVtZW50cy4gSWdub3JpbmcgZHVwbGljYXRlcy4nLCBwYXJzZXJSZXN1bHQuaG9va0VsZW1lbnRdLCBvcHRpb25zKVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gTXVzdCBub3QgYWxyZWFkeSBiZSBob3N0IG9yIHZpZXcgZWxlbWVudCBmb3IgYW4gQW5ndWxhciBjb21wb25lbnRcbiAgICAgIGlmIChpc0FuZ3VsYXJNYW5hZ2VkRWxlbWVudChwYXJzZXJSZXN1bHQuaG9va0VsZW1lbnQpKSB7XG4gICAgICAgIC8vIHRoaXMubG9nZ2VyLndhcm4oWydBIGhvb2sgZWxlbWVudCB3YXMgZm91bmQgdGhhdCBpcyBhbHJlYWR5IGEgaG9zdCBvciB2aWV3IGVsZW1lbnQgb2YgYW4gYWN0aXZlIEFuZ3VsYXIgY29tcG9uZW50LiBJZ25vcmluZy4nXSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiBldmVyeXRoaW5nIG9rYXksIGFkZCB0byByZXN1bHQgYXJyYXlcbiAgICAgIGNoZWNrZWRQYXJzZXJSZXN1bHRzLnB1c2gocGFyc2VyUmVzdWx0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2hlY2tlZFBhcnNlclJlc3VsdHM7XG4gIH1cbiAgXG5cbn1cbiJdfQ==