<!-- Warning: Do not add an accronym by hand with the edit mode: There is a button add (+) at the right of the search entry in view page mode (not edit) --> <script type="text/javascript"> var array = `| ABM | Antenna Bus Master | | ACS | ALMA Common Software | | ACU | Antenna Control Unit | | BACI | Basic Access Control Interfae | | CDB | Configuration Data Base | | CORBA | Common Object Request Broker Architecture | | DDS | Data Distribution Services | | DEVIO | Device Input and Output | | IDL | Interface Definition Language | | IPC | Inter-Process Communication | | JDAL | Java Database Application Library | | MACI | Management and Control Interface | | ORB | Object Request Broker | | RPC | Remote Procedure Call | | TMCDB | Telescope Monitoring Configuration Data Base |` </script> <style> body { background: #fafafa; color: #444; font: 100%/30px 'Helvetica Neue', helvetica, arial, sans-serif; text-shadow: 0 1px 0 #fff; } strong { font-weight: bold; } em { font-style: italic; } input { font-size: 100%; padding: 8px; vertical-align: top; } textarea { padding: 7px; margin: 0px; font-size: 150%; resize: none; overflow: hidden; box-sizing: border-box; vertical-align: top; } button { vertical-align: top; } table { background: #f5f5f5; border-collapse: separate; box-shadow: inset 0 1px 0 #fff; /* font-size: 12px; */ line-height: 24px; text-align: left; width: 800px; } th { border-left: 1px solid #555; border-right: 1px solid #777; border-top: 1px solid #555; border-bottom: 1px solid #333; box-shadow: inset 0 1px 0 #999; font-weight: bold; padding: 10px 15px; position: relative; } th:after { content: ''; display: block; height: 25%; left: 0; margin: 1px 0 0 0; position: absolute; top: 25%; width: 100%; } th:first-child { border-left: 1px solid #777; box-shadow: inset 1px 1px 0 #999; } th:last-child { box-shadow: inset -1px 1px 0 #999; } td { border-right: 1px solid #fff; border-left: 1px solid #e8e8e8; border-top: 1px solid #fff; border-bottom: 1px solid #e8e8e8; padding: 10px 15px; position: relative; transition: all 300ms; } /* column 1 */ td:first-child { box-shadow: inset 1px 0 0 #fff; width: 15%; } /* column 1 */ td:last-child { border-right: 1px solid #e8e8e8; box-shadow: inset -1px 0 0 #fff; width: 80%; } tr { background: #e1e1e1; } tr:nth-child(odd) td { background: #f1f1f1; } tr:last-of-type td { box-shadow: inset 0 -1px 0 #fff; } tr:last-of-type td:first-child { box-shadow: inset 1px -1px 0 #fff; } tr:last-of-type td:last-child { box-shadow: inset -1px -1px 0 #fff; } </style> <!--------------------------------------------- START JAVASCRIPT ----------------------------------------------> <script type="text/javascript"> function filterAcronym(){ // Callback: when typing in input field // From: https://stackoverflow.com/questions/51187477/how-to-filter-a-html-table-using-simple-javascript var input, filter, table, tr, td, cell, i, j; // Get in input = document.getElementById("idFilter"); filter = input.value.trim().toUpperCase(); // Set URL search parameter const urlParams = new URLSearchParams(window.location.search); urlParams.set('search', filter.toLowerCase()); //urlParams.search = searchParam; window.history.pushState(null, null, '?' + urlParams.toString()); // Set input element <- search //input.value = searchParam; // Only display match table = document.getElementById("idTable"); tr = table.getElementsByTagName("tr"); var num = 0; for (i = 0; i < tr.length; i++) { // Hide the row initially. tr[i].style.display = "none"; // Get line td = tr[i].getElementsByTagName("td"); // Retrieve only first column (Acronym) cell = tr[i].getElementsByTagName("td")[0]; // Uppercase current acronym var current_upper = ""; if (cell){ current_upper = cell.textContent.toUpperCase(); } // Check if match var bol = Boolean(); // Display only match if (current_upper.startsWith(filter)) { tr[i].style.display = ""; num += 1; } } // Update Text document.getElementById("idNumber").innerHTML = num; } function createTable(){ // Called: at init // Focus on filter entry document.getElementById("idFilter").focus(); table = document.getElementById("idTable"); var arrayOfLines = array.split("\n"); var num = 0; // For each line arrayOfLines.forEach(function (item, index) { // Create a Row and 2 cells var row = document.createElement('tr'); // With '|' as separator (like Markdown) var a_cell = item.split('|') // Cell1 var cell1 = document.createElement('td'); bold = document.createElement('strong'); cell1.appendChild(bold); bold.appendChild(document.createTextNode(a_cell[1].trim())); row.appendChild(cell1); // Parse markdown description content var s_content2 = markdown(a_cell[2].trim()); // Cell2 var cell2 = document.createElement('td'); //cell2.appendChild(document.createTextNode(a_cell[2].trim())); cell2.innerHTML = s_content2; row.appendChild(cell2); // Add line to table table.appendChild(row); num += 1; }); // Update Text: number of acronym document.getElementById("idNumber").innerHTML = num; // Get query parameter const urlParams = new URLSearchParams(window.location.search); const searchParam = urlParams.get('search'); // Set input element <- search var input = document.getElementById("idFilter"); input.value = searchParam; filterAcronym(); } function getUrl(){ // Helper: Returns current page url for with Confluence API const site = 'https://confluence.alma.cl'; const pageid = AJS.params.pageId; // '72169314'; return site + "/rest/api/content/" + pageid; } function getPage(){ // Helper: Get Confluence page content as string const req = new XMLHttpRequest(); req.open("GET", getUrl() + '?expand=body.storage,version', false); // false -> synchronous req.send(); return JSON.parse(req.responseText); } function setPage(o_page){ // Helper: set Confluence page content from string const req = new XMLHttpRequest(); req.open("PUT", getUrl(), false); // false -> synchronous req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("Accept", "application/json; charset=utf-8"); req.send(JSON.stringify(o_page)); } // TODO put in thread function addAcronym(){ // Callback: at press "Fire" console.log('Button clicked') const r_array=/(var array = `)([^`]*)/; const b_is_in_confluence = (typeof AJS != 'undefined') // Get user entry var acronym = document.getElementById('idNewAcronym').value.trim(); let description = document.getElementById('idNewDescription').value.trim(); // Sanityze entry let s_err = '' s_err += acronym.length == 0 ? 'Cannot add an empty acronym\n' : ''; s_err += description.length == 0 ? 'Cannot add an empty description\n' : ''; s_err += (acronym + description).match('[|`]') ? 'Characters ` and | are note alowed\n' : ''; if (s_err.length != 0) { alert(s_err); return; } description = description.replaceAll('\\', '\\\\'); description = description.replace(/(?:\r\n|\r|\n)/g, '<br/>'); // Convert to upper case if (isLowerCase(acronym)){ acronym = acronym.toUpperCase(); } // Craft new data line const s_new_line = '| ' + acronym.toUpperCase() + ' | ' + description + ' |'; console.log('Adding acronym:' + acronym + ',' + description); // Pull current page let o_page = getPage() // Get array of lines <- Json const s_content = o_page.body.storage.value; let s_lines = s_content.match(r_array)[2]; let a_lines = s_lines.split('\n'); // Insert line at good index let i_new = 0 while ((i_new < a_lines.length) && a_lines[i_new].toUpperCase() < s_new_line.toUpperCase()){ i_new++; } a_lines.splice(i_new, 0, s_new_line); // Restore Json s_lines = a_lines.join('\n'); o_page.body.storage.value = s_content.replace(r_array, '\$1' + s_lines); o_page.version.number++; o_page.version.message = "Add: " + s_new_line; // Push setPage(o_page); console.log('Reloading'); window.location.reload(true); console.log('Click end'); } function toogleAdd() { // Callback: At press "+" // Toogle visibility of div let divAdd = document.getElementById('idRow2'); divAdd.style.display = divAdd.style.display == 'none' ? 'inline-block' : 'none'; // Set acronym accroding to the one in filter var input_new = document.getElementById('idNewAcronym'); if (!input_new.value.trim()){ const s_filter = document.getElementById('idFilter').value.trim(); input_new.value = s_filter; } } function toogleHelp() { // Callback: At press "?" let divAdd = document.getElementById('idRow3'); divAdd.style.display = divAdd.style.display == 'none' ? 'inline-block' : 'none'; } function markdown(src) { // Helper: convert Markdown -> Html // Inspired from: https://github.com/adamvleggett/drawdown/blob/master/drawdown.js var rx_lt = /</g; var rx_gt = />/g; var rx_space = /\t|\r|\uf8ff/g; var rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g; var rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g; var rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g; function replace(rex, fn) { src = src.replace(rex, fn); } function element(tag, content) { return '<' + tag + '>' + content + '</' + tag + '>'; } function highlight(src) { return src.replace(rx_highlight, function(all, _, p1, emp, sub, sup, small, big, p2, content) { return _ + element( emp ? (p2 ? 'strong' : 'em') : sub ? (p2 ? 's' : 'sub') : sup ? 'sup' : small ? 'small' : big ? 'big' : 'code', highlight(content)); }); } function unesc(str) { return str.replace(rx_escape, '$1'); } var stash = []; var si = 0; // Highlight src = highlight(src); // Link replace(rx_link, function(all, p1, p2, p3, p4, p5, p6) { return '<a href="' + p4 + '">' + unesc(highlight(p3)) + '</a>' }); return src.trim(); }; function isLowerCase(str) { // Helper: Check if string is lower case return str.toLowerCase() == str; } function auto_height(elem) { elem.style.height = "1px"; elem.style.height = (elem.scrollHeight)+"px"; } window.onload = createTable; </script> <div id="idDead" style="width:100%"> <div id=idRow1 style="width:100%;"> <input onkeyup="filterAcronym()" tabindex="1" style="display:inline-block" type="text" id="idFilter" placeholder="Search for acronyms (ignorecase)" title="Type in part of an acronym"> <div style="display: inline-block">Results: <span id="idNumber"></span></div> <input onclick="toogleAdd()" style="display: inline-block" type="button" id="idNew" value="➕" title="Add a new acronym to the dataset"> </div> <div id=idRow2 style="display:none; width:100%; vertical-align:top;"> <input onkeyup="" style="display:inline-block; width:15%" type="text" id="idNewAcronym" placeholder="ALMA" title="Type acronym initials"> <textarea style="display:inline-block; width:60%;" rows="1" oninput="auto_height(this)" type="text" id="idNewDescription" placeholder="Atacama Large Milimeter Array" title="Type acronym description"></textarea> <input onclick="addAcronym()" style="display:inline-block; width:15%;" type="button" id="idNewAdd" value="Add now" title="Add a new acronym to the dataset"> <input onclick="toogleHelp()" style="display: inline-block" type="button" id="idToogleHelp" value="❓" title="Help"> <div id=idRow3 style="display:none; width:100%; color:#888;"> <b>Add an acronym!</b><br/> <b>1/ Acronym</b>: will be converted to uppercase<br> <b>2/ Description</b>: support some markdown plus any html syntax <ul style="margin:0;"> <li><b>Newline</b>: press enter, don't be shy, newlines will be converted to <br/></li> <li><b>Link</b>: [link](http://example.com)</li> <li><b>Typeface</b>: **bold**, *italic*, ***both***, ~~strikethrough~~, `monospace`, --subscript--, and ^^superscript^^</li> <li><b>Html</b>: beware badly formed html that can break the page (ex: unclosed tag) </div> </div> </div> <table id="idTable" style="width:100%;"> <!-- <tr class="header"> <th style="width:10%;">Acronym</th> <th style="width:80%;">Meaning</th> </tr> --> </table> |