summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorChris Conley2013-08-20 17:37:52 (EDT)
committer Bogdan Gheorghe2013-08-20 17:39:00 (EDT)
commit4a3521d25be74810cce94c7bd9d293026729e092 (patch)
tree54714af955c75f9097a64e60ff059c2ce4e8a6e4
parent40ca28d32b1ce67a4d87475f6baded10e9f17693 (diff)
downloadorg.eclipse.orion.client-4a3521d25be74810cce94c7bd9d293026729e092.zip
org.eclipse.orion.client-4a3521d25be74810cce94c7bd9d293026729e092.tar.gz
org.eclipse.orion.client-4a3521d25be74810cce94c7bd9d293026729e092.tar.bz2
Bug 414014 - Show git blame annotations in the editorv20130820-2139
Signed-off-by: Chris Conley <chrisconley15@gmail.com>
-rw-r--r--bundles/org.eclipse.orion.client.core/web/orion/blameAnnotations.js35
-rw-r--r--bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.css12
-rw-r--r--bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.js13
-rw-r--r--bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js81
-rw-r--r--bundles/org.eclipse.orion.client.editor/web/orion/editor/rulers.js61
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/edit/setup.js11
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/blamer.js31
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/edit/nls/root/messages.js2
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js23
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.html23
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.js170
11 files changed, 450 insertions, 12 deletions
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/blameAnnotations.js b/bundles/org.eclipse.orion.client.core/web/orion/blameAnnotations.js
new file mode 100644
index 0000000..f1e1710
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.core/web/orion/blameAnnotations.js
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2010, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0
+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+/*global define */
+
+define("orion/blameAnnotations", ["orion/EventTarget"], function(EventTarget) {
+
+
+ function BlameService(serviceRegistry) {
+ this._serviceRegistry = serviceRegistry;
+ EventTarget.attach(this);
+ this._serviceRegistration = serviceRegistry.registerService("orion.core.blame", this); //$NON-NLS-0$
+ }
+
+ BlameService.prototype = /** @lends orion.blameAnnotations.BlameService.prototype */ {
+ // provider
+ _setAnnotations: function(blameInfo) {
+ this.blameInfo = blameInfo;
+ this.dispatchEvent({type:"blameChanged", blameInfo:blameInfo}); //$NON-NLS-0$
+ }
+ };
+ BlameService.prototype.constructor = BlameService;
+
+ //return the module exports
+ return {BlameService: BlameService};
+});
+
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.css b/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.css
index d2311b8..6401aad 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.css
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.css
@@ -19,6 +19,13 @@
.annotation.currentLinkedGroup,
.annotation.selectedLinkedGroup {
}
+.annotation.blame {
+ background-color: rgb(255, 132, 44);
+}
+.annotation.currentBlame {
+ background-color: rgb(184, 103, 163);
+}
+
/* Styles for the annotation ruler (first line) */
.annotationHTML {
@@ -149,6 +156,11 @@
background-color: Gold;
border: 1px solid darkred;
}
+.annotationOverview.currentBlame {
+ background-color: rgb(184, 103, 163);
+ border: 1px solid black;
+}
+
/* Styles for text range */
.annotationRange {
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.js
index e6f991c..2810d87 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/annotations.js
@@ -161,6 +161,17 @@ define("orion/editor/annotations", ['i18n!orion/editor/nls/messages', 'orion/edi
*/
AnnotationType.ANNOTATION_LINKED_GROUP = "orion.annotation.linkedGroup"; //$NON-NLS-0$
+ /**
+ * Blame annotation type.
+ */
+ AnnotationType.ANNOTATION_BLAME = "orion.annotation.blame"; //$NON-NLS-0$
+
+ /**
+ * Current Blame annotation type.
+ */
+ AnnotationType.ANNOTATION_CURRENT_BLAME = "orion.annotation.currentBlame"; //$NON-NLS-0$
+
+
/** @private */
var annotationTypes = {};
@@ -245,6 +256,8 @@ define("orion/editor/annotations", ['i18n!orion/editor/nls/messages', 'orion/edi
registerType(AnnotationType.ANNOTATION_CURRENT_LINKED_GROUP);
registerType(AnnotationType.ANNOTATION_LINKED_GROUP);
registerType(AnnotationType.ANNOTATION_CURRENT_LINE, true);
+ registerType(AnnotationType.ANNOTATION_BLAME, true);
+ registerType(AnnotationType.ANNOTATION_CURRENT_BLAME, true);
AnnotationType.registerType(AnnotationType.ANNOTATION_FOLDING, FoldingAnnotation);
/**
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
index 7c9bf27..ceb9ed7 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
@@ -19,6 +19,18 @@ define("orion/editor/editor", [ //$NON-NLS-0$
'orion/util' //$NON-NLS-0$
], function(messages, mEventTarget, mTooltip, mAnnotations, util) {
+ /** @private */
+ function merge(obj1, obj2) {
+ if (obj2) {
+ for (var p in obj2) {
+ if (obj2.hasOwnProperty(p)) {
+ obj1[p] = obj2[p];
+ }
+ }
+ }
+ return obj1;
+ }
+
var AT = mAnnotations.AnnotationType;
var HIGHLIGHT_ERROR_ANNOTATION = "orion.annotation.highlightError"; //$NON-NLS-0$
@@ -602,6 +614,7 @@ define("orion/editor/editor", [ //$NON-NLS-0$
if (ruler) {
ruler.addAnnotationType(AT.ANNOTATION_CURRENT_SEARCH);
ruler.addAnnotationType(AT.ANNOTATION_MATCHING_SEARCH);
+ ruler.addAnnotationType(AT.ANNOTATION_CURRENT_BLAME);
ruler.addAnnotationType(AT.ANNOTATION_ERROR);
ruler.addAnnotationType(AT.ANNOTATION_WARNING);
ruler.addAnnotationType(AT.ANNOTATION_TASK);
@@ -617,6 +630,8 @@ define("orion/editor/editor", [ //$NON-NLS-0$
if (this._lineNumberRulerFactory) {
this._lineNumberRuler = this._lineNumberRulerFactory.createLineNumberRuler(this._annotationModel);
+ this._lineNumberRuler.addAnnotationType(AT.ANNOTATION_CURRENT_BLAME);
+ this._lineNumberRuler.addAnnotationType(AT.ANNOTATION_BLAME);
this._lineNumberRuler.onDblClick = addRemoveBookmark;
this.setLineNumberRulerVisible(this._lineNumberRulerVisible || this._lineNumberRulerVisible === undefined, true);
}
@@ -675,7 +690,7 @@ define("orion/editor/editor", [ //$NON-NLS-0$
this.reportStatus(util.formatMessage(messages.lineColumn, lineIndex + 1, offsetInLine + 1));
},
- showAnnotations: function(annotations, types, getType) {
+ showAnnotations: function(annotations, types, createAnnotation, getType) {
var annotationModel = this._annotationModel;
if (!annotationModel) {
return;
@@ -694,7 +709,10 @@ define("orion/editor/editor", [ //$NON-NLS-0$
if (annotations) {
for (var i = 0; i < annotations.length; i++) {
annotation = annotations[i];
- if (annotation) {
+ if (!annotation) { continue; }
+ if (createAnnotation) {
+ annotation = createAnnotation(annotation);
+ } else {
var start, end;
if (typeof annotation.line === "number") { //$NON-NLS-0$
// line/column
@@ -710,9 +728,10 @@ define("orion/editor/editor", [ //$NON-NLS-0$
var type = getType(annotation);
if (!type) { continue; }
annotation = AT.createAnnotation(type, start, end, annotation.description);
- annotation.creatorID = this;
- add.push(annotation);
}
+ annotation.creatorID = this;
+ add.push(annotation);
+
}
}
annotationModel.replaceAnnotations(remove, add);
@@ -723,7 +742,7 @@ define("orion/editor/editor", [ //$NON-NLS-0$
AT.ANNOTATION_ERROR,
AT.ANNOTATION_WARNING,
AT.ANNOTATION_TASK
- ], function(annotation) {
+ ], null, function(annotation) {
switch (annotation.severity) {
case "error": return AT.ANNOTATION_ERROR; //$NON-NLS-0$
case "warning": return AT.ANNOTATION_WARNING; //$NON-NLS-0$
@@ -737,11 +756,61 @@ define("orion/editor/editor", [ //$NON-NLS-0$
this.showAnnotations(occurrences, [
AT.ANNOTATION_READ_OCCURRENCE,
AT.ANNOTATION_WRITE_OCCURRENCE
- ], function(annotation) {
+ ], null, function(annotation) {
return annotation.readAccess ? AT.ANNOTATION_READ_OCCURRENCE : AT.ANNOTATION_WRITE_OCCURRENCE;
});
},
+ showBlame : function(blameMarkers) {
+ var blameRGB = this._blameRGB;
+ if (!blameRGB) {
+ var document = this.getTextView().getOptions("parent").ownerDocument; //$NON-NLS-0$
+ var div = util.createElement(document, "div"); //$NON-NLS-0$
+ div.className = "annotation blame"; //$NON-NLS-0$
+ document.body.appendChild(div);
+ var window = document.defaultView || document.parentWindow;
+ var blameStyle = window.getComputedStyle(div);
+ var color = blameStyle.getPropertyValue("background-color"); //$NON-NLS-0$
+ div.parentNode.removeChild(div);
+ var i1 = color.indexOf("("); //$NON-NLS-0$
+ var i2 = color.indexOf(")"); //$NON-NLS-0$
+ color = color.substring(i1 + 1, i2);
+ this._blameRGB = blameRGB = color.split(",").slice(0,3); //$NON-NLS-0$
+ }
+ var createGroupFunction = function() {
+ var annotation = mAnnotations.AnnotationType.createAnnotation(this.groupedType, this.start, this.end, "");
+ annotation.style = merge({}, annotation.style);
+ annotation.style.style = merge({}, annotation.style.style);
+ annotation.style.style.backgroundColor = "";
+ return annotation;
+ };
+ var model = this.getModel();
+ this.showAnnotations(blameMarkers, [
+ AT.ANNOTATION_BLAME
+ ], function (blameMarker) {
+ var start = model.getLineStart(blameMarker.Start - 1);
+ var end = model.getLineEnd(blameMarker.End - 1, true);
+ var string = "Message: " + blameMarker.Message.substring(0, 80) + "\nID:" +
+ blameMarker.Name + "\nLocation: " +
+ blameMarker.CommitLocation + "\nAuthor: " +
+ blameMarker.AuthorName + " (" + blameMarker.AuthorEmail +
+ ") " + blameMarker.Time + "\nCommitter: " +
+ blameMarker.CommitterName + " (" + blameMarker.CommitterEmail +
+ ")";
+
+ var annotation = mAnnotations.AnnotationType.createAnnotation(AT.ANNOTATION_BLAME, start, end, string);
+ var blameColor = blameRGB.slice(0);
+ blameColor.push(blameMarker.Shade);
+ annotation.style = merge({}, annotation.style);
+ annotation.style.style = merge({}, annotation.style.style);
+ annotation.style.style.backgroundColor = "rgba(" + blameColor.join() + ")"; //$NON-NLS-0$ //$NON-NLS-1$
+ annotation.groupId = blameMarker.Name;
+ annotation.groupedType = AT.ANNOTATION_CURRENT_BLAME;
+ annotation.createGroupedAnnotation = createGroupFunction;
+ return annotation;
+ });
+ },
+
/**
* Reveals and selects a portion of text.
* @param {Number} start
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/rulers.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/rulers.js
index 89f7638..fc58bf0 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/rulers.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/rulers.js
@@ -329,6 +329,7 @@ define("orion/editor/rulers", ['i18n!orion/editor/nls/messages', 'orion/editor/a
*/
onMouseOver: function(lineIndex, e) {
this.onMouseMove(lineIndex, e);
+ this._showCurrentGroup(lineIndex, e);
},
/**
* This event is sent when the mouse pointer exits a line annotation.
@@ -338,12 +339,9 @@ define("orion/editor/rulers", ['i18n!orion/editor/nls/messages', 'orion/editor/a
* @param {DOMEvent} e the mouse out event.
*/
onMouseOut: function(lineIndex, e) {
+ this._hideCurrentGroup();
var tooltip = mTooltip.Tooltip.getTooltip(this._view);
if (!tooltip) { return; }
- if (e.relatedTarget) {
- var relatedCompare = e.relatedTarget.compareDocumentPosition(this._view.getOptions("parent")); //$NON-NLS-0$
- if (relatedCompare & 8) { return; }
- }
tooltip.setTarget(null);
},
/** @ignore */
@@ -386,6 +384,10 @@ define("orion/editor/rulers", ['i18n!orion/editor/nls/messages', 'orion/editor/a
_getTooltipContents: function(lineIndex, annotations) {
return annotations;
},
+ _hideCurrentGroup: function() {
+ this._groupLineIndex = -1;
+ this._showGroupAnnotation(null);
+ },
/** @ignore */
_onAnnotationModelChanged: function(e) {
var view = this._view;
@@ -463,6 +465,57 @@ define("orion/editor/rulers", ['i18n!orion/editor/nls/messages', 'orion/editor/a
}
}
return result;
+ },
+ _showGroupAnnotation: function(groupAnnotation) {
+ var annotationModel = this._annotationModel;
+ if (!annotationModel) {
+ return;
+ }
+ if (this._groupedType) {
+ annotationModel.removeAnnotations(this._groupedType);
+ }
+ if (!groupAnnotation) { return; }
+ this._groupedType = groupAnnotation.groupedType;
+ var model = annotationModel.getTextModel();
+ var annotations = annotationModel.getAnnotations(0, model.getCharCount()), annotation;
+ var hoveredId = groupAnnotation.groupId;
+ var add = [];
+ while (annotations.hasNext()) {
+ annotation = annotations.next();
+ if (annotation.groupId === hoveredId) {
+ annotation = annotation.createGroupedAnnotation();
+ add.push(annotation);
+ }
+ }
+ annotationModel.replaceAnnotations(null, add);
+ },
+ _showCurrentGroup: function(lineIndex, e) {
+ if (this._groupLineIndex === lineIndex) {
+ return;
+ }
+ this._groupLineIndex = lineIndex;
+ var self = this;
+ var annotationModel = self._annotationModel;
+ var model = annotationModel.getTextModel();
+ var start = model.getLineStart(lineIndex);
+ var end = model.getLineEnd(lineIndex);
+ if (model.getBaseModel) {
+ start = model.mapOffset(start);
+ end = model.mapOffset(end);
+ }
+ var annotations = annotationModel.getAnnotations(start, end);
+ var groupAnnotation = null;
+ while(annotations.hasNext()){
+ var annotation = annotations.next();
+ if (!self.isAnnotationTypeVisible(annotation.type)) { continue; }
+ if (annotation.start <= start && annotation.end >= end){
+ if (annotation.groupId !== undefined) {
+ groupAnnotation = annotation;
+ break;
+ }
+ }
+ }
+ self._showGroupAnnotation(groupAnnotation);
}
};
mAnnotations.AnnotationTypeList.addMixin(Ruler.prototype);
diff --git a/bundles/org.eclipse.orion.client.ui/web/edit/setup.js b/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
index b8deba1..268c7a9 100644
--- a/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
+++ b/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
@@ -29,6 +29,7 @@ define([
'orion/globalCommands',
'orion/outliner',
'orion/problems',
+ 'orion/blameAnnotations',
'orion/editor/contentAssist',
'orion/editorCommands',
'orion/editor/editorFeatures',
@@ -54,7 +55,7 @@ define([
'orion/webui/tooltip',
'orion/widgets/input/DropDownMenu'
], function(messages, require, EventTarget, lib, mSelection, mStatus, mProgress, mDialogs, mCommandRegistry, mExtensionCommands,
- mFileClient, mOperationsClient, mSearchClient, mGlobalCommands, mOutliner, mProblems, mContentAssist, mEditorCommands, mEditorFeatures, mEditor,
+ mFileClient, mOperationsClient, mSearchClient, mGlobalCommands, mOutliner, mProblems, mBlameAnnotation, mContentAssist, mEditorCommands, mEditorFeatures, mEditor,
mSyntaxchecker, mTextView, mTextModel, mProjectionTextModel, mKeyBinding, mEmacs, mVI, mSearcher,
mContentTypes, PageUtil, mInputManager, i18nUtil, mThemePreferences, mThemeData, EditorSettings, mEditorPreferences, URITemplate, Sidebar,
mTooltip, DropDownMenu) {
@@ -66,6 +67,7 @@ exports.setUpEditor = function(serviceRegistry, preferences, isReadOnly){
var commandRegistry;
var statusReportingService;
var problemService;
+ var blameService;
var outlineService;
var contentTypeService;
var progressService;
@@ -88,6 +90,7 @@ exports.setUpEditor = function(serviceRegistry, preferences, isReadOnly){
contentTypeService = new mContentTypes.ContentTypeService(serviceRegistry);
fileClient = new mFileClient.FileClient(serviceRegistry);
searcher = new mSearchClient.Searcher({serviceRegistry: serviceRegistry, commandService: commandRegistry, fileService: fileClient});
+ blameService = new mBlameAnnotation.BlameService(serviceRegistry);
}());
var sidebarDomNode = lib.node("sidebar"), //$NON-NLS-0$
@@ -350,6 +353,12 @@ exports.setUpEditor = function(serviceRegistry, preferences, isReadOnly){
serviceRegistry.getService("orion.core.marker").addEventListener("problemsChanged", function(event) { //$NON-NLS-1$ //$NON-NLS-0$
editor.showProblems(event.problems);
});
+
+ // Blame event listener
+ serviceRegistry.getService("orion.core.blame").addEventListener("blameChanged", function(event) { //$NON-NLS-1$ //$NON-NLS-0$
+ editor.showBlame(event.blameInfo);
+ });
+
var syntaxChecker = new mSyntaxchecker.SyntaxChecker(serviceRegistry, editor);
editor.addEventListener("InputChanged", function(evt) { //$NON-NLS-0$
syntaxChecker.checkSyntax(inputManager.getContentType(), evt.title, evt.message, evt.contents);
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/blamer.js b/bundles/org.eclipse.orion.client.ui/web/orion/blamer.js
new file mode 100644
index 0000000..ed59b1a
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/blamer.js
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0
+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*global window define */
+
+define ("orion/blamer", [], function() {
+
+ function isVisible(serviceRegistry) {
+ return !!serviceRegistry.getService("orion.edit.blamer"); //$NON-NLS-0$
+ }
+
+ function getBlame(serviceRegistry, editor, fileName){
+ var service = serviceRegistry.getService("orion.edit.blamer"); //$NON-NLS-0$
+ if (service) {
+ service.doBlame(fileName).then(function(results) {
+ serviceRegistry.getService("orion.core.blame")._setAnnotations(results); //$NON-NLS-0$
+ });
+ }
+ }
+ return {isVisible: isVisible, getBlame: getBlame};
+});
+
+
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/edit/nls/root/messages.js b/bundles/org.eclipse.orion.client.ui/web/orion/edit/nls/root/messages.js
index 2ec3ff8..d110c5e 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/edit/nls/root/messages.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/edit/nls/root/messages.js
@@ -22,6 +22,8 @@ define({
"Toggle Outliner": "Toggle Outliner", //$NON-NLS-1$ //$NON-NLS-0$
"There are unsaved changes.": "There are unsaved changes.", //$NON-NLS-1$ //$NON-NLS-0$
"Save": "Save", //$NON-NLS-1$ //$NON-NLS-0$
+ "Blame": "Blame", //$NON-NLS-1$ //$NON-NLS-0$
+ "BlameTooltip":"Show blame annotations", //$NON-NLS-1$ //$NON-NLS-0$
"Resource is out of sync with the server. Do you want to save it anyway?": "Resource is out of sync with the server. Do you want to save it anyway?", //$NON-NLS-1$ //$NON-NLS-0$
"loadOutOfSync": "Resource is out of sync with the server. Do you want to load it anyway? This will overwrite your local changes.", //$NON-NLS-1$ //$NON-NLS-0$
"Reading metedata of": "Reading metedata of ${0}", //$NON-NLS-1$ //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
index 63f9f1f..42cbbf2 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
@@ -26,8 +26,9 @@ define([
'orion/searchUtils',
'orion/PageUtil',
'orion/PageLinks',
+ 'orion/blamer',
'orion/util'
-], function(messages, i18nUtil, lib, openResource, Deferred, URITemplate, mCommands, mKeyBinding, mCommandRegistry, mExtensionCommands, mContentTypes, mSearchUtils, mPageUtil, PageLinks, util) {
+], function(messages, i18nUtil, lib, openResource, Deferred, URITemplate, mCommands, mKeyBinding, mCommandRegistry, mExtensionCommands, mContentTypes, mSearchUtils, mPageUtil, PageLinks, blamer, util) {
var exports = {};
@@ -120,6 +121,7 @@ define([
}
this._generateGotoLineCommnand(editor);
this._generateFindCommnand(editor);
+ this._generateBlame(editor);
if (!this.isReadOnly) {
this._generateEditCommands(editor);
}
@@ -346,6 +348,25 @@ define([
return true;
}, findCommand);
},
+
+ _generateBlame: function(editor){
+ var self = this;
+ var blameCommand = new mCommands.Command({
+ name: messages.Blame,
+ tooltip: messages.BlameTooltip,
+ id: "orion.edit.blame",
+ visibleWhen: function() {
+ return blamer.isVisible(self.serviceRegistry);
+
+ },
+ callback: function(data) {
+ blamer.getBlame(self.serviceRegistry, editor, self.inputManager.getInput());
+ }
+ });
+ this.commandService.addCommand(blameCommand);
+ this.commandService.registerCommandContribution(this.toolbarId , "orion.edit.blame", 1, null, false, new mKeyBinding.KeyBinding('b', true,false,true)); //$NON-NLS-1$ //$NON-NLS-0
+ },
+
_generateEditCommands: function(editor) {
var self = this;
diff --git a/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.html b/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.html
new file mode 100644
index 0000000..b235383
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Blame Plugin</title>
+ <script src="../requirejs/require.js"></script>
+ <script>
+ /*global require*/
+ require({
+ baseUrl: '..',
+ paths: {
+ text: 'requirejs/text',
+ i18n: 'requirejs/i18n',
+ domReady: 'requirejs/domReady'
+ }
+ });
+
+ require(['blamePlugin.js']);
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.js b/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.js
new file mode 100644
index 0000000..1923ca8
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/plugins/blamePlugin.js
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0
+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+/*global define document*/
+
+define(["orion/xhr", "orion/plugin", "orion/Deferred", 'orion/operation'], function(xhr, PluginProvider, Deferred, operation) {
+
+ var headers = {
+ name: "Git Blame Plugin",
+ version: "1.0",
+ description: "Git Blame Plugin"
+ };
+ var provider = new PluginProvider(headers);
+
+ var blameRequest = {
+ getCommitInfo: function(location) {
+ var service = this;
+ var clientDeferred = new Deferred();
+ xhr("GET", location, {
+ headers: {
+ "Orion-Version": "1",
+ "Content-Type": "charset=UTF-8"
+ },
+ timeout: 15000,
+ handleAs: "json" //$NON-NLS-0$
+ }).then(function(result) {
+ service._getGitServiceResponse(clientDeferred, result);
+ }, function(error) {
+ service._handleGitServiceResponseError(clientDeferred, error);
+ });
+
+ return clientDeferred;
+ },
+ getBlameInfo: function(location) {
+ var service = this;
+
+ var clientDeferred = new Deferred();
+
+ xhr("GET", "/gitapi/blame/master" + location, {
+ headers: {
+ "Orion-Version": "1",
+ "Content-Type": "charset=UTF-8"
+ },
+ timeout: 15000,
+ handleAs: "json" //$NON-NLS-0$
+ }).then(function(result) {
+ service._getGitServiceResponse(clientDeferred, result);
+ }, function(error) {
+ service._handleGitServiceResponseError(clientDeferred, error);
+ });
+
+ return clientDeferred;
+ },
+
+ _getGitServiceResponse: function(deferred, result) {
+ var response = result.response ? JSON.parse(result.response) : null;
+
+ if (result.xhr && result.xhr.status === 202) {
+ var def = operation.handle(response.Location);
+ def.then(deferred.resolve, function(data) {
+ data.failedOperation = response.Location;
+ deferred.reject(data);
+ }, deferred.progress);
+ deferred.then(null, function(error) {
+ def.reject(error);
+ });
+ return;
+ }
+
+ deferred.resolve(response);
+ return;
+ },
+
+ _handleGitServiceResponseError: function(deferred, error) {
+ deferred.reject(error);
+ }
+ };
+
+ /*
+ * Makes a server requests for the blame data, as well as server requests for
+ * all of the commits that make up the blame data
+ */
+ function blameFile(url) {
+ var wrappedResult = new Deferred();
+ blameRequest.getBlameInfo(url).then(function(response) {
+ var range = [];
+ var commits = [];
+ var j;
+ var i;
+ var found;
+ for (i = 0; i < response.Children.length; i++) {
+ range = response.Children[i];
+ j = 0;
+ found = false;
+ var id = range.CommitLocation;
+ while (j < commits.length && !found) {
+ if (commits[j] === id) {
+ found = true;
+ }
+ j++;
+ }
+ if (!found) {
+ commits.push(id);
+ }
+ }
+
+ for (i = 0; i < commits.length; i++) {
+ commits[i] = blameRequest.getCommitInfo(commits[i] + "?pageSize=1");
+ }
+
+ Deferred.all(commits, function(error) {
+ return {
+ _error: error
+ };
+ }).then(function(blame) {
+
+ blame.sort(function compare(a, b) {
+ if (a.Children[0].Time < b.Children[0].Time) {
+ return 1;
+ }
+ if (a.Children[0].Time > b.Children[0].Time) {
+ return -1;
+ }
+ return 0;
+ });
+
+ for (var i = 0; i < response.Children.length; i++) {
+ range = response.Children[i];
+ for (var j = 0; j < blame.length; j++) {
+ var c = blame[j].Children[0];
+ if (c.Location === range.CommitLocation) {
+ range.AuthorName = c.AuthorName;
+ range.AuthorEmail = c.AuthorEmail;
+ range.CommitterName = c.CommitterName;
+ range.CommitterEmail = c.CommitterEmail;
+ range.Message = c.Message;
+ range.AuthorImage = c.AuthorImage;
+ range.Name = c.Name;
+ range.Time = new Date(c.Time).toLocaleString();
+ range.Shade = (1 / (blame.length + 1)) * (blame.length - j + 1);
+ break;
+ }
+ }
+ }
+ wrappedResult.resolve(response.Children);
+ });
+ });
+ return wrappedResult;
+ }
+
+ var serviceImpl = {
+ doBlame: function(fileName) {
+ return blameFile(fileName);
+ }
+ };
+ var properties = {
+ name: "Git Blame",
+ key: ["b", true, false, true] // Ctrl+Alt+b
+ };
+
+ provider.registerService("orion.edit.blamer", serviceImpl, properties);
+ provider.connect();
+}); \ No newline at end of file