/** @module utils */
import {Collection, Map, fromJS} from 'immutable';
import {renderUI} from './ui';
import createElement from 'virtual-dom/create-element';
Collection.prototype.$ = function $(query, setVal) {
let pathArray = selector(query);
let tagName = pathArray.pop();
let nodeVal, node;
if (setVal !== undefined) {
return this.setIn(selector(query), setVal);
} else {
nodeVal = this.getIn(selector(query));
node = (new Map()).set(tagName, nodeVal);
node.__queryNode = this;
node.__query = query;
return node;
}
}
Collection.prototype.children = function() {
const tagName = this.findKey(() => { return true });
let node = this.set(tagName, this.get(tagName) || new Map)
let children = this.get(tagName) && this.get(tagName).filterNot((val, key) => { return key === 'props' }) || new Map();
let props = this.getIn([tagName, 'props']) || new Map();
if (arguments.length === 0) {
return children;
}
if (arguments[0] && typeof arguments[0] === 'object') {
children = fromJS(arguments[0]);
} else if (typeof arguments[0] === 'string' && arguments[1] !== undefined) {
children = arguments[1] === null ? children.delete(arguments[0]) : children.set(arguments[0], arguments[1]);
} else if (arguments.length === 1 && typeof arguments[0] === 'string') {
return children.get(arguments[0]);
}
return this.__queryNode ? this.__queryNode.setIn(selector(this.__query), children.set('props', props)) : this.set(tagName, children.set('props', props));
}
Collection.prototype.toNode = function toNode(tagName) {
return (new Map()).set(tagName, this)
}
Collection.prototype.toVNode = function toVNode(store) {
return renderUI(store, this);
}
Collection.prototype.toElement = function toElement(store) {
let vNode = this.toVNode(store);
if (vNode) {
return createElement(vNode);
}
}
Collection.prototype.toHTML = function toHTML(store) {
let element = this.toElement(store);
if (element) {
return element.outerHTML;
}
}
Collection.prototype.props = function() {
const tagName = this.findKey(() => { return true });
let props = this.getIn([tagName, 'props']) || new Map();
if (arguments.length === 0) {
return props;
}
if (typeof arguments[0] === 'object') {
props = props.merge(arguments[0]);
} else if (typeof arguments[0] === 'string' && arguments[1] !== undefined) {
props = arguments[1] === null ? props.delete(arguments[0]) : props.set(arguments[0], fromJS(arguments[1]));
} else if (arguments.length === 1 && typeof arguments[0] === 'string') {
return props.get(arguments[0]);
}
return this.__queryNode ? this.__queryNode.setIn(selector(this.__query).concat('props'), props) : this.setIn([tagName, 'props'], props);
}
Collection.prototype.style = function() {
const tagName = this.findKey(() => { return true });
let style = this.getIn([tagName, 'props', 'style']) || new Map();
if (!style) {
return new Map();
}
if (arguments.length === 0) {
return style;
}
if (typeof arguments[0] === 'object') {
style = style.merge(arguments[0]);
} else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'string') {
style = style.set(arguments[0], arguments[1]);
} else if (typeof arguments[0] === 'string' && arguments[1] === null) {
style = style.delete(arguments[0]);
} else if (arguments.length === 1 && typeof arguments[0] === 'string') {
return style.get(arguments[0]);
}
return this.__queryNode ? this.__queryNode.setIn(selector(this.__query).concat(['props', 'style']), style) : this.setIn([tagName, 'props', 'style'], style);
}
Collection.prototype.events = function() {
const tagName = this.findKey(() => { return true });
let events = this.getIn([tagName, 'props', 'events']) || new Map();
if (!events) {
return new Map();
}
if (arguments.length === 0) {
return events;
}
if (typeof arguments[0] === 'object') {
events = events.merge(arguments[0]);
} else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'object') {
events = events.set(arguments[0], fromJS(arguments[1]));
} else if (typeof arguments[0] === 'string' && arguments[1] === null) {
events = events.delete(arguments[0]);
} else if (arguments.length === 1 && typeof arguments[0] === 'string') {
return events.get(arguments[0]);
}
return this.__queryNode ? this.__queryNode.setIn(selector(this.__query).concat(['props', 'events']), events) : this.setIn([tagName, 'props', 'events'], events);
}
/**
* Returns an array path from a string selector
*
* @example
* selector('div#foo form#bar input#baz');
* // returns ['div#foo', 'form#bar', 'input#baz']
*
* @param {String} selectorString A space separated series of tag names
* @return {Array} Path array used to deeply select inside of Immutable Nux vDOM objects
*/
export function selector(selectorString) {
return selectorString.split(' ');
};