From 4aefe4100e26d2dec634a458b5a84bc7e645f4c5 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:19:11 -0400 Subject: [PATCH 01/26] create 'htmldocuments.js' --- static/extensions/ScrTwPm/htmldocuments.js | 1083 ++++++++++++++++++++ 1 file changed, 1083 insertions(+) create mode 100644 static/extensions/ScrTwPm/htmldocuments.js diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js new file mode 100644 index 000000000..0454f3642 --- /dev/null +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -0,0 +1,1083 @@ +(function(Scratch) { + 'use strict'; + + if (Scratch.gui) { + Scratch.gui.getBlockly().then(ScratchBlocks => { + ScratchBlocks.BlockSvg.registerCustomNotch("htmldocuments-coolshape", + "c 2 0 3 1 4 2 l 4 4 c 1 1 4 -7 4 2 h 3 c 1 -1 2 -2 3 -3 c 1 1 2 2 3 3 l 3 0 c 0 -9 3 -1 4 -2 l 4 -4 c 1 -1 2 -2 4 -2" + ) + ScratchBlocks.BlockSvg.registerCustomNotch("htmldocuments-coolshape2", + "c 0 2 0 8 4 8 c 6 0 10 -7 14 -5 c 4 -2 8 5 14 5 c 4 0 4 -6 4 -8" + ) + }); +} + + + class HTMLtoCanvas { + constructor(runtime) { + // Initialize an array holding your default dropdown menu options + this.pages = {} + this.changePx = [ + "block-size", + "border-block-end-width", + "border-block-start-width", + "border-block-width", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-width", + "border-image-outset", + "border-image-width", + "border-inline-end-width", + "border-inline-start-width", + "border-inline-width", + "border-left-width", + "border-right-width", + "border-spacing", + "border-top-left-radius", + "border-top-right-radius", + "border-top-width", + "border-width", + "bottom", + "column-gap", + "column-rule-width", + "column-width", + "contain-intrinsic-block-size", + "contain-intrinsic-height", + "contain-intrinsic-inline-size", + "contain-intrinsic-size", + "contain-intrinsic-width", + "cx", + "cy", + "font-size", + "gap", + "grid-auto-columns", + "grid-auto-rows", + "grid-template-columns", + "grid-template-rows", + "height", + "inline-size", + "left", + "letter-spacing", + "margin-block-end", + "margin-block-start", + "margin-block", + "margin-bottom", + "margin-inline-end", + "margin-inline-start", + "margin-inline", + "margin-left", + "margin-right", + "margin-top", + "max-block-size", + "max-height", + "max-inline-size", + "max-width", + "min-block-size", + "min-height", + "min-inline-size", + "min-width", + "object-position", + "offset-distance", + "offset-path", + "outline-offset", + "outline-width", + "padding-block-end", + "padding-block-start", + "padding-block", + "padding-bottom", + "padding-inline-end", + "padding-inline-start", + "padding-inline", + "padding-left", + "padding-right", + "padding-top", + "perspective", + "perspective-origin", + "r", + "right", + "row-gap", + "rx", + "ry", + "scroll-margin-bottom", + "scroll-margin-left", + "scroll-margin-right", + "scroll-margin-top", + "scroll-padding-bottom", + "scroll-padding-left", + "scroll-padding-right", + "scroll-padding-top", + "shape-margin", + "tab-size", + "text-decoration-thickness", + "text-indent", + "top", + "transform-origin", + "translate", + "width", + "word-spacing", + "x", + "y" + ] + this.viewing = "" + this.runtime = runtime + } + getInfo() { + return { + id: 'htmldocuments', + name: 'HTML documents', + color1: '#ff9900', + blocks: [ + + { + opcode: 'createPage', + blockType: Scratch.BlockType.COMMAND, + text: 'create new page named [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'deletePage', + blockType: Scratch.BlockType.COMMAND, + text: 'delete page named [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'clearPage', + blockType: Scratch.BlockType.COMMAND, + text: 'clear content of [PAGE]', + // notchAccepts: "htmldocuments-coolshape", + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'allPages', + blockType: Scratch.BlockType.REPORTER, + text: 'all pages', + disableMonitor: true, + }, + { + opcode: 'getHTML', + blockType: Scratch.BlockType.REPORTER, + text: 'get html code of [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + // { + // opcode: 'get', + // blockType: Scratch.BlockType.REPORTER, + // text: 'get', + // }, + { blockType: Scratch.BlockType.LABEL, text: "Render HTML" }, + { + opcode: 'displayPage', + blockType: Scratch.BlockType.COMMAND, + text: 'display page [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'hidePage', + blockType: Scratch.BlockType.COMMAND, + text: 'hide page', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'current', + blockType: Scratch.BlockType.REPORTER, + text: 'current page displayed', + disableMonitor: true + }, + { blockType: Scratch.BlockType.LABEL, text: "Element Management" }, + { + opcode: 'nestEl', + blockType: Scratch.BlockType.CONDITIONAL, + text: 'add [EL] id [ID] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + EL: { + type: Scratch.ArgumentType.STRING, + menu: "nest", + defaultValue: "div" + } + } + }, + { + opcode: 'noNestEl', + blockType: Scratch.BlockType.COMMAND, + text: 'add [EL] id [ID] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + EL: { + type: Scratch.ArgumentType.STRING, + menu: "nonest", + defaultValue: "input" + }, + } + }, + { + opcode: 'text', + blockType: Scratch.BlockType.COMMAND, + text: 'add text [TEXT] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello World!" + }, + } + }, + { + opcode: 'removeEl', + blockType: Scratch.BlockType.COMMAND, + text: 'remove element with id [ID] from [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + } + }, + { + opcode: 'setAttr', + blockType: Scratch.BlockType.COMMAND, + text: 'set [ATTR] of [ID] to [VAL] in [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + VAL: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-class" + }, + ATTR: { + type: Scratch.ArgumentType.STRING, + defaultValue: "class", + menu:"attr" + }, + } + + }, + + { blockType: Scratch.BlockType.LABEL, text: "CSS Styles" }, + + // { + // opcode: 'styleEl', + // blockType: Scratch.BlockType.CONDITIONAL, + // text: 'add style to [PAGE]', + // branchCount: 1, + // // notchAccepts: "htmldocuments-coolshape", + // branches: [ + // { accepts: "htmldocuments-coolshape2" }, + // ], + // arguments: { + // PAGE: { + // type: Scratch.ArgumentType.STRING, + // defaultValue: "my-page" + // }, + // } + // }, + { + opcode: 'property', + blockType: Scratch.BlockType.COMMAND, + text: 'set [PROPERTY] for [TYPE] [NAME] to [VALUE] in [PAGE]', + // notchAccepts: "htmldocuments-coolshape2", + arguments: { + PROPERTY: { + type: Scratch.ArgumentType.STRING, + menu: "properties", + defaultValue: "color" + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "types" + }, + NAME: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "green", + }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page", + }, + } + }, + + { + opcode: 'remallstyle', + blockType: Scratch.BlockType.COMMAND, + text: 'clear styling of [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + + { blockType: Scratch.BlockType.LABEL, text: "Event Listeners" }, + + + { + opcode: 'eve', + blockType: Scratch.BlockType.HAT, + text: 'When listener for [ID] activated in [PAGE]', + isEdgeActivated: false, + arguments: { + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el", + // defaultValue: '{"Hello":"Item 1", "Bye":"Item 2"}' + }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + { + opcode: 'addeve', + blockType: Scratch.BlockType.COMMAND, + text: 'add event listener [EVE] for [ID] in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + { + opcode: 'remeve', + blockType: Scratch.BlockType.COMMAND, + text: 'remove event listeners from [ID] in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + + { blockType: Scratch.BlockType.LABEL, text: "Webpage Positioning" }, + + { + opcode: 'movePage', + blockType: Scratch.BlockType.COMMAND, + text: 'move [PAGE] to x: [X] y: [Y]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "50" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "50" + }, + } + }, + { + opcode: 'resizePage', + blockType: Scratch.BlockType.COMMAND, + text: 'resize [PAGE] to x: [X] y: [Y]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "300" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "200" + }, + } + }, + { + opcode: 'resetDefault', + blockType: Scratch.BlockType.COMMAND, + text: 'set [PAGE] display settings to stage size', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "300" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "200" + }, + } + }, + { + opcode: 'pagePos', + blockType: Scratch.BlockType.REPORTER, + text: '[AXIS] of [PAGE]', + disableMonitor: true, + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + AXIS: { + type: Scratch.ArgumentType.STRING, + menu: "axis" + }, + } + }, + { + opcode: 'spw', + blockType: Scratch.BlockType.REPORTER, + text: '[WH] of the stage', + disableMonitor: true, + arguments: { + WH: { + type: Scratch.ArgumentType.STRING, + menu: "wh" + }, + } + }, + + ], + menus: { + nonest: { + acceptReporters: true, + items: + [ + "area","base","br","col","embed","hr","img","input","link","meta","script","source","textarea","track","wbr" + ] + }, + nest: { + acceptReporters: true, + items: + [ + "a", "abbr", "address", "article", "aside", "audio", "b", "bdi", "bdo", "blockquote", "button", "canvas", "caption", "cite", "code", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "i", "iframe", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "menu", "meter", "nav", "object", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "slot", "small", "span", "strong", "sub", "summary", "sup", "table", "tbody", "td", "template", "tfoot", "th", "thead", "time", "tr", "u", "ul", "var", "video" + ] + }, + types: { + acceptReporters: false, + items: [ + {text: "id", value: "#"}, + {text: "class", value: "."}, + // {text: "animation", value: "@keyframes "}, + ] + }, + properties: { + acceptReporters: true, + items:[ + + 'align-content','align-items','align-self','all','animation','animation-delay','animation-direction','animation-duration','animation-fill-mode','animation-iter-count','animation-name','animation-play-state','animation-timing-fn','backface-visibility','background','background-attachment','background-blend-mode','background-clip','background-color','background-image','background-origin','background-position','background-repeat','background-size','border','border-bottom','border-bottom-color','border-bottom-left-rad','border-bottom-right-ra','border-bottom-style','border-bottom-width','border-collapse','border-color','border-image','border-image-outset','border-image-repeat','border-image-slice','border-image-source','border-image-width','border-left','border-left-color','border-left-style','border-left-width','border-radius','border-right','border-right-color','border-right-style','border-right-width','border-spacing','border-style','border-top','border-top-color','border-top-left-radius','border-top-right-radius','border-top-style','border-top-width','border-width','bottom','box-decoration-break','box-shadow','box-sizing','caption-side','caret-color', + 'clear','clip','clip-path','color','column-count','column-fill','column-gap','column-rule','column-rule-color','column-rule-style','column-rule-width','column-span','column-width','columns','content','counter-increment','counter-reset','cursor','direction','display','empty-cells','filter','flex','flex-basis','flex-direction','flex-flow','flex-grow','flex-shrink','flex-wrap','float','font', + 'font-family','font-kerning','font-size','font-stretch','font-style','font-variant','font-weight','gap','grid','grid-area','grid-auto-columns','grid-auto-flow','grid-auto-rows','grid-column','grid-column-end','grid-column-gap','grid-column-start','grid-gap','grid-row','grid-row-end','grid-row-gap','grid-row-start','grid-template','grid-template-areas','grid-template-columns','grid-template-rows','height','hyphens', + 'justify-content', + 'left','letter-spacing','line-height','list-style','list-style-image','list-style-position','list-style-type','margin','margin-bottom','margin-left','margin-right','margin-top','max-height','max-width', + 'min-height','min-width','object-fit','object-position','opacity','order','outline','outline-color','outline-offset','outline-style','outline-width','overflow','overflow-x','overflow-y','padding','padding-bottom','padding-left','padding-right','padding-top','page-break-after','page-break-before','page-break-inside','perspective','perspective-origin','pointer-events','position','quotes','right','row-gap','scroll-behavior','table-layout','text-align','text-align-last','text-decoration','text-decoration-color','text-decoration-line','text-decoration-style','text-indent','text-justify','text-overflow','text-shadow','text-transform','top','transform','transform-origin','transform-style','transition','transition-delay','transition-duration','transition-property','transition-timing-fn','user-select','vertical-align','visibility','white-space','width','word-break','word-spacing','word-wrap','writing-mode','z-index' + + ] + }, + axis: { + acceptReporters: false, + items: [ + {text:"x position", value: "x"}, {text:"y position", value: "y"}, "width","height" + ] + }, + wh: { + acceptReporters: false, + items: [ + "width","height" + ] + }, + eves: { + acceptReporters: true, + items: [ + // Mouse & Pointer + "click", "dblclick", "mousedown", "mouseup", "mouseenter", + "mouseleave", "mousemove", "mouseover", "mouseout", "contextmenu", "wheel", + + // Keyboard + "keydown", "keyup", "keypress", + + // Form & Input + "submit", "input", "change", "focus", "blur", "reset", "invalid", + + // Window & Document + "load", "DOMContentLoaded", "beforeunload", "unload", "resize", + "scroll", "error", "visibilitychange", + + // Drag & Drop + "dragstart", "drag", "dragenter", "dragover", "dragleave", "drop", "dragend", + + // Mobile & Media + "touchstart", "touchmove", "touchend", "play" + ] + }, + attr: { + acceptReporters: false, + items: [ + "accesskey", "autocapitalize", "autofocus", "class", "contenteditable", + "dir", "draggable", "enterkeyhint", "hidden", "inert", "inputmode", + "lang", "nonce", "part", "popover", "role", "slot", "style", "tabindex", + "title", "translate", "virtualkeyboardpolicy", + "accept", "accept-charset", "action", "align", "allow", "alt", "as", + "async", "autocomplete", "autoplay", "background", "bgcolor", "border", + "capture", "charset", "checked", "cite", "color", "cols", "colspan", + "content", "controls", "coords", "crossorigin", "csp", "data", "datetime", + "decoding", "default", "defer", "disabled", "download", "enctype", "for", + "form", "formaction", "formenctype", "formmethod", "formnovalidate", + "formtarget", "headers", "height", "high", "href", "hreflang", "http-equiv", + "imagesizes", "imagesrcset", "integrity", "ismap", "kind", "label", "list", + "loading", "loop", "low", "max", "maxlength", "min", "minlength", "media", + "method", "multiple", "muted", "name", "novalidate", "open", "optimum", + "pattern", "ping", "placeholder", "playsinline", "poster", "preload", + "readonly", "referrerpolicy", "rel", "required", "reversed", "rows", + "rowspan", "sandbox", "scope", "selected", "shape", "size", "sizes", + "span", "src", "srcdoc", "srclang", "srcset", "start", "step", "target", + "type", "usemap", "value", "width", "wrap" + ] + + } + + } + }; + } + + createPage(args, util) { + if (!Object.keys(this.pages).includes(args.PAGE)){ + if(/[a-z0-9]/i.test(args.PAGE)){ + this.pages[args.PAGE] = { + "data":{ + "x":5, + "y":5, + height: "350", + width: "470", + }, + "ids": [], + "code":"" + } + } else { + throw new Error ("Name must contain at least one number or letter") + } + } + } + clearPage(args, util){ + + if (Object.keys(this.pages).includes(args.PAGE)){ + this.pages[args.PAGE].code = "" + this.pages[args.PAGE].ids = [] + } + } + deletePage(args, util){ + + if (Object.keys(this.pages).includes(args.PAGE)){ + delete this.pages[args.PAGE] + if (this.viewing === args.PAGE){ + const elements = document.querySelectorAll('#htmlpage'); + elements.forEach(el => el.remove()); + } + + } + } + allPages(){ + return(JSON.stringify(Object.keys(this.pages))) + } + get(){ + if(Object.keys(this.pages).includes("my-page")){ + return(JSON.stringify(this.pages["my-page"].code)) + } + } + + + displayPage(args, util){ + try{ + const elements = document.querySelectorAll(`#htmlpage`); + elements.forEach(el => el.remove()); + const el = document.createElement("div"); + el.innerHTML = this.pages[args.PAGE].code; + el.setAttribute("id", "htmlpage") + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.style.width = `${this.pages[args.PAGE].data.width}px`; + el.style.height = `${this.pages[args.PAGE].data.height}px`; + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + this.viewing = args.PAGE + } catch (error) {} + } + + hidePage(args, util){ + const elements = document.querySelectorAll('#htmlpage'); + elements.forEach(el => el.remove()); + } + + noNestEl(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + if(args.ID !== ""){ + if(!this.pages[args.PAGE].ids.includes(args.ID)){ + this.pages[args.PAGE].ids.push(args.ID) + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} id="element${args.PAGE}${args.ID}">` + } else { + throw new Error (`Only one element with the id "${args.ID}" can exist in the document`) + } + } else { + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} >` + } + } + } + + nestEl(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + if (util.stackFrame.startedBranch) { + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` + + util.stackFrame.startedBranch = false; + return; + } + if(args.ID !== ""){ + if(!this.pages[args.PAGE].ids.includes(args.ID)){ + this.pages[args.PAGE].ids.push(args.ID) + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} id="element${args.PAGE}${args.ID}">` + } else { + throw new Error (`Ony one element with the id "${args.ID}" can exist in the document`) + } + } else { + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} >` + } + util.stackFrame.startedBranch = true; + util.startBranch(1, true); + } + } + + + text(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}${args.TEXT}` + } + } + + removeEl(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + if(this.pages[args.PAGE].ids.includes(args.ID)){ + let text = this.pages[args.PAGE].code + let startWord = ``; + let endWord = ``; + let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); + let result = text.replace(regex, '$1 $3'); + result = result.replace(``, "").replace(``, "") + this.pages[args.PAGE].code = (result); + let num = (this.pages[args.PAGE].ids.indexOf(args.ID)) + this.pages[args.PAGE].ids.splice(num, 1) + } + } + + } + + styleEl(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + + + if (util.stackFrame.startedBranch) { + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` + + util.stackFrame.startedBranch = false; + return; + } + + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + if (currentBlock) { + currentBlock.stylePage = { + page: args.PAGE, + compiledScope: 'global', + }; + } + this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` + + // util.stackFrame.startedBranch = false; + // return; + // } + // //do before + // const blockContainer = util.thread.blockContainer; + // const currentBlockId = util.thread.peekStack(); // + // const currentBlock = blockContainer.getBlock(currentBlockId); + // if (currentBlock) { + // currentBlock.stylePage = { + // page: args.PAGE, + // compiledScope: 'global', + // }; + + // this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` + console.log("After:", this.pages[page].code) + // } + + // } else { + // // throw new Error(`Just clicking this block won't do anything. You have to put it inside of an "add style to" loop first. The shape matches the shape of this block!`) + // } + // } + + + } + + + remallstyle(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + + let result = this.pages[args.PAGE].code; + + const startWord = ""; + const endWord = ""; + + const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); + + this.pages[args.PAGE].code = result.replace(regex, ''); + } + } + + setAttr(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + if(args.ID !== ""){ + let text = this.pages[args.PAGE].code; + let newText = ` ${args.ATTR}="${args.VAL}"`; + let newReg = new RegExp(`([^>]+)`); + let updatedString = text.replace(newReg, `$1${newText}`); + // console.log(updatedString) + this.pages[args.PAGE].code = updatedString; + } + } + } + + pagePos(args, util){ + if (Object.keys(this.pages).includes(args.PAGE)){ + return(this.pages[args.PAGE].data[args.AXIS]) + } else { + return('Page does not exist!') + } + } + + movePage(args, util){ + if(Object.keys(this.pages).includes(args.PAGE)){ + this.pages[args.PAGE].data.x = args.X + this.pages[args.PAGE].data.y = args.Y + console + if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ + const elements = document.querySelectorAll(`#htmlpage`); + elements.forEach(el => el.remove()); + const el = document.createElement("div"); + el.innerHTML = this.pages[args.PAGE].code; + el.setAttribute("id", "htmlpage") + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.style.width = `${this.pages[args.PAGE].data.width}px`; + el.style.height = `${this.pages[args.PAGE].data.height}px`; + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + this.viewing = args.PAGE + } + } + } + resizePage(args, util){ + if(Object.keys(this.pages).includes(args.PAGE)){ + this.pages[args.PAGE].data.width = args.X + this.pages[args.PAGE].data.height = args.Y + if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ + const elements = document.querySelectorAll(`#htmlpage`); + elements.forEach(el => el.remove()); + const el = document.createElement("div"); + el.innerHTML = this.pages[args.PAGE].code; + el.setAttribute("id", "htmlpage") + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.style.width = `${this.pages[args.PAGE].data.width}px`; + el.style.height = `${this.pages[args.PAGE].data.height}px`; + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + this.viewing = args.PAGE + } + } + } + + resetDefault(args, util){ + if(Object.keys(this.pages).includes(args.PAGE)){ + this.pages[args.PAGE].data.width = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10 + this.pages[args.PAGE].data.height = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10 + this.pages[args.PAGE].data.x = 5 + this.pages[args.PAGE].data.y = 5 + console.log(this.viewing) + console.log(document.querySelector("#htmlpage")) + if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ + const elements = document.querySelectorAll(`#htmlpage`); + elements.forEach(el => el.remove()); + const el = document.createElement("div"); + el.innerHTML = this.pages[args.PAGE].code; + el.setAttribute("id", "htmlpage") + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.style.width = `${this.pages[args.PAGE].data.width}px`; + el.style.height = `${this.pages[args.PAGE].data.height}px`; + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + this.viewing = args.PAGE + } + } + } + + spw(args, util){ + return(window.getComputedStyle(Scratch.renderer.canvas.parentElement)[args.WH].replace("px", "")) + } + + importHTML(args, util){ + + } + + getHTML(args, util){ + if(Object.keys(this.pages).includes(args.PAGE)){ + let el = this.pages[args.PAGE].code; + let cleanString = el.replace(//g, ""); + return(`${cleanString}`) + } else { + return('Page does not exist!') + } + } + + + addeve(args, util) { + let el = document.getElementById(`element${args.PAGE}${args.ID}`); + console.log(el) + if (!el) return; + + // This clones the element and replaces the old one. + // Clones do NOT keep event listeners attached via addEventListener. + const newEl = el.cloneNode(true); + el.parentNode.replaceChild(newEl, el); + + el = newEl + const triggerText = args.ID; + const triggerTexta = args.PAGE; + + el.addEventListener(args.EVE, () => { + console.log("going...") + + const targetOpcode = 'htmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + // 1. Check if it's a Field (dropdown/fixed text) + if (block.fields && block.fields.ID && block.fields.PAGE) { + console.log(block.fields.ID.value) + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + // 2. Check if it's an Input (text bubble) + else if (block.inputs && block.inputs.ID) { + const input = block.inputs.ID; + const inputa = block.inputs.PAGE; + // Dig into the 'shadow' block which holds the text value + const shadowBlock = blocks.getBlock(input.shadow); + const shadowBlocka = blocks.getBlock(inputa.shadow); + if (shadowBlock && shadowBlock.fields && shadowBlock.fields.TEXT && shadowBlocka && shadowBlocka.fields && shadowBlocka.fields.TEXT) { + hatValue = shadowBlock.fields.TEXT.value; + hatValuea = shadowBlocka.fields.TEXT.value; + } + } + + // Compare and trigger + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + }); + } + + remeve(args) { + const el = document.getElementById(`element${args.PAGE}${args.ID}`); + if (!el) return; + // This clones the element and replaces the old one. + // Clones do NOT keep event listeners attached via addEventListener. + const newEl = el.cloneNode(true); + el.parentNode.replaceChild(newEl, el); + } + + + eve() { + return true; + } + + current(){ + return(this.viewing) + } +} + + Scratch.extensions.register(new HTMLtoCanvas(Scratch.runtime)); +})(Scratch); From 4764423533d111dacbbcad4576f04ad26c8c0ffa Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:20:17 -0400 Subject: [PATCH 02/26] Add new directory for images --- static/images/s | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/images/s diff --git a/static/images/s b/static/images/s new file mode 100644 index 000000000..b4785957b --- /dev/null +++ b/static/images/s @@ -0,0 +1 @@ +s From 4797e084bfcd88e5d18aa5f61293876f47cd01c6 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:21:01 -0400 Subject: [PATCH 03/26] Delete static/images/s --- static/images/s | 1 - 1 file changed, 1 deletion(-) delete mode 100644 static/images/s diff --git a/static/images/s b/static/images/s deleted file mode 100644 index b4785957b..000000000 --- a/static/images/s +++ /dev/null @@ -1 +0,0 @@ -s From 07038072f24c9c3f75174ca1b59ac6f5669d8fa1 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:21:25 -0400 Subject: [PATCH 04/26] Create ds --- static/images/ScrTwPm/ds | 1 + 1 file changed, 1 insertion(+) create mode 100644 static/images/ScrTwPm/ds diff --git a/static/images/ScrTwPm/ds b/static/images/ScrTwPm/ds new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/static/images/ScrTwPm/ds @@ -0,0 +1 @@ + From 9c28ffc17d2aeea50bb60593a6eebc47432743ba Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:21:48 -0400 Subject: [PATCH 05/26] Add files via upload --- static/images/ScrTwPm/htmldocs.png | Bin 0 -> 205966 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 static/images/ScrTwPm/htmldocs.png diff --git a/static/images/ScrTwPm/htmldocs.png b/static/images/ScrTwPm/htmldocs.png new file mode 100644 index 0000000000000000000000000000000000000000..0fb9728beb70326071a76c311a5ae293f39751b7 GIT binary patch literal 205966 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

94md?hEc{9rArF0ZKbX3pdO#T_{7 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 z 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

uXoGw{ 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 literal 0 HcmV?d00001 From cb0fd0ecc834943d8ef24c79f87d3ecde74f5bb7 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:22:23 -0400 Subject: [PATCH 06/26] Delete static/images/ScrTwPm/ds --- static/images/ScrTwPm/ds | 1 - 1 file changed, 1 deletion(-) delete mode 100644 static/images/ScrTwPm/ds diff --git a/static/images/ScrTwPm/ds b/static/images/ScrTwPm/ds deleted file mode 100644 index 8b1378917..000000000 --- a/static/images/ScrTwPm/ds +++ /dev/null @@ -1 +0,0 @@ - From 15346e3ac211a472ded2eb6ba23f1b7a24314219 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 13:25:11 -0400 Subject: [PATCH 07/26] Add HTML Documents extension with details --- src/lib/extensions.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/extensions.js b/src/lib/extensions.js index 84d1c063a..048415e08 100644 --- a/src/lib/extensions.js +++ b/src/lib/extensions.js @@ -405,6 +405,14 @@ export default [ banner: "NamelessCat/corsproxy.avif", creator: "NamelessCat", }, + { + name: "HTML Documents", + description: "Create HTML webpages and display them on the stage.", + code: "ScrTwPm/htmldocuments.js", + banner: "ScrTwPm/htmldocs.png", + creator: "ScrTwPm", + isGitHub: true, + }, { name: "Extension Exposer", description: "Access the raw functions from other extensions.", From 357697a3f646c339a7d2ff012eed3e00d005e5e2 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 17:59:32 -0400 Subject: [PATCH 08/26] edits for suggestions --- static/extensions/ScrTwPm/htmldocuments.js | 2017 ++++++++++---------- 1 file changed, 1025 insertions(+), 992 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 0454f3642..568df3bd8 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -1,758 +1,767 @@ -(function(Scratch) { - 'use strict'; - - if (Scratch.gui) { - Scratch.gui.getBlockly().then(ScratchBlocks => { - ScratchBlocks.BlockSvg.registerCustomNotch("htmldocuments-coolshape", - "c 2 0 3 1 4 2 l 4 4 c 1 1 4 -7 4 2 h 3 c 1 -1 2 -2 3 -3 c 1 1 2 2 3 3 l 3 0 c 0 -9 3 -1 4 -2 l 4 -4 c 1 -1 2 -2 4 -2" - ) - ScratchBlocks.BlockSvg.registerCustomNotch("htmldocuments-coolshape2", - "c 0 2 0 8 4 8 c 6 0 10 -7 14 -5 c 4 -2 8 5 14 5 c 4 0 4 -6 4 -8" - ) - }); -} - - - class HTMLtoCanvas { - constructor(runtime) { - // Initialize an array holding your default dropdown menu options - this.pages = {} - this.changePx = [ - "block-size", - "border-block-end-width", - "border-block-start-width", - "border-block-width", - "border-bottom-left-radius", - "border-bottom-right-radius", - "border-bottom-width", - "border-image-outset", - "border-image-width", - "border-inline-end-width", - "border-inline-start-width", - "border-inline-width", - "border-left-width", - "border-right-width", - "border-spacing", - "border-top-left-radius", - "border-top-right-radius", - "border-top-width", - "border-width", - "bottom", - "column-gap", - "column-rule-width", - "column-width", - "contain-intrinsic-block-size", - "contain-intrinsic-height", - "contain-intrinsic-inline-size", - "contain-intrinsic-size", - "contain-intrinsic-width", - "cx", - "cy", - "font-size", - "gap", - "grid-auto-columns", - "grid-auto-rows", - "grid-template-columns", - "grid-template-rows", - "height", - "inline-size", - "left", - "letter-spacing", - "margin-block-end", - "margin-block-start", - "margin-block", - "margin-bottom", - "margin-inline-end", - "margin-inline-start", - "margin-inline", - "margin-left", - "margin-right", - "margin-top", - "max-block-size", - "max-height", - "max-inline-size", - "max-width", - "min-block-size", - "min-height", - "min-inline-size", - "min-width", - "object-position", - "offset-distance", - "offset-path", - "outline-offset", - "outline-width", - "padding-block-end", - "padding-block-start", - "padding-block", - "padding-bottom", - "padding-inline-end", - "padding-inline-start", - "padding-inline", - "padding-left", - "padding-right", - "padding-top", - "perspective", - "perspective-origin", - "r", - "right", - "row-gap", - "rx", - "ry", - "scroll-margin-bottom", - "scroll-margin-left", - "scroll-margin-right", - "scroll-margin-top", - "scroll-padding-bottom", - "scroll-padding-left", - "scroll-padding-right", - "scroll-padding-top", - "shape-margin", - "tab-size", - "text-decoration-thickness", - "text-indent", - "top", - "transform-origin", - "translate", - "width", - "word-spacing", - "x", - "y" - ] - this.viewing = "" - this.runtime = runtime - } - getInfo() { - return { - id: 'htmldocuments', - name: 'HTML documents', - color1: '#ff9900', - blocks: [ - - { - opcode: 'createPage', - blockType: Scratch.BlockType.COMMAND, - text: 'create new page named [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - { - opcode: 'deletePage', - blockType: Scratch.BlockType.COMMAND, - text: 'delete page named [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - { - opcode: 'clearPage', - blockType: Scratch.BlockType.COMMAND, - text: 'clear content of [PAGE]', - // notchAccepts: "htmldocuments-coolshape", - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - { - opcode: 'allPages', - blockType: Scratch.BlockType.REPORTER, - text: 'all pages', - disableMonitor: true, - }, - { - opcode: 'getHTML', - blockType: Scratch.BlockType.REPORTER, - text: 'get html code of [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - // { - // opcode: 'get', - // blockType: Scratch.BlockType.REPORTER, - // text: 'get', - // }, - { blockType: Scratch.BlockType.LABEL, text: "Render HTML" }, - { - opcode: 'displayPage', - blockType: Scratch.BlockType.COMMAND, - text: 'display page [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - { - opcode: 'hidePage', - blockType: Scratch.BlockType.COMMAND, - text: 'hide page', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - } - } - }, - { - opcode: 'current', - blockType: Scratch.BlockType.REPORTER, - text: 'current page displayed', - disableMonitor: true - }, - { blockType: Scratch.BlockType.LABEL, text: "Element Management" }, - { - opcode: 'nestEl', - blockType: Scratch.BlockType.CONDITIONAL, - text: 'add [EL] id [ID] to [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el" - }, - EL: { - type: Scratch.ArgumentType.STRING, - menu: "nest", - defaultValue: "div" - } - } - }, - { - opcode: 'noNestEl', - blockType: Scratch.BlockType.COMMAND, - text: 'add [EL] id [ID] to [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el" - }, - EL: { - type: Scratch.ArgumentType.STRING, - menu: "nonest", - defaultValue: "input" - }, - } - }, - { - opcode: 'text', - blockType: Scratch.BlockType.COMMAND, - text: 'add text [TEXT] to [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: "Hello World!" - }, - } - }, - { - opcode: 'removeEl', - blockType: Scratch.BlockType.COMMAND, - text: 'remove element with id [ID] from [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el" - }, - } - }, - { - opcode: 'setAttr', - blockType: Scratch.BlockType.COMMAND, - text: 'set [ATTR] of [ID] to [VAL] in [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el" - }, - VAL: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-class" - }, - ATTR: { - type: Scratch.ArgumentType.STRING, - defaultValue: "class", - menu:"attr" - }, - } - - }, - - { blockType: Scratch.BlockType.LABEL, text: "CSS Styles" }, - - // { - // opcode: 'styleEl', - // blockType: Scratch.BlockType.CONDITIONAL, - // text: 'add style to [PAGE]', - // branchCount: 1, - // // notchAccepts: "htmldocuments-coolshape", - // branches: [ - // { accepts: "htmldocuments-coolshape2" }, - // ], - // arguments: { - // PAGE: { - // type: Scratch.ArgumentType.STRING, - // defaultValue: "my-page" - // }, - // } - // }, - { - opcode: 'property', - blockType: Scratch.BlockType.COMMAND, - text: 'set [PROPERTY] for [TYPE] [NAME] to [VALUE] in [PAGE]', - // notchAccepts: "htmldocuments-coolshape2", - arguments: { - PROPERTY: { - type: Scratch.ArgumentType.STRING, - menu: "properties", - defaultValue: "color" - }, - TYPE: { - type: Scratch.ArgumentType.STRING, - menu: "types" - }, - NAME: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el" - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "green", - }, - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page", - }, - } - }, - - { - opcode: 'remallstyle', - blockType: Scratch.BlockType.COMMAND, - text: 'clear styling of [PAGE]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - } - }, - - { blockType: Scratch.BlockType.LABEL, text: "Event Listeners" }, - - - { - opcode: 'eve', - blockType: Scratch.BlockType.HAT, - text: 'When listener for [ID] activated in [PAGE]', - isEdgeActivated: false, - arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: "new-el", - // defaultValue: '{"Hello":"Item 1", "Bye":"Item 2"}' - }, - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - } - }, - { - opcode: 'addeve', - blockType: Scratch.BlockType.COMMAND, - text: 'add event listener [EVE] for [ID] in [PAGE]', - arguments: { - EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - } - }, - { - opcode: 'remeve', - blockType: Scratch.BlockType.COMMAND, - text: 'remove event listeners from [ID] in [PAGE]', - arguments: { - EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - } - }, - - { blockType: Scratch.BlockType.LABEL, text: "Webpage Positioning" }, - - { - opcode: 'movePage', - blockType: Scratch.BlockType.COMMAND, - text: 'move [PAGE] to x: [X] y: [Y]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - X: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "50" - }, - Y: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "50" - }, - } - }, - { - opcode: 'resizePage', - blockType: Scratch.BlockType.COMMAND, - text: 'resize [PAGE] to x: [X] y: [Y]', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - X: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "300" - }, - Y: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "200" - }, - } - }, - { - opcode: 'resetDefault', - blockType: Scratch.BlockType.COMMAND, - text: 'set [PAGE] display settings to stage size', - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - X: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "300" - }, - Y: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: "200" - }, - } - }, - { - opcode: 'pagePos', - blockType: Scratch.BlockType.REPORTER, - text: '[AXIS] of [PAGE]', - disableMonitor: true, - arguments: { - PAGE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "my-page" - }, - AXIS: { - type: Scratch.ArgumentType.STRING, - menu: "axis" - }, - } - }, - { - opcode: 'spw', - blockType: Scratch.BlockType.REPORTER, - text: '[WH] of the stage', - disableMonitor: true, - arguments: { - WH: { - type: Scratch.ArgumentType.STRING, - menu: "wh" - }, - } - }, - - ], - menus: { - nonest: { - acceptReporters: true, - items: - [ - "area","base","br","col","embed","hr","img","input","link","meta","script","source","textarea","track","wbr" +(function (Scratch) { + 'use strict'; + + + class HTMLtoCanvas { + constructor(runtime) { + // Initialize an array holding your default dropdown menu options + this.pages = {} + this.changePx = [ + "block-size", + "border-block-end-width", + "border-block-start-width", + "border-block-width", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-width", + "border-image-outset", + "border-image-width", + "border-inline-end-width", + "border-inline-start-width", + "border-inline-width", + "border-left-width", + "border-right-width", + "border-spacing", + "border-top-left-radius", + "border-top-right-radius", + "border-top-width", + "border-width", + "bottom", + "column-gap", + "column-rule-width", + "column-width", + "contain-intrinsic-block-size", + "contain-intrinsic-height", + "contain-intrinsic-inline-size", + "contain-intrinsic-size", + "contain-intrinsic-width", + "cx", + "cy", + "font-size", + "gap", + "grid-auto-columns", + "grid-auto-rows", + "grid-template-columns", + "grid-template-rows", + "height", + "inline-size", + "left", + "letter-spacing", + "margin-block-end", + "margin-block-start", + "margin-block", + "margin-bottom", + "margin-inline-end", + "margin-inline-start", + "margin-inline", + "margin-left", + "margin-right", + "margin-top", + "max-block-size", + "max-height", + "max-inline-size", + "max-width", + "min-block-size", + "min-height", + "min-inline-size", + "min-width", + "object-position", + "offset-distance", + "offset-path", + "outline-offset", + "outline-width", + "padding-block-end", + "padding-block-start", + "padding-block", + "padding-bottom", + "padding-inline-end", + "padding-inline-start", + "padding-inline", + "padding-left", + "padding-right", + "padding-top", + "perspective", + "perspective-origin", + "r", + "right", + "row-gap", + "rx", + "ry", + "scroll-margin-bottom", + "scroll-margin-left", + "scroll-margin-right", + "scroll-margin-top", + "scroll-padding-bottom", + "scroll-padding-left", + "scroll-padding-right", + "scroll-padding-top", + "shape-margin", + "tab-size", + "text-decoration-thickness", + "text-indent", + "top", + "transform-origin", + "translate", + "width", + "word-spacing", + "x", + "y" + ] + this.viewing = [] + this.runtime = runtime + } + getInfo() { + return { + id: 'htmldocuments', + name: 'HTML documents', + color1: '#ff9900', + blocks: [ + + { + opcode: 'createPage', + blockType: Scratch.BlockType.COMMAND, + text: 'create new page named [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'deletePage', + blockType: Scratch.BlockType.COMMAND, + text: 'delete page named [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'clearPage', + blockType: Scratch.BlockType.COMMAND, + text: 'clear content of [PAGE]', + // notchAccepts: "htmldocuments-coolshape", + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'allPages', + blockType: Scratch.BlockType.REPORTER, + text: 'all pages', + disableMonitor: true, + }, + { + opcode: 'getHTML', + blockType: Scratch.BlockType.REPORTER, + text: 'get html code of [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + // { + // opcode: 'get', + // blockType: Scratch.BlockType.REPORTER, + // text: 'get', + // }, + { blockType: Scratch.BlockType.LABEL, text: "Render HTML" }, + { + opcode: 'displayPage', + blockType: Scratch.BlockType.COMMAND, + text: 'display page [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'hidePage', + blockType: Scratch.BlockType.COMMAND, + text: 'hide page [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'hidePageAll', + blockType: Scratch.BlockType.COMMAND, + text: 'hide all pages', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + } + } + }, + { + opcode: 'current', + blockType: Scratch.BlockType.REPORTER, + text: 'current pages displayed', + disableMonitor: true + }, + { blockType: Scratch.BlockType.LABEL, text: "Element Management" }, + { + opcode: 'nestEl', + blockType: Scratch.BlockType.CONDITIONAL, + text: 'add [EL] id [ID] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + EL: { + type: Scratch.ArgumentType.STRING, + menu: "nest", + defaultValue: "div" + } + } + }, + { + opcode: 'noNestEl', + blockType: Scratch.BlockType.COMMAND, + text: 'add [EL] id [ID] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + EL: { + type: Scratch.ArgumentType.STRING, + menu: "nonest", + defaultValue: "input" + }, + } + }, + { + opcode: 'text', + blockType: Scratch.BlockType.COMMAND, + text: 'add text [TEXT] to [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello World!" + }, + } + }, + { + opcode: 'removeEl', + blockType: Scratch.BlockType.COMMAND, + text: 'remove element with id [ID] from [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + } + }, + { + opcode: 'setAttr', + blockType: Scratch.BlockType.COMMAND, + text: 'set [ATTR] of [ID] to [VAL] in [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + VAL: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-class" + }, + ATTR: { + type: Scratch.ArgumentType.STRING, + defaultValue: "class", + menu: "attr" + }, + } + + }, + + { blockType: Scratch.BlockType.LABEL, text: "CSS Styles" }, + + // { + // opcode: 'styleEl', + // blockType: Scratch.BlockType.CONDITIONAL, + // text: 'add style to [PAGE]', + // branchCount: 1, + // // notchAccepts: "htmldocuments-coolshape", + // branches: [ + // { accepts: "htmldocuments-coolshape2" }, + // ], + // arguments: { + // PAGE: { + // type: Scratch.ArgumentType.STRING, + // defaultValue: "my-page" + // }, + // } + // }, + { + opcode: 'property', + blockType: Scratch.BlockType.COMMAND, + text: 'set [PROPERTY] for [TYPE] [NAME] to [VALUE] in [PAGE]', + // notchAccepts: "htmldocuments-coolshape2", + arguments: { + PROPERTY: { + type: Scratch.ArgumentType.STRING, + menu: "properties", + defaultValue: "color" + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "types" + }, + NAME: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "green", + }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page", + }, + } + }, + + { + opcode: 'remallstyle', + blockType: Scratch.BlockType.COMMAND, + text: 'clear styling of [PAGE]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + + { blockType: Scratch.BlockType.LABEL, text: "Event Listeners" }, + + + { + opcode: 'eve', + blockType: Scratch.BlockType.HAT, + text: 'when listener for [ID] activated in [PAGE]', + isEdgeActivated: false, + arguments: { + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el", + // defaultValue: '{"Hello":"Item 1", "Bye":"Item 2"}' + }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + { + opcode: 'addeve', + blockType: Scratch.BlockType.COMMAND, + text: 'add event listener [EVE] for [ID] in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + { + opcode: 'remeve', + blockType: Scratch.BlockType.COMMAND, + text: 'remove event listeners from [ID] in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + + { blockType: Scratch.BlockType.LABEL, text: "Webpage Positioning" }, + + { + opcode: 'movePage', + blockType: Scratch.BlockType.COMMAND, + text: 'move [PAGE] to x: [X] y: [Y]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "50" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "50" + }, + } + }, + { + opcode: 'resizePage', + blockType: Scratch.BlockType.COMMAND, + text: 'resize [PAGE] to x: [X] y: [Y]', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "300" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "200" + }, + } + }, + { + opcode: 'resetDefault', + blockType: Scratch.BlockType.COMMAND, + text: 'set [PAGE] display settings to stage size', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "300" + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: "200" + }, + } + }, + { + opcode: 'pagePos', + blockType: Scratch.BlockType.REPORTER, + text: '[AXIS] of [PAGE]', + disableMonitor: true, + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + AXIS: { + type: Scratch.ArgumentType.STRING, + menu: "axis" + }, + } + }, + { + opcode: 'spw', + blockType: Scratch.BlockType.REPORTER, + text: '[WH] of the stage', + disableMonitor: true, + arguments: { + WH: { + type: Scratch.ArgumentType.STRING, + menu: "wh" + }, + } + }, + + ], + menus: { + nonest: { + acceptReporters: true, + items: + [ + "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "script", "source", "textarea", "track", "wbr" + ] + }, + nest: { + acceptReporters: true, + items: + [ + "a", "abbr", "address", "article", "aside", "audio", "b", "bdi", "bdo", "blockquote", "button", "canvas", "caption", "cite", "code", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "i", "iframe", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "menu", "meter", "nav", "object", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "slot", "small", "span", "strong", "sub", "summary", "sup", "table", "tbody", "td", "template", "tfoot", "th", "thead", "time", "tr", "u", "ul", "var", "video" + ] + }, + types: { + acceptReporters: false, + items: [ + { text: "id", value: "#" }, + { text: "class", value: "." }, + // {text: "animation", value: "@keyframes "}, ] - }, - nest: { - acceptReporters: true, - items: - [ - "a", "abbr", "address", "article", "aside", "audio", "b", "bdi", "bdo", "blockquote", "button", "canvas", "caption", "cite", "code", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "i", "iframe", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "menu", "meter", "nav", "object", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "slot", "small", "span", "strong", "sub", "summary", "sup", "table", "tbody", "td", "template", "tfoot", "th", "thead", "time", "tr", "u", "ul", "var", "video" + }, + properties: { + acceptReporters: true, + items: [ + + 'align-content', 'align-items', 'align-self', 'all', 'animation', 'animation-delay', 'animation-direction', 'animation-duration', 'animation-fill-mode', 'animation-iter-count', 'animation-name', 'animation-play-state', 'animation-timing-fn', 'backface-visibility', 'background', 'background-attachment', 'background-blend-mode', 'background-clip', 'background-color', 'background-image', 'background-origin', 'background-position', 'background-repeat', 'background-size', 'border', 'border-bottom', 'border-bottom-color', 'border-bottom-left-rad', 'border-bottom-right-ra', 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-image', 'border-image-outset', 'border-image-repeat', 'border-image-slice', 'border-image-source', 'border-image-width', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-radius', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-style', 'border-top-width', 'border-width', 'bottom', 'box-decoration-break', 'box-shadow', 'box-sizing', 'caption-side', 'caret-color', + 'clear', 'clip', 'clip-path', 'color', 'column-count', 'column-fill', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-style', 'column-rule-width', 'column-span', 'column-width', 'columns', 'content', 'counter-increment', 'counter-reset', 'cursor', 'direction', 'display', 'empty-cells', 'filter', 'flex', 'flex-basis', 'flex-direction', 'flex-flow', 'flex-grow', 'flex-shrink', 'flex-wrap', 'float', 'font', + 'font-family', 'font-kerning', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'gap', 'grid', 'grid-area', 'grid-auto-columns', 'grid-auto-flow', 'grid-auto-rows', 'grid-column', 'grid-column-end', 'grid-column-gap', 'grid-column-start', 'grid-gap', 'grid-row', 'grid-row-end', 'grid-row-gap', 'grid-row-start', 'grid-template', 'grid-template-areas', 'grid-template-columns', 'grid-template-rows', 'height', 'hyphens', + 'justify-content', + 'left', 'letter-spacing', 'line-height', 'list-style', 'list-style-image', 'list-style-position', 'list-style-type', 'margin', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'max-height', 'max-width', + 'min-height', 'min-width', 'object-fit', 'object-position', 'opacity', 'order', 'outline', 'outline-color', 'outline-offset', 'outline-style', 'outline-width', 'overflow', 'overflow-x', 'overflow-y', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'page-break-after', 'page-break-before', 'page-break-inside', 'perspective', 'perspective-origin', 'pointer-events', 'position', 'quotes', 'right', 'row-gap', 'scroll-behavior', 'table-layout', 'text-align', 'text-align-last', 'text-decoration', 'text-decoration-color', 'text-decoration-line', 'text-decoration-style', 'text-indent', 'text-justify', 'text-overflow', 'text-shadow', 'text-transform', 'top', 'transform', 'transform-origin', 'transform-style', 'transition', 'transition-delay', 'transition-duration', 'transition-property', 'transition-timing-fn', 'user-select', 'vertical-align', 'visibility', 'white-space', 'width', 'word-break', 'word-spacing', 'word-wrap', 'writing-mode', 'z-index' + + ] + }, + axis: { + acceptReporters: false, + items: [ + { text: "x position", value: "x" }, { text: "y position", value: "y" }, "width", "height" ] - }, - types: { - acceptReporters: false, - items: [ - {text: "id", value: "#"}, - {text: "class", value: "."}, - // {text: "animation", value: "@keyframes "}, - ] - }, - properties: { - acceptReporters: true, - items:[ - - 'align-content','align-items','align-self','all','animation','animation-delay','animation-direction','animation-duration','animation-fill-mode','animation-iter-count','animation-name','animation-play-state','animation-timing-fn','backface-visibility','background','background-attachment','background-blend-mode','background-clip','background-color','background-image','background-origin','background-position','background-repeat','background-size','border','border-bottom','border-bottom-color','border-bottom-left-rad','border-bottom-right-ra','border-bottom-style','border-bottom-width','border-collapse','border-color','border-image','border-image-outset','border-image-repeat','border-image-slice','border-image-source','border-image-width','border-left','border-left-color','border-left-style','border-left-width','border-radius','border-right','border-right-color','border-right-style','border-right-width','border-spacing','border-style','border-top','border-top-color','border-top-left-radius','border-top-right-radius','border-top-style','border-top-width','border-width','bottom','box-decoration-break','box-shadow','box-sizing','caption-side','caret-color', - 'clear','clip','clip-path','color','column-count','column-fill','column-gap','column-rule','column-rule-color','column-rule-style','column-rule-width','column-span','column-width','columns','content','counter-increment','counter-reset','cursor','direction','display','empty-cells','filter','flex','flex-basis','flex-direction','flex-flow','flex-grow','flex-shrink','flex-wrap','float','font', - 'font-family','font-kerning','font-size','font-stretch','font-style','font-variant','font-weight','gap','grid','grid-area','grid-auto-columns','grid-auto-flow','grid-auto-rows','grid-column','grid-column-end','grid-column-gap','grid-column-start','grid-gap','grid-row','grid-row-end','grid-row-gap','grid-row-start','grid-template','grid-template-areas','grid-template-columns','grid-template-rows','height','hyphens', - 'justify-content', - 'left','letter-spacing','line-height','list-style','list-style-image','list-style-position','list-style-type','margin','margin-bottom','margin-left','margin-right','margin-top','max-height','max-width', - 'min-height','min-width','object-fit','object-position','opacity','order','outline','outline-color','outline-offset','outline-style','outline-width','overflow','overflow-x','overflow-y','padding','padding-bottom','padding-left','padding-right','padding-top','page-break-after','page-break-before','page-break-inside','perspective','perspective-origin','pointer-events','position','quotes','right','row-gap','scroll-behavior','table-layout','text-align','text-align-last','text-decoration','text-decoration-color','text-decoration-line','text-decoration-style','text-indent','text-justify','text-overflow','text-shadow','text-transform','top','transform','transform-origin','transform-style','transition','transition-delay','transition-duration','transition-property','transition-timing-fn','user-select','vertical-align','visibility','white-space','width','word-break','word-spacing','word-wrap','writing-mode','z-index' - - ] - }, - axis: { - acceptReporters: false, - items: [ - {text:"x position", value: "x"}, {text:"y position", value: "y"}, "width","height" - ] - }, - wh: { - acceptReporters: false, - items: [ - "width","height" - ] - }, - eves: { - acceptReporters: true, - items: [ - // Mouse & Pointer - "click", "dblclick", "mousedown", "mouseup", "mouseenter", - "mouseleave", "mousemove", "mouseover", "mouseout", "contextmenu", "wheel", - - // Keyboard - "keydown", "keyup", "keypress", - - // Form & Input - "submit", "input", "change", "focus", "blur", "reset", "invalid", - - // Window & Document - "load", "DOMContentLoaded", "beforeunload", "unload", "resize", - "scroll", "error", "visibilitychange", - - // Drag & Drop - "dragstart", "drag", "dragenter", "dragover", "dragleave", "drop", "dragend", - - // Mobile & Media - "touchstart", "touchmove", "touchend", "play" - ] - }, - attr: { - acceptReporters: false, - items: [ - "accesskey", "autocapitalize", "autofocus", "class", "contenteditable", - "dir", "draggable", "enterkeyhint", "hidden", "inert", "inputmode", - "lang", "nonce", "part", "popover", "role", "slot", "style", "tabindex", - "title", "translate", "virtualkeyboardpolicy", - "accept", "accept-charset", "action", "align", "allow", "alt", "as", - "async", "autocomplete", "autoplay", "background", "bgcolor", "border", - "capture", "charset", "checked", "cite", "color", "cols", "colspan", - "content", "controls", "coords", "crossorigin", "csp", "data", "datetime", - "decoding", "default", "defer", "disabled", "download", "enctype", "for", - "form", "formaction", "formenctype", "formmethod", "formnovalidate", - "formtarget", "headers", "height", "high", "href", "hreflang", "http-equiv", - "imagesizes", "imagesrcset", "integrity", "ismap", "kind", "label", "list", - "loading", "loop", "low", "max", "maxlength", "min", "minlength", "media", - "method", "multiple", "muted", "name", "novalidate", "open", "optimum", - "pattern", "ping", "placeholder", "playsinline", "poster", "preload", - "readonly", "referrerpolicy", "rel", "required", "reversed", "rows", - "rowspan", "sandbox", "scope", "selected", "shape", "size", "sizes", - "span", "src", "srcdoc", "srclang", "srcset", "start", "step", "target", - "type", "usemap", "value", "width", "wrap" - ] + }, + wh: { + acceptReporters: false, + items: [ + "width", "height" + ] + }, + eves: { + acceptReporters: true, + items: [ + // Mouse & Pointer + "click", "dblclick", "mousedown", "mouseup", "mouseenter", + "mouseleave", "mousemove", "mouseover", "mouseout", "contextmenu", "wheel", - } + // Keyboard + "keydown", "keyup", "keypress", - } - }; - } + // Form & Input + "submit", "input", "change", "focus", "blur", "reset", "invalid", + + // Window & Document + "load", "DOMContentLoaded", "beforeunload", "unload", "resize", + "scroll", "error", "visibilitychange", + + // Drag & Drop + "dragstart", "drag", "dragenter", "dragover", "dragleave", "drop", "dragend", - createPage(args, util) { - if (!Object.keys(this.pages).includes(args.PAGE)){ - if(/[a-z0-9]/i.test(args.PAGE)){ - this.pages[args.PAGE] = { - "data":{ - "x":5, - "y":5, - height: "350", - width: "470", + // Mobile & Media + "touchstart", "touchmove", "touchend", "play" + ] }, - "ids": [], - "code":"" + attr: { + acceptReporters: false, + items: [ + "accesskey", "autocapitalize", "autofocus", "class", "contenteditable", + "dir", "draggable", "enterkeyhint", "hidden", "inert", "inputmode", + "lang", "nonce", "part", "popover", "role", "slot", "style", "tabindex", + "title", "translate", "virtualkeyboardpolicy", + "accept", "accept-charset", "action", "align", "allow", "alt", "as", + "async", "autocomplete", "autoplay", "background", "bgcolor", "border", + "capture", "charset", "checked", "cite", "color", "cols", "colspan", + "content", "controls", "coords", "crossorigin", "csp", "data", "datetime", + "decoding", "default", "defer", "disabled", "download", "enctype", "for", + "form", "formaction", "formenctype", "formmethod", "formnovalidate", + "formtarget", "headers", "height", "high", "href", "hreflang", "http-equiv", + "imagesizes", "imagesrcset", "integrity", "ismap", "kind", "label", "list", + "loading", "loop", "low", "max", "maxlength", "min", "minlength", "media", + "method", "multiple", "muted", "name", "novalidate", "open", "optimum", + "pattern", "ping", "placeholder", "playsinline", "poster", "preload", + "readonly", "referrerpolicy", "rel", "required", "reversed", "rows", + "rowspan", "sandbox", "scope", "selected", "shape", "size", "sizes", + "span", "src", "srcdoc", "srclang", "srcset", "start", "step", "target", + "type", "usemap", "value", "width", "wrap" + ] + + } + } - } else { - throw new Error ("Name must contain at least one number or letter") - } + }; } - } - clearPage(args, util){ - - if (Object.keys(this.pages).includes(args.PAGE)){ - this.pages[args.PAGE].code = "" - this.pages[args.PAGE].ids = [] + + createPage(args, util) { + if (!Object.keys(this.pages).includes(args.PAGE)) { + if (/[a-z0-9]/i.test(args.PAGE)) { + this.pages[args.PAGE] = { + "data": { + "x": 5, + "y": 5, + height: "350", + width: "470", + }, + "ids": [], + "code": "" + } + } else { + throw new Error("Name must contain at least one number or letter") + } + } } - } - deletePage(args, util){ - - if (Object.keys(this.pages).includes(args.PAGE)){ - delete this.pages[args.PAGE] - if (this.viewing === args.PAGE){ - const elements = document.querySelectorAll('#htmlpage'); - elements.forEach(el => el.remove()); + clearPage(args, util) { + + if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages[args.PAGE].code = "" + this.pages[args.PAGE].ids = [] } + } + deletePage(args, util) { + + if (Object.keys(this.pages).includes(args.PAGE)) { + delete this.pages[args.PAGE] + if (this.viewing.includes(args.PAGE)) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + } + } } - } - allPages(){ - return(JSON.stringify(Object.keys(this.pages))) - } - get(){ - if(Object.keys(this.pages).includes("my-page")){ - return(JSON.stringify(this.pages["my-page"].code)) + allPages() { + return (JSON.stringify(Object.keys(this.pages))) } - } + get() { + if (Object.keys(this.pages).includes("my-page")) { + return (JSON.stringify(this.pages["my-page"].code)) + } + } + + displayPage(args, util) { + try { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages[args.PAGE].code) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) + el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if(!this.viewing.includes(args.PAGE)){ + this.viewing.push(args.PAGE) + } + } catch (error) { } + } - displayPage(args, util){ - try{ - const elements = document.querySelectorAll(`#htmlpage`); + hidePageAll(args, util) { + const elements = document.querySelectorAll('.htmlpage'); elements.forEach(el => el.remove()); - const el = document.createElement("div"); - el.innerHTML = this.pages[args.PAGE].code; - el.setAttribute("id", "htmlpage") - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.style.width = `${this.pages[args.PAGE].data.width}px`; - el.style.height = `${this.pages[args.PAGE].data.height}px`; - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - this.viewing = args.PAGE - } catch (error) {} - } + this.viewing = [] + } - hidePage(args, util){ - const elements = document.querySelectorAll('#htmlpage'); - elements.forEach(el => el.remove()); - } + hidePage(args, util) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + this.viewing.splice(this.viewing.indexOf(args.PAGE), 1) + } - noNestEl(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - if(args.ID !== ""){ - if(!this.pages[args.PAGE].ids.includes(args.ID)){ - this.pages[args.PAGE].ids.push(args.ID) - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} id="element${args.PAGE}${args.ID}">` + noNestEl(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + if (args.ID !== "") { + if (!this.pages[args.PAGE].ids.includes(args.ID)) { + this.pages[args.PAGE].ids.push(args.ID) + this.pages[args.PAGE].code += `<${args.EL} id="element${args.PAGE}${args.ID}">` + } else { + throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + } } else { - throw new Error (`Only one element with the id "${args.ID}" can exist in the document`) + this.pages[args.PAGE].code += `<${args.EL} >` } - } else { - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} >` } } - } - nestEl(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - if (util.stackFrame.startedBranch) { - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` - - util.stackFrame.startedBranch = false; - return; - } - if(args.ID !== ""){ - if(!this.pages[args.PAGE].ids.includes(args.ID)){ - this.pages[args.PAGE].ids.push(args.ID) - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} id="element${args.PAGE}${args.ID}">` + nestEl(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + if (util.stackFrame.startedBranch) { + this.pages[args.PAGE].code += `` + + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (!this.pages[args.PAGE].ids.includes(args.ID)) { + this.pages[args.PAGE].ids.push(args.ID) + this.pages[args.PAGE].code += `<${args.EL} id="element${args.PAGE}${args.ID}">` + } else { + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + } } else { - throw new Error (`Ony one element with the id "${args.ID}" can exist in the document`) + this.pages[args.PAGE].code += `<${args.EL} >` } - } else { - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}<${args.EL} >` + util.stackFrame.startedBranch = true; + util.startBranch(1, true); } - util.stackFrame.startedBranch = true; - util.startBranch(1, true); } - } - - text(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}${args.TEXT}` + + text(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages[args.PAGE].code += `${args.TEXT}` + } } - } - removeEl(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - if(this.pages[args.PAGE].ids.includes(args.ID)){ - let text = this.pages[args.PAGE].code - let startWord = ``; - let endWord = ``; - let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); - let result = text.replace(regex, '$1 $3'); - result = result.replace(``, "").replace(``, "") - this.pages[args.PAGE].code = (result); - let num = (this.pages[args.PAGE].ids.indexOf(args.ID)) - this.pages[args.PAGE].ids.splice(num, 1) + removeEl(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + if (this.pages[args.PAGE].ids.includes(args.ID)) { + let text = this.pages[args.PAGE].code + let startWord = ``; + let endWord = ``; + let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); + let result = text.replace(regex, '$1 $3'); + result = result.replace(``, "").replace(``, "") + this.pages[args.PAGE].code = (result); + let num = (this.pages[args.PAGE].ids.indexOf(args.ID)) + this.pages[args.PAGE].ids.splice(num, 1) + } } + } - } + styleEl(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { - styleEl(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ + if (util.stackFrame.startedBranch) { + this.pages[args.PAGE].code += `` + + util.stackFrame.startedBranch = false; + return; + } - if (util.stackFrame.startedBranch) { - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` - - util.stackFrame.startedBranch = false; - return; - } - const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); // const currentBlock = blockContainer.getBlock(currentBlockId); @@ -762,85 +771,84 @@ compiledScope: 'global', }; } - this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` - - // util.stackFrame.startedBranch = false; - // return; - // } - // //do before - // const blockContainer = util.thread.blockContainer; - // const currentBlockId = util.thread.peekStack(); // - // const currentBlock = blockContainer.getBlock(currentBlockId); - // if (currentBlock) { - // currentBlock.stylePage = { - // page: args.PAGE, - // compiledScope: 'global', - // }; - - // this.pages[args.PAGE].code = `${this.pages[args.PAGE].code}` + + // util.stackFrame.startedBranch = false; + // return; + // } + // //do before + // const blockContainer = util.thread.blockContainer; + // const currentBlockId = util.thread.peekStack(); // + // const currentBlock = blockContainer.getBlock(currentBlockId); + // if (currentBlock) { + // currentBlock.stylePage = { + // page: args.PAGE, + // compiledScope: 'global', + // }; + + // this.pages[args.PAGE].code += `` - console.log("After:", this.pages[page].code) - // } - // } else { - // // throw new Error(`Just clicking this block won't do anything. You have to put it inside of an "add style to" loop first. The shape matches the shape of this block!`) - // } - // } + // if (parentBlock.stylePage && parentBlock) { + let page = args.PAGE//parentBlock.stylePage.page + this.pages[args.PAGE].code += `` + // } + // } else { + // // throw new Error(`Just clicking this block won't do anything. You have to put it inside of an "add style to" loop first. The shape matches the shape of this block!`) + // } + // } - } + + } - remallstyle(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ + remallstyle(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { - let result = this.pages[args.PAGE].code; + let result = this.pages[args.PAGE].code; - const startWord = ""; - const endWord = ""; + const startWord = ""; + const endWord = ""; - const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); + const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); - this.pages[args.PAGE].code = result.replace(regex, ''); + this.pages[args.PAGE].code = result.replace(regex, ''); + } } - } - setAttr(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - if(args.ID !== ""){ - let text = this.pages[args.PAGE].code; - let newText = ` ${args.ATTR}="${args.VAL}"`; - let newReg = new RegExp(`([^>]+)`); - let updatedString = text.replace(newReg, `$1${newText}`); - // console.log(updatedString) - this.pages[args.PAGE].code = updatedString; + setAttr(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + if (args.ID !== "") { + let text = this.pages[args.PAGE].code; + let newText = ` ${args.ATTR}="${args.VAL}"`; + let newReg = new RegExp(`([^>]+)`); + let updatedString = text.replace(newReg, `$1${newText}`); + this.pages[args.PAGE].code = updatedString; + } } } - } - - pagePos(args, util){ - if (Object.keys(this.pages).includes(args.PAGE)){ - return(this.pages[args.PAGE].data[args.AXIS]) - } else { - return('Page does not exist!') + + pagePos(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + return (this.pages[args.PAGE].data[args.AXIS]) + } else { + return ('Page does not exist!') + } } - } - movePage(args, util){ - if(Object.keys(this.pages).includes(args.PAGE)){ - this.pages[args.PAGE].data.x = args.X - this.pages[args.PAGE].data.y = args.Y - console - if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ - const elements = document.querySelectorAll(`#htmlpage`); - elements.forEach(el => el.remove()); - const el = document.createElement("div"); - el.innerHTML = this.pages[args.PAGE].code; - el.setAttribute("id", "htmlpage") - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.style.width = `${this.pages[args.PAGE].data.width}px`; - el.style.height = `${this.pages[args.PAGE].data.height}px`; - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - this.viewing = args.PAGE + movePage(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages[args.PAGE].data.x = args.X + this.pages[args.PAGE].data.y = args.Y + console + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages[args.PAGE].code) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) + el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if(!this.viewing.includes(args.PAGE)){ + this.viewing.push(args.PAGE) + } + } } } - } - resizePage(args, util){ - if(Object.keys(this.pages).includes(args.PAGE)){ - this.pages[args.PAGE].data.width = args.X - this.pages[args.PAGE].data.height = args.Y - if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ - const elements = document.querySelectorAll(`#htmlpage`); - elements.forEach(el => el.remove()); - const el = document.createElement("div"); - el.innerHTML = this.pages[args.PAGE].code; - el.setAttribute("id", "htmlpage") - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.style.width = `${this.pages[args.PAGE].data.width}px`; - el.style.height = `${this.pages[args.PAGE].data.height}px`; - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - this.viewing = args.PAGE + resizePage(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages[args.PAGE].data.width = args.X + this.pages[args.PAGE].data.height = args.Y + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages[args.PAGE].code) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) + el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if(!this.viewing.includes(args.PAGE)){ + this.viewing.push(args.PAGE) + } + } } } - } - resetDefault(args, util){ - if(Object.keys(this.pages).includes(args.PAGE)){ - this.pages[args.PAGE].data.width = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10 - this.pages[args.PAGE].data.height = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10 - this.pages[args.PAGE].data.x = 5 - this.pages[args.PAGE].data.y = 5 - console.log(this.viewing) - console.log(document.querySelector("#htmlpage")) - if(this.viewing === args.PAGE && document.querySelector("#htmlpage")){ - const elements = document.querySelectorAll(`#htmlpage`); - elements.forEach(el => el.remove()); - const el = document.createElement("div"); - el.innerHTML = this.pages[args.PAGE].code; - el.setAttribute("id", "htmlpage") - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.style.width = `${this.pages[args.PAGE].data.width}px`; - el.style.height = `${this.pages[args.PAGE].data.height}px`; - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - this.viewing = args.PAGE + resetDefault(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages[args.PAGE].data.width = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10 + this.pages[args.PAGE].data.height = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10 + this.pages[args.PAGE].data.x = 5 + this.pages[args.PAGE].data.y = 5 + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages[args.PAGE].code) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages[args.PAGE].data.x}px`; + el.style.top = `${this.pages[args.PAGE].data.y}px`; + el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) + el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if(!this.viewing.includes(args.PAGE)){ + this.viewing.push(args.PAGE) + } + } } } - } - spw(args, util){ - return(window.getComputedStyle(Scratch.renderer.canvas.parentElement)[args.WH].replace("px", "")) - } + spw(args, util) { + return (window.getComputedStyle(Scratch.renderer.canvas.parentElement)[args.WH].replace("px", "")) + } - importHTML(args, util){ + importHTML(args, util) { - } + } - getHTML(args, util){ - if(Object.keys(this.pages).includes(args.PAGE)){ - let el = this.pages[args.PAGE].code; - let cleanString = el.replace(//g, ""); - return(`${cleanString}`) - } else { - return('Page does not exist!') + prettierInText(html) { + /* + This function is AI generated. It formats the code for better readability when getting the html of a page. Tell me if this needs to go or if there's a better way to do this. Is this what the dom parser is for??? + */ + let clean = html.replace(/\s*([<>])\s*/g, '$1').replace(/\s+/g, ' '); + let reg = /(<[^>]+>)/g; + let matches = clean.split(reg).filter(Boolean); + let formatted = ''; + let pad = 0; + matches.forEach((token) => { + if (token.match(/<\/\w+/)) { + pad--; + } + formatted += ' '.repeat(Math.max(0, pad)) + token + '\n'; + if (token.match(/<[^\/][^>]*[^>\/]>/) && !token.match(/<(input|img|br|hr|meta|link)/)) { + pad++; + } + }); + return formatted.trim(); } - } - addeve(args, util) { - let el = document.getElementById(`element${args.PAGE}${args.ID}`); - console.log(el) - if (!el) return; - - // This clones the element and replaces the old one. - // Clones do NOT keep event listeners attached via addEventListener. - const newEl = el.cloneNode(true); - el.parentNode.replaceChild(newEl, el); - - el = newEl - const triggerText = args.ID; - const triggerTexta = args.PAGE; - - el.addEventListener(args.EVE, () => { - console.log("going...") - - const targetOpcode = 'htmldocuments_eve'; - const vm = Scratch.vm; - - vm.runtime.targets.forEach(target => { - const blocks = target.blocks; - const scripts = blocks.getScripts(); - - scripts.forEach(rootBlockId => { - const block = blocks.getBlock(rootBlockId); - - if (block && block.opcode === targetOpcode) { - let hatValue = ''; - let hatValuea = ''; - - // 1. Check if it's a Field (dropdown/fixed text) - if (block.fields && block.fields.ID && block.fields.PAGE) { - console.log(block.fields.ID.value) - hatValue = block.fields.ID.value; - hatValuea = block.fields.PAGE.value; - } - // 2. Check if it's an Input (text bubble) - else if (block.inputs && block.inputs.ID) { - const input = block.inputs.ID; - const inputa = block.inputs.PAGE; - // Dig into the 'shadow' block which holds the text value - const shadowBlock = blocks.getBlock(input.shadow); - const shadowBlocka = blocks.getBlock(inputa.shadow); - if (shadowBlock && shadowBlock.fields && shadowBlock.fields.TEXT && shadowBlocka && shadowBlocka.fields && shadowBlocka.fields.TEXT) { - hatValue = shadowBlock.fields.TEXT.value; - hatValuea = shadowBlocka.fields.TEXT.value; - } - } + getHTML(args, util) { + if (Object.keys(this.pages).includes(args.PAGE)) { + let el = this.pages[args.PAGE].code; + let cleanString = el.replace(//g, ""); + let toChange = `${cleanString}` + return (this.prettierInText(toChange)) + } else { + return ('Page does not exist!') + } + } - // Compare and trigger - if (hatValue === triggerText && hatValuea === triggerTexta) { - vm.runtime._pushThread(rootBlockId, target); - } - } + + addeve(args, util) { + let el = document.getElementById(`element${args.PAGE}${args.ID}`); + if (!el) return; + + // This clones the element and replaces the old one. + // Clones do NOT keep event listeners attached via addEventListener. + const newEl = el.cloneNode(true); + el.parentNode.replaceChild(newEl, el); + + el = newEl + const triggerText = args.ID; + const triggerTexta = args.PAGE; + + el.addEventListener(args.EVE, () => { + + const targetOpcode = 'htmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + // 1. Check if it's a Field (dropdown/fixed text) + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + // 2. Check if it's an Input (text bubble) + else if (block.inputs && block.inputs.ID) { + const input = block.inputs.ID; + const inputa = block.inputs.PAGE; + // Dig into the 'shadow' block which holds the text value + const shadowBlock = blocks.getBlock(input.shadow); + const shadowBlocka = blocks.getBlock(inputa.shadow); + if (shadowBlock && shadowBlock.fields && shadowBlock.fields.TEXT && shadowBlocka && shadowBlocka.fields && shadowBlocka.fields.TEXT) { + hatValue = shadowBlock.fields.TEXT.value; + hatValuea = shadowBlocka.fields.TEXT.value; + } + } + + // Compare and trigger + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); }); - }); - }); - } + } - remeve(args) { - const el = document.getElementById(`element${args.PAGE}${args.ID}`); - if (!el) return; - // This clones the element and replaces the old one. - // Clones do NOT keep event listeners attached via addEventListener. - const newEl = el.cloneNode(true); - el.parentNode.replaceChild(newEl, el); - } + remeve(args) { + const el = document.getElementById(`element${args.PAGE}${args.ID}`); + if (!el) return; + // This clones the element and replaces the old one. + // Clones do NOT keep event listeners attached via addEventListener. + const newEl = el.cloneNode(true); + el.parentNode.replaceChild(newEl, el); + } - eve() { - return true; - } + eve() { + return true; + } - current(){ - return(this.viewing) + current() { + if (document.querySelector(".htmlpage")) { + return (JSON.stringify(this.viewing)) + } else { + return ('') + } + } } -} - - Scratch.extensions.register(new HTMLtoCanvas(Scratch.runtime)); + + Scratch.extensions.register(new HTMLtoCanvas(Scratch.runtime)); })(Scratch); From 2eff3ae620c3f160d5fc1bef017cde39a48af3bf Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Sat, 22 Aug 2026 18:06:26 -0400 Subject: [PATCH 09/26] Format if statements for consistency --- static/extensions/ScrTwPm/htmldocuments.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 568df3bd8..d0a0b4765 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -671,9 +671,9 @@ el.style.border = "1px solid black" const container = Scratch.renderer.canvas.parentElement; container.appendChild(el); - if(!this.viewing.includes(args.PAGE)){ - this.viewing.push(args.PAGE) - } + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } } catch (error) { } } @@ -928,7 +928,7 @@ el.style.border = "1px solid black" const container = Scratch.renderer.canvas.parentElement; container.appendChild(el); - if(!this.viewing.includes(args.PAGE)){ + if (!this.viewing.includes(args.PAGE)) { this.viewing.push(args.PAGE) } } @@ -954,7 +954,7 @@ el.style.border = "1px solid black" const container = Scratch.renderer.canvas.parentElement; container.appendChild(el); - if(!this.viewing.includes(args.PAGE)){ + if (!this.viewing.includes(args.PAGE)) { this.viewing.push(args.PAGE) } } @@ -983,7 +983,7 @@ el.style.border = "1px solid black" const container = Scratch.renderer.canvas.parentElement; container.appendChild(el); - if(!this.viewing.includes(args.PAGE)){ + if (!this.viewing.includes(args.PAGE)) { this.viewing.push(args.PAGE) } } From d7db603c21363b76564a5d1d7a4098e6018d64b6 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Tue, 25 Aug 2026 14:48:47 -0400 Subject: [PATCH 10/26] Refactor HTMLtoCanvas to use Map for pages --- static/extensions/ScrTwPm/htmldocuments.js | 446 ++++++++++----------- 1 file changed, 222 insertions(+), 224 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index d0a0b4765..4860f17c3 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -5,7 +5,7 @@ class HTMLtoCanvas { constructor(runtime) { // Initialize an array holding your default dropdown menu options - this.pages = {} + this.pages = new Map() this.changePx = [ "block-size", "border-block-end-width", @@ -112,7 +112,7 @@ } getInfo() { return { - id: 'htmldocuments', + id: 'scrtwpmhtmldocuments', name: 'HTML documents', color1: '#ff9900', blocks: [ @@ -477,7 +477,7 @@ } }, { - opcode: 'pagePos', + opcode: 'ppos', blockType: Scratch.BlockType.REPORTER, text: '[AXIS] of [PAGE]', disableMonitor: true, @@ -610,39 +610,32 @@ createPage(args, util) { if (!Object.keys(this.pages).includes(args.PAGE)) { - if (/[a-z0-9]/i.test(args.PAGE)) { - this.pages[args.PAGE] = { - "data": { - "x": 5, - "y": 5, - height: "350", - width: "470", - }, - "ids": [], - "code": "" - } + if (args.PAGE !== "") { + this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", "")) + console.log(this.pages) } else { - throw new Error("Name must contain at least one number or letter") + throw new Error("Name cannot be empty") } } } clearPage(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages[args.PAGE].code = "" - this.pages[args.PAGE].ids = [] - } + // //if (Object.keys(this.pages).includes(args.PAGE)) { + // let pages = this.pages + this.pages.get(args.PAGE)?.set("code", "") + this.pages.get(args.PAGE)?.set("ids", []) + // } } deletePage(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - delete this.pages[args.PAGE] - if (this.viewing.includes(args.PAGE)) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - } - + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.delete(args.PAGE) + if (this.viewing.includes(args.PAGE)) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); } + + // } } allPages() { return (JSON.stringify(Object.keys(this.pages))) @@ -659,15 +652,15 @@ const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); elements.forEach(el => el.remove()); const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages[args.PAGE].code) + el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) el.setAttribute("class", `htmlpage display${args.PAGE}`) el.style.position = 'absolute'; el.style.pointerEvents = 'auto'; el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) - el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) el.style.border = "1px solid black" const container = Scratch.renderer.canvas.parentElement; container.appendChild(el); @@ -690,143 +683,149 @@ } noNestEl(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - if (args.ID !== "") { - if (!this.pages[args.PAGE].ids.includes(args.ID)) { - this.pages[args.PAGE].ids.push(args.ID) - this.pages[args.PAGE].code += `<${args.EL} id="element${args.PAGE}${args.ID}">` - } else { - throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) - } + // //if (Object.keys(this.pages).includes(args.PAGE)) { + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + console.log(this.pages) + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + console.log(this.pages) } else { - this.pages[args.PAGE].code += `<${args.EL} >` + throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) } + } else { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) } + // } } nestEl(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - if (util.stackFrame.startedBranch) { - this.pages[args.PAGE].code += `` - - util.stackFrame.startedBranch = false; - return; - } - if (args.ID !== "") { - if (!this.pages[args.PAGE].ids.includes(args.ID)) { - this.pages[args.PAGE].ids.push(args.ID) - this.pages[args.PAGE].code += `<${args.EL} id="element${args.PAGE}${args.ID}">` - } else { - throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + if (util.stackFrame.startedBranch) { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + console.log(this.pages) + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + console.log(this.pages) } else { - this.pages[args.PAGE].code += `<${args.EL} >` + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) } - util.stackFrame.startedBranch = true; - util.startBranch(1, true); + } else { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) } + util.stackFrame.startedBranch = true; + util.startBranch(1, true); + // } } text(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages[args.PAGE].code += `${args.TEXT}` - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${args.TEXT}`) + // } } removeEl(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - if (this.pages[args.PAGE].ids.includes(args.ID)) { - let text = this.pages[args.PAGE].code - let startWord = ``; - let endWord = ``; - let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); - let result = text.replace(regex, '$1 $3'); - result = result.replace(``, "").replace(``, "") - this.pages[args.PAGE].code = (result); - let num = (this.pages[args.PAGE].ids.indexOf(args.ID)) - this.pages[args.PAGE].ids.splice(num, 1) - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + if (this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + console.log(this.pages) + let text = this.pages.get(args.PAGE).get("code") + let startWord = ``; + let endWord = ``; + let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); + let result = text.replace(regex, '$1 $3'); + result = result.replace(``, "").replace(``, "") + console.log(this.pages) + this.pages.get(args.PAGE).set("code", result); + let num = (this.pages.get(args.PAGE).get("ids").indexOf(args.ID)) + this.pages.get(args.PAGE).get("ids").splice(num, 1) + console.log(this.pages) } + // } } styleEl(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { + //if (Object.keys(this.pages).includes(args.PAGE)) { - if (util.stackFrame.startedBranch) { - this.pages[args.PAGE].code += `` + if (util.stackFrame.startedBranch) { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) - util.stackFrame.startedBranch = false; - return; - } + util.stackFrame.startedBranch = false; + return; + } - const blockContainer = util.thread.blockContainer; - const currentBlockId = util.thread.peekStack(); // - const currentBlock = blockContainer.getBlock(currentBlockId); - if (currentBlock) { - currentBlock.stylePage = { - page: args.PAGE, - compiledScope: 'global', - }; - } - this.pages[args.PAGE].code += `` + // if (util.stackFrame.startedBranch) { + // //do after + // this.pages[args.PAGE].code += `` - // util.stackFrame.startedBranch = false; - // return; - // } - // //do before - // const blockContainer = util.thread.blockContainer; - // const currentBlockId = util.thread.peekStack(); // - // const currentBlock = blockContainer.getBlock(currentBlockId); - // if (currentBlock) { - // currentBlock.stylePage = { - // page: args.PAGE, - // compiledScope: 'global', - // }; + // util.stackFrame.startedBranch = false; + // return; + // } + // //do before + // const blockContainer = util.thread.blockContainer; + // const currentBlockId = util.thread.peekStack(); // + // const currentBlock = blockContainer.getBlock(currentBlockId); + // if (currentBlock) { + // currentBlock.stylePage = { + // page: args.PAGE, + // compiledScope: 'global', + // }; - // this.pages[args.PAGE].code += `` + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) // } // } else { @@ -874,120 +873,119 @@ remallstyle(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { + //if (Object.keys(this.pages).includes(args.PAGE)) { - let result = this.pages[args.PAGE].code; + let result = this.pages.get(args.PAGE).get("code"); - const startWord = ""; - const endWord = ""; + const startWord = ""; + const endWord = ""; - const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); + const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); - this.pages[args.PAGE].code = result.replace(regex, ''); - } + this.pages.get(args.PAGE).set("code", result.replace(regex, '')) + // } } setAttr(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - if (args.ID !== "") { - let text = this.pages[args.PAGE].code; - let newText = ` ${args.ATTR}="${args.VAL}"`; - let newReg = new RegExp(`([^>]+)`); - let updatedString = text.replace(newReg, `$1${newText}`); - this.pages[args.PAGE].code = updatedString; - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + if (args.ID !== "") { + let text = this.pages.get(args.PAGE).get("code"); + let newText = ` ${args.ATTR}="${args.VAL}"`; + let newReg = new RegExp(`([^>]+)`); + let updatedString = text.replace(newReg, `$1${newText}`); + this.pages.get(args.PAGE).set("code", updatedString) } + // } } - pagePos(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - return (this.pages[args.PAGE].data[args.AXIS]) + ppos(args, util) { + if ((this.pages).has(args.PAGE)) { + return (this.pages.get(args.PAGE).get("data").get(args.AXIS)) } else { return ('Page does not exist!') } } movePage(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages[args.PAGE].data.x = args.X - this.pages[args.PAGE].data.y = args.Y - console - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages[args.PAGE].code) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) - el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE).get("data").set("x", args.X) + this.pages.get(args.PAGE).get("data").set("y", args.Y) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) } } + // } } resizePage(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages[args.PAGE].data.width = args.X - this.pages[args.PAGE].data.height = args.Y - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages[args.PAGE].code) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) - el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE).get("data").set("width", args.X) + this.pages.get(args.PAGE).get("data").set("height", args.Y) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) } } + // } } resetDefault(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages[args.PAGE].data.width = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10 - this.pages[args.PAGE].data.height = Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10 - this.pages[args.PAGE].data.x = 5 - this.pages[args.PAGE].data.y = 5 - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages[args.PAGE].code) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages[args.PAGE].data.x}px`; - el.style.top = `${this.pages[args.PAGE].data.y}px`; - el.setAttribute("width", `${this.pages[args.PAGE].data.width}px`) - el.setAttribute("height", `${this.pages[args.PAGE].data.height}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE).get("data").set("width", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10) + this.pages.get(args.PAGE).get("data").set("height", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10) + this.pages.get(args.PAGE).get("data").set("x", 5) + this.pages.get(args.PAGE).get("data").set("y", 5) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) } } + // } } spw(args, util) { @@ -1021,8 +1019,8 @@ getHTML(args, util) { - if (Object.keys(this.pages).includes(args.PAGE)) { - let el = this.pages[args.PAGE].code; + if ((this.pages).has(args.PAGE)) { + let el = this.pages.get(args.PAGE).get("code"); let cleanString = el.replace(//g, ""); let toChange = `${cleanString}` return (this.prettierInText(toChange)) @@ -1047,7 +1045,7 @@ el.addEventListener(args.EVE, () => { - const targetOpcode = 'htmldocuments_eve'; + const targetOpcode = 'scrtwpmhtmldocuments_eve'; const vm = Scratch.vm; vm.runtime.targets.forEach(target => { @@ -1107,7 +1105,7 @@ if (document.querySelector(".htmlpage")) { return (JSON.stringify(this.viewing)) } else { - return ('') + return ('[]') } } } From e9b09b1e468da05616c48273d49de28dffee8de3 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Tue, 25 Aug 2026 16:23:15 -0400 Subject: [PATCH 11/26] removed access to add script tags in text --- static/extensions/ScrTwPm/htmldocuments.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 4860f17c3..3ac666337 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -1,6 +1,8 @@ (function (Scratch) { 'use strict'; + const dom = new DOMParser() + const toAString = new XMLSerializer() class HTMLtoCanvas { constructor(runtime) { @@ -726,7 +728,11 @@ text(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${args.TEXT}`) + let text = document.createRange().createContextualFragment(args.TEXT) + const elements = text.querySelectorAll(`script`); + elements.forEach(el => el.remove()); + text = toAString.serializeToString(text) + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${text}`) // } } From 79425e8cfa22abb7b9258f51d9412cc1b6f9118e Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 17:41:57 -0400 Subject: [PATCH 12/26] converted to DOM --- static/extensions/ScrTwPm/htmldocuments.js | 1005 +++++++++++++++----- 1 file changed, 790 insertions(+), 215 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 3ac666337..dca3102d1 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -4,7 +4,7 @@ const dom = new DOMParser() const toAString = new XMLSerializer() - class HTMLtoCanvas { + class HTMLDocuments { constructor(runtime) { // Initialize an array holding your default dropdown menu options this.pages = new Map() @@ -312,6 +312,7 @@ }, + { blockType: Scratch.BlockType.LABEL, text: "CSS Styles" }, // { @@ -613,7 +614,8 @@ createPage(args, util) { if (!Object.keys(this.pages).includes(args.PAGE)) { if (args.PAGE !== "") { - this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", "")) + // this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", "")) + this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", dom.parseFromString("", 'text/html')).set("eves", new Map())) console.log(this.pages) } else { throw new Error("Name cannot be empty") @@ -624,8 +626,10 @@ // //if (Object.keys(this.pages).includes(args.PAGE)) { // let pages = this.pages - this.pages.get(args.PAGE)?.set("code", "") + + this.pages.get(args.PAGE)?.set("code", dom.parseFromString("", 'text/html')) this.pages.get(args.PAGE)?.set("ids", []) + this.pages.get(args.PAGE)?.set("eves", new Map()) // } } deletePage(args, util) { @@ -650,26 +654,85 @@ displayPage(args, util) { - try { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; - el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; - el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) - el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } - } catch (error) { } + return new Promise((resolve, reject) => { + try { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + } + + ) + + + } + } + } catch (error) { } + resolve(); + }); } hidePageAll(args, util) { @@ -685,69 +748,344 @@ } noNestEl(args, util) { - // //if (Object.keys(this.pages).includes(args.PAGE)) { - if (args.ID !== "") { - if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { - console.log(this.pages) - this.pages.get(args.PAGE)?.get("ids").push(args.ID) - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) - console.log(this.pages) + if ((this.pages).has(args.PAGE)) { + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + // console.log(this.pages) + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); + const currentBlock = blockContainer.getBlock(currentBlockId); + const target = util.thread.target; + + + + let parentBlockId = "" + let parentBlock = "" + + + let childId = currentBlockId; + let blockId = target.blocks.getBlock(currentBlockId)?.parent; + + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + ]; + // let blockId = currentBlockId; + + + + + + + while (blockId) { + const parentBlock = target.blocks.getBlock(blockId); + // if (!parentBlock) break; + console.log(parentBlock) + + if (loopOpcodes.includes(parentBlock.opcode)) { + + + const substackId = parentBlock.inputs?.SUBSTACK?.block; + // const substack2Id = parentBlock.inputs?.SUBSTACK2?.block; + + // console.log(parentBlock) + + if (substackId === childId) { + + console.log(`found by ${args.ID}`) + parentBlockId = blockId; + console.log("pbid", parentBlockId) + const pB = blockContainer.getBlock(parentBlockId) + nest = pB.el.el + console.log("nest", nest) + + + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + return + } + + if (substackId) { + let checkId = substackId; + while (checkId) { + if (checkId === childId) return blockId; + checkId = target.blocks.getBlock(checkId)?.next; + } + } + + // if (substack2Id) { + // let checkId = substack2Id; + // while (checkId) { + // if (checkId === childId) return blockId; + // checkId = target.blocks.getBlock(checkId)?.next; + // } + // } + } + childId = blockId; + blockId = parentBlock.parent; + } + // console.log("cb", currentBlock) + // console.log("Parent is", currentBlock.parent) + // if (currentBlock && currentBlock.parent){ + // const parentBlockId = currentBlock.parent; + // const parentBlock = blockContainer.getBlock(parentBlockId) + // if(parentBlock && parentBlock.el){ + // console.log("el", parentBlock.el) + // nest = parentBlock.el.el + // } + // } + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // console.log(`nest is`, nest) + + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + } else { + throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + } } else { - throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + throw new Error(`Element must have an id`) + + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) } - } else { - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) } - // } } nestEl(args, util) { - //if (Object.keys(this.pages).includes(args.PAGE)) { - if (util.stackFrame.startedBranch) { - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) - console.log(this.pages) - util.stackFrame.startedBranch = false; - return; - } - if (args.ID !== "") { - if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { - this.pages.get(args.PAGE)?.get("ids").push(args.ID) - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) - console.log(this.pages) + if ((this.pages).has(args.PAGE)) { + if (util.stackFrame.startedBranch) { + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + if (currentBlock) { + currentBlock.el = { + el: args.ID, + compiledScope: 'global', + }; + } + // console.log(this.pages) + + const target = util.thread.target; + + + let parentBlockId = "" + let parentBlock = "" + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + ]; + let blockId = currentBlockId; + while (blockId) { + const block = target.blocks.getBlock(blockId); + if (!block) break; + + if (loopOpcodes.includes(block.opcode) && block !== currentBlock) { + // blockId = block.parent; + console.log(`found by ${args.ID}`) + parentBlockId = block; + console.log(parentBlockId) + parentBlock = blockContainer.getBlock(parentBlockId) + nest = parentBlockId.el.el + console.log("nest is", nest) + + + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + + + util.stackFrame.startedBranch = true; + util.startBranch(1); + return + + + + } + + blockId = block.parent; // Move to the parent block [3] + + } + // console.log("cb", currentBlock) + // if (currentBlock && currentBlock.parent && currentBlock.parent.el){ + // nest = currentBlock.parent.el + // } + // console.log(this.pages) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + } else { + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + } } else { - throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + throw new Error(`Element must have an id`) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) } - } else { - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + util.stackFrame.startedBranch = true; + util.startBranch(1, true); } - util.stackFrame.startedBranch = true; - util.startBranch(1, true); - // } } text(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { - let text = document.createRange().createContextualFragment(args.TEXT) - const elements = text.querySelectorAll(`script`); - elements.forEach(el => el.remove()); - text = toAString.serializeToString(text) - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${text}`) + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${text}`) + + + + if ((this.pages).has(args.PAGE)) { + // if (args.ID !== "") { + // if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + // console.log(this.pages) + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); + const currentBlock = blockContainer.getBlock(currentBlockId); + const target = util.thread.target; + + + + let parentBlockId = "" + let parentBlock = "" + + + let childId = currentBlockId; + let blockId = target.blocks.getBlock(currentBlockId)?.parent; + + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + ]; + // let blockId = currentBlockId; + + + + + + + while (blockId) { + const parentBlock = target.blocks.getBlock(blockId); + // if (!parentBlock) break; + console.log(parentBlock) + + if (loopOpcodes.includes(parentBlock.opcode)) { + + + const substackId = parentBlock.inputs?.SUBSTACK?.block; + // const substack2Id = parentBlock.inputs?.SUBSTACK2?.block; + + // console.log(parentBlock) + + if (substackId === childId) { + + console.log(`found by ${args.ID}`) + parentBlockId = blockId; + console.log("pbid", parentBlockId) + const pB = blockContainer.getBlock(parentBlockId) + nest = pB.el.el + console.log("nest", nest) + + + this.pages.get(args.PAGE)?.get("ids").push(args.ID) + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + + + let text = document.createRange().createContextualFragment(args.TEXT) + let elements = text.querySelectorAll(`script`); + elements.forEach(el => el.remove()); + text = toAString.serializeToString(text) + + + body.innerHTML += text + return + } + + if (substackId) { + let checkId = substackId; + while (checkId) { + if (checkId === childId) return blockId; + checkId = target.blocks.getBlock(checkId)?.next; + } + } + + // if (substack2Id) { + // let checkId = substack2Id; + // while (checkId) { + // if (checkId === childId) return blockId; + // checkId = target.blocks.getBlock(checkId)?.next; + // } + // } + } + childId = blockId; + blockId = parentBlock.parent; + } + // console.log("cb", currentBlock) + // console.log("Parent is", currentBlock.parent) + // if (currentBlock && currentBlock.parent){ + // const parentBlockId = currentBlock.parent; + // const parentBlock = blockContainer.getBlock(parentBlockId) + // if(parentBlock && parentBlock.el){ + // console.log("el", parentBlock.el) + // nest = parentBlock.el.el + // } + // } + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // console.log(`nest is`, nest) + + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + // } else { + // throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + // } + // } else { + // throw new Error(`Element must have an id`) + + // // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + // } + } + + + // } } removeEl(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { if (this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { - console.log(this.pages) - let text = this.pages.get(args.PAGE).get("code") - let startWord = ``; - let endWord = ``; - let regex = new RegExp(`(${startWord})(.*?)(${endWord})`); - let result = text.replace(regex, '$1 $3'); - result = result.replace(``, "").replace(``, "") - console.log(this.pages) - this.pages.get(args.PAGE).set("code", result); + + + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + let el = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) + // console.log(`body is`, body) + el.remove() + } + let num = (this.pages.get(args.PAGE).get("ids").indexOf(args.ID)) this.pages.get(args.PAGE).get("ids").splice(num, 1) console.log(this.pages) @@ -852,6 +1190,7 @@ // const parentBlock = blockContainer.getBlock(parentBlockId); let px = this.changePx let value = "" + console.log(px) if (px.includes(args.VALUE)) { if (!containsCssUnit(args.VALUE)) { value = `${args.VALUE}px` @@ -863,10 +1202,19 @@ } // if (parentBlock.stylePage && parentBlock) { - let page = args.PAGE//parentBlock.stylePage.page - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + + console.log(value) + if (!this.pages.get(args.PAGE)?.get("code").querySelector("style")) { + let body = this.pages.get(args.PAGE)?.get("code").querySelector("head") + // console.log(`body is`, body) + let el = document.createElement("style") + el.innerHTML = `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` + el = body.appendChild(el) + } else { + let el = this.pages.get(args.PAGE)?.get("code").querySelector("style") + el.innerHTML += `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value}};` + } + // } // } else { @@ -881,25 +1229,27 @@ remallstyle(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { - let result = this.pages.get(args.PAGE).get("code"); - const startWord = ""; - const endWord = ""; - - const regex = new RegExp(`${startWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}.*?${endWord.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')}`, 'gs'); + if (this.pages.get(args.PAGE)?.get("code").querySelector(`style`)) { + let el = this.pages.get(args.PAGE)?.get("code").querySelector(`style`) + // console.log(`body is`, body) + el.remove() + } - this.pages.get(args.PAGE).set("code", result.replace(regex, '')) // } } setAttr(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { if (args.ID !== "") { - let text = this.pages.get(args.PAGE).get("code"); - let newText = ` ${args.ATTR}="${args.VAL}"`; - let newReg = new RegExp(`([^>]+)`); - let updatedString = text.replace(newReg, `$1${newText}`); - this.pages.get(args.PAGE).set("code", updatedString) + + + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + let el = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) + // console.log(`body is`, body) + el.setAttribute(args.ATTR, args.VAL) + + } } // } } @@ -914,84 +1264,274 @@ movePage(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages.get(args.PAGE).get("data").set("x", args.X) - this.pages.get(args.PAGE).get("data").set("y", args.Y) - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; - el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; - el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) - el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } - } - // } + return new Promise((resolve, reject) => { + try { + this.pages.get(args.PAGE).get("data").set("x", args.X) + this.pages.get(args.PAGE).get("data").set("y", args.Y) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } + } + // } + + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + } + + ) + + + } + } + } catch (error) { } + resolve(); + }); + + } resizePage(args, util) { - //if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages.get(args.PAGE).get("data").set("width", args.X) - this.pages.get(args.PAGE).get("data").set("height", args.Y) - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; - el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; - el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) - el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } - } - // } + + return new Promise((resolve, reject) => { + try { + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE).get("data").set("width", args.X) + this.pages.get(args.PAGE).get("data").set("height", args.Y) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } + } + // } + + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + } + + ) + + + } + } + } catch (error) { } + resolve(); + }); } resetDefault(args, util) { - //if (Object.keys(this.pages).includes(args.PAGE)) { - this.pages.get(args.PAGE).get("data").set("width", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10) - this.pages.get(args.PAGE).get("data").set("height", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10) - this.pages.get(args.PAGE).get("data").set("x", 5) - this.pages.get(args.PAGE).get("data").set("y", 5) - if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { - const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); - elements.forEach(el => el.remove()); - const el = document.createElement("iframe"); - el.setAttribute("srcdoc", this.pages.get(args.PAGE).get("code")) - el.setAttribute("class", `htmlpage display${args.PAGE}`) - el.style.position = 'absolute'; - el.style.pointerEvents = 'auto'; - el.style.zIndex = '10'; - el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; - el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; - el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) - el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) - el.style.border = "1px solid black" - const container = Scratch.renderer.canvas.parentElement; - container.appendChild(el); - if (!this.viewing.includes(args.PAGE)) { - this.viewing.push(args.PAGE) - } - } - // } + + return new Promise((resolve, reject) => { + try { + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.get(args.PAGE).get("data").set("width", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).width.replace("px", "")) - 10) + this.pages.get(args.PAGE).get("data").set("height", Number(window.getComputedStyle(Scratch.renderer.canvas.parentElement).height.replace("px", "")) - 10) + this.pages.get(args.PAGE).get("data").set("x", 5) + this.pages.get(args.PAGE).get("data").set("y", 5) + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } + } + // } + + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + } + + ) + + + } + } + } catch (error) { } + resolve(); + }); } spw(args, util) { @@ -1003,9 +1543,6 @@ } prettierInText(html) { - /* - This function is AI generated. It formats the code for better readability when getting the html of a page. Tell me if this needs to go or if there's a better way to do this. Is this what the dom parser is for??? - */ let clean = html.replace(/\s*([<>])\s*/g, '$1').replace(/\s+/g, ' '); let reg = /(<[^>]+>)/g; let matches = clean.split(reg).filter(Boolean); @@ -1026,10 +1563,13 @@ getHTML(args, util) { if ((this.pages).has(args.PAGE)) { - let el = this.pages.get(args.PAGE).get("code"); - let cleanString = el.replace(//g, ""); + let doc = this.pages.get(args.PAGE).get("code") + let el = toAString.serializeToString(doc) + // let el = this.pages.get(args.PAGE).get("code"); + let cleanString = el.replace(//g, "").replace(/xmlns="[\s\S]*?"/g, ""); let toChange = `${cleanString}` - return (this.prettierInText(toChange)) + + return (this.prettierInText(cleanString)) } else { return ('Page does not exist!') } @@ -1037,69 +1577,104 @@ addeve(args, util) { - let el = document.getElementById(`element${args.PAGE}${args.ID}`); - if (!el) return; - - // This clones the element and replaces the old one. - // Clones do NOT keep event listeners attached via addEventListener. - const newEl = el.cloneNode(true); - el.parentNode.replaceChild(newEl, el); - - el = newEl - const triggerText = args.ID; - const triggerTexta = args.PAGE; - - el.addEventListener(args.EVE, () => { - - const targetOpcode = 'scrtwpmhtmldocuments_eve'; - const vm = Scratch.vm; - - vm.runtime.targets.forEach(target => { - const blocks = target.blocks; - const scripts = blocks.getScripts(); + let el = this.pages.get(args.PAGE)?.get("code").getElementById(`element${args.PAGE}${args.ID}`); + if (!el) throw new Error(`An element with the id "${args.ID}" doesn't exist in the page`); + this.pages.get(args.PAGE)?.get("eves").set(args.ID, args.EVE) + // console.log(this.pages.get(args.PAGE)?.get("eves")) + } - scripts.forEach(rootBlockId => { - const block = blocks.getBlock(rootBlockId); + remeve(args) { + let el = this.pages.get(args.PAGE)?.get("code").getElementById(`element${args.PAGE}${args.ID}`); + if (!el) return; + this.pages.get(args.PAGE)?.get("eves").delete(args.ID) - if (block && block.opcode === targetOpcode) { - let hatValue = ''; - let hatValuea = ''; - // 1. Check if it's a Field (dropdown/fixed text) - if (block.fields && block.fields.ID && block.fields.PAGE) { - hatValue = block.fields.ID.value; - hatValuea = block.fields.PAGE.value; + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + return new Promise((resolve, reject) => { + try { + //if (Object.keys(this.pages).includes(args.PAGE)) { + if (this.viewing.includes(args.PAGE) && document.querySelector(".htmlpage")) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) } - // 2. Check if it's an Input (text bubble) - else if (block.inputs && block.inputs.ID) { - const input = block.inputs.ID; - const inputa = block.inputs.PAGE; - // Dig into the 'shadow' block which holds the text value - const shadowBlock = blocks.getBlock(input.shadow); - const shadowBlocka = blocks.getBlock(inputa.shadow); - if (shadowBlock && shadowBlock.fields && shadowBlock.fields.TEXT && shadowBlocka && shadowBlocka.fields && shadowBlocka.fields.TEXT) { - hatValue = shadowBlock.fields.TEXT.value; - hatValuea = shadowBlocka.fields.TEXT.value; + } + // } + + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); } - } - // Compare and trigger - if (hatValue === triggerText && hatValuea === triggerTexta) { - vm.runtime._pushThread(rootBlockId, target); + ) + + } } - }); + } catch (error) { } + resolve(); }); - }); - } - - remeve(args) { - const el = document.getElementById(`element${args.PAGE}${args.ID}`); - if (!el) return; - // This clones the element and replaces the old one. - // Clones do NOT keep event listeners attached via addEventListener. - const newEl = el.cloneNode(true); - el.parentNode.replaceChild(newEl, el); + } } @@ -1116,5 +1691,5 @@ } } - Scratch.extensions.register(new HTMLtoCanvas(Scratch.runtime)); + Scratch.extensions.register(new HTMLDocuments(Scratch.runtime)); })(Scratch); From 0089c673d6ff7dc3b29b28c43a3bbc10ae9c63eb Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 19:17:43 -0400 Subject: [PATCH 13/26] Refactor HTMLDocuments class to remove 'ids' property Refactor HTMLDocuments class to remove unused 'ids' property and update related methods to use 'code' for element queries. --- static/extensions/ScrTwPm/htmldocuments.js | 227 +++++++++++++++++++-- 1 file changed, 213 insertions(+), 14 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index dca3102d1..5156354eb 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -6,7 +6,6 @@ class HTMLDocuments { constructor(runtime) { - // Initialize an array holding your default dropdown menu options this.pages = new Map() this.changePx = [ "block-size", @@ -313,6 +312,27 @@ }, + { + opcode: 'changeHTML', + blockType: Scratch.BlockType.CONDITIONAL, + text: 'change [ID] in [PAGE] to', + arguments: { + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: "new-el" + }, + EL: { + type: Scratch.ArgumentType.STRING, + menu: "nonest", + defaultValue: "input" + }, + } + }, + { blockType: Scratch.BlockType.LABEL, text: "CSS Styles" }, // { @@ -420,6 +440,40 @@ } }, + { blockType: Scratch.BlockType.LABEL, text: "Webpage Data" }, + + { + opcode: 'allEls', + blockType: Scratch.BlockType.REPORTER, + text: 'all elements in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + } + }, + { + opcode: 'dataEl', + blockType: Scratch.BlockType.REPORTER, + text: '[OPTS] [ID] in [PAGE]', + arguments: { + EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, + PAGE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "my-page" + }, + OPTS: { + type: Scratch.ArgumentType.STRING, + menu: "opts" + }, + } + }, + + { blockType: Scratch.BlockType.LABEL, text: "Webpage Positioning" }, { @@ -532,6 +586,26 @@ // {text: "animation", value: "@keyframes "}, ] }, + opts: { + acceptReporters: false, + items: [ + { text: "inner HTML", value: "innerHTML" }, + { text: "text content", value: "textContent" }, + { text: "children", value: "children" }, + { text: "parent element", value: "parentElement" }, + { text: "tag name", value: "tagName" }, + // { text: "style", value: "style" }, + { text: "value", value: "value" }, + { text: "checked", value: "checked" }, + { text: "class list", value: "classList" }, + { text: "offset width", value: "offsetWidth" }, + { text: "offset height", value: "offsetHeight" }, + { text: "scroll width", value: "scrollWidth" }, + { text: "scroll height", value: "scrollHeight" }, + { text: "disabled", value: "disabled" }, + // { text: "all data of", value: "all" }, + ] + }, properties: { acceptReporters: true, items: [ @@ -614,8 +688,7 @@ createPage(args, util) { if (!Object.keys(this.pages).includes(args.PAGE)) { if (args.PAGE !== "") { - // this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", "")) - this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("ids", []).set("code", dom.parseFromString("", 'text/html')).set("eves", new Map())) + this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("code", dom.parseFromString("", 'text/html')).set("eves", new Map())) console.log(this.pages) } else { throw new Error("Name cannot be empty") @@ -628,7 +701,6 @@ // let pages = this.pages this.pages.get(args.PAGE)?.set("code", dom.parseFromString("", 'text/html')) - this.pages.get(args.PAGE)?.set("ids", []) this.pages.get(args.PAGE)?.set("eves", new Map()) // } } @@ -750,7 +822,7 @@ noNestEl(args, util) { if ((this.pages).has(args.PAGE)) { if (args.ID !== "") { - if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { // console.log(this.pages) const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); @@ -769,6 +841,7 @@ let nest = "" const loopOpcodes = [ 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', ]; // let blockId = currentBlockId; @@ -800,7 +873,6 @@ console.log("nest", nest) - this.pages.get(args.PAGE)?.get("ids").push(args.ID) let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) // console.log(`body is`, body) let el = document.createElement(args.EL) @@ -867,7 +939,7 @@ return; } if (args.ID !== "") { - if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); // const currentBlock = blockContainer.getBlock(currentBlockId); @@ -887,6 +959,7 @@ let nest = "" const loopOpcodes = [ 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', ]; let blockId = currentBlockId; while (blockId) { @@ -903,7 +976,6 @@ console.log("nest is", nest) - this.pages.get(args.PAGE)?.get("ids").push(args.ID) let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) // console.log(`body is`, body) let el = document.createElement(args.EL) @@ -928,7 +1000,6 @@ // } // console.log(this.pages) // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) - this.pages.get(args.PAGE)?.get("ids").push(args.ID) let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) // console.log(`body is`, body) let el = document.createElement(args.EL) @@ -949,6 +1020,97 @@ } + changeHTML(args, util) { + if ((this.pages).has(args.PAGE)) { + if (util.stackFrame.startedBranch) { + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + if (currentBlock) { + currentBlock.el = { + el: args.ID, + compiledScope: 'global', + }; + } + let body = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) + body.innerHTML = "" + // console.log(this.pages) + + // const target = util.thread.target; + + + // let parentBlockId = "" + // let parentBlock = "" + // let nest = "" + // const loopOpcodes = [ + // 'scrtwpmhtmldocuments_nestEl', + // ]; + // let blockId = currentBlockId; + // while (blockId) { + // const block = target.blocks.getBlock(blockId); + // if (!block) break; + + // if (loopOpcodes.includes(block.opcode) && block !== currentBlock) { + // // blockId = block.parent; + // console.log(`found by ${args.ID}`) + // parentBlockId = block; + // console.log(parentBlockId) + // parentBlock = blockContainer.getBlock(parentBlockId) + // nest = parentBlockId.el.el + // console.log("nest is", nest) + + + // // let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // // // console.log(`body is`, body) + // // let el = document.createElement(args.EL) + // // el.setAttribute("id", `element${args.PAGE}${args.ID}`) + // // el = body.appendChild(el) + + + // util.stackFrame.startedBranch = true; + // util.startBranch(1); + // return + + + + // } + + // blockId = block.parent; // Move to the parent block [3] + + // } + // console.log("cb", currentBlock) + // if (currentBlock && currentBlock.parent && currentBlock.parent.el){ + // nest = currentBlock.parent.el + // } + // console.log(this.pages) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // // console.log(`body is`, body) + // let el = document.createElement(args.EL) + // el.setAttribute("id", `element${args.PAGE}${args.ID}`) + // el = body.appendChild(el) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + } else { + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + } + } else { + throw new Error(`Element must have an id`) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + } + util.stackFrame.startedBranch = true; + util.startBranch(1, true); + } + } + text(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { @@ -958,7 +1120,7 @@ if ((this.pages).has(args.PAGE)) { // if (args.ID !== "") { - // if (!this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + // if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { // console.log(this.pages) const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); @@ -977,6 +1139,8 @@ let nest = "" const loopOpcodes = [ 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', + ]; // let blockId = currentBlockId; @@ -1008,7 +1172,6 @@ console.log("nest", nest) - this.pages.get(args.PAGE)?.get("ids").push(args.ID) let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) // console.log(`body is`, body) @@ -1077,7 +1240,7 @@ removeEl(args, util) { //if (Object.keys(this.pages).includes(args.PAGE)) { - if (this.pages.get(args.PAGE)?.get("ids").includes(args.ID)) { + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { @@ -1086,8 +1249,6 @@ el.remove() } - let num = (this.pages.get(args.PAGE).get("ids").indexOf(args.ID)) - this.pages.get(args.PAGE).get("ids").splice(num, 1) console.log(this.pages) } // } @@ -1677,6 +1838,44 @@ } } + allEls(args, util) { + if (this.pages.has(args.PAGE)) { + const allIds = Array.from(this.pages.get(args.PAGE).get("code").querySelectorAll('[id]:not([id=""])')) + .map(element => element.id.replace(`element${args.PAGE}`, "")); + return (JSON.stringify(allIds)); + } else { + return ('[]') + } + } + + dataEl(args, util) { + try { + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + switch (args.OPTS) { + case "children": + return ([...this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)[args.OPTS]].map(child => child.id).filter(id => id !== "")) + case "parentElement": + return (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)[args.OPTS].getAttribute("id") ?? this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)[args.OPTS].tagName) + default: + if (args.OPTS !== "innerHTML") { + if (this.viewing.includes(args.PAGE)) { + return (document.querySelector(`.htmlpage.display${args.PAGE}`).contentDocument.querySelector(`#element${args.PAGE}${args.ID}`)[args.OPTS] ?? "") + } else { + return ("Display the page to use these.") + } + } else { + return (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)[args.OPTS] ?? "") + } + + } + } else { + return (`An element with the id "${args.ID}" doesn't exist in the page`) + } + } catch (error) { return ("") } + } + + + eve() { return true; From f0c6b260d20c6186cf2a51988303d7c454d05c4d Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 19:30:03 -0400 Subject: [PATCH 14/26] fixed all pages --- static/extensions/ScrTwPm/htmldocuments.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 5156354eb..f64798e18 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -458,7 +458,7 @@ { opcode: 'dataEl', blockType: Scratch.BlockType.REPORTER, - text: '[OPTS] [ID] in [PAGE]', + text: '[OPTS] of [ID] in [PAGE]', arguments: { EVE: { type: Scratch.ArgumentType.STRING, menu: 'eves', defaultValue: 'click' }, ID: { type: Scratch.ArgumentType.STRING, defaultValue: 'new-el' }, @@ -716,7 +716,7 @@ // } } allPages() { - return (JSON.stringify(Object.keys(this.pages))) + return (JSON.stringify(Array.from(this.pages.keys()))) } get() { if (Object.keys(this.pages).includes("my-page")) { @@ -1373,7 +1373,7 @@ el = body.appendChild(el) } else { let el = this.pages.get(args.PAGE)?.get("code").querySelector("style") - el.innerHTML += `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value}};` + el.innerHTML += `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` } // } From 95be9742ad0e3b8475e4cc37a3312037737f6f01 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 19:31:25 -0400 Subject: [PATCH 15/26] prettier! --- static/extensions/ScrTwPm/htmldocuments.js | 77 +++++++++++----------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index f64798e18..f1a3a6fd0 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -1335,55 +1335,56 @@ } property(args, util) { + if (this.pages.has(args.PAGE)) { + function containsCssUnit(str) { + const cssUnitsPattern = /\d+(?:px|em|rem|ex|ch|vw|vh|vmin|vmax|cm|mm|in|pt|pc|Q|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx|%)\b/i; + return cssUnitsPattern.test(str); + } - function containsCssUnit(str) { - const cssUnitsPattern = /\d+(?:px|em|rem|ex|ch|vw|vh|vmin|vmax|cm|mm|in|pt|pc|Q|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx|%)\b/i; - return cssUnitsPattern.test(str); - } + // const blockContainer = util.thread.blockContainer; + // const currentBlockId = util.thread.peekStack(); + // const currentBlock = blockContainer.getBlock(currentBlockId); - // const blockContainer = util.thread.blockContainer; - // const currentBlockId = util.thread.peekStack(); - // const currentBlock = blockContainer.getBlock(currentBlockId); - - // if (currentBlock) { - // if(currentBlock.parent){ - // const parentBlockId = currentBlock.parent; - // const parentBlock = blockContainer.getBlock(parentBlockId); - let px = this.changePx - let value = "" - console.log(px) - if (px.includes(args.VALUE)) { - if (!containsCssUnit(args.VALUE)) { - value = `${args.VALUE}px` + // if (currentBlock) { + // if(currentBlock.parent){ + // const parentBlockId = currentBlock.parent; + // const parentBlock = blockContainer.getBlock(parentBlockId); + let px = this.changePx + let value = "" + console.log(px) + if (px.includes(args.VALUE)) { + if (!containsCssUnit(args.VALUE)) { + value = `${args.VALUE}px` + } else { + value = args.VALUE + } } else { value = args.VALUE } - } else { - value = args.VALUE - } - // if (parentBlock.stylePage && parentBlock) { + // if (parentBlock.stylePage && parentBlock) { - console.log(value) - if (!this.pages.get(args.PAGE)?.get("code").querySelector("style")) { - let body = this.pages.get(args.PAGE)?.get("code").querySelector("head") - // console.log(`body is`, body) - let el = document.createElement("style") - el.innerHTML = `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` - el = body.appendChild(el) - } else { - let el = this.pages.get(args.PAGE)?.get("code").querySelector("style") - el.innerHTML += `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` - } + console.log(value) + if (!this.pages.get(args.PAGE)?.get("code").querySelector("style")) { + let body = this.pages.get(args.PAGE)?.get("code").querySelector("head") + // console.log(`body is`, body) + let el = document.createElement("style") + el.innerHTML = `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` + el = body.appendChild(el) + } else { + let el = this.pages.get(args.PAGE)?.get("code").querySelector("style") + el.innerHTML += `${args.TYPE}element${args.PAGE}${args.NAME}{${args.PROPERTY}:${value};}` + } - // } + // } - // } else { - // // throw new Error(`Just clicking this block won't do anything. You have to put it inside of an "add style to" loop first. The shape matches the shape of this block!`) - // } - // } + // } else { + // // throw new Error(`Just clicking this block won't do anything. You have to put it inside of an "add style to" loop first. The shape matches the shape of this block!`) + // } + // } + } } From 14cdadd78aeb2b82b20a4787e22b8dd4bfc8005d Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 19:39:00 -0400 Subject: [PATCH 16/26] fixed class setting --- static/extensions/ScrTwPm/htmldocuments.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index f1a3a6fd0..3cd2f8a38 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -1409,7 +1409,11 @@ if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { let el = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) // console.log(`body is`, body) - el.setAttribute(args.ATTR, args.VAL) + if(args.ATTR === "class"){ + el.setAttribute(args.ATTR, `element${args.PAGE}${args.VAL}`) + } else { + el.setAttribute(args.ATTR, args.VAL) + } } } From d458f2a66834bdf038cfce10a8cd1668ca97bcf0 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 20:14:18 -0400 Subject: [PATCH 17/26] big bug fix I just made a big change in how this works so there are a lot of things to fix --- static/extensions/ScrTwPm/htmldocuments.js | 95 ++++++++++++++++++++-- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index 3cd2f8a38..b3dd1c0f2 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -869,6 +869,7 @@ parentBlockId = blockId; console.log("pbid", parentBlockId) const pB = blockContainer.getBlock(parentBlockId) + if(pB && pB.el.bin.includes(currentBlockId)){ nest = pB.el.el console.log("nest", nest) @@ -879,6 +880,7 @@ el.setAttribute("id", `element${args.PAGE}${args.ID}`) el = body.appendChild(el) return + } } if (substackId) { @@ -917,6 +919,13 @@ // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) // console.log(this.pages) + + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) } else { throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) } @@ -943,10 +952,43 @@ const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); // const currentBlock = blockContainer.getBlock(currentBlockId); + let blocksInLoop = [] + function fn () { + const bc = util.thread.target.blocks; + const currentBlock = bc.getBlock(currentBlockId); + if (!currentBlock) return; + + // 3. Find the ID of the first block inside the loop's C-shaped slot (SUBSTACK) + const substackInput = currentBlock.inputs.SUBSTACK; + if (!substackInput || !substackInput.block) { + console.log("The loop branch is empty."); + return; + } + + const branchBlockIds = []; + let nextBlockId = substackInput.block; + + // 4. Follow the chain of linked blocks sequentially down the branch + while (nextBlockId) { + branchBlockIds.push(nextBlockId); + + const blockInfo = bc.getBlock(nextBlockId); + // Move down to the next block inline, stopping if there are no more + nextBlockId = blockInfo ? blockInfo.next : null; + } + + // 5. Output the list of specific IDs + blocksInLoop = (branchBlockIds); + console.log(blocksInLoop) + } + +fn() + if (currentBlock) { currentBlock.el = { el: args.ID, compiledScope: 'global', + bin: blocksInLoop }; } // console.log(this.pages) @@ -972,6 +1014,8 @@ parentBlockId = block; console.log(parentBlockId) parentBlock = blockContainer.getBlock(parentBlockId) + // const pB = blockContainer.getBlock(parentBlockId) + if(parentBlockId && parentBlockId.el.bin.includes(currentBlockId)){ nest = parentBlockId.el.el console.log("nest is", nest) @@ -986,7 +1030,7 @@ util.stackFrame.startedBranch = true; util.startBranch(1); return - + } } @@ -1034,10 +1078,41 @@ const blockContainer = util.thread.blockContainer; const currentBlockId = util.thread.peekStack(); // const currentBlock = blockContainer.getBlock(currentBlockId); + function fn () { + const bc = util.thread.target.blocks; + const currentBlock = bc.getBlock(currentBlockId); + if (!currentBlock) return; + + // 3. Find the ID of the first block inside the loop's C-shaped slot (SUBSTACK) + const substackInput = currentBlock.inputs.SUBSTACK; + if (!substackInput || !substackInput.block) { + console.log("The loop branch is empty."); + return; + } + + const branchBlockIds = []; + let nextBlockId = substackInput.block; + + // 4. Follow the chain of linked blocks sequentially down the branch + while (nextBlockId) { + branchBlockIds.push(nextBlockId); + + const blockInfo = bc.getBlock(nextBlockId); + // Move down to the next block inline, stopping if there are no more + nextBlockId = blockInfo ? blockInfo.next : null; + } + + // 5. Output the list of specific IDs + blocksInLoop = (branchBlockIds); + } + +fn() + if (currentBlock) { currentBlock.el = { el: args.ID, compiledScope: 'global', + bin: blocksInLoop }; } let body = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) @@ -1168,22 +1243,22 @@ parentBlockId = blockId; console.log("pbid", parentBlockId) const pB = blockContainer.getBlock(parentBlockId) + if(pB && pB.el.bin.includes(currentBlockId)){ nest = pB.el.el console.log("nest", nest) - let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) // console.log(`body is`, body) - let text = document.createRange().createContextualFragment(args.TEXT) let elements = text.querySelectorAll(`script`); elements.forEach(el => el.remove()); text = toAString.serializeToString(text) - - body.innerHTML += text + + console.log("BODY",body) return + } } if (substackId) { @@ -1231,6 +1306,16 @@ // // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) // // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) // } + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + + let text = document.createRange().createContextualFragment(args.TEXT) + let elements = text.querySelectorAll(`script`); + elements.forEach(el => el.remove()); + text = toAString.serializeToString(text) + body.innerHTML += text + } From 70d0d85f412362c0c753983f69038150714f5d27 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 20:20:16 -0400 Subject: [PATCH 18/26] ok maybe this is the last fix --- static/extensions/ScrTwPm/htmldocuments.js | 47 ++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index b3dd1c0f2..b4cbc4882 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -953,12 +953,10 @@ const currentBlockId = util.thread.peekStack(); // const currentBlock = blockContainer.getBlock(currentBlockId); let blocksInLoop = [] - function fn () { + function fn () { + const bc = util.thread.target.blocks; - const currentBlock = bc.getBlock(currentBlockId); - if (!currentBlock) return; - // 3. Find the ID of the first block inside the loop's C-shaped slot (SUBSTACK) const substackInput = currentBlock.inputs.SUBSTACK; if (!substackInput || !substackInput.block) { console.log("The loop branch is empty."); @@ -966,20 +964,37 @@ } const branchBlockIds = []; - let nextBlockId = substackInput.block; - // 4. Follow the chain of linked blocks sequentially down the branch - while (nextBlockId) { - branchBlockIds.push(nextBlockId); - - const blockInfo = bc.getBlock(nextBlockId); - // Move down to the next block inline, stopping if there are no more - nextBlockId = blockInfo ? blockInfo.next : null; - } + // Helper function to recursively collect block IDs down the chain + const scanChain = (startBlockId) => { + let nextBlockId = startBlockId; + + while (nextBlockId) { + branchBlockIds.push(nextBlockId); + + const blockInfo = blockContainer.getBlock(nextBlockId); + if (!blockInfo) break; + + // If this block is ANOTHER loop, dive inside its mouth first! + if (blockInfo.inputs && blockInfo.inputs.SUBSTACK && blockInfo.inputs.SUBSTACK.block) { + scanChain(blockInfo.inputs.SUBSTACK.block); + } + + // If it's an If-Else block, it might also have a SUBSTACK2 mouth + if (blockInfo.inputs && blockInfo.inputs.SUBSTACK2 && blockInfo.inputs.SUBSTACK2.block) { + scanChain(blockInfo.inputs.SUBSTACK2.block); + } + + // Move to the next block directly underneath + nextBlockId = blockInfo.next; + } + }; + + // Start scanning from the very first block inside your custom loop + scanChain(substackInput.block); + + blocksInLoop = branchBlockIds - // 5. Output the list of specific IDs - blocksInLoop = (branchBlockIds); - console.log(blocksInLoop) } fn() From b32cb8270fdc83da838b73c9766cbba379173aa2 Mon Sep 17 00:00:00 2001 From: ScrTwPm Date: Wed, 26 Aug 2026 20:29:17 -0400 Subject: [PATCH 19/26] more options for types --- static/extensions/ScrTwPm/htmldocuments.js | 2008 ++++++++++++++++++++ 1 file changed, 2008 insertions(+) diff --git a/static/extensions/ScrTwPm/htmldocuments.js b/static/extensions/ScrTwPm/htmldocuments.js index b4cbc4882..62a5e37ed 100644 --- a/static/extensions/ScrTwPm/htmldocuments.js +++ b/static/extensions/ScrTwPm/htmldocuments.js @@ -562,6 +562,2014 @@ } }, + ], + menus: { + nonest: { + acceptReporters: true, + items: + [ + "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "script", "source", "textarea", "track", "wbr" + ] + }, + nest: { + acceptReporters: true, + items: + [ + "a", "abbr", "address", "article", "aside", "audio", "b", "bdi", "bdo", "blockquote", "button", "canvas", "caption", "cite", "code", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "i", "iframe", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "menu", "meter", "nav", "object", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "slot", "small", "span", "strong", "sub", "summary", "sup", "table", "tbody", "td", "template", "tfoot", "th", "thead", "time", "tr", "u", "ul", "var", "video" + ] + }, + types: { + acceptReporters: false, + items: [ + { text: "id", value: "#" }, + { text: "class", value: "." }, + { text: "tag", value: "" }, + // {text: "animation", value: "@keyframes "}, + ] + }, + opts: { + acceptReporters: false, + items: [ + { text: "inner HTML", value: "innerHTML" }, + { text: "text content", value: "textContent" }, + { text: "children", value: "children" }, + { text: "parent element", value: "parentElement" }, + { text: "tag name", value: "tagName" }, + // { text: "style", value: "style" }, + { text: "value", value: "value" }, + { text: "checked", value: "checked" }, + { text: "class list", value: "classList" }, + { text: "offset width", value: "offsetWidth" }, + { text: "offset height", value: "offsetHeight" }, + { text: "scroll width", value: "scrollWidth" }, + { text: "scroll height", value: "scrollHeight" }, + { text: "disabled", value: "disabled" }, + // { text: "all data of", value: "all" }, + ] + }, + properties: { + acceptReporters: true, + items: [ + + 'align-content', 'align-items', 'align-self', 'all', 'animation', 'animation-delay', 'animation-direction', 'animation-duration', 'animation-fill-mode', 'animation-iter-count', 'animation-name', 'animation-play-state', 'animation-timing-fn', 'backface-visibility', 'background', 'background-attachment', 'background-blend-mode', 'background-clip', 'background-color', 'background-image', 'background-origin', 'background-position', 'background-repeat', 'background-size', 'border', 'border-bottom', 'border-bottom-color', 'border-bottom-left-rad', 'border-bottom-right-ra', 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-image', 'border-image-outset', 'border-image-repeat', 'border-image-slice', 'border-image-source', 'border-image-width', 'border-left', 'border-left-color', 'border-left-style', 'border-left-width', 'border-radius', 'border-right', 'border-right-color', 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-style', 'border-top-width', 'border-width', 'bottom', 'box-decoration-break', 'box-shadow', 'box-sizing', 'caption-side', 'caret-color', + 'clear', 'clip', 'clip-path', 'color', 'column-count', 'column-fill', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-style', 'column-rule-width', 'column-span', 'column-width', 'columns', 'content', 'counter-increment', 'counter-reset', 'cursor', 'direction', 'display', 'empty-cells', 'filter', 'flex', 'flex-basis', 'flex-direction', 'flex-flow', 'flex-grow', 'flex-shrink', 'flex-wrap', 'float', 'font', + 'font-family', 'font-kerning', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'gap', 'grid', 'grid-area', 'grid-auto-columns', 'grid-auto-flow', 'grid-auto-rows', 'grid-column', 'grid-column-end', 'grid-column-gap', 'grid-column-start', 'grid-gap', 'grid-row', 'grid-row-end', 'grid-row-gap', 'grid-row-start', 'grid-template', 'grid-template-areas', 'grid-template-columns', 'grid-template-rows', 'height', 'hyphens', + 'justify-content', + 'left', 'letter-spacing', 'line-height', 'list-style', 'list-style-image', 'list-style-position', 'list-style-type', 'margin', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'max-height', 'max-width', + 'min-height', 'min-width', 'object-fit', 'object-position', 'opacity', 'order', 'outline', 'outline-color', 'outline-offset', 'outline-style', 'outline-width', 'overflow', 'overflow-x', 'overflow-y', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'page-break-after', 'page-break-before', 'page-break-inside', 'perspective', 'perspective-origin', 'pointer-events', 'position', 'quotes', 'right', 'row-gap', 'scroll-behavior', 'table-layout', 'text-align', 'text-align-last', 'text-decoration', 'text-decoration-color', 'text-decoration-line', 'text-decoration-style', 'text-indent', 'text-justify', 'text-overflow', 'text-shadow', 'text-transform', 'top', 'transform', 'transform-origin', 'transform-style', 'transition', 'transition-delay', 'transition-duration', 'transition-property', 'transition-timing-fn', 'user-select', 'vertical-align', 'visibility', 'white-space', 'width', 'word-break', 'word-spacing', 'word-wrap', 'writing-mode', 'z-index' + + ] + }, + axis: { + acceptReporters: false, + items: [ + { text: "x position", value: "x" }, { text: "y position", value: "y" }, "width", "height" + ] + }, + wh: { + acceptReporters: false, + items: [ + "width", "height" + ] + }, + eves: { + acceptReporters: true, + items: [ + // Mouse & Pointer + "click", "dblclick", "mousedown", "mouseup", "mouseenter", + "mouseleave", "mousemove", "mouseover", "mouseout", "contextmenu", "wheel", + + // Keyboard + "keydown", "keyup", "keypress", + + // Form & Input + "submit", "input", "change", "focus", "blur", "reset", "invalid", + + // Window & Document + "load", "DOMContentLoaded", "beforeunload", "unload", "resize", + "scroll", "error", "visibilitychange", + + // Drag & Drop + "dragstart", "drag", "dragenter", "dragover", "dragleave", "drop", "dragend", + + // Mobile & Media + "touchstart", "touchmove", "touchend", "play" + ] + }, + attr: { + acceptReporters: false, + items: [ + "accesskey", "autocapitalize", "autofocus", "class", "contenteditable", + "dir", "draggable", "enterkeyhint", "hidden", "inert", "inputmode", + "lang", "nonce", "part", "popover", "role", "slot", "style", "tabindex", + "title", "translate", "virtualkeyboardpolicy", + "accept", "accept-charset", "action", "align", "allow", "alt", "as", + "async", "autocomplete", "autoplay", "background", "bgcolor", "border", + "capture", "charset", "checked", "cite", "color", "cols", "colspan", + "content", "controls", "coords", "crossorigin", "csp", "data", "datetime", + "decoding", "default", "defer", "disabled", "download", "enctype", "for", + "form", "formaction", "formenctype", "formmethod", "formnovalidate", + "formtarget", "headers", "height", "high", "href", "hreflang", "http-equiv", + "imagesizes", "imagesrcset", "integrity", "ismap", "kind", "label", "list", + "loading", "loop", "low", "max", "maxlength", "min", "minlength", "media", + "method", "multiple", "muted", "name", "novalidate", "open", "optimum", + "pattern", "ping", "placeholder", "playsinline", "poster", "preload", + "readonly", "referrerpolicy", "rel", "required", "reversed", "rows", + "rowspan", "sandbox", "scope", "selected", "shape", "size", "sizes", + "span", "src", "srcdoc", "srclang", "srcset", "start", "step", "target", + "type", "usemap", "value", "width", "wrap" + ] + + } + + } + }; + } + + createPage(args, util) { + if (!Object.keys(this.pages).includes(args.PAGE)) { + if (args.PAGE !== "") { + this.pages.set(args.PAGE, new Map().set("data", new Map().set("x", 5).set("y", 5).set("width", 470).set("height", 350)).set("code", dom.parseFromString("", 'text/html')).set("eves", new Map())) + console.log(this.pages) + } else { + throw new Error("Name cannot be empty") + } + } + } + clearPage(args, util) { + + // //if (Object.keys(this.pages).includes(args.PAGE)) { + // let pages = this.pages + + this.pages.get(args.PAGE)?.set("code", dom.parseFromString("", 'text/html')) + this.pages.get(args.PAGE)?.set("eves", new Map()) + // } + } + deletePage(args, util) { + + //if (Object.keys(this.pages).includes(args.PAGE)) { + this.pages.delete(args.PAGE) + if (this.viewing.includes(args.PAGE)) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + } + + // } + } + allPages() { + return (JSON.stringify(Array.from(this.pages.keys()))) + } + get() { + if (Object.keys(this.pages).includes("my-page")) { + return (JSON.stringify(this.pages["my-page"].code)) + } + } + + + displayPage(args, util) { + return new Promise((resolve, reject) => { + try { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + const el = document.createElement("iframe"); + el.setAttribute("srcdoc", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + el.setAttribute("class", `htmlpage display${args.PAGE}`) + el.style.position = 'absolute'; + el.style.pointerEvents = 'auto'; + el.style.zIndex = '10'; + el.style.left = `${this.pages.get(args.PAGE).get("data").get("x")}px`; + el.style.top = `${this.pages.get(args.PAGE).get("data").get("y")}px`; + el.setAttribute("width", `${this.pages.get(args.PAGE).get("data").get("width")}px`) + el.setAttribute("height", `${this.pages.get(args.PAGE).get("data").get("height")}px`) + el.style.border = "1px solid black" + const container = Scratch.renderer.canvas.parentElement; + container.appendChild(el); + if (!this.viewing.includes(args.PAGE)) { + this.viewing.push(args.PAGE) + } + el.onload = () => { + for (const [key, value] of this.pages.get(args.PAGE)?.get("eves")) { + // console.log(key, value) + console.log(el.contentDocument.querySelector(`#element${args.PAGE}${key}`)) + el.contentDocument.querySelector(`#element${args.PAGE}${key}`).addEventListener(value, () => { + const triggerText = String(key); + const triggerTexta = String(args.PAGE); + + const targetOpcode = 'scrtwpmhtmldocuments_eve'; + const vm = Scratch.vm; + + vm.runtime.targets.forEach(target => { + const blocks = target.blocks; + const scripts = blocks.getScripts(); + + scripts.forEach(rootBlockId => { + const block = blocks.getBlock(rootBlockId); + + if (block && block.opcode === targetOpcode) { + let hatValue = ''; + let hatValuea = ''; + + if (block.fields && block.fields.ID && block.fields.PAGE) { + hatValue = block.fields.ID.value; + hatValuea = block.fields.PAGE.value; + } + else if (block.inputs && block.inputs.ID && block.inputs.PAGE) { + const inputID = block.inputs.ID; + const inputPAGE = block.inputs.PAGE; + + const shadowBlockID = blocks.getBlock(inputID.shadow); + const shadowBlockPAGE = blocks.getBlock(inputPAGE.shadow); + + if (shadowBlockID && shadowBlockID.fields) { + const fieldKey = Object.keys(shadowBlockID.fields)[0]; + hatValue = shadowBlockID.fields[fieldKey]?.value || ''; + } + if (shadowBlockPAGE && shadowBlockPAGE.fields) { + const fieldKeya = Object.keys(shadowBlockPAGE.fields)[0]; + hatValuea = shadowBlockPAGE.fields[fieldKeya]?.value || ''; + } + } + + if (hatValue === triggerText && hatValuea === triggerTexta) { + vm.runtime._pushThread(rootBlockId, target); + } + } + }); + }); + } + + ) + + + } + } + } catch (error) { } + resolve(); + }); + } + + hidePageAll(args, util) { + const elements = document.querySelectorAll('.htmlpage'); + elements.forEach(el => el.remove()); + this.viewing = [] + } + + hidePage(args, util) { + const elements = document.querySelectorAll(`.htmlpage.display${args.PAGE}`); + elements.forEach(el => el.remove()); + this.viewing.splice(this.viewing.indexOf(args.PAGE), 1) + } + + noNestEl(args, util) { + if ((this.pages).has(args.PAGE)) { + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + // console.log(this.pages) + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); + const currentBlock = blockContainer.getBlock(currentBlockId); + const target = util.thread.target; + + + + let parentBlockId = "" + let parentBlock = "" + + + let childId = currentBlockId; + let blockId = target.blocks.getBlock(currentBlockId)?.parent; + + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', + ]; + // let blockId = currentBlockId; + + + + + + + while (blockId) { + const parentBlock = target.blocks.getBlock(blockId); + // if (!parentBlock) break; + console.log(parentBlock) + + if (loopOpcodes.includes(parentBlock.opcode)) { + + + const substackId = parentBlock.inputs?.SUBSTACK?.block; + // const substack2Id = parentBlock.inputs?.SUBSTACK2?.block; + + // console.log(parentBlock) + + if (substackId === childId) { + + console.log(`found by ${args.ID}`) + parentBlockId = blockId; + console.log("pbid", parentBlockId) + const pB = blockContainer.getBlock(parentBlockId) + if (pB && pB.el.bin.includes(currentBlockId)) { + nest = pB.el.el + console.log("nest", nest) + + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + return + } + } + + if (substackId) { + let checkId = substackId; + while (checkId) { + if (checkId === childId) return blockId; + checkId = target.blocks.getBlock(checkId)?.next; + } + } + + // if (substack2Id) { + // let checkId = substack2Id; + // while (checkId) { + // if (checkId === childId) return blockId; + // checkId = target.blocks.getBlock(checkId)?.next; + // } + // } + } + childId = blockId; + blockId = parentBlock.parent; + } + // console.log("cb", currentBlock) + // console.log("Parent is", currentBlock.parent) + // if (currentBlock && currentBlock.parent){ + // const parentBlockId = currentBlock.parent; + // const parentBlock = blockContainer.getBlock(parentBlockId) + // if(parentBlock && parentBlock.el){ + // console.log("el", parentBlock.el) + // nest = parentBlock.el.el + // } + // } + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // console.log(`nest is`, nest) + + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + } else { + throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + } + } else { + throw new Error(`Element must have an id`) + + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + } + } + } + + nestEl(args, util) { + if ((this.pages).has(args.PAGE)) { + if (util.stackFrame.startedBranch) { + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + let blocksInLoop = [] + function fn() { + + const bc = util.thread.target.blocks; + + const substackInput = currentBlock.inputs.SUBSTACK; + if (!substackInput || !substackInput.block) { + console.log("The loop branch is empty."); + return; + } + + const branchBlockIds = []; + + // Helper function to recursively collect block IDs down the chain + const scanChain = (startBlockId) => { + let nextBlockId = startBlockId; + + while (nextBlockId) { + branchBlockIds.push(nextBlockId); + + const blockInfo = blockContainer.getBlock(nextBlockId); + if (!blockInfo) break; + + // If this block is ANOTHER loop, dive inside its mouth first! + if (blockInfo.inputs && blockInfo.inputs.SUBSTACK && blockInfo.inputs.SUBSTACK.block) { + scanChain(blockInfo.inputs.SUBSTACK.block); + } + + // If it's an If-Else block, it might also have a SUBSTACK2 mouth + if (blockInfo.inputs && blockInfo.inputs.SUBSTACK2 && blockInfo.inputs.SUBSTACK2.block) { + scanChain(blockInfo.inputs.SUBSTACK2.block); + } + + // Move to the next block directly underneath + nextBlockId = blockInfo.next; + } + }; + + // Start scanning from the very first block inside your custom loop + scanChain(substackInput.block); + + blocksInLoop = branchBlockIds + + } + + fn() + + if (currentBlock) { + currentBlock.el = { + el: args.ID, + compiledScope: 'global', + bin: blocksInLoop + }; + } + // console.log(this.pages) + + const target = util.thread.target; + + + let parentBlockId = "" + let parentBlock = "" + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', + ]; + let blockId = currentBlockId; + while (blockId) { + const block = target.blocks.getBlock(blockId); + if (!block) break; + + if (loopOpcodes.includes(block.opcode) && block !== currentBlock) { + // blockId = block.parent; + console.log(`found by ${args.ID}`) + parentBlockId = block; + console.log(parentBlockId) + parentBlock = blockContainer.getBlock(parentBlockId) + // const pB = blockContainer.getBlock(parentBlockId) + if (parentBlockId && parentBlockId.el.bin.includes(currentBlockId)) { + nest = parentBlockId.el.el + console.log("nest is", nest) + + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + + + util.stackFrame.startedBranch = true; + util.startBranch(1); + return + } + + + } + + blockId = block.parent; // Move to the parent block [3] + + } + // console.log("cb", currentBlock) + // if (currentBlock && currentBlock.parent && currentBlock.parent.el){ + // nest = currentBlock.parent.el + // } + // console.log(this.pages) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + let el = document.createElement(args.EL) + el.setAttribute("id", `element${args.PAGE}${args.ID}`) + el = body.appendChild(el) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + } else { + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + } + } else { + throw new Error(`Element must have an id`) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + } + util.stackFrame.startedBranch = true; + util.startBranch(1, true); + } + } + + + changeHTML(args, util) { + if ((this.pages).has(args.PAGE)) { + if (util.stackFrame.startedBranch) { + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + util.stackFrame.startedBranch = false; + return; + } + if (args.ID !== "") { + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + function fn() { + const bc = util.thread.target.blocks; + const currentBlock = bc.getBlock(currentBlockId); + if (!currentBlock) return; + + // 3. Find the ID of the first block inside the loop's C-shaped slot (SUBSTACK) + const substackInput = currentBlock.inputs.SUBSTACK; + if (!substackInput || !substackInput.block) { + console.log("The loop branch is empty."); + return; + } + + const branchBlockIds = []; + let nextBlockId = substackInput.block; + + // 4. Follow the chain of linked blocks sequentially down the branch + while (nextBlockId) { + branchBlockIds.push(nextBlockId); + + const blockInfo = bc.getBlock(nextBlockId); + // Move down to the next block inline, stopping if there are no more + nextBlockId = blockInfo ? blockInfo.next : null; + } + + // 5. Output the list of specific IDs + blocksInLoop = (branchBlockIds); + } + + fn() + + if (currentBlock) { + currentBlock.el = { + el: args.ID, + compiledScope: 'global', + bin: blocksInLoop + }; + } + let body = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) + body.innerHTML = "" + // console.log(this.pages) + + // const target = util.thread.target; + + + // let parentBlockId = "" + // let parentBlock = "" + // let nest = "" + // const loopOpcodes = [ + // 'scrtwpmhtmldocuments_nestEl', + // ]; + // let blockId = currentBlockId; + // while (blockId) { + // const block = target.blocks.getBlock(blockId); + // if (!block) break; + + // if (loopOpcodes.includes(block.opcode) && block !== currentBlock) { + // // blockId = block.parent; + // console.log(`found by ${args.ID}`) + // parentBlockId = block; + // console.log(parentBlockId) + // parentBlock = blockContainer.getBlock(parentBlockId) + // nest = parentBlockId.el.el + // console.log("nest is", nest) + + + // // let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // // // console.log(`body is`, body) + // // let el = document.createElement(args.EL) + // // el.setAttribute("id", `element${args.PAGE}${args.ID}`) + // // el = body.appendChild(el) + + + // util.stackFrame.startedBranch = true; + // util.startBranch(1); + // return + + + + // } + + // blockId = block.parent; // Move to the parent block [3] + + // } + // console.log("cb", currentBlock) + // if (currentBlock && currentBlock.parent && currentBlock.parent.el){ + // nest = currentBlock.parent.el + // } + // console.log(this.pages) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // // console.log(`body is`, body) + // let el = document.createElement(args.EL) + // el.setAttribute("id", `element${args.PAGE}${args.ID}`) + // el = body.appendChild(el) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + } else { + throw new Error(`Ony one element with the id "${args.ID}" can exist in the document`) + } + } else { + throw new Error(`Element must have an id`) + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + } + util.stackFrame.startedBranch = true; + util.startBranch(1, true); + } + } + + text(args, util) { + //if (Object.keys(this.pages).includes(args.PAGE)) { + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}${text}`) + + + + if ((this.pages).has(args.PAGE)) { + // if (args.ID !== "") { + // if (!this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + // console.log(this.pages) + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); + const currentBlock = blockContainer.getBlock(currentBlockId); + const target = util.thread.target; + + + + let parentBlockId = "" + let parentBlock = "" + + + let childId = currentBlockId; + let blockId = target.blocks.getBlock(currentBlockId)?.parent; + + let nest = "" + const loopOpcodes = [ + 'scrtwpmhtmldocuments_nestEl', + 'scrtwpmhtmldocuments_changeHTML', + + ]; + // let blockId = currentBlockId; + + + + + + + while (blockId) { + const parentBlock = target.blocks.getBlock(blockId); + // if (!parentBlock) break; + console.log(parentBlock) + + if (loopOpcodes.includes(parentBlock.opcode)) { + + + const substackId = parentBlock.inputs?.SUBSTACK?.block; + // const substack2Id = parentBlock.inputs?.SUBSTACK2?.block; + + // console.log(parentBlock) + + if (substackId === childId) { + + console.log(`found by ${args.ID}`) + parentBlockId = blockId; + console.log("pbid", parentBlockId) + const pB = blockContainer.getBlock(parentBlockId) + if (pB && pB.el.bin.includes(currentBlockId)) { + nest = pB.el.el + console.log("nest", nest) + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + + let text = document.createRange().createContextualFragment(args.TEXT) + let elements = text.querySelectorAll(`script`); + elements.forEach(el => el.remove()); + text = toAString.serializeToString(text) + body.innerHTML += text + + console.log("BODY", body) + return + } + } + + if (substackId) { + let checkId = substackId; + while (checkId) { + if (checkId === childId) return blockId; + checkId = target.blocks.getBlock(checkId)?.next; + } + } + + // if (substack2Id) { + // let checkId = substack2Id; + // while (checkId) { + // if (checkId === childId) return blockId; + // checkId = target.blocks.getBlock(checkId)?.next; + // } + // } + } + childId = blockId; + blockId = parentBlock.parent; + } + // console.log("cb", currentBlock) + // console.log("Parent is", currentBlock.parent) + // if (currentBlock && currentBlock.parent){ + // const parentBlockId = currentBlock.parent; + // const parentBlock = blockContainer.getBlock(parentBlockId) + // if(parentBlock && parentBlock.el){ + // console.log("el", parentBlock.el) + // nest = parentBlock.el.el + // } + // } + // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // console.log(`nest is`, nest) + + + // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} id="element${args.PAGE}${args.ID}">`) + // this.pages.get(args.PAGE)?.set("code", document.createRange().createContextualFragment(this.pages.get(args.PAGE).get("code"))) + // console.log(this.pages) + // } else { + // throw new Error(`Only one element with the id "${args.ID}" can exist in the document`) + // } + // } else { + // throw new Error(`Element must have an id`) + + // // this.pages.get(args.PAGE)?.set("code", toAString.serializeToString(this.pages.get(args.PAGE).get("code"))) + // // this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}<${args.EL} >`) + // } + + let body = this.pages.get(args.PAGE)?.get("code").querySelector(nest === "" ? "body" : `#element${args.PAGE}${nest}`) + // console.log(`body is`, body) + + let text = document.createRange().createContextualFragment(args.TEXT) + let elements = text.querySelectorAll(`script`); + elements.forEach(el => el.remove()); + text = toAString.serializeToString(text) + body.innerHTML += text + + } + + + + // } + } + + removeEl(args, util) { + //if (Object.keys(this.pages).includes(args.PAGE)) { + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + + + if (this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`)) { + let el = this.pages.get(args.PAGE)?.get("code").querySelector(`#element${args.PAGE}${args.ID}`) + // console.log(`body is`, body) + el.remove() + } + + console.log(this.pages) + } + // } + + } + + styleEl(args, util) { + //if (Object.keys(this.pages).includes(args.PAGE)) { + + + if (util.stackFrame.startedBranch) { + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}`) + + util.stackFrame.startedBranch = false; + return; + } + + const blockContainer = util.thread.blockContainer; + const currentBlockId = util.thread.peekStack(); // + const currentBlock = blockContainer.getBlock(currentBlockId); + if (currentBlock) { + currentBlock.stylePage = { + page: args.PAGE, + compiledScope: 'global', + }; + } + this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}` + + // util.stackFrame.startedBranch = false; + // return; + // } + // //do before + // const blockContainer = util.thread.blockContainer; + // const currentBlockId = util.thread.peekStack(); // + // const currentBlock = blockContainer.getBlock(currentBlockId); + // if (currentBlock) { + // currentBlock.stylePage = { + // page: args.PAGE, + // compiledScope: 'global', + // }; + + // this.pages[args.PAGE].code += ``) - - util.stackFrame.startedBranch = false; - return; - } - - const blockContainer = util.thread.blockContainer; - const currentBlockId = util.thread.peekStack(); // - const currentBlock = blockContainer.getBlock(currentBlockId); - if (currentBlock) { - currentBlock.stylePage = { - page: args.PAGE, - compiledScope: 'global', - }; - } - this.pages.get(args.PAGE)?.set("code", `${this.pages.get(args.PAGE)?.get("code")}` - - // util.stackFrame.startedBranch = false; - // return; - // } - // //do before - // const blockContainer = util.thread.blockContainer; - // const currentBlockId = util.thread.peekStack(); // - // const currentBlock = blockContainer.getBlock(currentBlockId); - // if (currentBlock) { - // currentBlock.stylePage = { - // page: args.PAGE, - // compiledScope: 'global', - // }; - - // this.pages[args.PAGE].code += `