UNPKG

igniteui-react-core

Version:
260 lines (259 loc) 11.1 kB
import { Guid } from './Guid'; import { TypeRegistrar } from "./type"; export class ReactTemplateAdapter { constructor(renderer, portalManager, propertyName, igTemplating, createExternal) { this._value = null; this._initializing = new Set(); this._templateContents = new Map(); this._waiting = new Map(); this._renderer = renderer; this._portalManager = portalManager; this._propertyName = propertyName; this._igTemplating = igTemplating; this._createExternal = createExternal; } createMutationObserver(...args) { let origObserver = MutationObserver; if (window.Zone && window.Zone.__symbol__) { origObserver = window[window.Zone.__symbol__('MutationObserver')] || window[window.Zone.__symbol__('WebKitMutationObserver')]; } return new origObserver(...args); } setValue(target, value) { if (value === this._value) { return; } this._value = value; let html = this._igTemplating.html; var currTemplate = null; var templateId = Guid.newGuid().toString(); let self = this; var litTemplate = function (context) { if (!context) { return html `<div></div>`; } let contentId = context.___contentId; if (context.___immediate || (context.i && context.i.___immediate) || (context.i && context.i.nativeElement && context.i.nativeElement.___immediate) || (context.nativeElement && context.nativeElement.___immediate)) { let innerContext = context; if (!contentId && context.i && context.i.___contentId) { contentId = context.i.___contentId; innerContext = context.i; } if (!contentId && context.i && context.i.nativeElement && context.i.nativeElement.___contentId) { contentId = context.i.nativeElement.___contentId; innerContext = context.i.nativeElement; } if (!contentId && context.nativeElement && context.nativeElement.___contentId) { contentId = context.nativeElement.___contentId; innerContext = context.nativeElement; } var template = currTemplate; if (!template.___currentContextMap) { template.___currentContextMap = new Map(); } let currentContext = null; if (template.___currentContextMap.has(contentId)) { currentContext = template.___currentContextMap.get(contentId); } template.___currentContextMap.set(contentId, innerContext); self.adjustDynamicContent(null, template.___templateId, contentId, "Update", context); if (innerContext.___root) { let root = innerContext.___root; if (!root.___host) { var host = root.querySelector("#" + 'host-' + contentId); if (host) { root.___host = host; template.___checkHost(template, root, root.___host); } } else { if (root.___host) { template.___checkHost(template, root, root.___host); } } } } return html `<div id="${'host-' + contentId}" style="display: contents;"> </div>`; }; currTemplate = litTemplate; litTemplate.___isBridged = true; litTemplate.___templateId = templateId; litTemplate.___onTemplateInit = (template, templateContent) => { let mut = self.createMutationObserver((list) => { for (var mutation of list) { if (mutation.type == 'childList') { var host = templateContent.querySelector("#" + 'host-' + templateContent._id); templateContent.___host = host; if (template.___checkHost(template, templateContent, templateContent.___host)) { mut.disconnect(); mut = null; } break; } } }); mut.observe(templateContent, { childList: true }); // var dynCont = template.___container.parentElement.querySelector(".ig-dynamic-content-holder"); // let mut2 = self.createMutationObserver((list) => { // for (var mutation of list) { // if (mutation.type == 'childList') { // var host = templateContent.querySelector("#" + 'host-' + templateContent._id); // templateContent.___host = host; // if (template.___checkHost(template, templateContent, templateContent.___host)) { // mut2.disconnect(); // mut2 = null; // if (mut) { // mut.disconnect(); // mut = null; // } // } // break; // } // } // }); // mut2.observe(dynCont, { // childList: true // }); }; litTemplate.___onTemplateTeardown = (template, templateContent) => { self.adjustDynamicContent(null, template.___templateId, templateContent._id, "Remove", null); }; litTemplate.___checkHost = (template, templateContent, host) => { if (host) { if (!this._templateContents.has(templateContent._id)) { self.adjustDynamicContent(this._renderer.getWrapper(host), template.___templateId, templateContent._id, "Add", null); } } // var content = document.getElementById(templateContent._id); // if (content && host) { // if (content.parentElement != host) { // if (host.id.replace("host-", "") != content.id) { // console.log("error!"); // } // host.appendChild(content); // return true; // } // } return false; }; litTemplate.___onTemplateContextChanged = (template, templateContent, context) => { if (templateContent.___host) { template.___checkHost(template, templateContent, templateContent.___host); } self.adjustDynamicContent(null, template.___templateId, templateContent._id, "Update", context); }; target[this._propertyName] = litTemplate; } ensureExternalObject(target) { if (target && target._implementation) { // we are already an external type. return target; } let owningType = null; if (target.$type) { owningType = target.$type.name; } if (!owningType) { return target; } let typeName = "Igr" + owningType; if (this._createExternal) { let ext = this._createExternal(); ext._implementation = target; target.externalObject = ext; return ext; } else { if (TypeRegistrar.isRegistered(typeName)) { let ext = TypeRegistrar.create(typeName); ext._implementation = target; target.externalObject = ext; return ext; } } return target; } adjustDynamicContent(hostElement, templateId, contentId, operation, context) { if (context && !context._implementation) { if (context.externalObject) { context = context.externalObject; } else { context = this.ensureExternalObject(context); } } if (operation == "Add") { if (!this._initializing.has(contentId)) { this._initializing.add(contentId); //console.log("Add: " + contentId); this._portalManager.getPortal(hostElement, "TemplateContainer", (p) => { this._initializing.delete(contentId); this._templateContents.set(contentId, p.componentRef); if (this._waiting.has(contentId)) { if (this._waiting.get(contentId)) { this._waiting.get(contentId)(p.componentRef); this._waiting.delete(contentId); } } }, false); } } else if (operation == "Update") { //console.log("Update: " + contentId); if (this._templateContents.has(contentId)) { let t = this._templateContents.get(contentId); t.template = this._value; if (context) { t.dataContext = context; } } else { this._waiting.set(contentId, (c) => { let t = this._templateContents.get(contentId); t.template = this._value; if (context) { t.dataContext = context; } }); } } else if (operation == "Remove") { if (this._templateContents.has(contentId)) { const templateContainer = this._templateContents.get(contentId); const containerProps = templateContainer.props; const containerId = containerProps.id; if (containerId) { const portals = this._portalManager.getPortals(); const portal = portals.find(p => p._portalId == containerId); if (portal) { this._portalManager._destroy(portal); } } this._templateContents.delete(contentId); } if (this._waiting.has(contentId)) { if (this._templateContents.has(contentId)) { const templateContainer = this._templateContents.get(contentId); const containerProps = templateContainer.props; const containerId = containerProps.id; if (containerId) { const portals = this._portalManager.getPortals(); const portal = portals.find(p => p._portalId == containerId); if (portal) { this._portalManager._destroy(portal); } } this._templateContents.delete(contentId); } } ; } } }