Spaces:
Runtime error
Runtime error
| const formatMessage = require('format-message'); | |
| const BlockType = require('../../extension-support/block-type'); | |
| const ArgumentType = require('../../extension-support/argument-type'); | |
| const ProjectPermissionManager = require('../../util/project-permissions'); | |
| const Color = require('../../util/color'); | |
| const Cast = require('../../util/cast'); | |
| const EffectOptions = { | |
| acceptReporters: true, | |
| items: [ | |
| { text: "color", value: "color" }, | |
| { text: "grayscale", value: "grayscale" }, | |
| { text: "brightness", value: "brightness" }, | |
| { text: "contrast", value: "contrast" }, | |
| { text: "ghost", value: "ghost" }, | |
| { text: "blur", value: "blur" }, | |
| { text: "invert", value: "invert" }, | |
| { text: "saturate", value: "saturate" }, | |
| { text: "sepia", value: "sepia" } | |
| ] | |
| }; | |
| const urlToReportUrl = (url) => { | |
| let urlObject; | |
| try { | |
| urlObject = new URL(url); | |
| } catch { | |
| // we cant really throw an error in this state since it halts any blocks | |
| // or return '' since thatll just confuse the api likely | |
| // so just use example.com | |
| return 'example.com'; | |
| } | |
| // use host name | |
| return urlObject.hostname; | |
| }; | |
| // to avoid taking 1290 years for each url set | |
| // we save the ones that we already checked | |
| const safeOriginUrls = {}; | |
| /** | |
| * uhhhhhhhhhh | |
| * @param {Array} array the array | |
| * @param {*} value the value | |
| * @returns {Object} an object | |
| */ | |
| const ArrayToValue = (array, value) => { | |
| const object = {}; | |
| array.forEach(item => { | |
| object[String(item)] = value; | |
| }); | |
| return object; | |
| }; | |
| const isUrlRatedSafe = (url) => { | |
| return new Promise((resolve) => { | |
| const saveUrl = urlToReportUrl(url); | |
| if (safeOriginUrls.hasOwnProperty(saveUrl)) { | |
| return resolve(safeOriginUrls[saveUrl]); | |
| } | |
| fetch(`https://pm-bapi.vercel.app/api/safeurl?url=${saveUrl}`).then(res => { | |
| if (!res.ok) { | |
| resolve(true); | |
| return; | |
| } | |
| res.json().then(status => { | |
| safeOriginUrls[saveUrl] = status.safe; | |
| resolve(status.safe); | |
| }).catch(() => resolve(true)); | |
| }).catch(() => resolve(true)); | |
| }) | |
| } | |
| /** | |
| * Class for IFRAME blocks | |
| * @constructor | |
| */ | |
| class JgIframeBlocks { | |
| constructor(runtime) { | |
| /** | |
| * The runtime instantiating this block package. | |
| * @type {Runtime} | |
| */ | |
| this.runtime = runtime; | |
| this.createdIframe = null; | |
| this.iframeSettings = { | |
| x: 0, | |
| y: 0, | |
| rotation: 90, | |
| width: 480, | |
| height: 360, | |
| color: '#ffffff', | |
| opacity: 0, | |
| clickable: true | |
| }; | |
| this.iframeFilters = ArrayToValue(EffectOptions.items.map(item => item.value), 0); | |
| this.iframeLoadedValue = false; | |
| this.displayWebsiteUrl = ""; | |
| this.runtime.on('PROJECT_STOP_ALL', () => { | |
| // stop button clicked so delete the iframe | |
| this.RemoveIFrame(); | |
| }); | |
| } | |
| /** | |
| * @returns {object} metadata for this extension and its blocks. | |
| */ | |
| getInfo() { | |
| return { | |
| id: 'jgIframe', | |
| name: 'IFrame', | |
| color1: '#F36518', | |
| color2: '#E64D18', | |
| blocks: [ | |
| { | |
| opcode: 'createIframeElement', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.createIframeElement', | |
| default: 'set new iframe', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND | |
| }, | |
| { | |
| opcode: 'deleteIframeElement', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.deleteIframeElement', | |
| default: 'delete iframe', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND | |
| }, | |
| { | |
| opcode: 'iframeElementExists', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.iframeElementExists', | |
| default: 'iframe exists?', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.BOOLEAN, | |
| disableMonitor: true, | |
| }, | |
| "---", | |
| "---", | |
| { | |
| opcode: 'whenIframeIsLoaded', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.whenIframeIsLoaded', | |
| default: 'when iframe loads site', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.HAT | |
| }, | |
| { | |
| opcode: 'setIframeUrl', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeUrl', | |
| default: 'set iframe url to [URL]', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| URL: { | |
| type: ArgumentType.STRING, | |
| defaultValue: "https://www.example.com" | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframePosLeft', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframePosLeft', | |
| default: 'set iframe x to [X]', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| X: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 0 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframePosTop', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframePosTop', | |
| default: 'set iframe y to [Y]', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| Y: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 0 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeSizeWidth', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeSizeWidth', | |
| default: 'set iframe width to [WIDTH]', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| WIDTH: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 480 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeSizeHeight', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeSizeHeight', | |
| default: 'set iframe height to [HEIGHT]', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| HEIGHT: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 360 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeRotation', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeRotation', | |
| default: 'point iframe in direction [ROTATE]', | |
| description: '' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| ROTATE: { | |
| type: ArgumentType.ANGLE, | |
| defaultValue: 90 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeBackgroundColor', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeBackgroundColor', | |
| default: 'set iframe background color to [COLOR]', | |
| description: '' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| COLOR: { | |
| type: ArgumentType.COLOR | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeBackgroundOpacity', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeBackgroundOpacity', | |
| default: 'set iframe background transparency to [GHOST]%', | |
| description: '' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| GHOST: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 100 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'setIframeClickable', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.setIframeClickable', | |
| default: 'toggle iframe to be [USABLE]', | |
| description: '' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| USABLE: { | |
| type: ArgumentType.STRING, | |
| menu: 'iframeClickable' | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'showIframeElement', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.showIframeElement', | |
| default: 'show iframe', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND | |
| }, | |
| { | |
| opcode: 'hideIframeElement', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.hideIframeElement', | |
| default: 'hide iframe', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.COMMAND | |
| }, | |
| { | |
| opcode: 'getIframeLeft', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeLeft', | |
| default: 'iframe x', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeTop', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeTop', | |
| default: 'iframe y', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeWidth', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeWidth', | |
| default: 'iframe width', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeHeight', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeHeight', | |
| default: 'iframe height', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeRotation', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeRotation', | |
| default: 'iframe rotation', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeBackgroundColor', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeBackgroundColor', | |
| default: 'iframe background color', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeBackgroundOpacity', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeBackgroundOpacity', | |
| default: 'iframe background transparency', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'getIframeTargetUrl', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeTargetUrl', | |
| default: 'iframe target url', | |
| description: '' | |
| }), | |
| blockType: BlockType.REPORTER | |
| }, | |
| { | |
| opcode: 'iframeElementIsHidden', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.iframeElementIsHidden', | |
| default: 'iframe is hidden?', | |
| description: 'im too lazy to write these anymore tbh' | |
| }), | |
| blockType: BlockType.BOOLEAN, | |
| disableMonitor: true, | |
| }, | |
| { | |
| opcode: 'getIframeClickable', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeClickable', | |
| default: 'iframe is interactable?', | |
| description: '' | |
| }), | |
| blockType: BlockType.BOOLEAN, | |
| disableMonitor: true, | |
| }, | |
| "---", | |
| "---", | |
| // effects YAYYAYAWOOHOOO YEEAAAAAAAAA | |
| { | |
| opcode: 'iframeElementSetEffect', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.iframeElementSetEffect', | |
| default: 'set [EFFECT] effect on iframe to [AMOUNT]', | |
| description: 'YAYYAYAWOOHOOO YEEAAAAAAAAAYAYYAYAWOOHOOO YEEAAAAAAAAA' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| EFFECT: { | |
| type: ArgumentType.STRING, | |
| menu: 'effects', | |
| defaultValue: "color" | |
| }, | |
| AMOUNT: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 0 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'iframeElementChangeEffect', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.iframeElementChangeEffect', | |
| default: 'change [EFFECT] effect on iframe by [AMOUNT]', | |
| description: 'YAYYAYAWOOHOOO YEEAAAAAAAAAYAYYAYAWOOHOOO YEEAAAAAAAAA' | |
| }), | |
| blockType: BlockType.COMMAND, | |
| arguments: { | |
| EFFECT: { | |
| type: ArgumentType.STRING, | |
| menu: 'effects', | |
| defaultValue: "color" | |
| }, | |
| AMOUNT: { | |
| type: ArgumentType.NUMBER, | |
| defaultValue: 25 | |
| } | |
| } | |
| }, | |
| { | |
| opcode: 'iframeElementClearEffects', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.iframeElementClearEffects', | |
| default: 'clear iframe effects', | |
| description: 'YAYYAYAWOOHOOO YEEAAAAAAAAAYAYYAYAWOOHOOO YEEAAAAAAAAA' | |
| }), | |
| blockType: BlockType.COMMAND | |
| }, | |
| { | |
| opcode: 'getIframeEffectAmount', | |
| text: formatMessage({ | |
| id: 'jgIframe.blocks.getIframeEffectAmount', | |
| default: 'iframe [EFFECT]', | |
| description: 'YAYYAYAWOOHOOO YEEAAAAAAAAAYAYYAYAWOOHOOO YEEAAAAAAAAA' | |
| }), | |
| blockType: BlockType.REPORTER, | |
| arguments: { | |
| EFFECT: { | |
| type: ArgumentType.STRING, | |
| menu: 'effects', | |
| defaultValue: "color" | |
| } | |
| } | |
| }, | |
| "---" | |
| ], | |
| menus: { | |
| effects: EffectOptions, | |
| iframeClickable: { | |
| acceptReporters: true, | |
| items: [ | |
| 'interactable', | |
| 'non-interactable' | |
| ] | |
| } | |
| } | |
| }; | |
| } | |
| // permissions | |
| async IsWebsiteAllowed(url) { | |
| if (ProjectPermissionManager.IsDataUrl(url)) return true; | |
| if (!ProjectPermissionManager.IsUrlSafe(url)) return false; | |
| const safe = await isUrlRatedSafe(url); | |
| return safe; | |
| } | |
| // utilities | |
| GetCurrentCanvas() { | |
| return this.runtime.renderer.canvas; | |
| } | |
| SetNewIFrame() { | |
| const iframe = document.createElement("iframe"); | |
| iframe.onload = () => { | |
| this.iframeLoadedValue = true; | |
| }; | |
| this.createdIframe = iframe; | |
| return iframe; | |
| } | |
| RemoveIFrame() { | |
| if (this.createdIframe) { | |
| this.createdIframe.remove(); | |
| this.createdIframe = null; | |
| } | |
| } | |
| GetIFrameState() { | |
| if (this.createdIframe) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| SetIFramePosition(iframe, x, y, width, height, rotation) { | |
| const frame = iframe; | |
| const stage = { | |
| width: this.runtime.stageWidth, | |
| height: this.runtime.stageHeight | |
| }; | |
| frame.style.position = "absolute"; // position above canvas without pushing it down | |
| frame.style.width = `${(width / stage.width) * 100}%`; // convert pixel size to percentage for full screen | |
| frame.style.height = `${(height / stage.height) * 100}%`; | |
| frame.style.transformOrigin = "center center"; // rotation and translation begins at center | |
| // epic maths to place x and y at the center | |
| let xpos = ((((stage.width / 2) - (width / 2)) + x) / stage.width) * 100; | |
| let ypos = ((((stage.height / 2) - (height / 2)) - y) / stage.height) * 100; | |
| frame.style.left = `${xpos}%`; | |
| frame.style.top = `${ypos}%`; | |
| frame.style.transform = `rotate(${rotation - 90}deg)`; | |
| this.iframeSettings = { | |
| ...this.iframeSettings, | |
| x: x, | |
| y: y, | |
| rotation: rotation, | |
| width: width, | |
| height: height | |
| }; | |
| // when switching between project page & editor, we need to place the iframe again since it gets lost | |
| if (iframe.parentElement !== this.GetCurrentCanvas().parentElement) { | |
| /* todo: create layers so that iframe appears above 3d every time this is done */ | |
| this.GetCurrentCanvas().parentElement.prepend(iframe); | |
| } | |
| } | |
| SetIFrameColors(iframe, color, opacity) { | |
| const frame = iframe; | |
| const rgb = Cast.toRgbColorObject(color); | |
| const hex = Color.rgbToHex(rgb); | |
| frame.style.backgroundColor = `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${opacity * 100}%)`; | |
| this.iframeSettings = { | |
| ...this.iframeSettings, | |
| color: hex, | |
| opacity: Cast.toNumber(opacity) | |
| }; | |
| // when switching between project page & editor, we need to place the iframe again since it gets lost | |
| if (iframe.parentElement !== this.GetCurrentCanvas().parentElement) { | |
| /* todo: create layers so that iframe appears above 3d every time this is done */ | |
| this.GetCurrentCanvas().parentElement.prepend(iframe); | |
| } | |
| } | |
| SetIFrameClickable(iframe, clickable) { | |
| const frame = iframe; | |
| frame.style.pointerEvents = Cast.toBoolean(clickable) ? '' : 'none'; | |
| this.iframeSettings = { | |
| ...this.iframeSettings, | |
| clickable: Cast.toBoolean(clickable) | |
| }; | |
| // when switching between project page & editor, we need to place the iframe again since it gets lost | |
| if (iframe.parentElement !== this.GetCurrentCanvas().parentElement) { | |
| /* todo: create layers so that iframe appears above 3d every time this is done */ | |
| this.GetCurrentCanvas().parentElement.prepend(iframe); | |
| } | |
| } | |
| GenerateCssFilter(color, grayscale, brightness, contrast, ghost, blur, invert, saturate, sepia) { | |
| return `hue-rotate(${(color / 200) * 360}deg) ` + // scratch color effect goes back to normal color at 200 | |
| `grayscale(${grayscale}%) ` + | |
| `brightness(${brightness + 100}%) ` + // brightness at 0 will be 100 | |
| `contrast(${contrast + 100}%) ` + // same thing here | |
| `opacity(${100 - ghost}%) ` + // opacity at 0 will be 100 but opacity at 100 will be 0 | |
| `blur(${blur}px) ` + | |
| `invert(${invert}%) ` + // invert is actually a percentage lolol! | |
| `saturate(${saturate + 100}%) ` + // saturation at 0 will be 100 | |
| `sepia(${sepia}%)`; | |
| } | |
| ApplyFilterOptions(iframe) { | |
| iframe.style.filter = this.GenerateCssFilter( | |
| this.iframeFilters.color, | |
| this.iframeFilters.grayscale, | |
| this.iframeFilters.brightness, | |
| this.iframeFilters.contrast, | |
| this.iframeFilters.ghost, | |
| this.iframeFilters.blur, | |
| this.iframeFilters.invert, | |
| this.iframeFilters.saturate, | |
| this.iframeFilters.sepia, | |
| ); | |
| } | |
| createIframeElement() { | |
| this.RemoveIFrame(); | |
| const iframe = this.SetNewIFrame(); | |
| iframe.style.zIndex = 500; | |
| iframe.style.borderWidth = "0px"; | |
| iframe.src = "data:text/html;base64,PERPQ1RZUEUgaHRtbD4KPGh0bWwgbGFuZz0iZW4tVVMiPgo8aGVhZD48L2hlYWQ+Cjxib2R5PjxoMT5IZWxsbyE8L2gxPjxwPllvdSd2ZSBqdXN0IGNyZWF0ZWQgYW4gaWZyYW1lIGVsZW1lbnQuPGJyPlVzZSB0aGlzIHRvIGVtYmVkIHdlYnNpdGVzIHdpdGggdGhlaXIgVVJMcy4gTm90ZSB0aGF0IHNvbWUgd2Vic2l0ZXMgbWlnaHQgbm90IGFsbG93IGlmcmFtZXMgdG8gd29yayBmb3IgdGhlaXIgd2Vic2l0ZS48L3A+PC9ib2R5Pgo8L2h0bWw+"; | |
| this.displayWebsiteUrl = iframe.src; | |
| // positions iframe to fit stage | |
| this.SetIFramePosition(iframe, 0, 0, this.runtime.stageWidth, this.runtime.stageHeight, 90); | |
| // reset color & opacity | |
| this.SetIFrameColors(iframe, '#ffffff', 0); | |
| // reset other stuff | |
| this.SetIFrameClickable(iframe, true); | |
| // reset filters | |
| this.iframeFilters = ArrayToValue(EffectOptions.items.map(item => item.value), 0); // reset all filter stuff | |
| this.GetCurrentCanvas().parentElement.prepend(iframe); // adds the iframe above the canvas | |
| return iframe; | |
| } | |
| deleteIframeElement() { | |
| this.RemoveIFrame(); | |
| } | |
| iframeElementExists() { | |
| return this.GetIFrameState(); | |
| } | |
| setIframeUrl(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| let usingProxy = false; | |
| let checkingUrl = args.URL; | |
| if (Cast.toString(args.URL).startsWith("proxy://")) { | |
| // use the penguin mod proxy but still say we are on proxy:// since its what the user input | |
| // replace proxy:// with https:// though since we are still using the https protocol | |
| usingProxy = true; | |
| checkingUrl = Cast.toString(args.URL).replace("proxy://", "https://"); | |
| } | |
| if (Cast.toString(args.URL) === 'about:blank') { | |
| this.createdIframe.src = "about:blank"; | |
| this.displayWebsiteUrl = "about:blank"; | |
| return; | |
| } | |
| this.IsWebsiteAllowed(checkingUrl).then(safe => { | |
| if (!safe) { // website isnt in the permitted sites list? | |
| this.createdIframe.src = "about:blank"; | |
| this.displayWebsiteUrl = args.URL; | |
| return; | |
| } | |
| this.createdIframe.src = (usingProxy ? `https://detaproxy-1-s1965152.deta.app/?url=${Cast.toString(args.URL).replace("proxy://", "https://")}` : args.URL); | |
| // tell the user we are on proxy:// still since it looks nicer than the disgusting deta url | |
| this.displayWebsiteUrl = (usingProxy ? `${Cast.toString(this.createdIframe.src).replace("https://detaproxy-1-s1965152.deta.app/?url=https://", "proxy://")}` : this.createdIframe.src); | |
| }); | |
| } | |
| setIframePosLeft(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFramePosition(iframe, | |
| Cast.toNumber(args.X), | |
| this.iframeSettings.y, | |
| this.iframeSettings.width, | |
| this.iframeSettings.height, | |
| this.iframeSettings.rotation, | |
| ); | |
| } | |
| setIframePosTop(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFramePosition(iframe, | |
| this.iframeSettings.x, | |
| Cast.toNumber(args.Y), | |
| this.iframeSettings.width, | |
| this.iframeSettings.height, | |
| this.iframeSettings.rotation, | |
| ); | |
| } | |
| setIframeSizeWidth(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFramePosition(iframe, | |
| this.iframeSettings.x, | |
| this.iframeSettings.y, | |
| Cast.toNumber(args.WIDTH), | |
| this.iframeSettings.height, | |
| this.iframeSettings.rotation, | |
| ); | |
| } | |
| setIframeSizeHeight(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFramePosition(iframe, | |
| this.iframeSettings.x, | |
| this.iframeSettings.y, | |
| this.iframeSettings.width, | |
| Cast.toNumber(args.HEIGHT), | |
| this.iframeSettings.rotation, | |
| ); | |
| } | |
| setIframeRotation(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFramePosition(iframe, | |
| this.iframeSettings.x, | |
| this.iframeSettings.y, | |
| this.iframeSettings.width, | |
| this.iframeSettings.height, | |
| Cast.toNumber(args.ROTATE), | |
| ); | |
| } | |
| setIframeBackgroundColor(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| this.SetIFrameColors(iframe, args.COLOR, this.iframeSettings.opacity); | |
| } | |
| setIframeBackgroundOpacity(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| let opacity = Cast.toNumber(args.GHOST); | |
| if (opacity > 100) opacity = 100; | |
| if (opacity < 0) opacity = 0; | |
| opacity /= 100; | |
| opacity = 1 - opacity; | |
| this.SetIFrameColors(iframe, this.iframeSettings.color, opacity); | |
| } | |
| setIframeClickable(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| let clickable = false; | |
| if (Cast.toString(args.USABLE).toLowerCase() === 'interactable') { | |
| clickable = true; | |
| } | |
| if (Cast.toString(args.USABLE).toLowerCase() === 'on') { | |
| clickable = true; | |
| } | |
| if (Cast.toString(args.USABLE).toLowerCase() === 'enabled') { | |
| clickable = true; | |
| } | |
| if (Cast.toString(args.USABLE).toLowerCase() === 'true') { | |
| clickable = true; | |
| } | |
| this.SetIFrameClickable(iframe, clickable); | |
| } | |
| showIframeElement() { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| iframe.style.display = ""; | |
| } | |
| hideIframeElement() { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| const iframe = this.createdIframe; | |
| iframe.style.display = "none"; | |
| } | |
| getIframeLeft() { | |
| if (!this.GetIFrameState()) return 0; // iframe doesnt exist, stop | |
| return this.iframeSettings.x; | |
| } | |
| getIframeTop() { | |
| if (!this.GetIFrameState()) return 0; // iframe doesnt exist, stop | |
| return this.iframeSettings.y; | |
| } | |
| getIframeWidth() { | |
| if (!this.GetIFrameState()) return 480; // iframe doesnt exist, stop | |
| return this.iframeSettings.width; | |
| } | |
| getIframeHeight() { | |
| if (!this.GetIFrameState()) return 360; // iframe doesnt exist, stop | |
| return this.iframeSettings.height; | |
| } | |
| getIframeRotation() { | |
| if (!this.GetIFrameState()) return 90; // iframe doesnt exist, stop | |
| return this.iframeSettings.rotation; | |
| } | |
| getIframeTargetUrl() { | |
| if (!this.GetIFrameState()) return ''; // iframe doesnt exist, stop | |
| return this.displayWebsiteUrl; | |
| } | |
| getIframeBackgroundColor() { | |
| if (!this.GetIFrameState()) return '#ffffff'; // iframe doesnt exist, stop | |
| const rawColor = this.iframeSettings.color; | |
| const rgb = Cast.toRgbColorObject(rawColor); | |
| const hex = Color.rgbToHex(rgb); | |
| return hex; | |
| } | |
| getIframeBackgroundOpacity() { | |
| if (!this.GetIFrameState()) return 100; // iframe doesnt exist, stop | |
| const rawOpacity = this.iframeSettings.opacity; | |
| return (1 - rawOpacity) * 100; | |
| } | |
| getIframeClickable() { | |
| if (!this.GetIFrameState()) return true; // iframe doesnt exist, stop | |
| return this.iframeSettings.clickable; | |
| } | |
| iframeElementIsHidden() { | |
| if (!this.GetIFrameState()) return false; // iframe doesnt exist, stop | |
| return this.createdIframe.style.display === "none"; | |
| } | |
| whenIframeIsLoaded() { | |
| const value = this.iframeLoadedValue; | |
| this.iframeLoadedValue = false; | |
| return value; | |
| } | |
| // effect functions lolol | |
| iframeElementSetEffect(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| this.iframeFilters[args.EFFECT] = Cast.toNumber(args.AMOUNT); | |
| this.ApplyFilterOptions(this.createdIframe); | |
| } | |
| iframeElementChangeEffect(args) { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| this.iframeFilters[args.EFFECT] += Cast.toNumber(args.AMOUNT); | |
| this.ApplyFilterOptions(this.createdIframe); | |
| } | |
| iframeElementClearEffects() { | |
| if (!this.GetIFrameState()) return; // iframe doesnt exist, stop | |
| this.iframeFilters = ArrayToValue(EffectOptions.items.map(item => item.value), 0); // reset all values to 0 | |
| this.ApplyFilterOptions(this.createdIframe); | |
| } | |
| getIframeEffectAmount(args) { | |
| if (!this.GetIFrameState()) return 0; // iframe doesnt exist, stop | |
| return this.iframeFilters[args.EFFECT]; | |
| } | |
| } | |
| module.exports = JgIframeBlocks; | |