diff options
author | 2021-09-29 15:01:16 +1000 | |
---|---|---|
committer | 2021-09-29 15:01:16 +1000 | |
commit | 698df33896bc57187ea4fe443d95c8b53780df38 (patch) | |
tree | 6920aad7ab96e342fb67113a3f84f384937b21ef /docs/release/scripts/minimaws/lib | |
parent | 9c9b2f30bb67deefbfd869138e66d24bf277ebf1 (diff) |
0.236 filestag236
Diffstat (limited to 'docs/release/scripts/minimaws/lib')
11 files changed, 189 insertions, 73 deletions
diff --git a/docs/release/scripts/minimaws/lib/assets/common.js b/docs/release/scripts/minimaws/lib/assets/common.js index a9d1991e499..baedcf3940d 100644 --- a/docs/release/scripts/minimaws/lib/assets/common.js +++ b/docs/release/scripts/minimaws/lib/assets/common.js @@ -1,55 +1,119 @@ // license:BSD-3-Clause // copyright-holders:Vas Crabb -function sort_table(tbl, col, dir, numeric) +function make_collapsible(heading, section) { - var tbody = tbl.tBodies[0]; - var trows = Array.prototype.slice.call(tbody.rows, 0).sort( - function (x, y) + var hidden = false; + var display = section.style.display; + var icon = heading.insertBefore(document.createElement('img'), heading.firstChild); + icon.setAttribute('src', assetsurl + '/disclosedown.svg'); + icon.setAttribute('class', 'disclosure'); + icon.addEventListener( + 'click', + function (event) { - if (numeric) - return dir * (parseFloat(x.cells[col].textContent) - parseFloat(y.cells[col].textContent)); + hidden = !hidden; + if (hidden) + { + icon.setAttribute('src', assetsurl + '/discloseup.svg'); + section.style.display = 'none'; + } else - return dir * x.cells[col].textContent.localeCompare(y.cells[col].textContent); - }) - trows.forEach(function (row) { tbody.appendChild(row); }); + { + icon.setAttribute('src', assetsurl + '/disclosedown.svg'); + section.style.display = display; + var headingtop = 0; + for (var element = heading; element !== null; element = element.offsetParent) + headingtop += element.offsetTop; + var sectionbot = section.offsetHeight; + for (var element = section; element !== null; element = element.offsetParent) + sectionbot += element.offsetTop; + if ((window.pageYOffset + window.innerHeight) < sectionbot) + { + if ((sectionbot - headingtop) > window.innerHeight) + heading.scrollIntoView(true); + else + window.scroll(window.pageXOffset, sectionbot - window.innerHeight); + } + } + }); } function make_table_sortable(tbl) { - var headers = tbl.tHead.rows[0].cells; - for (var i = 0; i < headers.length; i++) + var sorticons = new Array(tbl.tHead.rows[0].cells.length); + + function TableSortHelper(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) + this.column = i; + this.header = tbl.tHead.rows[0].cells[i]; + this.sorted = false; + this.direction = 1; + + var container = this.header.appendChild(document.createElement('div')); + container.setAttribute('class', 'sorticon'); + + this.icon = container.appendChild(document.createElement('img')); + this.icon.setAttribute('src', assetsurl + '/sortind.svg'); + this.icon.addEventListener('click', this.icon_click.bind(this)); + } + + TableSortHelper.prototype = (function () + { + 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) { - 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'); + 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); }); + } + + return { + icon_click : function (event) + { + 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/docs/release/scripts/minimaws/lib/assets/disclosedown.svg b/docs/release/scripts/minimaws/lib/assets/disclosedown.svg new file mode 100644 index 00000000000..ddf75e25f0f --- /dev/null +++ b/docs/release/scripts/minimaws/lib/assets/disclosedown.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="16" width="16"> + <path d="m 0,0 h 16 l -8,16 z" /> +</svg> diff --git a/docs/release/scripts/minimaws/lib/assets/discloseup.svg b/docs/release/scripts/minimaws/lib/assets/discloseup.svg new file mode 100644 index 00000000000..51e2bea9863 --- /dev/null +++ b/docs/release/scripts/minimaws/lib/assets/discloseup.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="16" width="16"> + <path d="m 0,0 v 16 l 16,-8 z" /> +</svg> diff --git a/docs/release/scripts/minimaws/lib/assets/romident.js b/docs/release/scripts/minimaws/lib/assets/romident.js index e42daf875cf..599b0674007 100644 --- a/docs/release/scripts/minimaws/lib/assets/romident.js +++ b/docs/release/scripts/minimaws/lib/assets/romident.js @@ -132,6 +132,7 @@ function add_unmatched(names, crc, sha1) heading.textContent = 'Unmatched'; table = div.appendChild(document.createElement('table')); table.setAttribute('id', 'table-unmatched'); + make_collapsible(heading, table); } var content; if (crc === null) @@ -160,8 +161,10 @@ function add_issues(name) var list; if (!div.hasChildNodes()) { - div.appendChild(document.createElement('h2')).textContent = 'Potential Issues'; + var heading = div.appendChild(document.createElement('h2')); + heading.textContent = 'Potential Issues'; list = div.appendChild(document.createElement('dl')); + make_collapsible(heading, list); } else { @@ -229,6 +232,7 @@ function get_machine_table(shortname, description) var table = div.appendChild(document.createElement('table')); machine_info[shortname] = table; add_matches(table, matched_names, null); + make_collapsible(heading, table); return table; } } diff --git a/docs/release/scripts/minimaws/lib/assets/sortasc.svg b/docs/release/scripts/minimaws/lib/assets/sortasc.svg new file mode 100644 index 00000000000..c2ff41afccb --- /dev/null +++ b/docs/release/scripts/minimaws/lib/assets/sortasc.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="16" width="30"> + <path d="m 14,16 h 16 l -8,-16 z" /> +</svg> diff --git a/docs/release/scripts/minimaws/lib/assets/sortdesc.svg b/docs/release/scripts/minimaws/lib/assets/sortdesc.svg new file mode 100644 index 00000000000..4a10b3f6e47 --- /dev/null +++ b/docs/release/scripts/minimaws/lib/assets/sortdesc.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="16" width="30"> + <path d="m 14,0 h 16 l -8,16 z" /> +</svg> diff --git a/docs/release/scripts/minimaws/lib/assets/sortind.svg b/docs/release/scripts/minimaws/lib/assets/sortind.svg new file mode 100644 index 00000000000..6e351b6a6fb --- /dev/null +++ b/docs/release/scripts/minimaws/lib/assets/sortind.svg @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="16" width="30"> + <path d="m 0,16 h 16 l -8,-16 z" /> + <path d="m 14,0 h 16 l -8,16 z" /> +</svg> diff --git a/docs/release/scripts/minimaws/lib/assets/style.css b/docs/release/scripts/minimaws/lib/assets/style.css index 1e6ebd57ec0..9ba6631a783 100644 --- a/docs/release/scripts/minimaws/lib/assets/style.css +++ b/docs/release/scripts/minimaws/lib/assets/style.css @@ -5,6 +5,11 @@ th { text-align: left; background-color: #ddd; padding: 0.25em } td { padding-left: 0.25em; padding-right: 0.25em } +img[class=disclosure] { height: 0.7em; margin-right: 0.25em; vertical-align: baseline } + +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/docs/release/scripts/minimaws/lib/dbaccess.py b/docs/release/scripts/minimaws/lib/dbaccess.py index 7ca5ebf243d..c22b7c318fa 100644 --- a/docs/release/scripts/minimaws/lib/dbaccess.py +++ b/docs/release/scripts/minimaws/lib/dbaccess.py @@ -587,13 +587,13 @@ class QueryCursor(object): if pattern is not None: return self.dbcurs.execute( 'SELECT shortname, description ' \ - 'FROM machine WHERE isdevice = 0 AND shortname GLOB ? ' \ + 'FROM machine WHERE shortname GLOB ? ' \ 'ORDER BY shortname ASC', (pattern, )) else: return self.dbcurs.execute( 'SELECT shortname, description ' \ - 'FROM machine WHERE isdevice = 0 ' \ + 'FROM machine ' \ 'ORDER BY shortname ASC') def listsource(self, pattern): @@ -601,14 +601,14 @@ class QueryCursor(object): return self.dbcurs.execute( 'SELECT machine.shortname, sourcefile.filename ' \ 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id ' \ - 'WHERE machine.isdevice = 0 AND machine.shortname GLOB ? ' \ + 'WHERE machine.shortname GLOB ? ' \ 'ORDER BY machine.shortname ASC', (pattern, )) else: return self.dbcurs.execute( 'SELECT machine.shortname, sourcefile.filename ' \ 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id ' \ - 'WHERE machine.isdevice = 0 ORDER BY machine.shortname ASC') + 'ORDER BY machine.shortname ASC') def listclones(self, pattern): if pattern is not None: @@ -668,7 +668,7 @@ class QueryCursor(object): def get_machine_details(self, machine): return self.dbcurs.execute( 'SELECT machine.id AS id, machine.description AS description, machine.isdevice AS isdevice, machine.runnable AS runnable, sourcefile.filename AS sourcefile, system.year AS year, system.manufacturer AS manufacturer, cloneof.parent AS cloneof, romof.parent AS romof ' \ - 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id LEFT JOIN system ON machine.id = system.id LEFT JOIN cloneof ON system.id = cloneof.id LEFT JOIN romof ON system.id = romof.id ' \ + 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id LEFT JOIN system ON machine.id = system.id LEFT JOIN cloneof ON machine.id = cloneof.id LEFT JOIN romof ON machine.id = romof.id ' \ 'WHERE machine.shortname = ?', (machine, )) @@ -707,7 +707,7 @@ class QueryCursor(object): def get_sourcefile_machines(self, id): return self.dbcurs.execute( 'SELECT machine.shortname AS shortname, machine.description AS description, machine.isdevice AS isdevice, machine.runnable AS runnable, sourcefile.filename AS sourcefile, system.year AS year, system.manufacturer AS manufacturer, cloneof.parent AS cloneof, romof.parent AS romof ' \ - 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id LEFT JOIN system ON machine.id = system.id LEFT JOIN cloneof ON system.id = cloneof.id LEFT JOIN romof ON system.id = romof.id ' \ + 'FROM machine JOIN sourcefile ON machine.sourcefile = sourcefile.id LEFT JOIN system ON machine.id = system.id LEFT JOIN cloneof ON machine.id = cloneof.id LEFT JOIN romof ON machine.id = romof.id ' \ 'WHERE machine.sourcefile = ?', (id, )) diff --git a/docs/release/scripts/minimaws/lib/htmltmpl.py b/docs/release/scripts/minimaws/lib/htmltmpl.py index 7c9246865b1..a80b4099787 100644 --- a/docs/release/scripts/minimaws/lib/htmltmpl.py +++ b/docs/release/scripts/minimaws/lib/htmltmpl.py @@ -50,7 +50,7 @@ MACHINE_PROLOGUE = string.Template( ' <tr><th>Source file:</th><td><a href="${sourcehref}">${sourcefile}</a></td></tr>\n') MACHINE_CLONES_PROLOGUE = string.Template( - '<h2>Clones</h2>\n' \ + '<h2 id="heading-clones">Clones</h2>\n' \ '<table id="tbl-clones">\n' \ ' <thead>\n' \ ' <tr>\n' \ @@ -104,6 +104,7 @@ MACHINE_SOFTWARELISTS_TABLE_EPILOGUE = string.Template( '</table>\n' \ '<script>\n' \ ' make_table_sortable(document.getElementById("tbl-softwarelists"));\n' \ + ' make_collapsible(document.getElementById("heading-softwarelists"), document.getElementById("tbl-softwarelists"));\n' \ ' if (!document.getElementById("tbl-softwarelists").tBodies[0].rows.length)\n' \ ' {\n' \ ' document.getElementById("heading-softwarelists").style.display = "none";\n' \ @@ -112,35 +113,40 @@ MACHINE_SOFTWARELISTS_TABLE_EPILOGUE = string.Template( '</script>\n') MACHINE_OPTIONS_HEADING = string.Template( - '<h2>Options</h2>\n' \ - '<p>\n' \ - ' Format: <select id="select-options-format" onchange="update_cmd_preview()"><option value="cmd">Command line</option><option value="ini">INI file</option></select>\n' \ - ' <input type="checkbox" id="check-explicit-defaults" onchange="update_cmd_preview()"><label for="check-explicit-defaults">Explicit defaults</label>\n' \ - '</p>\n' \ - '<p id="para-cmd-preview"></p>\n') + '<h2 id="heading-options">Options</h2>\n' \ + '<div id="div-options">\n' \ + ' <p>\n' \ + ' Format: <select id="select-options-format" onchange="update_cmd_preview()"><option value="cmd">Command line</option><option value="ini">INI file</option></select>\n' \ + ' <input type="checkbox" id="check-explicit-defaults" onchange="update_cmd_preview()"><label for="check-explicit-defaults">Explicit defaults</label>\n' \ + ' </p>\n' \ + ' <p id="para-cmd-preview"></p>\n') + +MACHINE_OPTIONS_EPILOGUE = string.Template( + '</div>\n' \ + '<script>make_collapsible(document.getElementById("heading-options"), document.getElementById("div-options"));</script>\n') MACHINE_BIOS_PROLOGUE = string.Template( - '<h3>System BIOS</h3>' \ - '<select id="select-system-bios" onchange="update_cmd_preview()">') + ' <h3>System BIOS</h3>' \ + ' <select id="select-system-bios" onchange="update_cmd_preview()">') MACHINE_BIOS_OPTION = string.Template( - ' <option value="${name}" data-isdefault="${isdefault}">${name} - ${description}</option>\n') + ' <option value="${name}" data-isdefault="${isdefault}">${name} - ${description}</option>\n') MACHINE_RAM_PROLOGUE = string.Template( - '<h3>RAM Size</h3>' \ - '<select id="select-ram-option" onchange="update_cmd_preview()">') + ' <h3>RAM Size</h3>\n' \ + ' <select id="select-ram-option" onchange="update_cmd_preview()">\n') MACHINE_RAM_OPTION = string.Template( - ' <option value="${name}" data-isdefault="${isdefault}">${name} (${size})</option>\n') + ' <option value="${name}" data-isdefault="${isdefault}">${name} (${size})</option>\n') MACHINE_SLOTS_PLACEHOLDER_PROLOGUE = string.Template( - '<h3>Slots</h3>\n' \ - '<p id="para-slots-placeholder">Loading slot information…<p>\n' \ - '<script>\n') + ' <h3>Slots</h3>\n' \ + ' <p id="para-slots-placeholder">Loading slot information…<p>\n' \ + ' <script>\n') MACHINE_SLOTS_PLACEHOLDER_EPILOGUE = string.Template( - ' populate_slots(${machine});\n' - '</script>\n') + ' populate_slots(${machine});\n' + ' </script>\n') MACHINE_ROW = string.Template( ' <tr>\n' \ @@ -253,7 +259,7 @@ SOFTWARE_PROLOGUE = string.Template( ' <tr><th>Publisher:</th><td>${publisher}</td></tr>\n'); SOFTWARE_CLONES_PROLOGUE = string.Template( - '<h2>Clones</h2>\n' \ + '<h2 id="heading-clones">Clones</h2>\n' \ '<table id="tbl-clones">\n' \ ' <thead>\n' \ ' <tr>\n' \ @@ -323,7 +329,7 @@ SOFTWARELIST_PROLOGUE = string.Template( '</table>\n') SOFTWARELIST_MACHINE_TABLE_HEADER = string.Template( - '<h2>Machines</h2>\n' \ + '<h2 id="heading-machines">Machines</h2>\n' \ '<table id="tbl-machines">\n' \ ' <thead>\n' \ ' <tr>\n' \ @@ -346,7 +352,7 @@ SOFTWARELIST_MACHINE_TABLE_ROW = string.Template( ' </tr>\n') SOFTWARELIST_SOFTWARE_TABLE_HEADER = string.Template( - '<h2>Software</h2>\n' \ + '<h2 id="heading-software">Software</h2>\n' \ '<table id="tbl-software">\n' \ ' <thead>\n' \ ' <tr>\n' \ diff --git a/docs/release/scripts/minimaws/lib/wsgiserve.py b/docs/release/scripts/minimaws/lib/wsgiserve.py index f1ddc5df220..43d5dbc1253 100644 --- a/docs/release/scripts/minimaws/lib/wsgiserve.py +++ b/docs/release/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')]) @@ -275,7 +280,7 @@ class MachineHandler(QueryPageHandler): (self.machine_href(machine_info['romof']), htmlescape(parent[1]), htmlescape(machine_info['romof']))).encode('utf-8') else: yield ( - ' <tr><th>Parent machine:</th><td><a href="%s">%s</a></td></tr>\n' % + ' <tr><th>Parent ROM set:</th><td><a href="%s">%s</a></td></tr>\n' % (self.machine_href(machine_info['romof']), htmlescape(machine_info['romof']))).encode('utf-8') unemulated = [] imperfect = [] @@ -309,6 +314,7 @@ class MachineHandler(QueryPageHandler): manufacturer=htmlescape(clonemanufacturer or '')).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-clones').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-clones"), document.getElementById("tbl-clones"));</script>\n'.encode('utf-8') # make a table of software lists yield htmltmpl.MACHINE_SOFTWARELISTS_TABLE_PROLOGUE.substitute().encode('utf-8') @@ -354,7 +360,7 @@ class MachineHandler(QueryPageHandler): size=htmlescape('{:,}'.format(size)), isdefault=('yes' if isdef else 'no')).encode('utf-8') if not first: - yield '</select>\n<script>set_default_ram_option();</script>\n'.encode('utf-8') + yield ' </select>\n <script>set_default_ram_option();</script>\n'.encode('utf-8') # placeholder for machine slots - populated by client-side JavaScript if self.dbcurs.count_slots(id): @@ -368,7 +374,7 @@ class MachineHandler(QueryPageHandler): while pending: requested = pending.pop() slots = self.slot_data(self.dbcurs.get_machine_id(requested)) - yield (' slot_info[%s] = %s;\n' % (self.sanitised_json(requested), self.sanitised_json(slots))).encode('utf-8') + yield (' slot_info[%s] = %s;\n' % (self.sanitised_json(requested), self.sanitised_json(slots))).encode('utf-8') for slotname, slot in slots['slots'].items(): for choice, card in slot.items(): carddev = card['device'] @@ -380,17 +386,21 @@ class MachineHandler(QueryPageHandler): cardid = self.dbcurs.get_machine_id(carddev) carddev = self.sanitised_json(carddev) yield ( - ' bios_sets[%s] = %s;\n machine_flags[%s] = %s;\n softwarelist_info[%s] = %s;\n' % + ' bios_sets[%s] = %s;\n machine_flags[%s] = %s;\n softwarelist_info[%s] = %s;\n' % (carddev, self.sanitised_json(self.bios_data(cardid)), carddev, self.sanitised_json(self.flags_data(cardid)), carddev, self.sanitised_json(self.softwarelist_data(cardid)))).encode('utf-8') yield htmltmpl.MACHINE_SLOTS_PLACEHOLDER_EPILOGUE.substitute( machine=self.sanitised_json(self.shortname)).encode('utf=8') + # add disclosure triangle for options if present + if haveoptions: + yield htmltmpl.MACHINE_OPTIONS_EPILOGUE.substitute().encode('utf=8') + # list devices referenced by this system/device first = True for name, desc, src in self.dbcurs.get_devices_referenced(id): if first: yield \ - '<h2>Devices Referenced</h2>\n' \ + '<h2 id="heading-dev-refs">Devices Referenced</h2>\n' \ '<table id="tbl-dev-refs">\n' \ ' <thead>\n' \ ' <tr><th>Short name</th><th>Description</th><th>Source file</th></tr>\n' \ @@ -400,13 +410,14 @@ class MachineHandler(QueryPageHandler): yield self.machine_row(name, desc, src) if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-dev-refs').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-dev-refs"), document.getElementById("tbl-dev-refs"));</script>\n'.encode('utf-8') # list slots where this device is an option first = True for name, desc, slot, opt, src in self.dbcurs.get_compatible_slots(id): if (first): yield \ - '<h2>Compatible Slots</h2>\n' \ + '<h2 id="heading-comp-slots">Compatible Slots</h2>\n' \ '<table id="tbl-comp-slots">\n' \ ' <thead>\n' \ ' <tr><th>Short name</th><th>Description</th><th>Slot</th><th>Choice</th><th>Source file</th></tr>\n' \ @@ -423,13 +434,14 @@ class MachineHandler(QueryPageHandler): slotoption=htmlescape(opt)).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-comp-slots').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-comp-slots"), document.getElementById("tbl-comp-slots"));</script>\n'.encode('utf-8') # list systems/devices that reference this device first = True for name, desc, src in self.dbcurs.get_device_references(id): if first: yield \ - '<h2>Referenced By</h2>\n' \ + '<h2 id="heading-ref-by">Referenced By</h2>\n' \ '<table id="tbl-ref-by">\n' \ ' <thead>\n' \ ' <tr><th>Short name</th><th>Description</th><th>Source file</th></tr>\n' \ @@ -439,6 +451,7 @@ class MachineHandler(QueryPageHandler): yield self.machine_row(name, desc, src) if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-ref-by').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-ref-by"), document.getElementById("tbl-ref-by"));</script>\n'.encode('utf-8') yield '</html>\n'.encode('utf-8') @@ -662,6 +675,7 @@ class SoftwareListHandler(QueryPageHandler): status=htmlescape(machine_info['status'])).encode('utf-8') if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-machines').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-machines"), document.getElementById("tbl-machines"));</script>\n'.encode('utf-8') first = True for software_info in self.dbcurs.get_softwarelist_software(softwarelist_info['id'], self.software or None): @@ -673,6 +687,7 @@ class SoftwareListHandler(QueryPageHandler): yield '<p>No software found.</p>\n'.encode('utf-8') else: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-software').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-software"), document.getElementById("tbl-software"));</script>\n'.encode('utf-8') yield '</body>\n</html>\n'.encode('utf-8') @@ -702,6 +717,7 @@ class SoftwareListHandler(QueryPageHandler): yield self.clone_row(clone_info) if not first: yield htmltmpl.SORTABLE_TABLE_EPILOGUE.substitute(id='tbl-clones').encode('utf-8') + yield '<script>make_collapsible(document.getElementById("heading-clones"), document.getElementById("tbl-clones"));</script>\n'.encode('utf-8') parts = self.dbcurs.get_software_parts(software_info['id']).fetchall() first = True |