diff options
Diffstat (limited to 'src/js/fiveui/injected')
-rw-r--r-- | src/js/fiveui/injected/compute.js | 59 | ||||
-rw-r--r-- | src/js/fiveui/injected/prelude.js | 49 | ||||
-rw-r--r-- | src/js/fiveui/injected/ui.js | 47 |
3 files changed, 109 insertions, 46 deletions
diff --git a/src/js/fiveui/injected/compute.js b/src/js/fiveui/injected/compute.js index d8ae9e8..8fada15 100644 --- a/src/js/fiveui/injected/compute.js +++ b/src/js/fiveui/injected/compute.js @@ -19,6 +19,8 @@ * limitations under the License. */ +/*jshint evil:true */ + (function(){ var guidGenerator = function () { @@ -331,38 +333,43 @@ /** * @param {{rules: [string], dependencies: [string]}} ruleDescr */ - var assembleRules = function(ruleDescr) { - var ruleList = []; - - _.each(ruleDescr.dependencies, - function(dep){ - try { - eval(dep.content); - } catch (x) { - console.error('Could not evaluate rule dependency: ' + dep.url); - console.error(x); - } - }); - - var ruleStrList = ruleDescr.rules; - for(var i=0; i<ruleStrList.length; ++i) { - var moduleStr = - [ '(function(){' - , 'var exports = {};' - , ruleStrList[i] - , 'return exports;' - , '})()' - ].join('\n'); + var assembleRules = function(__assembleRules_ruleDescr) { + // Use long variable names: top-level variables in eval'ed + // dependencies will be created in the scope of this function and + // we want to avoid collisions. + var __assembleRules_ruleList = [] + , __assembleRules_deps = __assembleRules_ruleDescr.dependencies + , __assembleRules_i; + + // Use for loop instead of _.each so that top-level variables in + // eval'ed dependencies will be created in the scope of the + // `assembleRules` function. The goal is to run rules in the + // same scope so that rules have access to top-level variables + // from defined in dependency scripts. + for (__assembleRules_i = 0; __assembleRules_i < __assembleRules_deps.length; __assembleRules_i += 1) { + try { + eval(__assembleRules_deps[__assembleRules_i].content); + } catch (x) { + console.error('Could not evaluate rule dependency: ' + + __assembleRules_deps[__assembleRules_i].url); + console.error(x); + } + } + + var ruleStrList = __assembleRules_ruleDescr.rules; + for(__assembleRules_i=0; __assembleRules_i<ruleStrList.length; ++__assembleRules_i) { + var __assembleRules_moduleFunc = new Function('exports', ruleStrList[__assembleRules_i]); try { - var evaled = eval(moduleStr); - ruleList.push(evaled); + var __assembleRules_exported = {}; + __assembleRules_moduleFunc(__assembleRules_exported); + __assembleRules_ruleList.push(__assembleRules_exported); } catch (x) { console.error('Could not evaluate rule module: ' + x); - console.error(moduleStr); + console.error(__assembleRules_moduleFunc); } } - return ruleList; + return __assembleRules_ruleList; }; port.on('SetRules', function(payload) { diff --git a/src/js/fiveui/injected/prelude.js b/src/js/fiveui/injected/prelude.js index 250488f..5e7a47f 100644 --- a/src/js/fiveui/injected/prelude.js +++ b/src/js/fiveui/injected/prelude.js @@ -19,6 +19,8 @@ * limitations under the License. */ +/*global $5: true, JSON: true */ + /** * The FiveUI Prelude. * @@ -64,7 +66,9 @@ fiveui.query = function (sel, context) { var ctx = context || document; var $results = jQuery(sel, ctx); - jQuery('iframe, frame', ctx).each( + jQuery('iframe, frame', ctx) + .filter(function(idx, frame) { return sameOrigin(frame); }) + .each( function(idx, elt) { var $tempResults; if (elt.contentDocument) { @@ -89,6 +93,14 @@ fiveui.query = function (sel, context) { fiveui.stats.numElts += $filteredResults.length; return $filteredResults; + + // Frames are considered to be from the same origin if their location + // hosts, ports, and schemes are the same. + function sameOrigin(frame) { + var src = frame.src; + var origin = window.location.origin; + return src.indexOf(origin) === 0 && src.charAt(origin.length) !== ':'; + } }; /** @@ -244,22 +256,22 @@ fiveui.color.colorCheck = function (selector, colorSet) { var allowable, i, fnStr, forEachFuncStr; allowable = {}; for (i = 0; i < colorSet.length; i += 1) { allowable[colorSet[i]] = true; } - forEachFuncStr = 'function (j, elt) {\n' - + ' var allowable = ' + JSON.stringify(allowable) + ';\n' - + ' var color = fiveui.color.colorToHex($(elt).css("color"));\n' - + ' if (!(color in allowable)) {\n' - + ' report("Disallowed color " + color + " in element matching " + ' + JSON.stringify(selector) + ', $(elt));\n' - + ' }\n' - + '}\n'; - fnStr = 'function () { fiveui.query("' + selector + '").each(' + forEachFuncStr + '); }'; - return eval('false||'+fnStr); // the `false||` trick is required for eval to parse a - // function expression ?!? + + return function colorCheck() { + fiveui.query(selector).each(function(j, elt) { + var $elt = $(elt); + var color = fiveui.color.colorToHex($elt.css("color")); + if (!(color in allowable)) { + report("Disallowed color " + color + " in element matching " + selector, $elt); + } + }); + }; }; componentToHex = function (c) { var hex = c.toString(16).toUpperCase(); return hex.length == 1 ? "0" + hex : hex; -} +}; shortHexToHex = function (color) { var have = color.length - 1; @@ -287,7 +299,7 @@ fiveui.color.rgbToHex = function (r, g, b) { }; /** - * Convert a 3-byte hex value to base-10 RGB + * Convert a 3-byte hex value to base-10 RGB */ fiveui.color.hexToRGB = function (hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); @@ -356,7 +368,7 @@ fiveui.color.colorToRGB = function(color) { } var alpha = 1; - if (digits[5] != undefined) { + if (digits[5]) { alpha = parseFloat(digits[5]); } @@ -421,7 +433,7 @@ fiveui.color.contrast = function(lum1, lum2) { /** * Computationally determine the actual displayed background color for - * an object. This accounts for parent colors that may appear when + * an object. This accounts for parent colors that may appear when * a bg color is unspecified, or fully transparent. * * It does not account for elements that are shifted out of their @@ -435,6 +447,7 @@ fiveui.color.findBGColor = function(obj) { var fc = fiveui.color; var real = fc.colorToRGB(obj.css('background-color')); var none = fc.colorToRGB('rgba(0, 0, 0, 0)'); + var i; if (real.a != 1) { @@ -453,7 +466,7 @@ fiveui.color.findBGColor = function(obj) { // takeWhile alpha != 1 var colors = []; - for (var i=0; i < parents.length; i++) { + for (i=0; i < parents.length; i++) { colors.push(parents[i]); if (parents[i].a == 1) { break; @@ -464,7 +477,7 @@ fiveui.color.findBGColor = function(obj) { // neither commutative, nor associative, so we need to be carefull // of the order in which parent colors are combined. var res = real; - for (var i=0; i < colors.length; i++) { + for (i=0; i < colors.length; i++) { res = fc.alphaCombine(res, colors[i]); } return res; @@ -476,7 +489,7 @@ fiveui.color.findBGColor = function(obj) { /** * Combines two colors, accounting for alpha values less than 1. - * + * * @param {color} top The color "on top" * @param {color} bot The color "on bottom" * @return {color} the composite RGBA color. diff --git a/src/js/fiveui/injected/ui.js b/src/js/fiveui/injected/ui.js index eb22136..e23aa90 100644 --- a/src/js/fiveui/injected/ui.js +++ b/src/js/fiveui/injected/ui.js @@ -27,6 +27,17 @@ var core = {}; core.port = obtainPort(); + core.getElementByXPath = function(path, context) { + var nsResolver = document.createNSResolver( + context.ownerDocument == null ? context.documentElement : context.ownerDocument.documentElement + ); + var xpathResult = document.evaluate(path, document, nsResolver, XPathResult.ANY_TYPE, null); + var $result = $(), nextElem; + while (nextElem = xpathResult.iterateNext()) { + $result = $result.add(nextElem); + } + return $result; + }; /* User Interface **********************************************************/ @@ -320,6 +331,7 @@ , ' <div class="fiveui-problem-header">' , ' <div class="fiveui-problem-toggle"><span></span></div>' , ' <%= name %>' + , ' <a href="#" class="fiveui-problem-scrollTo">show</a>' , ' </div>' , ' <div class="fiveui-problem-body">' , ' <p><%= msg %></p>' @@ -340,6 +352,20 @@ this.$toggle = this.$el.find('.fiveui-problem-toggle'); this.$body = this.$el.find('.fiveui-problem-body'); this.$header = this.$el.find('.fiveui-problem-header'); + this.isOpen = false; + + var self = this; + + this.$el.on('click', function(event) { + if (!$(event.target).is('a, a *')) { + self.toggle(); + } + }); + + this.$el.on('click', '.fiveui-problem-scrollTo', function(event) { + event.preventDefault(); + self.scrollTo(); + }); this.$body.hide(); @@ -350,6 +376,16 @@ el.append(this.$el); }, + toggle:function() { + this.isOpen = !this.isOpen; + if (this.isOpen) { + this.open(); + } + else { + this.close(); + } + }, + /** * Close the context for a problem entry. * @public @@ -358,7 +394,6 @@ this.$toggle.find('span').removeClass('icon-caret-down') .addClass('icon-caret-right'); - this.$el.one('click', _.bind(this.open, this)); this.$body.slideUp(100); core.maskProblem(this.problem); @@ -368,12 +403,20 @@ this.$toggle.find('span').addClass('icon-caret-down') .removeClass('icon-caret-right'); - this.$el.one('click', _.bind(this.close, this)); this.$body.slideDown(100); core.highlightProblem(this.problem); }, + scrollTo:function() { + var $elem = core.getElementByXPath(this.problem.xpath, document); + var top = $elem.offset().top; + var height = $elem.height(); + var viewHeight = $(window).height(); + var extra = viewHeight - height; + $(window).scrollTop(top - (extra * 0.33)); + } + }); |