blob: 8273d5e8d83a2b0394a6eda1f7fbfb3826582015 [file] [log] [blame]
/**
* @typedef { import("./Filter").Filter } Filter
* @typedef { { ref: Element; name: string; description: string } } ListElement
* @typedef { [key: string, value: string][] } Dataset
*/
class DocumentableList extends Component {
constructor(props) {
super(props);
this.refs = {
tabs: findRefs(".names .tab[data-togglable]", findRef(".membersList")).concat(
findRefs(".contents h2[data-togglable]", findRef(".membersList"))
),
sections: findRefs(".contents .tab[data-togglable]", findRef(".membersList")),
};
this.state = {
list: new List(this.refs.tabs, this.refs.sections),
};
this.render(this.props);
}
toggleElementDatasetVisibility(isVisible, ref) {
ref.dataset.visibility = isVisible
}
toggleDisplayStyles(condition, ref) {
ref.style.display = condition ? null : 'none'
}
render({ filter }) {
this.state.list.sectionsRefs.map(sectionRef => {
const isTabVisible = this.state.list
.getSectionListRefs(sectionRef)
.filter((listRef) => {
const isListVisible = this.state.list
.getSectionListElementsRefs(listRef)
.map(elementRef => this.state.list.toListElement(elementRef))
.filter(elementData => {
const isElementVisible = this.state.list.isElementVisible(elementData, filter);
this.toggleDisplayStyles(isElementVisible, elementData.ref);
this.toggleElementDatasetVisibility(isElementVisible, elementData.ref);
return isElementVisible;
}).length;
findRefs("span.groupHeader", listRef).forEach(h => {
const headerSiblings = this.state.list.getSectionListElementsRefs(h.parentNode).map(ref => this.state.list.toListElement(ref))
const isHeaderVisible = headerSiblings.filter(s => this.state.list.isElementVisible(s, filter)) != 0
this.toggleDisplayStyles(isHeaderVisible, h)
})
this.toggleDisplayStyles(isListVisible, listRef);
return isListVisible;
}).length;
const outerThis = this
this.state.list.getTabRefFromSectionRef(sectionRef).forEach(function(tabRef){
outerThis.toggleDisplayStyles(isTabVisible, tabRef);
})
});
}
}
class List {
/**
* @param tabsRef { Element[] }
* @param sectionRefs { Element[] }
*/
constructor(tabsRef, sectionRefs) {
this._tabsRef = tabsRef;
this._sectionRefs = sectionRefs;
}
get tabsRefs() {
return this._tabsRef.filter(tabRef => this.filterTab(this._getTogglable(tabRef)));
}
get sectionsRefs() {
return this._sectionRefs.filter(sectionRef => this.filterTab(this._getTogglable(sectionRef)));
}
/**
* @param name { string }
*/
filterTab(name) {
return name !== "Linear supertypes" && name !== "Known subtypes" && name !== "Type hierarchy"
}
/**
* @param sectionRef { Element }
*/
getTabRefFromSectionRef(sectionRef) {
return this.tabsRefs.filter(
(tabRef) => this._getTogglable(tabRef) === this._getTogglable(sectionRef)
);
}
/**
* @param sectionRef { Element }
* @returns { Element[] }
*/
getSectionListRefs(sectionRef) {
return findRefs(".documentableList", sectionRef);
}
/**
* @param listRef { Element }
* @returns { Element[] }
*/
getSectionListElementsRefs(listRef) {
return findRefs(".documentableElement", listRef);
}
/**
* @param elementRef { Element }
* @returns { ListElement }
*/
toListElement(elementRef) {
return {
ref: elementRef,
name: getElementTextContent(getElementNameRef(elementRef)),
description: getElementTextContent(getElementDescription(elementRef)),
};
}
/**
* @param elementData { ListElement }
* @param filter { Filter }
*/
isElementVisible(elementData, filter) {
return !areFiltersFromElementSelected()
? false
: includesInputValue()
function includesInputValue() {
const lcValue = filter.value.toLowerCase()
return elementData.name.toLowerCase().includes(lcValue)
|| elementData.description.toLowerCase().includes(lcValue);
}
function areFiltersFromElementSelected() {
/** @type { Dataset } */
const dataset = Object.entries(elementData.ref.dataset)
/** @type { Dataset } */
const defaultFilters = Object.entries(Filter.defaultFilters)
.filter(([key]) => !!filter.filters[getFilterKey(key)])
/** @type { Dataset } */
const defaultFiltersForMembersWithoutDataAttribute =
defaultFilters.reduce((acc, [key, value]) => {
const filterKey = getFilterKey(key)
const shouldAddDefaultFilter = !dataset.some(([k]) => k === filterKey)
return shouldAddDefaultFilter ? [...acc, [filterKey, value]] : acc
}, [])
/** @type { Dataset } */
const datasetWithAppendedDefaultFilters = dataset
.filter(([k]) => isFilterData(k))
.map(([k, v]) => {
const defaultFilter = defaultFilters.find(([defaultKey]) => defaultKey === k)
return defaultFilter ? [k, `${v},${defaultFilter[1]}`] : [k, v]
})
const datasetWithDefaultFilters = [
...defaultFiltersForMembersWithoutDataAttribute,
...datasetWithAppendedDefaultFilters
]
const isVisible = datasetWithDefaultFilters
.every(([filterKey, value]) => {
const filterGroup = filter.filters[filterKey]
return value.split(",").some(v => filterGroup && filterGroup[v].selected)
})
return isVisible
}
}
/**
* @private
* @param elementData { ListElement }
*/
_getTogglable = elementData => elementData.dataset.togglable;
}