<canvas> in greasemonkey - javascript

I've created a <canvas>, in the variable canvas, but I can't seem to draw to it. I can see the blank canvas on the page, but it's blank.
alert(ctx);
ctx.fillStyle = "rgb(50,50,50)";
ctx.fillRect(10,10, 55,50);
alert("done");
The first alert says [object CanvasRenderingContext2D], and I do see the "done" alert, but the canvas is still blank. There are no relevant errors in the error console.
edit: Just to make sure, I pasted the script into a stand alone html page, and it worked as expected.

Canvas works fine for me in Greasemonkey. Post your Greasemonkey script; and what browser are you using?

I've figured out what the problem is, and I'm not sure if it's really a problem in firefox/greasemonkey.
First of all, the script is written for a private site, you'd need an invite to to see the page that it's on, so I posted what I thought was the relevant part of the script, but turns out it wasn't.
The problem was that after creating the canvas, I modified (+=) the .innerHTML of the content div (which I know is bad practice, but it works for greasemonkey that doesn't need to work in every browser). I imagine that this would completely destroy the previous tree, and then recreate it with the new content string given, which would mean that the canvas I had a reference to was no longer the one being displayed on the page, it was one that had been recreated, so my reference was meaningless, and hence when I drew to it, I got no error, but saw nothing. I imagine that if I used that reference to add it back to the page, I should have seen what I'd drawn.
The problem was fixed by not appending to the .innerHTML, I imagine that if I use the proper DOM methods to create the div that I want to add, and then append it to the tree, I should not have this problem (have not yet tested this, though).

Related

Higher priority of dialogues window than DOM elements

I've got a strange problem with displaying elements on page in a good order. I want to show at the begining document.write with welcome, then ask for a name with prompt and at the end show the result on the page. Somehow before anything shows a prompt is displaying. Why is this happening? This is for a school purpose :)
document.write(`Hello `);
const text = prompt(`what's your name?`);
document.write(`${text}, nice to meet you :)`);
If something is unclear, feel free to ask :)
As discussed in the comments, this works differently in different browsers and I suspect that is due to how browsers go about their rendering cycles.
It goes beyond document.write, if you try to append an element to the document you will observe the exact same behavior.
I tried to force chrome to render in-between the write/append calls but it sturdily refused to. I'm guessing this is some kind of supposed optimization on their side, not sure, but if you really insist on doing that you'll have to employ an additional context, and that will not work with document.write as it will overwrite whatever is already in the document.

Jquery image bookmarklet not working in Django

