aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Jones <bjones@galois.com>2012-10-23 11:42:28 -0700
committerGravatar Benjamin Jones <bjones@galois.com>2012-10-23 11:42:28 -0700
commit658da03955fd69a2eb9d33972a832877f3fcbf56 (patch)
treef1fa6d2715cdd1aec56f80acae6850ba8139d3e3
parent365412727345ab3619958e120bab982fddcdf9e7 (diff)
parent904c26f350a44e4906cf0a25cd363930047cf897 (diff)
Merge branch 'wip'
-rw-r--r--contexts/data/fiveui/background.js6
-rw-r--r--contexts/data/fiveui/injected/injected.css6
-rw-r--r--contexts/data/fiveui/injected/jquery-plugins.js182
-rw-r--r--contexts/data/fiveui/injected/prelude.js102
-rw-r--r--doc/Makefile4
-rw-r--r--exampleData/basic/testFontRules.html16
-rw-r--r--rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java2
7 files changed, 303 insertions, 15 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
+ */
diff --git a/doc/Makefile b/doc/Makefile
index fb2fecb..e9539c1 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -5,8 +5,8 @@ MAN_DEPS=$(MANUAL_SRC)/*.md $(MANUAL_SRC)/figures/*.png
jsdoc-toolkit=../build/jsdoc
-jsdoc: ../contexts/data/fiveui/injected/prelude.js
- @$(jsdoc-toolkit) ../contexts/data/fiveui/injected/prelude.js
+jsdoc: ../contexts/data/fiveui/injected/prelude.js ../contexts/data/fiveui/injected/jquery-plugins.js
+ @$(jsdoc-toolkit) ../contexts/data/fiveui/injected/prelude.js ../contexts/data/fiveui/injected/jquery-plugins.js
.PHONY: man
man: web-manual
diff --git a/exampleData/basic/testFontRules.html b/exampleData/basic/testFontRules.html
index 0de8fd5..3bea3f4 100644
--- a/exampleData/basic/testFontRules.html
+++ b/exampleData/basic/testFontRules.html
@@ -10,8 +10,20 @@
This is Verdana / Bold / 12px
</p>
- <p style="font-size: 150%">
- This is inherited font at 150%
+ <p style="font-family: Verdana; font-size: 150%">
+ This is Verdana font at 150%
+ </p>
+
+ <p style="font-family: Times;">
+ This is Times font
+ </p>
+
+ <p style="font-family: Times; font-size: 150%">
+ This is Times font at 150%
+ </p>
+
+ <p style="font-family: Times; font-size: 36px">
+ This is Times font at 36pt
</p>
</body>
diff --git a/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java b/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java
index 0ccdf9a..53e09d1 100644
--- a/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java
+++ b/rsTester/src/main/java/com/galois/fiveui/RSTestDescription.java
@@ -25,7 +25,7 @@ import com.google.gson.JsonParseException;
/**
* RSTestDescriptions represent a set of tests for a specific RuleSet.
*
- * RSTestDescriptions are also GSON-serializiable (and deserializable).
+ * RSTestDescriptions are also JSON-serializiable (and deserializable).
*
* An example of the JSON is given below:
*