asual / jquery-address Goto Github PK
View Code? Open in Web Editor NEWjQuery Address - Deep linking for the masses
Home Page: http://www.asual.com/jquery/address
License: GNU General Public License v2.0
jQuery Address - Deep linking for the masses
Home Page: http://www.asual.com/jquery/address
License: GNU General Public License v2.0
First off, the plugin is working great with Firefox and IE 7.
I am experiencing a bug with IE 8. I have a page that uses
Thanks,
I do something like this:
where value is an object and on change i get it back with $.deparam(value)
But in v1.3 this doesn't work because of the intern encode.
I have changed it a bit and without the encode and decode in the value function it works again.
Can you do something to get it work in the next version?
Another question is: can you implement such a function for address ... $.address.parameter(index,value) ... where value is an object. ... i think the problem here is just the get the value back not to set it (just a if and a encode).
Hi!, have you read this?
http://googlewebmastercentral.blogspot.com/2009/10/proposal-for-making-ajax-crawlable.html
http://docs.google.com/present/view?id=dc75gmks_120cjkt2chf
maybe you can implement #! instead of # by default or add an option to activate it
thanks
had made some changes to support objects for this version:
http://github.com/asual/jquery-address/blob/6cbd64b2f7784adc746f645980bc3121c8b0ab66/src/jquery.address.js
now it doesn't work but it could help you to support objects
i changed only this 2 functions and added one (the deparam function is from a other jquery plugin with a small change).
if you don't like it, close it :)
_parameter = function(name, value) {
value = _queryString(value);
if (value) {
params = value.split('&');
var r = [];
for (i = 0; i < params.length; i++) {
var p = params[i].split('=');
if (p[0] == name) {
var temp=$.address.decode(p.slice(1).join('='));
if(temp.indexOf('=')!=-1){
temp=$.address.deparam(temp);
}
r.push(temp);
//r.push(p.slice(1).join('='));
}
}
if (r.length !== 0) {
return r.length != 1 ? r : r[0];
}
}
},
parameter: function(name, value, append) {
var i, params;
if (value !== undefined) {
if(typeof value=='object'){
value=_encode($.param(value));
}
var names = this.parameterNames();
params = [];
for (i = 0; i < names.length; i++) {
var n = names[i],
v = this.parameter(n);
if (typeof v == 'string') {
v = [v];
}
if (n == name) {
v = (value === null || value === '') ? [] :
(append ? v.concat([value]) : [value]);
}
for (var j = 0; j < v.length; j++) {
params.push(n + '=' + v[j]);
}
}
if ($.inArray(name, names) == -1 && value !== null && value !== '') {
params.push(name + '=' + value);
}
this.queryString(params.join('&'));
return this;
}
return _parameter(name, this.value());
},
deparam: function(params,firstdecodeURIComponent){
var obj={},
params=params || '',
firstdecodeURIComponent=firstdecodeURIComponent || true
;
//coerce_types={'true':!0,'false':!1,'null':null};
if(firstdecodeURIComponent){
params=decodeURIComponent(params);
}
// Iterate over all name=value pairs.
$.each(params.replace(/\+/g,' ').split('&'),function(j,v){
var param=v.split('='),
key=decodeURIComponent(param[0]),
val,
cur=obj,
i=0,
// If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
// into its component parts.
keys=key.split(']['),
keys_last=keys.length - 1
;
// If the first keys part contains [ and the last ends with ], then []
// are correctly balanced.
if(/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])){
// Remove the trailing ] from the last keys part.
keys[keys_last]=keys[keys_last].replace(/\]$/,'');
// Split first keys part into two parts on the [ and add them back onto
// the beginning of the keys array.
keys=keys.shift().split('[').concat(keys);
keys_last=keys.length-1;
}else{
// Basic 'foo' style key.
keys_last=0;
}
// Are we dealing with a name=value pair, or just a name?
if(param.length===2){
val=decodeURIComponent(param[1]);
// Coerce values.
/*if(coerce){
val=val && !isNaN(val) ? +val // number
: val === 'undefined' ? undefined // undefined
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
: val; // string
}*/
if(keys_last){
// Complex key, build deep object structure based on a few rules:
// * The 'cur' pointer starts at the object top-level.
// * [] = array push (n is set to array length), [n] = array if n is
// numeric, otherwise object.
// * If at the last keys part, set the value.
// * For each keys part, if the current level is undefined create an
// object or array based on the type of the next keys part.
// * Move the 'cur' pointer to the next level.
// * Rinse & repeat.
for(;i<=keys_last;i++){
key=(keys[i]==='') ? cur.length : keys[i];
cur=cur[key]=(i<keys_last)
? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] ): val;
}
}else{
// Simple key, even simpler rules, since only scalars and shallow
// arrays are allowed.
if($.isArray(obj[key])){
// val is already an array, so push on the next value.
obj[key].push(val);
}else if(obj[key]!==undefined){
// val isn't an array, but since a second value has been specified,
// convert val into an array.
obj[key]=[obj[key],val];
}else{
// val is a scalar.
obj[key]=val;
}
}
}else if(key){
// No value was defined, so set something meaningful.
//obj[key]=(coerce) ? undefined : '';
obj[key]='';
}
});
return obj;
},
If I save a deep link in Firefox 3.6 and load it in Chrome 9, the page will load as if I loaded the link with the hash stripped.
The other way works fine, where I load a non-hashed link in Firefox 3.6 and it redirects to the hashed version.
To reproduce, try loading http://www.asual.com/jquery/address/samples/state/#/about in FF 3.6 and then in Chrome 9.
jquery.address-1.3.1 crawlable /#/link
needs to be automatically replaced with (redirected to) /#!/link
, because they are two different urls. Unfortunately still twitter has the same bug http://twitter.com/#!/laukstein http://twitter.com/#/laukstein.
Also if you keep flowing Ajax SEO, you need to redirect links like crawling/?_escaped_fragment_=%2Ffaq
with header status 301 Moved Permanently to crawling/faq
or crawling/#!/faq
(Twitter already has that feature _http://twitter.com/?_escaped_fragment_=/laukstein > http://twitter.com/laukstein).
You can read more about it in http://www.seomoz.org/blog/how-to-allow-google-to-crawl-ajax-content and http://searchengineland.com/googles-proposal-for-crawling-ajax-may-be-live-34411 .
Also use decodeURIComponent()
http://jsbin.com/esafe/edit or something similar to make urls readable and user friendly, probably not everyone will figure out that %2F
is /
. ;)
If a parameter is not already set, but an attempt is made to unset it again by passing null or an empty string as a value, the parameter is set with null or an empty string as a value. I believe this is due to the check for a name at http://github.com/asual/jquery-address/blob/master/src/jquery.address.js#L513.
As
That said, $.browser IS deprecated. Any plans of moving off it?
This bug relates to the use of $('form').address().
The plugin should check the form's action URL to make sure there are not already any query variables. Right now it merely appends the form data onto the action URL using +"?"+ . It should first check the action to see if the "?" character exists and if so append the form data appropriately.
For instance:
This sample code should provide a good example:
// Create jQuery object from form element
var form = $(this);
// Get the form action (while replacing trailing "?" or "&")
var action = form.attr('action').replace(/&$|\?$/, '');
// Append either a "?" or "&"
action += (action.indexOf('?') == -1) ? "?" : "&";
// Append the serialized form data
action += $.address.decode(form.serialize());
On IE9.0.8023.60000 Platform Preview http://.../jquery/address/samples/state/contact and http://.../jquery/address/samples/state/#/contact opens Home content
and not Contact content
.
In IE7 (I believe in IE6 as well) there is a bug with file input elements. They all don't work. Quick fix is to change line 408.
Was: $(document).bind('propertychange'
Change to: $(document).onpropertychange = function() { ....
And as well don't forget the closures :)
I'm not entirely sure how you are encoding/parsing data sent to the parameter function, but there seems to be a problem in that there's no way to differentiate a + and a space once it's sent through parameter(). For example:
$.address.parameter('test', value test');
$.address.parameter('test', 'value+test');
both encode to the identical value "value+test", where one would expect something more like "value%20test" and "value%2Btest" or similar. Just any way to differentiate those two values once they've been dropped into the URI.
in example
right clik on a tab and clik open in new tab,
leads to a broken page.
example:
start here;
http://www.asual.com/jquery/address/samples/tabs/#/extras.html
right click and open new tab on overview,
takes u here: page it missing content.
http://www.asual.com/jquery/address/samples/tabs/#Overview
should take u here;
http://www.asual.com/jquery/address/samples/tabs/#
A JQuery plugin (raty) is in conflict with JQuery Address. If i delete JQuery Address it works. How do I run them both?
Plz help me!
If the page uses anchor tags version 1.2 fails; this worked fine on 1.2rc. The bug is in the _unescape function:
_unescape = function() {
var base = _l.pathname.replace(/\/$/, ''),
fragment = '_escaped_fragment_';
$('a:not([href^=http])', this).each(function() {
//==>
if ($(this).attr('href') != null) { // need to add this guard as the next line will fail if using an a-tag without an href attr...
var href = $(this).attr('href').replace(new RegExp(base + '/?$'), '');
if (href == '' || href.indexOf(fragment) != -1) {
$(this).attr('href', '#' + decodeURIComponent(href.replace(new RegExp('/(.*)\\?' + fragment + '=(.*)$'), '!$2')));
}
}
});
},
The error is a result of the selector on line 229:
$('a:not([href^=http])', this).each(function() {
This also selects <a> tags without href attributes, causing the error on line 230 when it tries to use the replace function on the href attribute, which does not exist. A working fix is to use the following selector instead, which correctly only selects <a> tags which have the href attribute first, before applying the not(href^=http]) modifier.
$('a[href]:not([href^=http])', this).each(function() {
All commits past c8ba442 incorrectly treat dynamically created links as external changes instead of internal as they should be.
Also on this note - a feature request... I think it would be helpful if the $.address.change(fn) event, there was a way to determine if the change was internal or external.
Using jQuery 1.5 and the latest code, I get the following exception:
Syntax error, unrecognized expression: [rel*=address:]
The exception is fixed when line 264 is changed from:
if (el.is('[rel*=address:]')) {
To:
if (el.is('[rel*="address:"]')) {
(Notice the double quotes added.)
I would guess that Sizzle changed how they parse *= selectors in the latest jQuery. Also, the change above should be backwards compatible with older versions of jQuery.
I'm not really sure if this is an issue or if it's by design.. I have a page whose url looks like this: http://www.domain.com/folder?page=1
There is a link on the page to "/folder" and when the address plugin loads, it's url gets replaced with "#".
It's in the _unescape function, where it strips the base from internal urls, and then checks if there's anything remaining - but the base doesn't include the query string. Is this by design?
Thanks!
Go to http://www.asual.com/jquery/address/samples/form/
Enter a String to input und textarea:
for example: "Test mit Sonderzeichen + - / = ÖÄÜ und Leerzeichen"
after "change event" you'll see "Test+mit+Sonderzeichen+%2B+-+%2F+%3D+ÖÄÜ+und+Leerzeichen" :-/
any idea?
So I'm developing a web version of our site for the iPad and using jquery-address. We have several YouTube videos and a FB Like button for each. You can scroll through the videos and the address changes e.g. example.com/#vid=1233. The weird bug is that sometimes the page will redirect to facebook.com/#vid=1234 (before I updated to the latest version of jquery-address and was on 1.2.2, it would redirect to the Facebook Like url with the anchor tag address appended).
If I turn jquery-address off, the redirect problem goes away. The redirect doesn't always occur at the same position (i.e. it could be the 1st video or the 4th).
I don't have a public version of this right now as its currently in development.
If you try to validate latest jquery.address.js trough jslint.com, you have lots of errors there.
Internet Explorer 8 and 7 raise JS error:
"attribute only valid on v:image" in line 80 of jquery.address-1.3.1.js
It happens when on the same page Cufon is used for font rendering. Cufon on IE8/7 uses VML for rendering. The problem is that VML elements raise such exception when src attribute is accessed (and for nodeName also).
I made ad-hoc solution for my needs by adding such condition at the beginning of _search function:
if (el.nodeName.toLowerCase() == 'cufon') return '';
but this is far from general solution.
Greetings,
Lukasz
great work with your plugin!!
its easy to use+gives me all i want ;-)
i'm just such a penny pincher that i write to you the little warning i get when i use your script (mozilla+chrome tested):
in line 172 of the Address Plugin v1.1 there seems to be a problem with jquery 1.4.2
it doesnt except the ':' ($('a[rel*=address:]').address();) their, since normaly its used to start a filtered statment ...
i fixed it by add a double backslash infront of it
$('a[rel*=address:]').address();
worked for me... no warnings anymore ;-)
other than that: thanks man!!! really good plugin.
hope you find some easter eggs ;-) yours thomas
It would be very nice for users if the releases were marked using tags. It would allow for users to download/track the latest stable version through git, easily get a diff between versions, and add some cryptographic security (if using signed tags). A description of using tags on github is available at http://learn.github.com/p/tagging.html. Also, more reasoning for the request is available, if desired.
Note: From a bit of digging, I believe the commit for 1.2.2 is 9022dd7
Thanks
Hi! I'm new here.. Well, all another links that are outside of the main container where jquery-address loads works great!
But when I click on the links that are inside of the container, the plugin seems not to work. I tried using .live() and .delegate() methods like this:
$(document).ready(function(){
$.address.crawlable('true')
function loadURL(url){
if(url !='#'){
$("#conteudo").load(url)
$("#conteudo").empty().html("
})
$('a').live('click',function(){
loadURL($(this).attr('href'));
});
})
Some sugestions?
Sorry for my bad English...
When I have URL such as http://page.com/?id=user
and I change the url to:http://page.com/?id=user%ed
then change is not being called.
%ed is í encoded. Any ideas?
If you add a parameter with a special character in the value string, url is broken.
Ej,
& characte
$.address.parameter('par', 'a&b');
$.address.parameter('par', 'a#b');
there should be lots of cases with this behavior
THNKS!
I uploaded the tabs folder directly to my host and ran the index.html. Firebug throws me an error stating that function d is not defined, if Firebug is disabled then it runs as intended across all browsers. Just having this issue with Firefox and Firebug with the Script feature turned on.
I ran into this before when the jQuery file wasn't either loaded or needed to be upgraded. But seeing how the test samples are run as-is I'm not sure what could be causing the problem.
If the value is an integer (e.g. $.address.value(1)), string functions like substr, split etc. will fail.
Doing a value.toString() fixes this bug for me.
value: function(value) {
if (value !== UNDEFINED) {
if (!isNaN(value) ) value=value.toString();
...
best regards
Arne
Currently the setting of pathnames / path / querystring etc is tied directly to $.address.value() .. It would be really nice to have the parser exposed so that link comparison could be simpler, and no additional custom hash/location parsing mechanisms would have to be put in place.
For example, it would be nice to be able to call $.address.parse(uri_or_hash) that returns an object that is similar to the event that is dispatched with EXTERNAL_CHANGE so that link comparison would be much easier. Right now one has to parse the string again to determine whether the link is selected/active or not.
a possible example:
$.address.change(function(event) {
$('a').each(function() {
// parse the data once into an object that is easy to compare
var data = $(this).data('address-'data') || $(this).data('address-'data', $.address.parse($(this).attr('href'));
if (event.parameters.somequeryvar && event.parameters.somequeryvar == data.parameters.somequeryvar) {
$(this).addClass('selected');
} else {
$(this).removeClass('selected');
}
});
});
Another possible example with this method would be to pass an object to $.address.value() with the elements already parsed .....
Maybe it'd be a good idea to start moving rel attributes over to the data-* attributes specified in:
very minor though, just putting it up here in case you decide to make a larger change one day.
Right now it properly uses .live('click') to make sure dynamically loaded links are also handled by the jQuery Address plugin, but forms do not.
Can you change it from using .submit() to .live('submit', fnc) instead so that dynamically-loaded form will be caught by the plugin as well?
Note: This only applies when using $('form').address(). To get around this issue you can do the following:
$('form').live('submit', function(e){
e.preventDefault();
var url = $(this).attr('action');
url += (url.indexOf('?') == -1) ? '?' : (url.indexOf('&') != (url.length-1) ? '&' : '');
url += $(this).serialize();
$.address.value(url);
});
Firefox 3.6.13, Firebug 1.6 State
: on firs try Open Link in New Tab
has 3 GET html requests. Does it needs to be so? Screenshot in http://goo.gl/4v1ho .
For Express
it works fine.
Use case:
I have a man menu, every menu item is a link with different has value ( #info, #settings, #admin, etc.). When user click menu item, $.address.externalChange handler builds corresponding view with ajax.
Suppose user clicked #admin and he is presented administration page where he can navigate deeper to admin sub-views (the admin sub-views are created with ajax). The point is that when he navigates a sub-view, the browser address string doesn't not change.
Then I would like user to be able to click #admin menu item, to "return" from the sub-view, i.e. to see original admin view.
To implement this it would be good to have $.address.extenralChange callback to be invoked. Currently it is not invoked because the browser address string is #admin, and the menu item he clicked has the same href - #admin.
I'm getting an error on page load when testing IE7 that seems to be coming from line 213 of jquery address. The error is not thrown if I don't load the js file, and is otherwise hard to nail down any specifics because of IE7's general difficulty in debugging.
The error is called "Permission denied", coming from "var win = _frame.contentWindow;" in:
_st(function() {
$(_frame).bind('load',
function() {
var win = _frame.contentWindow;
_value = win[ID] !== UNDEFINED ? win[ID] : '';
if (_value != _href()) {
_update(FALSE);
_l.hash = _crawl(_value, TRUE);
}
});
if (_frame.contentWindow[ID] === UNDEFINED) {
_html();
}
},
50);
This block of code is called only on IE6 and IE7. "if (_msie && _version < 8)"
Inserting an alert(win[ID]); will throw the error if placed ahead of the line where win[ID] is first referenced.
I'm not too familiar with how to deal with IE7 issues, does anyone else out there experience this error? My thought is that it might have to do with accessing properties of another frame (sandbox issues) though of course unless i'm mistaken, the frame that is created for history purposes shouldn't be outside the sandbox.
Any help would be greatly appreciated!
What really would be great to have in $.address is if it could make use of the pushState capabilities of newer browsers (like Chrome, Safari or FF4).
Check out here: https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
This causes problems where you can't use the
Visiting a page without the # mark on the ipad fails to call the init function.
http://www.asual.com/jquery/address/samples/api/ on an iPad does not show the inner box at all but
http://www.asual.com/jquery/address/samples/api/#/ works correctly.
I know these samples seem to be using an older version, but I have tested with 1.3.1 and the same issue exists
jquery-address is automatically invoking google analytics, and is getting it wrong.
I think it makes much more sense for me to manage this manually, in my change callback, but I cannot see a way to tell jquery-address to not invoke pageTracker.
I would argue that, although helpful, doing this is orthogonal to jquery-address' purpose, and therefore should be optional.
Currently, we can only set a strong representing a function defined in the window object as the tracker, using the $.address.tracker(value); function.
In my current project which is relly important regarding memory leak and other stuff, we don't want to create many and many function in the window object.
The idea here is to check in the _track function if the _opts.tracker is a function or not. If it is, just use it directly. If not, just use the current beahvior.
THE FIX ::
On line 113, we have :
var fn = _t[_opts.tracker],
Just replace it by :
var fn = $.isFunction(_opts.tracker) ? _opts.tracker : _t[_opts.tracker],
and we're done.
Thanks a lot for your plugin, and including this fix will be great for many people I think.
$.address.autoUpdate(false);
$.address.parameter('test', 1);
console.debug($.address.parameter('test'));
$.address.parameter('test', 0);
console.debug($.address.parameter('test'));
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.