aboutsummaryrefslogtreecommitdiff
path: root/src/js/fiveui/injected/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/fiveui/injected/ui.js')
-rw-r--r--src/js/fiveui/injected/ui.js228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/js/fiveui/injected/ui.js b/src/js/fiveui/injected/ui.js
new file mode 100644
index 0000000..6831436
--- /dev/null
+++ b/src/js/fiveui/injected/ui.js
@@ -0,0 +1,228 @@
+/*
+ * Module : injected/fiveui-injected-ui.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.
+ */
+
+(function(){
+ /**
+ * Storage namespace for in-browser logic
+ */
+ var core = {};
+ core.port = obtainPort();
+
+ core.ui = $('<div></div>').attr('id', 'uic-dialog');
+
+ core.lockDepth = 0;
+
+ core.lockMask = function() {
+ core.lockDepth = core.lockDepth + 1;
+ if(core.lockDepth == 1) {
+ core.port.emit('MaskRules', null);
+ }
+ };
+
+ core.unlockMask = function() {
+ core.lockDepth = core.lockDepth - 1;
+ if(core.lockDepth == 0) {
+ core.port.emit('UnmaskRules', null);
+ }
+ };
+
+ /**
+ * Due to the lack of a confirmation continuation with the port api, this
+ * function runs a continuation after 10ms of delivering the MaskRules
+ * message, then waits another 10ms before delivering the UnmaskRules
+ * message. The two delays seem to give a better chance that the
+ * continuation runs within the masked context.
+ */
+ core.maskRules = function(body) {
+ core.lockMask();
+
+ setTimeout(function() {
+ body();
+ setTimeout(function() {
+ core.unlockMask();
+ }, 10);
+ }, 10);
+ };
+
+ core.highlightProblem = function(elt) {
+ core.maskRules(function() {
+ elt.css('background-color', 'rgba(255,0,0,0.3)')
+ .addClass('uic-problem');
+ });
+ };
+
+ core.maskProblem = function(elt) {
+ core.maskRules(function() {
+ elt.css('background-color', '')
+ .removeClass('uic-problem');
+ });
+ };
+
+ core.renderStats = function (stats) {
+ core.maskRules(function () {
+ var statsDiv, statsDetail;
+ statsDiv = $('#fiveui-stats');
+ statsDiv.children().remove();
+ statsDetail = $('<table class="fiveui-table"><tr><td class="fiveui-table-text">rules checked:</td><td class="fiveui-table-number">' + stats.numRules + '</td></tr>' +
+ '<tr><td class="fiveui-table-text">elements checked:</td><td class="fiveui-table-number">' + stats.numElts + '</td></tr>' +
+ '<tr><td class="fiveui-table-text">elapsed time (ms):</td><td class="fiveui-table-number">' + (stats.end - stats.start) + '</td></tr></table>');
+ statsDiv.append(statsDetail);
+ });
+ };
+
+ core.renderProblem = function(prob) {
+ core.maskRules(function() {
+ var probDiv = $('<div class="pr"></div>');
+
+
+ /** Problem Controls **/
+ var prControls = $('<div class="prControls"></div>');
+ probDiv.append(prControls);
+
+ var prSeverity = $('<div class="prSeverity"></div>');
+ prControls.append(prSeverity);
+
+ if (1 == prob.severity) {
+ prSeverity.addClass('prSeverity-err');
+ } else {
+ prSeverity.addClass('prSeverity-warn');
+ }
+
+ var prExpand = $('<div class="prExpand prExpand-right"></div>');
+ prControls.append(prExpand);
+
+ /** Problem Content **/
+ var prMessage = $('<div class="prMessage"></div>');
+ probDiv.append(prMessage);
+
+ var prTitle = $('<div class="prTitle">'+prob.name+'</div>');
+ prMessage.append(prTitle);
+
+ var prDetails = $('<div class="prDetails"></div>');
+ prMessage.append(prDetails);
+
+ var prDescr = $('<p>'+prob.descr+'</p>');
+ prDetails.append(prDescr);
+ 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(fiveui.query('.' + prob.hash));
+ } else {
+ elt.addClass('prExpand-down')
+ .removeClass('prExpand-right');
+ prDetails.show();
+ core.highlightProblem(fiveui.query('.' + prob.hash));
+ }
+
+ 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($('<div id="controls"></div>'));
+
+ core.ui.append($('<div id="problemList"></div>'));
+
+ 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', 'uic-top');
+
+ $('#controls').append($('<div id="clearButton"></div>')
+ .button({ label: 'clear' }));
+
+ $('#clearButton').click(function() {
+ $('#problemList').children().remove();
+ port.emit('ClearProblems');
+ core.renderStats(fiveui.stats.zero);
+ core.maskProblem(fiveui.query('.uic-problem'));
+ });
+
+ ///////////////////////////////////////////
+ // 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($('<div id="breakButton"></div>')
+ .button({ label: 'break' }));
+ $('#breakButton').click(function() {
+ debugger; //
+ }); //
+ ////////////////////////////////////////////
+
+ core.ui.append($('<div id="fiveui-stats"></div>'));
+
+ if(!state.winState.closed) {
+ core.ui.dialog('open');
+ }
+
+ $(state.problems).each(function(ix,prob) {
+ core.renderProblem(prob);
+ });
+ core.renderStats(state.stats);
+ });
+ };
+
+ registerBackendListeners(core.port);
+})();