File indexing completed on 2024-04-14 16:00:15

0001 class QmlOnline {
0002     constructor(div) {
0003         this.div = document.getElementById(div)
0004         this.canvas = undefined
0005         this.img = undefined
0006         this.status = undefined
0007         this.figure = undefined
0008         this.config = undefined
0009         this.qtLoader = undefined
0010 
0011         var self = this
0012         this.defaultConfig = {
0013             qmlMessage: function (msg) {
0014                 console.log(`qml: ${msg}`)
0015                 self.config && self.config.qmlMessage && self.config.qmlMessage(msg)
0016             },
0017             qmlError: function (error) {
0018                 console.log(`qml error: ${JSON.stringify(error)}`)
0019                 console.log(`${self.config}`)
0020                 self.config && self.config.qmlError && self.config.qmlError(error)
0021             },
0022             posInit: function () {
0023                 self.config && self.config.posInit && self.config.posInit()
0024             },
0025         };
0026     }
0027 
0028     init() {
0029         /*
0030             <figure style="overflow:visible;" id="qtspinner">
0031                 <center style="margin-top:1.5em;">
0032                     <img id="webasm_load_image" ;
0033                         style="max-height: 400px; object-fit: contain; display: block; margin-left: auto; margin-right: auto;">
0034                     </img>
0035                     <strong>Qt for WebAssembly: qmlonline</strong>
0036                     <div id="qtstatus"></div>
0037                     <noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript>
0038                 </center>
0039             </figure>
0040         */
0041         this.figure = document.createElement("figure")
0042         this.figure.style = "overflow:visible;"
0043         this.figure.id = "qt-spinner"
0044 
0045         const center = document.createElement("center")
0046         center.style = "margin-top:1.5em;"
0047 
0048         this.img = document.createElement("img")
0049         this.img.id = "webasm-load-image"
0050         this.img.style = "max-height: 400px; object-fit: contain; display: block; margin-left: auto; margin-right: auto;"
0051         center.appendChild(this.img)
0052 
0053         const strong = document.createElement("strong")
0054         strong.body = "Qt for WebAssembly: qmlonline"
0055         center.appendChild(strong)
0056 
0057         this.status = document.createElement("div")
0058         this.status.id = "qt-status"
0059         center.appendChild(this.status)
0060 
0061         const noScript = document.createElement("noscript")
0062         noScript.body = "JavaScript is disabled. Please enable JavaScript to use this application."
0063         center.appendChild(noScript)
0064 
0065         this.figure.appendChild(center)
0066         this.div.appendChild(this.figure)
0067 
0068         /*
0069             <canvas id="qtcanvas" oncontextmenu="event.preventDefault()"
0070                 contenteditable="true" style="height: 100%; width: 100%;"></canvas>
0071         */
0072         this.canvas = document.createElement("canvas")
0073         this.canvas.id = "qt-canvas"
0074         this.canvas.setAttribute("oncontextmenu", "event.preventDefault()")
0075         this.canvas.setAttribute("contenteditable", "true")
0076         this.canvas.style = "height: 100%; width: 100%;"
0077         this.div.appendChild(this.canvas)
0078 
0079         this.loadKonqi()
0080         this.loadWebASM()
0081     }
0082 
0083     registerCall(userConfig) {
0084         this.config = userConfig
0085     }
0086 
0087     loadKonqi() {
0088         const images = [
0089             "https://community.kde.org/images.community/thumb/4/40/Mascot_konqi.png/360px-Mascot_konqi.png",
0090             "https://community.kde.org/images.community/thumb/c/ce/Mascot_konqi-dev-kde.png/424px-Mascot_konqi-dev-kde.png",
0091             "https://community.kde.org/images.community/thumb/f/fb/Mascot_konqi-app-dev-katie.png/424px-Mascot_konqi-app-dev-katie.png",
0092             "https://community.kde.org/images.community/thumb/1/11/Mascot_konqi-dev-qt.png/424px-Mascot_konqi-dev-qt.png",
0093             "https://community.kde.org/images.community/thumb/5/50/Mascot_konqi-base-framework.png/526px-Mascot_konqi-base-framework.png",
0094             "https://community.kde.org/images.community/thumb/a/af/Mascot_konqi-base-plasma.png/520px-Mascot_konqi-base-plasma.png",
0095             "https://community.kde.org/images.community/thumb/7/79/Mascot_konqi-app-dev.png/651px-Mascot_konqi-app-dev.png",
0096             "https://community.kde.org/images.community/thumb/f/f4/Mascot_konqi-support-document.png/571px-Mascot_konqi-support-document.png",
0097             "https://community.kde.org/images.community/thumb/9/99/Mascot_konqi-app-hardware.png/424px-Mascot_konqi-app-hardware.png",
0098         ];
0099         this.img.src = images[Math.floor(Math.random() * images.length)];
0100     }
0101 
0102     loadWebASM() {
0103         const self = this
0104         var qtLoader
0105         qtLoader = QtLoader({
0106             path: "https://qmlonline.kde.org/",
0107             canvasElements: [self.canvas],
0108             showLoader: function (loaderStatus) {
0109                 self.figure.style.display = 'block';
0110                 self.canvas.style.display = 'none';
0111                 self.status.innerHTML = loaderStatus + "...";
0112             },
0113             showError: function (errorText) {
0114                 self.status.innerHTML = errorText;
0115                 self.figure.style.display = 'block';
0116                 self.canvas.style.display = 'none';
0117             },
0118             showExit: function () {
0119                 self.status.innerHTML = "Application exit";
0120                 if (qtLoader.exitCode !== undefined)
0121                     self.status.innerHTML += " with code " + qtLoader.exitCode;
0122                 if (qtLoader.exitText !== undefined)
0123                     self.status.innerHTML += " (" + qtLoader.exitText + ")";
0124                 self.figure.style.display = 'block';
0125                 self.canvas.style.display = 'none';
0126                 console.log("exit", qtLoader.exitCode)
0127             },
0128             showCanvas: function () {
0129                 self.figure.style.display = 'none';
0130                 self.canvas.style.display = 'block';
0131                 Module.instantiateWasm = function (imports, successCallback) {
0132                     console.log('instantiateWasm: instantiating asynchronously');
0133                 };
0134             },
0135         });
0136         qtLoader.loadEmscriptenModule("qmlonline");
0137         this.qtLoader = qtLoader
0138 
0139         // TODO: Find a better way to set the initial code and wait for the webassembly to start
0140         var intervalID = setInterval(
0141             function () {
0142                 console.log("Waiting for webassembly to load...")
0143 
0144                 if (Module && !Module.printErr) {
0145                     Module.printErr = function (text) {
0146                         // qml message
0147                         let match = /qml:\ (.*)/.exec(text)
0148                         if (match) {
0149                             self.defaultConfig.qmlMessage(match[1])
0150                         }
0151 
0152                         //const match = /qrc:\/userItem:(?<line_number>\d+): (?<error_message>.*)/.exec(lines[i])
0153                         match = /qrc:\/userItem:(\d+): (.*)/.exec(text)
0154 
0155                         if (match) {
0156                             let line_number = match[1]
0157                             let error_message = match[2]
0158 
0159                             self.defaultConfig.qmlError({
0160                                 row: line_number - 1,
0161                                 column: 0,
0162                                 text: error_message,
0163                                 type: "error"
0164                             });
0165                         }
0166 
0167                         //const match = /qrc:\/userItem:(?<line_number>\d+):(?<column_number>\d+): (?<error_message>.*)/
0168                         match = /qrc:\/userItem:(\d+):(\d+): (.*)/.exec(text)
0169 
0170                         if (match) {
0171                             let line_number = match[1]
0172                             let column_number = match[2]
0173                             let error_message = match[3]
0174 
0175                             self.defaultConfig.qmlError({
0176                                 row: line_number - 1,
0177                                 column: column_number,
0178                                 text: error_message,
0179                                 type: "error"
0180                             });
0181                         }
0182                     }
0183                 }
0184 
0185                 if (Module.self !== undefined) {
0186                     clearInterval(intervalID);
0187                     Module.self().setCode(
0188                         "import QtQuick 2.7; \
0189 import QtQuick.Controls 2.3; \
0190 Rectangle { \
0191 color: 'red'; \
0192 anchors.fill: parent; \
0193 Text { \
0194     text: 'WEEEEEEEEEE'; \
0195     font.pixelSize: 50; \
0196     color: 'white'; \
0197     anchors.centerIn: parent; \
0198     RotationAnimator on rotation { \
0199         running: true; \
0200         loops: Animation.Infinite; \
0201         from: 0; \
0202         to: 360; \
0203         duration: 1500; \
0204     } \
0205 } \
0206 }")
0207                 }
0208                 self.defaultConfig.posInit()
0209             },
0210         100);
0211     }
0212 
0213     setCode(code) {
0214         Module && Module.self && Module.self().setCode(code)
0215     }
0216 
0217     buildInfo() {
0218         if (Module && Module.Version) {
0219             return new Module.Version()
0220         }
0221         return undefined
0222     }
0223 
0224     resizeCanvas() {
0225         this.qtLoader && this.qtLoader.resizeCanvasElement(this.canvas);
0226     }
0227 }