@awcrotwell/motion
Version:
Motion allows you to build reactive, real-time frontend UI components in your Amber application using pure Crystal that are reusable, testable & encapsulated. For brevity, we will call them MotionComponents.
60 lines (59 loc) • 2.47 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const AttributeTracker_1 = __importDefault(require("./AttributeTracker"));
const BindingManager_1 = __importDefault(require("./BindingManager"));
const Component_1 = __importDefault(require("./Component"));
const documentLifecycle_1 = require("./documentLifecycle");
const Consumer_1 = __importDefault(require("./Consumer"));
function getConfig(name) {
const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
if (element) {
return element.getAttribute('content');
}
return false;
}
class Client {
constructor(options) {
this.consumer = new Consumer_1.default(getConfig('url') || '/cable');
this.root = document;
this.shutdownBeforeUnload = true;
this.keyAttribute = 'data-motion-key';
this.stateAttribute = 'data-motion-state';
this.motionAttribute = 'data-motion';
Object.assign(this, options);
this._componentSelector = `[${this.keyAttribute}][${this.stateAttribute}]`;
this.logging = true;
this._componentTracker = new AttributeTracker_1.default(this.keyAttribute, (element) => element.hasAttribute(this.stateAttribute) // ensure matches selector
? new Component_1.default(this, element)
: null);
this._motionTracker = new AttributeTracker_1.default(this.motionAttribute, (element) => new BindingManager_1.default(this, element));
documentLifecycle_1.documentLoaded.then(() => {
// avoid mutations while loading the document
this._componentTracker.attachRoot(this.root);
this._motionTracker.attachRoot(this.root);
});
if (this.shutdownBeforeUnload) {
documentLifecycle_1.beforeDocumentUnload.then(() => this.shutdown());
}
}
log(...args) {
if (this.logging) {
// eslint-disable-next-line no-console
console.log('[Motion]', ...args);
}
}
findComponent(element) {
return this._componentTracker.getManager(element.closest(this._componentSelector));
}
shutdown() {
this._componentTracker.shutdown();
this._motionTracker.shutdown();
}
getExtraDataForEvent() {
// noop
}
}
exports.default = Client;