igniteui-react-core
Version:
Ignite UI React Core.
260 lines (259 loc) • 11.1 kB
JavaScript
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);
}
}
;
}
}
}