Conflict of displayDialogAsync and html5-history-api - html

I have an application by mean-stack that hosts a website and an Excel add-in. html5 is enabled, and it has
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script src="https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js"></script>
In the Excel add-in, I have a button that opens a page in the website by Dialog API:
$scope.openDialog = function () {
Office.context.ui.displayDialogAsync("https://localhost:3000/preview/tmp/6wr-4PqdBrYQwjp3AAAD", {}, function () {})
}
When I click on this button in Excel Online in Chrome, it opens a dialog box with the following url (note that # and several %2F are systematically appended), but it does not prevent from well displaying the page.
https://localhost:3000/preview/tmp/6wr-4PqdBrYQwjp3AAAD?_host_Info=excel|web|16.00|en-us|b6f37f78-e519-7d03-0069-b9c4317a362c|isDialog#%2Fpreview%2Ftmp%2F6wr-4PqdBrYQwjp3AAAD%3F_host_Info=excel%7Cweb%7C16.00%7Cen-us%7Cb6f37f78-e519-7d03-0069-b9c4317a362c%7CisDialog
However, when I click on this button in Excel Online in Firefox, the url changes quickly to the following url, which turns out to display the homepage of the website:
https://localhost:3000/home#%2Fpreview%2Ftmp%2F6wr-4PqdBrYQwjp3AAAD%3F_host_Info=excel%7Cweb%7C16.00%7Cen-gb%7C919fff78-e51f-dc20-0c3c-871b7d0ec25d%7CisDialog
So my questions are:
1) Why does Office.context.ui.displayDialogAsync add systematically # and %2F to the url of my website? Is it possible to prevent this from happening?
2) Is it possible to make a url (regardless of # and %2F) that Firefox accept?
Edit 1: It seems that if I don't use html5-history-api, it will work. So does not know how to disable html5-history-api for that displayDialogAsync? (The reason why I have to use html5-history-api after office.js is here.)

It is not displayDialogAsync that is doing this. It is a frequent issue with Angular routing and Angular location strategy. Search for "angular app is adding hash to my urls" and you will find a lot of information about it and solutions.

Related

How can you click an href link but block the linked page from displaying

It was hard to encapsulate my question in the title.
I've rewritten a personal web page that made extensive use of javascript. I'm simplifying matters (or so I hope).
I use a home automation server that has a REST interface. I can send commands such as 'http://192.168.0.111/rest/nodes/7%2032%20CD%201/cmd/DON to turn on a light. I'm putting links on my simplified web page using an href tag. The problem is that it opens the rest interface page and displays the XML result. I'd like to avoid having that page show up. ie when you click on the link it 'goes' to the link but doesn't change the page.
This seems like it should/would not be possible but I've learned not to underestimate the community.
Any thoughts?
You can use the fetch function if your browser is modern enough:
document.querySelector(lightSelector).addEventListener('click', e => {
e.preventDefault(); // prevent the REST page from opening
fetch(lightURL).then // put promises here
})
The variables lightSelector and lightURL are expected to be defined somewhere.
The code listens for clicks on the link, and when one comes, we prevent the REST page from opening (your intention) then we send a request to your light URL with fetch. You can add some promises to deal with the response (e.g. print "light on" or "light off" for example) using then but that's another matter.
If you make the "link" a button, you can get rid of e.preventDefault(); which is the part preventing the REST page from opening.

Controlling the "Oops! Chrome could not find ... " page?

When you type in an invalid address, Chrome displays a grey page that says "Oops! Google Chrome could not find X. Did you mean Y?"
Because this is not an HTTP page but rather one of the browser's built-in things, I can't put a content script in it and can't control it, so my extension is frozen until the user manually goes to another page.
Since the extension is supposed to be able to control the browser on its own, it's very important that anytime this page opens, it automatically goes back to a page I do have content script access to, and then displays a message instead.
Is this impossible?
You can use the chrome.webNavigation.onErrorOccurred to detect such errors, and redirect to a different page if you want. Unless you've got an extremely good reason to do so, I strongly recommend against implementing such a feature, because it might break the user's expectations of how the browser behaves.
Nevertheless, sample code:
chrome.webNavigation.onErrorOccurred(function(details) {
if (details.frameId === 0) {
// Main frame
chrome.tabs.update(details.tabId, {
url: chrome.runtime.getURL('error.html?error=' + encodeURIComponent(details.error))
});
}
});
According to the docs the only pages an extension can override are:
The bookmarks manager
The history
The new-tab
So, an extension can't change/contol/affect the behaviour of the browser regarding the "Oops!..." page.

chrome-extension:// links open about:blank

I've recently been contributing to the Enhanced Steam extension and I've found that a link fetched with chrome.extension.getURL simply opens about:blank and not the link described.
I do not believe it's actually a problem with the extension, but rather a problem in chrome. The link it supplies is valid (chrome-extension://pimjhgjngccknempdnehdeaihcjbajod/options.html) and navigating directly works correctly.
I tried chrome.tabs.create, but found that I am not allowed to use it due to the script modifying pre-existing content.
Any help or work arounds would be appreciated.
I put all my required files into "web_accessible_resources", it solved my problem. See this in #4 https://bugs.chromium.org/p/chromium/issues/detail?id=310870#c4
It is Chrome's previous problem which is not secure. In build 31.0.1650.57, Chrome fixed this which is to force to put required files in "web_accessible_resources". In Chrome extension, lots of samples don't use "web_accessible_resources", those are the bugs, those samples will have this "chrome-extension:// links open about:blank" problem in build 31.0.1650.57.
Actually my chrome extension MarkView was facing this issue and I had to update its manifest.json to make it work for this Chrome update. By the way, MarkView is tool to read and write Awesome Markdown Files, it provides features including Content Outline, Sortable Tables and code block syntax highlight with line number.
Looks like a bug in Chrome to me. If you don't have too many pages like this to change then could you try using message passing to pass the page you want to open to the background page? Then use either window.open or chrome.tabs.create within the background page. Example code shown below:
//CONTENT SCRIPT
chrome.runtime.sendMessage({greeting: "OpenPage", filename:"somepage.html", querystring:"?aValue="+someVal}, function(response) {});
Then in your Background page
//BACKGROUND PAGE
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting == "OpenPage"){
open_page(request.filename, request.querystring)
}
});
function open_page(filename, querystring){
var pageUrl = chrome.extension.getURL(filename)+querystring;
chrome.tabs.create({'url': pageUrl }, function(tab) {
// Tab opened.
});
}