Im working through Django By Example and in one chapter a Jquery bookmarklet is built within a Django app so that a user can easily save jpg images from a website into their user profile area within the Django app.
Im not an experienced JS or Jquery programmer but I did some JS some years back and can read the code however the tutorial does give exact instructions on what to do which I have followed and although I have managed to get the bookmarklet button to appear in my bookmarks bar in Chrome, nothing happens when I click it when browsing a webpage with jpg images.
This is my local Django dashboard where the bookmarklet button is added to the bookmarks bar and this part works fine
and this is what it should look like when clicked on, this is the part where nothing happens for me
these are the relevant js files
https://github.com/davejonesbkk/bookmarks/blob/master/images/templates/bookmarklet_launcher.js
https://github.com/davejonesbkk/bookmarks/blob/master/images/static/js/bookmarklet.js
the only thing I can see that is different with these compared to the files that came with the book is the indentation is a bit off but for some reason the indentation does seem to have changed a bit when I uploaded to Git and they dont look like that locally. Is indentation important in JS?
I followed the same book with the same examples but didn't had any trouble. Make sure your dashboard.html file is referring to the correct javascript file. If nothing works try to add the bookmark manually, you can see how that's done over here http://www.howtogeek.com/189358/beginner-geek-how-to-use-bookmarklets-on-any-device/ it'll sure to work.
And answer to your last question, Indentation is not as important in JavaScript as it's in Python, as python doesn't use any curly braces "{}" or semi-colons ";". But you can write your entire javascript code in a single line and it'll work because your using curly braces everywhere to tell which line of code ends where.
I agree with all the above. In addition, the following:
Error I noticed in the book:
In bookmarklet-launcher.js the js function being called from bookmarklet.js is called myBookmarklet(), however there is no function called this way in bookmarklet.js. So, you may want to use the same name in both js files.
Practically speaking however, the bookmarklet will always work because, not finding a myBookmarklet function in memory, bookmarklet-launcher.js appends the bookmarklet.js script to the body element and, being bookmarklet.js a self-invoking function, its content executed (without the need it to being called). There are some additional interesting technicalities here (the key function in bookmarklet.js is not self invoking but it will anyway be always called because of the script checking whether jQuery is present...) but ok, this is more relevant for those busy with the mentioned book (Django 2 by example).
Check whether bookmarkled, once you click on it, is added to the
current webpage:
2.1. Open devtools (F12 on Chrome) and check e.g. in the html head element whether you find the newly added link element containing the css attribute and/or in the body element whether you find the script element containing the reference to the bookmarklet.js file.
2.2. Alternative: Add an alert message on top of the bookmarklet.js script so that it will be launched if it is correctly loaded. Example:
(function(){
alert('bookmarkled loaded!');
var jquery_version =...
Make sure you're trying to use it on a HTTP site only. Since you're serving from same protocol. HTTPS site would always tell say: There is a problem loadingbyour jquery. That's how I solved mine.
dude.I have solved the problems I met like you.
The most important thing is that noticing the syntax error(without warnings),mainly caused by ignoring blank.
for example, in the line:
jQuery('#bookmarklet .images').append('<img src="'+image_url+'"/>');
between #bookmarklet and .images should lie a blank space,because of jquery syntax rules(meaning to search tag with id of bookmarklet and search tag with class equaling images within result previously).
Another two places worth notice are codes containing #bookmarklet .images a and #bookmarklet #close,requiring blank spaces between filter condition.
That's where I found I made mistaks mainly after studying syntax of jquery.
You'd better compare your codes with codes already loaded up to github by someone to make sure there are no more little errors(such as spelling).

Run Javascript/jQuery inside iframe

I'm currently working on a web editor where you can enter your HTML, CSS and JavaScript code and see the result in real time. Something similar to JSBin or JSFiddle. (I'm doing that to get an offline editor)
I've already been through many problems especially when it comes to CSS but I solved them by using an iframe and injecting all my code into it. And that works amazingly well until you type some JavaScript.
I'm sending the code between <script></script> but unlike CSS it won't run. What's very weird is that when I enter something like $('button').css('color', 'red');, the buttons of the editor effectively get affected but not those of my iframe. Exactly the opposite of what I expected. I've tried many things, looked at many topics on the forum, but nothing works. I also tried to load a blank page in my iframe. In that case, JavaScript runs but it becomes impossible to edit the code in the iframe! What's going on? Where am I going wrong? Thank you in advance for your help!
Here's my editor : https://jsbin.com/tuqite/edit?html,js,output/
Try updating the content of the iframe like this.
// this string contains both html and script
var html_string= "content";
document.getElementById('childFrame').src = "data:text/html;charset=utf-8," + escape(html_string);
By directly updating the iframe DOM like the way you are doing may not be the right way .

Content Scripts: Page-worker - <body> element with 0 width

I want to automatically open a website and reveal details about the rendered DOM. For that purpose I use a page-worker (https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/page-worker). When in the content script I execute something like the following:
var body = document.getElementsByTagName("body")[0];
console.log(getComputedStyle(body).width);
console.log(body.getBoundingClientRect().width);
The output is "0" for both of the width values. The same also applies to other elements. Should I conclude that DOM elements are not rendered properly when using a page-worker? Is there a way to gain authentic data from that? Or is there any other proper way to get details about the rendered DOM that behave exactly like the website was opened in a web browser by hand? Because if I open the same website manually and execute the same commands, it reveals (correctly) the width of the window (1440), of course.
edit
I probably should have said that before, but:
It's not that gaining the values does not work at all. If I go deeper in the DOM structure, I get correct values. I only have problems with the root body element, I think. Weirdly enough if I execute the exact same commands on the firefox console, the return values are perfectly correct.
It's very interesting the way you do it.
You don't have to do getElementsByTagName to get the body element, its a property of the document object var body = document.body;
getComputedStyle is a function of the window object so that's why it works without you putting window. in front of it but still just want to let you know.
You dont do a getPropertyValue which is required for getComputedStyle, I just tried it without it and it worked but i never saw it used like that before so maybe that has something to do with it:
So doing this from bootstrap or from scratchpad window: gBrowser.contentWindow.getComputedStyle(gBrowser.contentDocument.body).getPropertyValue('width')
works for me.
From your content-script scope do:
window.getComputedStyle(document.body).getPropertyValue('width')
If it still doesn't work I would thinky maybe myabe maybe, thers a chance you might be executing the code to early.
Let me know how that works.

Can you insert a form onto a page using jQuery's $.load() function?

I have a page where there's a drag and drop table where the order of the rows determines the value of a subtotal. However, it's more complicated than just addition and I would rather not duplicate the logic in JavaScript to update the values.
A simple solution would be to reload the whole page using Ajax and then replace the table from the page fetched via Ajax. Perhaps it's not the most elegant solution but I thought it'd be a quick way to get the job done that would be acceptable for now.
You can do that with jQuery like this:
$('#element-around-table').load(document.location.href + ' #table-id');
However, my "simple" solution turned out to not be so simple because the table also contains a <form> tag which is not being displayed in Firefox (Safari works).
When I inspect the page using Firebug, I see the form, but it and its elements grayed out.
Searching on the web, I found a rather confused post by a guy who says FF3 and IE strip <form> tags from innerHTML calls.
I'm probably going to move on to do this some other way, but for my future reference, I'd like to know: is this the case?
That post is rather confused, I just tested your code and it worked fine. The form tag was shown in firefox 3.0.8 just fine.
Looking at you code example, though I wonder if you just gave an incomplete example... make sure that the page you call returns only the html that goes inside that wrapper element.
I've run into this type of thing before. FORM tags need to be added to the DOM. If they're added using a method that writes to innerHTML, the tag will appear, but it won't be there as far as JavaScript is concerned.

Categories

Resources