var EQ_top_location = "EQ_top_location"; var EQ_parent = "EQ_parent"; var EQ_self = "EQ_self"; var EQ_old_onclick = document.onclick; document.onclick = function() { EQ_top_location = top.location; EQ_parent = parent; EQ_self = self; document.onclick = EQ_old_onclick; } // lookup array for names of URL components var URLCompName = [ "full", "scheme", "host", "port", "path", "param", "query", "anchor" ]; // removes whitespace from both ends of string function trimString( s ) { return s.replace( /^\s*/, "" ).replace( /\s*$/, "" ); } // assign annotInfo.url to EQ_baseURL // BNF for URL from RFC1808 // http://www.cis.ohio-state.edu/htbin/rfc/rfc1808.html#id1257 function EQ_fix_url( relURL ) { EQ_baseURL = trimString( EQ_baseURL ); relURL = trimString( relURL ); // case 0: return EQ_baseURL if relURL is empty if ( relURL.length == 0 ) return EQ_baseURL; // case 1: relURL is absolute if it contains a scheme if ( /^[\w\-\.\+]+:/.test( relURL ) ) return relURL; // case 2: relURL is absolute if it starts with // if ( /^\/\//.test( relURL ) ) return "http:" + relURL; // relevant BNF // regular expression for full url // net_loc = *( pchar | ";" | "?" ) // query/fragment = *( pchar | reserved ) // = [\w\$\-_\.\+!\*'\(\)%;\/\?:@&=] // pchar = uchar | ":" | "@" | "&" | "=" // uchar = [\w\$\-_\.\+!\*'\(\)%] // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" // remarks about differences from RFC 1808: // In order to deal with base URLs such as "http://foo.com/blah&q=http://bar.com" // paths may not contain '&' while queries may start with '&'. // (RFC allows '&' in paths and does not allow queries to start with '&'. var fullURL = /^([\w\-\.\+]+:)\/\/([\w\$\-_\.\+!\*'\(\)%@&=;\?]*)(:\d+)?([~\/\w\$\-_\.\+!\*'\(\)%:@=]*)?(;[;\/\w\$\-_\.\+!\*'\(\)%:@&=]*)?([\?&][\w\$\-_\.\+!\*'\(\)%;\/\?:@&=]*)?(#.*)?$/; var result = EQ_baseURL.match( fullURL ); // if the base URL is invalid, return the relative URL if ( result == null ) return relURL; // assign parts of match result to variable with some meaningful names var temp = "number of variables matched = " + result.length; for (var i=0; i 0 ) temp += "\n" + URLCompName[i] + ":\t" + result[i]; // use more meaningful names for URL components var baseScheme = result[1]; var baseHost = result[2]; var basePort = result[3]; var basePath = result[4]; var baseParam = result[5]; var baseQuery = result[6]; var baseAnchor = result[7]; // replace scheme with "http" if ( /https/.test( baseScheme ) ) baseScheme = "https://"; else baseScheme = "http://"; // case 3: relURL starts from root directory // doesn't try to optimize relative path in this case // ie. all .. and . references in relative path will // be retained. if ( /^\//.test( relURL ) ) return baseScheme + baseHost + basePort + relURL; // case 4: relURL starts with ; if ( /^;/.test( relURL ) ) return baseScheme + baseHost + basePort + basePath + relURL; // case 5: relURL starts with ? if ( /^\?/.test( relURL ) ) return baseScheme + baseHost + basePort + basePath + baseParam + relURL; // case 6: relURL starts with # if ( /^\#/.test( relURL ) ) return baseScheme + baseHost + basePort + basePath + baseParam + baseQuery + relURL; basePathList = basePath.replace(/^\//gi, "" ).split("/"); relPathList = relURL.split("/"); // try to pop off filename if ( ( basePathList.length>0 && /\./.test( basePathList[basePathList.length-1] ) ) || /\/$/.test( basePath ) ) basePathList.length--; // combine both arrays with basePathList at the beginning basePathList = basePathList.concat( relPathList ); // expand array to hold maximum number of tokens first // resize after parsing is done relPathList.length = basePathList.length; var curSize = 0; var minSize = 0; // highest level of parent recursion possible for (var i=0; i minSize ) curSize--; else { // insert ".." into path minSize++; // can't recurse above this ".." directory relPathList[ curSize++ ] = curToken; } } else if ( curToken == "." ) { if ( i == basePathList.length-1 ) // last token relPathList[ curSize++ ] = ""; } else // default action is to insert into path relPathList[ curSize++ ] = curToken; } relPathList.length = curSize; return baseScheme+baseHost + basePort + "/" + relPathList.join( "/" ); } function EQ_newWindowOpen() { if ( arguments.length == 0 ) return EQ_originalWindowOpen(); // create the new absolute URL and replace the first argument with it. arguments[0] = EQ_fix_url( arguments[0] ); // Netscape has a nice apply() function which is // a static method of the function object which allows // you to pass an array (ie. the arguments object) to // a function variable (ie. oldOpen) // usage: function.apply( oldOpen, arguments ); // for now, since window.open has a maximum of 4 arguments, // we can pass in the arguments individually. switch ( arguments.length ) { case 2: return EQ_originalWindowOpen( arguments[0], arguments[1] ); break; case 3: return EQ_originalWindowOpen( arguments[0], arguments[1], arguments[2] ); break; case 4: return EQ_originalWindowOpen( arguments[0], arguments[1], arguments[2], arguments[3] ); break; default: return EQ_originalWindowOpen( arguments[0] ); } return EQ_originalWindowOpen(); } // override window.open var EQ_originalWindowOpen = window.open; window.open = EQ_newWindowOpen;