In an XAgent inside XPages how to redirect to a new Window? - xpages

I have this XAgent with seems to work fine but it opens it in the CURRENT browser. How would I open it in a new window?
This code is running in After RenderedResponse of an XPage.
Thanks
// Track Downloads
// Setup XAgent stuff
var exCon = facesContext.getExternalContext();
var writer = facesContext.getResponseWriter();
var response = exCon.getResponse();
var fileLink = param.get("link");
// Insert Logging Code here
facesContext.getExternalContext().redirect(fileLink);
writer.endDocument()

Looks like you are trying to track when somebody clicks on the download link.
Without tracking the link would have been pointing directly at the file causing the browser to initiate the download and the user would stay on the current page. With the XAgent tracking in place the user is going to a different page in the application to do the tracking and initiate the download.
You could add a target of '_blank' to the initial link that is calling the XAgent. This will cause a new window/tab to open in the users browser but it will close once the download initiates.
Using this method of tracking the downloads will, however, remove the ability for the user of the site to be able to right click on your download link and do a 'save as'.

For a download link you could also consider to just stream the file using the OutputStream (there only can be one: Writer or Stream!) to directly serve the bytes of the file to download. You need to set the MIME type in the header. If it is not a file type the browser can handle, the download dialog will appear anyway. Opening a new window is actually considered bad style these days. If a user wants a new Window there is Ctrl+Click and Shift+Click -> a decision you shouldn't make for them (which opens the can of worms of browser illiterate users).

Related

I'm looking for an example of writing to a file from a Chrome Extension [duplicate]

