It's stupid but it works^H worked


  • Trolleybus Mechanic

    You know how every now and then / every day, you run across a little nugget left behind the couch by a co-worker? Some disgusting little piece of "I don't understand"? It works, usually because of a fluke, or race condition that relies on slow internet connections from 1999, or because of a known bug in a browser? And you point it out, because one day it WILL explode? And you get told "no, it's ok". Then one day that little bit of code that is sitting in production explodes?

    @Anonymized so forgive the fucked up js syntax said:

    <input id="LogoutButton" onclick="SaveFormBeforeLogout()" value="Logout" />

    <script type='text/javascript'>

       function SaveFormBeforeLogout()
      {
           document.getElementById("PostbackButtonToSaveFormButton").click();

          alert("Your form will be saved. Click OK to logout.");

          redirect("logout.aspx");

    }

    </script>

     So now that (rightfully) FireFox (and presumably all other browsers to follow) don't allow JavaScript alerts to modally block exiting a page, guess what happens when someone tries to logout?



  • "It's stupid but it work worked" ...?


  • Garbage Person

    @Lorne Kates said:

    You know how every now and then / every day, you run across a little nugget left behind the couch by a co-worker? Some disgusting little piece of "I don't understand"? It works, usually because of a fluke, or race condition that relies on slow internet connections from 1999, or because of a known bug in a browser? And you point it out, because one day it WILL explode? And you get told "no, it's ok". Then one day that little bit of code that is sitting in production explodes?

    @Anonymized so forgive the fucked up js syntax said:

    <input id="LogoutButton" onclick="SaveFormBeforeLogout()" value="Logout" />

    <script type='text/javascript'>

       function SaveFormBeforeLogout()
      {
           document.getElementById("PostbackButtonToSaveFormButton").click();

          alert("Your form will be saved. Click OK to logout.");

          redirect("logout.aspx");

    }

    </script>

     So now that (rightfully) FireFox (and presumably all other browsers to follow) don't allow JavaScript alerts to modally block exiting a page, guess what happens when someone tries to logout?

    I thought the bloody spec said alerts were modal - period.Then again, Firefox changing the spec because "It's better this way" isn't unheard-of.


  • @Weng said:

    I thought the bloody spec said alerts were modal - period.Then again, Firefox changing the spec because "It's better this way" isn't unheard-of.

    The spec says a lot of stupid things that can lead to malware attacks that browsers have to ignore, what's your point?


  • Garbage Person

    @blakeyrat said:

    @Weng said:
    I thought the bloody spec said alerts were modal - period.Then again, Firefox changing the spec because "It's better this way" isn't unheard-of.

    The spec says a lot of stupid things that can lead to malware attacks that browsers have to ignore, what's your point?

    Asking programmers to be prescient about ways the standard will change in the future is quite damned idiotic.

     Take, for example, damned near every .net application ever written. They aren't going to be .net4.5 compatible because giant chunks of the framework (every single bit of it that is a reimplementation of a native part of the Windows API - which, AFAIK, is almost the entire System.* namespace, plus many, many more) are getting pruned off and replaced by wrappers around the relevant native API. Also, every deprecated item is getting dropped entirely. Did anyone foresee this? Fuck no. This is Microsoft, they worship at the altar of non-breaking changes. Incidentally, it's going to separate the wheat from the chaff in terms of .net developer skill - the good ones won't have any problems regearing to work with the new framework. The crap ones will be lobbying management never to move forward from .net4

     

    And really, it's not as if this Javascript is going to do anything fatally incorrect - it'll just display a dialog box that doesn't make sense in its new context, with no harm done other than looking silly.



  • The issue is that the alert call was used to stall the process so that the form submission had time to complete.

    Or possibly that the form submission would cause a different page to be loaded, but then the javascript still has time to load a third page to replace the form processor page.

    Perhaps both, I am not sure here.



  • @Weng said:

    Asking programmers to be prescient about ways the standard will change in the future is quite damned idiotic.

    This is the W3C we're talking about. The standard doesn't change. Until 5 years after it's obvious to everybody everywhere it needs to. The inability of web pages to send data during Unload is one of those huge problems the W3C badly needs to fix, and there's a great need for. (As this code shows.)

    The issue here is that the standards writers didn't have the foresight to imagine how the features they put down could be used to make everybody's life miserable, and so they didn't add any protection into the standard. Which means browsers like Firefox, IE, and the rest have to do it on their own.

    @Weng said:

    (Odd and probably inaccurate rant about .Net 4)

    If you want to rant about .Net 4.5, why don't you start a new thread? Because I don't see what the holy shit it has to do with what I typed at all. Or this thread. Or anything. At all. Ever.

    @Weng said:

    And really, it's not as if this Javascript is going to do anything fatally incorrect - it'll just display a dialog box that doesn't make sense in its new context, with no harm done other than looking silly.

    I may be mistaken, too lazy to check, but I believe the problem is it won't display the dialog at all. And it'll be a crapshoot whether or not the form gets saved, depending on the browser and speed of the internet link. (My guess: IE 7, 8: Yes. IE 9: crapshoot, tending towards yes. FF: Rarely or never. Chrome: Definitely never.)



  • BTW, I have a fix/hack for sending data from Unload in Chrome. PM me if you want the codez (it's only a couple lines), but I won't post it here because some Chromium dev will read it and fix the hole.



  • @Daniel Beardsmore said:

    "It's stupid but it work worked" ...?

    I think the OP wanted ^W and not ^H. A forgivable mistake, but annoying to us pedants. I noticed it right away as well.


  • Garbage Person

    @blakeyrat said:

    If you want to rant about .Net 4.5, why don't you start a new thread? Because I don't see what the holy shit it has to do with what I typed at all. Or this thread. Or anything. At all. Ever.
    Don't let me post with a hangover. Stupid connections get made in my head and the "this is not the appropriate place" and "you don't really know enough about this topic to rant about it" filters misfire.

     @blakeyrat said:

    This is the W3C we're talking about. The standard doesn't change. Until 5 years after it's obvious to everybody everywhere it needs to. The inability of web pages to send data during Unload is one of those huge problems the W3C badly needs to fix, and there's a great need for. (As this code shows.)

     Yeah, the W3C fellates donkeys, but there's a sort of de facto standard that actually does change over time, particularly with regard to Javascript.



  •  I thought people used ^H to indicate backspace.

     


  • Garbage Person

    @El_Heffe said:

     I thought people used ^H to indicate backspace.

     

    ^H is the control character for 'delete one character'. ^W is the control character to delete the entire previous word. The title should therefore have been either: "It's stupid but it works^Hed" or "It's stupid but it works^Wworked"

  • Trolleybus Mechanic

    #define ^H ^W

    When I first saw this code, I asked why we do it this way. "Because it works". And when a popup stops being onunload modal?  "But it works". 

    @blakeyrat said:

    BTW, I have a fix/hack for sending data from Unload in Chrome. PM me if you want the codez (it's only a couple lines), but I won't post it here because some Chromium dev will read it and fix the hole.
     

    Appreciated, but I think I'll just do this:

    @teh codez of JavaScript said:

    alert("Your form will be saved and you will be logged out");

    document.getElementById("saveAndLogoutButton").click(); 

    @teh pseudocodez on da server .Net said:

    sub saveAndLogoutButton_OnClick()
    {
        theSameFuckingSaveRoutineTheOtherButtonCalls();
        Response.Redirect("logout.aspx");

     }

     


  • Trolleybus Mechanic

    @blakeyrat said:

    I may be mistaken, too lazy to check, but I believe the problem is it won't display the dialog at all. And it'll be a crapshoot whether or not the form gets saved, depending on the browser and speed of the internet link. (My guess: IE 7, 8: Yes. IE 9: crapshoot, tending towards yes. FF: Rarely or never. Chrome: Definitely never.)
     

    Exactly. The dialog shows, and modally prevents the javascript redirect until OK is pressed. But the page has already trigged a submit (which saves the form). Before, I suppose it wouldn't process unload (and show the response from the POST) until after the click handler had returned. Before the click handler returns, there's a redirect statement, so the response from the POST is lost. Now, the submit triggers and unload, which murders anything else that's running-- including the alert.

    So the user sees a microsecond flash of the alert, and then the page refreshes as if they'd just clicked the save button (which, in a way, they had).

    The sad part is, I don't know if the original developer even did this because they thought it was a clever way of saving the form on a logout, or if they just had absolutely no idea how event handlers and form submissions worked, and just by fluke came up with a way of fulfilling the requirements.

    Ok-- I say "I don't know", but if I had to draw a roulette wheel where black was the former, and red was the latter, the wheel be redder than a wagon that had run over a strawberry patch full of children.

    There would be no green spots. And instead of a ball, it'd be a solid cube of stupid. And instead of a croupier, it'd be that developer. And serving drinks, instead of a middle aged woman desperately clinging to the last vestiges of her faded youth by working a soul crushing job at ungodly hours while the very fabric of her life crumbles down around her, it'd be an analogy that's stretched to its absolute limits-- like the face of the plastic-surgeon addict at the craps table five rows over weepily blowing on the dice, hoping for a seven so that maybe, just maybe, the paycheck worth of chips they just wagered will pay off and they can get both that one last face lift-- and something to eat.



  • @blakeyrat said:

    The inability of web pages to send data during Unload is one of those huge problems the W3C badly needs to fix, and there's a great need for. (As this code shows.)

    I'm curious; what else would use that unload thingy for?



  • @beermouse said:

    @blakeyrat said:
    The inability of web pages to send data during Unload is one of those huge problems the W3C badly needs to fix, and there's a great need for. (As this code shows.)

    I'm curious; what else would use that unload thingy for?

    Analytics. Sending a pixel/whatever during unload lets you see:

    1) Which link was clicked to exit the page (especially important if an external link)

    2) How long the user was actually on the page (even if they don't continue on to another page on your site)

    3) Flush-out various other events that you've been tracking so they don't get lost (for example, we track the X/Y of clicks so we can make a heatmap, we queue them in a JS variable and flush the queue during Unload)

    W3C needs to come up with a standard where you can queue up a single simple (just a GET on a url) HTTP request during page unload, and tell the browser to send it without delaying the loading of the next page. I don't think that's unreasonable, web analytics are important for everybody (even the most GNU nerd in GNU-land) and if added to the spec and browsers, thousands of pages wouldn't need to delay Unload any longer because they could accomplish their goal much easier. It's obviously a net good for everybody involved. I'm not holding my breath though.

    Lorne is lucky; he has access to the back-end, so he doesn't have to worry about any of this. Web Analytics products generally do not, we're limited to DOM and JavaScript and pain pain pain.



  • @Weng said:

    @El_Heffe said:

     I thought people used ^H to indicate backspace.

     

    ^H is the control character for 'delete one character'. ^W is the control character to delete the entire previous word. The title should therefore have been either: "It's stupid but it works^Hed" or "It's stupid but it works^Wworked"
     

    It's stupid but it works^H^H^H^H^H worked

     



  • @blakeyrat said:

    1) Which link was clicked to exit the page (especially important if an external link)
    @blakeyrat said:
    W3C needs to come up with a standard where you can queue up a single simple (just a GET on a url) HTTP request during page unload, and tell the browser to send it without delaying the loading of the next page.
    If I may take a break from the comedy to ask a serious question .... ....  If I'm on a page and don't click on anything -- I leave the page by closing that tab, what happens?



  • @El_Heffe said:

    I leave the page by closing that tab, what happens?
     

    The hastily-spec'd event window.beforeunload fires, and if the developer filled it, you get a dialog box that allows you to go ahead and unload, or stay.

    Try it on Gmail by exiting quickly before shit is fully loaded. Since Firefox 4:

    As you can see, it is window-modal, and not in-page like its new alert() style.



  • @El_Heffe said:

    @blakeyrat said:

    1) Which link was clicked to exit the page (especially important if an external link)
    @blakeyrat said:
    W3C needs to come up with a standard where you can queue up a single simple (just a GET on a url) HTTP request during page unload, and tell the browser to send it without delaying the loading of the next page.
    If I may take a break from the comedy to ask a serious question .... ....  If I'm on a page and don't click on anything -- I leave the page by closing that tab, what happens?

    Monkeys fly out of your ass? I have no idea what you're getting at. If there's data to send, it gets sent. If not, nothing happens.



  • @dhromed said:

    @El_Heffe said:

    I leave the page by closing that tab, what happens?
     

    The hastily-spec'd event window.beforeunload fires, and if the developer filled it, you get a dialog box that allows you to go ahead and unload, or stay.

    That's what I was wondering about.  I didn't know if such a spec existed or if each browser just did .... whatever .... or nothing.

     



  • @El_Heffe said:

    I didn't know if such a spec existed or if each browser just did .... whatever .... or nothing.

    Those two things are not mutually-exclusive.

    Unload (and BeforeUnload) fire no matter what caused the Unload. The answer to "what happens when you close the tab" is "the same thing happens when you click a link, or quit the browser, or restart your computer-- the Unload/BeforeUnload handler fires."

    I thought you were asking about what my analytics script did. Or about the monkeys in your ass.



  • I gleaned something different from the code, so I feel like I missed something - maybe it's an ASPX thing, which I know nothing about. Was it a typo in the JS code to say onclick and not onunload? Or is it because the SaveFormBeforeLogout basically calls another (assuming submit) button's click handler?


  • ♿ (Parody)

    @blakeyrat said:

    Unload (and BeforeUnload) fire no matter what caused the Unload. The answer to "what happens when you close the tab" is "the same thing happens when you click a link, or quit the browser, or restart your computer-- the Unload/BeforeUnload handler fires."

    I thought it was an interesting question. I've never played around with this sort of event, and I had no idea either what would happen in case you left the page in some way other than navigation by link. Presumably, this also happens if you use the browser's back (or forward) button? Also, can you (as an analytics thingy) tell the difference between these various ways to leave?



  • @dohpaz42 said:

    I gleaned something different from the code, so I feel like I missed something - maybe it's an ASPX thing, which I know nothing about. Was it a typo in the JS code to say onclick and not onunload? Or is it because the SaveFormBeforeLogout basically calls another (assuming submit) button's click handler?

    From what I understand, it's supposed to save the data, and then log out. So it first clicks the save button, and then is supposed to wait until the save page has been loaded before logging out. However, if the alert doesn't modally block script execution, it will just redirect to logout page right after hitting the other button, which - depending on the implementation and good weather - might not have finished its action yet.

    Edit: Can't onunload only be in the <body> element? That would cancel your typo argument.



  • @boomzilla said:

    Presumably, this also happens if you use the browser's back (or forward) button?

    It happens regardless of how the page is unloaded. So yes, hitting the back or forward button qualifies. So does hitting refresh. About the only time it won't is if your browser crashes, or computer bluescreens. (Although note there's no guarantee script in an Unload handler will actually run for long... if you take longer than a few milliseconds, you'll be cut-off.)

    @boomzilla said:

    Also, can you (as an analytics thingy) tell the difference between these various ways to leave?

    The only ways I care about are: form submission, or link click. Which I can tell because they have their own handlers that fire just before the Unload handler fires.

    Whether you can tell the difference between Back, Forward, Refresh, closing the window, closing the browser-- I dunno. Probably not. It's never come-up, so I've never tried.



  • @derula said:

    From what I understand, it's supposed to save the data, and then log out. So it first clicks the save button, and then is supposed to wait until the save page has been loaded before logging out. However, if the alert doesn't modally block script execution, it will just redirect to logout page right after hitting the other button, which - depending on the implementation and good weather - might not have finished its action yet.

    The way that I understand this code is this:

    • The user clicks a submit button.
    • The submit button calls an onclick of another button - I'm assuming it's also a submit button
    • Because the call to the second button occurs BEFORE the alert, the page gets submitted (i.e., implicitly unloaded) before the alert()
    • No alert()

    Now, the above logic does follow a couple of assumptions, but without knowing what the second button is and what it's JS handler (if any) is, I could go either way with the success/fail rate (i.e., it's sunny today, so it works; it's rainy today so it fails). Regardless, it seems to me that unless the onclick was a typo, then the unload issue is moot, because according to the supplied code, there is no custom unload handler - hence my confusion, since everyone is going the unload route in the discussion.

    @derula said:


    Edit: Can't onunload only be in the <body> element? That would cancel your typo argument.

    I can't speak in terms of HTML, but I do know that the JS unload event can only work from the window level of the DOM. So even if onclick was a typo, unload shouldn't ever work from the document > form level. But that would be a different WTF than what is being discussed.

    With all of that tl;dr said, yes I understand the spirit of the WTF; it should be using asynchronous calls and only redirecting on a success and not using an alert() kludge. :)



  • @blakeyrat said:

    It happens regardless of how the page is unloaded. [...] About the only time it won't is if your browser crashes, or computer bluescreens.
     

    So the only way to foil your evil world domination plans is to leave the page via killall -KILL resp. taskkill /T /F ?

    Good thing I'm not too paranoid about web statistics;)

     



  • @Ilya Ehrenburg said:

    So the only way to foil your evil world domination plans is to leave the page via killall -KILL resp. taskkill /T /F ?

    If you're using Linux, we don't give a shit about you. So it all works out.



  • @blakeyrat said:

    @Ilya Ehrenburg said:
    So the only way to foil your evil world domination plans is to leave the page via killall -KILL resp. taskkill /T /F ?

    If you're using Linux, we don't give a shit about you. So it all works out.



  • @blakeyrat said:

    If you're using Linux, we don't give a shit about you. So it all works out.
    Great! So when I'm on windows, all I have to do is spoof the user agent and no more web stats?



  • @Ilya Ehrenburg said:

    @blakeyrat said:

    If you're using Linux, we don't give a shit about you. So it all works out.
    Great! So when I'm on windows, all I have to do is spoof the user agent and no more web stats?

    It works the other way too; simply change your UA to "Internet Explorer 12" or some such non-sense. His stats won't be useful for a few more years.



  • @dohpaz42 said:

    @Ilya Ehrenburg said:

    @blakeyrat said:

    If you're using Linux, we don't give a shit about you. So it all works out.
    Great! So when I'm on windows, all I have to do is spoof the user agent and no more web stats?

    It works the other way too; simply change your UA to "Internet Explorer 12" or some such non-sense. His stats won't be useful for a few more years.

    We only care about statistical significance. Our web analytics data is to support usability research, not building the world's biggest CRM database or anything. I know, I know, that ruins all the conspiracy theories-- sorry.



  • @blakeyrat said:

    I know, I know, that ruins all the conspiracy theories-- sorry.

    To be fair, if you worked for Facebook or Google (and who knows, you just might) then that would be a viable conspiracy theory. But then again, your company was bought by the French, so there is still a chance.


  • ♿ (Parody)

    @blakeyrat said:

    We only care about statistical significance.

    Those words are like fingernails on a chalk board. Almost no one uses them in a meaningful or significant way.



  • @blakeyrat said:

    I know, I know, that ruins all the conspiracy theories-- sorry.
    Pffft. As if we let facts meddle with our conspiracy theories.

     



  • @boomzilla said:

    @blakeyrat said:
    We only care about statistical significance.
    Those words are like fingernails on a chalk board. [b]Only a statistically insignificant proportion of people use[/b] them in a meaningful or significant way.
    FTFY.



  • @Lorne Kates said:

    And you point it out, because one day it WILL explode? And you get told "no, it's ok". Then one day that little bit of code that is sitting in production explodes?
     

     

    I once pointed out a WTF in code to some boss I had in a previous job. Some code which messed up with non-internalized strings. He tould me what were the odds of something bad happening. I told him "one in a million, but..."

    He just told me not to waste company resources on it then. I went on "... but with over 10 million transactions a day, that's going to happen quite frequently".

     My orders remained the same. And from what people told me about a couple years later, the system was so messed up, it was unusable (the WTF I pointed out being just the tip of the iceberg, though all of the WTF's were of this same kind).

     



  • @Renan said:

    I once pointed out a WTF in code to some boss I had in a previous job. Some code which messed up with non-internalized strings. He tould me what were the odds of something bad happening. I told him "one in a million, but..."


    He just told me not to waste company resources on it then. I went on "... but with over 10 million transactions a day, that's going to happen quite frequently".


    Bad:


    "One in a million... but with over 10 million transactions a day, that's going to happen quite frequently."


    Better:


    "One in a million for any single transaction... but with over 10 million transactions per day, that's a 99.995% chance of something bad happening on a given day."


    Best:


    "It will probably happen several to dozens of times each day."

    Otherwise they hear "one in a million" and just tune everything else out.



  • @Scarlet Manuka said:

    Otherwise they hear "one in a million" and just tune everything else out.
     

    But, in all fairness, that is because they are idiots.



  • @dhromed said:

    @Scarlet Manuka said:

    Otherwise they hear "one in a million" and just tune everything else out.
     

    But, in all fairness, that is because they are idiots.

    Life, and business, isn't fair. If you already know that the person that makes decisions is an idiot, then you need to talk to him on their "level". Otherwise, you are TRWTF*.

    * "You" in this case is not specifically directed toward any one person, but instead is a generalization made in the first person



  • @dohpaz42 said:

    "You" in this case is not specifically directed toward any one person, but instead is a generalization made in the [b]second[/b] person

    FTFY.



  • @blakeyrat said:

    @beermouse said:
    @blakeyrat said:
    The inability of web pages to send data during Unload is one of those huge problems the W3C badly needs to fix, and there's a great need for. (As this code shows.)

    I'm curious; what else would use that unload thingy for?

    Analytics.

    Thanks for your reply and sorry for butchering it; but is there anything else useful[tm] that could be done with this?



  • @beermouse said:

    Thanks for your reply and sorry for butchering it; but is there anything else useful[tm] that could be done with this?

    There's the example in this thread, using it to "save" the contents of a form before the page unloads.

    Edit: wait a minute, are you implying analytics isn't important enough on its own? If the fucking W3C had thought of analytics when they designed this whole ball of shit in the first place, think of how much code we'd all be saving. Just having a reliable way of identifying the browser/version and OS would save tons of JS on every page load.


Log in to reply