Love Zhaoying Posted June 24, 2023 Share Posted June 24, 2023 (edited) I am starting this thread to post a few tricks that I'm learning about scripting MOAP. I started with some examples and information on this excellent thread from @Innula Zenovka and @Quistess Alpha. Edited June 24, 2023 by Love Zhaoying Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 24, 2023 Author Share Posted June 24, 2023 One of the things I needed to doin my MOAP implementation, was "send back a response" to the MOAP page from a "POST" call, and do something with the response. Adding the highlighted part below to the function allowed me to get and process the "POST" response body. (Function "addtxt()" just writes the response to a textarea). This javascript function is included when the page is initially built by LSL. function SendToLSL() { if (input.value.trim().length!=0) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { // Setup a callback if (this.readyState==4 && this.status==200) // Only if ready and OK addtxt(this.responseText); // Add the response to my textarea }; xhttp.open(\"POST\",\"GetSomeData\", true); xhttp.send(input.value.trim()); input.value = ''; } } I did not put the code in a "code block" so I could highlight it, sorry. I am a programmer, but a "true n00b" at "Web Programming" - so believe it or not, escaping the "&&" to "&&" was the hardest part! Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 24, 2023 Share Posted June 24, 2023 3 minutes ago, Love Zhaoying said: escaping the "&&" to "&&" was the hardest part! Interesting, do you need to do that even if the javascript is within CDATA metatags? Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 24, 2023 Author Share Posted June 24, 2023 (edited) 6 minutes ago, Quistess Alpha said: Interesting, do you need to do that even if the javascript is within CDATA metatags? I'm not using those tags, here is the LSL that generates the "main HTML Body" (taken from your example? I did not find it in the thread just now): generateMainBody(){ gsMainBody = " <html xmlns=\"http://www.w3.org/1999/xhtml\"> <style> div.log {width:auto;border:2px solid black;height:calc(100vh - 75px);} div.fixed {position:fixed;bottom:10px;} </style> <body> <div class='log'><textarea id='txtlog' style='font-size:28px;width:100%;max-width:100%;height:calc(100vh - 75px);'/></div> <div class='fixed'><button onclick=\"SendToLSL()\" style='font-size:28px;'>Send</button><input id='cmdLine' style='font-size:28px;height:35px;' size='50'></input><button onclick=\"cleartxt()\" style='font-size:28px;'>Clear</button></div> </body> <script> var input = document.getElementById('cmdLine'); var txtArea = document.getElementById('txtlog'); function addtxt(newvalue){ txtArea.scrollTop = txtArea.scrollHeight; txtArea.value += newvalue + '\\r\\n'; } input.addEventListener('keypress', function(event) { if (event.key === 'Enter') { event.preventDefault(); SendToLSL(); } }); function focus(){input.focus(); input.select();} function cleartxt(){txtArea.value = '';focus();} function SendToLSL() { if (input.value.trim().length!=0) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState==4 && this.status==200) addtxt(this.responseText); }; xhttp.open(\"POST\",\"GetSomeData\", true); xhttp.send(input.value.trim()); input.value = ''; } } focus(); </script> </html>"; } ..but don't get me wrong, I had to use my Google skills to find the XMLHttpRequest response handling for "POST"! Just getting it to WORK was a challenge until I realized the error really did mean it was the "&"! Edited June 24, 2023 by Love Zhaoying Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 24, 2023 Share Posted June 24, 2023 2 minutes ago, Love Zhaoying said: I'm not using those tags, Also not a web programmer, but those tags seem to fix a lot of 'funny character' problems without having to escape them, or at least, I know it works for '>' and '<'. so a script segment would look like: <script> //<![CDATA[ /*Some javascript stuff here*/ //]]> </script> I've made it a habit to add those even when it's not "required" but maybe I hadn't picked up that trick when I posted the example you worked off of? Also, I always copy them from other script snippets, they are not easy to remember. 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 24, 2023 Author Share Posted June 24, 2023 @Quistess Alpha - while I've got your attention.. this morning while I was testing the script - the media page (I will tire or writing MOAP, it feels silly) worked for "clicks" but would not let me type any input! Even with previous versions of the script. I finally had to reboot my PC - then it worked fine. (Maybe just exiting / re-running the SL viewer would have been enough..) Have you seen anything like this - where the pages just "don't work" for unexplained reasons, then they "do work"? Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 24, 2023 Share Posted June 24, 2023 (edited) 6 minutes ago, Love Zhaoying said: Have you seen anything like this - where the pages just "don't work" for unexplained reasons, then they "do work"? That's getting into the weeds, but I have noticed my backspace key doesn't work in SL's web-browser-on-a-prim. Media stuff opens you up to a lot more 'platform dependent behavior' than usual: the user's OS and current state of libraries etc. . . so, not exactly, but I'm not surprised. Edited June 24, 2023 by Quistess Alpha 1 Link to comment Share on other sites More sharing options...
Innula Zenovka Posted June 25, 2023 Share Posted June 25, 2023 Apparently <![CDATA[ … ]]> is used in XML to escape <, > and &. It should not, however, be used in HTML, which regards it as a comment https://developer.mozilla.org/en-US/docs/Web/API/CDATASection. 2 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 25, 2023 Author Share Posted June 25, 2023 Looks like I'll have to implement a timed poll for GET to get updates (this is basically a console). I've come to terms with that since it will follow the same basic pattern as POST. I'll post the approach tomorrow when I'm "done". The goal is to NOT reload the page, but: 1) Send a POST to the script when user enters data, and 2) Use a "long polling GET" to get updates from the script for a "log" in a scrolling textarea. Easy peasy, the examples I started with for this part were just unnecessarily complicated. Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 25, 2023 Author Share Posted June 25, 2023 Ok, I ended up using two XMLHTTPRequest Objects: 1 for "POST", and 1 for "Polling". The relevant code is below. I made the "GET" XMLHTTPRequest instance "global" since it is always polling, and the "POST" XMLHTTPRequest instance local to the "SendToLSL()" function. I left out any code not relevant to the GET / POST. The "POST" waits for a response (in this use-case, it will be an echo of the command entered). The "GET" is always looking for any data. So far, this works pretty well.. Original inspirations were: 1) In Innula's and Quistess's thread (see OP for link), and 2) In the Wiki here: https://wiki.secondlife.com/wiki/User:Becky_Pippen/Shared_Media_LSL_Recipes#Reverse_Ajax_-_Long-polling_the_HTTP-in_server.2C_chat_logger_example. That example was overly complex for what I needed, and appears to pre-date some of the newer restrictions and conventions. // Javascript const debug = false; var phttp = new XMLHttpRequest(); // Global XMLHttpRequest - For polling changes from LSL script - GET phttp.timeout = 20000; // 20 second timeout phttp.ontimeout = function () { // On timeout, starts polling again if(debug)addtxt('timeout'); // Add debugging info to textarea startpoll(); // Open a new GET - start polling LSL script } phttp.onreadystatechange = function() { // Handle changes in GET request state if (this.readyState==4 && this.status==200) { // If success addtxt(this.responseText); // Add response to textarea setTimeout('startpoll()',500); // Start a new poll after 0.5 seconds if (debug) addtxt('Added timed poll for 500'); } }; function SendToLSL() { // Called when users clicks "SEND" button or ENTER key from field to send if (input.value.trim().length!=0) { // Only send if something was entered var xhttp = new XMLHttpRequest(); // XMLHttpRequest - For sending changes to LSL script - POST xhttp.onreadystatechange = function() { // Wait for a change if (this.readyState==4 && this.status==200) { // Add the POST response to textarea addtxt(this.responseText); } }; xhttp.open(\"POST\",\"GetSomeData\", true); // POST command xhttp.send(input.value.trim()); // Send POST to LSL script input.value = ''; // Clear input field } } function startpoll() { // Called to initiate a new GET poll if (debug) addtxt('polling'); // Add debug info to textarea phttp.open(\"GET\",\"GetSomeData\", true); // GET command phttp.send(); // Send GET to LSL script } // Startup code addtxt('Initialized.'); // Add to textarea focus(); // Set focus to input field setTimeout('startpoll()',500); // Start polling after 0.5 seconds Link to comment Share on other sites More sharing options...
Love Zhaoying Posted June 26, 2023 Author Share Posted June 26, 2023 Today I Learned: From a certain point of view, for my use-case there's not really a reason to use MOAP. If I just say the URL in chat instead of setting my HUD to MOAP, clicking the URL opens a nice window that works perfectly (so far.. I probably just jinxed it). Anyway, now that I know the option is there, I can more easily design the whole thing for non-MOAP. The "in-viewer browser" version looks a lot better, is more readable, etc. than the MOAP version. So the project becomes: not using "media-on-a-prim" or "shared media" but, "create a simple website/form from LSL that has NO external dependencies". Seems legit on the surface. Perhaps I'll keep going on this thread if I find "browser vs. MOAP" differences and issues, or make a separate one. Speaking of "differences between MOAP and in-viewer browser": I was starting to try "cookies" from the MOAP version and it did not work. It will be interesting to find out if cookies work from the "in-viewer browser", or if I need to open the website in Chrome. Any thoughts? Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 26, 2023 Share Posted June 26, 2023 (edited) 1 hour ago, Love Zhaoying said: Any thoughts? Goes beyond what I have specific knowledge in, but AFAIK, the 'in-viewer browser' and MOAP should be essentially the same save for one looking like it's in-world and the other being a pop-up. just posting a link in chat lets the user decide whether to open in the 'linden browser' or their preffered OS browser (right-click -> open in internal/external browser) (external browser is also great for people with dual monitors...). For links posted in chat, if you surround the link in '[]'s you can add nicer-looking text: "[http://www.duckduckgo.com Do the duck!]" when said in local becomes: Do the duck! Edited June 26, 2023 by Quistess Alpha 'dial'-> dual. why would I ever use my old CRT for SL?. . . 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now