I have latests CefGlue version (3.2272.2035)
I need to save current page as PDF. I'd like to interact with my CEF somehow (JS/C#) and make it create PDF for me.
I've tried to use javascript.window.print() for that purpose with no success, because, all i've got is such window.
I've found OnPrintJob method in CefPrintHandler but I don't know what is the right way to call it + comments say: "Implement this interface to handle printing on Linux"
and I need to handle printing to pdf on Windows environments (both x64/x86)
Any code example would be appreciated. Thanks in advance for any help.
You'd need to merge this patch and recompile cef from source; Besides, you might have to add some glue logic to CefGlue. I tested the patch myself (on C++ API) and it worked fine.
EDITED: the patch will be merged in trunk.
If you only need to print some pages (specially if these pages are under your control), you will do just fine. However if you need (as I did at the time) to print almost anything, you'll probably face the fact that some web pages don't render anything useful to the print view. Also, even those well-behaved diverge significantly from what you see on the screen - and that's not a CEF behavior, as even google chrome showed the same issues. In my application this was a no-go so I dropped printing and started capturing the screen (and implemented saving that to a pdf using a pdf library in C++), but perhaps your application isn't as demanding as mine was. Cheers!
Related
Final Update
For most practical purposes, this question is obsolete as both firefox and chrome have native support for avif through the standard picture html tag with a source marked as type="image/avif". See https://reachlightspeed.com/blog/using-the-new-high-performance-avif-image-format-on-the-web-today/ . Fire fox still likes to hang and often forces a control F5 to bypass caches and requires sending the correct content type from the server. Hopefully will be fixed soon.
Here is the commit where I got avif support working: https://github.com/quackack/quackack-comics/commit/f1a98ed1f40b6a22584d61bc338bd91df3232fa5#diff-e25b0950ce48f4e928f98e0a6fbb694c . Note that it contains many unrelated changes and in fact avif is barely mentioned, only as a content type and a file extension.
Original Question
I am trying to change a website where I host web comics from using jpegs to the newer avif image format. It is much smaller and seems to be the new image format with the most widespread support. Unfortunately, web browsers don't properly support the new format yet. So I was planning to use this package: https://github.com/Kagami/avif.js to allow my comics to be rendered. Some basic tests showed that AVIF would give the same quality as jpeg for less than half the space.
Unfortunately, after more than 5 hours of time spent on this, I am unable to get this to work with my react framework. You can see my website at the time of writing at 'https://github.com/quackack/quackack-comics/tree/cda4c3893d8477192c4ff3aa78d00096b7621ff7'.
I tried using npm install to install avif.js and then added
require("avif.js").register("/avif-sw.js");
to index.js . But I get error
Failed to register/update a ServiceWorker for scope ‘http://localhost:3000/’: Bad Content-Type of ‘text/html’ received for script ‘http://localhost:3000/avif-sw.js’. Must be a JavaScript MIME type
And avif files are still not able to load. I think the requests are getting rerouted to index.html instead of the javascript package. It seems like the appropriate thing to do is something like
import * as avif from 'avif.js';
avif.register('avif.js/avif-sw.js');
But this fails too with the same error, as do many other similar variations.
At this point I am inclined to wait for proper browser support for avif, as I don't get enough traffic to worry about data costs anyway. If this could easily be fixed, then I would love to have the improvements from avif. I just want smaller file sizes and widespread browser support.
Update
Okay, I found that I could get this to work if I changed from the default react bundler (which I believe to be webpack) to Parcel. Then it does work exactly as you expect... until I try to deploy the project.
There is an issue where I cannot load the service worker when i try to deploy my single page webapp to AWS as a single page web app. There it makes a request to my url with avif-sw.js where there is not actually a js file. I believe the issue is closely related to https://github.com/parcel-bundler/parcel/issues/670
So the first key is to use Parcel to build your web app. But Parcel still does something wrong with deployment it seems. I will continue to investigate this in a few days.
Here is the almost working version using parcel: https://github.com/quackack/quackack-comics/tree/parcel
Update 2
My earlier update was incorrect. I only thought it was working because of a cached service worker. My final solution is in the answer below.
It doesn't seem to be a problem now. Simply convert your images to avif with tools like https://avif.io/ and use them as the image source or background source via typical CSS. As Chrome and Firefox now support it (even though users still have to enable it on Firefox), everything goes well. Even works on mobile now! :)
Okay, I finally got it working. Unfortunately, mobile devices don't seem to be able to handle the large file sizes so I had to keep using jpeg anyway. It worked on my laptop though.
Here is the commit that got everything to work: https://github.com/quackack/quackack-comics/commit/75e75307e688f0e515b4bbc9eb22eef290d2c209
What I had to do:
Switch to Parcel.
Copy the contents of the avif.js library into source before building. I used the command:
copyfiles -f node_modules/avif.js/*.js .
Put this specifically into reg.js:
require("avif.js").register("./avif-sw.js");
navigator.serviceWorker.register("./avif-sw.js", undefined);
What the last two steps do is trick parcel into actually keeping a copy of "avif-sw.js" around that can actually be loaded as a service worker. Probably with a bit more tinkering you can get this to work without using parcel at all, just by copying local and then registering. No requires required. But I stopped investigating after I found this solution can't work on mobile.
This was exceptionally hard to debug because service workers are cached by the browser and I had to clear broswer data after every edit. It was also hard to debug because the source files are cached to so I had to delete my projects cache and build frequently too.
You might also want to use npm module "http-server-spa", or similar, to test how your built SPA will act when deployed.
I have a client that hosts a touch screen kiosk in their lobby. It's essentially an internal html website. They want customers to be able to click a link and have a pdf print without seeing a print dialog or having to back track... completely unnoticeable printing.
I have read articles and tried snippets of code for almost a year without finding a reputable solution. There are those out there that rightly warn of security breaches or that it cannot be done at all.
The client's old touch screen structure was made entirely in Flash which I am avoiding. BUT, they were able to pull this off. I am sure this question has been asked a thousand times, but is it really impossible?
The current CPU running the touch screen is Windows XP. They do have an IT guy that works close, but I am not sure what to ask. He never offered any other solutions.
Thank you
Not 100% sure what you're trying to accomplish but maybe you could trigger a server-side program to run instead of relying on the kiosk itself to handle the printing. You could configure the server to send these PDF requests straight to the printer.
Maybe you can bake a custom browser for them (using webkit for example) that prints without asking.
Chrome running in kisok mode, started with the --kiosk AND --kiosk-printing switches and with a default printer set, can print silently using javascript print().
This is Windows only AFAIK.
I'm pretty new to workign with Javascript.
In most languages you can run the code quickly locally on your machine. From what I've seen, in JS you generally only use it via the browser, and so I've been uploading my code an viewing its effects in the browser. This has proven very tiresome. Also, if I mak one error, it seems like my JS/JQuery will just do NOTHING, instead of giving me a useful error, message, which is making it painfully slow to code in.
IS there some way to run JS locally to see that it is working as I go? And then only upload it to the web when I'm mostly done? What ways are there for me to do this? What ways aer there for me to unit test the Javascript locally? Say I have some JAML that should render as <p>HI</p>, how do I run this locally in a unit test?
Thanks for the help,
Alex
EDIT:
Thanks for all the great suggestions. I'll have to take a bit of time and go through them to see which ones best help me in my situation.
Since you're using jQuery, I assume that you actually want to manipulate the various elements on your page. So depending on your specific development enviroment, uploading it each time is probably the way to go anyway. If you can set up a dev enviroment on your local machine (not always possible) then go with that.
As an actual answer to your question, I suggest using Chrome's developer tools, it doesn't just have the console, but an element inspector, and a resource tracker (resource tracker is invaluable when working with JSON and AJAX, since invalid json will fail silently)
As far as I know, the firebug plugin for firefox (dont use it myself) has a similar feature set, so if you're more comfortable with that go with it.
Just remember, as a developer, your development (and debuggin) enviroment is just as important as the code that you are writing.
EDIT: Noticed that you mentioned unit testing. There are several unit testing frameworks out there for JS including one that integrates with firebug called FireUnit. Do a quick google search to find more if you want.
You don't need to upload the JS file to a server to test it. Just write an html and declare the js binding
<script
src="js/yourJSFile.js"
type="text/javascript"></script>
Edit the JS file in your favorite editor and then refresh the page to test it.
For unit testing the best option is Selenium. It allows you to record an interaction with the browser and then play it back.
You can use Firebug with Firefox to debug JS, and Google Chrome has a debugger built-in (use the Tools -> Developer Tools menu).
You can run Javascript from the local file on your machine in your browser, so you can skip the uploading step.
Also, I'd recommend using Firefox/Firebug combo for developing Javascript as it will be very handy, especially for the part you mentioned about not seeing what's going wrong with your code.
Even if you upload your javascript it gets downloaded back to you as soon as you visit the webpage that invoques it. Its run client side always. So stick to local and use firebug as the others have said. Google`s developer tool is quite nice too.
In the browser if you open the developer tools, follow the following steps:
1) Navigate to sources
2) Under sources, click snippet and open run.js
3) You can use run.js to write as much code as you want and run it locally only to see if your code is working or not (it will give you output on the console)
4) Also you can get used to some keyboard shortcuts to make it faster for you.
5) For small javascript codes, you can navigate to console and run your code there
If you want to do unit testing with Javascript there are extension of Firebug that can help you with that. I haven't try any of them, so I can't really tell you which one are worth considering, but you can easily find them if you search for the keyword "Firebug unit testing" on Google.
What seems to be comming on top is FireUnit. You can find some information about how it works here.
Consider Spider Monkey, which is a javascript engine separate from a browser. If what you are developing does not involve rendering to a webpage or can be separated from the rendering code (good practice!), then this could be useful.
I prefer Chrome to Firefox and I just found Web Server for Chrome.
It's just a Google App that quickly sets up a web server for you and will be set up anywhere you are logged into Chrome. It only allows file access to your current devices, or if you specify, other devices only on the current LAN.
You just point it to the directory with your index.html file and type http://127.0.0.1:8887 in your browser.
Additionally to the answers given you can use Jasmine for automated testing.
A tutorial that seems to help get started with automated testing on Jasmine is provided by Evan Hahn.
I used it and for me it works like a charm. Especially if test driven development is what you are going for!
More precisely my goal is to create an add-on (or plug-in?) which is able to communicate with my main Cocoa application using something like the NSDistributedNotificationCenter. I need to be able to inject JavaScript code into the current webpage and get return values from the JS calls when my add-on receives the request to do so by my main application. Then I need to pass the return values back to my main application for processing.
Alternatively if there is a simple way to call JS in the active Firefox webpage and get return values that would also do the job.
If you want more info on why I want to do this, you can look at my other question: How to send JavaScript code to IE using C# (.Net 3.5), run it, then get a string return value from the JS code?
Note that I'm not only interested in knowing how to make a Firefox add-on but also in everything I talked about above. For example, how to inject JS into the active webpage, etc.
I'd like guidance on what technologies to use, tutorials and sample code if possible. The best would be a sample Xcode project but I'm not counting on this :P
Thanks in advance!
N.B: I'm working on 10.4.
You could try using C-Types with FF, which is a regular dll being called by Javascript in your addon, this is WAY better approach that using XPCOM, because if the Interfaces you use in there can change in each FF version, indeed you will have to do multiple dlls each for your addon supported FF versions
Go here my friend->
https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes
First learn how to write add-ons for Firefox. Adding Objective-C code afterwards is the easy part.
I know there is source available to the OSX FF Plugins for displaying download progress over the Dock Icon (http://github.com/vasi/firefox-dock-progress) and the "pdf plugin" that allows FF to do in-line PDFs is on Google Code.
I want to show a PREVIEW kind of thing for an post , so took details by JS
but problem comes when it comes to <input type="file" , it's not giving full path to the file
Ex:
if I do
$("#image").val();
it only give "Sunset.jpg" not C:\Documents and Settings\All Users....\Sunset.jpg
any idea how to get that detail value?
Although, as others have already pointed out, you cannot learn the full path to the file in JavaScript, perhaps a completely different approach to the problem might still work for you.
You could upload the photo automatically as soon as the visitor has picked it (the behavior you see in GMail, among other applications), so it's residing on your server even as the visitor continues interacting with your page. At that point, showing a preview is as simple as serving one yourself from your own (now server-side) copy of the image.
This if for security reasons, so you cannot read files from the users system using JavaScript.
If you happen find a workaround, there will probably be security patches released by browser vendors sooner rather than later. I know because in earlier versions if IE, it was possible to read the full path and hence display a preview, at least if the file was an image. I used that in a CMS UI, but of course that nifty feature was ruined by an IE service release :-/
In general the file upload control is somewhat of a "black box" for security reasons. You have only very limited access to scripting and styling it. This is so you can't snoop or upload files without the user knowing, or so you cannot trick the user into uploading files with a deceptive interface.
This is now possible as of Firefox 3.6
https://developer.mozilla.org/en/DOM/FileList
Though the code they show does not seem to work in Chrome, so I'm guessing even the HTML5 JavaScript API for things like this has yet to be standardized.
This is a security feature. You cannot change or get the entire path in secure browsers, so what you want to do, cannot be done. If you use something like Flash, Silverlight or Java, then it should be relatively easy.
As far as I know, there is no way to do what you want to do in javascript. Its a pretty big security issue - having filesystem access in a browser.
There are a few browser plugins (java/flash/gears) that may allow you to do this sort of thing. I know with gears you can get the user to select a file - and open it to read the content using JS.