Bookmarking PDF in Google Chrome

Lately I've been reading a lot of PDF books using Google Chrome. To go to a particular page, you can simply append #page=23 to the url (as in file:///C:/my_book.pdf#page=23). This is a nice and easy way to bookmark your current page number to continue reading the book later.
My question:
What's a way to find out what page you're currently in within the book?
OR
What's a Chrome plugin that bookmarks PDF files within your file system?
I've tried a few extensions, but they don't work unless the book is in a server (as in http:// localhost/my_book.pdf), which is not desired in my case.
Thanks!
As of Chrome version 31+ the page number is displayed by the scroll bar if you scroll at all. I'm not sure when (what version) this feature was added.
There's a chrome extension called "PDF Bookmark" it is free and works in my case.
Here's the link for your reference.
Does it automatically update the hash tag to the page number?
If so, you could use document.location.hash as follows:
currentPage = document.location.hash.split("="); currentPage = currentPage[1];
not very user friendly but you can append document.documentElement.scrollTop property value to the url
on the console
> document.documentElement.scrollTop
<- 4000
bookmark as "file://path/to/pdf.pdf#4000"
and then when you reopen it use that value to set the same property
document.documentElement.scrollTop = 4000
a simple user script should be able to do this...

HTML / Javascript One Click Print (no dialogs)

Is it possible to have a print option that bypasses the print dialog?
I am working on a closed system and would like to be able to pre-define the print dialog settings; and process the print as soon as I click the button.
From what I am reading, the way to do this varies for each browser. For example, IE would use ActiveX. Chrome / Firefox would require extensions. Based on this, it appears I'll have to write an application in C++ that can handle parameters passed by the browser to auto print with proper formatting (for labels). Then i'll have to rewrite it as an extension for Chrome / Firefox. End result being that users on our closed system will have to download / install these features depending on which browser they use.
I'm hoping there is another way to go about this, but this task most likely violates browser security issues.
I ended up implementing a custom application that works very similar to the Nexus Mod Manager. I wrote a C# application that registers a custom Application URI Scheme. Here's how it works:
User clicks "Print" on the website.
Website links user to "CustomURL://Print/{ID}
Application is launched by windows via the custom uri scheme.
Application communicates with the pre-configured server to confirm the print request and in my case get the actual print command.
The application then uses the C# RawPrinterHelper class to send commands directly to the printer.
This approach required an initial download from the user, and a single security prompt from windows when launching the application the first time. I also implemented some Javascript magic to make it detect whether the print job was handled or not. If it wasn't it asks them to download the application.
I know this is a late reply, but here's a solution I'm using. I have only used this with IE, and have not tested it with any other browser.
This Sub Print blow effectively replaces the default print function.
<script language='VBScript'>
Sub Print()
OLECMDID_PRINT = 6
OLECMDEXECOPT_DONTPROMPTUSER = 2
OLECMDEXECOPT_PROMPTUSER = 1
call WB.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,1)
End Sub
document.write "<object ID='WB' WIDTH=0 HEIGHT=0 CLASSID='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2'></object>"
</script>
Then use Javascript's window.print(); ties to a hyperlink or a button to execute the print command.
If you want to automatically print when the page loads, then put the code below near tag.
<script type="text/javascript">
window.onload=function(){self.print();}
</script>
I am writing this answer for firefox browser.
Open File > Page Setup
Make all the headers and footers blank
Set the margins to 0 (zero)
In the address bar of Firefox, type about:config
Search for print.always_print_silent and double click it
Change it from false to true
This lets you skip the Print pop up box that comes up, as well as skipping the step where you have to click OK, automatically printing the right sized slip.
If print.always_print_silent does not come up
Right click on a blank area of the preference window
Select new > Boolean
Enter "print.always_print_silent" as the name (without quotes)
Click OK
Select true for the value
You may also want to check what is listed for print.print_printer
You may have to choose Generic/Text Only (or whatever your receipt printer might be named)
The general answer is: NO you cannot do this in the general case but there some cases where you might do it.
Check
http://justtalkaboutweb.com/2008/05/09/javascript-print-bypass-printer-dialog-in-ie-and-firefox/
If you where allowed to do such a thing anyway, it would be a security issue since a malware script could silently sent printing jobs to visitor's printer.
I found a awesome plugin by Firefox which solve this issue. try seamless printing plugin of firefox which will print something from a web application without showing a print dialog.
Open Firefox
Search addon name seamless printing and install it
After successful installation the printing window will get bypassed when user wants to print anything.
I was able to solve the problem with this library: html2pdf.js (https://github.com/eKoopmans/html2pdf.js)
Considering that you have access to it, you could do something like that (taken from the github repository):
var element = document.getElementById('element-to-print');
html2pdf(element);