aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Trevor Elliott <trevor@galois.com>2013-06-27 11:07:38 -0700
committerGravatar Trevor Elliott <trevor@galois.com>2013-06-27 11:07:38 -0700
commit3378c9fd490f2be86425f13cbd9ece7f9ac31026 (patch)
tree668342d4b469226119cff701ab2bc3351a07dac7
parent899930095f519c19da9e379053a8557fbb7cff29 (diff)
Keep elements highlighted when at least one problem is toggled
-rw-r--r--src/js/fiveui/injected/compute.js27
-rw-r--r--src/js/fiveui/injected/ui.js63
-rw-r--r--src/js/fiveui/js/state.js61
3 files changed, 99 insertions, 52 deletions
diff --git a/src/js/fiveui/injected/compute.js b/src/js/fiveui/injected/compute.js
index 899d7e2..921229e 100644
--- a/src/js/fiveui/injected/compute.js
+++ b/src/js/fiveui/injected/compute.js
@@ -95,13 +95,16 @@
};
core.hash = function(rule, message, node) {
+
var prob = {
- name: rule.name,
- msg: message,
- descr: rule.description,
- url: window.location.href,
+ name: rule.name,
+ msg: message,
+ descr: rule.description,
+ url: window.location.href,
severity: 1,
- xpath: core.getElementXPath(node)
+ xpath: core.getElementXPath(node),
+ phash: null,
+ hash: null,
};
var nodeParents = function(node) {
@@ -123,9 +126,11 @@
};
var str = prob.name + prob.descr + prob.url + prob.severity
- + name + nodeHash(node) + message;
+ + name + nodeHash(node);
- prob.hash = hex_md5(str); // hex_md5() is from md5.js
+ // hex_md5() is from md5.js
+ prob.hash = hex_md5(str);
+ prob.phash = hex_md5(str + message);
return prob;
};
@@ -237,10 +242,10 @@
error:function(message, node) {
var prob = core.hash(theRule, message, node);
var query = $(node);
- if(!query.hasClass(prob.hash)) {
- query.addClass(prob.hash);
- core.reportProblem(prob);
- }
+
+ // let the backend sort out if this problem has been reported already
+ query.addClass(prob.hash);
+ core.reportProblem(prob);
}
};
diff --git a/src/js/fiveui/injected/ui.js b/src/js/fiveui/injected/ui.js
index d742720..1eecd93 100644
--- a/src/js/fiveui/injected/ui.js
+++ b/src/js/fiveui/injected/ui.js
@@ -62,27 +62,55 @@
}, 10);
};
- core.highlightProblem = function(elt) {
- core.maskRules(function() {
+ core.highlighted = {};
+
+ core.highlightProblem = function(prob) {
+ var obj = core.highlighted[prob.hash];
+ if(obj) {
+ // increment the number of times this has been highlighted
+ obj.highlighted = obj.highlighted + 1;
+ } else {
+ // add the rule to the list of highlighted elements, and change its style
+ // to look obvious.
+ var elt = fiveui.query('.' + prob.hash);
var oldStyle = elt.attr('style');
- elt.attr('style', 'background-color: rgba(255,0,0,0.3); background-image: none;');
- elt.addClass('uic-problem');
+ core.maskRules(function() {
+ elt.attr('style', 'background-color: rgba(255,0,0,0.3); background-image: none;');
+ elt.addClass('uic-problem');
+ });
- return oldStyle;
- });
+ // record the element for the future
+ core.highlighted[prob.hash] = {
+ highlighted: 1,
+ oldStyle: oldStyle,
+ }
+ }
};
- core.maskProblem = function(elt, oldStyle) {
- core.maskRules(function() {
- if (oldStyle == undefined) {
- elt.removeAttr('style');
- } else {
- elt.attr('style', oldStyle);
- }
+ core.maskProblem = function(prob) {
+ var obj = core.highlighted[prob.hash];
- elt.removeClass('uic-problem');
- });
+ if(obj) {
+ obj.highlighted = obj.highlighted - 1;
+
+ if(obj.highlighted == 0) {
+ var elt = fiveui.query('.' + prob.hash);
+
+ // remove the fiveui style
+ core.maskRules(function() {
+ if (_.isEmpty(obj.oldStyle)) {
+ elt.removeAttr('style');
+ } else {
+ elt.attr('style', obj.oldStyle);
+ }
+
+ elt.removeClass('uic-problem');
+ });
+
+ delete core.highlighted[prob.hash];
+ }
+ }
};
core.renderStatsTemplate = _.template(
@@ -170,18 +198,17 @@
prExpand.click(
function() {
- var oldStyle;
var elt = $(this);
if(elt.is('.prExpand-down')) {
elt.removeClass('prExpand-down')
.addClass('prExpand-right');
prDetails.hide();
- core.maskProblem(fiveui.query('.' + prob.hash), oldStyle);
+ core.maskProblem(prob);
} else {
elt.addClass('prExpand-down')
.removeClass('prExpand-right');
prDetails.show();
- oldStyle = core.highlightProblem(fiveui.query('.' + prob.hash));
+ core.highlightProblem(prob);
}
return false;
diff --git a/src/js/fiveui/js/state.js b/src/js/fiveui/js/state.js
index b3487c5..903f047 100644
--- a/src/js/fiveui/js/state.js
+++ b/src/js/fiveui/js/state.js
@@ -41,19 +41,28 @@ fiveui.WinState = function(x, y, width, height, closed) {
/**
* @constructor
- * @param {string} name The name of the rule that this problem represents.
- * @param {string} descr Short description of the problem.
- * @param {string} url The url that the problem occurred at.
- * @param {number} severity The severity of the problem
+ * @param {string} cfg The config object for the problem. See
+ * fiveui.Problem.sanitize
*/
-fiveui.Problem = function(name, descr, url, severity, hash, xpath, msg) {
- this.name = name || '';
- this.descr = descr || '';
- this.url = url || '';
- this.severity = severity || 0;
- this.hash = hash;
- this.xpath = xpath;
- this.msg = msg;
+fiveui.Problem = function(cfg) {
+ _.defaults(this, fiveui.Problem.sanitize(cfg));
+};
+
+fiveui.Problem.sanitize = function(obj) {
+
+ var defs = {
+ name: '', // the name of the rule that this problem came from
+ descr: '', // short description of the problem
+ url: '', // url that the problem came from
+ severity: 0, // severity of the problem
+ phash: null, // hash for the combination of problem and element in context
+ hash: null, // hash for the element in context
+ xpath: '', // path of the element in the document
+ msg: '', // problem message
+ };
+
+ return _.defaults(_.pick(obj, _.keys(defs)), defs);
+
};
/**
@@ -61,7 +70,7 @@ fiveui.Problem = function(name, descr, url, severity, hash, xpath, msg) {
* @return {!fiveui.Problem} The problem that the object represents.
*/
fiveui.Problem.fromJSON = function(obj) {
- return new fiveui.Problem(obj.name, obj.descr, obj.url, obj.severity, obj.hash, obj.xpath, obj.msg);
+ return new fiveui.Problem(obj);
};
/**
@@ -73,26 +82,32 @@ fiveui.Problem.fromJSON = function(obj) {
* the corresponding tab.
*/
fiveui.TabState = function(tabId, winState, uiPort) {
- this.tabId = tabId;
- this.winState = winState;
- this.uiPort = uiPort;
+ this.tabId = tabId;
+ this.winState = winState;
+ this.uiPort = uiPort;
this.computePorts = [];
- this.problems = [];
+ this.problems = [];
this.seenProblems = new Set();
- this.stats = {};
+ this.stats = {};
};
_.extend(fiveui.TabState.prototype, {
+ /**
+ * Returns true when the combination of element and problem has been seen
+ * before, to avoid repeats.
+ *
+ * NOTE: we use phash here, as it allows multiple distinct problems to target
+ * the same element.
+ */
addProblem: function(prob) {
- if(!this.seenProblems.contains(prob.hash)) {
+ if(this.seenProblems.contains(prob.phash)) {
+ return false;
+ } else {
this.problems.push(prob);
- this.seenProblems.add(prob.hash);
+ this.seenProblems.add(prob.phash);
return true;
}
- else {
- return false;
- }
},
addStats: function (stats) {