github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/cmd/deck/static/plugins-script.js (about) 1 "use strict"; 2 3 function getParameterByName(name) { // http://stackoverflow.com/a/5158301/3694 4 const match = new RegExp('[?&]' + name + '=([^&/]*)').exec(window.location.search); 5 return match && decodeURIComponent(match[1].replace(/\+/g, ' ')); 6 } 7 8 function redrawOptions() { 9 const rs = allHelp.AllRepos.sort(); 10 const sel = document.getElementById("repo"); 11 while (sel.length > 1) { 12 sel.removeChild(sel.lastChild); 13 } 14 const param = getParameterByName("repo"); 15 rs.forEach((opt) => { 16 const o = document.createElement("option"); 17 o.text = opt; 18 o.selected = (param && opt === param); 19 sel.appendChild(o); 20 }); 21 } 22 23 window.onload = function () { 24 // set dropdown based on options from query string 25 redrawOptions(); 26 redraw(); 27 // Register dialog 28 const dialog = document.querySelector('dialog'); 29 dialogPolyfill.registerDialog(dialog); 30 dialog.querySelector('.close').addEventListener('click', () => { 31 dialog.close(); 32 }); 33 }; 34 35 document.addEventListener("DOMContentLoaded", () => { 36 configure(); 37 }); 38 39 function configure() { 40 if (!branding) { 41 return; 42 } 43 if (branding.logo) { 44 document.getElementById('img').src = branding.logo; 45 } 46 if (branding.favicon) { 47 document.getElementById('favicon').href = branding.favicon; 48 } 49 if (branding.background_color) { 50 document.body.style.background = branding.background_color; 51 } 52 if (branding.header_color) { 53 document.getElementsByTagName('header')[0].style.backgroundColor = branding.header_color; 54 } 55 } 56 57 function selectionText(sel) { 58 return sel.selectedIndex === 0 ? "" : sel.options[sel.selectedIndex].text; 59 } 60 61 /** 62 * Returns a section to the content of the dialog 63 * @param title title of the section 64 * @param body body of the section 65 * @return {Element} 66 */ 67 function addDialogSection(title, body) { 68 const container = document.createElement("DIV"); 69 const sectionTitle = document.createElement("H5"); 70 const sectionBody = document.createElement("DIV"); 71 72 sectionBody.classList.add("dialog-section-body"); 73 if (Array.isArray(body)) { 74 body.forEach(el => { 75 sectionBody.appendChild(el); 76 }); 77 } else { 78 sectionBody.innerHTML = body; 79 } 80 81 sectionTitle.classList.add("dialog-section-title"); 82 sectionTitle.innerHTML = title; 83 84 container.classList.add("dialog-section"); 85 container.appendChild(sectionTitle); 86 container.appendChild(sectionBody); 87 88 return container; 89 } 90 91 /** 92 * Return a list of link elements that links to commands. 93 * @param commands list of commands 94 * @return {Array} 95 */ 96 function getLinkableCommands(commands) { 97 const result = []; 98 commands.forEach(command => { 99 const commandName = extractCommandName(command.Examples[0]); 100 const link = document.createElement("A"); 101 link.href = "/command-help#" + commandName; 102 link.innerHTML = command.Examples[0]; 103 link.classList.add("plugin-help-command-link"); 104 result.push(link); 105 }); 106 return result; 107 } 108 109 /** 110 * Create a card for a plugin. 111 * @param {string} repo repo name 112 * @param {string} name name of the plugin 113 * @param {Object} pluginObj plugin object 114 * @return {Element} the card element that contains the plugin 115 */ 116 function createPlugin(repo, name, pluginObj) { 117 const isExternal = pluginObj.isExternal; 118 const plugin = pluginObj.plugin; 119 120 const title = document.createElement("H3"); 121 title.innerHTML = name; 122 title.classList.add("mdl-card__title-text"); 123 const supportTitle = document.createElement("DIV"); 124 supportTitle.innerHTML = isExternal ? " external plugin" : ""; 125 supportTitle.classList.add("mdl-card__subtitle-text"); 126 const cardTitle = document.createElement("DIV"); 127 cardTitle.classList.add("mdl-card__title"); 128 cardTitle.appendChild(title); 129 cardTitle.appendChild(supportTitle); 130 131 const cardDesc = document.createElement("DIV"); 132 cardDesc.innerHTML = getFirstSentence(plugin.Description); 133 cardDesc.classList.add("mdl-card__supporting-text"); 134 135 const cardAction = document.createElement("DIV"); 136 const actionButton = document.createElement("A"); 137 actionButton.innerHTML = "Details"; 138 actionButton.classList.add(...["mdl-button", "mdl-button--colored", "mdl-js-button", "mdl-js-ripple-effect"]); 139 actionButton.addEventListener("click", () => { 140 const dialog = document.querySelector("dialog"); 141 const title = dialog.querySelector(".mdl-dialog__title"); 142 const content = dialog.querySelector(".mdl-dialog__content"); 143 144 while (content.firstChild) { 145 content.removeChild(content.firstChild); 146 } 147 148 title.innerHTML = name; 149 if (plugin.Description) { 150 content.appendChild(addDialogSection("Description", plugin.Description)); 151 } 152 if (plugin.Events) { 153 const sectionContent = "[" + plugin.Events.sort().join(", ") + "]"; 154 content.appendChild(addDialogSection("Events handled", sectionContent)); 155 } 156 if (plugin.Config) { 157 let sectionContent = plugin.Config ? plugin.Config[repo] : ""; 158 let sectionTitle = 159 repo === "" ? "Configuration(global)" : "Configuration(" + repo + ")"; 160 if (sectionContent && sectionContent !== "") { 161 content.appendChild(addDialogSection(sectionTitle, sectionContent)); 162 } 163 } 164 if (plugin.Commands) { 165 let sectionContent = getLinkableCommands(plugin.Commands); 166 content.appendChild(addDialogSection("Commands", sectionContent)); 167 } 168 dialog.showModal(); 169 }); 170 cardAction.appendChild(actionButton); 171 cardAction.classList.add(...["mdl-card__actions", "mdl-card--border"]); 172 173 const card = document.createElement("DIV"); 174 card.appendChild(cardTitle); 175 card.appendChild(cardDesc); 176 card.appendChild(cardAction); 177 178 card.classList.add(...["plugin-help-card", "mdl-card", "mdl-shadow--2dp"]); 179 if (isDeprecated(plugin.Description)) { 180 card.classList.add("deprecated"); 181 } 182 return card; 183 } 184 185 /** 186 * Takes an org/repo string and a repo to plugin map and returns the plugins 187 * that apply to the repo. 188 * @param {string} repoSel repo name 189 * @param {Map<string, PluginHelp>} repoPlugins maps plugin name to plugin 190 * @return {Array<string>} 191 */ 192 function applicablePlugins(repoSel, repoPlugins) { 193 if (repoSel === "") { 194 const all = repoPlugins[""]; 195 if (all) { 196 return all.sort(); 197 } 198 return []; 199 } 200 const parts = repoSel.split("/"); 201 const byOrg = repoPlugins[parts[0]]; 202 let plugins = []; 203 if (byOrg && byOrg !== []) { 204 plugins = plugins.concat(byOrg); 205 } 206 const pluginNames = repoPlugins[repoSel]; 207 if (pluginNames) { 208 pluginNames.forEach((pluginName) => { 209 if (!plugins.includes(pluginName)) { 210 plugins.push(pluginName); 211 } 212 }); 213 } 214 return plugins.sort(); 215 } 216 217 /** 218 * Redraw plugin cards. 219 * @param {string} repo repo name. 220 * @param {Map<string, Object>} helpMap maps a plugin name to a plugin. 221 */ 222 function redrawPlugin(repo, helpMap) { 223 const container = document.querySelector("#plugin-container"); 224 while (container.childElementCount !== 0) { 225 container.removeChild(container.firstChild); 226 } 227 const names = helpMap.keys(); 228 const nameArray = Array.from(names).sort(); 229 nameArray.forEach(name => { 230 container.appendChild(createPlugin(repo, name, helpMap.get(name))) 231 }); 232 } 233 234 /** 235 * Redraws the content of the page. 236 */ 237 function redraw() { 238 const repoSel = selectionText(document.getElementById("repo")); 239 if (window.history && window.history.replaceState !== undefined) { 240 if (repoSel !== "") { 241 history.replaceState(null, "", "/plugins?repo=" 242 + encodeURIComponent(repoSel)); 243 } else { 244 history.replaceState(null, "", "/plugins") 245 } 246 } 247 redrawOptions(); 248 249 const plugins = new Map(); 250 applicablePlugins(repoSel, allHelp.RepoPlugins) 251 .forEach((name) => { 252 if (allHelp.PluginHelp[name]) { 253 plugins.set( 254 name, 255 { 256 isExternal: false, 257 plugin: allHelp.PluginHelp[name] 258 }); 259 } 260 }); 261 applicablePlugins(repoSel, allHelp.RepoExternalPlugins) 262 .forEach((name) => { 263 if (allHelp.ExternalPluginHelp[name]) { 264 plugins.set( 265 name, 266 { 267 isExternal: true, 268 plugin: allHelp.ExternalPluginHelp[name] 269 }); 270 } 271 }); 272 redrawPlugin(repoSel, plugins); 273 } 274 275 /** 276 * Returns first sentence from plugin's example. 277 * @param {string} text 278 * @return {string} 279 */ 280 function getFirstSentence(text) { 281 const fullStop = text.indexOf("."); 282 return fullStop === -1 ? text : text.slice(0, fullStop + 1); 283 } 284 285 /** 286 * Returns true if the plugin is deprecated. 287 * @param {string} text 288 * @return {boolean} 289 */ 290 function isDeprecated(text) { 291 const dictionary = ["deprecated!"]; 292 text = text.toLowerCase(); 293 for (let i = 0; i < dictionary.length; i++) { 294 if (text.indexOf(dictionary[i]) !== -1) { 295 return true; 296 } 297 } 298 return false; 299 } 300 301 /** 302 * Extracts a command name from a command example. It takes the first example, 303 * with out the slash, as the name for the command. Also, any '-' character is 304 * replaced by '_' to make the name valid in the address. 305 * @param {string} commandExample 306 * @return {string} 307 */ 308 function extractCommandName(commandExample) { 309 const command = commandExample.split(" "); 310 if (!command || command.length === 0) { 311 throw new Error("Cannot extract command name."); 312 } 313 return command[0].slice(1).split("-").join("_"); 314 }