Bug 398117 - Comapre - Use URITemplate for compare.html parameters and remove dojo dependencies in glue code.
diff --git a/bundles/org.eclipse.orion.client.core/web/compare/compare.js b/bundles/org.eclipse.orion.client.core/web/compare/compare.js
index 7cefabe..35fba7c 100644
--- a/bundles/org.eclipse.orion.client.core/web/compare/compare.js
+++ b/bundles/org.eclipse.orion.client.core/web/compare/compare.js
@@ -11,78 +11,57 @@
 
 /*global define document */
 
-define(['dojo', 'orion/bootstrap', 'orion/status', 'orion/progress', 'orion/operationsClient', 'orion/commands', 'orion/fileClient', 'orion/searchClient', 'orion/globalCommands',
-		'orion/compare/compare-features', 'orion/compare/compare-container', 'orion/compare/compareUtils', 'orion/contentTypes', 'dojo/parser', 'dojo/hash', 'dijit/layout/BorderContainer', 'dijit/layout/ContentPane'],
-		function(dojo, mBootstrap, mStatus, mProgress, mOperationsClient, mCommands, mFileClient, mSearchClient, mGlobalCommands, mCompareFeatures, mCompareContainer, mCompareUtils, mContentTypes) {
-
-		dojo.addOnLoad(function(){
-			mBootstrap.startup().then(function(core) {
-				var serviceRegistry = core.serviceRegistry;
-				var preferences = core.preferences;
-				// we use internal border containers so we need dojo to parse.
-				dojo.parser.parse();
-				var commandService = new mCommands.CommandService({
-					serviceRegistry: serviceRegistry
-				});
-				// File operations
-				var fileClient = new mFileClient.FileClient(serviceRegistry);
-				var contentTypeService = new mContentTypes.ContentTypeService(serviceRegistry);
-				var searcher = new mSearchClient.Searcher({
-					serviceRegistry: serviceRegistry, commandService: commandService, fileService: fileClient
-				});
-				var operationsClient = new mOperationsClient.OperationsClient(serviceRegistry);
-				var statusService = new mStatus.StatusReportingService(serviceRegistry, operationsClient, "statusPane", "notifications", "notificationArea"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-				var progressService = new mProgress.ProgressService(serviceRegistry, operationsClient);
-
-				mGlobalCommands.generateBanner("orion-compare", serviceRegistry, commandService, preferences, searcher); //$NON-NLS-0$
-				var uiFactory = new mCompareFeatures.TwoWayCompareUIFactory({
-					parentDivID: "compareContainer", //$NON-NLS-0$
-					showTitle: true,
-					showLineStatus: true
-				});
-				uiFactory.buildUI();
-
-				// Diff operations
-				var readOnly = isReadOnly();
-				var conflciting = isConflciting();
-
-				var diffParams = mCompareUtils.parseCompareHash(dojo.hash());
-				var diffProvider = new mCompareContainer.DefaultDiffProvider(serviceRegistry);
-				var options = {
-					readonly: readOnly,
-					onPage: true,
-					generateLink: true,
-					commandSpanId: "pageNavigationActions", //$NON-NLS-0$
-					hasConflicts: conflciting,
-					diffProvider: diffProvider,
-					complexURL: diffParams.complexURL,
-					blockNumber: diffParams.block,
-					changeNumber: diffParams.change
-				};
-				
-				var twoWayCompareContainer = new mCompareContainer.TwoWayCompareContainer(serviceRegistry, "compareContainer", uiFactory, options); //$NON-NLS-0$
-				twoWayCompareContainer.startup();
-
-				// every time the user manually changes the hash, we need to load the diff.
-				dojo.subscribe("/dojo/hashchange", twoWayCompareContainer, function() { //$NON-NLS-0$
-					diffParams = mCompareUtils.parseCompareHash(dojo.hash());
-					options.complexURL = diffParams.complexURL;
-					options.block = diffParams.block;
-					options.change = diffParams.change;
-					twoWayCompareContainer = new mCompareContainer.TwoWayCompareContainer(serviceRegistry, "compareContainer", uiFactory, options); //$NON-NLS-0$
-					twoWayCompareContainer.startup();
-				});
-			});
-
-			function isReadOnly() {
-				var queryParams = dojo.queryToObject(window.location.search.slice(1));
-				return queryParams["readonly"] != null; //$NON-NLS-0$
-			}
-
-			function isConflciting() {
-				var queryParams = dojo.queryToObject(window.location.search.slice(1));
-				return queryParams["conflict"] != null; //$NON-NLS-0$
-			}
-
+define(['orion/bootstrap', 'orion/status', 'orion/progress', 'orion/operationsClient', 'orion/commands', 'orion/fileClient', 'orion/searchClient', 'orion/globalCommands',
+		'orion/compare/compare-features', 'orion/compare/compare-container', 'orion/compare/compareUtils', 'orion/contentTypes', 'orion/PageUtil'],
+		function(mBootstrap, mStatus, mProgress, mOperationsClient, mCommands, mFileClient, mSearchClient, mGlobalCommands, mCompareFeatures, mCompareContainer, mCompareUtils, mContentTypes, PageUtil) {
+	mBootstrap.startup().then(function(core) {
+		var serviceRegistry = core.serviceRegistry;
+		var preferences = core.preferences;
+		// we use internal border containers so we need dojo to parse.
+		//dojo.parser.parse();
+		var commandService = new mCommands.CommandService({
+			serviceRegistry: serviceRegistry
 		});
+		// File operations
+		var fileClient = new mFileClient.FileClient(serviceRegistry);
+		var contentTypeService = new mContentTypes.ContentTypeService(serviceRegistry);
+		var searcher = new mSearchClient.Searcher({
+			serviceRegistry: serviceRegistry, commandService: commandService, fileService: fileClient
+		});
+		var operationsClient = new mOperationsClient.OperationsClient(serviceRegistry);
+		var statusService = new mStatus.StatusReportingService(serviceRegistry, operationsClient, "statusPane", "notifications", "notificationArea"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+		var progressService = new mProgress.ProgressService(serviceRegistry, operationsClient);
+
+		mGlobalCommands.generateBanner("orion-compare", serviceRegistry, commandService, preferences, searcher); //$NON-NLS-0$
+		var uiFactory = new mCompareFeatures.TwoWayCompareUIFactory({
+			parentDivID: "compareContainer", //$NON-NLS-0$
+			showTitle: true,
+			showLineStatus: true
+		});
+		uiFactory.buildUI();
+		var diffProvider = new mCompareContainer.DefaultDiffProvider(serviceRegistry);
+		
+		var startWidget = function(){
+			var compareParams = PageUtil.matchResourceParameters();
+			var options = {
+				readonly: compareParams.readonly === "true", //$NON-NLS-0$
+				onPage: true,
+				generateLink: true,
+				commandSpanId: "pageNavigationActions", //$NON-NLS-0$
+				hasConflicts: compareParams.conflict === "true", //$NON-NLS-0$
+				diffProvider: diffProvider,
+				resource: compareParams.resource,
+				compareTo: compareParams.compareTo,
+				blockNumber: compareParams.block,
+				changeNumber: compareParams.change
+			};
+			var twoWayCompareContainer = new mCompareContainer.TwoWayCompareContainer(serviceRegistry, "compareContainer", uiFactory, options); //$NON-NLS-0$
+			twoWayCompareContainer.startup();
+		};
+		startWidget();
+		// every time the user manually changes the hash, we need to reastart the compare widget.
+		window.addEventListener("hashchange", function() { //$NON-NLS-0$
+			startWidget();
+		}, false);		
+	});
 });
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.js b/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.js
index 239e6eb..c045be8 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.js
@@ -25,18 +25,15 @@
 		this._diffProvider = new mDiffProvider.DiffProvider(serviceRegistry);
 	}	
 	DefaultDiffProvider.prototype = {
-		_resolveComplexDiff: function(complexURL, onlyDiff, errorCallback) {
-			var compareTwoIndex = complexURL.indexOf(","); //$NON-NLS-0$
-			if(compareTwoIndex > 0){
-				var fileLocNew = complexURL.substring(0, compareTwoIndex);
-				var fileLocBase = complexURL.substring(compareTwoIndex+1);
+		_resolveDiff: function(resource, compareTo, onlyDiff, errorCallback) {
+			if(compareTo){
 				var that = this;
-				var dl = new dojo.DeferredList([ that._getContentType(fileLocBase), that._getContentType(fileLocNew) ]);
+				var dl = new dojo.DeferredList([ that._getContentType(compareTo), that._getContentType(resource) ]);
 				dl.then(function(results) {
 					var baseFileContentType = results[0][1];
 					var newFileContentType = results[1][1];
-					that.callBack({ baseFile:{URL: fileLocBase, Name: that._resolveFileName(fileLocBase), Type: baseFileContentType},
-					 			newFile:{URL: fileLocNew, Name: that._resolveFileName(fileLocNew), Type: newFileContentType}
+					that.callBack({ baseFile:{URL: compareTo, Name: that._resolveFileName(compareTo), Type: baseFileContentType},
+					 			newFile:{URL: resource, Name: that._resolveFileName(resource), Type: newFileContentType}
 							 });
 				}, errorCallback);
 			} else {
@@ -45,7 +42,7 @@
 					return;
 				}
 				var that = this;
-				that._diffProvider.getDiffContent(complexURL).then(function(jsonData, secondArg) {
+				that._diffProvider.getDiffContent(resource).then(function(jsonData, secondArg) {
 					if (that._hasConflicts) {
 						that._diffContent = jsonData.split("diff --git")[1]; //$NON-NLS-0$
 					} else {
@@ -56,7 +53,7 @@
 				 			diff: that._diffContent
 						 });
 					} else {
-						that._resolveComplexFileURL(complexURL);
+						that._resolveComplexFileURL(resource);
 					}
 				}, errorCallback);
 			}
@@ -89,10 +86,10 @@
 			}, errorCallback);
 		},
 		
-		provide: function(complexURL, onlyDiff, hasConflicts,callBack, errorCallBack) {
+		provide: function(resource, compareTo, onlyDiff, hasConflicts,callBack, errorCallBack) {
 			this.callBack = callBack;
 			this._hasConflicts = hasConflicts;
-			this._resolveComplexDiff(complexURL, onlyDiff, errorCallBack);
+			this._resolveDiff(resource, compareTo, onlyDiff, errorCallBack);
 		}
 	};
 	return DefaultDiffProvider;
@@ -153,7 +150,8 @@
 				this.options.charDiff = (options.charDiff !== undefined &&  options.charDiff !== null) ? options.charDiff : this.options.charDiff;
 				this.options.hasConflicts = (options.hasConflicts !== undefined &&  options.hasConflicts !== null) ? options.hasConflicts : this.options.hasConflicts;
 				this.options.diffProvider = options.diffProvider ? options.diffProvider : this.options.diffProvider;
-				this.options.complexURL = options.complexURL ?  options.complexURL : this.options.complexURL;
+				this.options.resource = options.resource ?  options.resource : this.options.resource;
+				this.options.compareTo = options.compareTo ?  options.compareTo : this.options.compareTo;
 				
 				this.options.baseFile.URL = (options.baseFile && options.baseFile.URL) ? options.baseFile.URL : this.options.baseFile.URL;
 				this.options.baseFile.Name = (options.baseFile && typeof(options.baseFile.Name) === "string") ? options.baseFile.Name : this.options.baseFile.Name; //$NON-NLS-0$
@@ -225,7 +223,7 @@
 				id: "orion.compare.generateLink", //$NON-NLS-0$
 				groupId: "orion.compareGroup", //$NON-NLS-0$
 				visibleWhen: function(item) {
-					return item.options.complexURL && item.options.generateLink;
+					return item.options.resource && item.options.generateLink;
 				},
 				callback : function(data) {
 					data.items.generateLink();
@@ -237,7 +235,7 @@
 				id: "orion.compare.openComparePage", //$NON-NLS-0$
 				groupId: "orion.compareGroup", //$NON-NLS-0$
 				visibleWhen: function(item) {
-					return item.options.complexURL && !item.options.generateLink;
+					return item.options.resource && !item.options.generateLink;
 				},
 				hrefCallback: function(data) {
 					return data.items.openComparePage();
@@ -341,7 +339,8 @@
 		
 		generateLink: function(){	
 			var diffPos = this.getCurrentDiffPos();
-			var href = mCompareUtils.generateCompareHref(this.options.complexURL, {
+			var href = mCompareUtils.generateCompareHref(this.options.resource, {
+				compareTo: this.options.compareTo,
 				readonly: this.options.readonly,
 				conflict: this.options.hasConflicts,
 				block: diffPos.block ? diffPos.block : 1, 
@@ -352,7 +351,8 @@
 		
 		openComparePage: function(){	
 			var diffPos = this.getCurrentDiffPos();
-			var href = mCompareUtils.generateCompareHref(this.options.complexURL, {
+			var href = mCompareUtils.generateCompareHref(this.options.resource, {
+				compareTo: this.options.compareTo,
 				readonly: !this.options.editableInComparePage,
 				conflict: this.options.hasConflicts,
 				block: diffPos.block ? diffPos.block : 1, 
@@ -395,13 +395,13 @@
 			return delim;
 		},
 
-		resolveComplexDiff: function(onsave) {
+		resolveDiff: function(onsave) {
 			if(!this.options.diffProvider){
 				console.log("A diff provider is needed for Complex diff URL"); //$NON-NLS-0$
 				return;
 			}
 			var that = this;
-			that.options.diffProvider.provide(that.options.complexURL, onsave, that.options.hasConflicts, function(diffParam){
+			that.options.diffProvider.provide(that.options.resource, that.options.compareTo, onsave, that.options.hasConflicts, function(diffParam){
 				that.options.baseFile.URL = (diffParam.baseFile && typeof(diffParam.baseFile.URL) === "string") ? diffParam.baseFile.URL : that.options.baseFile.URL; //$NON-NLS-0$
 				that.options.baseFile.Name = (diffParam.baseFile && typeof(diffParam.baseFile.Name) === "string") ? diffParam.baseFile.Name : that.options.baseFile.Name; //$NON-NLS-0$
 				that.options.baseFile.Type = (diffParam.baseFile && typeof(diffParam.baseFile.Type) === "object") ? diffParam.baseFile.Type : that.options.baseFile.Type; //$NON-NLS-0$
@@ -498,8 +498,8 @@
 		
 		startup: function(onsave, onLoadContents){
 			this._onLoadContents = onLoadContents;
-			if(this.options.complexURL){
-				this.resolveComplexDiff(onsave);
+			if(this.options.resource){
+				this.resolveDiff(onsave);
 			} else if(!this.resolveDiffByContents(onsave)){
 				//resolve from mapper
 			}
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/compare/compareTreeExplorer.js b/bundles/org.eclipse.orion.client.core/web/orion/compare/compareTreeExplorer.js
index 6b8f1e8..e2e1a8e 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/compare/compareTreeExplorer.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/compare/compareTreeExplorer.js
@@ -79,7 +79,7 @@
 						dojo.addClass(diffStatusIcon, "imageSprite"); //$NON-NLS-0$
 						dojo.addClass(diffStatusIcon, "core-sprite-file"); //$NON-NLS-0$
 						displayName = item.name;
-						linkRef = mCompareUtils.generateCompareHref(item.fileURL + "," + item.fileURLBase, {readonly: true});
+						linkRef = mCompareUtils.generateCompareHref(item.fileURL, {compareTo: item.fileURLBase, readonly: true});
 						break;
 				}
 			}
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/compare/compareUtils.js b/bundles/org.eclipse.orion.client.core/web/orion/compare/compareUtils.js
index 49f9fc3..b9ebe81 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/compare/compareUtils.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/compare/compareUtils.js
@@ -11,7 +11,7 @@
  *******************************************************************************/
 /*global define require orion window document console */
 
-define([], function() {
+define(['orion/URITemplate'], function(URITemplate) {
 
 var orion = orion || {};
 
@@ -177,7 +177,7 @@
 	return mapper[mapperIndex][3] === 1;
 };
 
-orion.compareUtils.mergeDiffBlocks = function(oldTextModel, newDiffBlocks, mapper, diffArray, diffArraySubstrIndex, lineDelim){
+orion.compareUtils.mergeDiffBlocks = function(oldTextModel, newDiffBlocks, mapper, diffArray, diffArraySubstrIndex, lineDelim){//test
 	for(var i = 0; i < newDiffBlocks.length; i++){
 		var startLineIndex = newDiffBlocks[i][0];
 		var mapperIndex = newDiffBlocks[i][1];
@@ -200,51 +200,17 @@
 
 orion.compareUtils.generateCompareHref = function(diffLocation, options) {
 	var base =  require.toUrl("compare/compare.html"); //$NON-NLS-0$
-	var compareParam = "";
-	var diffPosition = "";
-	if(options){
-		if(options.readonly){
-			compareParam = "?readonly"; //$NON-NLS-0$
-		}
-		if(options.conflict){
-			if(compareParam === ""){
-				compareParam = "?conflict"; //$NON-NLS-0$
-			} else {
-				compareParam = compareParam + "&conflict"; //$NON-NLS-0$
-			}
-		}
-		if(options.block && options.block > 0){
-			diffPosition = ",block=" + options.block; //$NON-NLS-0$
-			if(options.change && options.change > 0){
-				diffPosition = diffPosition + "&change="+ options.change; //$NON-NLS-0$
-			}
-		}
+	if(!options.conflict){
+		options.conflict = undefined;
 	}
-	var tempLink = document.createElement("a"); //$NON-NLS-0$
-	tempLink.href = base + compareParam + "#" + diffLocation + diffPosition; //$NON-NLS-0$
-	return tempLink.href;
+	if(!options.readonly){
+		options.readonly = undefined;
+	}
+	var href = new URITemplate(base + "#{,resource,params*}").expand({ //$NON-NLS-0$
+		resource: diffLocation,
+		params: options
+	});
+	return href;
 };
-
-orion.compareUtils.parseCompareHash = function(hash) {
-	var diffObj = {complexURL: hash};
-	var diffPosIndex = hash.indexOf(",block="); //$NON-NLS-0$
-	if(diffPosIndex > 0){
-		diffObj.complexURL = hash.substring(0, diffPosIndex);
-		var diffPosStr = hash.substring(diffPosIndex+1);
-		var splitDiffPosStr = diffPosStr.split("&"); //$NON-NLS-0$
-		for(var i=0; i < splitDiffPosStr.length; i++){
-			var splitParams = splitDiffPosStr[i].split("="); //$NON-NLS-0$
-			if(splitParams.length === 2){
-				if(splitParams[0] === "block"){ //$NON-NLS-0$
-					diffObj.block = parseInt(splitParams[1]);
-				} else if(splitParams[0] === "change"){ //$NON-NLS-0$
-					diffObj.change = parseInt(splitParams[1]);
-				} 
-			}
-		}
-	} 
-	return diffObj;
-};
-
 return orion.compareUtils;
 });
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/fileCommands.js b/bundles/org.eclipse.orion.client.core/web/orion/fileCommands.js
index 3a5d386..e082529 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/fileCommands.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/fileCommands.js
@@ -494,7 +494,7 @@
 					if(data.items[0].Directory && data.items[1].Directory){
 						return require.toUrl("compare-tree/compare-tree.html#") + data.items[0].Location + "," + data.items[1].Location; //$NON-NLS-1$ //$NON-NLS-0$
 					}
-					return mCompareUtils.generateCompareHref(data.items[0].Location + "," + data.items[1].Location, {readonly: true}); //$NON-NLS-0$
+					return mCompareUtils.generateCompareHref(data.items[0].Location, {compareTo: data.items[1].Location, readonly: true}); //$NON-NLS-0$
 				}
 			});
 		commandService.addCommand(compareWithEachOtherCommand);
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommitExplorer.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommitExplorer.js
index 45a9687..96aee12 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommitExplorer.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommitExplorer.js
@@ -392,7 +392,7 @@
 									diffProvider: diffProvider,

 									hasConflicts: false,

 									readonly: true,

-									complexURL: item.parent.DiffLocation,

+									resource: item.parent.DiffLocation,

 									callback : function(){}

 								};

 								

diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitStatusExplorer.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitStatusExplorer.js
index e056fbc..723a164 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitStatusExplorer.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitStatusExplorer.js
@@ -433,7 +433,7 @@
 									hasConflicts: hasConflict,

 									readonly: true,

 									editableInComparePage: true,

-									complexURL: item.diffUri,

+									resource: item.diffUri,

 									callback : function(){}

 								};

 								

@@ -631,7 +631,7 @@
 									diffProvider: diffProvider,

 									hasConflicts: hasConflict,

 									readonly: true,

-									complexURL: item.diffUri,

+									resource: item.diffUri,

 									callback : function(){}

 								};