diff options
author | Benjamin Jones <bjones@galois.com> | 2013-07-16 14:59:45 -0700 |
---|---|---|
committer | Benjamin Jones <bjones@galois.com> | 2013-07-16 14:59:45 -0700 |
commit | f1d4987e44a5ba3e66bf724d264ef2a57b82b775 (patch) | |
tree | 92b0bb138bc8a15cf550dea0957b56d1432f2732 | |
parent | 9d0ce00fb2421d32643455c60df6822cd11b27b4 (diff) | |
parent | e089832e50c87a79a9872009fd47231473d81b7a (diff) |
Merge branch 'master' into new-ui
-rw-r--r-- | src/js/fiveui/injected/jquery-plugins.js | 61 | ||||
-rw-r--r-- | src/js/fiveui/injected/prelude.js | 35 | ||||
-rw-r--r-- | src/js/tests/PhantomJSJasmineRunner.html | 3 | ||||
-rw-r--r-- | src/js/tests/SpecRunner.html | 2 | ||||
-rw-r--r-- | src/js/tests/specs/jquery-plugins.js | 135 |
5 files changed, 216 insertions, 20 deletions
diff --git a/src/js/fiveui/injected/jquery-plugins.js b/src/js/fiveui/injected/jquery-plugins.js index a7dedbd..a8c99f2 100644 --- a/src/js/fiveui/injected/jquery-plugins.js +++ b/src/js/fiveui/injected/jquery-plugins.js @@ -33,6 +33,10 @@ fiveui.jquery = fiveui.jquery || {}; /** * Wrapper for the :contains('text') selector * + * Example: + * + * $('div').hasText('to remove').remove(); + * * @param {!String} text Text to select for * @returns {!Object} A modified jQuery object */ @@ -41,6 +45,42 @@ fiveui.jquery.hasText = function (text) { }; /** + * Filter for elements which lack of the given attribute. + * + * Example: + * + * This object will be non-empty: + * + * $('<table></table>').noAttr('summary') + * + * @param {!String} attribute name + * @returns {!Object} a filtered jQuery object + */ +fiveui.jquery.noAttr = function (name) { + return this.filter(function () { + $attr = $.trim($(this).attr(name)); + return $attr == undefined || $attr == ''; + }); +}; + + +/** + * Filter for elements having no sub-elements matching the given selector. + * + * Example: the following should contain no elements + * + * $('<div><p>hello</p></div>').noSubElt('p') + * + * @param {!String} sel a jQuery selector + * @param {!Object} A filtered jQuery object + */ +fiveui.jquery.noSubElt = function (sel) { + return this.filter(function () { + return $(this).find(sel).length == 0; + }); +}; + +/** * Color checker plugin: filters for elements whose CSS color property is * not in the given set. * @@ -48,17 +88,20 @@ fiveui.jquery.hasText = function (text) { * $(..).notColorSet(set) == $(..).cssIsNot("color", set, fiveui.color.colorToHex) * @see {fiveui.color.colorToHex} * - * @param {String[]} cset A set of allowable color strings + * @param {String[]} cset An array of allowable color strings * @returns {!Object} A modified jQuery object */ fiveui.jquery.notColorSet = function (cset) { var allowable = {}; - for (var i = 0; i < cset.length; i += 1) { allowable[cset[i]] = true; } // array -> object + // input array -> object + for (var i = 0; i < cset.length; i += 1) { + allowable[fiveui.color.colorToHex(cset[i])] = true; + } return this.filter(function (index) { - var color = fiveui.color.colorToHex($(this).css("color")); // .css("color") returns rgb(...) + var color = fiveui.color.colorToHexWithDefault($(this).css("color")); // .css("color") returns rgb(...) return !(color in allowable); }); -} +}; /** * General CSS propetry checker plugin @@ -80,7 +123,10 @@ fiveui.jquery.cssIsNot = function (prop, set, fn) { 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 + // array -> object + for (var i = 0; i < set.length; i += 1) { + allowable[fn(set[i])] = true; + } } return this.filter(function (index) { var cssProp = fn($(this).css(prop)); @@ -96,10 +142,7 @@ fiveui.jquery.cssIsNot = function (prop, set, fn) { * @returns {Object} jQuery object */ fiveui.jquery.linksTo = function (href) { - return this.filter(function (index) { - var addr = $(this).attr("href"); - return (addr == href); - }); + return this.filter('[href=' + href + ']'); } /** diff --git a/src/js/fiveui/injected/prelude.js b/src/js/fiveui/injected/prelude.js index 9f84c96..cb1422a 100644 --- a/src/js/fiveui/injected/prelude.js +++ b/src/js/fiveui/injected/prelude.js @@ -300,7 +300,7 @@ fiveui.color.hexToRGB = function (hex) { /** * Covert rgb colors to hex and abreviated hex colors to their full 3 byte - * form. + * and uppercase normal form. * * In case there are parse errors during the conversion, i.e. color values * that are not understood, the input is returned unchanged. @@ -312,16 +312,29 @@ fiveui.color.hexToRGB = function (hex) { fiveui.color.colorToHex = function(color) { if (color.substr(0, 1) === '#') { if (color.length === 7) { - return color; + return color.toUpperCase(); } else { // deal with #0 or #F7 cases - return shortHexToHex(color); + return shortHexToHex(color).toUpperCase(); } } - else { // color == 'rgb...' + else if (color.substr(0,3) === 'rgb') { var c = fiveui.color.colorToRGB(color) return fiveui.color.rgbToHex(c.r, c.g, c.b); } + else { + throw new Error('could not convert color string "' + color + '"'); + } +}; + +fiveui.color.colorToHexWithDefault = function (color) { + try { + return fiveui.color.colorToHex(color); + } + catch (e) { + console.log(e); + return color; + } }; /** @@ -333,14 +346,14 @@ fiveui.color.colorToHex = function(color) { */ fiveui.color.colorToRGB = function(color) { - if (color.substr(0, 1) === '#') { - return fiveui.color.hexToRGB(fiveui.color.colorToHex(color)); - } + if (color.substr(0, 1) === '#') { + return fiveui.color.hexToRGB(fiveui.color.colorToHex(color)); + } - var digits = /rgba?\((\d+), (\d+), (\d+)(, ([-+]?[0-9]*\.?[0-9]+))?/.exec(color); - if (!digits) { - throw new ParseError('could not parse color string: ' + color); - } + var digits = /rgba?\((\d+), (\d+), (\d+)(, ([-+]?[0-9]*\.?[0-9]+))?/.exec(color); + if (!digits) { + throw new Error('could not parse color string: "' + color + '"'); + } var alpha = 1; if (digits[5] != undefined) { diff --git a/src/js/tests/PhantomJSJasmineRunner.html b/src/js/tests/PhantomJSJasmineRunner.html index 606a251..907e176 100644 --- a/src/js/tests/PhantomJSJasmineRunner.html +++ b/src/js/tests/PhantomJSJasmineRunner.html @@ -26,6 +26,7 @@ <script type="text/javascript" src="../fiveui/js/settings.js"></script> <script type="text/javascript" src="../fiveui/js/state.js"></script> <script type="text/javascript" src="../fiveui/injected/prelude.js"></script> + <script type="text/javascript" src="../fiveui/injected/jquery-plugins.js"></script> <!-- spec files --> <script type="text/javascript" src="specs/set.js"></script> @@ -35,6 +36,8 @@ <script type="text/javascript" src="specs/settings.js"></script> <script type="text/javascript" src="specs/state.js"></script> <script type="text/javascript" src="specs/prelude.js"></script> + <script type="text/javascript" src="specs/jquery-plugins.js"></script> + </head> <body> diff --git a/src/js/tests/SpecRunner.html b/src/js/tests/SpecRunner.html index 606967e..caf0248 100644 --- a/src/js/tests/SpecRunner.html +++ b/src/js/tests/SpecRunner.html @@ -24,6 +24,7 @@ <script type="text/javascript" src="../fiveui/js/settings.js"></script> <script type="text/javascript" src="../fiveui/js/state.js"></script> <script type="text/javascript" src="../fiveui/injected/prelude.js"></script> + <script type="text/javascript" src="../fiveui/injected/jquery-plugins.js"></script> <script type="text/javascript" src="specs/set.js"></script> <script type="text/javascript" src="specs/utils.js"></script> @@ -32,6 +33,7 @@ <script type="text/javascript" src="specs/settings.js"></script> <script type="text/javascript" src="specs/state.js"></script> <script type="text/javascript" src="specs/prelude.js"></script> + <script type="text/javascript" src="specs/jquery-plugins.js"></script> </head> diff --git a/src/js/tests/specs/jquery-plugins.js b/src/js/tests/specs/jquery-plugins.js new file mode 100644 index 0000000..7fc196b --- /dev/null +++ b/src/js/tests/specs/jquery-plugins.js @@ -0,0 +1,135 @@ +describe('jQuery plugins', function () { + + describe('fiveui.jquery.hasText', function () { + it('finds an element containing "text foo bar"', function () { + var $t = $('<div>text foo bar</div>'); + expect($t.hasText('text foo bar').length).toEqual(1); + }); + + it('finds no element containing "quux"', function () { + var $t = $('<div>text foo bar</div>'); + expect($t.hasText('quux').length).toEqual(0); + }); + + it('finds a nested element containing "hobbit"', function () { + $t = $('<div><h1>golum</h1><div>hobbit</div></div>'); + expect($t.hasText('hobbit').length).toEqual(1); + }); + }); + + describe('fiveui.jquery.noAttr', function () { + it('returns elements having no summary attribute', function () { + var $t = $('<table></table>').noAttr('summary'); + expect($t.length).toEqual(1); + }); + + it('returns no elements on empty input', function () { + var $t = $('').noAttr('summary'); + expect($t.length).toEqual(0); + }); + + it('doesn\'t return elements with attributes other than the given', function () { + var $t = $('<table foo="bar"></table>').noAttr('summary'); + expect($t.length).toEqual(1); + }); + + it('returns multiple elements having no summary attribute', function () { + var htm = '<table></table>' + + '<table summary="empty"></table>' + + '<table></table>' + + '<table></table>' + + '<table summary="full"></table>'; + var $t = $(htm).noAttr('summary'); + expect($t.length).toEqual(3); + }); + + }); + + describe('fiveui.jquery.noSubElt', function () { + var $t = $('<div><p>red hering</p><h1>blue hering</h1></div>') + + it('filters out elements with a sub-heading', function () { + expect($t.noSubElt('h1').length).toEqual(0); + expect($t.noSubElt(':header').length).toEqual(0); + }); + + it('filters out elements with a <p>', function () { + expect($t.noSubElt('p').length).toEqual(0); + }); + + it('retains elements without <li>', function () { + expect($t.noSubElt('li').length).toEqual(1); + }); + + it('accepts arbitrary jQuery seclectors', function () { + expect($t.noSubElt('p[name=bob]').length).toEqual(1); + }); + }); + + describe('fiveui.jquery.notColorSet', function () { + var htm = '<p style="color: #000000">foo</p>' + + '<p style="color: #ffffff">foo</p>' + + '<p style="color: #e1e1e1">foo</p>' + + '<p style="color: #ffffff">foo</p>'; + var $t = $(htm); + + it('filters out black', function () { + expect($t.notColorSet(['#000000']).length).toEqual(3); + }); + + it('filters out white', function () { + expect($t.notColorSet(['#ffffff']).length).toEqual(2); + }); + + it('filters out black and white', function () { + expect($t.notColorSet(['#ffffff', '#000000']).length).toEqual(1); + }); + + it('filters out everything', function () { + expect($t.notColorSet(['#ffffff', '#000000', '#e1e1e1']).length).toEqual(0); + }); + }); + + describe('fiveui.jquery.cssIsNot', function () { + var htm = '<p style="color: #000000; background-color: #232323">foo</p>' + + '<p style="color: #ffffff; font-size: 5em">foo</p>' + + '<p style="color: #e1e1e1; background-color: #141414">foo</p>' + + '<p style="color: #ffffff">foo</p>' + + '<h1 style="color: #ffffff; font-size: 5em">big</h1>'; + var $t = $(htm); + + it('filters out colors', function () { + expect($t.cssIsNot('color', ['#ffffff', '#000000'], fiveui.color.colorToHexWithDefault).length).toEqual(1); + }); + + it('filters out background-colors', function () { + expect($t.cssIsNot('background-color', ['#141414', '#232323'], fiveui.color.colorToHexWithDefault).length).toEqual(3); + }); + + it('filters out elements of different type', function () { + expect($t.cssIsNot('font-size', ['5em']).length).toEqual(3); + }); + }); + + describe('fiveui.jquery.linksTo', function () { + it('filters out elements with no href', function () { + expect($('<p>foo</p>').linksTo('bar').length).toEqual(0); + }); + + it('filters out elements with wrong href', function () { + expect($('<a href="quux">foo</a>').linksTo('bar').length).toEqual(0); + }); + + var htm = '<a href="quux">foo</a> <a href="bar">foo2</a> <a href="quux">foo3</a>'; + var $t = $(htm); + + it('filters in among various hrefs', function () { + expect($t.linksTo('bar').length).toEqual(1); + }); + + it('filters out among various hrefs', function () { + expect($t.linksTo('quux').length).toEqual(2); + }); + }); + +}); |