HTML5 canvas intellisense in Visual Studio Code - visual-studio-code

is there a way to get intellisense for the HTML5 canvas element? In VS Code 0.7.10 when I write in my JS code this:
context = document.getElementById(canvasId).getContext('2d');
then when I write
context.
I do not have any intellisense help for my context.
Thanks.

VS Code can support it!
Just tell VS Code what type is the context. Adding the following code on your variable then the VS Code will know what it is. Sorry that I don't have enough point to post the image. Just click the solution to see how it works.
/** #type {CanvasRenderingContext2D} */
solution

That's currently not supported by VS Code and it is hard to fix. Because JavaScript lacks type annotations, VS Code tries to flow types as good as possible. In your example document.getElementById breaks this flow because from the spec it can return any html element (and we have no further knowledge of the html structure or the value of canvasId).
Something like this, would be more favourable to VS Code:
var canvas = document.createElement('canvas');
canvas.|
Alternative, you could look into using TypeScript because there you use type annotations and type casting.

I use the "type cast":
var canvas = /** #type {HTMLCanvasElement} */ (document.querySelector('#canvas'))
and then enjoy basic Intellisense:

You have to re-declare #type variable and assign ctx to get the intellisense working again when you pass ctx as argument in another function. this worked for me in react :
const drawGame=(ctx)=>{
/** #type {CanvasRenderingContext2D} */
var dgCtx = ctx
dgCtx.fillStyle = "#79d70e"
dgCtx.fillRect(0,0,gs.width, gs.height)
}
useEffect(()=>{
const canvas = canvasRef.current
/** #type {CanvasRenderingContext2D} */
const ctx = canvas.getContext("2d")
drawGame(ctx)
},[])

Related

How do I clear an element before rendering?

I have inherited an older project using jquery.
I am modernising the code.
In particular this $(selector).html("<h1>lol</h1>"); which as far as I understand is a full replacement of the selectors content.
I always end up with an error if I try to render to a cleared element.
This code:
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<h1>TypeScript Starter</h1>`;
// trying to replace jquery $(selector).html("<h1>lol</h1>");
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
Or see my stackblitz
I always get the following error:
Error in lit-html.js (93:55)
Cannot read properties of null (reading 'insertBefore')
Do you know what I am missing? 🧐
Thanks!
Note: This is a duplicate of my question (and based on a suggested technique) from a closed Lit Github Issue
Note: Maybe I am talking rubbish. I can't find a clear answer if render REPLACES content or APPENDS content. A concrete answer on that would be fine!
Lit v1 will clear the container before rendering the first time. Lit v2 will not.
Only clear the existing container content once before using render. After that render will correctly update content from previous render calls.
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<h1>TypeScript Starter</h1>`;
// trying to replace jquery $(selector).html("<h1>lol</h1>");
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
render(html`<h1>lol2</h1>`, appDiv);

WEBGL autocompletion in VS CODE

I have a school project and i need to use WEBGL. But its pretty difficult to write all the code without autocompletion. I didn't find proper extension. Do you have ideas?
In order for visual studio code to give you auto completion it needs to know the types of variables.
So for example if you have this
const gl = init();
VSCode has no idea what type the variable gl is so it can't auto complete. But you can tell it the type by adding a JSDOC style comment above it like this
/** #type {WebGLRenderingContext} */
const gl = init();
Now it will auto complete
The same is true for HTML elements. If you do this
const canvas = document.querySelector('#mycanvas');
VSCode has no idea what type of element that is but you can tell it
/** #type {HTMLCanvasElement} */
const canvas = document.querySelector('#mycanvas');
Now it will know it's an HTMLCanvasElement
And, because it knows it's an HTMLCanvasElement it knows that .getContext('webgl') returns a WebGLRenderingContext so it will automatically offer auto completion for the context as well
Note that if you're pass the canvas into some function then again, VSCode has no idea what that function returns. In otherwords
/** #type {HTMLCanvasElement} */
const canvas = document.querySelector('#mycanvas');
const gl = someLibraryInitWebGL(canvas);
You won't get completion anymore since VSCode as no idea what someLibraryInitWebGL returns so follow the rule at the top and tell it.
/** #type {HTMLCanvasElement} */
const canvas = document.querySelector('#mycanvas');
/** #type {WebGLRenderingContext} */
const gl = someLibraryInitWebGL(canvas);
You can see other JSDOC annotations here if you want to document your own functions, for example their argument and return types.

