Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save r7kamura/75c9c2948caea133ae2e to your computer and use it in GitHub Desktop.
Save r7kamura/75c9c2948caea133ae2e to your computer and use it in GitHub Desktop.
var _ = require('lodash');
var Rx = require('rx');
(function () {
/**
* @param {HTMLElement} element
* @return {Rx.Observable}
*/
function createDeactivate$(element) {
return Rx.Observable.fromEvent(element, 'blur');
}
/**
* @param {HTMLElement} element
* @return {Rx.Observable}
*/
function createToggle$(element) {
return Rx.Observable.fromEvent(element, 'click');
}
/**
* @param {Rx.Observable} deactivate$
* @return {Rx.Observable}
*/
function createDeactivateModification$(deactivate$) {
return deactivate$.map(function () {
return function (state) {
state.active = false;
return state;
};
})
}
/**
* @param {Rx.Observable} toggle$
* @return {Rx.Observable}
*/
function createToggleModification$(toggle$) {
return toggle$.doAction(function (event) {
event.preventDefault();
}).map(function () {
return function (state) {
state.active = !state.active;
return state;
};
});
}
/**
* @return {Rx.Observable}
*/
function createInitializeModification$() {
return Rx.Observable.just(function (state) {
state.active = false;
return state;
});
}
/**
* Interprets user input.
* @param {HTMLElement} element
* @param {Object<Rx.Observable>}
*/
function intent(element) {
return {
deactivate$: createDeactivate$(element),
toggle$: createToggle$(element)
};
}
/**
* Transits the state.
* @param {Object<Rx.Observable>} actions
* @return {Rx.Observable}
*/
function model(actions) {
return Rx.Observable.merge(
createToggleModification$(actions.toggle$),
createDeactivateModification$(actions.deactivate$),
createInitializeModification$()
).scan(function (state, modification) {
return modification(state);
}, {});
}
/**
* Reflects the state to the DOM.
* @param {Rx.Observable} state$
* @return {Rx.Observable}
*/
function view(state$) {
return state$.map(function (state) {
return state.active;
});
}
/**
* @param {Rx.Observable}
* @param {HTMLElement}
*/
function driver(request$, element) {
request$.subscribe(function (active) {
var selector = element.getAttribute('data-target');
var target = selector ? document.querySelector(selector) : element.parentNode;
target.classList.toggle('active', active);
});
}
_.each(document.querySelectorAll('.toggle-button'), function (element) {
driver(view(model(intent(element))), element);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment