Bug 438076 - Replace Global Search Page (search.html) with Inline Search in Edit Page (edit.html)
- Committing changes to backup work in progress
-
diff --git a/bundles/org.eclipse.orion.client.ui/web/css/controls.css b/bundles/org.eclipse.orion.client.ui/web/css/controls.css
index 14b799b..2d57c71 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/controls.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/controls.css
@@ -1214,3 +1214,7 @@
 	font-size: 12px;

 	color: #222;

 }

+

+.fileExplorerProgressDiv {

+	margin-left: 10px;	

+}

diff --git a/bundles/org.eclipse.orion.client.ui/web/css/layout.css b/bundles/org.eclipse.orion.client.ui/web/css/layout.css
index be28a5f..21a659b 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/layout.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/layout.css
@@ -306,11 +306,15 @@
 .sidebarWrapper > .sidebar {

 	position: relative;

 	left: 0;

-	top: 5px;

-	height: calc(100% - 70px);

+	top: 0;

+	height: calc(100% - 38px);

 	overflow-x: visible;

 }

 

+.projectNavSidebarWrapper > .sidebar {

+	height: calc(100% - 4px);

+}

+

 .workingTarget {

 	position: absolute;

 	top: 2px;  /* $ToolbarHeight + 2 */

diff --git a/bundles/org.eclipse.orion.client.ui/web/css/theme.css b/bundles/org.eclipse.orion.client.ui/web/css/theme.css
index 016f01e..9cbe501 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/theme.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/theme.css
@@ -206,7 +206,7 @@
 

 .filesystemSwitcherWrapper {

 	display: inline-block;

-	max-width: calc(100% - 50px);

+	max-width: 100%;

 	white-space: nowrap;

 }

 

diff --git a/bundles/org.eclipse.orion.client.ui/web/edit/edit.html b/bundles/org.eclipse.orion.client.ui/web/edit/edit.html
index 109e12a..c5f7550 100644
--- a/bundles/org.eclipse.orion.client.ui/web/edit/edit.html
+++ b/bundles/org.eclipse.orion.client.ui/web/edit/edit.html
@@ -40,6 +40,7 @@
 				<div id="rightPane" class="mainpane mainPanelLayout hasSplit">
 					<div class="fixedToolbarHolder">
 						<div id="editor" class="workingTarget"></div>
+						<div id="replaceCompareDiv" class="replaceCompareDiv workingTarget"></div>
 					</div>
 				</div>
 			</div>
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareView.js b/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareView.js
index 7a3c790..7fe1aeb 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareView.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareView.js
@@ -764,6 +764,12 @@
 		this._conflcit = conflicting;
 	};
 	
+	InlineCompareView.prototype.gotoDiff = function(lineNumber, offsetInTheLine){
+		//TODO find out why this isn't working...
+		var offset = this._textView.getModel().getLineStart(lineNumber) + offsetInTheLine;
+		this._diffNavigator.gotoDiff(offset, this._textView);
+	};
+	
 	return InlineCompareView;
 }());
 
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer-table.js b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer-table.js
index e68793f..6d0e6c2 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer-table.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer-table.js
@@ -1056,6 +1056,7 @@
 			if(!progress){
 				progress = document.createElement("div"); //$NON-NLS-0$
 				progress.id = "progress"; //$NON-NLS-0$
+				progress.classList.add("fileExplorerProgressDiv"); //$NON-NLS-0$
 				lib.empty(parent);
 				parent.appendChild(progress);
 			}
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/inlineSearchResultExplorer.js b/bundles/org.eclipse.orion.client.ui/web/orion/inlineSearchResultExplorer.js
index 7ac2e31..69a321c 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/inlineSearchResultExplorer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/inlineSearchResultExplorer.js
@@ -142,16 +142,7 @@
     };
 
     SearchResultRenderer.prototype.getCellHeaderElement = function(col_no) {
-        var title = null;
-        if (col_no === 0) {
-        	title = _createElement("th"); //$NON-NLS-0$
-        } else if (col_no === 1) {
-            title = _createElement("th"); //$NON-NLS-0$
-            var h2 = _createElement("h2", "search_header", null, title); //$NON-NLS-1$  //$NON-NLS-0$
-            h2.textContent = _headerString(this.explorer.model);
-        }
-        
-        return title;
+        return null;
     };
 
     SearchResultRenderer.prototype.focus = function() {
@@ -215,11 +206,31 @@
         }
 		var params = helper ? mSearchUtils.generateFindURLBinding(helper.params, helper.inFileQuery, null, helper.params.replace, true) : null;
 		var name = this.explorer.model._filterText ? null : renderName;
