mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Added path manipulation lib from jQuery.mobile, using it to ensure all URLs are made absolute (to fix IE issues)
This commit is contained in:
parent
3b72f598a2
commit
30989b598d
@ -233,6 +233,7 @@ class LeftAndMain extends Controller {
|
||||
THIRDPARTY_DIR . '/jquery/jquery.js',
|
||||
THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js',
|
||||
SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js',
|
||||
SAPPHIRE_DIR . '/admin/javascript/lib.js',
|
||||
THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js',
|
||||
THIRDPARTY_DIR . '/json-js/json2.js',
|
||||
THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js',
|
||||
|
@ -271,7 +271,8 @@
|
||||
|
||||
var url = $(node).find('a:first').attr('href');
|
||||
if(url && url != '#') {
|
||||
if($(node).find('a:first').is(':internal')) url = $('base').attr('href') + url;
|
||||
|
||||
if($(node).find('a:first').is(':internal')) url = url = $.path.makeUrlAbsolute(url, $('base').attr('href'));
|
||||
// Reload only edit form if it exists (side-by-side view of tree and edit view), otherwise reload whole panel
|
||||
if(container.find('.cms-edit-form').length) {
|
||||
url += '?cms-view-form=1';
|
||||
|
@ -144,7 +144,7 @@ jQuery.noConflict();
|
||||
// which matches one class on the menu
|
||||
window.History.pushState(data, title, url);
|
||||
} else {
|
||||
window.location = url;
|
||||
window.location = $.path.makeUrlAbsolute(url, $('base').attr('href'));
|
||||
}
|
||||
},
|
||||
|
||||
|
239
admin/javascript/lib.js
Normal file
239
admin/javascript/lib.js
Normal file
@ -0,0 +1,239 @@
|
||||
(function($) {
|
||||
|
||||
// Copyright (c) 2011 John Resig, http://jquery.com/
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
//define vars for interal use
|
||||
var $window = $( window ),
|
||||
$html = $( 'html' ),
|
||||
$head = $( 'head' ),
|
||||
|
||||
//url path helpers for use in relative url management
|
||||
path = {
|
||||
|
||||
// This scary looking regular expression parses an absolute URL or its relative
|
||||
// variants (protocol, site, document, query, and hash), into the various
|
||||
// components (protocol, host, path, query, fragment, etc that make up the
|
||||
// URL as well as some other commonly used sub-parts. When used with RegExp.exec()
|
||||
// or String.match, it parses the URL into a results array that looks like this:
|
||||
//
|
||||
// [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content
|
||||
// [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread
|
||||
// [2]: http://jblas:password@mycompany.com:8080/mail/inbox
|
||||
// [3]: http://jblas:password@mycompany.com:8080
|
||||
// [4]: http:
|
||||
// [5]: //
|
||||
// [6]: jblas:password@mycompany.com:8080
|
||||
// [7]: jblas:password
|
||||
// [8]: jblas
|
||||
// [9]: password
|
||||
// [10]: mycompany.com:8080
|
||||
// [11]: mycompany.com
|
||||
// [12]: 8080
|
||||
// [13]: /mail/inbox
|
||||
// [14]: /mail/
|
||||
// [15]: inbox
|
||||
// [16]: ?msg=1234&type=unread
|
||||
// [17]: #msg-content
|
||||
//
|
||||
urlParseRE: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
|
||||
|
||||
//Parse a URL into a structure that allows easy access to
|
||||
//all of the URL components by name.
|
||||
parseUrl: function( url ) {
|
||||
// If we're passed an object, we'll assume that it is
|
||||
// a parsed url object and just return it back to the caller.
|
||||
if ( $.type( url ) === "object" ) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var matches = path.urlParseRE.exec( url || "" ) || [];
|
||||
|
||||
// Create an object that allows the caller to access the sub-matches
|
||||
// by name. Note that IE returns an empty string instead of undefined,
|
||||
// like all other browsers do, so we normalize everything so its consistent
|
||||
// no matter what browser we're running on.
|
||||
return {
|
||||
href: matches[ 0 ] || "",
|
||||
hrefNoHash: matches[ 1 ] || "",
|
||||
hrefNoSearch: matches[ 2 ] || "",
|
||||
domain: matches[ 3 ] || "",
|
||||
protocol: matches[ 4 ] || "",
|
||||
doubleSlash: matches[ 5 ] || "",
|
||||
authority: matches[ 6 ] || "",
|
||||
username: matches[ 8 ] || "",
|
||||
password: matches[ 9 ] || "",
|
||||
host: matches[ 10 ] || "",
|
||||
hostname: matches[ 11 ] || "",
|
||||
port: matches[ 12 ] || "",
|
||||
pathname: matches[ 13 ] || "",
|
||||
directory: matches[ 14 ] || "",
|
||||
filename: matches[ 15 ] || "",
|
||||
search: matches[ 16 ] || "",
|
||||
hash: matches[ 17 ] || ""
|
||||
};
|
||||
},
|
||||
|
||||
//Turn relPath into an asbolute path. absPath is
|
||||
//an optional absolute path which describes what
|
||||
//relPath is relative to.
|
||||
makePathAbsolute: function( relPath, absPath ) {
|
||||
if ( relPath && relPath.charAt( 0 ) === "/" ) {
|
||||
return relPath;
|
||||
}
|
||||
|
||||
relPath = relPath || "";
|
||||
absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : "";
|
||||
|
||||
var absStack = absPath ? absPath.split( "/" ) : [],
|
||||
relStack = relPath.split( "/" );
|
||||
for ( var i = 0; i < relStack.length; i++ ) {
|
||||
var d = relStack[ i ];
|
||||
switch ( d ) {
|
||||
case ".":
|
||||
break;
|
||||
case "..":
|
||||
if ( absStack.length ) {
|
||||
absStack.pop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
absStack.push( d );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "/" + absStack.join( "/" );
|
||||
},
|
||||
|
||||
//Returns true if both urls have the same domain.
|
||||
isSameDomain: function( absUrl1, absUrl2 ) {
|
||||
return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain;
|
||||
},
|
||||
|
||||
//Returns true for any relative variant.
|
||||
isRelativeUrl: function( url ) {
|
||||
// All relative Url variants have one thing in common, no protocol.
|
||||
return path.parseUrl( url ).protocol === "";
|
||||
},
|
||||
|
||||
//Returns true for an absolute url.
|
||||
isAbsoluteUrl: function( url ) {
|
||||
return path.parseUrl( url ).protocol !== "";
|
||||
},
|
||||
|
||||
//Turn the specified realtive URL into an absolute one. This function
|
||||
//can handle all relative variants (protocol, site, document, query, fragment).
|
||||
makeUrlAbsolute: function( relUrl, absUrl ) {
|
||||
if ( !path.isRelativeUrl( relUrl ) ) {
|
||||
return relUrl;
|
||||
}
|
||||
|
||||
var relObj = path.parseUrl( relUrl ),
|
||||
absObj = path.parseUrl( absUrl ),
|
||||
protocol = relObj.protocol || absObj.protocol,
|
||||
doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ),
|
||||
authority = relObj.authority || absObj.authority,
|
||||
hasPath = relObj.pathname !== "",
|
||||
pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ),
|
||||
search = relObj.search || ( !hasPath && absObj.search ) || "",
|
||||
hash = relObj.hash;
|
||||
|
||||
return protocol + doubleSlash + authority + pathname + search + hash;
|
||||
},
|
||||
|
||||
//Add search (aka query) params to the specified url.
|
||||
addSearchParams: function( url, params ) {
|
||||
var u = path.parseUrl( url ),
|
||||
p = ( typeof params === "object" ) ? $.param( params ) : params,
|
||||
s = u.search || "?";
|
||||
return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" );
|
||||
},
|
||||
|
||||
convertUrlToDataUrl: function( absUrl ) {
|
||||
var u = path.parseUrl( absUrl );
|
||||
if ( path.isEmbeddedPage( u ) ) {
|
||||
// For embedded pages, remove the dialog hash key as in getFilePath(),
|
||||
// otherwise the Data Url won't match the id of the embedded Page.
|
||||
return u.hash.split( dialogHashKey )[0].replace( /^#/, "" );
|
||||
} else if ( path.isSameDomain( u, documentBase ) ) {
|
||||
return u.hrefNoHash.replace( documentBase.domain, "" );
|
||||
}
|
||||
return absUrl;
|
||||
},
|
||||
|
||||
//get path from current hash, or from a file path
|
||||
get: function( newPath ) {
|
||||
if( newPath === undefined ) {
|
||||
newPath = location.hash;
|
||||
}
|
||||
return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' );
|
||||
},
|
||||
|
||||
//return the substring of a filepath before the sub-page key, for making a server request
|
||||
getFilePath: function( path ) {
|
||||
var splitkey = '&' + $.mobile.subPageUrlKey;
|
||||
return path && path.split( splitkey )[0].split( dialogHashKey )[0];
|
||||
},
|
||||
|
||||
//set location hash to path
|
||||
set: function( path ) {
|
||||
location.hash = path;
|
||||
},
|
||||
|
||||
//test if a given url (string) is a path
|
||||
//NOTE might be exceptionally naive
|
||||
isPath: function( url ) {
|
||||
return ( /\// ).test( url );
|
||||
},
|
||||
|
||||
//return a url path with the window's location protocol/hostname/pathname removed
|
||||
clean: function( url ) {
|
||||
return url.replace( documentBase.domain, "" );
|
||||
},
|
||||
|
||||
//just return the url without an initial #
|
||||
stripHash: function( url ) {
|
||||
return url.replace( /^#/, "" );
|
||||
},
|
||||
|
||||
//remove the preceding hash, any query params, and dialog notations
|
||||
cleanHash: function( hash ) {
|
||||
return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) );
|
||||
},
|
||||
|
||||
//check whether a url is referencing the same domain, or an external domain or different protocol
|
||||
//could be mailto, etc
|
||||
isExternal: function( url ) {
|
||||
var u = path.parseUrl( url );
|
||||
return u.protocol && u.domain !== documentUrl.domain ? true : false;
|
||||
},
|
||||
|
||||
hasProtocol: function( url ) {
|
||||
return ( /^(:?\w+:)/ ).test( url );
|
||||
}
|
||||
};
|
||||
|
||||
$.path = path;
|
||||
|
||||
// Internal Helper
|
||||
$.expr[':'].internal = function(obj){return obj.href.match(/^mailto\:/) || (obj.hostname == location.hostname);};
|
||||
$.expr[':'].external = function(obj){return !$(obj).is(':internal')};
|
||||
}(jQuery));
|
Loading…
Reference in New Issue
Block a user