HTML with Transcrypt script gives missing { before try block error - javascript

I am trying to add a javascript file that generated via Transcrypt from Python file.
However, when I add that script to my HTML file, there are some errors appeared in Console and I failed.
The Python file that I used: try.py
def greet():
name = document.getElementById("Name").value
if name == "" or name.length == 0 or name == null:
document.getElementById("groet").innerHTML = '<p><font color="#ff0000">Hello Anonymous, may I know yor name? Please insert it below:</font></p>'
else:
document.getElementById("groet").innerHTML = '<p><font color="#00ff00">Hello, '+name+', thank you for introducing you</font></p>'
After that script, I ran the command python3 -m transcrypt -b try.py and a folder called "target" created automatically and it contains a file "try.js".
So, I wrote a HTML file which is a basic sample that shows a greeting message: hello.html
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="__target__/try.js"></script>
</head>
<title>Insert Text</title>
<body onload=try.greet()>
<h2>Hello Demo Name</h2>
<p>
<div id = "groet">...</div>
</p>
<p>Your Name: <input name="name" type="text" maxlength="80" id="Name" value=""/> [Please enter your name]<br><br>
<button onclick=try.greet()>Refresh the greeting!</button>
</p>
</body>
</html>
I am expecting that when I clicked the button or reload the file the greeting message should be placed. However, in console I got two errors:
Uncaught SyntaxError: import declarations may only appear at top level of a module try.js:1:13
Uncaught SyntaxError: missing { before try block hello.html:1:3
So, what is the problem guys?
[EDIT]
After the T.J's answer, I updated the html file as following:
'use strict';import{AssertionError,AttributeError,BaseException,DeprecationWarning,Exception,IndexError,IterableError,KeyError,NotImplementedError,RuntimeWarning,StopIteration,UserWarning,ValueError,Warning,__JsIterator__,__PyIterator__,__Terminal__,__add__,__and__,__call__,__class__,__envir__,__eq__,__floordiv__,__ge__,__get__,__getcm__,__getitem__,__getslice__,__getsm__,__gt__,__i__,__iadd__,__iand__,__idiv__,__ijsmod__,__ilshift__,__imatmul__,__imod__,__imul__,__in__,__init__,__ior__,__ipow__,
__irshift__,__isub__,__ixor__,__jsUsePyNext__,__jsmod__,__k__,__kwargtrans__,__le__,__lshift__,__lt__,__matmul__,__mergefields__,__mergekwargtrans__,__mod__,__mul__,__ne__,__neg__,__nest__,__or__,__pow__,__pragma__,__proxy__,__pyUseJsNext__,__rshift__,__setitem__,__setproperty__,__setslice__,__sort__,__specialattrib__,__sub__,__super__,__t__,__terminal__,__truediv__,__withblock__,__xor__,abs,all,any,assert,bool,bytearray,bytes,callable,chr,copy,deepcopy,delattr,dict,dir,divmod,enumerate,filter,float,
getattr,hasattr,input,int,isinstance,issubclass,len,list,map,max,min,object,ord,pow,print,property,py_TypeError,py_iter,py_metatype,py_next,py_reversed,py_typeof,range,repr,round,set,setattr,sorted,str,sum,tuple,zip}from"./org.transcrypt.__runtime__.js";var __name__="__main__";export var greet=function(){var py_name=document.getElementById("Name").value;if(py_name==""||py_name.length==0||py_name==null)document.getElementById("groet").innerHTML='<p><font color="#ff0000">Hello Anonymous, may I know yor name? Please insert it below:</font></p>';
else document.getElementById("groet").innerHTML='<p><font color="#00ff00">Hello, '+py_name+", thank you for introducing you</font></p>"};
//# sourceMappingURL=hello.map
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module">
import { greet } from "./hello.js";
document.getElementById("greetButton").onclick=greet();
</script>
</head>
<title>Insert Text</title>
<body>
<h2>Hello Demo Name</h2>
<p>
<div id = "groet">...</div>
</p>
<p>Your Name: <input name="name" type="text" maxlength="80" id="Name" value=""/> [Please enter your name]<br><br>
<button id="greetButton">Refresh the greeting!</button>
</p>
</body>
</html>

import declarations may only appear at top level of a module
is fairly clear: You're not loading the script as a module, so you can't use import. Add type="module" to the script tag. (But be sure that your target browsers support modules -- all modern major ones do, but you don't have to go more than a few versions back in some before module support isn't there.)
missing { before try block
You have
<body onload=try.greet()>
try is a keyword in JavaScript, you can't use it as an identifier. You'll need to use a different name for your try object. (I'll use xtry in the rest of this answer.)
If your code really is a module, you also won't be able to use your xtry as a global, even if it's declared at the top level of your code, because the top level scope of a module isn't global scope. You'll need to import it to use it. That also means you don't need a script tag for try.js since the import will do it. Remove the onload and your current script tag and instead:
<script type="module">
import { xtry } from "__target__/try.js";
xtry.greet();
</script>
That won't run until the HTML has been fully parsed and the DOM has been populated (because of the type="module").
Side note: onload attribute handlers are generally not best practice, for two reasons: 1. They can only use globals, and 2. The load event happens very late in the page load cycle, waiting for all resources (including all images) to load. Sometimes that's what you want, but not often. Instead, use modern event handling (if you really need to hook up a handler on load) and use modern script techniques (type="module", defer, ...).

In addition to #T.J. Crowder's answer, I changed the script in html as:
<script type="module">
import * as hello from "./__target__/hello.js";
window.hello = hello;
</script>
As explained in the tutorial of Transcrypt.
With this way, I can call the Python function on button's click.

Related

Running scripts with content pulled from local storage with innerHTML

I've been playing around with web development and wanted to create a basic application which allows users to enter html into a text area, which is saved in local storage, then later inserted into a document element with .innerHTML.
Minimum working example:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prototyping</title>
</head>
<body>
<!--- Using bootstrap v. 5.2.0 --->
<form>
<label for="content"></label>
<textarea class="form-control" id="content"></textarea>
</form>
<div id="displayContent"></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2"
crossorigin="anonymous"></script>
<script src="index.js"></script>
</body>
</html>
JavaScript
const userInput = document.getElementById('content');
const displayInput = document.getElementById('displayContent')
userInput.addEventListener('input', (event) => {
localStorage.setItem(event.target.id, event.target.value);
displayInput.innerHTML = localStorage.getItem(event.target.id);
});
Now I was concerned that using .innerHTML would allow users to inject js code <script>alert('HAHA')</script>. However, scripts fail to run. Or at least with my limited knowledge of HTML, I cannot get a script to run. This is what I want, but I don't understand why. When inspecting the page, I will see the <script>. Is this because localStorage converts the input into strings? What is happening that prevents the script from running?
The reason why the alert you try to inject "fails to run", is because at this stage the DOM is already parsed and all the javascript within it is already executed. So, the code would not be executed again.
Still, since you are inserting HTML, any HTML that will be added, will also be rendered. And with that, there are also some ways to execute javascript-code like this. One example is the following snippet as an input:
<img src=z onerror="alert('Injected code')">
Similar results could be achieved with other event-listener-attributes or deferred scripts.
However, if you only save and open the input on the client-side and not expose it to other users, there is no way it could do any damage. It would be the same as if you use the console in the developer-menu that is built-in in every modern browser (F12 in most of them).
If that is still a problem for your use-case or you expose the inputs to other users, I would strongly recommend you to parse the text-input so that no js-code would be executed.
Probably the safest way of achieving this could be to only insert text instead of HTML:
displayInput.textContent = localStorage.getItem(event.target.id)
Another way could be could be to encode the < and > to their html equivilant (source):
let content = event.target.value.replace(/</g, "<").replace(/>/g, ">")
localStorage.setItem(event.target.id, content)
displayInput.innerHTML = localStorage.getItem(event.target.id)
I hope this helps. Keep it up!

linking extrenal javascript file inside head tag not working

i have linked my script.js file to my index.html file and both files are in same directory. i have linked that script.js file in section but that is not working when i open-up the console it is shwoing
script.js:2 Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
but whenever i link that file in the last part of the section perfectly, even putting that file in the first section of also not working.
inde.html:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="script.js"></script>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<p id="name">
<span>john</span>
</p>
</body>
</html>
script.js:
var result = document.getElementById("name");
var final = result.getElementsByTagName("span");
console.log(final);
Scripts can go in the head so long as the logic that tries to find elements in the DOM, happens after the DOM is loaded.
As covered by the duplicate, the usage of a document ready or a load event handler on the window allows any logic to be put in the head, without having to worry about the DOM being loaded yet, as they delay the execution of the logic until the DOM is loaded.
Thank You #taplar

6 javascript tasks assigned to me by my lecturer

I am a complete beginner to javascript. I am also new to this website. I am asking for help to complete an assignment. I have been trying for more than 4 hours by looking at lecture material and online for a solution. It is causing me a lot of unnecessary stress. Before javascript we only used CSS and Html. I was given 6 javascript tasks to manipulate the html file (taskc.html) already given to me.
The tasks are as follows
Make a statement to change contents of h1 from "Welcome" to "Text"
2nd statement should make an new alert window when the page loads that delivers a message explaining what the page is about
3rd statement should change the title to "text"
4th statement should log the contents (innerHTML) of the first paragraph element in the console.
5th statement should hide the contents of the second paragraph when the page loads
6th statement should change the contents of the header to have a new colour of your choice
Here is that html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Task C - The Document Object Mode</title>
</head>
<body>
<h1 id="header">Welcome</h1>
<p id="first">This site uses JavaScript</p>
<p id="second">Javascript is very useful</p>
</body>
</html>
Because the actual coding im meant to add is meant to be in the .js file I was given. so I figured I had to link the js file in the html file so I added
<script type="text/javascript" src="taskc.js"></script>
With that out of the way I went to the lecture notes and I thought I would simply need to modify some of the code given to me there like
document.getElementById('demo').innerHTML = 'Hello World!';
When I put this code in brackets I got the error (document is not defined)
I modified it to match the requirements for task 1
here it is
document.getElementById('header').innerHTML = 'text';
I was confused because I didn't know what this error meant and of course Errors and how to fix them are never explained so I had to lookup how to resolve the error.
I found that to fix it I have to declare it as a variable so I ended up doing this.
var document = 'taskc.html';
When I did this for document, alert and console all the errors went away, but when I did a live preview only statement 1 was working
If anyone could help me fix this I would really appreciate because I don't understand enough javascript to be able to complete this in a reasonable amount of time.
So first: Please use Javascript functions to keep your code tidy and clean.
Example:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Task C - The Document Object Mode</title>
</head>
<body>
<h1 id="header">Welcome</h1>
<p id="first">This site uses JavaScript</p>
<p id="second">Javascript is very useful</p>
<script type="text/javascript" src="taskc.js">test();</script>
</body>
</html>
function test(){
alert("This is a test!");
}
Always implement scripts that are document referenced at the bottom of your html.
If you use JQuery you can use following code to check document is loaded:
$(document).ready(function(){
//foo bar
});

JavaScript intellisense not working correctly

On my visual studio code and visual studio(ide) in javascript file intellisense working not correctly rather intellisense opening but not showing properties or methods only showing history what I've typed into the js file, screen: https://pastenow.ru/67UPL . Code working, event have keyCode property but I can't see this property in intellisense. I tried on dreamveawer, jetbrains rider - event has keycode property and other method properties.
How do I solve the problem?
js file:
function KordinatlariGoster(event) {
document.Kordinatlar.txtX.value = event.clientX;
document.Kordinatlar.txtY.value = event.clientY;
}
html file:
<html>
<head>
<title>4N71K</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/Main.css" />
<script src="scripts/script.js"></script>
</head>
<body onMouseMove="KordinatlariGoster(event)">
<form name="Kordinatlar">
<label>X oxu : <input type="text" name="txtX"></label>
<label>Y oxu : <input type="text" name="txtY"></label>
</form>
</body>
</html>
As JavaScript is weakly typed language and thus the interpreter cannot know before hand what will be present in an Object or the type of the object, so it cannot provide proper suggestions using intellisense. While we strongly typed languages such as java, kotlin etc; the intellisense can know the members of the Object and provide with suggestions.Hope this helps

Can i access html element Id from any from anyfiles?

I am a beginner to Java-script.
i have a concern
on mainPage.html
<div id="showDialog" style="display:none"> </div>
on mainPage.js
$('#ShowDialog').load("../xxxx.html", function (content) {
xxxxxxxxxxx
});
It is easy understand that if you want to use the id element you just call #element
So, my question is here:
if you are in Setup.js (setup.html has no id attribute like #ShowDialog)
can you still call (So, it will do something on mainPage.html ?? )
$('#ShowDialog').load("../xxxx.html", function (content) {
xxxxxxxxxxx
});
If so, is the class also do the same job? i know id is unique and class is common. So, if one file class can be accessed from other file?
like
$('.ShowDialog').load("../xxxx.html", function (content) {
xxxxxxxxxxx
});
By the way, why we call class using $(.'ShowDialog')rather than just call name like $('ShowDialog')
for class="ShowDialog"
If you want to reference an html Element from an external Javascript file it could be as follows:
myHtml.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- First Import Jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Then the module you wish to work with-->
<script src="./ReferencebyId.js"></script>
<title>referencing html Element by Id</title>
</head>
<body>
<!-- the Id you will reference on the module -->
<p id="myId">Change this text</p>
<button onclick="changeInnerHtml()">Change paragraph text</button>
</body>
</html>
ReferencebyId.js
function changeInnerHtml(){
//This is how you would reference the Id, with '#' character
$("#myId").text("changed from external js file referencing Id");
}
Remember that if you wish to use the class to reference the Html Element, you have to make sure only that element has that class, or if you wish to affect more than one element you can put them the same class, and reference them as $(".nameOfClass")
Could you please explain what is it that you are trying to do?
As I understand from your code, you are trying to load content from an external HTML to other HTML with the load function in JQuery and place it inside the div with id="showDialog"
$('#ShowDialog').load("../xxxx.html", function (content) {...}
Is this what you are trying to do? or are you trying to run some JavaScript from other file?
What do you mean by:
setup.html has no id attribute like #ShowDialog
does setup.html does not have any div with that id?
and by:
can you still call (So, it will do something on mainPage.html ?? )
call what? the loader.
about:
By the way, why we call class using $(.'ShowDialog')rather than just call name like $('ShowDialog')
The preceding dot (.) is because classes on jQuery selectors are specified with a preceding dot (.), and id's with a hash sign (#), think of it, like Css selectors, but in jQuery.
Please explain exactly what are you trying to do so we can help you better :)

Categories