From d35ff4bca69175bb6909722379298c17ae2f0989 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 23 Sep 2021 17:03:20 +1000 Subject: -minimaws: Made table sort widgets (and the code behind them) less ugly. -util/delegate.cpp: Added a couple of comments about assumptions. --- scripts/minimaws/lib/assets/common.js | 109 +++++++++++++++++++------------ scripts/minimaws/lib/assets/sortasc.png | Bin 1157 -> 0 bytes scripts/minimaws/lib/assets/sortasc.svg | 4 ++ scripts/minimaws/lib/assets/sortdesc.png | Bin 1195 -> 0 bytes scripts/minimaws/lib/assets/sortdesc.svg | 4 ++ scripts/minimaws/lib/assets/sortind.png | Bin 1247 -> 0 bytes scripts/minimaws/lib/assets/sortind.svg | 5 ++ scripts/minimaws/lib/assets/style.css | 3 + scripts/minimaws/lib/wsgiserve.py | 9 ++- src/lib/util/delegate.cpp | 11 ++++ 10 files changed, 102 insertions(+), 43 deletions(-) delete mode 100644 scripts/minimaws/lib/assets/sortasc.png create mode 100644 scripts/minimaws/lib/assets/sortasc.svg delete mode 100644 scripts/minimaws/lib/assets/sortdesc.png create mode 100644 scripts/minimaws/lib/assets/sortdesc.svg delete mode 100644 scripts/minimaws/lib/assets/sortind.png create mode 100644 scripts/minimaws/lib/assets/sortind.svg diff --git a/scripts/minimaws/lib/assets/common.js b/scripts/minimaws/lib/assets/common.js index a9d1991e499..b7b482d5405 100644 --- a/scripts/minimaws/lib/assets/common.js +++ b/scripts/minimaws/lib/assets/common.js @@ -1,55 +1,82 @@ // license:BSD-3-Clause // copyright-holders:Vas Crabb -function sort_table(tbl, col, dir, numeric) +function make_table_sortable(tbl) { - var tbody = tbl.tBodies[0]; - var trows = Array.prototype.slice.call(tbody.rows, 0).sort( - function (x, y) + var sorticons = new Array(tbl.tHead.rows[0].cells.length); + + function TableSortHelper(i) + { + this.column = i; + this.header = tbl.tHead.rows[0].cells[i] + this.sorted = false; + this.direction = 1; + + this.icon = document.createElement('img'); + this.icon.setAttribute('src', assetsurl + '/sortind.svg'); + this.icon.addEventListener('click', this.icon_click.bind(this)); + + var container = document.createElement('div'); + container.setAttribute('class', 'sorticon'); + container.appendChild(this.icon); + this.header.appendChild(container); + } + + TableSortHelper.prototype = (function () { - if (numeric) - return dir * (parseFloat(x.cells[col].textContent) - parseFloat(y.cells[col].textContent)); - else - return dir * x.cells[col].textContent.localeCompare(y.cells[col].textContent); - }) - trows.forEach(function (row) { tbody.appendChild(row); }); -} + function set_unsorted(obj) + { + obj.sorted = false; + obj.icon.setAttribute('src', assetsurl + '/sortind.svg'); + } + function sort_table(obj) + { + var c = obj.header.cellIndex; + var numeric = obj.header.getAttribute('class') == 'numeric'; + var tbody = tbl.tBodies[0]; + var trows; + if (numeric) + { + trows = Array.prototype.slice.call(tbody.rows, 0).sort( + function (x, y) + { + return obj.direction * (parseFloat(x.cells[c].textContent) - parseFloat(y.cells[c].textContent)); + }); + } + else + { + trows = Array.prototype.slice.call(tbody.rows, 0).sort( + function (x, y) + { + return obj.direction * x.cells[c].textContent.localeCompare(y.cells[c].textContent); + }); + } + trows.forEach(function (row) { tbody.appendChild(row); }); + } -function make_table_sortable(tbl) -{ - var headers = tbl.tHead.rows[0].cells; - for (var i = 0; i < headers.length; i++) - { - (function (col) - { - var dir = 1; - var sorticon = document.createElement('img'); - sorticon.setAttribute('src', assetsurl + '/sortind.png'); - sorticon.style.cssFloat = 'right'; - sorticon.style.marginLeft = '0.5em'; - headers[col].appendChild(sorticon); - headers[col].addEventListener( - 'click', - function (event) + return { + icon_click : function (event) { - var imgsrc = sorticon.getAttribute('src'); - imgsrc = imgsrc.substr(imgsrc.lastIndexOf('/') + 1); - if (imgsrc != 'sortind.png') - dir = -dir; - if (dir < 0) - sorticon.setAttribute('src', assetsurl + '/sortdesc.png'); + if (this.sorted) + this.direction = -this.direction; + if (this.direction < 0) + this.icon.setAttribute('src', assetsurl + '/sortdesc.svg'); else - sorticon.setAttribute('src', assetsurl + '/sortasc.png'); - for (var i = 0; i < headers.length; i++) + this.icon.setAttribute('src', assetsurl + '/sortasc.svg'); + this.sorted = true; + for (var i = 0; i < sorticons.length; i++) { - if (i != col) - headers[i].lastChild.setAttribute('src', assetsurl + '/sortind.png'); + if (i != this.column) + set_unsorted(sorticons[i]); } - sort_table(tbl, col, dir, headers[col].getAttribute('class') == 'numeric'); - }); - }(i)); - } + sort_table(this); + } + }; + })(); + + for (var i = 0; i < sorticons.length; i++) + sorticons[i] = new TableSortHelper(i); } diff --git a/scripts/minimaws/lib/assets/sortasc.png b/scripts/minimaws/lib/assets/sortasc.png deleted file mode 100644 index 29b893cdd02..00000000000 Binary files a/scripts/minimaws/lib/assets/sortasc.png and /dev/null differ diff --git a/scripts/minimaws/lib/assets/sortasc.svg b/scripts/minimaws/lib/assets/sortasc.svg new file mode 100644 index 00000000000..c2ff41afccb --- /dev/null +++ b/scripts/minimaws/lib/assets/sortasc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/scripts/minimaws/lib/assets/sortdesc.png b/scripts/minimaws/lib/assets/sortdesc.png deleted file mode 100644 index 63f48fc7213..00000000000 Binary files a/scripts/minimaws/lib/assets/sortdesc.png and /dev/null differ diff --git a/scripts/minimaws/lib/assets/sortdesc.svg b/scripts/minimaws/lib/assets/sortdesc.svg new file mode 100644 index 00000000000..4a10b3f6e47 --- /dev/null +++ b/scripts/minimaws/lib/assets/sortdesc.svg @@ -0,0 +1,4 @@ + + + + diff --git a/scripts/minimaws/lib/assets/sortind.png b/scripts/minimaws/lib/assets/sortind.png deleted file mode 100644 index 773dd6aec02..00000000000 Binary files a/scripts/minimaws/lib/assets/sortind.png and /dev/null differ diff --git a/scripts/minimaws/lib/assets/sortind.svg b/scripts/minimaws/lib/assets/sortind.svg new file mode 100644 index 00000000000..6e351b6a6fb --- /dev/null +++ b/scripts/minimaws/lib/assets/sortind.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/scripts/minimaws/lib/assets/style.css b/scripts/minimaws/lib/assets/style.css index 1e6ebd57ec0..8cbce4aaf0e 100644 --- a/scripts/minimaws/lib/assets/style.css +++ b/scripts/minimaws/lib/assets/style.css @@ -5,6 +5,9 @@ th { text-align: left; background-color: #ddd; padding: 0.25em } td { padding-left: 0.25em; padding-right: 0.25em } +div[class=sorticon] { float: right; height: 100%; margin-left: 0.5em } +div[class=sorticon] img { height: 0.7em; vertical-align: baseline } + table[class=sysinfo] th { text-align: right } div[class=dropzone] { padding: 0 1em; border-width: 2px; border-radius: 1em; border-style: dashed } diff --git a/scripts/minimaws/lib/wsgiserve.py b/scripts/minimaws/lib/wsgiserve.py index 0a5cda4f762..26e7d523904 100644 --- a/scripts/minimaws/lib/wsgiserve.py +++ b/scripts/minimaws/lib/wsgiserve.py @@ -67,6 +67,8 @@ class ErrorPageHandler(HandlerBase): class AssetHandler(HandlerBase): + EXTENSIONMAP = { '.js': 'application/javascript', '.svg': 'image/svg+xml' } + def __init__(self, directory, app, application_uri, environ, start_response, **kwargs): super(AssetHandler, self).__init__(app=app, application_uri=application_uri, environ=environ, start_response=start_response, **kwargs) self.directory = directory @@ -90,8 +92,11 @@ class AssetHandler(HandlerBase): else: try: f = open(path, 'rb') - type, encoding = mimetypes.guess_type(path) - self.start_response('200 OK', [('Content-type', type or 'application/octet-stream'), ('Cache-Control', 'public, max-age=3600')]) + base, extension = os.path.splitext(path) + mimetype = self.EXTENSIONMAP.get(extension) + if mimetype is None: + mimetype, encoding = mimetypes.guess_type(path) + self.start_response('200 OK', [('Content-type', mimetype or 'application/octet-stream'), ('Cache-Control', 'public, max-age=3600')]) return wsgiref.util.FileWrapper(f) except: self.start_response('500 %s' % (self.STATUS_MESSAGE[500], ), [('Content-type', 'text/html; charset=utf-8'), ('Cache-Control', 'public, max-age=3600')]) diff --git a/src/lib/util/delegate.cpp b/src/lib/util/delegate.cpp index cedb8e60bd8..3ccb7294ee4 100644 --- a/src/lib/util/delegate.cpp +++ b/src/lib/util/delegate.cpp @@ -156,6 +156,14 @@ delegate_generic_function delegate_mfp_msvc::adjust_this_pointer(delegate_generi else if ((0x48 == func[0]) && (0x8b == func[1]) && (0x01 == func[2]) && (0xff == func[3]) && ((0x20 == func[4]) || (0x60 == func[4]) || (0xa0 == func[4]))) { // virtual function call thunk - mov rax,QWORD PTR [rcx] ; jmp QWORD PTR [rax+...] + // Assumes Windows calling convention, and doesn't consider + // that the "this" pointer could be in RDX if RCX is a + // pointer to space for an oversize scalar result. Since + // the result area is uninitialised on entry, you won't see + // something that looks like a vtable dispatch through RCX + // in this case - it won't behave badly, it just won't + // bypass virtual call thunks in the rare situations where + // the return type is an oversize scalar. LOG("Found virtual member function thunk at %p ", func); std::uint8_t const *const vptr = *reinterpret_cast(object); if (0x20 == func[4]) // no displacement @@ -177,6 +185,9 @@ delegate_generic_function delegate_mfp_msvc::adjust_this_pointer(delegate_generi std::uint32_t const *func = reinterpret_cast(m_function); while (true) { + // Assumes little Endian mode. Instructions are always stored + // in little Endian format on AArch64, so if big Endian mode is + // to be supported, the values need to be swapped. if ((0xf9400010 == func[0]) && (0xf9400210 == (func[1] & 0xffc003ff)) && (0xd61f0200 == func[2])) { // virtual function call thunk - ldr xip0,[x0] ; ldr xip0,[x0,#...] ; br xip0 -- cgit v1.2.3