Visual Studio Code loops in snippets

Is there a way how to use loops or conditionals when creating snippets in VS Code? I am trying to create a snippet that will generate a template for JSDoc documentation syntax for a function. Example (I am using coffeescript):
myFunction: (param1, param2): ->
# some code
return
And I would like a snippet that generates:
###*
* #param {} param1
* #param {} param2
* #return {}
###
myFunction: (param1, param2): ->
# some code
return
I am able to create a snippet, that will simply generate:
###*
* #return {}
###
using this snippet settings:
"JSDocs Template": {
"prefix": "jsdoc",
"body": [
"###*",
" * #return {}",
"###"
],
"description": "create template for JSDocs"
}
But to achieve want I need, I would have to use a loop to go through the param list and that is where I struggle...
I am not sure is that possible using snippets. You can achieve this by writing your own extension using VS Code API.
But you can use this extension
https://marketplace.visualstudio.com/items?itemName=stevencl.addDocComments
to achieve what you trying to achieve in your example.
Update:
You have to modify this extension script a little bit.
Go to C:\Users\%UserProfile%.vscode\extensions\stevencl.adddoccomments-0.0.8\out\
Add this additional logic in the 'extension.js' file.
Right now it only works for the ts and js file. Just added the coffeescript language type.
And it works!!!
Mark it right ans if you agree.
So after some research I found out that such a behaviour is not possible with snippets only, therefore I have create my own extension CoffeeScript JSDoc. Feel free to use it and extend it if necessary...

VSCode : It is not showing java script functions in intellisense e.g. .toLowerCase

VS Code is an amazing text editor but I am facing some issues.
ISSUE
VS Code not showing IntelliSense for basic javascript functions like myVariable.toLowerCase();
Please let me know if there is any solution for this.
Thanks VS Code team for making development beautiful!
I'm on the VSCode team.
We cannot infer the types of JavaScript variables like categoryName in many cases, so we cannot know that toLowerCase is a valid method on categoryName. There are a few ways to fix this:
Use jsdoc to specify the argument type:
/**
* #param {string} categoryName
*/
function foo(categoryName){
// `string` member completions avalible here
}
Add a guard to the function:
function foo(categoryName){
if (typeof categoryName !== 'string')
return
// `string` member completions available here
}
Use TypeScript or Flow types
function foo(categoryName: string){
// `string` member completions available here
}
Hope that helps.

mshtml fireevent onchange not firing

I am unable to fire an "onchange" event in mshtml. Can you please tell me what I am doing wrong here.
HTMLSelectElement element = (HTMLSelectElement)this.HTMLDocument.all.item(controlId, 0);
IHTMLElement e = element as IHTMLElement;
IHTMLDocument4 doc = e.document as IHTMLDocument4;
object dummy = null;
object eventObj = doc.CreateEventObject(ref dummy);
HTMLSelectElementClass se = element as HTMLSelectElementClass;
se.FireEvent("onchange", ref eventObj);
I am getting variable "se" as null. I got this piece of code from another link http://www.itwriting.com/phorum/read.php?3,1507
Can anyone help me with this.
Thanks,
Sam
Runtime Callable Wrapper objects generated by COM calls like HTMLDocument.all.item can translate interface casting to QueryInterface calls. But the RCW does not know how to convert to a managed class like HTMLSelectElementClass, thus it returns null.
Instead of casting to HTMLSelectElementClass, cast to IHTMLElement3 to call fireEvent.
By the way, your code does not work in IE11 mode as document.all is deprecated. Use IHTMLDocument3::getElementById instead.
I had tried all those which Sheng mentioned but didn't work.
This issue was solved by injecting javascript code for "onchange" and executing it. It worked.