devote / HTML5-History-API

HTML5 History API expansion for browsers not supporting pushState, replaceState
http://spb-piksel.ru
MIT License
1.02k stars 182 forks source link

IE fallback with multiple parts in the deeplink duplicates the deeplink #26

Closed ThaNarie closed 10 years ago

ThaNarie commented 11 years ago

Hi,

I'm encountering a wrong behavior when using deeplinks like this in IE 8: http://localhost:8888/_projects/_libraries/frontend/_svn/skeleton/deploy/public/#/video/1

When doing a push-state with '/video/1' the resulting url is: http://localhost:8888/_projects/_libraries/frontend/_svn/skeleton-gaia/deploy/public/#/video/video/1 So the first part of the deeplink is repeated. When refreshing and setting the deeplink to that value, the first 2 parts get duplidated. So in short, everythint except the last part is duplicated.

When stepping trough with breakpoints I located the line that caused the error:

// convert relative link to the absolute href = /^(?:[\w0-9]+:)?\/\//.test( href ) ? href.indexOf( "/" ) === 0 ? _protocol + href : href : _protocol + "//" + current._host + ( href.indexOf( "/" ) === 0 ? href : href.indexOf( "?" ) === 0 ? _pathname + href : href.indexOf( "#" ) === 0 ? _pathname + current._search + href : _pathname.replace( /[^\/]+$/g, '' ) + href );

At that moment 'href' = "video/1", and _pathname = "/_projects/_libraries/frontend/_svn/skeleton/deploy/public/video/1" All the checks fail, so it will execute the last part: _pathname.replace( /[^\/]+$/g, '' ) + href

Here, only '1' is stripped from the _pathname, and video/1 is added, so 'video' is doubled.

I don't know all the situations this line is executed for (different inputs), so I'm not sure how to fix it correctly myself.

If you need more information, or if I have to test something, please let me know.

devote commented 11 years ago

Thanks for comment, I'll fix it in the near future.

devote commented 11 years ago

Hi again

I was unable to reproduce the problem, you can explain exactly what you do as a use that call.

Thank you!

devote commented 11 years ago

Are you sure that your link looks that way: /video/1

The situation about which you're talking about can be shown by using relative url like: video/1

ThaNarie commented 11 years ago

I will try to make a stripped-down example of my problem :)

ThaNarie commented 11 years ago

I've created a test-page to test the history behavior. After that I noticed I was not running the latest version, so I've updated. Some errors were fixed (the one I stated above, and also absolute/relative differences between IE8 and chrome).

Between all tests it behaves much better, but there are still some strange errors. I hope you don't mind me testing this so extensively? :) You want me to open another ticket for this?

http://devmonks.nl/n/narie/history/test/1

result summary:

devote commented 11 years ago

I looked at your example, and I want to make some amendments.

You are using an asynchronous download and basepath option in this situation can not be read.

You need to do this:

...
var historyPath = '/history.js';
...
...
    ], function () {
        history.redirect && history.redirect('/', basePath);
        new Main();
    });
...
ThaNarie commented 11 years ago

Aah, that is good to know! I've changed the code on the link above, and it changed the behavior a little:

All other issues remain :)

ThaNarie commented 11 years ago

FYI: i've also wrote some code to wrap around the 2 history calls I'm using, to fix the inconsistencies. For the time being, because of this, it looks like I can use the library in it's current state :)

http://devmonks.nl/n/narie/history_fixed/test/1

When you fix things I can remove checks from my own code :)

devote commented 11 years ago

All other issues remain :)

deeplinks should never include the domain or basepath, or always include the full correct href

Not sure what it is, if you pushed a link like /test/1 So in this case, the browser converts domain link from the beginning: http://somesite.com/test/1 This behavior is observed in all HTML5 browsers

deeplinks should always begin with a '/' if there is a difference between setting absolute or relative

Above, I described a situation in which this can not happen

url's should never strip the basepath (chrome)

Not only Chrome, but all HTML5-browsers

relative (without starting '/') should act relative (chrome) (or at least do the same thing in all browsers)

Is not that so?

it breaks the 'push current deeplink' because it now acts as a relative push because the deeplink has no starting '/'

Do not quite understand what you mean

devote commented 11 years ago

When you fix things I can remove checks from my own code :)

Hmm, interesting solution.

ThaNarie commented 11 years ago

Aah, you are correct or course, forgot for a moment you are mimicking the normal HTML5 browser implementation. HTML5 uses the domain when absolute (pushState starting with "/") and the base-href when relative (not starting with "/") IE8 uses the # when absolute, and the current #/path/segments when relative.

Where I say chrome, I mean all HTML5 browsers yes :) And where I say should, I mean "what I think would be the best" :)

The whole issue is that there is no 'deeplink' part in the API, only a href, correct? And when pushing and retreiving states, you are mostly interested in the deeplink part. So that is why I wrote that 'abstraction' part.

Still, there are some issues/differences with IE8 that behave differently from HTML5 when you add or remove the first "/".

@your last question: If you go to "http://devmonks.nl/n/narie/history/test/1" in IE8, and click the 'replace current deeplink' (that gets and sets the deeplink), the deeplink gets longer, but should stay the same.

So to summarize it all:

devote commented 11 years ago

IE8 doesn't always act the same way as HTML5

I agree with you, and of course realizing maximum convenience for you, but it should not conflict with the current functionality of HTML5 browsers. With each new situation, there may be certain problems, since we are all working with the same hash reference, and the HTML4 browser responds to them differently.

devote commented 10 years ago

I close this issue, if you still want to solve this, let me know. Thank you