From 93c039e29536b9fc29d6431d81e7ad7a542d86e0 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Mon, 6 May 2013 13:13:15 -0600 Subject: [PATCH 01/13] * Work toward multiple dialog boxes --- code/boot.js | 27 ++++++++++++++++----------- main.js | 3 +-- style.css | 4 ++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/code/boot.js b/code/boot.js index c08acf8b..064241be 100644 --- a/code/boot.js +++ b/code/boot.js @@ -340,18 +340,23 @@ window.setupTooltips = function(element) { } window.setupDialogs = function() { - $('#dialog').dialog({ - autoOpen: false, - modal: true, - buttons: [ - { text: 'OK', click: function() { if($(this).data("closeCallback")) {$(this).data("closeCallback")();} $(this).dialog('close'); } } - ] - }); - + window.dialogID = 0; window.alert = function(text, isHTML, closeCallback) { - var h = isHTML ? text : window.convertTextToTableMagic(text); - $('#dialog').data("closeCallback", closeCallback); - $('#dialog').html(h).dialog('open'); + var id = 'dialog-' + window.dialogID++; + $('body').append('
'); + $('#' + id).dialog({ + autoOpen: false, + modal: false, + data: {closeCallback: closeCallback}, + buttons: { + 'OK': function() { + if($(this).data("closeCallback")) { + $(this).data("closeCallback")(); + } + $(this).dialog('close'); + } + } + }).html(isHTML ? text : window.convertTextToTableMagic(text)).dialog('open'); } } diff --git a/main.js b/main.js index 0431d98e..f74a5c2e 100644 --- a/main.js +++ b/main.js @@ -97,8 +97,7 @@ document.getElementsByTagName('body')[0].innerHTML = '' + ' ' + ' ' + '' - + '
' - + '
'; + + '
'; // putting everything in a wrapper function that in turn is placed in a // script tag on the website allows us to execute in the site’s context diff --git a/style.css b/style.css index 5ebfdb69..712afe6b 100644 --- a/style.css +++ b/style.css @@ -732,9 +732,9 @@ h3 { opacity: 0.6; } -.ui-dialog-titlebar { +/*.ui-dialog-titlebar { display: none; -} +}*/ .ui-dialog-content { padding: 12px; From 84f5499c1819a653400d1acccb7fd1a119fc4ca9 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Mon, 6 May 2013 17:09:39 -0600 Subject: [PATCH 02/13] * Window manager stuff. Multiple windows can be opened now. Still resolving bugs. --- code/boot.js | 21 ------------- code/dialog.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++ code/redeeming.js | 40 +++++++++++++++--------- main.js | 3 +- style.css | 27 ++++++++++++----- 5 files changed, 125 insertions(+), 43 deletions(-) create mode 100644 code/dialog.js diff --git a/code/boot.js b/code/boot.js index 064241be..3ad6790d 100644 --- a/code/boot.js +++ b/code/boot.js @@ -339,27 +339,6 @@ window.setupTooltips = function(element) { } } -window.setupDialogs = function() { - window.dialogID = 0; - window.alert = function(text, isHTML, closeCallback) { - var id = 'dialog-' + window.dialogID++; - $('body').append('
'); - $('#' + id).dialog({ - autoOpen: false, - modal: false, - data: {closeCallback: closeCallback}, - buttons: { - 'OK': function() { - if($(this).data("closeCallback")) { - $(this).data("closeCallback")(); - } - $(this).dialog('close'); - } - } - }).html(isHTML ? text : window.convertTextToTableMagic(text)).dialog('open'); - } -} - window.setupTaphold = function() { @@INCLUDERAW:external/taphold.js@@ } diff --git a/code/dialog.js b/code/dialog.js new file mode 100644 index 00000000..5d53d0f0 --- /dev/null +++ b/code/dialog.js @@ -0,0 +1,77 @@ +// DIALOGS ///////////////////////////////////////////////////////// + +/* The ID of onscreen dialogs. + * Starts at 0. + */ +window.DIALOG_ID = 0; + +/* All onscreen dialogs, keyed by their ID. + */ +window.DIALOGS = {}; + +/* Creates a dialog and puts it onscreen. Takes one parameter: options. + * (text|html): The text or HTML to display in the dialog. Text is auto-converted to HTML. + * title: The dialog's title + */ +window.dialog = function(options) { + var id = 'dialog-' + window.DIALOG_ID++; + var jqID = '#' + id; + + var html = ''; + if(options.text) { + html = window.convertTextToTableMagic(options.text); + } else if(options.html) { + html = options.html; + } else { + console.log('window.dialog: warning: no text in dialog'); + html = window.convertTextToTableMagic(''); + } + + $('body').append('
'); + window.DIALOGS[id] = $(jqID).dialog($.extend(true, { + autoOpen: false, + modal: false, + title: '#', + buttons: { + 'OK': function() { + $(this).dialog('close'); + } + }, + close: function(event, ui) { + console.log('window.dialog: dialog ' + $(this).dialog('option', 'title') + ' closed.'); + if($(this).data('closeCallback')) { + $(this).data('closeCallback')(); + } + + $($(this).data('jqID')).remove(); + delete window.DIALOGS[$(this).data('id')]; + } + }, options)); + + $(jqID).html(html); + $(jqID).data('closeCallback', options.closeCallback); + $(jqID).data('id', id); + $(jqID).data('jqID', jqID); + + $(jqID).dialog('open'); +} + +/* Deprecated. Creates a dialog with default settings. + * Use window.dialog instead. + */ +window.alert = function(text, isHTML, closeCallback) { + var obj = {closeCallback: closeCallback}; + if(isHTML) { + obj.html = text; + } else { + obj.text = text; + } + console.log('window.alert: this function is deprecated, please use window.dialog instead'); + + window.dialog(obj); +} + +window.setupDialogs = function() { + window.DIALOG_ID = 0; + window.DIALOGS = {}; +} diff --git a/code/redeeming.js b/code/redeeming.js index 1c4931de..399b501f 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -1,4 +1,3 @@ - // REDEEMING ///////////////////////////////////////////////////////// /* Resource type names mapped to actual names and abbreviations. @@ -93,11 +92,12 @@ window.REDEEM_HINTS = { }; window.handleRedeemResponse = function(data, textStatus, jqXHR) { - var passcode = this.passcode, to_alert, to_log; + var passcode = this.passcode, to_dialog, to_log, buttons; if(data.error) { - to_alert = '' + data.error + '
' + (window.REDEEM_ERRORS[data.error] || 'There was a problem redeeming the passcode. Try again?'); - to_log = '[ERROR] ' + data.error; + to_dialog = '' + data.error + '
' + (window.REDEEM_ERRORS[data.error] || 'There was a problem redeeming the passcode. Try again?'); + to_log = '[ERROR] ' + data.error; + buttons = {}; } else if(data.result) { var encouragement = window.REDEEM_ENCOURAGEMENT[Math.floor(Math.random() * window.REDEEM_ENCOURAGEMENT.length)]; var payload = {}; @@ -190,7 +190,7 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { // Let the user know if we had to guess if (inferred.length > 0) { - results.table.push('*Guessed (check console)'); + results.table.push('*Guessed (check console)'); $.each(inferred, function (idx, val) { console.log(passcode + ' => [INFERRED] ' + val.type + ':' + val.key + ' :: ' + @@ -198,17 +198,27 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { }); } - // Add table footers - results.table.push('>' + encouragement + '
' + results.html.join('/') + '') + - '\', true);" style="font-family: monospace;">[plaintext]
'); - // Display formatted versions in a table, plaintext, and the console log - to_alert = '' + results.table.map(function(a) {return '' + a + '';}).join("\n") + '
'; - to_log = '[SUCCESS] ' + results.plain.join('/'); + to_dialog = '' + + results.table.map(function(a) {return '' + a + '';}).join("\n") + + '
'; + to_log = '[SUCCESS] ' + results.plain.join('/'); + buttons = { + 'PLAINTEXT' : function() { + dialog({ + title: 'Passcode: ' + passcode, + html: '' + encouragement + '' + + '
' + results.html.join('/') + '
' + }); + } + } } - alert(to_alert, true); + dialog({ + title: 'Passcode: ' + passcode, + html: to_dialog, + buttons: buttons + }); console.log(passcode + ' => ' + to_log); } @@ -225,7 +235,9 @@ window.setupRedeem = function() { } else { extra = 'No status code was returned.'; } - alert('The HTTP request failed. ' + extra); + dialog({ + html: 'The HTTP request failed. ' + extra + }); }); }); } diff --git a/main.js b/main.js index f74a5c2e..91218bf4 100644 --- a/main.js +++ b/main.js @@ -61,7 +61,8 @@ document.getElementsByTagName('head')[0].innerHTML = '' + '' + '' //note: smartphone.css injection moved into code/smartphone.js - + ''; + + '' + + ''; document.getElementsByTagName('body')[0].innerHTML = '' + '
Loading, please wait
' diff --git a/style.css b/style.css index 915baecc..c01f4147 100644 --- a/style.css +++ b/style.css @@ -708,7 +708,7 @@ h3 { background-color: rgba(8, 48, 78, 0.9); border: 1px solid #20A8B1; color: #eee; - font: 13px/15px "Helvetica Neue", Arial, Helvetica, sans-serif; + font: 13px/15px Roboto, Arial, Helvetica, sans-serif; padding: 2px 4px; } @@ -732,9 +732,22 @@ h3 { opacity: 0.6; } -/*.ui-dialog-titlebar { - display: none; -}*/ +.ui-dialog-titlebar { + text-align: center; + padding: 4px; + background-color: rgba(8, 60, 78, 0.9); +} + +.ui-dialog-title { + padding: 2px; + font-weight: bold; +} + +.ui-dialog-titlebar-close { + position: absolute; + right: .2em; + top: 0; +} .ui-dialog-content { padding: 12px; @@ -756,7 +769,7 @@ h3 { .ui-dialog-buttonset button, .ui-dialog-content button { padding: 2px; - min-width: 80px; + min-width: 40px; color: #FFCE00; border: 1px solid #FFCE00; background-color: rgba(8, 48, 78, 0.9); @@ -782,12 +795,12 @@ td + td { #qrcode > canvas { border: 8px solid white; -} +} /* redeem results *****************************************************/ .redeem-result { font-size: 14px; - font-family: arial,helvetica,sans-serif; + font-family: Roboto, Arial, Helvetica, sans-serif; table-layout: fixed; } From 1f3dfacafc75a65f6506029e4e78a877b405ea10 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Mon, 6 May 2013 17:11:36 -0600 Subject: [PATCH 03/13] * Branding --- main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index 91218bf4..bc23ae46 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,8 @@ // ==UserScript== -// @id ingress-intel-total-conversion@jonatkins +// @id iitc@dovahkiin // @name IITC: Ingress intel map total conversion // @version 0.11.3.@@DATETIMEVERSION@@ -// @namespace https://github.com/jonatkins/ingress-intel-total-conversion +// @namespace http://git.stratosphe.re/dovahkiin/iitc.git // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ // @description [@@BUILDNAME@@-@@BUILDDATE@@] Total conversion for the ingress intel map. From 2bdeb13f456b57dc6c98f5ef58d4dba9d43088ee Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Tue, 7 May 2013 01:42:47 -0600 Subject: [PATCH 04/13] * Update redeeming.js to take advantage of new dialogs * Dialogs now support collapsing and expanding * Fix IITC about window - no longer resizes all onscreen dialogs --- code/dialog.js | 102 ++++++++++++++++++++++++++++++++++++++------- code/redeeming.js | 29 ++++++++----- code/utils_misc.js | 8 +++- style.css | 65 ++++++++++++++++++++++------- 4 files changed, 162 insertions(+), 42 deletions(-) diff --git a/code/dialog.js b/code/dialog.js index 5d53d0f0..33a3beb7 100644 --- a/code/dialog.js +++ b/code/dialog.js @@ -1,6 +1,7 @@ // DIALOGS ///////////////////////////////////////////////////////// +// Inspired by TES III: Morrowind. Long live House Telvanni. /////// -/* The ID of onscreen dialogs. +/* The global ID of onscreen dialogs. * Starts at 0. */ window.DIALOG_ID = 0; @@ -9,15 +10,32 @@ window.DIALOG_ID = 0; */ window.DIALOGS = {}; -/* Creates a dialog and puts it onscreen. Takes one parameter: options. +/* Creates a dialog and puts it onscreen. Takes one argument: options. + * Here are the most commonly used ones: + * * (text|html): The text or HTML to display in the dialog. Text is auto-converted to HTML. - * title: The dialog's title + * title: The dialog's title. + * closeCallback: A callback to run on close. + * modal: Whether to open a modal dialog. Implies draggable=false; dialogClass='ui-dialog-modal'. + * Please note that modal dialogs hijack the entire screen and should only be used in very + * specific cases. (If IITC is running on mobile, modal will always be true). + * + * See http://docs.jquery.com/UI/API/1.8/Dialog for a list of all the options. If you previously + * applied a class to your dialog after creating it with alert(), dialogClass may be particularly + * useful. */ window.dialog = function(options) { - var id = 'dialog-' + window.DIALOG_ID++; - var jqID = '#' + id; + // Override for smartphones. Preserve default behavior and create a modal dialog. + options = options || {}; + if(isSmartphone()) { + options.modal = true; + } + var id = 'dialog-' + (options.modal ? 'modal' : window.DIALOG_ID++); + var jqID = '#' + id; var html = ''; + + // Convert text to HTML if necessary if(options.text) { html = window.convertTextToTableMagic(options.text); } else if(options.html) { @@ -27,46 +45,102 @@ window.dialog = function(options) { html = window.convertTextToTableMagic(''); } + // Modal dialogs should not be draggable + if(options.modal) { + options.dialogClass = 'ui-dialog-modal'; + options.draggable = false; + } + + // Create the window, appending a div to the body $('body').append('
'); window.DIALOGS[id] = $(jqID).dialog($.extend(true, { autoOpen: false, modal: false, + draggable: true, title: '#', + closeText: 'X', buttons: { 'OK': function() { - $(this).dialog('close'); + $(this).dialog('close'); } }, - close: function(event, ui) { - console.log('window.dialog: dialog ' + $(this).dialog('option', 'title') + ' closed.'); + create: function(event, ui) { + var titlebar = $(this).closest('.ui-dialog').find('.ui-dialog-titlebar'); + var close = titlebar.find('.ui-dialog-titlebar-close'); + + // Title should not show up on mouseover + close.removeAttr('title').addClass('ui-dialog-titlebar-button'); + + if(!$(this).dialog('option', 'modal')) { + // Start out with a cloned version of the close button + var collapse = close.clone(); + + // Change it into a collapse button and set the click handler + collapse.addClass('ui-dialog-titlebar-button-collapse'); + collapse.find('.ui-button-text').html('–'); + collapse.click($.proxy(function() { + var collapsed = ($(this).data('collapsed') === true); + + // Find the button pane and content dialog in this ui-dialog, and add or remove the 'hidden' class + var selector = $(this).closest('.ui-dialog').find('.ui-dialog-content,.ui-dialog-buttonpane'); + if (collapsed) { + $(selector).removeClass('ui-dialog-content-hidden'); + } else { + $(selector).addClass('ui-dialog-content-hidden'); + } + + // Toggle collapsed state + $(this).data('collapsed', !collapsed); + }, this)); + + // Put it into the titlebar + titlebar.prepend(collapse); + close.addClass('ui-dialog-titlebar-button-close'); + } + }, + close: function(event, ui) { + // We're closing, so log it to the console + console.log('window.dialog: ' + id + ' (' + $(this).dialog('option', 'title') + ') closed.'); + + // Run the close callback if we have one if($(this).data('closeCallback')) { - $(this).data('closeCallback')(); + $.proxy($(this).data('closeCallback'), this)(); } + // Remove this window $($(this).data('jqID')).remove(); delete window.DIALOGS[$(this).data('id')]; } }, options)); + // Set HTML and IDs $(jqID).html(html); - $(jqID).data('closeCallback', options.closeCallback); $(jqID).data('id', id); $(jqID).data('jqID', jqID); + // Set the callback to be executed on close + $(jqID).data('closeCallback', options.closeCallback); + + // ui-modal includes overrides for modal dialogs + if (options.modal) { + $(jqID).parent().addClass('ui-modal'); + } + + // Run it $(jqID).dialog('open'); + return $(jqID); } -/* Deprecated. Creates a dialog with default settings. - * Use window.dialog instead. +/* Creates an alert dialog with default settings. + * If you want more configurability, use window.dialog instead. */ window.alert = function(text, isHTML, closeCallback) { - var obj = {closeCallback: closeCallback}; + var obj = {title: '', closeCallback: closeCallback}; if(isHTML) { obj.html = text; } else { obj.text = text; } - console.log('window.alert: this function is deprecated, please use window.dialog instead'); window.dialog(obj); } diff --git a/code/redeeming.js b/code/redeeming.js index 399b501f..47bb2fe8 100644 --- a/code/redeeming.js +++ b/code/redeeming.js @@ -92,12 +92,16 @@ window.REDEEM_HINTS = { }; window.handleRedeemResponse = function(data, textStatus, jqXHR) { - var passcode = this.passcode, to_dialog, to_log, buttons; + var passcode = this.passcode, to_dialog, to_log, dialog_title, dialog_buttons; if(data.error) { + // What to display to_dialog = '' + data.error + '
' + (window.REDEEM_ERRORS[data.error] || 'There was a problem redeeming the passcode. Try again?'); to_log = '[ERROR] ' + data.error; - buttons = {}; + + // Dialog options + dialog_title = 'Error: ' + passcode; + dialog_buttons = {}; } else if(data.result) { var encouragement = window.REDEEM_ENCOURAGEMENT[Math.floor(Math.random() * window.REDEEM_ENCOURAGEMENT.length)]; var payload = {}; @@ -199,32 +203,34 @@ window.handleRedeemResponse = function(data, textStatus, jqXHR) { } // Display formatted versions in a table, plaintext, and the console log - to_dialog = '' + + to_dialog = '
' + results.table.map(function(a) {return '' + a + '';}).join("\n") + '
'; to_log = '[SUCCESS] ' + results.plain.join('/'); - buttons = { + + dialog_title = 'Passcode: ' + passcode; + dialog_buttons = { 'PLAINTEXT' : function() { dialog({ - title: 'Passcode: ' + passcode, - html: '' + encouragement + '' + - '
' + results.html.join('/') + '
' + title: 'Rewards: ' + passcode, + html: '' + results.html.join('/') + '' }); } } } + // Display it dialog({ - title: 'Passcode: ' + passcode, - html: to_dialog, - buttons: buttons + title: dialog_title, + buttons: dialog_buttons, + html: to_dialog }); console.log(passcode + ' => ' + to_log); } window.setupRedeem = function() { $("#redeem").keypress(function(e) { - if((e.keyCode ? e.keyCode : e.which) !== 13) return; + if((e.keyCode ? e.keyCode : e.which) !== 13 || !$(this).val()) return; var data = {passcode: $(this).val()}; window.postAjax('redeemReward', data, window.handleRedeemResponse, @@ -236,6 +242,7 @@ window.setupRedeem = function() { extra = 'No status code was returned.'; } dialog({ + title: 'Request failed: ' + data.passcode, html: 'The HTTP request failed. ' + extra }); }); diff --git a/code/utils_misc.js b/code/utils_misc.js index dc9c6a6f..53b61c35 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -27,8 +27,12 @@ window.aboutIITC = function(){ + '
' + attrib + '
' + '
' + '
' + contrib + '
'; - alert(a, true, function() {$('.ui-dialog').removeClass('ui-dialog-aboutIITC');}); - $('.ui-dialog').addClass('ui-dialog-aboutIITC'); + dialog({ + title: 'IITC ' + v, + html: a, + dialogClass: 'ui-dialog-aboutIITC', + closeCallback: function() {$('.ui-dialog').removeClass('ui-dialog-aboutIITC');} + }); } diff --git a/style.css b/style.css index c01f4147..c4db1026 100644 --- a/style.css +++ b/style.css @@ -503,7 +503,7 @@ h3 { .mods span { background-color: rgba(0, 0, 0, 0.3); - /* can’t use inline-block because Webkit’s implementation is buggy and + /* can’t use inline-block because Webkit's implementation is buggy and * introduces additional margins in random cases. No clear necessary, * as that’s solved by setting height on .mods. */ display: block; @@ -666,7 +666,6 @@ h3 { font-size: 16px; } - /* update status */ #updatestatus { background-color: rgba(8, 48, 78, 0.9); @@ -712,6 +711,25 @@ h3 { padding: 2px 4px; } +.ui-widget-overlay { + height: 100%; + left: 0; + position: fixed; + top: 0; + width: 100%; + z-index: 10000; + background: #444; + opacity: 0.6; +} + +.ui-modal { + z-index: 10001 !important; +} + +.ui-tooltip { + z-index: 10002 !important; +} + .ui-tooltip, .ui-dialog a { color: #FFCE00; } @@ -721,15 +739,8 @@ h3 { border-radius: 2px; } -.ui-widget-overlay { - height: 100%; - left: 0; - position: fixed; - top: 0; - width: 100%; - z-index:9998; - background: #444; - opacity: 0.6; +.ui-dialog-modal .ui-dialog-titlebar-close { + display: none; } .ui-dialog-titlebar { @@ -743,10 +754,26 @@ h3 { font-weight: bold; } -.ui-dialog-titlebar-close { +.ui-dialog-titlebar-button { position: absolute; - right: .2em; - top: 0; + float: left; + width: 17px; + height: 19px; + top: 2px; + cursor: pointer; + color: #FFCE00; + font-family: "Arial", sans; + font-size: 14px; + border-style: none; + background-color: rgba(0, 0, 0, 0); +} + +.ui-dialog-titlebar-button-close { + right: 4px; +} + +.ui-dialog-titlebar-button-collapse { + right: 28px; } .ui-dialog-content { @@ -757,6 +784,10 @@ h3 { max-width: 700px !important; } +.ui-dialog-content-hidden { + display: none !important; +} + .ui-dialog-buttonpane { padding: 12px; border-top: 1px solid #20A8B1; @@ -798,7 +829,7 @@ td + td { } /* redeem results *****************************************************/ -.redeem-result { +.redeem-result-table { font-size: 14px; font-family: Roboto, Arial, Helvetica, sans-serif; table-layout: fixed; @@ -809,6 +840,10 @@ td + td { text-align: right; } +.redeem-result-html { + font-family: Inconsolata, Consolas, Menlo, "Courier New", monospace; +} + .pl_nudge_date { background-color: #724510; border-left: 1px solid #ffd652; From 42f151b3ac0511dada77787b6bf2358b40c0556d Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Tue, 7 May 2013 02:02:59 -0600 Subject: [PATCH 05/13] * Enable dialog snapping --- code/dialog.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/dialog.js b/code/dialog.js index 33a3beb7..e45e697d 100644 --- a/code/dialog.js +++ b/code/dialog.js @@ -126,6 +126,9 @@ window.dialog = function(options) { $(jqID).parent().addClass('ui-modal'); } + // Enable snapping + $(jqID).dialog().parents('.ui-dialog').draggable('option', 'snap', true); + // Run it $(jqID).dialog('open'); return $(jqID); From 9b56ac098243fad82db81b1fdd8aeee2a12197ad Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Tue, 7 May 2013 16:37:20 -0600 Subject: [PATCH 06/13] * Revert userscript headers from local build --- main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index bc23ae46..91218bf4 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,8 @@ // ==UserScript== -// @id iitc@dovahkiin +// @id ingress-intel-total-conversion@jonatkins // @name IITC: Ingress intel map total conversion // @version 0.11.3.@@DATETIMEVERSION@@ -// @namespace http://git.stratosphe.re/dovahkiin/iitc.git +// @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ // @description [@@BUILDNAME@@-@@BUILDDATE@@] Total conversion for the ingress intel map. From dfadadd2967d4c7ffb52fb2ec48dffbc0400b86b Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Wed, 8 May 2013 03:31:32 -0600 Subject: [PATCH 07/13] IITC Dialog Overhaul, part 2 Core changes * window_management.js => panes.js (clarity, distinction from dialogs) * Make portal preview use dialogs instead of the large preview "window" * Use `open' callback instead of `create' callback for all dialogs * Replace collapse/close buttons with themed buttons inspired by the AP Gain plugin * Dialogs can now gain and lose focus, with changing title bar * Tweak the Poslinks window to use dialogs * Add collapseCallback, expandCallback, collapseExpandCallback, focusCallback, and blurCallback * Fix http in About dialog that caused Chrome to complain Plugin changes * guess-player-level 0.4.1: Use dialogs with titles, typo fix * portal-counts 0.0.8: Use dialogs with titles, typo fix * portals-list 0.0.12: Don't hijack every single dialog onscreen, add titles, typo fix * scoreboard 0.1.8: Use dialogs with titles --- code/boot.js | 30 +++-- code/dialog.js | 146 +++++++++++++++++++----- code/{window_management.js => panes.js} | 0 code/portal_detail_display.js | 9 +- code/utils_misc.js | 16 ++- plugins/guess-player-levels.user.js | 9 +- plugins/portal-counts.user.js | 17 ++- plugins/portals-list.user.js | 25 ++-- plugins/scoreboard.user.js | 22 +++- style.css | 42 +++++-- 10 files changed, 224 insertions(+), 92 deletions(-) rename code/{window_management.js => panes.js} (100%) diff --git a/code/boot.js b/code/boot.js index db2411b9..09d56bf3 100644 --- a/code/boot.js +++ b/code/boot.js @@ -27,25 +27,23 @@ window.setupBackButton = function() { } } - - - window.setupLargeImagePreview = function() { $('#portaldetails').on('click', '.imgpreview', function() { - var ex = $('#largepreview'); - if(ex.length > 0) { - ex.remove(); - return; - } var img = $(this).find('img')[0]; - var w = img.naturalWidth/2; - var h = img.naturalHeight/2; - var c = $('#portaldetails').attr('class'); - $('body').append( - '
' + img.outerHTML + '
' - ); - $('#largepreview').click(function() { $(this).remove() }); - }); + var w = img.naturalWidth, c = $('#portaldetails').attr('class'); + var d = dialog({ + html: '' + img.outerHTML + '', + title: $(this).parent().find('h3.title').html() + }); + + // We have to dynamically set the width of this dialog, so get the .ui-dialog component + var p = d.parents('.ui-dialog'); + + // Don't let this dialog get smaller than the default maximum dialog width + var width = Math.max(parseInt(p.css('max-width')), w); + p.css('min-width', width + 'px'); + p.css('width', width + 'px'); + }); } // adds listeners to the layer chooser such that a long press hides diff --git a/code/dialog.js b/code/dialog.js index e45e697d..f818171b 100644 --- a/code/dialog.js +++ b/code/dialog.js @@ -1,5 +1,6 @@ // DIALOGS ///////////////////////////////////////////////////////// // Inspired by TES III: Morrowind. Long live House Telvanni. /////// +//////////////////////////////////////////////////////////////////// /* The global ID of onscreen dialogs. * Starts at 0. @@ -10,15 +11,33 @@ window.DIALOG_ID = 0; */ window.DIALOGS = {}; -/* Creates a dialog and puts it onscreen. Takes one argument: options. - * Here are the most commonly used ones: - * +/* The number of dialogs on screen. + */ +window.DIALOG_COUNT = 0; + +/* The dialog that has focus. + */ +window.DIALOG_FOCUS = null; + +/* Creates a dialog and puts it onscreen. Takes one argument: options, a JS object. + * == Common options * (text|html): The text or HTML to display in the dialog. Text is auto-converted to HTML. * title: The dialog's title. - * closeCallback: A callback to run on close. * modal: Whether to open a modal dialog. Implies draggable=false; dialogClass='ui-dialog-modal'. * Please note that modal dialogs hijack the entire screen and should only be used in very * specific cases. (If IITC is running on mobile, modal will always be true). + * id: A unique ID for this dialog. If a dialog with id `id' is already open and dialog() is called + * again, it will be automatically closed. + * + * == Callbacks + * closeCallback: A callback to run on close. Takes no arguments. + * collapseCallback: A callback to run on dialog collapse. Takes no arguments. + * expandCallback: A callback to run on dialog expansion. Takes no arguments. + * collapseExpandCallback: A callback to run on both collapse and expand (overrides collapseCallback + * and expandCallback, takes a boolean argument `collapsing' - true if collapsing; + * false if expanding) + * focusCallback: A callback to run when the dialog gains focus. + * blurCallback: A callback to run when the dialog loses focus. * * See http://docs.jquery.com/UI/API/1.8/Dialog for a list of all the options. If you previously * applied a class to your dialog after creating it with alert(), dialogClass may be particularly @@ -31,7 +50,8 @@ window.dialog = function(options) { options.modal = true; } - var id = 'dialog-' + (options.modal ? 'modal' : window.DIALOG_ID++); + // Build an identifier for this dialog + var id = 'dialog-' + (options.modal ? 'modal' : (options.id ? options.id : 'anonymous-' + window.DIALOG_ID++)); var jqID = '#' + id; var html = ''; @@ -49,23 +69,35 @@ window.dialog = function(options) { if(options.modal) { options.dialogClass = 'ui-dialog-modal'; options.draggable = false; + options.resizable = false; + } + + // Close out existing dialogs. + if(window.DIALOGS[id]) { + try { + window.DIALOGS[id].dialog('close'); + } catch(err) { + // This dialog doesn't exist anyway + } } // Create the window, appending a div to the body $('body').append('
'); - window.DIALOGS[id] = $(jqID).dialog($.extend(true, { + var dialog = $(jqID).dialog($.extend(true, { autoOpen: false, modal: false, draggable: true, + resizable: true, + closeText: ' ', title: '#', - closeText: 'X', buttons: { 'OK': function() { $(this).dialog('close'); } }, - create: function(event, ui) { + open: function() { var titlebar = $(this).closest('.ui-dialog').find('.ui-dialog-titlebar'); + titlebar.find('.ui-dialog-title').addClass('ui-dialog-title-active'); var close = titlebar.find('.ui-dialog-titlebar-close'); // Title should not show up on mouseover @@ -76,17 +108,33 @@ window.dialog = function(options) { var collapse = close.clone(); // Change it into a collapse button and set the click handler - collapse.addClass('ui-dialog-titlebar-button-collapse'); - collapse.find('.ui-button-text').html('–'); + collapse.addClass('ui-dialog-titlebar-button-collapse ui-dialog-titlebar-button-collapse-expanded'); collapse.click($.proxy(function() { var collapsed = ($(this).data('collapsed') === true); - // Find the button pane and content dialog in this ui-dialog, and add or remove the 'hidden' class - var selector = $(this).closest('.ui-dialog').find('.ui-dialog-content,.ui-dialog-buttonpane'); + // Run callbacks if we have them + if($(this).data('collapseExpandCallback')) { + $.proxy($(this).data('collapseExpandCallback'), this)(!collapsed); + } else { + if(collapsed && $(this).data('collapseCallback')) { + $.proxy($(this).data('collapseCallback'), this)(); + } else if (!collapsed && $(this).data('expandCallback')) { + $.proxy($(this).data('expandCallback'), this)(); + } + } + + // Find the button pane and content dialog in this ui-dialog, and add or remove the 'hidden' class. + var dialog = $(this).closest('.ui-dialog'); + var selector = dialog.find('.ui-dialog-content,.ui-dialog-buttonpane'); + var button = dialog.find('.ui-dialog-titlebar-button-collapse'); if (collapsed) { $(selector).removeClass('ui-dialog-content-hidden'); + $(button).removeClass('ui-dialog-titlebar-button-collapse-collapsed'); + $(button).addClass('ui-dialog-titlebar-button-collapse-expanded'); } else { $(selector).addClass('ui-dialog-content-hidden'); + $(button).removeClass('ui-dialog-titlebar-button-collapse-expanded'); + $(button).addClass('ui-dialog-titlebar-button-collapse-collapsed'); } // Toggle collapsed state @@ -97,41 +145,77 @@ window.dialog = function(options) { titlebar.prepend(collapse); close.addClass('ui-dialog-titlebar-button-close'); } - }, - close: function(event, ui) { - // We're closing, so log it to the console - console.log('window.dialog: ' + id + ' (' + $(this).dialog('option', 'title') + ') closed.'); + window.DIALOG_COUNT++; + + console.log('window.dialog: ' + $(this).data('id') + ' (' + $(this).dialog('option', 'title') + ') opened. ' + window.DIALOG_COUNT + ' remain.'); + }, + close: function() { // Run the close callback if we have one if($(this).data('closeCallback')) { $.proxy($(this).data('closeCallback'), this)(); } - // Remove this window - $($(this).data('jqID')).remove(); + // Make sure that we don't keep a dead dialog in focus + if(window.DIALOG_FOCUS && $(window.DIALOG_FOCUS).data('id') === $(this).data('id')) { + window.DIALOG_FOCUS = null; + } + + // Finalize delete window.DIALOGS[$(this).data('id')]; + + window.DIALOG_COUNT--; + console.log('window.dialog: ' + $(this).data('id') + ' (' + $(this).dialog('option', 'title') + ') closed. ' + window.DIALOG_COUNT + ' remain.'); + }, + focus: function() { + if($(this).data('focusCallback')) { + $.proxy($(this).data('focusCallback'), this)(); + } + + // Blur the window currently in focus unless we're gaining focus + if(window.DIALOG_FOCUS && $(window.DIALOG_FOCUS).data('id') !== $(this).data('id')) { + $.proxy(function(event, ui) { + if($(this).data('blurCallback')) { + $.proxy($(this).data('blurCallback'), this)(); + } + + $(this).closest('.ui-dialog').find('.ui-dialog-title').removeClass('ui-dialog-title-active').addClass('ui-dialog-title-inactive'); + }, window.DIALOG_FOCUS)(); + } + + // This dialog is now in focus + window.DIALOG_FOCUS = this; + $(this).closest('.ui-dialog').find('.ui-dialog-title').removeClass('ui-dialog-title-inactive').addClass('ui-dialog-title-active'); } }, options)); - // Set HTML and IDs - $(jqID).html(html); - $(jqID).data('id', id); - $(jqID).data('jqID', jqID); + window.DIALOGS[id] = dialog[0]; - // Set the callback to be executed on close - $(jqID).data('closeCallback', options.closeCallback); + // Set HTML and IDs + dialog.html(html); + dialog.data('id', id); + dialog.data('jqID', jqID); + + // Set callbacks + dialog.data('closeCallback', options.closeCallback); + dialog.data('collapseCallback', options.collapseCallback); + dialog.data('expandCallback', options.expandCallback); + dialog.data('collapseExpandCallback', options.collapseExpandCallback); + dialog.data('focusCallback', options.focusCallback); + dialog.data('blurCallback', options.blurCallback); // ui-modal includes overrides for modal dialogs if (options.modal) { - $(jqID).parent().addClass('ui-modal'); + dialog.parent().addClass('ui-modal'); } // Enable snapping - $(jqID).dialog().parents('.ui-dialog').draggable('option', 'snap', true); + dialog.dialog().parents('.ui-dialog').draggable('option', 'snap', true); // Run it - $(jqID).dialog('open'); - return $(jqID); + dialog.dialog('open'); + + return dialog; } /* Creates an alert dialog with default settings. @@ -145,10 +229,12 @@ window.alert = function(text, isHTML, closeCallback) { obj.text = text; } - window.dialog(obj); + return dialog(obj); } window.setupDialogs = function() { window.DIALOG_ID = 0; - window.DIALOGS = {}; + window.DIALOGS = {} + window.DIALOG_COUNT = 0; + window.DIALOG_FOCUS = null; } diff --git a/code/window_management.js b/code/panes.js similarity index 100% rename from code/window_management.js rename to code/panes.js diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index 0f02d879..ed2e3e8d 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -18,7 +18,7 @@ window.renderPortalDetails = function(guid) { if(d.portalV2.linkedEdges) $.each(d.portalV2.linkedEdges, function(ind, link) { links[link.isOrigin ? 'outgoing' : 'incoming']++; }); - function linkExpl(t) { return ''+t+''; } + function linkExpl(t) { return ''+t+''; } var linksText = [linkExpl('links'), linkExpl(' ↳ ' + links.incoming+'  •  '+links.outgoing+' ↴')]; var player = d.captured && d.captured.capturingPlayerId @@ -50,14 +50,13 @@ window.renderPortalDetails = function(guid) { var perma = '/intel?ll='+lat+','+lng+'&z=17&pll='+lat+','+lng; var imgTitle = 'title="'+getPortalDescriptionFromDetails(d)+'\n\nClick to show full image."'; var poslinks = 'window.showPortalPosLinks('+lat+','+lng+',\'' + d.portalV2.descriptiveText.TITLE + '\')'; - var postcard = 'Send in a postcard. Will put it online after receiving. Address:\\n\\nStefan Breunig\\nINF 305 – R045\\n69120 Heidelberg\\nGermany'; $('#portaldetails') .attr('class', TEAM_TO_CSS[getTeam(d)]) .html('' + '

'+d.portalV2.descriptiveText.TITLE+'

' + 'X' - // help cursor via “.imgpreview img” + // help cursor via ".imgpreview img" + '
' + '' + ''+Math.floor(getPortalLevel(d))+'' @@ -73,7 +72,7 @@ window.renderPortalDetails = function(guid) { ); // try to resolve names that were required for above functions, but - // weren’t available yet. + // weren't available yet. resolvePlayerNames(); runHooks('portalDetailsUpdated', {portalDetails: d}); @@ -107,7 +106,7 @@ window.clearPortalIndicators = function() { // highlights portal with given GUID. Automatically clears highlights // on old selection. Returns false if the selected portal changed. -// Returns true if it’s still the same portal that just needs an +// Returns true if it's still the same portal that just needs an // update. window.selectPortal = function(guid) { var update = selectedPortal === guid; diff --git a/code/utils_misc.js b/code/utils_misc.js index 53b61c35..c3966db4 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -19,7 +19,7 @@ window.aboutIITC = function(){ + ' ' + '
' + '
' - + ' MapQuest OSM tiles Courtesy of MapQuest ' + + ' MapQuest OSM tiles Courtesy of MapQuest ' + '
' + '
' + '
Version: ' + v + '
' @@ -139,19 +139,23 @@ window.rangeLinkClick = function() { } window.showPortalPosLinks = function(lat, lng, name) { - var portal_name = ''; + var encoded_name = ''; if(name !== undefined) { - portal_name = encodeURIComponent(' (' + name + ')'); + encoded_name = encodeURIComponent(' (' + name + ')'); } if (typeof android !== 'undefined' && android && android.intentPosLink) { android.intentPosLink(lat, lng, portal_name); } else { var qrcode = '
'; var script = ''; - var gmaps = 'Google maps'; + var gmaps = 'Google Maps'; var osm = 'OpenStreetMap'; - var latLng = ''+lat+','+lng +''; - alert('
' + qrcode + script + gmaps + ' ' + osm + '
' + latLng + '
'); + var latLng = '<' + lat + ',' + lng +'>'; + dialog({ + html: '
' + qrcode + script + gmaps + '; ' + osm + '
' + latLng + '
', + title: name, + id: 'poslinks' + }); } } diff --git a/plugins/guess-player-levels.user.js b/plugins/guess-player-levels.user.js index daf5ab7a..2a9582e2 100644 --- a/plugins/guess-player-levels.user.js +++ b/plugins/guess-player-levels.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-guess-player-levels@breunigs // @name IITC plugin: guess player level -// @version 0.4.0.@@DATETIMEVERSION@@ +// @version 0.4.1.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -101,7 +101,7 @@ window.plugin.guessPlayerLevels.guess = function() { }); }); - var s = 'the players have at least the following level:\n\n'; + var s = 'Players have at least the following level:\n\n'; s += 'Resistance:\t   \tEnlightened:\t\n'; var namesR = plugin.guessPlayerLevels.sort(playersRes); @@ -132,7 +132,10 @@ window.plugin.guessPlayerLevels.guess = function() { s += '\nAverage level:\t'+averageR.toFixed(2)+'\tAverage level:\t'+averageE.toFixed(2); s += '\n\nIf there are some unresolved names, simply try again.' //console.log(s); - alert(s); + dialog({ + text: s, + title: 'Player levels: R' + averageR.toFixed(2) + ', E' + averageE.toFixed(2) + }); } window.plugin.guessPlayerLevels.sort = function(playerHash) { diff --git a/plugins/portal-counts.user.js b/plugins/portal-counts.user.js index 76800b97..b0b699bd 100644 --- a/plugins/portal-counts.user.js +++ b/plugins/portal-counts.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-portals-count@yenky // @name IITC plugin: Show total counts of portals -// @version 0.0.7.@@DATETIMEVERSION@@ +// @version 0.0.8.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -13,6 +13,7 @@ // ==/UserScript== /* whatsnew +* 0.0.8 : use dialog() instead of alert() * 0.0.6 : ignoring outside bounds portals (even if close to) * 0.0.5 : changed table layout, added some colors * 0.0.4 : reverse show order of portals, using MAX_PORTAL_LEVEL now for array, changed table layout to be more compact, cleaned up code @@ -74,7 +75,7 @@ window.plugin.portalcounts.getPortals = function(){ var counts = ''; if(retval) { - counts += ''; //'+window.plugin.portalcounts.enlP+' Portal(s)'; + counts += ''; //'+window.plugin.portalcounts.enlP+' Portal(s)'; for(var level = window.MAX_PORTAL_LEVEL; level > 0; level--){ counts += ''; if(minlvl > level) @@ -90,12 +91,18 @@ window.plugin.portalcounts.getPortals = function(){ else counts += window.plugin.portalcounts.neuP; counts += ' Portal(s)'; - counts += ''; + counts += ''; counts += ''; } else - counts += ''; + counts += ''; counts += '
EnlightmentResistance
EnlightenedResistance
Level '+level+'
Enlightment:'+window.plugin.portalcounts.enlP+' Portal(s)
Enlightened:'+window.plugin.portalcounts.enlP+' Portal(s)
Resistance:'+window.plugin.portalcounts.resP+' Portal(s)
No Portals in range !
No Portals in range!
'; - alert('
'+counts+'
'); + + + var total = window.plugin.portalcounts.enlP + window.plugin.portalcounts.resP + window.plugin.portalcounts.neuP; + dialog({ + html: '
' + counts + '
', + title: 'Portal counts: ' + total + ' ' + (total == 1 ? 'portal' : 'portals'), + }); } var setup = function() { diff --git a/plugins/portals-list.user.js b/plugins/portals-list.user.js index 3877d5c3..fdb94300 100644 --- a/plugins/portals-list.user.js +++ b/plugins/portals-list.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @id iitc-plugin-portals-list@teo96 // @name IITC plugin: show list of portals -// @version 0.0.11.@@DATETIMEVERSION@@ +// @version 0.0.12.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -13,6 +13,7 @@ // ==/UserScript== /* whatsnew +* 0.0.12: Use dialog() instead of alert so the user can drag the box around * 0.0.11: Add nominal energy column and # links, fix sort bug when opened even amounts of times, nits * 0.0.10: Fixed persistent css problem with alert * 0.0.9 : bugs hunt @@ -120,13 +121,15 @@ window.plugin.portalslist.displayPL = function() { if (window.plugin.portalslist.getPortals()) { html += window.plugin.portalslist.portalTable('level', window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter); } else { - html = '
Nothing to Show !
'; + html = '
Nothing to show!
'; }; - alert('
' + html + '
', true, function() { - $(".ui-dialog").removeClass('ui-dialog-portalslist'); - $(document).off('.portalslist'); - }); - $(".ui-dialog").addClass('ui-dialog-portalslist'); + + dialog({ + html: '
' + html + '
', + dialogClass: 'ui-dialog-portalslist', + title: 'Portal list: ' + window.plugin.portalslist.listPortals.length + ' ' + (window.plugin.portalslist.listPortals.length == 1 ? 'portal' : 'portals'), + id: 'portal-list' + }); // Setup sorting $(document).on('click.portalslist', '#portalslist table th', function() { @@ -264,7 +267,7 @@ window.plugin.portalslist.portalTable = function(sortBy, sortOrder, filter) { html += ''; html += '
Click on portals table headers to sort by that column. ' - + 'Click on All Portals, Resistant Portals, Enlightened Portals to filter
' + + 'Click on All Portals, Resistance Portals, Enlightened Portals to filter
' + 'Thanks to @vita10gy & @xelio for their IITC plugins who inspired me. A @teo96 production. Vive la Résistance !
'; window.plugin.portalslist.sortOrder = window.plugin.portalslist.sortOrder*-1; @@ -275,7 +278,7 @@ window.plugin.portalslist.stats = function(sortBy) { //console.log('** stats'); var html = '' + '' - + '' + + '' + '' + '' + '
All Portals : (click to filter)' + window.plugin.portalslist.listPortals.length + 'Resistant Portals : ' + window.plugin.portalslist.resP +' (' + Math.floor(window.plugin.portalslist.resP/window.plugin.portalslist.listPortals.length*100) + '%)Resistance Portals : ' + window.plugin.portalslist.resP +' (' + Math.floor(window.plugin.portalslist.resP/window.plugin.portalslist.listPortals.length*100) + '%)Enlightened Portals : '+ window.plugin.portalslist.enlP +' (' + Math.floor(window.plugin.portalslist.enlP/window.plugin.portalslist.listPortals.length*100) + '%)
'; @@ -318,8 +321,8 @@ window.plugin.portalslist.getPortalLink = function(portal,guid) { var setup = function() { $('#toolbox').append(' Portals list'); $('head').append('