11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciimport {App} from '../index.mjs'
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciimport {FocusEvent, SelectRelatedEvent} from './events.mjs';
81cb0ef41Sopenharmony_ciimport {DOM, entriesEquals, ExpandableText, V8CustomElement} from './helper.mjs';
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciDOM.defineCustomElement('view/property-link-table',
111cb0ef41Sopenharmony_ci                        template =>
121cb0ef41Sopenharmony_ci                            class PropertyLinkTable extends V8CustomElement {
131cb0ef41Sopenharmony_ci  _object;
141cb0ef41Sopenharmony_ci  _propertyDict;
151cb0ef41Sopenharmony_ci  _instanceLinkButtons = false;
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci  _showHandler = this._handleShow.bind(this);
181cb0ef41Sopenharmony_ci  _showSourcePositionHandler = this._handleShowSourcePosition.bind(this);
191cb0ef41Sopenharmony_ci  _showRelatedHandler = this._handleShowRelated.bind(this);
201cb0ef41Sopenharmony_ci  _arrayValueSelectHandler = this._handleArrayValueSelect.bind(this);
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  constructor() {
231cb0ef41Sopenharmony_ci    super(template);
241cb0ef41Sopenharmony_ci  }
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  set instanceLinkButtons(newValue) {
271cb0ef41Sopenharmony_ci    this._instanceLinkButtons = newValue;
281cb0ef41Sopenharmony_ci  }
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  set propertyDict(propertyDict) {
311cb0ef41Sopenharmony_ci    if (entriesEquals(this._propertyDict, propertyDict)) return;
321cb0ef41Sopenharmony_ci    if (typeof propertyDict !== 'object') {
331cb0ef41Sopenharmony_ci      throw new Error(
341cb0ef41Sopenharmony_ci          `Invalid property dict, expected object: ${propertyDict}`);
351cb0ef41Sopenharmony_ci    }
361cb0ef41Sopenharmony_ci    this._propertyDict = propertyDict;
371cb0ef41Sopenharmony_ci    this.requestUpdate();
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  _update() {
411cb0ef41Sopenharmony_ci    this._fragment = new DocumentFragment();
421cb0ef41Sopenharmony_ci    this._table = DOM.table();
431cb0ef41Sopenharmony_ci    for (let key in this._propertyDict) {
441cb0ef41Sopenharmony_ci      const value = this._propertyDict[key];
451cb0ef41Sopenharmony_ci      this._addKeyValue(key, value);
461cb0ef41Sopenharmony_ci    }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci    const tableDiv = DOM.div('properties');
491cb0ef41Sopenharmony_ci    tableDiv.appendChild(this._table);
501cb0ef41Sopenharmony_ci    this._fragment.appendChild(tableDiv);
511cb0ef41Sopenharmony_ci    this._createFooter();
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci    const newContent = DOM.div();
541cb0ef41Sopenharmony_ci    newContent.appendChild(this._fragment);
551cb0ef41Sopenharmony_ci    this.$('#content').replaceWith(newContent);
561cb0ef41Sopenharmony_ci    newContent.id = 'content';
571cb0ef41Sopenharmony_ci    this._fragment = undefined;
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  _addKeyValue(key, value) {
611cb0ef41Sopenharmony_ci    if (key == 'title') {
621cb0ef41Sopenharmony_ci      this._addTitle(value);
631cb0ef41Sopenharmony_ci      return;
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci    if (key == '__this__') {
661cb0ef41Sopenharmony_ci      this._object = value;
671cb0ef41Sopenharmony_ci      return;
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci    const row = this._table.insertRow();
701cb0ef41Sopenharmony_ci    row.insertCell().innerText = key;
711cb0ef41Sopenharmony_ci    const cell = row.insertCell();
721cb0ef41Sopenharmony_ci    if (value == undefined) return;
731cb0ef41Sopenharmony_ci    if (Array.isArray(value)) {
741cb0ef41Sopenharmony_ci      cell.appendChild(this._addArrayValue(value));
751cb0ef41Sopenharmony_ci      return;
761cb0ef41Sopenharmony_ci    } else if (App.isClickable(value)) {
771cb0ef41Sopenharmony_ci      cell.className = 'clickable';
781cb0ef41Sopenharmony_ci      cell.onclick = this._showHandler;
791cb0ef41Sopenharmony_ci      cell.data = value;
801cb0ef41Sopenharmony_ci    }
811cb0ef41Sopenharmony_ci    if (value.isCode) {
821cb0ef41Sopenharmony_ci      cell.classList.add('code');
831cb0ef41Sopenharmony_ci    }
841cb0ef41Sopenharmony_ci    new ExpandableText(cell, value.toString());
851cb0ef41Sopenharmony_ci  }
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  _addArrayValue(array) {
881cb0ef41Sopenharmony_ci    if (array.length == 0) {
891cb0ef41Sopenharmony_ci      return DOM.text('empty');
901cb0ef41Sopenharmony_ci    } else if (array.length > 200) {
911cb0ef41Sopenharmony_ci      return DOM.text(`${array.length} items`);
921cb0ef41Sopenharmony_ci    }
931cb0ef41Sopenharmony_ci    const select = DOM.element('select');
941cb0ef41Sopenharmony_ci    select.onchange = this._arrayValueSelectHandler;
951cb0ef41Sopenharmony_ci    for (let value of array) {
961cb0ef41Sopenharmony_ci      const option = DOM.element('option');
971cb0ef41Sopenharmony_ci      option.innerText = value === undefined ? '' : value.toString();
981cb0ef41Sopenharmony_ci      option.data = value;
991cb0ef41Sopenharmony_ci      select.add(option);
1001cb0ef41Sopenharmony_ci    }
1011cb0ef41Sopenharmony_ci    return select;
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  _addTitle(value) {
1051cb0ef41Sopenharmony_ci    const title = DOM.element('h3');
1061cb0ef41Sopenharmony_ci    title.innerText = value;
1071cb0ef41Sopenharmony_ci    this._fragment.appendChild(title);
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  _createFooter() {
1111cb0ef41Sopenharmony_ci    if (this._object === undefined) return;
1121cb0ef41Sopenharmony_ci    if (!this._instanceLinkButtons) return;
1131cb0ef41Sopenharmony_ci    const footer = DOM.div('footer');
1141cb0ef41Sopenharmony_ci    let showButton = footer.appendChild(DOM.button('Show', this._showHandler));
1151cb0ef41Sopenharmony_ci    showButton.data = this._object;
1161cb0ef41Sopenharmony_ci    if (this._object.sourcePosition) {
1171cb0ef41Sopenharmony_ci      let showSourcePositionButton = footer.appendChild(
1181cb0ef41Sopenharmony_ci          DOM.button('Source Position', this._showSourcePositionHandler));
1191cb0ef41Sopenharmony_ci      showSourcePositionButton.data = this._object;
1201cb0ef41Sopenharmony_ci    }
1211cb0ef41Sopenharmony_ci    let showRelatedButton = footer.appendChild(
1221cb0ef41Sopenharmony_ci        DOM.button('Show Related', this._showRelatedHandler));
1231cb0ef41Sopenharmony_ci    showRelatedButton.data = this._object;
1241cb0ef41Sopenharmony_ci    this._fragment.appendChild(footer);
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  _handleArrayValueSelect(event) {
1281cb0ef41Sopenharmony_ci    const logEntry = event.currentTarget.selectedOptions[0].data;
1291cb0ef41Sopenharmony_ci    this.dispatchEvent(new FocusEvent(logEntry));
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  _handleShow(event) {
1331cb0ef41Sopenharmony_ci    this.dispatchEvent(new FocusEvent(event.currentTarget.data));
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  _handleShowSourcePosition(event) {
1371cb0ef41Sopenharmony_ci    this.dispatchEvent(new FocusEvent(event.currentTarget.data.sourcePosition));
1381cb0ef41Sopenharmony_ci  }
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  _handleShowRelated(event) {
1411cb0ef41Sopenharmony_ci    this.dispatchEvent(new SelectRelatedEvent(event.currentTarget.data));
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci});
144