Replace custom elements with HTMLElement (#585)

This commit is contained in:
MS 2024-02-21 18:04:38 -05:00 committed by GitHub
parent 761b120aee
commit 688dc0b6ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 132 additions and 70 deletions

View file

@ -251,8 +251,7 @@ class SortIndicator extends window.HTMLElement {
} }
} }
// Wrapper for <tr> class FuncRow extends window.HTMLElement {
class FuncRow extends window.HTMLTableRowElement {
static observedAttributes = ['expanded']; static observedAttributes = ['expanded'];
constructor() { constructor() {
@ -262,27 +261,13 @@ class FuncRow extends window.HTMLTableRowElement {
} }
connectedCallback() { connectedCallback() {
if (this.address === null) { if (this.shadowRoot !== null) {
return; return;
} }
if (this.querySelector('td')) { const template = document.querySelector('template#funcrow-template').content;
return; const shadow = this.attachShadow({ mode: 'open' });
} shadow.appendChild(template.cloneNode(true));
const obj = getDataByAddr(this.address);
const td0 = document.createElement('td');
const td1 = document.createElement('td');
const td2 = document.createElement('td');
td0.innerText = `${obj.address}`;
td1.innerText = `${obj.name}`;
td2.innerText = getMatchPercentText(obj);
this.appendChild(td0);
this.appendChild(td1);
this.appendChild(td2);
} }
get address() { get address() {
@ -308,40 +293,36 @@ class FuncRow extends window.HTMLTableRowElement {
} }
} }
// Wrapper for <tr> class NoDiffMessage extends window.HTMLElement {
// Displays asm diff for the given @data-address value. connectedCallback() {
class FuncRowChild extends window.HTMLTableRowElement { if (this.shadowRoot !== null) {
constructor() { return;
super(); }
const td = document.createElement('td'); const template = document.querySelector('template#nodiff-template').content;
td.setAttribute('colspan', 3); const shadow = this.attachShadow({ mode: 'open' });
this.appendChild(td); shadow.appendChild(template.cloneNode(true));
}
}
// Displays asm diff for the given @data-address value.
class DiffRow extends window.HTMLElement {
connectedCallback() {
if (this.shadowRoot !== null) {
return;
}
const template = document.querySelector('template#diffrow-template').content;
const shadow = this.attachShadow({ mode: 'open' });
shadow.appendChild(template.cloneNode(true));
} }
connectedCallback() { get address() {
const td = this.querySelector('td'); return this.getAttribute('data-address');
}
const addr = this.getAttribute('data-address'); set address(value) {
this.setAttribute('data-address', value);
const obj = getDataByAddr(addr);
if ('stub' in obj) {
const diff = document.createElement('div');
diff.className = 'identical';
diff.innerText = 'Stub. No diff.';
td.appendChild(diff);
} else if (obj.diff.length === 0) {
const diff = document.createElement('div');
diff.className = 'identical';
diff.innerText = 'Identical function - no diff';
td.appendChild(diff);
} else {
const dd = new DiffDisplay();
dd.option = '1';
dd.address = addr;
td.appendChild(dd);
}
} }
} }
@ -497,17 +478,39 @@ class ListingTable extends window.HTMLElement {
setRowExpand(address, shouldExpand) { setRowExpand(address, shouldExpand) {
const tbody = this.querySelector('tbody'); const tbody = this.querySelector('tbody');
const funcrow = tbody.querySelector(`tr.funcrow[data-address="${address}"]`); const funcrow = tbody.querySelector(`func-row[data-address="${address}"]`);
if (funcrow === null) { if (funcrow === null) {
return; return;
} }
const existing = tbody.querySelector(`tr.diffRow[data-address="${address}"]`); const existing = tbody.querySelector(`diff-row[data-address="${address}"]`);
if (shouldExpand) { if (shouldExpand) {
if (existing === null) { if (existing === null) {
const diffrow = document.createElement('tr', { is: 'func-row-child' }); const diffrow = document.createElement('diff-row');
diffrow.className = 'diffRow'; diffrow.address = address;
diffrow.setAttribute('data-address', address);
// Decide what goes inside the diff row.
const obj = getDataByAddr(address);
if ('stub' in obj) {
const msg = document.createElement('no-diff');
const p = document.createElement('div');
p.innerText = 'Stub. No diff.';
msg.appendChild(p);
diffrow.appendChild(msg);
} else if (obj.diff.length === 0) {
const msg = document.createElement('no-diff');
const p = document.createElement('div');
p.innerText = 'Identical function - no diff';
msg.appendChild(p);
diffrow.appendChild(msg);
} else {
const dd = new DiffDisplay();
dd.option = '1';
dd.address = address;
diffrow.appendChild(dd);
}
// Insert the diff row after the parent func row. // Insert the diff row after the parent func row.
tbody.insertBefore(diffrow, funcrow.nextSibling); tbody.insertBefore(diffrow, funcrow.nextSibling);
} }
@ -530,12 +533,25 @@ class ListingTable extends window.HTMLElement {
const tbody = this.querySelector('tbody'); const tbody = this.querySelector('tbody');
for (const row of data) { for (const obj of data) {
const tr = document.createElement('tr', { is: 'func-row' }); const row = document.createElement('func-row');
tr.className = 'funcrow'; row.setAttribute('data-address', obj.address); // ?
tr.setAttribute('data-address', row.address);
tr.onchangeExpand = shouldExpand => this.setRowExpand(row.address, shouldExpand); const items = [
tbody.appendChild(tr); ['address', obj.address],
['name', obj.name],
['matching', getMatchPercentText(obj)]
];
items.forEach(([slotName, content]) => {
const div = document.createElement('div');
div.setAttribute('slot', slotName);
div.innerText = content;
row.appendChild(div);
});
row.onchangeExpand = shouldExpand => this.setRowExpand(obj.address, shouldExpand);
tbody.appendChild(row);
} }
this.sortRows(); this.sortRows();
@ -560,7 +576,7 @@ class ListingTable extends window.HTMLElement {
// Select only the function rows and the diff child row. // Select only the function rows and the diff child row.
// Exclude any nested tables used to *display* the diffs. // Exclude any nested tables used to *display* the diffs.
const tbody = this.querySelector('tbody'); const tbody = this.querySelector('tbody');
const rows = tbody.querySelectorAll('tr.funcrow[data-address], tr.diffRow[data-address]'); const rows = tbody.querySelectorAll('func-row[data-address], diff-row[data-address]');
// Sort all rows according to chosen order // Sort all rows according to chosen order
const newRows = Array.from(rows); const newRows = Array.from(rows);
@ -582,7 +598,7 @@ class ListingTable extends window.HTMLElement {
filterRows() { filterRows() {
const tbody = this.querySelector('tbody'); const tbody = this.querySelector('tbody');
const rows = tbody.querySelectorAll('tr.funcrow[data-address], tr.diffRow[data-address]'); const rows = tbody.querySelectorAll('func-row[data-address], diff-row[data-address]');
rows.forEach(row => { rows.forEach(row => {
const addr = row.getAttribute('data-address'); const addr = row.getAttribute('data-address');
@ -591,7 +607,7 @@ class ListingTable extends window.HTMLElement {
}); });
// Update row count // Update row count
this.querySelector('#rowcount').textContent = `${tbody.querySelectorAll('tr.funcrow:not([hidden])').length}`; this.querySelector('#rowcount').textContent = `${tbody.querySelectorAll('func-row:not([hidden])').length}`;
} }
} }
@ -600,6 +616,7 @@ window.onload = () => {
window.customElements.define('diff-display', DiffDisplay); window.customElements.define('diff-display', DiffDisplay);
window.customElements.define('diff-display-options', DiffDisplayOptions); window.customElements.define('diff-display-options', DiffDisplayOptions);
window.customElements.define('sort-indicator', SortIndicator); window.customElements.define('sort-indicator', SortIndicator);
window.customElements.define('func-row', FuncRow, { extends: 'tr' }); window.customElements.define('func-row', FuncRow);
window.customElements.define('func-row-child', FuncRowChild, { extends: 'tr' }); window.customElements.define('diff-row', DiffRow);
window.customElements.define('no-diff', NoDiffMessage);
}; };

View file

@ -39,19 +39,19 @@
font-family: monospace; font-family: monospace;
} }
.funcrow:hover { func-row:hover {
background: #404040 !important; background: #404040 !important;
} }
.funcrow:nth-child(odd of :not([hidden])), #listing > thead th { func-row:nth-child(odd of :not([hidden])), #listing > thead th {
background: #282828; background: #282828;
} }
.funcrow:nth-child(even of :not([hidden])) { func-row:nth-child(even of :not([hidden])) {
background: #383838; background: #383838;
} }
.funcrow > td, .diffRow > td, #listing > thead th { #listing > thead th {
border: 1px #f0f0f0 solid; border: 1px #f0f0f0 solid;
padding: 0.5em; padding: 0.5em;
word-break: break-all !important; word-break: break-all !important;
@ -169,5 +169,50 @@ <h1>Decompilation Status</h1>
</table> </table>
</listing-table> </listing-table>
</div> </div>
<template id="funcrow-template">
<style>
:host(:not([hidden])) {
display: table-row;
contain: paint;
}
::slotted(*) {
border: 1px #f0f0f0 solid;
display: table-cell;
padding: 0.5em;
word-break: break-all !important;
}
</style>
<slot name="address"></slot>
<slot name="name"></slot>
<slot name="matching"></slot>
</template>
<template id="diffrow-template">
<style>
:host(:not([hidden])) {
display: table-row;
contain: paint;
}
td.singleCell {
border: 1px #f0f0f0 solid;
display: table-cell;
padding: 0.5em;
word-break: break-all !important;
}
</style>
<td class="singleCell" colspan="3">
<slot></slot>
</td>
</template>
<template id="nodiff-template">
<style>
::slotted(*) {
font-style: italic;
text-align: center;
}
</style>
<slot></slot>
</template>
</body> </body>
</html> </html>