diff options
author | Rogan Creswick <creswick@gmail.com> | 2012-10-30 08:55:32 -0700 |
---|---|---|
committer | Rogan Creswick <creswick@gmail.com> | 2012-10-30 08:55:32 -0700 |
commit | 90c8a9c2f3340a4489f886aa6e4a7c9693639809 (patch) | |
tree | 58195bf0a5e1d2562ca28739eddbf9287ed68fbe | |
parent | 7d46321a04b0c07b66833e6cd803ecced696e3f7 (diff) | |
parent | 00b39d16630cad9699c0eda6f5e1cedc535c7805 (diff) |
Merge branch 'master' of src.galois.com:/srv/git/FiveUI
-rw-r--r-- | contexts/Makefile | 2 | ||||
-rw-r--r-- | contexts/data/fiveui/background.js | 10 | ||||
-rw-r--r-- | contexts/data/fiveui/firefox/main.js | 4 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/fiveui-injected-compute.js | 47 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/fiveui-injected-ui.js | 21 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/injected.css | 47 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/jquery-plugins.js | 52 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/prelude-test.html | 8 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/prelude-test.js | 66 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/prelude.js | 118 | ||||
-rw-r--r-- | contexts/data/fiveui/state.js | 18 |
11 files changed, 262 insertions, 131 deletions
diff --git a/contexts/Makefile b/contexts/Makefile index 972c386..2bac1e8 100644 --- a/contexts/Makefile +++ b/contexts/Makefile @@ -158,7 +158,7 @@ lint_excludes := lib/jquery.js # Run the linter over the project javascript sources. .PHONY: lint lint: - find . -name "*.js" | xargs $(cl_linter) --strict --exclude_files=$(lint_excludes) + find data/fiveui -name "*.js" | xargs $(cl_linter) --strict --exclude_files=$(lint_excludes) closurebuilder := $(CLOSURE_LIB)/closure/bin/build/closurebuilder.py \ --root=$(CLOSURE_LIB) --root=$(FIVEUI_DATA_DIR) \ diff --git a/contexts/data/fiveui/background.js b/contexts/data/fiveui/background.js index 6786db8..d73bc9e 100644 --- a/contexts/data/fiveui/background.js +++ b/contexts/data/fiveui/background.js @@ -27,7 +27,7 @@ goog.require('fiveui.State'); /** * @constructor - * + * * @param {!function(!string):!string} dataLoader */ fiveui.Background = function(settings, updateWidget, loadScripts, dataLoader) { @@ -62,6 +62,12 @@ fiveui.Background.prototype._registerComputeListeners = function(port, tabState) tabState.uiPort.emit('ShowProblem', problem); } }); + port.on('ReportStats', function (stats) { + if (tabState.addStats(stats) && tabState.uiPort != null) { + bg.updateWidget(tabState); + tabState.uiPort.emit('ShowStats', stats); + } + }); }; fiveui.Background.prototype._registerUiListeners = function(port, tabState){ @@ -195,7 +201,7 @@ fiveui.Background.prototype.showUI = function(tabId) { var tabState = this.state.getTabState(tabId); if(null == tabState) { return; - }; + } if(tabState.winState.closed) { tabState.winState.closed = false; diff --git a/contexts/data/fiveui/firefox/main.js b/contexts/data/fiveui/firefox/main.js index a96bc2e..dc6258c 100644 --- a/contexts/data/fiveui/firefox/main.js +++ b/contexts/data/fiveui/firefox/main.js @@ -185,8 +185,8 @@ fiveui.firefox.main = function() { { include: data.url('fiveui/options.html'), contentScriptWhen: 'end', contentScriptFile: [ - data.url("ace/ace.js"), - data.url("ace/mode-javascript.js"), + data.url("lib/ace/ace.js"), + data.url("lib/ace/mode-javascript.js"), data.url("target/firefox-options.js") ], contentScript: "fiveui.firefox.options.init()", diff --git a/contexts/data/fiveui/injected/fiveui-injected-compute.js b/contexts/data/fiveui/injected/fiveui-injected-compute.js index 0c931a4..b6a814f 100644 --- a/contexts/data/fiveui/injected/fiveui-injected-compute.js +++ b/contexts/data/fiveui/injected/fiveui-injected-compute.js @@ -84,6 +84,10 @@ core.port.emit('ReportProblem', prob); }; + core.reportStats = function(stats) { + core.port.emit('ReportStats', stats); + }; + core.hash = function(rule, name, node) { var prob = { name: name, @@ -119,27 +123,12 @@ }; core.evaluate = function(rs) { + var i; var theRule = null; + var date = new Date(); + var stats = { start: date.getTime(), end: null, numRules: 0, numElts: 0 }; + fiveui.stats.numElts = 0; // reset stats element counter - /** - * <p>Report a problem to FiveUI.</p> - * - * <p>report is used to indicate that a guideline has been violated. - * Invocations should provide a short (1-line) string description of - * the problem, as well as a reference to the element of the DOM that - * violated the guideline.</p> - * - * <p>The second parameter is not strictly required, but we strongly - * suggest providing a node if at all possible, as that is used to - * visually highlight the problematic areas of the DOM at runtime. - * Debugging a guideline violation becomes much more difficult without - * the visual indicator.</p> - * - * @function - * @param {!string} desc The description of the problem to report. - * @param {?Node} node The node in the DOM that caused the problem. - * @name report - */ var report = function(name, node) { var prob = core.hash(theRule, name, node); var query = $(node); @@ -149,13 +138,13 @@ } }; - for (var i=0 ; i < rs.length; ++i) { + for (i = 0; i < rs.length; i += 1) { theRule = rs[i]; try { var fn = eval('('+rs[i].ruleStr+')'); - } catch (x) { + } catch (e) { console.log('could not load ruleStr for rule: '+theRule.name); - console.log(x); + console.log(e); } var scope = { @@ -166,13 +155,19 @@ if (fn) { try { + // note: fiveui.stats.numElts is updated as a side effect here fn.apply(scope); - } catch (x) { + } catch (e) { console.log('exception running rule: '+theRule.name); - console.log(x); + console.log(e); } + stats.numRules += 1; } } + date = new Date(); + stats.end = date.getTime(); + stats.numElts = fiveui.stats.numElts; + core.reportStats(stats); }; /** @@ -212,9 +207,7 @@ function(e) { var eTagName = e.target.tagName; if (eTagName == 'IFRAME' || eTagName == 'FRAME') { - // console.log('frame added'); e.target.onload = function() { - // console.log('frame loaded'); core.scheduleRules(); registerDomListeners(e.target.contentDocument); }; @@ -235,5 +228,5 @@ }; registerBackendListeners(core.port); -})(); +}()); diff --git a/contexts/data/fiveui/injected/fiveui-injected-ui.js b/contexts/data/fiveui/injected/fiveui-injected-ui.js index 619aec0..b93e442 100644 --- a/contexts/data/fiveui/injected/fiveui-injected-ui.js +++ b/contexts/data/fiveui/injected/fiveui-injected-ui.js @@ -77,6 +77,18 @@ }); }; + core.renderStats = function (stats) { + core.maskRules(function () { + var statsDiv, statsDetail; + statsDiv = $('#fiveui-stats'); + statsDiv.children().remove(); + statsDetail = $('<table class="fiveui-table"><tr><td class="fiveui-table-text">rules checked:</td><td class="fiveui-table-number">' + stats.numRules + '</td></tr>' + + '<tr><td class="fiveui-table-text">elements checked:</td><td class="fiveui-table-number">' + stats.numElts + '</td></tr>' + + '<tr><td class="fiveui-table-text">elapsed time (ms):</td><td class="fiveui-table-number">' + (stats.end - stats.start) + '</td></tr></table>'); + statsDiv.append(statsDetail); + }); + }; + core.renderProblem = function(prob) { core.maskRules(function() { var probDiv = $('<div class="pr"></div>'); @@ -157,6 +169,10 @@ core.renderProblem(problem); }); + port.on('ShowStats', function(stats) { + core.renderStats(stats); + }); + port.on('RestoreUI', function(state) { core.ui.append($('<div id="controls"></div>')); @@ -180,6 +196,7 @@ $('#clearButton').click(function() { $('#problemList').children().remove(); port.emit('ClearProblems'); + core.renderStats(fiveui.stats.zero); core.maskProblem(fiveui.query('.uic-problem')); }); @@ -194,6 +211,7 @@ }); // //////////////////////////////////////////// + core.ui.append($('<div id="fiveui-stats"></div>')); if(!state.winState.closed) { core.ui.dialog('open'); @@ -202,7 +220,8 @@ $(state.problems).each(function(ix,prob) { core.renderProblem(prob); }); - }); + core.renderStats(state.stats); + }); }; registerBackendListeners(core.port); diff --git a/contexts/data/fiveui/injected/injected.css b/contexts/data/fiveui/injected/injected.css index 8137083..c862c19 100644 --- a/contexts/data/fiveui/injected/injected.css +++ b/contexts/data/fiveui/injected/injected.css @@ -25,16 +25,6 @@ border-color: red; } -/* p.solid {border-style: solid; } */ -/* p.double {border-style: double; } */ -/* p.groove {border-style: groove; } */ -/* p.dotted {border-style: dotted; } */ -/* p.dashed {border-style: dashed; } */ -/* p.inset {border-style: inset; } */ -/* p.outset {border-style: outset; } */ -/* p.ridge {border-style: ridge; } */ -/* p.hidden {border-style: hidden; } */ - /* Reduce the JQuery UI spacing on the left of the dialog content. */ #uic-dialog { padding-left: 3px; @@ -46,7 +36,7 @@ } .ui-dialog .ui-dialog-content { - overflow: hidden !important; + /* overflow: hidden !important; */ position: relative; } @@ -54,22 +44,43 @@ font-family: Courier; } +/* stats area style */ + +#fiveui-stats { + font-family: Courier; + font-size: 10px; + background-color: #F0F0F0; + border: 1px solid #DDDDDD; + border-style: groove; + padding: 3px; + height: 40px; + width: 97%; + margin-top: 0.5em; + margin-bottom: 0.75em; +} +.fiveui-table-number { + text-align: right; + color: blue; +} + +.fiveui-table-text { + text-align: left; + color: black; + padding-right: 3px; +} -/* #listWrapper { */ -/* overflow: auto; */ -/* position: relative */ -/* top: 0px; */ -/* bottom: 0px; */ -/* } */ +/* problem list style */ #problemList { border-style: groove; background: white; + /* position: absolute; - top: 49px; + top: 95px; bottom: 0px; + */ /* coarse estimate of width in most standard sizes */ width: 97%; diff --git a/contexts/data/fiveui/injected/jquery-plugins.js b/contexts/data/fiveui/injected/jquery-plugins.js index 06c4b4a..23403f7 100644 --- a/contexts/data/fiveui/injected/jquery-plugins.js +++ b/contexts/data/fiveui/injected/jquery-plugins.js @@ -31,25 +31,11 @@ if (typeof goog != 'undefined') { */ fiveui.jqueryPlugins = fiveui.jqueryPlugins || {}; -/** - * Provide a short alias for fiveui.query along the lines of the jQuery $ alias. - * - * <p><pre> - * EXAMPLES: - * - * $5("p").hasText("foo") -> jQuery object containing paragraph elements - * containing the text "foo" - * </pre></p> - * - * @const - * - */ -var $5 = fiveui.query; /** * Simple proof of concept plugin * - * @return {!object} A modified jQuery object + * @returns {!Object} A modified jQuery object */ fiveui.jqueryPlugins.myPlugin = function () { return this.css("border-style", "solid").css("border-color", "red"); @@ -58,8 +44,8 @@ fiveui.jqueryPlugins.myPlugin = function () { /** * Wrapper for the :contains('text') selector * - * @param {!string} text Text to select for - * @return {!object} A modified jQuery object + * @param {!String} text Text to select for + * @returns {!Object} A modified jQuery object */ fiveui.jqueryPlugins.hasText = function (text) { return this.filter(":contains('" + text + "')") @@ -69,12 +55,12 @@ fiveui.jqueryPlugins.hasText = function (text) { * Color checker plugin: filters for elements whose CSS color property is * not in the given set. * - * Note: This is a special case of fiveui.jqueryPlugins.cssIsNot, i.e. - * $(..).notColorSet(set) == $(..).cssIsNot("color", set, fiveui.color.colorToHex) - * @see {fiveui.color.colorToHex} + * @description Note: This is a special case of fiveui.jqueryPlugins.cssIsNot, i.e. + * $(..).notColorSet(set) == $(..).cssIsNot("color", set, fiveui.color.colorToHex) + * @see {fiveui.color.colorToHex} * - * @param {Array.<string>} cset A set of allowable color strings - * @return {!object} A modified jQuery object + * @param {String[]} cset A set of allowable color strings + * @returns {!Object} A modified jQuery object */ fiveui.jqueryPlugins.notColorSet = function (cset) { var allowable = {}; @@ -88,15 +74,15 @@ fiveui.jqueryPlugins.notColorSet = function (cset) { /** * General CSS propetry checker plugin * - * This plugin filters for elements whose CSS property `prop` is not a member + * @description This plugin filters for elements whose CSS property `prop` is not a member * of the given array `cset`. The values checked are transformed using the * optional given function `fn`. This may be used to normalize values that the * browser returns so they can be compared to values in `cset`. * - * @param {string} prop CSS property selector - * @param {string, Array.<string>} set allowable values (either a string or an array of strings) - * @param {function(string):string=} fn Function to apply to return values of $(this).css(prop), fn defaults to the identity function. - * @return{Object} jQuery object + * @param {String} prop CSS property selector + * @param {String|String[]} set allowable values (either a string or an array of strings) + * @param {function(String):String} [fn] Function to apply to return values of $(this).css(prop), fn defaults to the identity function. + * @returns {Object} jQuery object */ fiveui.jqueryPlugins.cssIsNot = function (prop, set, fn) { var allowable = {}; @@ -117,7 +103,7 @@ fiveui.jqueryPlugins.cssIsNot = function (prop, set, fn) { * Send a report to FiveUI reporting a problem with each element in the * jQuery object. * - * @param{string} msg Message to report + * @param {!String} msg Message to report */ fiveui.jqueryPlugins.report = function (msg) { this.each(function (i, elt) { @@ -128,8 +114,8 @@ fiveui.jqueryPlugins.report = function (msg) { /** * Visually highlight elements in the jQuery object (mostly for debugging purposes). * - * @param {?string=} hint Highlighted border color, defaults to "red" - * @return {!Object} A modified jQuery object + * @param {String} [hint] Highlighted border color, defaults to "red" + * @returns {!Object} A modified jQuery object */ fiveui.jqueryPlugins.highlight = function (hint) { hint = hint || "red"; // Default is "red" @@ -143,9 +129,9 @@ fiveui.jqueryPlugins.highlight = function (hint) { * object have. This is useful for analysis of a given page when * writing guielines. * - * @param {!string} prop CSS property to be inspected - * @param {bool=} log Boolean which enables console logging of the result; default is `false`. - * @return {Object.<string, number>} A frequence map { "property": frequency } + * @param {String} prop CSS property to be inspected + * @param {boolean} [log] Boolean which enables console logging of the result; default is `false`. + * @returns {Object} A frequence map { "property": frequency } */ fiveui.jqueryPlugins.propDist = function (prop, log) { var res = {}; diff --git a/contexts/data/fiveui/injected/prelude-test.html b/contexts/data/fiveui/injected/prelude-test.html index c33a85f..4234e4a 100644 --- a/contexts/data/fiveui/injected/prelude-test.html +++ b/contexts/data/fiveui/injected/prelude-test.html @@ -22,10 +22,18 @@ <head> <script src="../../lib/closure-library/closure/goog/base.js"></script> <script src="../../target/deps.js"></script> + <script src="../../lib/jquery/jquery-1.7.1.min.js"></script> <script src="prelude.js"></script> <script src="../test-wrapper.js"></script> <script src="prelude-test.js"></script> </head> <body onload="runTests()"> + + <!-- getFontTests --> + <p id="getFontTest1" style="font-family: Arial; font-weight: normal; font-size: 12px">FontTest1</p> + <p id="getFontTest2" style="font-family: Arial sans-serif; font-weight: normal; font-size: 12px">FontTest2</p> + <p id="getFontTest3" style="font-family: Arial; font-weight: bold; font-size: 12px">FontTest3</p> + <p id="getFontTest4" style="font-family: Verdana; font-weight: bold; font-size: 12">FontTest4</p> + </body> </html> diff --git a/contexts/data/fiveui/injected/prelude-test.js b/contexts/data/fiveui/injected/prelude-test.js index f911419..b093f97 100644 --- a/contexts/data/fiveui/injected/prelude-test.js +++ b/contexts/data/fiveui/injected/prelude-test.js @@ -35,21 +35,18 @@ var runTests = function() { var gt = goog.testing; var ga = goog.asserts; - - - var test = new Test('Prelude tests'); test.setUp(function() { }); var isStringTests = [ + // name , input , oracle ['isString: undefined', undefined, false], - ['isString: null' , null, false], - ['isString: a string' , 'str', true] + ['isString: null' , null, false], + ['isString: a string' , 'str', true] ]; test.addTestSet(fiveui.isString, isStringTests); var trimTests = [ - // name , input , oracle ['string.trim leading space' , ' str', 'str'], ['string.trim on null' , null, null], ['string.trim trailing space' , 'str ', 'str'], @@ -140,5 +137,62 @@ var runTests = function() { ]; test.addTestSet(fiveui.color.colorToHex, colorToHexTests); + // fiveui.font API tests + var getFontTests = [ + // CSS ID, Family, Weight, Size + ['#getFontTest1', 'Arial', 'normal', '12'], + ['#getFontTest2', 'Arial sans-serif', 'normal', '12'], + ['#getFontTest3', 'Arial', 'bold', '12'], + ['#getFontTest4', 'Verdana', 'bold', '12'] + ]; + goog.structs.forEach(getFontTests, function (spec) { + var desc = spec[0]; + test.add(desc, function() { + var jElt = $5(spec[0]); + var font = fiveui.font.getFont(jElt); + if (font.family.indexOf(spec[1]) === -1) { + goog.asserts.fail(spec[0]+': got wrong family: ' + font.family + + ' expected: ' + spec[1]); + } + if (font.weight.indexOf(spec[2]) === -1) { + goog.asserts.fail(spec[0]+': got wrong weight: ' + font.weight); + } + if (font.size.indexOf(spec[3]) === -1) { + goog.asserts.fail(spec[0]+': got wrong size: ' + font.size); + } + }); + }); + + // fiveui.font.validate API tests + var validateTests = + // name, allow, font, oracle + [ ['a:verdana-bold-10 f:verdana+sans-bold-10', {'Verdana':{'bold':[10]}}, + {'family':'Verdana sans-serif', 'weight':'bold', 'size':'10'}, + true ] + , ['a:verdana-normal-12 f:verdana+sans-bold-10', {'Verdana':{'normal':[12]}}, + {'family':'Verdana sans-serif', 'weight':'bold', 'size':'10'}, + false ] + , ['a:arial-normal-12 f:verdana+sans-bold-10', {'Arial':{'normal':[12]}}, + {'family':'Verdana sans-serif', 'weight':'bold', 'size':'10'}, + false ] + , ['a:verdana-normal-10,12,14 f:verdana-normal-14', {'Verdana':{'normal':[10, 12, 14]}}, + {'family':'Verdana', 'weight':'normal', 'size':'14'}, + true ] + , ['a:verdana-normal,bold-12 f:verdana-bold-12', {'Verdana':{'normal':[12], 'bold':[12]}}, + {'family':'Verdana', 'weight':'bold', 'size':'12'}, + true ] + , ['a:verdana,arial-normal-12 f:arial-normal-12', {'Verdana':{'normal':[12]}, 'Arial':{'normal':[12]}}, + {'family':'Arial', 'weight':'normal', 'size':'12'}, + false ] + ]; + goog.structs.forEach(validateTests, function (spec) { + var desc = spec[0]; + test.add(desc, function () { + if (fiveui.font.validate(spec[1], spec[2]) !== spec[3]) { + goog.asserts.fail(spec[0] + 'Font did not validate'); + } + }); + }); + test.run(); }; diff --git a/contexts/data/fiveui/injected/prelude.js b/contexts/data/fiveui/injected/prelude.js index 6d86126..5eb8d25 100644 --- a/contexts/data/fiveui/injected/prelude.js +++ b/contexts/data/fiveui/injected/prelude.js @@ -31,6 +31,7 @@ if (typeof goog != 'undefined') { /** * The FiveUI Prelude. * + * @description * The prelude provides a collection of utilities to ease the * conversion from human-readable guideline documents (such as the Web * Accessibilty Guidelines, or Apple Human Interface Guidelines) to @@ -40,11 +41,23 @@ if (typeof goog != 'undefined') { */ fiveui = fiveui || {}; +/** + * A global namespace for statistics collection. + * + * @namespace + */ +fiveui.stats = fiveui.stats || {}; +/** @global */ +fiveui.stats.numElts = 0; +/** @const */ +fiveui.stats.zero = { numRules: 0, start: 0, end: 0, numElts: 0 }; + /** DOM Traversal ************************************************************/ /** * fiveui.query is a wrapper around the jQuery $() function. * + * @description * fiveui.query recurses into iframes and frames, whereas $(...) stops * when it encounters internal frames. * @@ -52,9 +65,9 @@ fiveui = fiveui || {}; * visible page, and as such, should use fiveui.query; however, $(...) * is available if recursing into frames is not necessary. * - * @param {string} sel The jQuery selector string. - * @param {?Object} context Optional: The context to run the query within. This is often a DOM object/tree. - * @return {Object} A jQuery object, suitable for chaining. + * @param {String} sel The jQuery selector string. + * @param {Object} [context] The context to run the query within. This is often a DOM object/tree. + * @returns {Object} A jQuery object, suitable for chaining. */ fiveui.query = function (sel, context) { var ctx = context || document; @@ -68,15 +81,30 @@ fiveui.query = function (sel, context) { } ); - return $results.not('#uic-top').filter(':visible'); + // update global stats + $filteredResults = $results.not('#uic-top').filter(':visible'); + fiveui.stats.numElts += $filteredResults.length; + return $filteredResults; }; +/** + * Provide a short alias for fiveui.query along the lines of the jQuery $ alias. + * + * @example $5("p").hasText("foo") -> jQuery object containing paragraph elements + * containing the text "foo" + * </pre></p> + * + * @const + * + */ +var $5 = fiveui.query; + /** Utilities ****************************************************************/ /** * Determine if a given value is a string or not. * - * @param {?*} o A value of some type that may or may not be defined. + * @param {*} [o] A value of some type that may or may not be defined. * @returns {!boolean} true if the object is a defined, non-null string, false * otherwise. */ @@ -96,8 +124,8 @@ fiveui.string = {}; * Non-destructively removes whitespace from the start and end of a * string. * - * @param {?string} s The string to trim of whitespace. - * @return {?string} The input string, without leading or trailing + * @param {String} [s] The string to trim of whitespace. + * @returns {String} The input string, without leading or trailing * whitespace. Returns null if you gave it null. */ fiveui.string.trim = function(s) { @@ -110,8 +138,8 @@ fiveui.string.trim = function(s) { /** * Tokenize a string on whitespace. * - * @param {!string} s The string to tokenize. - * @return {!Array.<!string>} An array of substrings. + * @param {!String} s The string to tokenize. + * @returns {String[]>} An array of substrings. */ fiveui.string.tokens = function (s) { var posLength = function(ar) { @@ -125,12 +153,13 @@ fiveui.string.tokens = function (s) { /** * A simple heuristic check to see if a string is in Title Case. * + * @description * This does not perform an exhaustive gramatical analysis, and as * such, it is prone to generating false-positives in some cases. In * particular, it only has a short 'white list' of articles, * conjections, and prepositions that are allowed to be in lower case. * - * @param {!string} str The string to check. + * @param {!String} str The string to check. * @returns {!boolean} true if the string is in title case, false if * it is not. */ @@ -159,7 +188,7 @@ fiveui.string.isTitleCase = function(str) { /** * Utilities for word-specific processing. * - * The fiveui.word namespace focuses on tools for working directly + * @description The fiveui.word namespace focuses on tools for working directly * with words in the sense of natural languages, rather than general * strings (as is the case for the fiveui.string namespace). * @@ -170,7 +199,7 @@ fiveui.word = {}; /** * Check to see if a sting begins with a capital letter. * - * @param {!string} word The string to check for capitalization. + * @param {!String} word The string to check for capitalization. * @returns {!boolean} */ fiveui.word.capitalized = function(word) { @@ -180,7 +209,7 @@ fiveui.word.capitalized = function(word) { /** * Check to see if a sting consists entirely of capital letters. * - * @param {!string} word The string to check for capitalization. + * @param {!String} word The string to check for capitalization. * @returns {!boolean} */ fiveui.word.allCaps = function(word) { @@ -201,10 +230,10 @@ fiveui.color = {}; * Color check compiler. It is recommended to use the jQuery plugin * fiveui.jqueryPlugins.cssIsNot instead. * - * @param {!string} selector The HTML element selector to check. - * @param {!array} colorSet An array of strings containing the HEX values of + * @param {!String} selector The HTML element selector to check. + * @param {String[]} colorSet An array of strings containing the HEX values of * colors in the desired color set. - * @returns {!function} A function which checks the rule + * @returns {!function()} A function which checks the rule * @see fiveui.jqueryPlugins.cssIsNot */ fiveui.color.colorCheck = function (selector, colorSet) { @@ -227,8 +256,8 @@ fiveui.color.colorCheck = function (selector, colorSet) { * Covert rgb colors to hex and abreviated hex colors to their full 3 byte * form. * - * @param {!string} color The color string to convert. This should be either of the form rgb(...) or #... - * @returns {!string} The color string in #XXXXXX form + * @param {!String} color The color string to convert. This should be either of the form rgb(...) or #... + * @returns {!String} The color string in #XXXXXX form * @throws {ParseError} if the rgb color string cannot be parsed */ fiveui.color.colorToHex = function(color) { @@ -251,8 +280,8 @@ fiveui.color.colorToHex = function(color) { var digits = /rgba?\((\d+), (\d+), (\d+)/.exec(color); if (!digits) { throw { - name: 'ParseError', - message: 'Could not parse rgb color: ' + color + 'name': 'ParseError', + 'message': 'Could not parse rgb color: ' + color }; } @@ -281,47 +310,61 @@ fiveui.font = {}; * Extracts the font-family, font-size (in px, as an int), and font-weight * from a jQuery object. * - * @param {!object} jElt A jQuery object to extract font info from - * @returns {!object} An object with properties: 'family', 'size', and 'weight' + * @param {!Object} jElt A jQuery object to extract font info from + * @returns {!Object} An object with properties: 'family', 'size', and 'weight' * @throws {ParseError} if the font size cannot be parsed */ fiveui.font.getFont = function (jElt) { var res = {}; var sizeTxt = /(\d+)/.exec(jElt.css('font-size')); if (!sizeTxt) { - throw { name: 'ParseError', message: 'Could not parse font size: ' + jElt.css('font-size') }; + throw { + name: 'ParseError', + message: 'Could not parse font size: ' + jElt.css('font-size') + }; } else { res.size = sizeTxt[1]; } res.family = jElt.css('font-family'); res.weight = jElt.css('font-weight'); + // normalize reporting of the following two synonyms + if (res.weight === '400') { res.weight = 'normal'; } + if (res.weight === '700') { res.weight = 'bold'; } return res; -} +}; /** - * Validate a font property object extracted using fiveui.font.getFont + * Validate a font property object extracted using fiveui.font.getFont(). * - * <p><pre> - * EXAMPLES:: + * @description The `allow` parameter should be an object whose top level properties are + * (partial) font family names (e.g. 'Verdana'). For each font family name + * there should be an object whose properties are font weights (e.g. 'bold'), + * and for each font weight there should be an array of allowable sizes + * (e.g. [10, 11, 12]). * - * > allow = { 'Verdana': { 'bold': {"10":{}, "12":{}}, 'normal': {"10":{}, "12":{}} } }; - * > font = { family: 'Verdana Arial sans-serif', size: "10", weight: "normal" }; - * > fiveui.font.validate(allow, font) -> true - * </pre></p> + * The `font` parameter should be an object containing 'family', 'weight', and + * 'size' properties. These are returned by @see fiveui.font.getFont(). + * + * @example > allow = { 'Verdana': { 'bold': [10, 12], 'normal': [10, 12]}}; + * > font = { family: 'Verdana Arial sans-serif', size: "10", weight: "normal" }; + * > fiveui.font.validate(allow, font) -> true * - * @param {!object} allow Object containing allowable font sets (see EXAMPLES) - * @param {!object} font object to check + * @param {!Object} allow Object containing allowable font sets (see description and examples) + * @param {!Object} font object to check + * @param font.family A partial font family name (e.g. 'Verdana') + * @param font.weight A font weight (e.g. 'bold') + * @param font.size A font size string (e.g. "10") * @returns {!boolean} */ fiveui.font.validate = function (allow, font) { var x; for (x in allow) { // loop over allowed font family keywords - if (font.family.indexOf(x) != -1) { break; } + if (font.family.indexOf(x) !== -1) { break; } else { return false; } } - return (font.weight in allow[x] && font.size in allow[x][font.weight]); -} + return (font.weight in allow[x] && allow[x][font.weight].indexOf(parseInt(font.size)) != -1); +}; /** * Functions outside the fiveui namespace that can be called during rule @@ -331,6 +374,7 @@ fiveui.font.validate = function (allow, font) { /** * <p>Report a problem to FiveUI.</p> * + * @description * <p>report is used to indicate that a guideline has been violated. * Invocations should provide a short (1-line) string description of * the problem, as well as a reference to the element of the DOM that @@ -343,7 +387,7 @@ fiveui.font.validate = function (allow, font) { * the visual indicator.</p> * * @function - * @param {!string} desc The description of the problem to report. + * @param {!String} desc The description of the problem to report. * @param {?Node} node The node in the DOM that caused the problem. * @name report */ diff --git a/contexts/data/fiveui/state.js b/contexts/data/fiveui/state.js index b1d99a0..4537a1b 100644 --- a/contexts/data/fiveui/state.js +++ b/contexts/data/fiveui/state.js @@ -80,6 +80,7 @@ fiveui.TabState = function(tabId, winState, uiPort) { this.computePorts = []; this.problems = []; this.seenProblems = new goog.structs.Set(); + this.stats = {}; }; fiveui.TabState.prototype.addProblem = function(prob) { @@ -87,24 +88,33 @@ fiveui.TabState.prototype.addProblem = function(prob) { this.problems.push(prob); this.seenProblems.add(prob.hash); return true; - } else { + } + else { return false; } }; +fiveui.TabState.prototype.addStats = function (stats) { + this.stats = stats; + return true; +}; + fiveui.TabState.prototype.clearProblems = function() { this.problems = []; this.seenProblems = new goog.structs.Set(); }; +fiveui.TabState.prototype.clearStats = function() { + for (var p in fiveui.stats.zero) { this.stats[p] = fiveui.stats.zero[p]; } +}; + /* * Returns a copy of only the attributes in a TabState that are needed for * interpage communication. */ fiveui.TabState.prototype.toEmit = function() { - // return jQuery.extend(true, {}, { winState: this.winState, problems: this.problems }); - return { winState: this.winState, problems: this.problems }; -} + return { winState: this.winState, problems: this.problems, stats: this.stats }; +}; /** * @constructor |