seedofjoy / bazooka Goto Github PK
View Code? Open in Web Editor NEWSimple tool for declarative binding applications to HTML nodes.
License: MIT License
Simple tool for declarative binding applications to HTML nodes.
License: MIT License
Baz needs some way to communicate between components
Maybe, include special component for basic pub/sub. This way users could write their own communication layer based on $.Event/localStorage/AJAX/Rx/new-fancy-technology
var pubsub = function (element) {
Baz.r.method('sub', function (ev, cb) { // `r` for register
// save callback to {ev:[]cb} map
});
Baz.r.method('pub', function (ev) {
// run callbacks from {ev:[]cb} map
});
}
// ###############
var clicker = function (element) {
$(element).onclick(Baz.g.method('pub', 'clicked')); // `g` for get
}
var ticker = function (element) {
Baz.g.method('sub', 'clicked', function(){
// handler for clicker's clicks
});
}
Typically, almost all components live in separate files, therefore
Baz.register
method call takes the form of
Bazooka.register({
compA: require('/path/to/A'),
compB: require('/path/to/B'),
/* ... */
compZ: require('/path/to/Z')
})
This, however, will result in the source code of all components being evaluated on every page, even if the current page needs only a subset of components.
Workaround is simple: just wrap each require
in a function remembering to account for both BazComponent.simple
and BazComponent.universal
component types:
Bazooka.register({
compA: (el) => require('/path/to/A')(el),
compB: (el) => require('/path/to/B').bazFunc(el),
/* ... */
compZ: (el) => require('/path/to/Z')(el)
})
Since lazy evaluation is desired in most cases, it might be better to add support for "lazy registering" to the library API. The API may be similar to:
Bazooka.lazyRegister({
compA: '/path/to/A',
compB: '/path/to/B',
}, require)
Currently, if node with bazId was removed from a DOM tree, we simply remove its information from internal registries, but do not remove any listeners, which bazFunc had bound to the node
if (wrappersRegistry[bazId] && !wrappersRegistry[bazId].__wrapped__.parentNode) {
wrappersRegistry[bazId] = null;
nodesComponentsRegistry[bazId] = [];
}
I think it would be better, if components could describe some kind of dispose function. Something like this:
var onclick = e => console.log(e)
export function bazFunc(node) {
node.addEventListener('click', onclick)
return () => node.removeEventListener('click', onclick)
}
<div id="test1" data-bazooka="test">test1</div>
<div id="test2wrap">
<div id="test2" data-bazooka="test">test2</div>
</div>
<button id="btn">Killall</button>
import Baz from 'bazooka';
Baz.register({
test: function(node) {
var bazid = node.getAttribute('data-bazid');
console.log('Attached bazid', bazid);
return function() {
console.log('Disposed bazid', bazid);
}
}
});
window.btn.onclick = function() {
window.test1.parentNode.removeChild(window.test1);
window.test2wrap.parentNode.removeChild(window.test2wrap);
Baz.refresh();
}
Baz.refresh();
Expected output after button click:
Attached bazid 0
Attached bazid 1
Disposed bazid 0
Disposed bazid 1
Actual output:
Attached bazid 0
Attached bazid 1
Disposed bazid 0
That's because Bazooka checks wrapper.__wrapped__.parentNode
and this is not null for test2
node (parentNode
is test2wrap, parentNode.parentNode
is null).
Using document.body.contains(wrapper.__wrapped__)
gives the expected behavior (not sure if rootNode
can be used here)
All current tests are now covering only single binding via Baz.refresh()
, so we won't know if we will broke code, which depends on Mutation Observer
Baz() binds nodes only once
Also, binding requires running component's code, so it won't happen if component must be require()
d
Collection of helper functions. For example, parsing of data-attributes
return dispose
(#27)bazFunc
s, which:
dispose = oldBazFunc(node); dispose(); newBazFunc(node)
when hot reload is neededbazFuncs
(?)Namespaces for BazComponents?
Current system of registering all components, which may or may not occur after Baz.refresh(), makes it impossible to asynchronously load them
Optional callback may enable this
Something like <div data-bazooka="component" data-baz-async="viewport" />
to initialize bazComponent when node came to viewport
I suggest using https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API for this purposes (with fallback to a regular sync initialization for browsers without it)
Currently, if a component throws during initialization, all not yet initialized components won't be initialized at all.
I believe init function should be wrapped in try-catch block.
In case an exception occurs, the exception should be reported via console.error
, but it shouldn't prevent another components from being initialized.
We should add optional prefix where generating node's bazid
Let bazooka users decide do they need polyfills or not
Currently, polyfills are used to:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.