// ==UserScript== // @name App Inventor 2 block helper // @version 0.7.7 // @namespace App Inventer 2 block helper // @description An easy way to operate blocks at MIT App Inventor 2. // @author wangsk789@163.com // @match https://*.appinventor.mit.edu/* // @match http://localhost/* // @match http://192.168.*.* // @license MIT // @downloadURL https://update.greasyfork.org/scripts/463114/App%20Inventer%202%20block%20helper.user.js // @updateURL https://update.greasyfork.org/scripts/463114/App%20Inventer%202%20block%20helper.meta.js // ==/UserScript== (function() { //'use strict'; setTimeout(() => { var lastBlock; var types = ["component_event", "global_declaration", "procedures_defreturn", "procedures_defnoreturn"]; function genHelperPalette() { var box = document.createElement('div'); document.querySelector(".ode-WorkColumns").appendChild(box); box.outerHTML = ''; } var isHelperOpen = false; function switchHelper() { var helper = document.querySelector("#helperPalette"); if (helper.style.display == "none") { helper.style.display = "block" updateoutline(); isHelperOpen = true; } else { helper.style.display = "none" isHelperOpen = false; } } // AƱadir estilo CSS global var style = document.createElement('style'); style.innerHTML = ` #helperOutline { display: block; white-space: nowrap; overflow-y: scroll; overflow-x: hidden; /* Desactiva el desplazamiento horizontal */ } #highlightedBlocks { display: block; white-space: nowrap; overflow-y: scroll; overflow-x: hidden; /* Desactiva el desplazamiento horizontal */ border-top: 1px solid #ccc; margin-top: 10px; } .gwt-TreeItem { display: flex; align-items: center; width: 100%; } .boldButton { margin-right: 5px; cursor: pointer; background-color: #ddd; border: 1px solid #ccc; padding: 2px; } `; document.head.appendChild(style); function updateoutline() { let blocks = Blockly.getMainWorkspace().getTopBlocks().filter((block) => types.indexOf(block.type) > -1); blocks.sort((a, b) => a.toString().localeCompare(b.toString())); var helperOutline = document.querySelector("#helperOutline"); var highlightedBlocks = document.querySelector("#highlightedBlocks"); helperOutline.innerHTML = ""; highlightedBlocks.innerHTML = ""; blocks.forEach((block) => { let div = document.createElement('DIV'); div.className = "gwt-TreeItem"; div.style.whiteSpace = "nowrap"; div.style.padding = "3px"; div.style.overflow = "hidden"; div.id = "id" + block.id; let boldButton = document.createElement('div'); boldButton.className = "boldButton"; boldButton.textContent = "B"; boldButton.addEventListener("click", (e) => { e.stopPropagation(); if (div.style.fontWeight === "bold") { div.style.fontWeight = "normal"; removeBlockFromHelper(block); } else { div.style.fontWeight = "bold"; moveBlockToHelper(block); } }); div.appendChild(boldButton); let textDiv = document.createElement('div'); textDiv.textContent = simpleString(block); div.appendChild(textDiv); div.addEventListener("click", () => { btnonclick(div); }); if (div.style.fontWeight === "bold") { highlightedBlocks.appendChild(div); } else { helperOutline.appendChild(div); } }); } function btnonclick(obj) { if (lastBlock) { lastBlock.setHighlighted(false); } var block = Blockly.getMainWorkspace().getBlockById(obj.id.substr(2)); if (block == lastBlock) { lastBlock = null; } else { Blockly.getMainWorkspace().centerOnBlock(block.id); block.select(); block.setHighlighted(true); lastBlock = block; } } function simpleString(block) { var text = ''; for (var i = 0, input; (input = block.inputList[i]); i++) { if (input.name == Blockly.BlockSvg.COLLAPSED_INPUT_NAME) { continue; } for (var j = 0, field; (field = input.fieldRow[j]); j++) { text += field.getText() + ' '; } } text = goog.string.trim(text) || '???'; return text; } function removeallcomments() { if (confirm("Are you sure to remove all comments?")) { Blockly.getMainWorkspace().getAllBlocks().forEach(b => { b.setCommentText(null) }); } } function searchkeyword() { var input = document.querySelector("#keyword"); if (input.value) { findBlock(input.value); } } var lastIndex = -1; function findBlock(keyword) { var blocks = Blockly.getMainWorkspace().getAllBlocks().filter(block => simpleString(block).toLowerCase().includes(keyword.toLowerCase())); if (lastIndex > -1) { blocks[lastIndex].setHighlighted(false); } lastIndex++; if (lastIndex < blocks.length) { expand(blocks[lastIndex]); Blockly.getMainWorkspace().cleanUp(); Blockly.getMainWorkspace().centerOnBlock(blocks[lastIndex].id); blocks[lastIndex].select(); blocks[lastIndex].setHighlighted(true); } else { lastIndex = -1; } } function expand(block) { block.setCollapsed(false); let parent = block.getParent(); if (parent) { expand(parent); } } function downloadPNGIgnoreOrphan() { var topblocks = Blockly.getMainWorkspace().getTopBlocks(); var blocks = topblocks.filter((block) => { return types.indexOf(block.type) >= 0 }); if (confirm("Are you sure to download all " + blocks.length + " blocks?")) { var i = 0; var timer = setTimeout(function() { if (i < blocks.length) { exportBlockAsPng(blocks[i]); i++; timer = setTimeout(arguments.callee, 1000) } }, 1000); } } function genHelperButton() { let btnHelper = document.createElement('div'); var container = document.querySelectorAll(".center")[1]; container.appendChild(btnHelper); btnHelper.outerHTML = '
AI2HELPER
'; } genHelperButton(); genHelperPalette(); document.querySelector("#removeallcomments").addEventListener("click", () => { removeallcomments(); }); document.querySelector("#helperButton").addEventListener("click", () => { switchHelper(); }); document.querySelector("#searchkeyword").addEventListener("click", () => { searchkeyword(); }); document.querySelector("#downloadPNGIgnoreOrphan").addEventListener("click", () => { downloadPNGIgnoreOrphan(); }); document.querySelector("#updateoutline").addEventListener("click", () => { updateoutline(); }); document.querySelectorAll(".right")[1].childNodes[0].addEventListener("click", () => { var helper = document.querySelector("#helperPalette"); helper.style.display = "none"; }); document.querySelectorAll(".right")[1].childNodes[1].addEventListener("click", () => { if (isHelperOpen) { var helper = document.querySelector("#helperPalette"); helper.style.display = "block"; updateoutline(); } }); function moveBlockToHelper(block) { var highlightedBlocks = document.querySelector("#highlightedBlocks"); var div = document.createElement('div'); div.className = "gwt-TreeItem"; div.style.whiteSpace = "nowrap"; div.style.padding = "3px"; div.style.overflow = "hidden"; div.id = "id" + block.id; let boldButton = document.createElement('div'); boldButton.className = "boldButton"; boldButton.textContent = "B"; boldButton.addEventListener("click", (e) => { e.stopPropagation(); div.parentNode.removeChild(div); // Remove from helper when B is clicked again block.setHighlighted(false); // Unhighlight the block div.style.fontWeight = "normal"; }); div.appendChild(boldButton); let textDiv = document.createElement('div'); textDiv.textContent = simpleString(block); div.appendChild(textDiv); div.addEventListener("click", () => { btnonclick(div); }); highlightedBlocks.appendChild(div); block.select(); block.setHighlighted(true); } function removeBlockFromHelper(block) { var div = document.querySelector("#highlightedBlocks #id" + block.id); if (div) { div.parentNode.removeChild(div); } block.setHighlighted(false); } }, 10000); })();