User can achieve this by running 'Reload Window' available via editor's 'Command Palette'. That however from an extension authoring point of view is not as straight forward as prompting the user right away.
Desired outcome is to take current implementation in this pull request from [screenshot]
to [screenshot]
.
Once you prompt the user to confirm using vscode.window.showInformationMessage(...) to confirm, you can run vscode.commands.executeCommand("workbench.action.reloadWindow") to reload the window.
Accepted answer posted by user ajshort was crucial to figuring out how to call arbitrary editor commands, however, tying it together with user action still wasn't clear to me.
See function bellow for resolving the user action (click).
/** Prompts user to reload editor window in order for configuration change to take effect. */
function promptToReloadWindow() {
const action = 'Reload';
vscode.window
.showInformationMessage(
`Reload window in order for change in extension \`${EXTENSION_ID}\` configuration to take effect.`,
action
)
.then(selectedAction => {
if (selectedAction === action) {
vscode.commands.executeCommand('workbench.action.reloadWindow');
}
});
}
Related
I am trying to put the Back Button Redirect Script function to good use. I have a plugin which plays background (user-initiated) music on my site. As long as the user clicks forward, the music streams continuously and nearly uninterrupted from page to page, without restarting. If the user clicks the back button (or refreshes), the music stops and they must manually press play to restart the stream. The author says they have no way to resolve it. I'm not giving up just yet.
My thought is, why not use JavaScript to record the browser's previous page URL, then capture the back button trigger and send the user "forward" to that URL, thus keeping the music stream intact while honoring the user's desire to go back a page?
Conceptually, being a supernoob at JavaScript, I patched this together from different sources on here and codingbeautydev...
$(window).bind("onpopstate", function (e) {
const previousPage = document.getElementById("previous-page");
previousPage.textContent = document.referrer;
window.history.pushState({ page: 1 }, "", "");
window.onpopstate = function (event) {
if (event) {
window.location.href = previousPage;
}
};
});
My first thought is there are surely some syntex errors in there at my doing and potentially much more that need be modified, but I'm hoping someone can easily touch up my rough sketch. Additionally, beyond making this work, I see the limits of this allowing only 1-page of history, and I'm curious if there's a way to nest it into a stack of a few pages to which could be visited in reverse order, all the while moving "forward". First things first though, then on to bigger and better.
Thanks guys! 😀
Mark
You cannot change the default behavior of the browsers's back or forward button unless your app uses URL hashes to navigate, but from my understanding of your question the user actually goes from say .com/paper to .com/boxes and not .com/paper#page1 to .com/paper#page2.
One possible option you could try is using the following (from here):
window.addEventListener('pageshow', function (event) {
if (event.persisted || performance.getEntriesByType("navigation")[0].type === 'back_forward') {
// User got here from using the Back or Forward button
}
});
This will trigger when the user got on the page this code runs on using the back or forward window button, also if the user goes from /boxes back to /paper.
You can try to save the current state of the music playing on the background (which song, timestamp, audio level, etc) in local storage (at max) every second or so, and get the stored values inside the function above to continue the music the user was last listening to when he left the previous page. Not the most elegant solution, but all I think of right now that might actually work.
Edit:
The code you requested. Chrome & Safari will block/ignore it due to history manipulation, except when an user interacts with the page first. It's not how history should be used. Don't use it in production, but play with it all you want. Also, here's an simple example how history can be used.
window.history.pushState({}, '', window.location.pathname);
let previousPage = document.referrer;
window.addEventListener('popstate', (e) => {
window.location.assign(previousPage)
});
We recently discovered that Chrome no longer supports window.showModalDialog which is problematic because our enterprise application uses this method.
There is, apparently, a short term workaround that allows you to restore showModalDialog but it involves modifying the registry which is too complicated (and risky) four our average user. Therefore I'm not a big fan of this workaround.
The long term solution is obviously to remove all calls to this obsolete method and replace them with a convenient jQuery plugin (such as VistaPrint's Skinny Modal Dialog plugin, for example. Other suggestions are welcome by the way).
The typical scenario we use the modal dialog is to ask the user for Yes/No confirmation before executing an action that cannot be undone, ask the user to agree to terms and condition before proceeding, etc. Typically the onclick event on the "Yes" or "Ok" button in the modal dialog looks like this:
window.returnValue = true;
window.close();
Similarly, the "Cancel" or "No" button looks like this:
window.returnValue = false;
window.close();
The fact that we can return a value from the dialog is very convenient because it allows the "parent" window to be notified whether the user has clicked the "Ok" or the "Cancel" button like so:
var options = "center:1;status:1;menubar:0;toolbar:0;dialogWidth:875px;dialogHeight:650px";
var termsOfServiceAccepted = window.showModalDialog(myUrl, null, options);
if (termsOfServiceAccepted) {
... proceed ...
}
The last thing I'm going to mention about the showModalDialog is that it works great even when the document displayed in the dialog is from a different domain. It's very common for us to have our javascript running from http://the-client.com but the "Terms of Service" web page is from http://the-enterprise-vendor.com
I need a temporary solution that I can deploy ASAP while we work on the long term solution. Here are my criteria:
minimal code change in existing JavaScript
the pop up window must be able to return a value to the "parent". Typically this value is a Boolean but it could be any simple type (e.g.: string, int, etc.)
solution must work even if the URL of the content is from different domain
Here's what I have so far:
1) Add the following method in my JavaScript:
function OpenDialog(url, width, height, callback)
{
var win = window.open(url, "MyDialog", width, height, "menubar=0,toolbar=0");
var timer = setInterval(function ()
{
if (win.closed)
{
clearInterval(timer);
var returnValue = win.returnValue;
callback(returnValue);
}
}, 500);
}
As you can see in this method, I try to make the pop up window look as similar to a dialog as possible by hiding the menu and the toolbar, I setup a time every 500 milliseconds to check if the window has been closed by the user and if so, get the 'returnValue' and invoke a callback.
2) replace all calls to showModalDialog with the following:
OpenDialog(myUrl, 875, 650, function (termsOfServiceAccepted)
{
if (termsOfServiceAccepted)
{
... proceed ....
}
});
The fourth parameter to the method is the callback where I check if the user has clicked the "Ok" button before allowing her to proceed.
I know it's a long question but basically it boils down to:
What do you think of the solution I propose?
In particular, do you think I'll be able to get a returnValue from a window that was opened with window.open?
Any other alternative you can suggest?
I have two ideas that could help you but the first one is tied to CORS, so you won't be able to use it from different domains at least you can access both services and configure them.
FIRST IDEA:
The first one is related to this native api. You could create on the parent window a global function like this:
window.callback = function (result) {
//Code
}
As you can see it receives a result argument which can hold the boolean value you need. The you could open the popup using the same old window.open(url) function. The popup's onlick event handler could look like this:
function() {
//Do whatever you want.
window.opener.callback(true); //or false
}
SECOND IDEA: Solves the problem
The other idea I got is to use this other native api to trigger an event on the parent window when the popup resolves (better known as cross-document messaging). So you could do this from the parent window:
window.onmessage = function (e) {
if (e.data) {
//Code for true
} else {
//Code for false
}
};
By this way you are listening to any posted message on this window, and checking if the data attached to the message is true (the user clicks ok in the popup) or false (the user clicks cancel in the popup).
In the popup you should post a message to the parent window attaching a true or a false value when corresponds:
window.opener.postMessage(true, '*'); //or false
I think that this solution perfectly fits your needs.
EDIT
I have wrote that the second solution was also tied to CORS but digging deeper
I realized that cross-document messaging isn't tied to CORS
So lately I have been learning JS and trying to interact with webpages, scraping at first but now also doing interactions on a specific webpage.
For instance, I have a webpage that contains a button, I want to press this button roughly every 30 seconds and then it refreshes (and the countdown starts again). I wrote to following script to do this:
var klikCount = 0;
function getPlayElement() {
var playElement = document.querySelector('.button_red');
return playElement;
}
function doKlik() {
var playElement = getPlayElement();
klikCount++;
console.log('Watched ' + klikCount);
playElement.click();
setTimeout(doKlik, 30000);
}
doKlik()
But now I need to step up my game, and every time I click the button a new window pops up and I need to perform an action in there too, then close it and go back to the 'main' script.
Is this possible through JS? Please keep in mind I am a total javascript noob and not aware of a lot of basic functionality.
Thank you,
Alex
DOM events have an isTrusted property that is true only when the event has been generated by the user, instead of synthetically, as it is for the el.click() case.
The popup is one of the numerous Web mechanism that works only if the click, or similar action, has been performed by the user, not the code itself.
Giving a page the ability to open infinite amount of popups has never been a great idea so that very long time ago they killed the feature in many ways.
You could, in your own tab/window, create iframes and perform actions within these frames through postMessage, but I'm not sure that's good enough for you.
Regardless, the code that would work if the click was generated from the user, is something like the following:
document.body.addEventListener(
'click',
event => {
const outer = open(
'about:blank',
'blanka',
'menubar=no,location=yes,resizable=no,scrollbars=no,status=yes'
);
outer.document.open();
outer.document.write('This is a pretty big popup!');
// post a message to the opener (aka current window)
outer.document.write(
'<script>opener.postMessage("O hi Mark!", "*");</script>'
);
// set a timer to close the popup
outer.document.write(
'<script>setTimeout(close, 1000)</script>'
);
outer.document.close();
// you could also outer.close()
// instead of waiting the timeout
}
);
// will receive the message and log
// "O hi Mark!"
addEventListener('message', event => {
console.log(event.data);
});
Every popup has an opener, and every different window can communicate via postMessage.
You can read more about window.open in MDN.
I'm developing a social network website and I'm working with php/mysql/jquery and I want users to have the most user-friendly website experience. That's why I try to avoid a save (submit) button at all. So, when they're on their own profile and enter information like what languages they speak or where do they live, I want to auto-create a page entry, if it doesn't exists already.
For example if somebody speaks german and that entry isn't available in the database yet (it's called pages with rows title,text,date_added). This is most likely comperable with a Facebook page you can create on Facebook, but this should be about everything (languages, companies, locations, activities).
So my specific problem is now, how to implement this feature the most smartest way. I mean on what event should this save be triggered, because I obviously can't save a new entry on every letter that has been typed. I've already implemented an autocomplete function, so they can choose from entries that already exist, but as mentioned I want them to create new entries (pages), too. Most preferably without "flooding" the database with new entries.
The things I thought of:
When a user switches from one input to another and input has been
made. Can this even be registered by JQuery? But here's the
question, what if he leaves the page without switching to another
input.
Save all data only then if he leaves the current page. I think
there is this onunload function in JQuery.
Get confirmation from the user: "This entry hasn't been made yet.
Do you want to save this entry?". But when should I ask this? I
can't predict when the user is finished with typing.
You could do the following:
1) Every time the user presses a button or clicks inside an input field - register a timeout using setTimeout (if the timeout was already set - clear it). The actual timeout in ms is up to you, it depends on the users and the data they are entering - maybe half a second or a whole second will be fine.
2) Inside the timeout - submit the data to the backend
3) And as you mentioned - if the user attempts to leave the page with a timeout waiting to happen - ask him if he really wants to leave. Keep in mind you are limited in what you can do from the unload handler itself, so it is best just to return him to the page and invoke the save then (as AJAX will probably not work from that handler, or at least it will not be consistent in all browsers).
var to = null;
$(':input').on('click contextmenu keyup blur', function () {
if(to) { clearTimeout(to); }
to = setTimeout(function () {
$.ajax(...send data to server...).done(function () {
// possibly show a message indicating the data was saved
})
}, 1000);
});
window.onbeforeunload = function() {
if(to) {
return "Are you sure you want to navigate away, you have unsaved data?";
}
}
As in the title,
how can i close a MessageDialog from code in HTML5 Windows Store app?
my code so far:
var msg = new Windows.UI.Popups.MessageDialog("Please wait");
msg.commands.append(new Windows.UI.Popups.UICommand("OK",
function (command) {
...
}));
msg.showAsync();
and then i would like to close this popup FROM THE CODE, i have not found any methods
in the specification like
msg.close();
is there a way?
thanks
The fact that your message is "Please wait" suggests to me that you might want to use a different tool for this job.
If what you're trying to do is inform the user that you're doing something in the background that they need to wait for, consider using a Progress control instead, as documented here:
http://msdn.microsoft.com/en-us/library/windows/apps/hh465487.aspx
If you use a Progress control, you can both include a text label with your desired text, and dismiss the progress control when you've finished whatever task it is you're asking the user to wait for.
And to answer your original question, I don't believe there's any API for dismissing a MessageDialog programmatically, as that would break the interaction pattern of this control, which is for the app to display a message, and then allow the user to dismiss it when they're ready to.
Hope that helps.
For more information on Windows Store app development, register for App Builder.
I think you want to use a flyout, similarly to this answer. The link solves a slightly different problem in that it closes the flyout after a timeout.
However, you should be able to define a flyout that you, as well as the user, can close. In both cases, you end up calling something like:
flyout.winControl.hide(); // Dismiss the flyout
Take a look at this...
(function(){
"use strict";
var page = WinJS.UI.Pages.define("/html/cancelcommand.html", {
ready: function (element, options) {
document.getElementById("cancelCommand").addEventListener("click", cancelCommand_Click, false);
}
});
// Click handler for the 'cancelCommand' button.
// Demonstrates setting the command to be invoked when the 'escape' key is pressed.
// Also demonstrates retrieval of the label of the chosen command and setting a callback to a function.
// A message will be displayed indicating which command was invoked.
// In this scenario, 'Try again' is selected as the default choice, and the 'escape' key will invoke the command named 'Close'
function cancelCommand_Click() {
// Create the message dialog and set its content
var msg = new Windows.UI.Popups.MessageDialog("No internet connection has been found.");
// Add commands and set their command handlers
msg.commands.append(new Windows.UI.Popups.UICommand("Try again", commandInvokedHandler));
msg.commands.append(new Windows.UI.Popups.UICommand("Close", commandInvokedHandler));
// Set the command that will be invoked by default
msg.defaultCommandIndex = 0;
// Set the command to be invoked when escape is pressed
msg.cancelCommandIndex = 1;
// Show the message dialog
msg.showAsync();
}
function commandInvokedHandler(command) {
// Display message
WinJS.log && WinJS.log("The '" + command.label + "' command has been selected.", "sample", "status");
}
}());
http://code.msdn.microsoft.com/windowsapps/Message-dialog-sample-00c928f5/sourcecode?fileId=50972&pathId=1064922824