/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { element } from '../BaseElement.js';
import { LitTabpane } from './lit-tabpane.js';
import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js';
@element('lit-tabs')
export class LitTabs extends HTMLElement {
private tabPos: any;
private nav: HTMLDivElement | undefined | null;
private line: HTMLDivElement | undefined | null;
private slots: HTMLSlotElement | undefined | null;
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
`;
}
static get observedAttributes() {
return ['activekey', 'mode', 'position'];
}
get position() {
return this.getAttribute('position') || 'top';
}
set position(value) {
this.setAttribute('position', value);
}
get mode() {
return this.getAttribute('mode') || 'flat';
}
set mode(value) {
this.setAttribute('mode', value);
}
get activekey() {
return this.getAttribute('activekey') || '';
}
set activekey(value: string) {
this.setAttribute('activekey', value);
}
set onTabClick(fn: any) {
this.addEventListener('onTabClick', fn);
}
updateLabel(key: string, value: string) {
if (this.nav) {
let item = this.nav.querySelector(`.nav-item[data-key='${key}']`);
if (item) {
item.querySelector('span')!.innerHTML = value;
this.initTabPos();
}
}
}
updateDisabled(key: string, value: string) {
if (this.nav) {
let item = this.nav.querySelector(`.nav-item[data-key='${key}']`);
if (item) {
if (value) {
item.setAttribute('data-disabled', '');
} else {
item.removeAttribute('data-disabled');
}
this.initTabPos();
}
}
}
updateCloseable(key: string, value: string) {
if (this.nav) {
let item = this.nav.querySelector(`.nav-item[data-key='${key}']`);
if (item) {
if (value) {
item.setAttribute('data-closeable', '');
} else {
item.removeAttribute('data-closeable');
}
this.initTabPos();
}
}
}
updateHidden(key: string, value: string) {
if (this.nav) {
let item = this.nav.querySelector(`.nav-item[data-key='${key}']`);
if (item) {
if (value === 'true') {
item.setAttribute('data-hidden', '');
} else {
item.removeAttribute('data-hidden');
}
this.initTabPos();
}
}
}
initTabPos() {
const items = this.nav!.querySelectorAll('.nav-item');
Array.from(items).forEach((a, index) => {
// @ts-ignore
this.tabPos[a.dataset.key] = {
index: index,
width: a.offsetWidth,
height: a.offsetHeight,
left: a.offsetLeft,
top: a.offsetTop,
label: a.textContent,
};
});
if (this.activekey) {
if (this.position.startsWith('left')) {
this.line?.setAttribute(
'style',
`height:${this.tabPos[this.activekey].height}px;transform:translate(100%,${
this.tabPos[this.activekey].top
}px)`
);
} else if (this.position.startsWith('top')) {
if (this.tabPos[this.activekey]) {
this.line?.setAttribute(
'style',
`width:${this.tabPos[this.activekey].width}px;transform:translate(${
this.tabPos[this.activekey].left
}px,100%)`
);
}
} else if (this.position.startsWith('right')) {
this.line?.setAttribute(
'style',
`height:${this.tabPos[this.activekey].height}px;transform:translate(-100%,${
this.tabPos[this.activekey].top
}px)`
);
} else if (this.position.startsWith('bottom')) {
this.line?.setAttribute(
'style',
`width:${this.tabPos[this.activekey].width}px;transform:translate(${this.tabPos[this.activekey].left}px,100%)`
);
}
}
}
connectedCallback() {
let that = this;
this.tabPos = {};
this.nav = this.shadowRoot?.querySelector('#nav');
this.line = this.shadowRoot?.querySelector('#tab-line');
this.slots = this.shadowRoot?.querySelector('#slot');
this.slots?.addEventListener('slotchange', () => {
const elements: Element[] | undefined = this.slots?.assignedElements();
let panes = this.querySelectorAll('lit-tabpane');
if (this.activekey) {
panes.forEach((a) => {
if (a.key === this.activekey) {
a.style.display = 'block';
} else {
a.style.display = 'none';
}
});
} else {
panes.forEach((a, index) => {
if (index === 0) {
a.style.display = 'block';
this.activekey = a.key || '';
} else {
a.style.display = 'none';
}
});
}
let navHtml = '';
elements
?.map((it) => it as LitTabpane)
.forEach((a) => {
if (a.disabled) {
navHtml += `
${a.icon ? `
` : ``}
${a.tab}
`;
} else if (a.hidden) {
navHtml += `
${a.icon ? `
` : ``}
${a.tab}
`;
} else {
if (a.key === this.activekey) {
navHtml += `
${a.icon ? `
` : ``}
${a.tab}
`;
} else {
navHtml += `
${a.icon ? `
` : ``}
${a.tab}
`;
}
}
});
this.nav!.innerHTML = navHtml;
this.initTabPos();
this.nav!.querySelectorAll('.close-icon').forEach((a) => {
a.onclick = (e) => {
e.stopPropagation();
const closeKey = (e.target! as HTMLElement).parentElement!.dataset.key;
this.dispatchEvent(
new CustomEvent('close-handler', {
detail: { key: closeKey },
composed: true,
})
);
};
});
});
this.nav!.onclick = (e) => {
if ((e.target! as HTMLElement).closest('div')!.hasAttribute('data-disabled')) return;
let key = (e.target! as HTMLElement).closest('div')!.dataset.key;
if (key) {
this.activeByKey(key);
}
let label = (e.target! as HTMLElement).closest('div')!.querySelector('span')!.textContent;
this.dispatchEvent(
new CustomEvent('onTabClick', {
detail: { key: key, tab: label },
})
);
};
new ResizeObserver((entries) => {
let filling = this.shadowRoot!.querySelector('#tab-filling');
this.shadowRoot!.querySelector('.tab-nav-container')!.style.height = filling!.offsetWidth + 'px';
}).observe(this.shadowRoot!.querySelector('#tab-filling')!);
}
activeByKey(key: string, isValid: boolean = true) {
if (key === null || key === undefined) return; //如果没有key 不做相应
this.nav!.querySelectorAll('.nav-item').forEach((a) => {
if (a.querySelector('span')?.innerText === 'Comparison') {
a.setAttribute('id', 'nav-comparison');
}
if (a.getAttribute('data-key') === key) {
a.setAttribute('data-selected', 'true');
if (isValid) {
let span = a.querySelector('span') as HTMLSpanElement;
let title = span.innerText;
let rowType = document
.querySelector('sp-application')!
.shadowRoot?.querySelector('sp-system-trace')!
.getAttribute('clickRow');
if (title === 'Counters' || title === 'Thread States') {
title += `(${rowType})`;
}
if (title === 'Analysis') {
let rowId = document
.querySelector('sp-application')!
.shadowRoot?.querySelector('sp-system-trace')!
.getAttribute('rowId');
if (rowId!.indexOf('DiskIOLatency') > -1) {
title += '(disk-io)';
} else if (rowId!.indexOf('VirtualMemory') > -1) {
title += '(virtual-memory-cell)';
} else {
title += `(${rowType})`;
}
}
if (title === 'Slices' || title === 'Current Selection') {
let rowName = document
.querySelector('sp-application')!
.shadowRoot?.querySelector('sp-system-trace')!
.getAttribute('rowName');
if (rowName && rowName!.indexOf('deliverInputEvent') > -1) {
title += '(deliverInputEvent)';
} else {
let rowType = document
.querySelector('sp-application')!
.shadowRoot?.querySelector('sp-system-trace')!
.getAttribute('clickRow');
title += `(${rowType})`;
}
}
SpStatisticsHttpUtil.addOrdinaryVisitAction({
event: title,
action: 'trace_tab',
});
}
} else {
a.removeAttribute('data-selected');
}
});
let tbp = this.querySelector(`lit-tabpane[key='${key}']`);
let panes = this.querySelectorAll('lit-tabpane');
panes.forEach((a) => {
if (a.key === key) {
a.style.display = 'block';
this.activekey = a.key;
this.initTabPos();
} else {
a.style.display = 'none';
}
});
}
activePane(key: string) {
if (key === null || key === undefined) return false;
let tbp = this.querySelector(`lit-tabpane[key='${key}']`);
if (tbp) {
this.activeByKey(key);
return true;
} else {
return false;
}
}
disconnectedCallback() {}
adoptedCallback() {}
attributeChangedCallback(name: string, oldValue: string, newValue: string) {
if (name === 'activekey' && this.nav && oldValue !== newValue && newValue != '') {
this.activeByKey(newValue, false);
}
}
}