VulpesOS/assets/webapps/camera.gaiamobile.org/bower_components/gaia-component/gaia-component.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

251 lines
No EOL
9.6 KiB
JavaScript

;
(function (define) {
'use strict';
define([
'require',
'exports',
'module'
], function (require, exports, module) {
var textContent = Object.getOwnPropertyDescriptor(Node.prototype, 'textContent');
var innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
var removeAttribute = Element.prototype.removeAttribute;
var setAttribute = Element.prototype.setAttribute;
var noop = function () {
};
exports.register = function (name, props) {
var baseProto = getBaseProto(props.extends);
var template = props.template || baseProto.templateString;
var extensible = props.extensible = props.hasOwnProperty('extensible') ? props.extensible : true;
delete props.extends;
if (template) {
if (extensible && props.template) {
props.templateString = props.template;
}
var output = processCss(template, name);
props.template = document.createElement('template');
props.template.innerHTML = output.template;
props.lightCss = output.lightCss;
props.globalCss = props.globalCss || '';
props.globalCss += output.globalCss;
}
injectGlobalCss(props.globalCss);
delete props.globalCss;
var descriptors = mixin(props.attrs || {}, base.descriptors);
props._attrs = props.attrs;
delete props.attrs;
var proto = createProto(baseProto, props);
Object.defineProperties(proto, descriptors);
try {
return document.registerElement(name, { prototype: proto });
} catch (e) {
if (e.name !== 'NotSupportedError') {
throw e;
}
}
};
var base = {
properties: {
GaiaComponent: true,
attributeChanged: noop,
attached: noop,
detached: noop,
created: noop,
createdCallback: function () {
if (this.dirObserver) {
addDirObserver();
}
injectLightCss(this);
this.created();
},
attributeChangedCallback: function (name, from, to) {
var prop = toCamelCase(name);
if (this._attrs && this._attrs[prop]) {
this[prop] = to;
}
this.attributeChanged(name, from, to);
},
attachedCallback: function () {
if (this.dirObserver) {
this.setInnerDirAttributes = setInnerDirAttributes.bind(null, this);
document.addEventListener('dirchanged', this.setInnerDirAttributes);
}
this.attached();
},
detachedCallback: function () {
if (this.dirObserver) {
document.removeEventListener('dirchanged', this.setInnerDirAttributes);
}
this.detached();
},
setupShadowRoot: function () {
if (!this.template) {
return;
}
var node = document.importNode(this.template.content, true);
this.createShadowRoot().appendChild(node);
if (this.dirObserver) {
setInnerDirAttributes(this);
}
return this.shadowRoot;
},
setAttr: function (name, value) {
var internal = this.shadowRoot.firstElementChild;
setAttribute.call(internal, name, value);
setAttribute.call(this, name, value);
},
removeAttr: function (name) {
var internal = this.shadowRoot.firstElementChild;
removeAttribute.call(internal, name);
removeAttribute.call(this, name);
}
},
descriptors: {
textContent: {
set: function (value) {
textContent.set.call(this, value);
if (this.lightStyle) {
this.appendChild(this.lightStyle);
}
},
get: function () {
return textContent.get();
}
},
innerHTML: {
set: function (value) {
innerHTML.set.call(this, value);
if (this.lightStyle) {
this.appendChild(this.lightStyle);
}
},
get: innerHTML.get
}
}
};
var defaultPrototype = createProto(HTMLElement.prototype, base.properties);
function getBaseProto(proto) {
if (!proto) {
return defaultPrototype;
}
proto = proto.prototype || proto;
return !proto.GaiaComponent ? createProto(proto, base.properties) : proto;
}
function createProto(proto, props) {
return mixin(Object.create(proto), props);
}
var hasShadowCSS = function () {
var div = document.createElement('div');
try {
div.querySelector(':host');
return true;
} catch (e) {
return false;
}
}();
var regex = {
shadowCss: /(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,
':host': /(?:\:host)/g,
':host()': /\:host\((.+)\)(?: \:\:content)?/g,
':host-context': /\:host-context\((.+)\)([^{,]+)?/g,
'::content': /(?:\:\:content)/g
};
function processCss(template, name) {
var globalCss = '';
var lightCss = '';
if (!hasShadowCSS) {
template = template.replace(regex.shadowCss, function (match) {
var hostContext = regex[':host-context'].exec(match);
if (hostContext) {
globalCss += match.replace(regex['::content'], '').replace(regex[':host-context'], '$1 ' + name + '$2').replace(/ +/g, ' ');
} else {
lightCss += match.replace(regex[':host()'], name + '$1').replace(regex[':host'], name).replace(regex['::content'], name);
}
return '';
});
}
return {
template: template,
lightCss: lightCss,
globalCss: globalCss
};
}
function injectGlobalCss(css) {
if (!css) {
return;
}
var style = document.createElement('style');
style.innerHTML = css.trim();
headReady().then(function () {
document.head.appendChild(style);
});
}
function headReady() {
return new Promise(function (resolve) {
if (document.head) {
return resolve();
}
window.addEventListener('load', function fn() {
window.removeEventListener('load', fn);
resolve();
});
});
}
function injectLightCss(el) {
if (hasShadowCSS) {
return;
}
var stylesheet = el.querySelector('style');
if (!stylesheet) {
stylesheet = document.createElement('style');
stylesheet.setAttribute('scoped', '');
stylesheet.appendChild(document.createTextNode(el.lightCss));
el.appendChild(stylesheet);
}
el.lightStyle = stylesheet;
}
function toCamelCase(string) {
return string.replace(/-(.)/g, function replacer(string, p1) {
return p1.toUpperCase();
});
}
var dirObserver;
function setInnerDirAttributes(component) {
var dir = component.dir || document.dir;
Array.from(component.shadowRoot.children).forEach(element => {
if (element.nodeName !== 'STYLE') {
element.dir = dir;
}
});
}
function addDirObserver() {
if (dirObserver) {
return;
}
dirObserver = new MutationObserver(onChanged);
dirObserver.observe(document.documentElement, {
attributeFilter: ['dir'],
attributes: true
});
function onChanged(mutations) {
document.dispatchEvent(new Event('dirchanged'));
}
}
function mixin(target, source) {
for (var key in source) {
target[key] = source[key];
}
return target;
}
});
}(typeof define == 'function' && define.amd ? define : function (n, w) {
'use strict';
return typeof module == 'object' ? function (c) {
c(require, exports, module);
} : function (c) {
var m = { exports: {} };
c(function (n) {
return w[n];
}, m.exports, m);
w[n] = m.exports;
};
}('gaia-component', this)));