P5.js: print("content") outside of setup/draw invokes print dialog. possible to catch with FES?

Created on 7 Feb 2020  路  20Comments  路  Source: processing/p5.js

Most appropriate sub-area of p5.js?

  • [ ] Color
  • [x] Core/Environment/Rendering
  • [ ] Data
  • [ ] Events
  • [ ] Image
  • [ ] IO
  • [ ] Math
  • [ ] Typography
  • [ ] Utilities
  • [ ] WebGL
  • [ ] Other (specify if possible)

Details about the bug:

  • p5.js version: 0.10.2
  • Web browser and version: Firefox 72.0.2
  • Operating System: MacOS 10.14 (Mojave)
  • Steps to reproduce this:

The following code causes the print dialog to appear in Firefox (using editor.p5js.org).

print("Hello world!")
bug friendly-errors

All 20 comments

Welcome! 馃憢 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, be sure to follow the issue template if you haven't already.

Hm odd! I am not able to recreate on Mac 10.15.2 using the online editor and Firefox 72.0.2. This sketch just prints the text in the console for me:

function setup() {
  print("Hello world!")
}

Ah, I'm realizing my mistake. I tried to use the print function all by itself, outside of the setup function. Coming from Java Processing, I expected this to work, and the reference examples for print don't include a setup or draw function.

I realize my case is probably a bit unusual, but it might be worth updating the documentation?

I don't think this is something we can specifically document just for print() as most functions in p5.js cannot be used outside of setup() or draw() before setup() or draw() is called. However, this behaviour should be caught by the friendly error system, not sure if it would be impossible to catch print() though.

@limzykenneth Can I work on this issue?

@debajitdeb11 Sure, do have a look at it. I'm not sure how would the FES detect print("something") is being used before initialization though as unlike the other functions, print() exist on the global scope. Let us know what you find, thanks!

Where is the source code for the online editor is located in the source file?
editor

The source code for the web editor is located in another repo but why do you need the source code for it for this issue?

i think this is a great place for FES. if someone is interested in working on it i鈥檓 also happy to answer questions, code review, whatever!

@debajitdeb11 if you are still working on this maybe window.onbeforeprint can help you? I am just guessing here but maybe using something like a check for _setupDone or similar inside it to call report() to trigger a friendly warning message?

@akshay-99 the thing with calling print(...args) outside setup or draw is that it gets called before the library is loaded and browser calls window.print() . So I think it's hard for FES to detect it.
A better way to go around situation will be to have a static function p5.print() alongside this one.

p5.print('Hello World'); // logs Hello World into console.
print('Hello'); // opens print dialog box
function setup() {
  // put setup code here
}

function draw() {
  // put drawing code here
}

@outofambit what do you suggest about this?
If there is way for it to be get detected by FES, I would like to work on it.

@DivyamAhuja I am sorry I didn't reply earlier. I must have missed this comment somehow.
When we use global mode, all of p5's API functions get attached to the window object when p5 is initialised.

Also you are right that the call is made before the library initialises. And hence my mention of_setupDone was wrong. But we can still use window.onbeforeprint :smile:
The FES has helpForMisusedAtTopLevelCode which currently handles many cases similar to this issue. helpForMisusedAtTopLevelCode is built such that it can work even before p5 is initialised. The reason it does not handle print() is due to the fact that print is already there in the window object and hence calling it does not produce an error.
But what if just before this line, we add this

window.onbeforeprint = () => {
    helpForMisusedAtTopLevelCode(new ErrorEvent('print', {message:'print used'}));
}

The effect of this now is that if a print() is called outside setup, onbeforeprint triggers and calls helpForMisusedAtTopLevelCode, passing to it a new ErrorEvent. The contents of this can be anything since it won't be put on the console. We just need to make sure that the message field has "print" somewhere in it so that the regex here can match it

It is interesting to note that there is another way to handle this, one that is not just limited to print but can work for anything else in the window object that may conflict with p5

We can simply redefine the function in the window object to make it pass through the FES before it executes its original task.
Lets assume we have a function something that is both defined in p5 and the window object. We can catch the use of something outside of setup and draw in the following way

let somethingBackup = window.something;
window.something = (params) => {
    helpForMisusedAtTopLevelCode(new ErrorEvent('something', {message:'something used'}));
   somethingBackup(params);
}

@debajitdeb11 @DivyamAhuja is anyone working on this?

@akshay-99 No, am not working on it. You can continue working on it if you want.

BTW calling print(); with no parameters invokes the browsers print dialog.
Which is really bad when using an online IDE like https://jsitor.com/ with auto run on
and you type print() before entering what to print in the draw loop.

Having a command to override the system print would be great, NoPrintDialog();

Could the sandbox flags be used to disable the window.print()?
https://html.spec.whatwg.org/multipage/origin.html#sandbox-propagates-to-auxiliary-browsing-contexts-flag

Or could we just hijack window.print() https://stackoverflow.com/questions/32181838/override-window-print-for-all-windows-using-window-prototype

I think overriding default print function with this should work.

const _windowPrint = window.print;

window.print = function(...args){
  if(args.length === 0){
    _windowPrint();
  }
  else{
    console.log(...args);
  }
}

current implementation adds print function to p5 class while overriding window.print will be helpful I think.
https://editor.p5js.org/DivyamAhuja/sketches/6zIHhzpg0

@DivyamAhuja ah that's interesting. I was talking about overriding it for catching its use for outside setup and draw to warn the user. But your idea of removing p5.prototype.print and overriding window directly is simpler.

One question I have in mind is instance mode, as this would leak p5's functionality to the global object even in instance mode. So hypothetically if the user is also using some other script that also overrides print, and using p5 in instance mode to avoid any clashes, this print functionality would still clash. Which means it would depend on the order of the import which script's print is used. But this is a very unlikely situation indeed.

@hellonearthis yeah I guess a command or a parameter which when called or set true, would map print to console.log even when called with 0 parameters would help in that case.

@akshay-99 Yeah, I didn't think of a case with multiple libraries. In this case overriding may really be flawed

I have had this print() problem when used inside a draw() loop.

p5 could treat print() as console.log('') to would prevent the browser print() to not popup
but there might also be a case to use print() so made add a printerMode(CONSOLE|PRINTER) to let the user enable the printer as the default could be console.

Overriding outside of the p5 scope is problematic unless it could be address like p5.print('hi');
but not sure on that point.

Was this page helpful?
0 / 5 - 0 ratings