diff options
author | Trevor Elliott <trevor@galois.com> | 2013-06-27 11:07:38 -0700 |
---|---|---|
committer | Trevor Elliott <trevor@galois.com> | 2013-06-27 11:07:38 -0700 |
commit | 3378c9fd490f2be86425f13cbd9ece7f9ac31026 (patch) | |
tree | 668342d4b469226119cff701ab2bc3351a07dac7 | |
parent | 899930095f519c19da9e379053a8557fbb7cff29 (diff) |
Keep elements highlighted when at least one problem is toggled
-rw-r--r-- | src/js/fiveui/injected/compute.js | 27 | ||||
-rw-r--r-- | src/js/fiveui/injected/ui.js | 63 | ||||
-rw-r--r-- | src/js/fiveui/js/state.js | 61 |
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) { |