Adding/removing breakpoints.
This commit is contained in:
parent
4e85308deb
commit
076fb70335
|
@ -238,6 +238,15 @@ body {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
.debugger-fnview-gutter-icon-el {
|
.debugger-fnview-gutter-icon-el {
|
||||||
|
padding-left: 7px;
|
||||||
|
position: relative;
|
||||||
|
top: -6px;
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
.debugger-fnview-gutter-addr {
|
.debugger-fnview-gutter-addr {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
|
|
|
@ -16,7 +16,7 @@ var module = angular.module('xe.ui.code.functionView', [
|
||||||
|
|
||||||
|
|
||||||
module.controller('FunctionViewController', function(
|
module.controller('FunctionViewController', function(
|
||||||
$rootScope, $scope, app, log) {
|
$rootScope, $scope, app, log, Breakpoint) {
|
||||||
$scope.codeType = 'source';
|
$scope.codeType = 'source';
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
|
@ -93,6 +93,8 @@ module.controller('FunctionViewController', function(
|
||||||
el.classList.add('debugger-fnview-gutter-code-el');
|
el.classList.add('debugger-fnview-gutter-code-el');
|
||||||
el.innerText = hex32(line[2]);
|
el.innerText = hex32(line[2]);
|
||||||
cm.setGutterMarker(n, 'debugger-fnview-gutter-code', el);
|
cm.setGutterMarker(n, 'debugger-fnview-gutter-code', el);
|
||||||
|
|
||||||
|
updateLineIcon(n, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -138,11 +140,57 @@ module.controller('FunctionViewController', function(
|
||||||
};
|
};
|
||||||
$scope.$watch('codeType', updateCode);
|
$scope.$watch('codeType', updateCode);
|
||||||
|
|
||||||
|
function updateLineIcon(line, sourceLine) {
|
||||||
|
var cm = $scope.codeMirror;
|
||||||
|
if (sourceLine[0] != 'i') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var address = sourceLine[1];
|
||||||
|
var breakpoint = app.session.breakpoints[address];
|
||||||
|
var el;
|
||||||
|
if (breakpoint) {
|
||||||
|
el = document.createElement('span');
|
||||||
|
el.classList.add('debugger-fnview-gutter-icon-el');
|
||||||
|
if (breakpoint.enabled) {
|
||||||
|
el.innerHTML = '●';
|
||||||
|
} else {
|
||||||
|
el.innerHTML = '◌';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
el = null;
|
||||||
|
}
|
||||||
|
cm.setGutterMarker(line, 'debugger-fnview-gutter-icon', el);
|
||||||
|
};
|
||||||
|
|
||||||
|
function toggleBreakpoint(line, sourceLine, shiftKey) {
|
||||||
|
var address = sourceLine[1];
|
||||||
|
var breakpoint = app.session.breakpoints[address];
|
||||||
|
if (breakpoint) {
|
||||||
|
// Existing breakpoint - toggle or remove.
|
||||||
|
if (shiftKey || !breakpoint.enabled) {
|
||||||
|
app.session.toggleBreakpoint(breakpoint, !breakpoint.enabled);
|
||||||
|
} else {
|
||||||
|
app.session.removeBreakpoint(breakpoint);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// New breakpoint needed.
|
||||||
|
breakpoint = app.session.addCodeBreakpoint(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLineIcon(line, sourceLine);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.codeMirror.on('gutterClick', function(
|
$scope.codeMirror.on('gutterClick', function(
|
||||||
instance, line, gutterClass, e) {
|
instance, line, gutterClass, e) {
|
||||||
if (e.which == 1) {
|
if (e.which == 1) {
|
||||||
if (gutterClass == 'debugger-fnview-gutter-icon') {
|
if (gutterClass == 'debugger-fnview-gutter-icon' ||
|
||||||
console.log('click', e);
|
gutterClsas == 'debugger-fnview-gutter-addr') {
|
||||||
|
var sourceLine = $scope.sourceLines[line];
|
||||||
|
if (!sourceLine || sourceLine[0] != 'i') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
toggleBreakpoint(line, sourceLine, e.shiftKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,45 @@
|
||||||
var module = angular.module('xe.datasources', []);
|
var module = angular.module('xe.datasources', []);
|
||||||
|
|
||||||
|
|
||||||
|
module.service('Breakpoint', function() {
|
||||||
|
// http://stackoverflow.com/a/2117523/377392
|
||||||
|
var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
|
||||||
|
function uuid4() {
|
||||||
|
return uuidFormat.replace(/[xy]/g, function(c) {
|
||||||
|
var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var Breakpoint = function(opt_id) {
|
||||||
|
this.id = opt_id || uuid4();
|
||||||
|
this.type = Breakpoint.Type.TEMP;
|
||||||
|
this.address = 0;
|
||||||
|
this.enabled = true;
|
||||||
|
};
|
||||||
|
Breakpoint.Type = {
|
||||||
|
TEMP: 'temp',
|
||||||
|
CODE: 'code'
|
||||||
|
};
|
||||||
|
Breakpoint.fromJSON = function(json) {
|
||||||
|
var breakpoint = new Breakpoint(json.id);
|
||||||
|
breakpoint.type = json.type;
|
||||||
|
breakpoint.address = json.address;
|
||||||
|
breakpoint.enabled = json.enabled;
|
||||||
|
return breakpoint;
|
||||||
|
};
|
||||||
|
Breakpoint.prototype.toJSON = function() {
|
||||||
|
return {
|
||||||
|
'id': this.id,
|
||||||
|
'type': this.type,
|
||||||
|
'address': this.address,
|
||||||
|
'enabled': this.enabled
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return Breakpoint;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
module.service('DataSource', function($q) {
|
module.service('DataSource', function($q) {
|
||||||
var DataSource = function(source) {
|
var DataSource = function(source) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
|
|
@ -13,17 +13,50 @@ var module = angular.module('xe.session', []);
|
||||||
|
|
||||||
|
|
||||||
module.service('Session', function(
|
module.service('Session', function(
|
||||||
$rootScope, $q, $http, log, FileDataSource, RemoteDataSource) {
|
$rootScope, $q, $http, log,
|
||||||
|
Breakpoint, FileDataSource, RemoteDataSource) {
|
||||||
var Session = function(id, opt_dataSource) {
|
var Session = function(id, opt_dataSource) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
||||||
|
this.breakpoints = {};
|
||||||
|
|
||||||
this.dataSource = opt_dataSource || null;
|
this.dataSource = opt_dataSource || null;
|
||||||
|
|
||||||
|
this.loadState();
|
||||||
};
|
};
|
||||||
|
|
||||||
Session.prototype.dispose = function() {
|
Session.prototype.dispose = function() {
|
||||||
|
this.saveState();
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Session.prototype.loadState = function() {
|
||||||
|
var json = JSON.parse(window.localStorage[this.id]);
|
||||||
|
if (!json) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var breakpointList = json.breakpoints;
|
||||||
|
this.breakpoints = {};
|
||||||
|
for (var n = 0; n < breakpointList.length; n++) {
|
||||||
|
var breakpointJson = breakpointList[n];
|
||||||
|
this.breakpoints[breakpointJson.address] =
|
||||||
|
Breakpoint.fromJSON(breakpointJson);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.saveState = function() {
|
||||||
|
var json = {
|
||||||
|
id: this.id,
|
||||||
|
breakpoints: []
|
||||||
|
};
|
||||||
|
for (var key in this.breakpoints) {
|
||||||
|
var breakpoint = this.breakpoints[key];
|
||||||
|
json.breakpoints.push(breakpoint.toJSON());
|
||||||
|
}
|
||||||
|
window.localStorage[this.id] = JSON.stringify(json);
|
||||||
|
};
|
||||||
|
|
||||||
Session.DEFAULT_HOST = '127.0.0.1:6200';
|
Session.DEFAULT_HOST = '127.0.0.1:6200';
|
||||||
|
|
||||||
Session.getHost = function(opt_host) {
|
Session.getHost = function(opt_host) {
|
||||||
|
@ -67,7 +100,7 @@ module.service('Session', function(
|
||||||
p.then((function() {
|
p.then((function() {
|
||||||
log.info('Connected!');
|
log.info('Connected!');
|
||||||
log.clearProgress();
|
log.clearProgress();
|
||||||
this.dataSource = dataSource;
|
this.setDataSource(dataSource);
|
||||||
d.resolve(this);
|
d.resolve(this);
|
||||||
}).bind(this), (function(e) {
|
}).bind(this), (function(e) {
|
||||||
log.error('Unable to connect: ' + e);
|
log.error('Unable to connect: ' + e);
|
||||||
|
@ -82,11 +115,72 @@ module.service('Session', function(
|
||||||
};
|
};
|
||||||
|
|
||||||
Session.prototype.disconnect = function() {
|
Session.prototype.disconnect = function() {
|
||||||
|
this.setDataSource(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.setDataSource = function(dataSource) {
|
||||||
if (this.dataSource) {
|
if (this.dataSource) {
|
||||||
this.dataSource.dispose();
|
this.dataSource.dispose();
|
||||||
this.dataSource = null;
|
this.dataSource = null;
|
||||||
$rootScope.$emit('refresh');
|
$rootScope.$emit('refresh');
|
||||||
}
|
}
|
||||||
|
if (!dataSource) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
|
||||||
|
var breakpointList = [];
|
||||||
|
for (var key in this.breakpoints) {
|
||||||
|
breakpointList.push(this.breakpoints[key]);
|
||||||
|
}
|
||||||
|
this.dataSource.addBreakpoints(breakpointList);
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.addBreakpoint = function(breakpoint) {
|
||||||
|
this.breakpoints[breakpoint.address] = breakpoint;
|
||||||
|
if (this.dataSource) {
|
||||||
|
this.dataSource.addBreakpoint(breakpoint);
|
||||||
|
}
|
||||||
|
this.saveState();
|
||||||
|
return breakpoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.addTempBreakpoint = function(address) {
|
||||||
|
var breakpoint = new Breakpoint();
|
||||||
|
breakpoint.type = Breakpoint.Type.TEMP;
|
||||||
|
breakpoint.address = address;
|
||||||
|
breakpoint.enabled = true;
|
||||||
|
return this.addBreakpoint(breakpoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.addCodeBreakpoint = function(address) {
|
||||||
|
var breakpoint = new Breakpoint();
|
||||||
|
breakpoint.type = Breakpoint.Type.CODE;
|
||||||
|
breakpoint.address = address;
|
||||||
|
breakpoint.enabled = true;
|
||||||
|
return this.addBreakpoint(breakpoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.removeBreakpoint = function(breakpoint) {
|
||||||
|
delete this.breakpoints[breakpoint.address];
|
||||||
|
if (this.dataSource) {
|
||||||
|
this.dataSource.removeBreakpoint(breakpoint.id);
|
||||||
|
}
|
||||||
|
this.saveState();
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.prototype.toggleBreakpoint = function(breakpoint, enabled) {
|
||||||
|
var oldEnabled = enabled;
|
||||||
|
breakpoint.enabled = enabled;
|
||||||
|
if (this.dataSource) {
|
||||||
|
if (breakpoint.enabled) {
|
||||||
|
this.dataSource.addBreakpoint(breakpoint);
|
||||||
|
} else {
|
||||||
|
this.dataSource.removeBreakpoint(breakpoint.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.saveState();
|
||||||
};
|
};
|
||||||
|
|
||||||
return Session;
|
return Session;
|
||||||
|
|
Loading…
Reference in New Issue