I'm currently creating an extension for google chrome which can save all images or links to images on the harddrive.
The problem is I don't know how to save file on disk with JS or with Google Chrome Extension API.
Have you got an idea ?
You can use HTML5 FileSystem features to write to disk using the Download API. That is the only way to download files to disk and it is limited.
You could take a look at NPAPI plugin. Another way to do what you need is simply send a request to an external website via XHR POST and then another GET request to retrieve the file back which will appear as a save file dialog.
For example, for my browser extension My Hangouts I created a utility to download a photo from HTML5 Canvas directly to disk. You can take a look at the code here capture_gallery_downloader.js the code that does that is:
var url = window.webkitURL || window.URL || window.mozURL || window.msURL;
var a = document.createElement('a');
a.download = 'MyHangouts-MomentCapture.jpg';
a.href = url.createObjectURL(dataURIToBlob(data.active, 'jpg'));
a.textContent = 'Click here to download!';
a.dataset.downloadurl = ['jpg', a.download, a.href].join(':');
If you would like the implementation of converting a URI to a Blob in HTML5 here is how I did it:
/**
* Converts the Data Image URI to a Blob.
*
* #param {string} dataURI base64 data image URI.
* #param {string} mimetype the image mimetype.
*/
var dataURIToBlob = function(dataURI, mimetype) {
var BASE64_MARKER = ';base64,';
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
var raw = window.atob(base64);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
var bb = new this.BlobBuilder();
bb.append(uInt8Array.buffer);
return bb.getBlob(mimetype);
};
Then after the user clicks on the download button, it will use the "download" HTML5 File API to download the blob URI into a file.
I had long been wishing to make a chrome extension for myself to batch download images. Yet every time I got frustrated because the only seemingly applicable option is NPAPI, which both chrome and firefox seem to have not desire in supporting any longer.
I suggest those who still wanted to implement 'save-file-on-disk' functionality to have a look at this Stackoverflow post, the comment below this post help me a lot.
Now since chrome 31+, the chrome.downloads API became stable. We can use it to programmatically download file. If the user didn't set the ask me before every download advance option in chrome setting, we can save file without prompting user to confirm!
Here is what I use (at extension's background page):
// remember to add "permissions": ["downloads"] to manifest.json
// this snippet is inside a onMessage() listener function
var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
chrome.downloads.download({url:imgurl},function(downloadId){
console.log("download begin, the downId is:" + downloadId);
});
Though it's a pity that chrome still doesn't provide an Event when the download completes.chrome.downloads.download's callback function is called when the download begin successfully (not on completed)
The Official documentation about chrome.downloadsis here.
It's not my original idea about the solution, but I posted here hoping that it may be of some use to someone.
There's no way that I know of to silently save files to the user's drive, which is what it seems like you're hoping to do. I think you can ASK for files to be saved one at a time (prompting the user each time) using something like:
function saveAsMe (filename)
{
document.execCommand('SaveAs',null,filename)
}
If you wanted to only prompt the user once, you could grab all the images silently, zip them up in a bundle, then have the user download that. This might mean doing XmlHttpRequest on all the files, zipping them in Javascript, UPLOADING them to a staging area, and then asking the user if they would like to download the zip file. Sounds absurd, I know.
There are local storage options in the browser, but they are only for the developer's use, within the sandbox, as far as I know. (e.g. Gmail offline caching.) See recent announcements from Google like this one.
Google Webstore
Github
I made an extension that does something like this, if anyone here is still interested.
It uses an XMLHTTPRequest to grab the object, which in this case is presumed to be an image, then makes an ObjectURL to it, a link to that ObjectUrl, and clicks on the imaginary link.
Consider using the HTML5 FileSystem features that make writing to files possible using Javascript.
Looks like reading and writing files from browsers has become possible. Some newer Chromium based browsers can use the "Native File System API". This 2020 blog post shows code examples of reading from and writing to the local file system with JavaScript.
https://blog.merzlabs.com/posts/native-file-system/
This link shows which browsers support the Native File System API.
https://caniuse.com/native-filesystem-api
Since Javascript hitch-hikes to your computer with webpages from just about anywhere, it would be dangerous to give it the ability to write to your disk.
It's not allowed. Are you thinking that the Chrome extension will require user interaction? Otherwise it might fall into the same category.

Automatically open Office documents on a Sharepoint Server 2013 in Firefox (full Office integration)

I recently switched to Firefox. Unfortunately my company still uses Sharepoint Server 2013 (migration to Sharepoint Online is planned somewhere in the future) which no longer offers a fluid integration with Office.
Every time I want to edit an Office document, it gets downloaded instead of being 'forwarded' to be opened by Word, Excel, etc. Modifications need to be saved locally and than uploaded afterwards. This is hugely annoying.
Is there some way that I can automate this in code, using a Firefox extension? Does Sharepoint expose some kind of hook or metadata containing the document's URL?
(Self-answer originally provided by Dotsoltecti; copied from question body into a proper answer).
Sharepoint 2013 passes the document's URL via the right-click contextual menu.
There exists a very neat add-on for Firefox called "custom right-click menu" by Sander Ronde. After installing this extension I added the script below:
var feedback = crmAPI.getClickInfo();
var url = feedback.linkUrl;
if (url.endsWith("docx") || url.endsWith("doc")) { var uri = "ms-word:ofe|u|" }
if (url.endsWith("xlsx") || url.endsWith("xls")) { var uri = "ms-excel:ofe|u|" }
if (url.endsWith("pptx") || url.endsWith("ppt")) { var uri = "ms-powerpoint:ofe|u|"}
var toOpen = uri.concat(url);
window.open(toOpen);
Et voilĂ : right clicking on a Word/Excel/PowerPoint-document executes the script and correctly forwards the document to the said program (you have to whitelist your SharePoint-site with the pop-up blocker). Modifications are handled directly by the Office-program.
Only drawback so far is that every time a document is opened, a new blank window is generated. I haven't found a solution for that yet, so suggestions are always welcome.

Intermittent behavior in xpages application: by pressing the button to save, the document is not redirected and is displayed again

I'm having a problem with a new xpages application that was deployed in production for a few months, but has now only been expanded to the entire enterprise now. The problem that did not happen while the application was in production pilot is intermittent and happens when an action executes a current notesxsppdocument save (currentdocument). The symptom is that by pressing the button you save, the document is not redirected and is displayed again. What can be this problem. session timeout, a bug from xpages? The application basically uses the components of the extension library, there is no external component to the xpages. When the problem occurs, if the user closes the document's xpages opens again and then clicks the button again the code runs successfully.
I have a function that stores a file attached to the doc in a repository. I suspect she's the problem. The function uses the file upload component and a button to execute a java agent that stores the file in a repository. The button code below follows. Its function is basically to create the rich text if it does not exist and call the agent that consumes a web service to transfer the file to a repository and erase it from the document.
I asked the user not to use the function for a few days at the time of the service to verify that the problem will persist.
if(validaArquivo())
{
var url=#ReplaceSubstring(context.getUrl(),"openDocument","editDocument")
url += '&tab=dossie' ;
var fieldItem:NotesItem =
currentDocument.getDocument().getFirstItem("arquivos");
if (fieldItem==null){
// create the field as an RTF
//writeToLog("Creating xxxxx field");
var rtItem:NotesRichTextItem =
currentDocument.getDocument().createRichTextItem("arquivos");
currentDocument.save();
}else if (fieldItem.getType()==1280){
//writeToLog("--> Converting xxxxx to RTF");
currentDocument.replaceItemValue("arquivosTEXT",
fieldItem.getText());
fieldItem.remove();
var rtItem:NotesRichTextItem =
currentDocument.getDocument().createRichTextItem("arquivos");
currentDocument.save();
}
var agente:NotesAgent=database.getAgent("(SalvaAnexos)");
agente.runWithDocumentContext(currentDocument.getDocument(true));
context.redirectToPage(url)
}
else
{
document1.removeAllAttachments("arquivos");
}
When users are using the application, rebuild or to change some code on prod environment can cause this.

How to return PDF file after xpage submission properly? First submission make app stop working in browser

I have a simple request for Xpages app. I have calculator like page where user enters some data and after submission (button action with full submit e,g, 'Export to PDF' button) app should create PDF and return back to browser. Everything is actualy working fine for me except that this works first time only. It returns PDF back to browser but then browser page stops working ... buttons or ajax partial refreshes dont work anymore. I understand its related to fact that browser submits data to server and expects payload come back but instead I'm sedning PDF file but how to handle it different way? I need the page submit because I'm managing the viewState for page that is necessery for me when rendering PDF content ... Any idea how to solve it properly?
Here is my code I'm using for sending PDF back to browser.
ExternalContext exCon = DominoAccess.getFacesContext().getExternalContext();
HttpServletResponse response = (HttpServletResponse)exCon.getResponse();
ServletOutputStream out = response.getOutputStream();
response.setContentType("application/pdf");
response.setHeader("Content-disposition","attachment; filename="+fileName);
response.setHeader("Cache-Control", "no-cache");
//Get the document out to the screen
createPdf(out,html);
// Stop the page from further processing;
DominoAccess.getFacesContext().responseComplete();

Download link page JSF

How can I produce a URL which somebody could open and that would immediately download a file e.g. pdf?
I have been using ice:outputResource but that requires the user clicks on a link. Is it possible to do this in JSF?
Thanks,
Dwayne
You want to download a PDF file immediately when one opens a page? Use Javascript to fire the request on the PDF file during page load.
<script>
window.onload = function() {
window.location = 'http://example.com/context/path/to/file.pdf';
}
</script>
Update: your question is actually ambiguous. From other point of view, are you asking how to return a PDF file on a GET request? If so: if it's a static PDF file, then just put the PDF somewhere in the webcontent and link to it. Or if it's to be dynamically generated or served from a database or local disk file system outside the webapp, then create a servlet which does the job. Example here.

Resources