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/jquery.js',
|
||||||
THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js',
|
THIRDPARTY_DIR . '/jquery-livequery/jquery.livequery.js',
|
||||||
SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js',
|
SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js',
|
||||||
|
SAPPHIRE_DIR . '/admin/javascript/lib.js',
|
||||||
THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js',
|
THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js',
|
||||||
THIRDPARTY_DIR . '/json-js/json2.js',
|
THIRDPARTY_DIR . '/json-js/json2.js',
|
||||||
THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js',
|
THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js',
|
||||||
|
@ -271,7 +271,8 @@
|
|||||||
|
|
||||||
var url = $(node).find('a:first').attr('href');
|
var url = $(node).find('a:first').attr('href');
|
||||||
if(url && url != '#') {
|
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
|
// 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) {
|
if(container.find('.cms-edit-form').length) {
|
||||||
url += '?cms-view-form=1';
|
url += '?cms-view-form=1';
|
||||||
|
@ -144,7 +144,7 @@ jQuery.noConflict();
|
|||||||
// which matches one class on the menu
|
// which matches one class on the menu
|
||||||
window.History.pushState(data, title, url);
|
window.History.pushState(data, title, url);
|
||||||
} else {
|
} 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