/**
* Refer to <span color = "yellow">{@link ve.Component}</span> for methods or fields inherited from this Component's parent such as `.options.attributes` or `.element`.
*
* Hierarchy used for organising both nested and un-nested lists via item/group distinctions.
* - Functional binding: <span color=00ffff>veHierarchy</span>().
*
* ##### Constructor:
* - `arg0_components_obj`: {@link Object}<{@link ve.Component}|{@link ve.HierarchyDatatype}> - The individual items to append to the current hierarchy.
* - `arg1_options`: {@link Object}
*
* ##### Instance:
* - `.components_obj`: {@link Object}<{@link ve.Component}|{@link ve.HierarchyDatatype}>
* - `.nestable`: {@link Nestable}
* - `.v`: {@link this.components_obj} - Accessor. The current components_obj mounted to the ve.Hierarchy.
*
* ##### Methods:
* - <span color=00ffff>{@link ve.Hierarchy.addItem|addItem}</span>(arg0_parent_el:{@link HTMLElement}, arg1_hierarchy_datatype:{@link ve.HierarchyDatatype})
* - <span color=00ffff>{@link ve.Hierarchy.getHierarchyObject|getHierarchyObject}</span>(arg0_options:{flatten_object: {@link boolean} }) | {@link Object}
* - <span color=00ffff>{@link ve.Hierarchy.removeItem|removeItem}</span>(arg0_hierarchy_datatype:{@link ve.HierarchyDatatype})
*
* @augments ve.Component
* @augments {@link ve.Component}
* @memberof ve.Component
* @type {ve.Hierarchy}
*/
ve.Hierarchy = class extends ve.Component {
static reserved_keys = ["element", "id", "name"];
constructor (arg0_components_obj, arg1_options) {
//Convert from parameters
let components_obj = (arg0_components_obj) ? arg0_components_obj : {};
let options = (arg1_options) ? arg1_options : {};
super(options);
//Initialise options
options.attributes = (options.attributes) ? options.attributes : {};
//Declare local instance variables
this.element = document.createElement("div");
this.element.setAttribute("component", "ve-hierarchy");
Object.iterate(options.attributes, (local_key, local_value) => {
this.element.setAttribute(local_key, local_value.toString());
});
this.options = options;
HTML.applyTelestyle(this.element, options.style);
//Append components_obj to this.element
this.v = components_obj;
}
/**
* Returns the current {@link this.components_obj}.
* - Accessor of {@link ve.Hierarchy}
*
* @returns {ve.Component[]}
*/
get v () {
//Return statement
return this.components_obj;
}
/**
* Sets the current {@link this.components_obj} displayed in the hierarchy.
* - Accessor of {@link ve.Hierarchy}
*
* @param arg0_components_obj
*/
set v (arg0_components_obj) {
//Convert from parameters
let components_obj = arg0_components_obj;
//Reset element; re-append all components in components_obj to element
/**
* Stores the components currently displayed in the {@link ve.Hierarchy}.
* @instance
* @memberof this
* @type {ve.Component[]}
*/
this.components_obj = components_obj;
this.element.innerHTML = "";
//1. Append all non-hierarchy datatype Vercengen components to controls; iterate over all this.components_obj
Object.iterate(this.components_obj, (local_key, local_value) => {
if (!local_value.is_vercengen_hierarchy_datatype)
this.element.appendChild(local_value.element);
});
//2. Append all hierarchy datatype Vercengen components; iterate over all this.components_obj
let ol_el = document.createElement("ol");
ol_el.setAttribute("class", "list ve-drag-disabled ve-hierarchy");
Object.iterate(this.components_obj, (local_key, local_value) => {
if (local_value.is_vercengen_hierarchy_datatype)
ol_el.appendChild(local_value.element);
});
this.element.appendChild(ol_el);
this.nestable = new Nestable(ol_el, { items: ".group, .item" });
this.nestable.on("stop", () => {
this.fireToBinding();
});
this.fireFromBinding();
}
/**
* Appends the associated hierarchy datatype to the hierarchy.
*
* @param {HTMLElement} arg0_parent_el
* @param {ve.HierarchyDatatype} arg1_hierarchy_datatype
*/
addItem (arg0_parent_el, arg1_hierarchy_datatype) {
//Convert from parameters
let parent_el = (arg0_parent_el) ? arg0_parent_el : this.element.querySelector("ol");
let hierarchy_datatype = arg1_hierarchy_datatype;
//Append child
if (typeof parent_el === "string") parent_el = this.element.querySelector(parent_el);
if (parent_el)
parent_el.appendChild(hierarchy_datatype.element);
}
/**
* Returns an object representative of the items in the hierarchy.
* - Method of: {@link ve.Hierarchy}
*
* @param {Object} [arg0_options]
* @param {boolean} [arg0_options.flatten_object=false] - Whether the object should be flattened, returning only serialisable JSON keys.
*
* @returns {Object}
*/
getHierarchyObject (arg0_options) {
//Convert from parameters
let options = (arg0_options) ? arg0_options : {};
//Declare local instance variables
let ol_el = this.element.querySelector("ol");
//Return statement
return HTML.listToObject(ol_el, (local_el) => {
//Declare local instance variables
let local_name = (local_el && local_el.instance && local_el.instance.name) ?
local_el.instance.name : "";
//Return statement
if (local_el.tagName === "OL") {
try {
local_name = local_el.parentElement.instance.name;
} catch {}
return {
id: local_el.id,
element: (!options.flatten_object) ? local_el : undefined,
name: (local_name) ? local_name : undefined
};
} else if (local_el.tagName === "LI") {
return {
id: local_el.id,
element: (!options.flatten_object) ? local_el : undefined,
name: (local_name) ? local_name : undefined
};
}
});
}
/**
* Removes the associated hierarchy datatype from the hierarchy.
* - Method of: {@link ve.Hierarchy}
*
* @param {ve.HierarchyDatatype} arg0_hierarchy_datatype
*/
removeItem (arg0_hierarchy_datatype) {
//Convert from parameters
let hierarchy_datatype = arg0_hierarchy_datatype;
//Remove item
hierarchy_datatype.remove();
}
};
//Functional binding
/**
* @returns {ve.Hierarchy}
*/
veHierarchy = function () {
//Return statement
return new ve.Hierarchy(...arguments);
};