-		var link = navigatorRenderer.createLink(null, {Location: item.location, Name: name}, this.explorer._commandService, this.explorer._contentTypeService,
-			this.explorer._openWithCommands, {id:this.getItemLinkId(item)}, params, {holderDom: this._lastFileIconDom});
+		var link = null;
+		var folders = item.fullPathName.split("/");
+		var parentFolder = folders[folders.length - 1];
+		var parentSpan = document.createElement("span"); //$NON-NLS-0$
+		parentSpan.classList.add("fileParentSpan"); //$NON-NLS-0$
+		parentSpan.appendChild(document.createTextNode(parentFolder + "/")); //$NON-NLS-0$
+		
+		if (this.explorer.model.replaceMode()) {
+			link = document.createTextNode(renderName);
+			spanHolder.classList.add("replaceFileNameSpan"); //$NON-NLS-0$
+			spanHolder.appendChild(parentSpan);
+		} else {
+			link = navigatorRenderer.createLink(null, 
+					{Location: item.location, Name: name}, 
+					this.explorer._commandService, 
+					this.explorer._contentTypeService,
+					this.explorer._openWithCommands, 
+					{id:this.getItemLinkId(item)}, 
+					params, 
+					{holderDom: this._lastFileIconDom});
+			mNavUtils.addNavGrid(this.explorer.getNavDict(), item, link);
+			link.insertBefore(parentSpan, link.firstChild);
+		}
         spanHolder.appendChild(link);
         spanHolder.classList.add("fileNameSpan"); //$NON-NLS-0$
-        mNavUtils.addNavGrid(this.explorer.getNavDict(), item, link);
     };
 
     SearchResultRenderer.prototype.generateContextTip = function(detailModel) {
@@ -386,15 +397,6 @@
         return this.explorer.model.getId(item) + "_detailIcon"; //$NON-NLS-0$
     };
 
-    SearchResultRenderer.prototype.renderLocationElement = function(item, onSpan) {
-        var spanHolder = onSpan ? onSpan : lib.node(this.getLocationSpanId(item));
-        _empty(spanHolder);
-        var scopeParams = this.explorer.model.getScopingParams(item);
-        
-        spanHolder.appendChild(document.createTextNode("[" + scopeParams.name + "]"));
-        spanHolder.classList.add("fileLocationSpan"); //$NON-NLS-0$
-    };
-
     SearchResultRenderer.prototype.getPrimColumnStyle = function(item) {
         if(item && item.type === "file") { //$NON-NLS-0$
         	return "search_primaryColumn"; //$NON-NLS-0$
@@ -437,11 +439,23 @@
                     //render file location
                     span = _createSpan(null, this.getLocationSpanId(item), col, null);
                     if (item.parentLocation) {
-                        this.renderLocationElement(item, span);
+						var scopeParams = this.explorer.model.getScopingParams(item);
+						tableRow.title = scopeParams.name;
                     }
+                } else {
+					this.renderDetailLineNumber(item, span);
+                    span.classList.add("searchDetailLineNumber"); //$NON-NLS-0$
+                    
+                    this.renderDetailElement(item, col);
+                }
+                break;
+			case 20: //TODO fix look and feel, re-enable
+				if (item.type === "file") { //$NON-NLS-0$
+					col = _createElement('td'); //$NON-NLS-0$
                     var button = _createElement("button", ["imageSprite", "core-sprite-delete", "dismissButton", "deleteSearchRowButton"], null, col); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 					button.title = messages["Remove from search results"]; //$NON-NLS-0$
                     button.addEventListener("click", function(){ //$NON-NLS-0$
+                    //TODO fix behavior in replace preview mode
                     	var model = this.explorer.model;
                     	model.removeChild(item.parent, item);
                     	this.explorer.getNavHandler().refreshModel(this.explorer.getNavDict(), model, model.children);
@@ -456,14 +470,9 @@
             			}
             			
             			//TODO update match count, maybe...
-                    }.bind(this));                    
-                } else {
-					this.renderDetailLineNumber(item, span);
-                    span.classList.add("searchDetailLineNumber"); //$NON-NLS-0$
-                    
-                    this.renderDetailElement(item, col);
+                    }.bind(this));
                 }
-                break;
+				break;
         }
         
         return col;
@@ -584,12 +593,13 @@
      * Creates a new search result explorer.
      * @name orion.InlineSearchResultExplorer
      */
-    function InlineSearchResultExplorer(registry, commandService) {
+    function InlineSearchResultExplorer(registry, commandService, inlineSearchPane) {
         this.registry = registry;
         this._commandService = commandService;
         this.fileClient = new mFileClient.FileClient(this.registry);
         this.defaulRows = 40;
 		this._contentTypeService = new mContentTypes.ContentTypeRegistry(this.registry);
+		this._inlineSearchPane = inlineSearchPane;
         this.declareCommands();
     }
 
@@ -627,15 +637,13 @@
         }
 
         this._reporting = false;
-        this._uiFactory = null;
         this._currentPreviewModel = null;
         this._currentReplacedContents = {
             contents: null
         };
         this._popUpContext = false;
-        this.timerRunning -= false;
         this._timer = null;
