diff options
author | Benjamin Jones <bjones@galois.com> | 2012-10-23 11:42:28 -0700 |
---|---|---|
committer | Benjamin Jones <bjones@galois.com> | 2012-10-23 11:42:28 -0700 |
commit | 658da03955fd69a2eb9d33972a832877f3fcbf56 (patch) | |
tree | f1fa6d2715cdd1aec56f80acae6850ba8139d3e3 /contexts/data/fiveui | |
parent | 365412727345ab3619958e120bab982fddcdf9e7 (diff) | |
parent | 904c26f350a44e4906cf0a25cd363930047cf897 (diff) |
Merge branch 'wip'
Diffstat (limited to 'contexts/data/fiveui')
-rw-r--r-- | contexts/data/fiveui/background.js | 6 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/injected.css | 6 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/jquery-plugins.js | 182 | ||||
-rw-r--r-- | contexts/data/fiveui/injected/prelude.js | 102 |
4 files changed, 286 insertions, 10 deletions
diff --git a/contexts/data/fiveui/background.js b/contexts/data/fiveui/background.js index dd95ed3..6786db8 100644 --- a/contexts/data/fiveui/background.js +++ b/contexts/data/fiveui/background.js @@ -147,7 +147,8 @@ fiveui.Background.prototype.pageLoad = function(tabId, url, data) { var computeScripts = goog.array.concat( [ this.dataLoader('lib/jquery/jquery-1.7.1.min.js') , this.dataLoader('fiveui/injected/prelude.js') - , this.dataLoader('lib/jshash/md5.js') ], + , this.dataLoader('lib/jshash/md5.js') + , this.dataLoader('fiveui/injected/jquery-plugins.js') ], dependencies, [ this.dataLoader('fiveui/injected/fiveui-injected-compute.js') @@ -160,7 +161,8 @@ fiveui.Background.prototype.pageLoad = function(tabId, url, data) { this.dataLoader('lib/jquery/jquery-1.7.1.min.js'), this.dataLoader('lib/jquery/jquery-ui-1.8.17.custom.min.js'), this.dataLoader('fiveui/injected/prelude.js'), - this.dataLoader('fiveui/injected/fiveui-injected-ui.js') + this.dataLoader('fiveui/injected/fiveui-injected-ui.js'), + this.dataLoader('fiveui/injected/jquery-plugins.js') ]); this.loadScripts(tabId, uiScripts, false, data); } diff --git a/contexts/data/fiveui/injected/injected.css b/contexts/data/fiveui/injected/injected.css index 100963e..8137083 100644 --- a/contexts/data/fiveui/injected/injected.css +++ b/contexts/data/fiveui/injected/injected.css @@ -19,7 +19,11 @@ * limitations under the License. */ -.uic-problem {} +.uic-problem { + background-color: rgba(255, 0, 0, 0.3); + border: 2px solid; + border-color: red; +} /* p.solid {border-style: solid; } */ /* p.double {border-style: double; } */ diff --git a/contexts/data/fiveui/injected/jquery-plugins.js b/contexts/data/fiveui/injected/jquery-plugins.js new file mode 100644 index 0000000..06c4b4a --- /dev/null +++ b/contexts/data/fiveui/injected/jquery-plugins.js @@ -0,0 +1,182 @@ +/* + * Module : injected/jquery-plugins.js + * Copyright : (c) 2011-2012, Galois, Inc. + * + * Maintainer : + * Stability : Provisional + * Portability: Portable + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +if (typeof goog != 'undefined') { + goog.provide('fiveui.jqueryPlugins'); +} + +/** + * This module provides several useful jQuery plugins related to checking and reporting + * UI consistency issues. + * + * @namespace + */ +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 + */ +fiveui.jqueryPlugins.myPlugin = function () { + return this.css("border-style", "solid").css("border-color", "red"); +} + +/** + * Wrapper for the :contains('text') selector + * + * @param {!string} text Text to select for + * @return {!object} A modified jQuery object + */ +fiveui.jqueryPlugins.hasText = function (text) { + return this.filter(":contains('" + 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} + * + * @param {Array.<string>} cset A set of allowable color strings + * @return {!object} A modified jQuery object + */ +fiveui.jqueryPlugins.notColorSet = function (cset) { + var allowable = {}; + for (var i = 0; i < cset.length; i += 1) { allowable[cset[i]] = true; } // array -> object + return this.filter(function (index) { + var color = fiveui.color.colorToHex($(this).css("color")); // .css("color") returns rgb(...) + return !(color in allowable); + }); +} + +/** + * General CSS propetry checker plugin + * + * 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 + */ +fiveui.jqueryPlugins.cssIsNot = function (prop, set, fn) { + var allowable = {}; + fn = fn || function (x) { return x; }; // default is Id + if (typeof set === "string") { + allowable[fn(set)] = true; + } + else { // assume `set` is an array of strings + for (var i = 0; i < set.length; i += 1) { allowable[fn(set[i])] = true; } // array -> object + } + return this.filter(function (index) { + var cssProp = fn($(this).css(prop)); + return !(cssProp in allowable); + }); +} + +/** + * Send a report to FiveUI reporting a problem with each element in the + * jQuery object. + * + * @param{string} msg Message to report + */ +fiveui.jqueryPlugins.report = function (msg) { + this.each(function (i, elt) { + report(msg, elt); // NOTE: this doesn't work. report() is not in scope here! + }); +} + +/** + * 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 + */ +fiveui.jqueryPlugins.highlight = function (hint) { + hint = hint || "red"; // Default is "red" + return this.css("background-color", "rgba(255, 0, 0, 0.3)") + .css("border-style", "solid") + .css("border-color", hint); +} + +/** + * Returns a list of css properties that element in the jQuery + * 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 } + */ +fiveui.jqueryPlugins.propDist = function (prop, log) { + var res = {}; + log = log || false; + this.each(function (i, elt) { + var p = $(elt).css(prop); + if (p in res) { + res[p] += 1; + } + else { + res[p] = 1; + } + }); + if (log) { + console.log("Property distribution:"); + for (var p in res) { + console.log(" " + p + ": " + res[p]); + } + } + return res; +} + +/** + * Register the plugins. This adds methods to the jQuery.fn namespace. + */ +fiveui.jqueryPlugins.init = function () { + for (fn in fiveui.jqueryPlugins) { + f = fiveui.jqueryPlugins[fn]; + if (jQuery.isFunction(f) && fn != "init") { + jQuery.fn[fn] = fiveui.jqueryPlugins[fn]; + } + } +} +fiveui.jqueryPlugins.init(); diff --git a/contexts/data/fiveui/injected/prelude.js b/contexts/data/fiveui/injected/prelude.js index 4e37148..6d86126 100644 --- a/contexts/data/fiveui/injected/prelude.js +++ b/contexts/data/fiveui/injected/prelude.js @@ -179,6 +179,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. * @returns {!boolean} */ @@ -196,11 +197,15 @@ fiveui.word.allCaps = function(word) { */ fiveui.color = {}; -/* Color check compiler. +/** + * 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 * colors in the desired color set. * @returns {!function} A function which checks the rule + * @see fiveui.jqueryPlugins.cssIsNot */ fiveui.color.colorCheck = function (selector, colorSet) { var allowable, i, fnStr, forEachFuncStr; @@ -218,7 +223,14 @@ fiveui.color.colorCheck = function (selector, colorSet) { // function expression ?!? }; -/* covert rgb(a) colors to hex */ +/** + * 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 + * @throws {ParseError} if the rgb color string cannot be parsed + */ fiveui.color.colorToHex = function(color) { var have, need; if (color.substr(0, 1) === '#') { @@ -230,16 +242,23 @@ fiveui.color.colorToHex = function(color) { var haveDigits = color.substr(1, color.length); var need = 6 - have; var reps = Math.ceil(need / have); + var i, strColor; for (i = 0, stdColor = color; i < reps; i += 1) { stdColor += haveDigits; } return stdColor.substr(0, 7); } } - var digits = /rgb(a)?\((\d+), (\d+), (\d+)/.exec(color); + var digits = /rgba?\((\d+), (\d+), (\d+)/.exec(color); + if (!digits) { + throw { + name: 'ParseError', + message: 'Could not parse rgb color: ' + color + }; + } - var red = parseInt(digits[2]); - var green = parseInt(digits[3]); - var blue = parseInt(digits[4]); + var red = parseInt(digits[1]); + var green = parseInt(digits[2]); + var blue = parseInt(digits[3]); var rgb = blue | (green << 8) | (red << 16); if (rgb === 0) { @@ -252,10 +271,79 @@ fiveui.color.colorToHex = function(color) { /** - * Utilities for dealing with font. + * Utilities for dealing with fonts. * * @namespace */ 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' + * @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') }; + } + else { + res.size = sizeTxt[1]; + } + res.family = jElt.css('font-family'); + res.weight = jElt.css('font-weight'); + return res; +} + +/** + * Validate a font property object extracted using fiveui.font.getFont + * + * <p><pre> + * EXAMPLES:: + * + * > 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> + * + * @param {!object} allow Object containing allowable font sets (see EXAMPLES) + * @param {!object} font object to check + * @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; } + else { return false; } + } + return (font.weight in allow[x] && font.size in allow[x][font.weight]); +} + +/** + * Functions outside the fiveui namespace that can be called during rule + * evaluation. + */ +/** + * <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 + */ |