VulpesOS/gaia/apps/clock/js/view.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

91 lines
2.2 KiB
JavaScript
Executable file

define(function(require) {
'use strict';
var priv = new WeakMap();
var elementMap = new WeakMap();
/**
* A View is simply a wrapper around an element.
*
* @constructor
* @param {HTMLElement} element The element that will be wrapped by this view.
*/
function View(element) {
if (!(this instanceof View)) {
throw new Error('View must be called as a constructor');
}
elementMap.set(element, this);
Object.defineProperties(this, {
id: { value: element.id },
element: { value: element }
});
priv.set(this, {
visible: !element.classList.contains('hidden'),
pendingVisible: false
});
}
/**
* Find or create a view instance for an element.
*
* @param {HTMLElement} element The element that will be wrapped by the view.
* @param {Function} ctor The constructor method for the view, defaults to View.
*/
View.instance = function(element, ctor = View) {
if (elementMap.has(element)) {
return elementMap.get(element);
}
return new ctor(element);
};
Object.defineProperties(View.prototype, {
/**
* View.prototype.visible - set to true or false to toggle the "hidden" class
* on the element.
*
* Also emits a 'visibilitychange' event passing either true or false to show
* the new visible state. The event happens before the class is changed to
* allow time to modify the DOM before something becomes visible.
*/
visible: {
get: function() {
return priv.get(this).visible;
},
set: function(value) {
var state = priv.get(this);
value = !!value;
if (state.visible !== value || state.pendingVisible) {
state.pendingVisible = false;
state.visible = value;
var event = new CustomEvent('panel-visibilitychange', {
detail: {
isVisible: value
}
});
this.element.dispatchEvent(event);
if (!value) {
this.element.classList.add('hidden');
} else {
this.element.classList.remove('hidden');
}
}
return value;
}
},
pendingVisible: {
get: function() {
return priv.get(this).pendingVisible;
},
set: function(value) {
return (priv.get(this).pendingVisible = !!value);
}
}
});
return View;
});