Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

print("content") outside of setup/draw invokes print dialog. possible to catch with FES? #4272

Open
1 of 11 tasks
Tracked by #6215 ...
alexdmiller opened this issue Feb 7, 2020 · 23 comments
Open
1 of 11 tasks
Tracked by #6215 ...
Assignees
Milestone

Comments

@alexdmiller
Copy link

Most appropriate sub-area of p5.js?

  • Color
  • 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!")
@alexdmiller alexdmiller added the Bug label Feb 7, 2020
@welcome
Copy link

welcome bot commented Feb 7, 2020

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.

@stalgiag
Copy link
Contributor

stalgiag commented Feb 8, 2020

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!")
}

@alexdmiller
Copy link
Author

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?

@limzykenneth
Copy link
Member

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.

@debajitdeb11
Copy link

@limzykenneth Can I work on this issue?

@limzykenneth
Copy link
Member

@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!

@debajitdeb11
Copy link

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

@limzykenneth
Copy link
Member

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?

@lmccart lmccart changed the title print() function, even with content, causes print dialog to appear in firefox print("content") outside of setup/draw invokes print dialog. possible to catch with FES? Feb 25, 2020
@outofambit
Copy link
Contributor

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

@akshay-99
Copy link
Member

akshay-99 commented Feb 29, 2020

@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?

@DivyamAhuja
Copy link
Contributor

@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.

@akshay-99
Copy link
Member

@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 😄
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

@akshay-99
Copy link
Member

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);
}

@akshay-99
Copy link
Member

@debajitdeb11 @DivyamAhuja is anyone working on this?

@DivyamAhuja
Copy link
Contributor

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

@hellonearthis
Copy link
Contributor

hellonearthis commented Mar 30, 2020

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

@DivyamAhuja
Copy link
Contributor

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

@akshay-99
Copy link
Member

@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.

@DivyamAhuja
Copy link
Contributor

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

@hellonearthis
Copy link
Contributor

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.

@jht1493
Copy link

jht1493 commented Apr 1, 2021

This simple sketch is very easy for a novice user write.
In auto-refresh mode get into loop with print dialog repeating opening.
Must kill browser window/tab to stop.

I recommend print with no args call console.log.

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  print();
}

@Qianqianye Qianqianye added this to the 1.5.0 milestone Jul 27, 2022
@Qianqianye Qianqianye modified the milestones: 1.6.1, 1.7.0 Jun 15, 2023
@Qianqianye
Copy link
Contributor

Thank you all for working on this. I'd like to bump up this issue for the upcoming 1.7.0 release with another print() related issue #2765.
Since the issue was filed a while ago, what will be the good next steps to move this issue forward? @limzykenneth @davepagurek. Also adding GSoC FES contributor @Ayush23Dash and mentors @almchung @nbriz to this discussion.

@Qianqianye Qianqianye mentioned this issue Jul 1, 2023
4 tasks
@limzykenneth
Copy link
Member

With the suggested beforeprint event it is possible to catch print being called outside of setup and draw to print a FES warning, this possibly can be implemented in helpForMisusedAtTopLevelCode as a special case. It won't stop the print dialog from showing, nor should it really for instances of it being used outside of setup and draw. @Ayush23Dash if you need help with this do let us know.

For the more general case for print() with no arguments opening print dialogs when used in draw() we can focus discussions on #2765. I have a couple vague ideas how this may be solved but have not yet tried it out but if there's idea for solutions that can preserve both print("something") and print() behaviours, do leave a comment in #2765.

@Qianqianye Qianqianye modified the milestones: 1.7.0, 1.7.1 Jul 10, 2023
@Qianqianye Qianqianye mentioned this issue Oct 12, 2023
7 tasks
@Qianqianye Qianqianye modified the milestones: 1.8.0, 1.9.0 Nov 23, 2023
@Qianqianye Qianqianye mentioned this issue Nov 23, 2023
7 tasks
@Qianqianye Qianqianye modified the milestones: 1.9.0, 1.9.1 Dec 1, 2023
@Qianqianye Qianqianye mentioned this issue Feb 22, 2024
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants