From 2618fb0c74567b42ec238706132937f087f8fc06 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Mon, 15 Jul 2013 15:25:47 -0700 Subject: New UI --- src/js/chrome/manifest.json | 9 +- src/js/fiveui/build.mk | 28 +- src/js/fiveui/css/ui.css | 116 ++++++ src/js/fiveui/injected/compute.js | 2 +- src/js/fiveui/injected/jquery-plugins.js | 2 + src/js/fiveui/injected/prelude.js | 4 +- src/js/fiveui/injected/ui.js | 525 ++++++++++++++++++--------- src/js/fiveui/js/background.js | 2 + src/js/lib/font-awesome/css/font-awesome.css | 4 +- src/js/lib/ui.css | 112 ------ src/js/lib/ui.html | 13 - src/js/lib/ui.js | 261 ------------- 12 files changed, 510 insertions(+), 568 deletions(-) create mode 100644 src/js/fiveui/css/ui.css delete mode 100644 src/js/lib/ui.css delete mode 100644 src/js/lib/ui.html delete mode 100644 src/js/lib/ui.js diff --git a/src/js/chrome/manifest.json b/src/js/chrome/manifest.json index bbd8711..40d6649 100644 --- a/src/js/chrome/manifest.json +++ b/src/js/chrome/manifest.json @@ -26,5 +26,12 @@ ], // We have to relax the content security policy to allow rules to be evaluated: - "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" + "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", + + "web_accessible_resources": [ + "data/font-awesome/font/fontawesome-webfont.eot", + "data/font-awesome/font/fontawesome-webfont.svg", + "data/font-awesome/font/fontawesome-webfont.ttf", + "data/font-awesome/font/fontawesome-webfont.woff" + ] } diff --git a/src/js/fiveui/build.mk b/src/js/fiveui/build.mk index e229eed..41d2c06 100644 --- a/src/js/fiveui/build.mk +++ b/src/js/fiveui/build.mk @@ -45,7 +45,8 @@ $2: $(patsubst $(fiveui-dir)/%,$1/data/%,$(wildcard $(fiveui-dir)/js/*)) $(call fiveui-files,$1/data,css) -$2: $1/data/css/options.css +$2: $1/data/css/options.css \ + $1/data/css/ui.css $(call fiveui-files,$1/data,images) @@ -69,6 +70,31 @@ $2: $1/data/jquery/jquery-1.8.3.js \ $1/data/jquery/bundled.css +# font awesome +$1/data/font-awesome/css: | $1/data/font-awesome + $$(call cmd,mkdir) + +$1/data/font-awesome/css/%: $(lib-dir)/font-awesome/css/% \ + | $1/data/font-awesome/css + $$(call cmd,cp) + +$1/data/font-awesome/font: | $1/data/font-awesome + $$(call cmd,mkdir) + +$1/data/font-awesome/font/%: $(lib-dir)/font-awesome/font/% \ + | $1/data/font-awesome/font + $$(call cmd,cp) + +$1/data/font-awesome: | $1/data + $$(call cmd,mkdir) + +$2: $1/data/font-awesome/css/font-awesome.css \ + $1/data/font-awesome/font/fontawesome-webfont.eot \ + $1/data/font-awesome/font/fontawesome-webfont.svg \ + $1/data/font-awesome/font/fontawesome-webfont.woff \ + $1/data/font-awesome/font/fontawesome-webfont.ttf + + # simple libraries $1/data/%: $(lib-dir)/% | $1/data $$(call cmd,cp) diff --git a/src/js/fiveui/css/ui.css b/src/js/fiveui/css/ui.css new file mode 100644 index 0000000..0b723c9 --- /dev/null +++ b/src/js/fiveui/css/ui.css @@ -0,0 +1,116 @@ + + +div.fiveui { + background-color: #e1e1e1; + min-width: 400px; + min-height: 300px; + width: 400px; + height: 300px; + position: absolute; + z-index: 1000; + border: 1px solid black; + resize: both; + overflow: hidden; +} + +div.fiveui>* { + font-family: Arial; + padding: 4px; +} + +div.fiveui>div.fiveui-titlebar { + background-color: #366689; + color: #fff; + font-weight: bold; + cursor: hand; + cursor: pointer; + border-bottom: 1px solid black; +} + +div.fiveui-titlebar>div.fiveui-close { + position: absolute; + top: 0; + right: 0; + padding: 0.2em; + width: 1em; +} + +div.fiveui>div.fiveui-titlebar:active{ + cursor: hand; + cursor: pointer; +} + + +div.fiveui>div.fiveui-controls { + padding: 0; +} + +div.fiveui-control { + background-color: #8ea548; + color: #fff; + font-family: Awesome; + display: inline; + border-right: 1px solid black; + margin: 0; + cursor: hand; + cursor: pointer; + float: left; + padding: 4px; + width: 1.5em; + text-align: center; +} + +div.fiveui-control:active { + background-color: #366689; +} + +div.fiveui-problems { + overflow-y: auto; + overflow-x: hidden; + width: 100%; + border-top: 1px solid black; + margin: 0; + padding: 0; + resize: none; +} + +div.fiveui-stats { + background-color: #fff; + position: absolute; + width: 100%; + bottom: 10px; + left: 0px; + border-top: 1px solid black; + border-bottom: 1px solid black; +} + +div.fiveui-problem { + border-bottom: 1px solid black; + padding: 0; + margin: 0; + cursor: hand; + cursor: pointer; +} + +div.fiveui-problem-header { + padding: 4px; + font-size: 1.1em; +} + +div.fiveui-problem-toggle { + float: left; + width: 1em; + padding-left: 4px; +} + +div.fiveui-problem-body { + padding: 4px; +} + +div.fiveui-severity-0 { + background-color: #F2FC7E; +} + +div.fiveui-severity-1 { + background-color: #F5B3B3; +} diff --git a/src/js/fiveui/injected/compute.js b/src/js/fiveui/injected/compute.js index 921229e..9fc16a8 100644 --- a/src/js/fiveui/injected/compute.js +++ b/src/js/fiveui/injected/compute.js @@ -283,7 +283,7 @@ * @param {DOMNode} elt */ var underFiveUI = function(elt) { - var ancestor = $(elt).parentsUntil('#fiveui-top', 'body'); + var ancestor = $(elt).parentsUntil('.fiveui', 'body'); return ancestor.length == 0; }; diff --git a/src/js/fiveui/injected/jquery-plugins.js b/src/js/fiveui/injected/jquery-plugins.js index 43cfbd6..a7dedbd 100644 --- a/src/js/fiveui/injected/jquery-plugins.js +++ b/src/js/fiveui/injected/jquery-plugins.js @@ -19,6 +19,8 @@ * limitations under the License. */ +var fiveui = fiveui || {}; + /** * This module provides several useful jQuery plugins related to checking and reporting * UI consistency issues. diff --git a/src/js/fiveui/injected/prelude.js b/src/js/fiveui/injected/prelude.js index ce242f6..9f84c96 100644 --- a/src/js/fiveui/injected/prelude.js +++ b/src/js/fiveui/injected/prelude.js @@ -81,8 +81,8 @@ fiveui.query = function (sel, context) { } ); - $filteredResults = $results.not('#fiveui-top') - .not('#fiveui-top *') + $filteredResults = $results.not('.fiveui') + .not('.fiveui *') .filter(':visible'); // update global stats diff --git a/src/js/fiveui/injected/ui.js b/src/js/fiveui/injected/ui.js index 1eecd93..60c3019 100644 --- a/src/js/fiveui/injected/ui.js +++ b/src/js/fiveui/injected/ui.js @@ -20,13 +20,358 @@ */ (function(){ + /** * Storage namespace for in-browser logic */ var core = {}; core.port = obtainPort(); - core.ui = $('
'); + + /* User Interface **********************************************************/ + + core.UI = function() { + this._initialize.apply(this, arguments); + }; + + + _.extend(core.UI, { + + /** + * Template for the UI dialog + */ + uiTemplate:_.template( + [ '
' + , '
' + , ' FiveUI
' + , '
' + , '
' + , '
' + , '
' + , '
' + , '
' + , '
' + , '
' + ].join('')), + + /** + * Template for the stats panel of the UI dialog. + */ + statsTemplate:_.template( + [ '' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , ' ' + , '
rules checked:<%= numRules %>
elements checked:<%= numElts %>
elapsed time (ms):<%= time %>
' + ].join('')), + + }); + + _.extend(core.UI.prototype, { + + /** + * Create the UI, and attach all event handlers. + * @private + */ + _initialize:function(opts) { + + // apply options + var optNames = [ 'port' ]; + _.defaults(this, _.pick(opts, optNames)); + + this.$el = $(core.UI.uiTemplate()); + this.$problems = this.$el.find('.fiveui-problems'); + this.$stats = this.$el.find('.fiveui-stats'); + + this._setupButtons(); + this._setupDragDrop(); + this._pollResize(); + + this._registerBackendListeners(); + + // initially, keep the window hidden + this.$el.hide(); + }, + + /** + * Setup the functionality of the close button on the ui + * @private + */ + _setupButtons:function() { + + var close = this.$el.find('.fiveui-close'); + close.on('click.fiveui', _.bind(this.hide, this)); + + var clear = this.$el.find('.fiveui-clear'); + clear.on('click.fiveui', _.bind(this.clearProblems, this)); + + // note, this only works in chrome + var pause = this.$el.find('.fiveui-break'); + pause.on('click.fiveui', function() { + debugger; + }); + + }, + + /** + * Setup the drag and drop functionality for the problems window. + * @private + */ + _setupDragDrop:function() { + + var self = this; + var header = this.$el.find('.fiveui-titlebar'); + var offset = { x: 0, y: 0 }; + + // update the location of the ui + var mouseMove = function(e) { + self.$el.css({ + left: e.originalEvent.clientX + offset.x, + top: e.originalEvent.clientY + offset.y, + }); + }; + + var cancel = function(e) { + e.stopPropagation(); + }; + + // both of these will cause funny things to happen with the text of the title + // bar. + header.on('dragstart', cancel); + header.on('selectstart', cancel); + + // figure out how far the cursor is from the top-left of the ui + header.on('mousedown.fiveui', function(e) { + + // prevent the close button from being used as a drag handle + if(e.target != header[0]) { + return false; + } + + var pos = self.$el.position(); + offset.x = pos.left - e.originalEvent.clientX; + offset.y = pos.top - e.originalEvent.clientY; + + $(window).on('mousemove.fiveui', mouseMove); + header.one('mouseup.fiveui', function() { + $(window).off('mousemove.fiveui', mouseMove); + + // deliver the new position to teh backend + self.port.emit('Position', self.$el.position()); + }); + }); + + }, + + _pollResize:function() { + + var height = this.$el.height(); + + if(height != this.height) { + + console.log('changing height'); + + this.height = height; + + var ppos = this.$problems.position(); + var spos = this.$stats.position(); + + this.$problems.height(spos.top - ppos.top) + + // notify the backend about the new height + this.port.emit('Size', { + width: this.$el.width(), + height: this.$el.height() + }); + } + + setTimeout(_.bind(this._pollResize, this), 100); + }, + + /** + * Setup listeners to the backend. + */ + _registerBackendListeners:function() { + + var self = this; + + this.port.on('ShowUI', function(unused) { + self.show(); + }); + + this.port.on('ShowProblem', _.bind(this.addProblem, this)); + + this.port.on('ShowStats', _.bind(this.renderStats, this)); + + // initialize/create the ui, set its position and size + this.port.on('RestoreUI', function(state) { + + // set the position and size + self.$el.css({ + 'top': state.winState.y, + 'left': state.winState.x, + 'width': state.winState.width + 'px', + 'height': state.winState.height + 'px' + }); + + // optionally show the window + if(!state.winState.closed) { + self.show(); + } + + // add all problems + _.each(state.problems, _.bind(self.addProblem, self)); + + // render stats + self.renderStats(state.stats); + + }); + }, + + /** + * Clear the problems list + * @public + */ + clearProblems:function() { + this.$el.find('.fiveui-problems').children().remove(); + this.port.emit('ClearProblems'); + }, + + /** + * Add an entry in the problems list. + * @public + */ + addProblem:function(problem) { + + var p = new core.Problem(problem); + p.appendTo(this.$el.find('.fiveui-problems')); + + }, + + /** + * Attach the UI to a jquery selector. + * @public + */ + appendTo:function(el) { + el.append(this.$el); + }, + + /** + * Hide the UI + * @public + */ + hide:function() { + this.$el.hide(); + this.port.emit('CloseUI'); + }, + + /** + * Show the UI + * @public + */ + show:function() { + this.$el.show(); + }, + + /** + * Render statistics + */ + renderStats:function(stats) { + + stats = stats || {}; + _.defaults(stats, { + numRules: 0, + numElts: 0, + start: 0, + end: 0, + }); + + stats.time = stats.end - stats.start; + + this.$stats.html(core.UI.statsTemplate(stats)); + }, + + }); + + + /** + * Entries in the problem list. + */ + core.Problem = function() { + this._initialize.apply(this, arguments); + }; + + _.extend(core.Problem, { + + /** + * Template for entries in the problems list + */ + problemTemplate:_.template( + [ '
' + , '
' + , '
' + , ' <%= name %>' + , '
' + , '
' + , '

<%= msg %>

' + , '

<%= xpath %>

' + , '
' + , '
' + ].join('')), + + }); + + _.extend(core.Problem.prototype, { + + _initialize:function(problem) { + + this.problem = problem; + + this.$el = $(core.Problem.problemTemplate(problem)); + 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.$body.hide(); + + this.close(); + }, + + appendTo:function(el) { + el.append(this.$el); + }, + + /** + * Close the context for a problem entry. + * @public + */ + close:function() { + this.$toggle.find('span').removeClass('icon-caret-down') + .addClass('icon-caret-right'); + + this.$el.one('click', _.bind(this.open, this)); + this.$body.slideUp(100); + }, + + open:function() { + 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.lockDepth = 0; @@ -72,7 +417,7 @@ } else { // add the rule to the list of highlighted elements, and change its style // to look obvious. - var elt = fiveui.query('.' + prob.hash); + var elt = core.query('.' + prob.hash); var oldStyle = elt.attr('style'); core.maskRules(function() { @@ -95,7 +440,7 @@ obj.highlighted = obj.highlighted - 1; if(obj.highlighted == 0) { - var elt = fiveui.query('.' + prob.hash); + var elt = core.query('.' + prob.hash); // remove the fiveui style core.maskRules(function() { @@ -113,33 +458,9 @@ } }; - core.renderStatsTemplate = _.template( - [ '' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , ' ' - , '
rules checked:<%= numRules %>
elements checked:<%= numElts %>
elapsed time (ms):<%= time %>
' - ].join('')); - core.renderStats = function (stats) { // give stats some sane defaults. - stats = stats || {}; - _.defaults(stats, { - numRules: 0, - numElts: 0, - start: 0, - end: 0, - }); core.maskRules(function () { @@ -152,153 +473,7 @@ }); }; - core.renderProblem = function(prob) { - core.maskRules(function() { - var probDiv = $('
'); - - - /** Problem Controls **/ - var prControls = $('
'); - probDiv.append(prControls); - - var prSeverity = $('
'); - prControls.append(prSeverity); - - if (1 == prob.severity) { - prSeverity.addClass('prSeverity-err'); - } else { - prSeverity.addClass('prSeverity-warn'); - } - - var prExpand = $('
'); - prControls.append(prExpand); - - /** Problem Content **/ - var prMessage = $('
'); - probDiv.append(prMessage); - - var prTitle = $('
'+prob.name+'
'); - prMessage.append(prTitle); - - var prDetails = $('
'); - prMessage.append(prDetails); - - - var prDescr = $('

'+prob.descr+'

'); - var prPath = $('

'+prob.xpath+'

'); - prDetails.append(prDescr); - if (prob.msg) { - var reportMsg = $('
'+prob.msg+'
'); - prDetails.append(reportMsg); - } - prDetails.append(prPath); - prDetails.hide(); - - $('#problemList').append(probDiv); - - prExpand.click( - function() { - var elt = $(this); - if(elt.is('.prExpand-down')) { - elt.removeClass('prExpand-down') - .addClass('prExpand-right'); - prDetails.hide(); - core.maskProblem(prob); - } else { - elt.addClass('prExpand-down') - .removeClass('prExpand-right'); - prDetails.show(); - core.highlightProblem(prob); - } - - return false; - }); - }); - }; - - var dragStop = function(evt,e) { - core.port.emit('Position', core.ui.parent().position()); - }; - - var resizeStop = function(evt,e) { - core.port.emit('Size', { width: core.ui.width(), height: core.ui.height() }); - }; - - var beforeClose = function(evt,e) { - core.port.emit('CloseUI'); - }; - - var registerBackendListeners = function(port) { - - port.on('ShowUI', function(unused) { - core.ui.dialog('open'); - }); - - port.on('ShowProblem', function(problem) { - core.renderProblem(problem); - }); - - port.on('ShowStats', function(stats) { - core.renderStats(stats); - }); - - port.on('RestoreUI', function(state) { - core.ui.append($('
')); - - core.ui.append($('
')); - - var newDialog = core.ui.dialog({ title: 'FiveUI', - dragStop: dragStop, - resizeStop: resizeStop, - beforeClose: beforeClose, - position: [state.winState.x, state.winState.y], - width: state.winState.width, - height: state.winState.height, - autoOpen: false, - zIndex: 50000 - }); - newDialog.parent().attr('id', 'fiveui-top'); - - $('#controls').append($('
') - .button({ label: 'clear' })); - - $('#clearButton').click(function() { - $('#problemList').children().remove(); - port.emit('ClearProblems'); - - core.renderStats(); - $('prExpand-down').click(); - - // Just in case the click event on prExpand-down missde anything: - core.maskProblem(fiveui.query('.uic-problem'), undefined); - core.renderStats(); - }); - - /////////////////////////////////////////// - // Add a button that causes a debuger break. - // - // handy for playing with Jquery on the dom. - // Note: This only works in Google Chrome. - $('#controls').append($('
') - .button({ label: 'break' })); - $('#breakButton').click(function() { - debugger; // - }); // - //////////////////////////////////////////// - - core.ui.append($('
')); - - if(!state.winState.closed) { - core.ui.dialog('open'); - } - - $(state.problems).each(function(ix,prob) { - core.renderProblem(prob); - }); - - core.renderStats(state.stats); - }); - }; + core.win = new core.UI({ port: core.port }); - registerBackendListeners(core.port); + core.win.appendTo($('body')); })(); diff --git a/src/js/fiveui/js/background.js b/src/js/fiveui/js/background.js index dfe0649..79e2512 100644 --- a/src/js/fiveui/js/background.js +++ b/src/js/fiveui/js/background.js @@ -160,6 +160,8 @@ fiveui.Background.prototype.pageLoad = function(tabId, url, data) { var uiScripts = [ this.dataLoader('underscore.js') + , this.dataLoader('font-awesome/css/font-awesome.css') + , this.dataLoader('css/ui.css') , this.dataLoader('jquery/bundled.css') , this.dataLoader('jquery/jquery-1.8.3.js') , this.dataLoader('jquery/jquery-ui-1.9.2.custom.js') diff --git a/src/js/lib/font-awesome/css/font-awesome.css b/src/js/lib/font-awesome/css/font-awesome.css index 7ede182..79e14f5 100644 --- a/src/js/lib/font-awesome/css/font-awesome.css +++ b/src/js/lib/font-awesome/css/font-awesome.css @@ -27,8 +27,8 @@ * -------------------------- */ @font-face { font-family: 'FontAwesome'; - src: url('../font/fontawesome-webfont.eot?v=3.2.1'); - src: url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); + src: url('chrome-extension://__MSG_@@extension_id__/data/font-awesome/font/fontawesome-webfont.eot?v=3.2.1'); + src: url('chrome-extension://__MSG_@@extension_id__/data/font-awesome/font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('chrome-extension://__MSG_@@extension_id__/data/font-awesome/font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('chrome-extension://__MSG_@@extension_id__/data/font-awesome/font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('chrome-extension://__MSG_@@extension_id__/data/font-awesome/font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); font-weight: normal; font-style: normal; } diff --git a/src/js/lib/ui.css b/src/js/lib/ui.css deleted file mode 100644 index c7c6c79..0000000 --- a/src/js/lib/ui.css +++ /dev/null @@ -1,112 +0,0 @@ - - -div.fiveui { - background-color: #e1e1e1; - min-width: 400px; - min-height: 300px; - width: 400px; - height: 300px; - position: absolute; - z-index: 1000; - border: 1px solid black; - resize: both; - overflow: hidden; -} - -div.fiveui>* { - font-family: Arial; - padding: 4px; -} - -div.fiveui>div.fiveui-titlebar { - background-color: #366689; - color: #fff; - font-weight: bold; - cursor: hand; - cursor: pointer; - border-bottom: 1px solid black; -} - -div.fiveui-titlebar>div.fiveui-close { - position: absolute; - top: 0; - right: 0; - padding: 0.2em; - width: 1em; -} - -div.fiveui>div.fiveui-titlebar:active{ - cursor: hand; - cursor: pointer; -} - - -div.fiveui>div.fiveui-controls { - padding: 0; -} - -div.fiveui-control { - background-color: #8ea548; - color: #fff; - font-family: Awesome; - display: inline; - border-right: 1px solid black; - margin: 0; - cursor: hand; - cursor: pointer; - float: left; - padding: 4px; - width: 1.5em; - text-align: center; -} - -div.fiveui-control:active { - background-color: #366689; -} - -div.fiveui-problems { - overflow-y: auto; - overflow-x: hidden; - width: 100%; - border-top: 1px solid black; - margin: 0; - padding: 0; - resize: none; -} - -div.fiveui-stats { - background-color: #fff; - position: absolute; - width: 100%; - bottom: 10px; - left: 0px; - border-top: 1px solid black; - border-bottom: 1px solid black; -} - -div.fiveui-problem { - border-bottom: 1px solid black; - padding: 0; - margin: 0; - cursor: hand; - cursor: pointer; -} - -div.fiveui-problem-header { - padding: 4px; - font-size: 1.1em; -} - -div.fiveui-problem-toggle { - float: left; - width: 1em; - padding-left: 4px; -} - -div.fiveui-problem-body { - padding: 4px; -} - -div.fiveui-severity-0 { - background-color: #F5B3B3; -} diff --git a/src/js/lib/ui.html b/src/js/lib/ui.html deleted file mode 100644 index 8bf6714..0000000 --- a/src/js/lib/ui.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - New UI - - - - - - - - - diff --git a/src/js/lib/ui.js b/src/js/lib/ui.js deleted file mode 100644 index eadc01e..0000000 --- a/src/js/lib/ui.js +++ /dev/null @@ -1,261 +0,0 @@ - -var fiveui = fiveui || {}; - -;(function() { - -/* Templates ******************************************************************/ - -fiveui.UI = function() { - this._initialize.apply(this, arguments); -}; - - -_.extend(fiveui.UI, { - - /** - * Template for the UI dialog - */ - uiTemplate:_.template( - [ '
' - , '
' - , ' FiveUI
' - , '
' - , '
' - , '
' - , '
' - , '
' - , '
' - , '
' - , '
' - ].join('')), - -}); - - - -_.extend(fiveui.UI.prototype, { - - /** - * Create the UI, and attach all event handlers. - * @private - */ - _initialize:function() { - - this.$el = $(fiveui.UI.uiTemplate()); - this.$problems = this.$el.find('.fiveui-problems'); - this.$stats = this.$el.find('.fiveui-stats'); - - this._setupClose(); - this._setupControls(); - this._setupDragDrop(); - this._pollResize(); - - }, - - /** - * Setup the functionality of the close button on the ui - * @private - */ - _setupClose:function() { - - var close = this.$el.find('.fiveui-close'); - close.on('click.fiveui', _.bind(this.hide, this)); - - }, - - /** - * Setup the functionality for the controls part of the UI. - * @private - */ - _setupControls:function() { - - - }, - - /** - * Setup the drag and drop functionality for the problems window. - * @private - */ - _setupDragDrop:function() { - - var self = this; - var header = this.$el.find('.fiveui-titlebar'); - var offset = { x: 0, y: 0 }; - - - // update the location of the ui - var mouseMove = function(e) { - self.$el.css({ - left: e.originalEvent.clientX + offset.x, - top: e.originalEvent.clientY + offset.y, - }); - }; - - var cancel = function(e) { - e.stopPropagation(); - }; - - // both of these will cause funny things to happen with the text of the title - // bar. - header.on('dragstart', cancel); - header.on('selectstart', cancel); - - // figure out how far the cursor is from the top-left of the ui - header.on('mousedown.fiveui', function(e) { - - // prevent the close button from being used as a drag handle - if(e.target != header[0]) { - return false; - } - - var pos = self.$el.position(); - offset.x = pos.left - e.originalEvent.clientX; - offset.y = pos.top - e.originalEvent.clientY; - - $(window).on('mousemove.fiveui', mouseMove); - header.one('mouseup.fiveui', function() { - $(window).off('mousemove.fiveui', mouseMove); - }); - }); - - }, - - _pollResize:function() { - - var height = this.$el.height(); - - if(height != this.height) { - this.height = height; - - var ppos = this.$problems.position(); - var spos = this.$stats.position(); - - this.$problems.height(spos.top - ppos.top) - } - - setTimeout(_.bind(this._pollResize, this), 100); - }, - - /** - * Clear the problems list - * @public - */ - clearProblems:function() { - this.$el.find('.fiveui-problems').children().remove(); - }, - - /** - * Add an entry in the problems list. - * @public - */ - addProblem:function(problem) { - - var p = new fiveui.Problem(problem); - p.appendTo(this.$el.find('.fiveui-problems')); - - }, - - /** - * Attach the UI to a jquery selector. - * @public - */ - appendTo:function(el) { - el.append(this.$el); - }, - - /** - * Hide the UI - * @public - */ - hide:function() { - this.$el.hide(); - }, - - /** - * Show the UI - * @public - */ - show:function() { - this.$el.show(); - }, - -}); - - -/** - * Entries in the problem list. - */ -fiveui.Problem = function() { - this._initialize.apply(this, arguments); -}; - -_.extend(fiveui.Problem, { - - /** - * Template for entries in the problems list - */ - problemTemplate:_.template( - [ '
' - , '
' - , '
' - , ' <%= name %>' - , '
' - , '
' - , ' <%= descr %>
' - , ' <%= xpath %>' - , '
' - , '
' - ].join('')), - -}); - -_.extend(fiveui.Problem.prototype, { - - _initialize:function(problem) { - this.$el = $(fiveui.Problem.problemTemplate(problem)); - 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.$body.hide(); - - this.close(); - }, - - appendTo:function(el) { - el.append(this.$el); - }, - - /** - * Close the context for a problem entry. - * @public - */ - close:function() { - this.$toggle.find('span').removeClass('icon-caret-down') - .addClass('icon-caret-right'); - - this.$el.one('click', _.bind(this.open, this)); - this.$body.slideUp(100); - }, - - open:function() { - console.log('open'); - - this.$toggle.find('span').addClass('icon-caret-down') - .removeClass('icon-caret-right'); - - this.$el.one('click', _.bind(this.close, this)); - this.$body.slideDown(100); - }, - -}); - - -$(function() { - - var ui = new fiveui.UI(); - ui.appendTo(jQuery('body')); - -}); - -})(); -- cgit v1.2.3