@web-atoms/core
Version:
631 lines (630 loc) • 22 kB
JavaScript
System.register(["tslib", "../../core/AtomBinder", "../../core/AtomComponent", "../../core/BindableProperty", "../../core/Command", "../../core/FormattedString", "../../core/Hacks", "../../core/WebImage", "../../core/XNode", "../../di/TypeKey", "../styles/AtomStyle", "../styles/AtomStyleSheet"], function (_export, _context) {
"use strict";
var __decorate, __metadata, AtomBinder, AtomComponent, BindableProperty, Command, FormattedString, refreshInherited, visitDescendents, WebImage, XNode, isControl, TypeKey, AtomStyle, AtomStyleSheet, AtomControl, isAtomControl, fromHyphenToCamel, defaultStyleSheets, ElementValueSetters, propertyId, getSelection, body, html;
function setAttribute(name) {
return (ctrl, e, value) => {
e.setAttribute(name, value);
};
}
function setEvent(name) {
return (ctrl, e, value) => {
ctrl.bindEvent(e, name, value);
};
}
function setStyle(name, applyUnit) {
if (applyUnit) {
return (ctrl, e, value) => {
if (typeof value === "number") {
e.style[name] = value + applyUnit;
return;
}
e.style[name] = value;
};
}
return (ctrl, e, value) => {
e.style[name] = value;
};
}
function disposeChildren(owner, e) {
if (!e) {
return;
}
let s = e.firstElementChild;
while (s) {
const c = s;
s = s.nextElementSibling;
const ac = c.atomControl;
if (ac) {
ac.dispose();
c.remove();
continue;
}
disposeChildren(owner, c);
owner.unbind(c);
owner.unbindEvent(c);
c.remove();
}
}
_export("AtomControl", void 0);
return {
setters: [function (_tslib) {
__decorate = _tslib.__decorate;
__metadata = _tslib.__metadata;
}, function (_coreAtomBinder) {
AtomBinder = _coreAtomBinder.AtomBinder;
}, function (_coreAtomComponent) {
AtomComponent = _coreAtomComponent.AtomComponent;
}, function (_coreBindableProperty) {
BindableProperty = _coreBindableProperty.BindableProperty;
}, function (_coreCommand) {
Command = _coreCommand.default;
}, function (_coreFormattedString) {
FormattedString = _coreFormattedString.default;
}, function (_coreHacks) {
refreshInherited = _coreHacks.refreshInherited;
visitDescendents = _coreHacks.visitDescendents;
}, function (_coreWebImage) {
WebImage = _coreWebImage.default;
}, function (_coreXNode) {
XNode = _coreXNode.default;
isControl = _coreXNode.isControl;
}, function (_diTypeKey) {
TypeKey = _diTypeKey.TypeKey;
}, function (_stylesAtomStyle) {
AtomStyle = _stylesAtomStyle.AtomStyle;
}, function (_stylesAtomStyleSheet) {
AtomStyleSheet = _stylesAtomStyleSheet.AtomStyleSheet;
}],
execute: function () {
isAtomControl = isControl;
fromHyphenToCamel = input => input.replace(/-([a-z])/g, g => g[1].toUpperCase());
if (typeof bridge !== "undefined" && bridge.platform) {
throw new Error("AtomControl of Web should not be used with Xamarin Forms");
}
defaultStyleSheets = {};
_export("ElementValueSetters", ElementValueSetters = {
text(ctrl, e, value) {
e.textContent = value;
},
["class"](ctrl, e, value) {
if (typeof value === "string") {
e.className = value;
return;
}
ctrl.setElementClass(e, value, true);
},
alt: setAttribute("alt"),
title: setAttribute("title"),
href: setAttribute("href"),
target: setAttribute("target"),
style: setAttribute("style"),
styleLeft: setStyle("left", "px"),
styleTop: setStyle("top", "px"),
styleBottom: setStyle("bottom", "px"),
styleRight: setStyle("right", "px"),
styleWidth: setStyle("width", "px"),
styleHeight: setStyle("height", "px"),
stylePosition: setStyle("position"),
styleFontSize: setStyle("fontSize", "px"),
styleFontFamily: setStyle("fontFamily"),
styleFontWeight: setStyle("fontWeight"),
styleBorder: setStyle("border"),
styleBorderWidth: setStyle("borderWidth", "px"),
styleBorderColor: setStyle("borderColor"),
styleColor: setStyle("color"),
styleBackgroundColor: setStyle("backgroundColor"),
dir: setAttribute("dir"),
name: setAttribute("name"),
tabIndex: setAttribute("tabIndex"),
contentEditable: setAttribute("contentEditable"),
eventClick: setEvent("click"),
eventKeydown: setEvent("keydown"),
eventKeyup: setEvent("keyup"),
eventKeypress: setEvent("keypress"),
eventMousedown: setEvent("mousedown"),
eventMouseup: setEvent("mouseup"),
eventMousemove: setEvent("mousemove"),
src(ctrl, e, value) {
if (value && /^http\:/i.test(value)) {
e.src = value.substring(5);
return;
}
e.src = value;
},
styleClass(ctrl, e, value) {
ctrl.setElementClass(e, value);
},
styleDisplay(ctrl, e, value) {
if (typeof value === "boolean") {
e.style.display = value ? "" : "none";
return;
}
e.style.display = value;
},
formattedText(ctrl, e, value) {
if (value instanceof FormattedString) {
value.applyTo(ctrl.app, e);
} else {
e.textContent = (value || "").toString();
}
},
disabled(ctrl, e, value) {
if (value) {
e.setAttribute("disabled", "");
return;
}
e.removeAttribute("disabled");
},
autofocus(ctrl, element, value) {
ctrl.app.callLater(() => {
const ie = element;
if (ie) {
setTimeout(() => requestAnimationFrame(() => ie.focus()), 100);
}
});
},
autocomplete(ctrl, element, value) {
ctrl.app.callLater(() => {
element.autocomplete = value;
});
},
onCreate(ctrl, element, value) {
value(ctrl, element);
},
watch(ctrl, element, value) {
setTimeout((c1, e1, v1) => {
e1.dispatchEvent(new CustomEvent("watch", {
bubbles: true,
cancelable: true,
detail: {
control: c1,
value: v1
}
}));
}, 1, ctrl, element, value);
},
ariaLabel(ctrl, e, value) {
if (value === null) {
e.removeAttribute("aria-label");
return;
}
if (typeof value === "object") {
value = JSON.stringify(value);
}
if (typeof value !== "string") {
value = value.toString();
}
e.setAttribute("aria-label", value);
},
ariaPlaceholder(ctrl, e, value) {
if (value === null) {
e.removeAttribute("aria-placeholder");
return;
}
if (typeof value === "object") {
value = JSON.stringify(value);
}
if (typeof value !== "string") {
value = value.toString();
}
e.setAttribute("aria-placeholder", value);
}
});
ElementValueSetters["aria-label"] = ElementValueSetters.ariaLabel;
ElementValueSetters["aria-placeholder"] = ElementValueSetters.ariaPlaceholder;
ElementValueSetters["style-display"] = ElementValueSetters.styleDisplay;
ElementValueSetters["style-left"] = ElementValueSetters.styleLeft;
ElementValueSetters["style-top"] = ElementValueSetters.styleTop;
ElementValueSetters["style-bottom"] = ElementValueSetters.styleBottom;
ElementValueSetters["style-right"] = ElementValueSetters.styleRight;
ElementValueSetters["style-width"] = ElementValueSetters.styleWidth;
ElementValueSetters["style-height"] = ElementValueSetters.styleHeight;
ElementValueSetters["style-position"] = ElementValueSetters.stylePosition;
ElementValueSetters["style-font-size"] = ElementValueSetters.styleFontSize;
ElementValueSetters["style-font-family"] = ElementValueSetters.styleFontFamily;
ElementValueSetters["style-font-weight"] = ElementValueSetters.styleFontWeight;
ElementValueSetters["style-border"] = ElementValueSetters.styleBorder;
ElementValueSetters["style-border-width"] = ElementValueSetters.styleBorderWidth;
ElementValueSetters["style-border-color"] = ElementValueSetters.styleBorderColor;
ElementValueSetters["style-color"] = ElementValueSetters.styleColor;
ElementValueSetters["style-background-color"] = ElementValueSetters.styleBackgroundColor;
ElementValueSetters["on-create"] = ElementValueSetters.onCreate;
propertyId = 1;
;
_export("AtomControl", AtomControl = class AtomControl extends AtomComponent {
static from(e1) {
var _a;
let e = e1;
while (e) {
const {
atomControl
} = e;
if (atomControl) {
return atomControl;
}
e = (_a = e._logicalParent) !== null && _a !== void 0 ? _a : e.parentElement;
}
}
static registerProperty(attributeName, attributeValue, setter) {
const setterSymbol = `${attributeName}_${attributeValue}_${propertyId++}`;
ElementValueSetters[setterSymbol] = setter;
function setterFx(v) {
return {
[setterSymbol]: v
};
}
setterFx.toString = () => {
return setterSymbol;
};
setterFx.property = setterSymbol;
return setterFx;
}
get controlStyle() {
if (this.mControlStyle === undefined) {
const key = TypeKey.getName(this.defaultControlStyle || this.constructor);
this.mControlStyle = defaultStyleSheets[key];
if (this.mControlStyle) {
return this.mControlStyle;
}
if (this.defaultControlStyle) {
this.mControlStyle = defaultStyleSheets[key] || (defaultStyleSheets[key] = this.theme.createNamedStyle(this.defaultControlStyle, key));
}
this.mControlStyle = this.mControlStyle || null;
}
return this.mControlStyle;
}
set controlStyle(v) {
if (v instanceof AtomStyle) {
this.mControlStyle = v;
} else {
const key = TypeKey.getName(v);
this.mControlStyle = defaultStyleSheets[key] || (defaultStyleSheets[key] = this.theme.createNamedStyle(v, key));
}
AtomBinder.refreshValue(this, "controlStyle");
this.invalidate();
}
get theme() {
return this.mTheme || this.mCachedTheme || (this.mCachedTheme = this.parent ? this.parent.theme : this.app.resolve(AtomStyleSheet, false, null));
}
set theme(v) {
this.mTheme = v;
refreshInherited(this, "theme");
}
get parent() {
let e = this.element._logicalParent || this.element.parentElement;
if (!e) {
return null;
}
while (e) {
const ac = e.atomControl;
if (ac) {
return ac;
}
e = e._logicalParent || e.parentElement;
}
}
get factory() {
return AtomControl;
}
constructor(app, e = document.createElement("div")) {
super(app, e);
}
onPropertyChanged(name) {
super.onPropertyChanged(name);
switch (name) {
case "theme":
this.mCachedTheme = null;
AtomBinder.refreshValue(this, "style");
break;
case "renderer":
this.rendererChanged();
break;
}
}
atomParent(e) {
var _a;
while (e) {
const ac = e.atomControl;
if (ac) {
return ac;
}
e = (_a = e._logicalParent) !== null && _a !== void 0 ? _a : e.parentElement;
}
}
append(element) {
if (element instanceof AtomControl) {
this.element.appendChild(element.element);
} else {
this.element.appendChild(element);
}
return this;
}
updateSize() {
this.onUpdateSize();
visitDescendents(this.element, (e, ac) => {
if (ac) {
ac.updateSize();
return false;
}
return true;
});
}
rendererChanged() {
disposeChildren(this, this.element);
this.element.innerHTML = "";
const r = this.renderer;
if (!r) {
return;
}
delete this.render;
this.render(r);
}
preCreate() {}
setElementValue(element, name, value) {
if (value === undefined) {
return;
}
const setter = ElementValueSetters[name];
if (setter !== void 0) {
setter(this, element, value);
return;
}
if (/^(data|aria)\-/.test(name)) {
if (value === null) {
element.removeAttribute(name);
return;
}
if (typeof value === "object") {
value = JSON.stringify(value);
}
if (typeof value !== "string") {
value = value.toString();
}
element.setAttribute(name, value);
return;
}
if (/^style/.test(name)) {
name = name.substring(5);
if (name.startsWith("-")) {
name = fromHyphenToCamel(name.substring(1));
} else {
name = name.charAt(0).toLowerCase() + name.substring(1);
}
if (value instanceof WebImage) {
value = `url(${value})`;
}
element.style[name] = value;
return;
}
if (/^event/.test(name)) {
name = name.substring(5);
if (name.startsWith("-")) {
name = fromHyphenToCamel(name.substring(1));
} else {
name = name.charAt(0).toLowerCase() + name.substring(1);
}
this.bindEvent(element, name, value);
return;
}
if (name.startsWith("attr-")) {
if (value === null) {
element.removeAttribute(name.substring(5));
return;
}
element.setAttribute(name.substring(5), value);
} else {
element[name] = value;
}
}
setElementClass(element, value, clear) {
const s = value;
if (s && typeof s === "object") {
if (!s.className) {
if (clear) {
let sr = "";
for (const key in s) {
if (s.hasOwnProperty(key)) {
const sv = s[key];
if (sv) {
sr += sr ? " " + key : key;
}
}
}
element.className = sr;
return;
}
for (const key in s) {
if (s.hasOwnProperty(key)) {
const sv = s[key];
if (sv) {
if (!element.classList.contains(key)) {
element.classList.add(key);
}
} else {
if (element.classList.contains(key)) {
element.classList.remove(key);
}
}
}
}
return;
}
}
const sv1 = s ? s.className || s.toString() : "";
element.className = sv1;
}
onUpdateSize() {}
removeAllChildren(e) {
let child = e.firstElementChild;
while (child) {
const c = child;
child = child.nextElementSibling;
const ac = c;
if (ac && ac.atomControl) {
ac.atomControl.dispose();
} else {
this.unbindEvent(child);
this.unbind(child);
}
c.remove();
}
}
createNode(app, e, iterator, creator) {
const name = iterator.name;
const attributes = iterator.attributes;
if (typeof name === "string") {
const element = document.createElement(name);
if (name === "input") {
if (!attributes.autocomplete) {
this.app.callLater(() => {
element.autocomplete = "google-stop";
});
}
}
e === null || e === void 0 ? void 0 : e.appendChild(element);
this.render(iterator, element, creator);
return element;
}
if (name[isAtomControl]) {
const forName = attributes === null || attributes === void 0 ? void 0 : attributes.for;
const ctrl = new name(app, forName ? document.createElement(forName) : undefined);
const element = ctrl.element;
e === null || e === void 0 ? void 0 : e.appendChild(element);
ctrl.render(iterator, element, creator);
return element;
}
throw new Error(`not implemented create for ${iterator.name}`);
}
toTemplate(app, iterator, creator) {
var _a;
if (iterator.isTemplate) {
return this.toTemplate(app, iterator.children[0], creator);
}
const name = iterator.name;
if (typeof name === "string") {
return class Template extends AtomControl {
constructor(a = app, e = document.createElement(name)) {
super(a, e);
}
create() {
super.create();
this.render(iterator, undefined, creator);
}
};
}
if (name[isAtomControl]) {
const forName = (_a = name.attributes) === null || _a === void 0 ? void 0 : _a.for;
if (forName) {
return class Template extends name {
constructor(a = app, e = document.createElement(forName)) {
super(a, e);
}
create() {
super.create();
this.render(iterator, undefined, creator);
}
};
}
return class Template extends name {
constructor(a = app, e) {
super(a, e);
}
create() {
super.create();
this.render(iterator, undefined, creator);
}
};
}
throw new Error(`Creating template from ${name} not supported`);
}
dispatchClickEvent(e, data) {
let clickEvent = data.clickEvent;
if (!clickEvent) {
return;
}
clickEvent = clickEvent.replace(/-([a-z])/g, g => g[1].toUpperCase());
const ce = new CustomEvent(clickEvent, {
detail: data,
bubbles: true,
cancelable: true
});
e.target.dispatchEvent(ce);
if (ce.preventClickEvent) {
e.preventDefault();
}
}
});
__decorate([BindableProperty, __metadata("design:type", XNode)], AtomControl.prototype, "renderer", void 0);
getSelection = () => {
const sel = window.getSelection();
if (sel.rangeCount) {
var frag = sel.getRangeAt(0).cloneContents();
var el = document.createElement("div");
el.appendChild(frag);
return el.innerHTML;
}
return "";
};
body = document.body;
html = body.parentElement;
window.addEventListener("click", e => {
if (e.defaultPrevented) {
return;
}
if (getSelection()) {
return;
}
const originalTarget = e.target;
let start = originalTarget;
if (originalTarget === html) {
return;
}
let clickEvent;
while (start && start !== body) {
clickEvent || (clickEvent = start.getAttribute("data-click-event"));
if (start.tagName === "A") {
if (!clickEvent) {
return;
}
if (clickEvent === "route") {
const {
href
} = start;
if (href) {
if (Command.invokeRoute(href, true)) {
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
}
}
}
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
break;
}
start = start.parentNode;
}
let control = AtomControl.from(originalTarget);
if (control !== void 0) {
const data = new Proxy(originalTarget, {
get(target, p) {
if (typeof p !== "string") {
return;
}
while (target) {
const value = target.dataset[p];
if (value !== void 0) {
return value;
}
target = target.parentElement;
}
}
});
control.dispatchClickEvent(e, data);
}
});
}
};
});
//# sourceMappingURL=AtomControl.js.map