-        this.twoWayCompareView = null;
+        this.compareView = null;
     };
 
     /* one-time setup of commands */
@@ -653,46 +661,51 @@
                 return that.model && that.model.replaceMode() && !that._reporting && that._hasCheckedItems;
             }
         });
-
-        var hideCompareCommand = new mCommands.Command({
-            name: messages["Hide Compare"],
-            tooltip: messages["Hide compare view of changes"],
-            id: "orion.globalSearch.hideCompare", //$NON-NLS-0$
-            callback: function(data) {
-                that.toggleCompare(false);
-            },
-            visibleWhen: function(item) {
-                return that.model && that.model.replaceMode() && !that._reporting && that._uiFactory;
-            }
-        });
-
-        var showCompareCommand = new mCommands.Command({
-            name: messages["Show Compare"],
-            tooltip: messages["Show compare view of changes"],
-            id: "orion.globalSearch.showCompare", //$NON-NLS-0$
-            callback: function(data) {
-                that.toggleCompare(true);
-            },
-            visibleWhen: function(item) {
-                return that.model && that.model.replaceMode() && !that._reporting && !that._uiFactory;
-            }
-        });
-
-        this._commandService.addCommand(hideCompareCommand);
-        this._commandService.addCommand(showCompareCommand);
-        this._commandService.addCommand(replaceAllCommand);
-        this._commandService.addCommandGroup("pageActions", "orion.searchActions.unlabeled", 200); //$NON-NLS-1$ //$NON-NLS-0$
-        this._commandService.registerCommandContribution("pageActions", "orion.globalSearch.hideCompare", 1, "orion.searchActions.unlabeled"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-        this._commandService.registerCommandContribution("pageActions", "orion.globalSearch.showCompare", 2, "orion.searchActions.unlabeled"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-        this._commandService.registerCommandContribution("pageActions", "orion.globalSearch.replaceAll", 3, "orion.searchActions.unlabeled"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
         
-        mExplorer.createExplorerCommands(this._commandService, function(item) {
+        var nextResultCommand = new mCommands.Command({
+            tooltip: messages["Next result"],
+            imageClass: "core-sprite-move-down", //$NON-NLS-0$
+            id: "orion.search.nextResult", //$NON-NLS-0$
+            groupId: "orion.searchGroup", //$NON-NLS-0$
+            visibleWhen: function(item) {
+                return !that._reporting && (that.getItemCount() > 0);
+            },
+            callback: function() {
+                that.gotoNext(true, true);
+            }
+        });
+        var prevResultCommand = new mCommands.Command({
+            tooltip: messages["Previous result"],
+            imageClass: "core-sprite-move-up", //$NON-NLS-0$
+            id: "orion.search.prevResult", //$NON-NLS-0$
+            groupId: "orion.searchGroup", //$NON-NLS-0$
+            visibleWhen: function(item) {
+                return !that._reporting && (that.getItemCount() > 0);
+            },
+            callback: function() {
+                that.gotoNext(false, true);
+            }
+        });
+        this._commandService.addCommand(nextResultCommand);
+        this._commandService.addCommand(prevResultCommand);
+
+        this._commandService.addCommand(replaceAllCommand);
+        this._commandService.addCommandGroup("searchPageActions", "orion.searchActions.unlabeled", 200); //$NON-NLS-1$ //$NON-NLS-0$
+        
+         mExplorer.createExplorerCommands(this._commandService, function(item) {
 			var emptyKeyword = false;
 			if(that.model._provideSearchHelper && that.model._provideSearchHelper().params.keyword === ""){
 				emptyKeyword = true;
 			}
 			return !item._reporting && !emptyKeyword;
         });
+        
+        this._commandService.registerCommandContribution("searchPageActions", "orion.globalSearch.replaceAll", 1); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+        
+        this._commandService.registerCommandContribution("searchPageActions", "orion.explorer.expandAll", 2); //$NON-NLS-1$ //$NON-NLS-0$
+        this._commandService.registerCommandContribution("searchPageActions", "orion.explorer.collapseAll", 3); //$NON-NLS-1$ //$NON-NLS-0$
+        this._commandService.registerCommandContribution("searchPageActions", "orion.search.nextResult", 4); //$NON-NLS-1$ //$NON-NLS-0$
+        this._commandService.registerCommandContribution("searchPageActions", "orion.search.prevResult", 5); //$NON-NLS-1$ //$NON-NLS-0$
     };
 
     InlineSearchResultExplorer.prototype._checkStale = function(model) {
@@ -746,19 +759,19 @@
 
     InlineSearchResultExplorer.prototype.preview = function() {
         var that = this;
-        this._commandService.openParameterCollector("pageActions", function(parentDiv) { //$NON-NLS-0$
+        this._commandService.openParameterCollector("searchPageActions", function(parentDiv) { //$NON-NLS-0$
             // create replace text
             var replaceStringDiv = _createElement('input', null, "globalSearchReplaceWith", parentDiv); //$NON-NLS-1$  //$NON-NLS-0$
             replaceStringDiv.type = "text"; //$NON-NLS-0$
             replaceStringDiv.name = "ReplaceWith:"; //$NON-NLS-0$
             replaceStringDiv.placeholder = "Replace With"; //$NON-NLS-0$
             replaceStringDiv.onkeydown = function(e) {
-                if (e.keyCode === 13 /*Enter*/ ) {
+                if (e.keyCode === lib.KEY.ENTER) {
                     var replaceInputDiv = lib.node("globalSearchReplaceWith"); //$NON-NLS-0$
                     that._commandService.closeParameterCollector();
                     return that._doPreview(replaceInputDiv.value);
                 }
-                if (e.keyCode === 27 /*ESC*/ ) {
+                if (e.keyCode === lib.KEY.ESCAPE) {
                     that._commandService.closeParameterCollector();
                     return false;
                 }
@@ -859,18 +872,16 @@
     InlineSearchResultExplorer.prototype.replacePreview = function(init, comparing) {
         _empty(this.getParentDivId());
         if (comparing) {
-            this._uiFactory = new mSearchFeatures.SearchUIFactory({
-                parentDivID: this.getParentDivId()
-            });
-            this._uiFactory.buildUI();
-            this.twoWayCompareView = null;
+            if (this.compareView) {
+            	this.compareView.destroy();
+            	this.compareView = null;
+            }
             this._currentPreviewModel = null;
         } else {
-            if (this._uiFactory) {
-                this._uiFactory.destroy();
+            if (this.compareView) {
+            	this.compareView.destroy();
+            	this.compareView = null;
             }
-            this._uiFactory = null;
-            this.twoWayCompareView = null;
             this._currentPreviewModel = null;
         }
         this.initCommands();
@@ -878,7 +889,7 @@
             this.reportStatus(messages["Preparing preview..."]);
         }
         var that = this;
-        this.createTree(this._uiFactory ? this._uiFactory.getMatchDivID() : this.getParentDivId(), this.model, {
+		this.createTree(this.getParentDivId(), this.model, {
             selectionPolicy: "singleSelection", //$NON-NLS-0$
             indent: 0,
             setFocus: false,
@@ -971,36 +982,31 @@
     };
 
     InlineSearchResultExplorer.prototype.buildPreview = function(updating) {
-        if (!this._uiFactory) {
-            return;
-        }
         if (_validFiles(this.model).length === 0) {
             return;
         }
-        var uiFactory = this._uiFactory;
         var fileItem = _getFileModel(this.getNavHandler().currentModel());
         this._currentPreviewModel = fileItem;
         var that = this;
         this.model.provideFileContent(fileItem, function(fileItem) {
-            if (that.model.onMatchNumberChanged) {
-                that.model.onMatchNumberChanged(fileItem);
+            if (this.model.onMatchNumberChanged) {
+                this.model.onMatchNumberChanged(fileItem);
             }
-			that.model.getReplacedFileContent(that._currentReplacedContents, updating, fileItem);
-			var replacedContents = that._currentReplacedContents.contents;
+			this.model.getReplacedFileContent(this._currentReplacedContents, updating, fileItem);
+			var replacedContents = this._currentReplacedContents.contents;
 			if(Array.isArray(replacedContents)){
-				replacedContents = that._currentReplacedContents.contents.join(that._currentReplacedContents.lineDelim);
+				replacedContents = this._currentReplacedContents.contents.join(this._currentReplacedContents.lineDelim);
 			}
             // Diff operations
-            var fileName = that.model.getFileName(fileItem);
-            var fType = that._contentTypeService.getFilenameContentType(fileName);
+            var fileName = this.model.getFileName(fileItem);
+            var fType = this._contentTypeService.getFilenameContentType(fileName);
             var options = {
                 readonly: true,
                 hasConflicts: false,
-                newFileOnRight: true,
                 oldFile: {
                     Name: fileItem.location,
                     Type: fType,
-                    Content: that.model.getFileContents(fileItem)
+                    Content: this.model.getFileContents(fileItem)
                 },
                 newFile: {
                     Name: fileItem.location,
@@ -1008,33 +1014,19 @@
                     Content: replacedContents
                 }
             };
-            if (!that.twoWayCompareView) {
-                that.uiFactoryCompare = new mCompareUIFactory.TwoWayCompareUIFactory({
-                    parentDivID: uiFactory.getCompareDivID(),
-                    showTitle: true,
-                    rightTitle: i18nUtil.formatMessage(messages["Replaced File (${0})"], fileName),
-                    leftTitle: i18nUtil.formatMessage(messages["Original File (${0})"], fileName),
-                    showLineStatus: false
-                });
-                that.uiFactoryCompare.buildUI();
-                options.uiFactory = that.uiFactoryCompare;
-                options.parentDivID =  uiFactory.getCompareDivID();
-                that.twoWayCompareView = new mCompareView.TwoWayCompareView(options);
-				that.twoWayCompareView.setOptions({highlighters: [new CompareStyler(that.registry), new CompareStyler(that.registry)]});
-                that.twoWayCompareView.startup();
-                that._uiFactory.setCompareWidget(that.twoWayCompareView);
+            if (!this.compareView) {           	
+				options.parentDivId = this._replaceCompareNode;
+                this.compareView = new mCompareView.InlineCompareView(options);
+                this.compareView.setOptions({highlighters: [new CompareStyler(this.registry)]});
+                this.compareView.startup();
             } else {
-                that.twoWayCompareView.setOptions(options);
-                that.twoWayCompareView.refresh(true);
+                this.compareView.setOptions(options);
+                this.compareView.refresh(true);
             }
-             _empty(that.uiFactoryCompare.getTitleDiv());
-            _place(document.createTextNode(i18nUtil.formatMessage(messages['Replaced File (${0})'], fileName)), that.uiFactoryCompare.getTitleDiv(), "only"); //$NON-NLS-1$ //$NON-NLS-0$
-            _empty(that.uiFactoryCompare.getTitleDiv(true));
-            _place(document.createTextNode(i18nUtil.formatMessage(messages['Original File (${0})'], fileName)), that.uiFactoryCompare.getTitleDiv(true), "only"); //$NON-NLS-1$ //$NON-NLS-0$
            window.setTimeout(function() {
-                that.renderer.focus();
-            }, 100);
-        });
+                this.renderer.focus();
+            }.bind(this), 100);
+        }.bind(this));
     };
     
     InlineSearchResultExplorer.prototype.caculateNextPage = function() {
@@ -1062,8 +1054,8 @@
 
     InlineSearchResultExplorer.prototype.initCommands = function() {
         var that = this;
-        this._commandService.destroy("pageActions"); //$NON-NLS-0$
-        this._commandService.renderCommands("pageActions", "pageActions", that, that, "button"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+        this._commandService.destroy("searchPageActions"); //$NON-NLS-0$
+        this._commandService.renderCommands("searchPageActions", "searchPageActions", that, that, "button"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 
         this._commandService.destroy("pageNavigationActions"); //$NON-NLS-0$
         this._commandService.renderCommands("pageNavigationActions", "pageNavigationActions", that, that, "button"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
@@ -1196,9 +1188,9 @@
         if (!_onSameFile(this._currentPreviewModel, currentModel)) {
             this.buildPreview();
         }
-        if (currentModel.type === "detail") { //$NON-NLS-0$
+        if (this.compareView && (currentModel.type === "detail")) { //$NON-NLS-0$
 		    var detailInfo = this.model.getDetailInfo(currentModel);
-            this.twoWayCompareView.gotoDiff(detailInfo.lineNumber, detailInfo.matches[detailInfo.matchNumber].startIndex, false);
+			this.compareView.gotoDiff(detailInfo.lineNumber, detailInfo.matches[detailInfo.matchNumber].startIndex);
         }
     };
 
@@ -1207,25 +1199,14 @@
         if (this.model.storeLocationStatus) {
             this.model.storeLocationStatus(currentModel);
         }
-        var that = this;
         if (this.model.replaceMode()) {
-            if (!this._uiFactory) {
-                return;
-            }
-            if (!this._timer) {
-                this._timer = window.setTimeout(function() {
-                    that.onReplaceCursorChanged(prevModel, currentModel);
-                    that.timerRunning = false;
-                    that._timer = null;
-                }, 500);
-            } else if (this.timerRunning) {
-                window.clearTimeOut(this._timer);
-                this._timer = window.setTimeout(function() {
-                    that.onReplaceCursorChanged(prevModel, currentModel);
-                    that.timerRunning = false;
-                    that._timer = null;
-                }, 500);
-            }
+			if (this._timer) {
+				window.clearTimeout(this._timer);
+			}			
+            this._timer = window.setTimeout(function() {
+            	this._timer = null;
+                this.onReplaceCursorChanged(prevModel, currentModel);
+            }.bind(this), 200);
         } else if (currentModel.type === "detail") { //$NON-NLS-0$
             if (this._popUpContext) {
                 this.popupContext(currentModel);
@@ -1348,15 +1329,15 @@
 
     //provide to the expandAll/collapseAll commands
     InlineSearchResultExplorer.prototype.getItemCount = function() {
-        return this.model.getListRoot().children.length;
+    	var count = 0;
+    	if (this.model) {
+    		count = this.model.getListRoot().children.length;
+    	}
+        return count;
     };
 
     InlineSearchResultExplorer.prototype.getParentDivId = function(secondLevel) {
-        if (!this.model.replaceMode() || !secondLevel) {
-            return this.parentNode.id;
-        } else {
-            return this._uiFactory ? this._uiFactory.getMatchDivID() : this.parentNode.id;
-        }
+    	return this.parentNode.id;
     };
 
     InlineSearchResultExplorer.prototype.gotoCurrent = function(cachedItem) {
@@ -1416,6 +1397,10 @@
 		} else {
 			this.startUp();
 		}
+		
+		var resultTitleDiv = this._inlineSearchPane.getSearchResultsTitleDiv();
+		lib.empty(resultTitleDiv);
+		resultTitleDiv.appendChild(document.createTextNode(_headerString(this.model)));
 	};
 
 	/**
@@ -1430,8 +1415,6 @@
 		//TODO: we need a better way to render the progress and allow user to be able to cancel the crawling search
 		var crawling = searchParams.regEx || searchParams.caseSensitive;
 		var crawler;
-//		lib.empty(lib.node("pageNavigationActions")); //$NON-NLS-0$
-//		lib.empty(lib.node("pageActions")); //$NON-NLS-0$
 		
 		lib.empty(resultsNode);
 		
@@ -1481,8 +1464,11 @@
 	 * @param {String | DomNode} parentNode The parent node to display the results in
 	 * @param {Searcher} searcher
 	 */
-	InlineSearchResultExplorer.prototype.runSearch = function(searchParams, parentNode, searcher) {
+	InlineSearchResultExplorer.prototype.runSearch = function(searchParams, parentNode, searcher, compareNode) {
 		var parent = lib.node(parentNode);
+		if (compareNode) {
+			this._replaceCompareNode = compareNode;
+		}
 		this._search(parent, searchParams, searcher);
 	};
 
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.css b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.css
index c8e8faf..f8cb54d 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.css
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.css
@@ -6,6 +6,8 @@
 
 .searchResultsWrapperDiv .treeTableRow > td {
 	padding: 3px;
+	overflow: hidden;
+	text-overflow: ellipsis;
 }
 
 .searchResultsWrapperDiv > b {
@@ -13,19 +15,42 @@
 }
 
 .searchWrapper {
-	border: 1px solid transparent;
-	border-bottom: none;
+	background: whitesmoke;
+	border: 1px solid rgb(222, 222, 222);
+	border-radius: 0 5px 5px 0;
 	display: block;
-	position: relative;
+	overflow: hidden;
+	position: absolute;
+	top: 0;
+	width: 0;
 	z-index: 100;
-	white-space: nowrap;
-	width: calc(100% - 2px);
 }
 
 .searchWrapperActive {
-	background: whitesmoke;
-	border-color: rgb(222, 222, 222);
-	padding-bottom: 5px;
+	height: calc(100% - 11px);
+	width: calc(100% - 2px);
+	transition: width 0.2s ease;
+}
+
+.searchResultsWrapperDiv {
+	height: calc(100% - 220px - 18px); /* subtract height of search options*/
+	width: 100%;
+}
+
+.searchResultsWrapperDiv > div {
+	border-top: 1px solid #333;
+	height: 100%;
+	overflow: auto;
+	width: 100%;
+}
+
+.searchResultsWrapperDiv > div > .treetable {
+	background: white;
+	table-layout: fixed;
+}
+
+.replaceModeActive > .searchResultsWrapperDiv {
+	height: calc(100% - 220px - 18px - 38px); /* subtract height of search options and replace box */
 }
 
 .searchWrapper > .comboTextInputWrapper {
@@ -162,59 +187,31 @@
 	padding: 7px 10px;
 }
 
-.inlineSearchWrapperDiv {
-	background: whitesmoke;
-	display: block;
-	opacity: 0;
-	overflow: hidden;
-	position: absolute;
-	transition: opacity 0.2s ease, overflow 0s ease 0.2s, visibility 0s ease 0.2s;
-	visibility: hidden;
-	width: calc(100% - 2px); /* subtract border width */
-	z-index: 100;
-}
-
-.isVisible {
-	border: 1px solid rgb(222, 222, 222);
-	border-top: none;
-	height: calc(100% - 68px); /* subtract top and border */
-	opacity: 1;
-	overflow: auto;
-	top: 67px;
-	transition-delay: 0s;
-	visibility: visible;
-}
-
-.projectNavSidebarWrapper > .sidebarToolbar > .inlineSearchWrapperDiv.isVisible {
-	top: 38px;
-	height: calc(100% - 40px);
-}
-
-.projectNavSidebarWrapper.sidebarWrapper > .sidebar {
-	height: calc(100% - 40px);
+.projectNavSidebarWrapper > .searchWrapperActive {
+	height: calc(100% - 14px);
 }
 
 .fileNameSpan {
 	display: inline-block;
+	font-weight: bold;
 	outline: none;
 	padding: 2px;
 	vertical-align: middle;
 }
 
-.fileLocationSpan {
-	cursor: text;
-	display: inline-block;
-	margin-left: 5px;
-	outline: none;
-	padding: 2px;
-	vertical-align: middle;
-	-webkit-user-select: text;
-	-moz-user-select: text;
-	user-select: text;
+.fileParentSpan {
+	color: #666 !important;
+	font-size: 8pt; 
+	font-weight: normal;
+}
+
+.replaceFileNameSpan {
+	color: black;
+	cursor: pointer;
 }
 
 .deleteSearchRowButton {
-	margin-left: 10px !important;
+	margin-left: 2px !important;
 }
 
 .searchDetailRow {
@@ -250,3 +247,35 @@
 .searchWrapperActive > .comboTextInputWrapper > .comboTextInputButton {
 	background-color: rgb(221, 221, 221);
 }
+
+.replaceCompareDiv {
+	display: none;
+	z-index: 1;
+}
+
+.replaceCompareDivVisible {
+	display: block;
+}
+
+
+.searchResultsTitle {
+	display: inline-block;
+	font-weight: bold;
+	margin: 0;
+	margin-left: 20px;
+	color: #333;
+	width: calc(100% - 150px);
+	overflow: hidden;
+	text-overflow: ellipsis;
+	vertical-align: middle;
+	white-space: nowrap;
+}
+
+.replaceModeActive > .searchResultsTitle {
+	width: calc(100% - 250px);
+}
+
+.searchPageActions {
+	display: inline-block;
+}
+
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.html b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.html
index ec05241..0a2e9a3 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.html
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.html
@@ -1,8 +1,7 @@
 <div class="searchWrapper">

 	<button class="imageSprite core-sprite-close dismissButton searchDismissButton"></button>

 	<!-- search box gets inserted here -->

-</div>

-<div class="inlineSearchWrapperDiv">

+	

 	<div class="searchOptWrapperDiv">

 		<div class="searchMainOptionBlock">

 			<!-- search box gets inserted here -->

@@ -32,5 +31,6 @@
 			</div>

 		</div>

 	</div>

+	<div id="searchResultsTitle" class="searchResultsTitle"></div><div id="searchPageActions" class="searchPageActions"></div>

 	<div class="searchResultsWrapperDiv"></div>

 </div>
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.js b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.js
index 45ab7af..8b68f27 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/search/InlineSearchPane.js
@@ -46,7 +46,6 @@
 			this._parentNode.appendChild(domNodeFragment);

 			

 			this._searchWrapper = lib.$(".searchWrapper", this._parentNode); //$NON-NLS-0$

-			this._wrapperDiv = lib.$(".inlineSearchWrapperDiv", this._parentNode); //$NON-NLS-0$

 			

 			this._focusOnTextInput = function(){

 				this._searchTextInputBox.focus();

@@ -57,25 +56,26 @@
 				this.hide();

 			}.bind(this));

 			

-			this._searchOptWrapperDiv = lib.$(".searchOptWrapperDiv", this._wrapperDiv); //$NON-NLS-0$

-			this._searchResultsWrapperDiv = lib.$(".searchResultsWrapperDiv", this._wrapperDiv); //$NON-NLS-0$

-			

+			this._searchOptWrapperDiv = lib.$(".searchOptWrapperDiv", this._parentNode); //$NON-NLS-0$

+			this._searchResultsTitle = lib.$(".searchResultsTitle", this._parentNode); //$NON-NLS-0$

+			this._searchResultsWrapperDiv = lib.$(".searchResultsWrapperDiv", this._parentNode); //$NON-NLS-0$

 			this._searchResultsWrapperDiv.id = "inlineSearchResultsWrapper";

+			

+			this._replaceCompareDiv = lib.node("replaceCompareDiv"); //$NON-NLS-0$

 

 			this._searcher = new mSearchClient.Searcher({serviceRegistry: this._serviceRegistry, commandService: this._commandRegistry, fileService: this._fileClient});

-			this._searchResultExplorer = new InlineSearchResultExplorer(this._serviceRegistry, this._commandRegistry);

+			this._searchResultExplorer = new InlineSearchResultExplorer(this._serviceRegistry, this._commandRegistry, this);

 			this._render();

 		},

 		

 		isVisible: function() {

-			return this._wrapperDiv.classList.contains("isVisible"); //$NON-NLS-0$

+			return this._searchWrapper.classList.contains("searchWrapperActive"); //$NON-NLS-0$

 		},

 				

 		show: function() {

 			this._previousActiveElement = document.activeElement;

 			

 			this._searchWrapper.classList.add("searchWrapperActive"); //$NON-NLS-0$

-			this._wrapperDiv.classList.add("isVisible"); //$NON-NLS-0$

 			window.setTimeout(this._focusOnTextInput, 100);

 			

 			this.dispatchEvent({type: "open"});

@@ -83,7 +83,6 @@
 		

 		hide: function() {

 			this._searchWrapper.classList.remove("searchWrapperActive"); //$NON-NLS-0$

-			this._wrapperDiv.classList.remove("isVisible"); //$NON-NLS-0$

 			

 			if (!this._replaceBoxIsHidden()) {

 				this._hideReplaceField();

@@ -141,7 +140,7 @@
 				this._replaceBox.addTextInputValueToRecentEntries();

 				this._fileNamePatternsBox.addTextInputValueToRecentEntries();

 				var searchParams = mSearchUtils.getSearchParams(this._searcher, options.keyword, options);

-				this._searchResultExplorer.runSearch(searchParams, this._searchResultsWrapperDiv, this._searcher);

+				this._searchResultExplorer.runSearch(searchParams, this._searchResultsWrapperDiv, this._searcher, this._replaceCompareDiv);

 			}

 		},

 	    

@@ -192,6 +191,7 @@
 			this._searchBox = new ComboTextInput({

 				id: "advSearchInput", //$NON-NLS-0$

 				parentNode: searchBoxParentNode,

+				insertBeforeNode: this._searchOptWrapperDiv,

 				hasButton: true,

 				buttonClickListener: searchButtonListener,

 				hasInputCompletion: true,

@@ -369,17 +369,22 @@
 			} else {

 				this._hideReplaceField();

 			}

+			this._searchResultExplorer.initCommands();

 		},

 		

 		_showReplaceField: function() {

 			this._searchBox.hideButton();

 			this._replaceWrapper.classList.remove("replaceWrapperHidden"); //$NON-NLS-0$

+			this._searchWrapper.classList.add("replaceModeActive"); //$NON-NLS-0$

+			this._replaceCompareDiv.classList.add("replaceCompareDivVisible");

 			this._toggleReplaceLink.innerHTML = messages["Hide Replace"]; //$NON-NLS-0$

 		},

 		

 		_hideReplaceField: function() {

 			this._searchBox.showButton();

 			this._replaceWrapper.classList.add("replaceWrapperHidden"); //$NON-NLS-0$

+			this._searchWrapper.classList.remove("replaceModeActive"); //$NON-NLS-0$

+			this._replaceCompareDiv.classList.remove("replaceCompareDivVisible");

 			this._toggleReplaceLink.innerHTML = messages["Show Replace"]; //$NON-NLS-0$

 		},

 		

@@ -416,6 +421,10 @@
 				locationElement.appendChild(document.createTextNode(scopeString));

 				scopeElementWrapper.appendChild(locationElement);	

 			}, this);

+		},

+		

+		getSearchResultsTitleDiv: function() {

+			return this._searchResultsTitle;

 		}

 	});

 

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/search/nls/root/messages.js b/bundles/org.eclipse.orion.client.ui/web/orion/search/nls/root/messages.js
index 9851ec2..65aa6a7 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/search/nls/root/messages.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/search/nls/root/messages.js
@@ -29,8 +29,8 @@
 	"Replace": "Replace",
 	"Replace...": "Replace...",
 	"Replace All": "Replace All",
-	"Show Replace": "Show Replace",
-	"Hide Replace": "Hide Replace",
+	"Show Replace": "Switch to Replace Mode",
+	"Hide Replace": "Switch to Search Mode",
 	"Search ${0}": "Search ${0}",
 	"Type a keyword or wild card to search in ": "Type a keyword or wild card to search in ",
 	"Search failed.": "Search failed.",
@@ -40,7 +40,7 @@
 	"Failed to write file.": "Failed to write file.",
 	"Results": "Results",
 	"Files ${0} of ${1} matching ${2}": "Files ${0} of ${1} matching \"${2}\"",
-	"Replace ${0} with ${1} for files ${2} of ${3}": "Replace ${0} with ${1} for files ${2} of ${3}",
+	"Replace ${0} with ${1} for files ${2} of ${3}": "Replace \"${0}\" with \"${1}\" for files ${2} of ${3}",
 	"Location": "Location",
 	"Click to compare": "Click to compare",
 	"Search again in this folder with \"${0}\"": "Search again in this folder with \"${0}\"",
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/project-nav.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/project-nav.js
index e38376f..87d2ebb 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/project-nav.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/project-nav.js
@@ -454,16 +454,14 @@
 				toolbarNode: this.toolbarNode
 			});
 			this.explorer.display(this.project);
-			//TODO do this in a less hackish way
-			this.toolbarNode.parentNode.classList.add("projectNavSidebarWrapper"); //$NON-NLS-0$
+			this.toolbarNode.classList.add("projectNavSidebarWrapper"); //$NON-NLS-0$
 		},
 		destroy: function() {
 			if (this.explorer) {
 				this.explorer.destroy();
 			}
 			this.explorer = null;
-			//TODO do this in a less hackish way
-			this.toolbarNode.parentNode.classList.remove("projectNavSidebarWrapper"); //$NON-NLS-0$
+			this.toolbarNode.classList.remove("projectNavSidebarWrapper"); //$NON-NLS-0$
 		},
 		getProjectJson: function(metadata) {
 			function getJson(children) {