1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

DarkConsole: fix rendering, move request log, load over ajax

Summary:
This accomplishes three major goals:

  # Fixes phutil_render_tag -> phutil_tag callsites in DarkConsole.
  # Moves the Ajax request log to a new panel on the left. This panel (and the tabs panel) get scrollbars when they get large, instead of making the page constantly scroll down.
  # Loads the panel content over ajax, instead of dumping it into the page body / ajax response body. I've been planning to do this for about 3 years, which is why the plugins are architected the way they are. This should make debugging easier by making response bodies not be 50%+ darkconsole stuff.

Additionally, load the plugins dynamically (the old method predates library maps and PhutilSymbolLoader).

Test Plan:
{F30675}

  - Switched between requests and tabs, reloaded page, saw same tab.
  - Used "analyze queries", "profile page", triggered errors.
  - Verified page does not load anything by default if dark console is closed with Charles.
  - Generally banged on it a bit.

Reviewers: vrana, btrahan, chad

Reviewed By: vrana

CC: aran

Maniphest Tasks: T2432

Differential Revision: https://secure.phabricator.com/D4692
This commit is contained in:
epriestley 2013-01-28 18:45:32 -08:00
parent 9a0ae6376f
commit 114ed6c7fe
18 changed files with 560 additions and 481 deletions

View file

@ -166,7 +166,6 @@ $package_spec = array(
'javelin-behavior-maniphest-subpriority-editor', 'javelin-behavior-maniphest-subpriority-editor',
), ),
'darkconsole.pkg.js' => array( 'darkconsole.pkg.js' => array(
'javelin-behavior-dark-console-ajax',
'javelin-behavior-dark-console', 'javelin-behavior-dark-console',
'javelin-behavior-error-log', 'javelin-behavior-error-log',
), ),

View file

@ -42,6 +42,13 @@ celerity_register_resource_map(array(
'disk' => '/rsrc/image/credit_cards.png', 'disk' => '/rsrc/image/credit_cards.png',
'type' => 'png', 'type' => 'png',
), ),
'/rsrc/image/darkload.gif' =>
array(
'hash' => '3a52cb7145d6e70f461fed21273117f2',
'uri' => '/res/3a52cb71/rsrc/image/darkload.gif',
'disk' => '/rsrc/image/darkload.gif',
'type' => 'gif',
),
'/rsrc/image/divot.png' => '/rsrc/image/divot.png' =>
array( array(
'hash' => '3be267bd11ea375bf68e808893718e0e', 'hash' => '3be267bd11ea375bf68e808893718e0e',
@ -598,7 +605,7 @@ celerity_register_resource_map(array(
), ),
'aphront-dark-console-css' => 'aphront-dark-console-css' =>
array( array(
'uri' => '/res/1e1f78d4/rsrc/css/aphront/dark-console.css', 'uri' => '/res/63841304/rsrc/css/aphront/dark-console.css',
'type' => 'css', 'type' => 'css',
'requires' => 'requires' =>
array( array(
@ -1057,7 +1064,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-aphront-form-disable-on-submit' => 'javelin-behavior-aphront-form-disable-on-submit' =>
array( array(
'uri' => '/res/ca54e8b9/rsrc/js/application/core/behavior-form.js', 'uri' => '/res/70fd43fd/rsrc/js/application/core/behavior-form.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1145,7 +1152,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-dark-console' => 'javelin-behavior-dark-console' =>
array( array(
'uri' => '/res/aa6f8a71/rsrc/js/application/core/behavior-dark-console.js', 'uri' => '/res/c3e8a3d8/rsrc/js/application/core/behavior-dark-console.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1155,21 +1162,9 @@ celerity_register_resource_map(array(
3 => 'javelin-dom', 3 => 'javelin-dom',
4 => 'javelin-request', 4 => 'javelin-request',
5 => 'phabricator-keyboard-shortcut', 5 => 'phabricator-keyboard-shortcut',
6 => 'javelin-behavior-dark-console-ajax',
), ),
'disk' => '/rsrc/js/application/core/behavior-dark-console.js', 'disk' => '/rsrc/js/application/core/behavior-dark-console.js',
), ),
'javelin-behavior-dark-console-ajax' =>
array(
'uri' => '/res/ac3ab63a/rsrc/js/application/core/behavior-dark-console-ajax.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-dark-console-ajax.js',
),
'javelin-behavior-device' => 'javelin-behavior-device' =>
array( array(
'uri' => '/res/a10b851b/rsrc/js/application/core/behavior-device.js', 'uri' => '/res/a10b851b/rsrc/js/application/core/behavior-device.js',
@ -1493,7 +1488,7 @@ celerity_register_resource_map(array(
), ),
'javelin-behavior-lightbox-attachments' => 'javelin-behavior-lightbox-attachments' =>
array( array(
'uri' => '/res/5efba371/rsrc/js/application/core/behavior-lightbox-attachments.js', 'uri' => '/res/08f5e202/rsrc/js/application/core/behavior-lightbox-attachments.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -1986,7 +1981,7 @@ celerity_register_resource_map(array(
), ),
'javelin-dom' => 'javelin-dom' =>
array( array(
'uri' => '/res/2826c532/rsrc/js/javelin/lib/DOM.js', 'uri' => '/res/459f3c08/rsrc/js/javelin/lib/DOM.js',
'type' => 'js', 'type' => 'js',
'requires' => 'requires' =>
array( array(
@ -3393,7 +3388,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/023adc14/core.pkg.css', 'uri' => '/res/pkg/023adc14/core.pkg.css',
'type' => 'css', 'type' => 'css',
), ),
'66dca903' => 'b3c1b6e7' =>
array( array(
'name' => 'core.pkg.js', 'name' => 'core.pkg.js',
'symbols' => 'symbols' =>
@ -3432,19 +3427,18 @@ celerity_register_resource_map(array(
31 => 'javelin-behavior-global-drag-and-drop', 31 => 'javelin-behavior-global-drag-and-drop',
32 => 'javelin-behavior-phabricator-home-reveal-tiles', 32 => 'javelin-behavior-phabricator-home-reveal-tiles',
), ),
'uri' => '/res/pkg/66dca903/core.pkg.js', 'uri' => '/res/pkg/b3c1b6e7/core.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'8edbada5' => '032118cf' =>
array( array(
'name' => 'darkconsole.pkg.js', 'name' => 'darkconsole.pkg.js',
'symbols' => 'symbols' =>
array( array(
0 => 'javelin-behavior-dark-console-ajax', 0 => 'javelin-behavior-dark-console',
1 => 'javelin-behavior-dark-console', 1 => 'javelin-behavior-error-log',
2 => 'javelin-behavior-error-log',
), ),
'uri' => '/res/pkg/8edbada5/darkconsole.pkg.js', 'uri' => '/res/pkg/032118cf/darkconsole.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'ec01d039' => 'ec01d039' =>
@ -3521,7 +3515,7 @@ celerity_register_resource_map(array(
'uri' => '/res/pkg/f96657b8/diffusion.pkg.js', 'uri' => '/res/pkg/f96657b8/diffusion.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'fbeded59' => '1c6f020b' =>
array( array(
'name' => 'javelin.pkg.js', 'name' => 'javelin.pkg.js',
'symbols' => 'symbols' =>
@ -3546,7 +3540,7 @@ celerity_register_resource_map(array(
17 => 'javelin-typeahead-ondemand-source', 17 => 'javelin-typeahead-ondemand-source',
18 => 'javelin-tokenizer', 18 => 'javelin-tokenizer',
), ),
'uri' => '/res/pkg/fbeded59/javelin.pkg.js', 'uri' => '/res/pkg/1c6f020b/javelin.pkg.js',
'type' => 'js', 'type' => 'js',
), ),
'e30a3fa8' => 'e30a3fa8' =>
@ -3608,18 +3602,17 @@ celerity_register_resource_map(array(
'diffusion-icons-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => '023adc14', 'global-drag-and-drop-css' => '023adc14',
'inline-comment-summary-css' => 'ec01d039', 'inline-comment-summary-css' => 'ec01d039',
'javelin-aphlict' => '66dca903', 'javelin-aphlict' => 'b3c1b6e7',
'javelin-behavior' => 'fbeded59', 'javelin-behavior' => '1c6f020b',
'javelin-behavior-aphlict-dropdown' => '66dca903', 'javelin-behavior-aphlict-dropdown' => 'b3c1b6e7',
'javelin-behavior-aphlict-listen' => '66dca903', 'javelin-behavior-aphlict-listen' => 'b3c1b6e7',
'javelin-behavior-aphront-basic-tokenizer' => '66dca903', 'javelin-behavior-aphront-basic-tokenizer' => 'b3c1b6e7',
'javelin-behavior-aphront-drag-and-drop' => '310cd201', 'javelin-behavior-aphront-drag-and-drop' => '310cd201',
'javelin-behavior-aphront-drag-and-drop-textarea' => '310cd201', 'javelin-behavior-aphront-drag-and-drop-textarea' => '310cd201',
'javelin-behavior-aphront-form-disable-on-submit' => '66dca903', 'javelin-behavior-aphront-form-disable-on-submit' => 'b3c1b6e7',
'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-audit-preview' => 'f96657b8',
'javelin-behavior-dark-console' => '8edbada5', 'javelin-behavior-dark-console' => '032118cf',
'javelin-behavior-dark-console-ajax' => '8edbada5', 'javelin-behavior-device' => 'b3c1b6e7',
'javelin-behavior-device' => '66dca903',
'javelin-behavior-differential-accept-with-errors' => '310cd201', 'javelin-behavior-differential-accept-with-errors' => '310cd201',
'javelin-behavior-differential-add-reviewers-and-ccs' => '310cd201', 'javelin-behavior-differential-add-reviewers-and-ccs' => '310cd201',
'javelin-behavior-differential-comment-jump' => '310cd201', 'javelin-behavior-differential-comment-jump' => '310cd201',
@ -3634,84 +3627,84 @@ celerity_register_resource_map(array(
'javelin-behavior-differential-user-select' => '310cd201', 'javelin-behavior-differential-user-select' => '310cd201',
'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
'javelin-behavior-error-log' => '8edbada5', 'javelin-behavior-error-log' => '032118cf',
'javelin-behavior-global-drag-and-drop' => '66dca903', 'javelin-behavior-global-drag-and-drop' => 'b3c1b6e7',
'javelin-behavior-konami' => '66dca903', 'javelin-behavior-konami' => 'b3c1b6e7',
'javelin-behavior-lightbox-attachments' => '66dca903', 'javelin-behavior-lightbox-attachments' => 'b3c1b6e7',
'javelin-behavior-maniphest-batch-selector' => '7707de41', 'javelin-behavior-maniphest-batch-selector' => '7707de41',
'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 'javelin-behavior-maniphest-subpriority-editor' => '7707de41',
'javelin-behavior-maniphest-transaction-controls' => '7707de41', 'javelin-behavior-maniphest-transaction-controls' => '7707de41',
'javelin-behavior-maniphest-transaction-expand' => '7707de41', 'javelin-behavior-maniphest-transaction-expand' => '7707de41',
'javelin-behavior-maniphest-transaction-preview' => '7707de41', 'javelin-behavior-maniphest-transaction-preview' => '7707de41',
'javelin-behavior-phabricator-active-nav' => '66dca903', 'javelin-behavior-phabricator-active-nav' => 'b3c1b6e7',
'javelin-behavior-phabricator-autofocus' => '66dca903', 'javelin-behavior-phabricator-autofocus' => 'b3c1b6e7',
'javelin-behavior-phabricator-home-reveal-tiles' => '66dca903', 'javelin-behavior-phabricator-home-reveal-tiles' => 'b3c1b6e7',
'javelin-behavior-phabricator-keyboard-shortcuts' => '66dca903', 'javelin-behavior-phabricator-keyboard-shortcuts' => 'b3c1b6e7',
'javelin-behavior-phabricator-nav' => '66dca903', 'javelin-behavior-phabricator-nav' => 'b3c1b6e7',
'javelin-behavior-phabricator-object-selector' => '310cd201', 'javelin-behavior-phabricator-object-selector' => '310cd201',
'javelin-behavior-phabricator-oncopy' => '66dca903', 'javelin-behavior-phabricator-oncopy' => 'b3c1b6e7',
'javelin-behavior-phabricator-remarkup-assist' => '66dca903', 'javelin-behavior-phabricator-remarkup-assist' => 'b3c1b6e7',
'javelin-behavior-phabricator-search-typeahead' => '66dca903', 'javelin-behavior-phabricator-search-typeahead' => 'b3c1b6e7',
'javelin-behavior-phabricator-tooltips' => '66dca903', 'javelin-behavior-phabricator-tooltips' => 'b3c1b6e7',
'javelin-behavior-phabricator-watch-anchor' => '66dca903', 'javelin-behavior-phabricator-watch-anchor' => 'b3c1b6e7',
'javelin-behavior-refresh-csrf' => '66dca903', 'javelin-behavior-refresh-csrf' => 'b3c1b6e7',
'javelin-behavior-repository-crossreference' => '310cd201', 'javelin-behavior-repository-crossreference' => '310cd201',
'javelin-behavior-toggle-class' => '66dca903', 'javelin-behavior-toggle-class' => 'b3c1b6e7',
'javelin-behavior-workflow' => '66dca903', 'javelin-behavior-workflow' => 'b3c1b6e7',
'javelin-dom' => 'fbeded59', 'javelin-dom' => '1c6f020b',
'javelin-event' => 'fbeded59', 'javelin-event' => '1c6f020b',
'javelin-install' => 'fbeded59', 'javelin-install' => '1c6f020b',
'javelin-json' => 'fbeded59', 'javelin-json' => '1c6f020b',
'javelin-mask' => 'fbeded59', 'javelin-mask' => '1c6f020b',
'javelin-request' => 'fbeded59', 'javelin-request' => '1c6f020b',
'javelin-resource' => 'fbeded59', 'javelin-resource' => '1c6f020b',
'javelin-stratcom' => 'fbeded59', 'javelin-stratcom' => '1c6f020b',
'javelin-tokenizer' => 'fbeded59', 'javelin-tokenizer' => '1c6f020b',
'javelin-typeahead' => 'fbeded59', 'javelin-typeahead' => '1c6f020b',
'javelin-typeahead-normalizer' => 'fbeded59', 'javelin-typeahead-normalizer' => '1c6f020b',
'javelin-typeahead-ondemand-source' => 'fbeded59', 'javelin-typeahead-ondemand-source' => '1c6f020b',
'javelin-typeahead-preloaded-source' => 'fbeded59', 'javelin-typeahead-preloaded-source' => '1c6f020b',
'javelin-typeahead-source' => 'fbeded59', 'javelin-typeahead-source' => '1c6f020b',
'javelin-uri' => 'fbeded59', 'javelin-uri' => '1c6f020b',
'javelin-util' => 'fbeded59', 'javelin-util' => '1c6f020b',
'javelin-vector' => 'fbeded59', 'javelin-vector' => '1c6f020b',
'javelin-workflow' => 'fbeded59', 'javelin-workflow' => '1c6f020b',
'lightbox-attachment-css' => '023adc14', 'lightbox-attachment-css' => '023adc14',
'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-task-summary-css' => 'e30a3fa8',
'maniphest-transaction-detail-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8',
'phabricator-busy' => '66dca903', 'phabricator-busy' => 'b3c1b6e7',
'phabricator-content-source-view-css' => 'ec01d039', 'phabricator-content-source-view-css' => 'ec01d039',
'phabricator-core-buttons-css' => '023adc14', 'phabricator-core-buttons-css' => '023adc14',
'phabricator-core-css' => '023adc14', 'phabricator-core-css' => '023adc14',
'phabricator-crumbs-view-css' => '023adc14', 'phabricator-crumbs-view-css' => '023adc14',
'phabricator-directory-css' => '023adc14', 'phabricator-directory-css' => '023adc14',
'phabricator-drag-and-drop-file-upload' => '310cd201', 'phabricator-drag-and-drop-file-upload' => '310cd201',
'phabricator-dropdown-menu' => '66dca903', 'phabricator-dropdown-menu' => 'b3c1b6e7',
'phabricator-file-upload' => '66dca903', 'phabricator-file-upload' => 'b3c1b6e7',
'phabricator-filetree-view-css' => '023adc14', 'phabricator-filetree-view-css' => '023adc14',
'phabricator-flag-css' => '023adc14', 'phabricator-flag-css' => '023adc14',
'phabricator-form-view-css' => '023adc14', 'phabricator-form-view-css' => '023adc14',
'phabricator-header-view-css' => '023adc14', 'phabricator-header-view-css' => '023adc14',
'phabricator-jump-nav' => '023adc14', 'phabricator-jump-nav' => '023adc14',
'phabricator-keyboard-shortcut' => '66dca903', 'phabricator-keyboard-shortcut' => 'b3c1b6e7',
'phabricator-keyboard-shortcut-manager' => '66dca903', 'phabricator-keyboard-shortcut-manager' => 'b3c1b6e7',
'phabricator-main-menu-view' => '023adc14', 'phabricator-main-menu-view' => '023adc14',
'phabricator-menu-item' => '66dca903', 'phabricator-menu-item' => 'b3c1b6e7',
'phabricator-nav-view-css' => '023adc14', 'phabricator-nav-view-css' => '023adc14',
'phabricator-notification' => '66dca903', 'phabricator-notification' => 'b3c1b6e7',
'phabricator-notification-css' => '023adc14', 'phabricator-notification-css' => '023adc14',
'phabricator-notification-menu-css' => '023adc14', 'phabricator-notification-menu-css' => '023adc14',
'phabricator-object-item-list-view-css' => '023adc14', 'phabricator-object-item-list-view-css' => '023adc14',
'phabricator-object-selector-css' => 'ec01d039', 'phabricator-object-selector-css' => 'ec01d039',
'phabricator-paste-file-upload' => '66dca903', 'phabricator-paste-file-upload' => 'b3c1b6e7',
'phabricator-prefab' => '66dca903', 'phabricator-prefab' => 'b3c1b6e7',
'phabricator-project-tag-css' => 'e30a3fa8', 'phabricator-project-tag-css' => 'e30a3fa8',
'phabricator-remarkup-css' => '023adc14', 'phabricator-remarkup-css' => '023adc14',
'phabricator-shaped-request' => '310cd201', 'phabricator-shaped-request' => '310cd201',
'phabricator-side-menu-view-css' => '023adc14', 'phabricator-side-menu-view-css' => '023adc14',
'phabricator-standard-page-view' => '023adc14', 'phabricator-standard-page-view' => '023adc14',
'phabricator-textareautils' => '66dca903', 'phabricator-textareautils' => 'b3c1b6e7',
'phabricator-tooltip' => '66dca903', 'phabricator-tooltip' => 'b3c1b6e7',
'phabricator-transaction-view-css' => '023adc14', 'phabricator-transaction-view-css' => '023adc14',
'phabricator-zindex-css' => '023adc14', 'phabricator-zindex-css' => '023adc14',
'sprite-apps-large-css' => '023adc14', 'sprite-apps-large-css' => '023adc14',

View file

@ -218,6 +218,7 @@ phutil_register_library_map(array(
'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php', 'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
'DarkConsoleController' => 'aphront/console/DarkConsoleController.php', 'DarkConsoleController' => 'aphront/console/DarkConsoleController.php',
'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php', 'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php',
'DarkConsoleDataController' => 'aphront/console/DarkConsoleDataController.php',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/DarkConsoleErrorLogPlugin.php', 'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/DarkConsoleErrorLogPlugin.php',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php', 'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
'DarkConsoleEventPlugin' => 'aphront/console/plugin/DarkConsoleEventPlugin.php', 'DarkConsoleEventPlugin' => 'aphront/console/plugin/DarkConsoleEventPlugin.php',
@ -1693,6 +1694,7 @@ phutil_register_library_map(array(
'ConpherenceUpdateController' => 'ConpherenceController', 'ConpherenceUpdateController' => 'ConpherenceController',
'ConpherenceViewController' => 'ConpherenceController', 'ConpherenceViewController' => 'ConpherenceController',
'DarkConsoleController' => 'PhabricatorController', 'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleDataController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin', 'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPlugin' => 'DarkConsolePlugin', 'DarkConsoleEventPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPluginAPI' => 'PhutilEventListener', 'DarkConsoleEventPluginAPI' => 'PhutilEventListener',

View file

@ -73,7 +73,10 @@ class AphrontDefaultApplicationConfiguration
'profile/(?P<phid>[^/]+)/' => 'PhabricatorXHProfProfileController', 'profile/(?P<phid>[^/]+)/' => 'PhabricatorXHProfProfileController',
), ),
'/~/' => 'DarkConsoleController', '/~/' => array(
'' => 'DarkConsoleController',
'data/(?P<key>[^/]+)/' => 'DarkConsoleDataController',
),
'/search/' => array( '/search/' => array(
'' => 'PhabricatorSearchController', '' => 'PhabricatorSearchController',

View file

@ -5,57 +5,32 @@
*/ */
final class DarkConsoleCore { final class DarkConsoleCore {
const PLUGIN_ERRORLOG = 'ErrorLog';
const PLUGIN_SERVICES = 'Services';
const PLUGIN_EVENT = 'Event';
const PLUGIN_XHPROF = 'XHProf';
const PLUGIN_REQUEST = 'Request';
public static function getPlugins() {
return array(
self::PLUGIN_ERRORLOG,
self::PLUGIN_REQUEST,
self::PLUGIN_SERVICES,
self::PLUGIN_EVENT,
self::PLUGIN_XHPROF,
);
}
private $plugins = array(); private $plugins = array();
private $settings; const STORAGE_VERSION = 1;
private $coredata;
public function getPlugin($plugin_name) {
return idx($this->plugins, $plugin_name);
}
public function __construct() { public function __construct() {
foreach (self::getPlugins() as $plugin_name) { $symbols = id(new PhutilSymbolLoader())
$plugin = self::newPlugin($plugin_name); ->setType('class')
if ($plugin->isPermanent() || !isset($disabled[$plugin_name])) { ->setAncestorClass('DarkConsolePlugin')
if ($plugin->shouldStartup()) { ->selectAndLoadSymbols();
$plugin->didStartup();
$plugin->setConsoleCore($this); foreach ($symbols as $symbol) {
$this->plugins[$plugin_name] = $plugin; $plugin = newv($symbol['name'], array());
} if (!$plugin->shouldStartup()) {
continue;
} }
$plugin->setConsoleCore($this);
$plugin->didStartup();
$this->plugins[$symbol['name']] = $plugin;
} }
} }
public static function newPlugin($plugin) { public function getPlugins() {
$class = 'DarkConsole'.$plugin.'Plugin';
return newv($class, array());
}
public function getEnabledPlugins() {
return $this->plugins; return $this->plugins;
} }
public function render(AphrontRequest $request) { public function getKey(AphrontRequest $request) {
$plugins = $this->getPlugins();
$user = $request->getUser();
$plugins = $this->getEnabledPlugins();
foreach ($plugins as $plugin) { foreach ($plugins as $plugin) {
$plugin->setRequest($request); $plugin->setRequest($request);
@ -70,128 +45,58 @@ final class DarkConsoleCore {
$plugin->setData($plugin->generateData()); $plugin->setData($plugin->generateData());
} }
$selected = $user->getConsoleTab(); $plugins = msort($plugins, 'getOrderKey');
$visible = $user->getConsoleVisible();
if (!isset($plugins[$selected])) { $key = Filesystem::readRandomCharacters(24);
$selected = head_key($plugins);
}
$tabs = array(); $tabs = array();
foreach ($plugins as $key => $plugin) { $data = array();
$tabs[$key] = array( foreach ($plugins as $plugin) {
$class = get_class($plugin);
$tabs[] = array(
'class' => $class,
'name' => $plugin->getName(), 'name' => $plugin->getName(),
'panel' => $plugin->render(), 'color' => $plugin->getColor(),
); );
$data[$class] = $plugin->getData();
} }
$tabs_markup = array(); $storage = array(
$panel_markup = array(); 'vers' => self::STORAGE_VERSION,
foreach ($tabs as $key => $data) { 'tabs' => $tabs,
$is_selected = ($key == $selected); 'data' => $data,
if ($is_selected) { 'user' => $request->getUser()
$style = null; ? $request->getUser()->getPHID()
$tabclass = 'dark-console-tab-selected'; : null,
} else { );
$style = 'display: none;';
$tabclass = null;
}
$tabs_markup[] = javelin_tag( $cache = new PhabricatorKeyValueDatabaseCache();
'a', $cache = new PhutilKeyValueCacheProfiler($cache);
array( $cache->setProfiler(PhutilServiceProfiler::getInstance());
'class' => "dark-console-tab {$tabclass}",
'sigil' => 'dark-console-tab',
'id' => 'dark-console-tab-'.$key,
),
(string)$data['name']);
$panel_markup[] = javelin_render_tag( $cache->setKeys(
'div',
array(
'class' => 'dark-console-panel dark-console-panel-'.$key,
'style' => $style,
'sigil' => 'dark-console-panel',
),
(string)$data['panel']);
}
$console = javelin_render_tag(
'table',
array( array(
'class' => 'dark-console', 'darkconsole:'.$key => json_encode($storage),
'sigil' => 'dark-console',
'style' => $visible ? '' : 'display: none;',
), ),
'<tr>'. $ttl = (60 * 60 * 6));
'<th class="dark-console-tabs">'.
implode("\n", $tabs_markup).
'</th>'.
'<td>'.implode("\n", $panel_markup).'</td>'.
'</tr>');
if (!empty($_COOKIE['phsid'])) { return $key;
$console = str_replace(
$_COOKIE['phsid'],
phutil_escape_html('<session-key>'),
$console);
}
if ($request->isAjax()) {
// for ajax this HTML gets updated on the client
$request_history = null;
} else {
$request_table_header =
'<div class="dark-console-panel-request-log-separator"></div>';
$rows = array();
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Sequence',
'Type',
'URI',
));
$table->setColumnClasses(
array(
'',
'',
'wide',
));
$request_table = $request_table_header . $table->render();
$request_history = javelin_render_tag(
'table',
array(
'class' => 'dark-console dark-console-request-log',
'sigil' => 'dark-console-request-log',
'style' => $visible ? '' : 'display: none;',
),
'<tr>'.
'<th class="dark-console-tabs">'.
phutil_tag(
'a',
array(
'class' => 'dark-console-tab dark-console-tab-selected',
),
'Request Log').
'</th>'.
'<td>'.
javelin_render_tag(
'div',
array(
'class' => 'dark-console-panel dark-console-panel-RequestLog',
),
$request_table).
'</td>'.
'</tr>');
}
return "\n\n\n\n".$console.$request_history."\n\n\n\n";
} }
public function render(AphrontRequest $request) {
$user = $request->getUser();
$visible = $user ? $user->getConsoleVisible() : true;
return javelin_tag(
'div',
array(
'id' => 'darkconsole',
'class' => 'dark-console',
'style' => $visible ? '' : 'display: none;',
'data-console-key' => $this->getKey($request),
),
'');
}
} }

View file

@ -0,0 +1,69 @@
<?php
/**
* @group console
*/
final class DarkConsoleDataController extends PhabricatorController {
private $key;
public function willProcessRequest(array $data) {
$this->key = $data['key'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$cache = new PhabricatorKeyValueDatabaseCache();
$cache = new PhutilKeyValueCacheProfiler($cache);
$cache->setProfiler(PhutilServiceProfiler::getInstance());
$result = $cache->getKey('darkconsole:'.$this->key);
if (!$result) {
return new Aphront400Response();
}
$result = json_decode($result, true);
if (!is_array($result)) {
return new Aphront400Response();
}
if ($result['vers'] != DarkConsoleCore::STORAGE_VERSION) {
return new Aphront400Response();
}
if ($result['user'] != $user->getPHID()) {
return new Aphront400Response();
}
$output = array();
$output['tabs'] = $result['tabs'];
$output['panel'] = array();
foreach ($result['data'] as $class => $data) {
try {
$obj = newv($class, array());
$obj->setData($data);
$obj->setRequest($request);
$panel = $obj->renderPanel();
if (!empty($_COOKIE['phsid'])) {
$panel = str_replace(
$_COOKIE['phsid'],
'(session-key)',
$panel);
}
$output['panel'][$class] = $panel;
} catch (Exception $ex) {
$output['panel'][$class] = 'error';
}
}
return id(new AphrontAjaxResponse())->setContent($output);
}
}

View file

@ -7,29 +7,32 @@ final class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
public function getName() { public function getName() {
$count = count($this->getData()); $count = count($this->getData());
if ($count) { if ($count) {
return return pht('Error Log (%d)', $count);
'<span style="color: #ff0000;">&bull;</span> '.
"Error Log ({$count})";
} }
return pht('Error Log');
return 'Error Log';
} }
public function getOrder() {
return 0;
}
public function getColor() {
if (count($this->getData())) {
return '#ff0000';
}
return null;
}
public function getDescription() { public function getDescription() {
return 'Shows errors and warnings.'; return pht('Shows errors and warnings.');
} }
public function generateData() { public function generateData() {
return DarkConsoleErrorLogPluginAPI::getErrors(); return DarkConsoleErrorLogPluginAPI::getErrors();
} }
public function renderPanel() {
public function render() {
$data = $this->getData(); $data = $this->getData();
$rows = array(); $rows = array();

View file

@ -37,7 +37,7 @@ final class DarkConsoleEventPlugin extends DarkConsolePlugin {
); );
} }
public function render() { public function renderPanel() {
$data = $this->getData(); $data = $this->getData();
$out = array(); $out = array();

View file

@ -11,12 +11,27 @@ abstract class DarkConsolePlugin {
abstract public function getName(); abstract public function getName();
abstract public function getDescription(); abstract public function getDescription();
abstract public function render(); abstract public function renderPanel();
public function __construct() { public function __construct() {
} }
public function getColor() {
return null;
}
final public function getOrderKey() {
return sprintf(
'%09d%s',
(int)(999999999 * $this->getOrder()),
$this->getName());
}
public function getOrder() {
return 1.0;
}
public function setConsoleCore(DarkConsoleCore $core) { public function setConsoleCore(DarkConsoleCore $core) {
$this->core = $core; $this->core = $core;
return $this; return $this;
@ -52,10 +67,6 @@ abstract class DarkConsolePlugin {
return $this->getRequest()->getRequestURI(); return $this->getRequest()->getRequestURI();
} }
public function isPermanent() {
return false;
}
public function shouldStartup() { public function shouldStartup() {
return true; return true;
} }

View file

@ -20,8 +20,7 @@ final class DarkConsoleRequestPlugin extends DarkConsolePlugin {
); );
} }
public function render() { public function renderPanel() {
$data = $this->getData(); $data = $this->getData();
$sections = array( $sections = array(

View file

@ -136,11 +136,16 @@ final class DarkConsoleServicesPlugin extends DarkConsolePlugin {
'start' => PhabricatorStartup::getStartTime(), 'start' => PhabricatorStartup::getStartTime(),
'end' => microtime(true), 'end' => microtime(true),
'log' => $log, 'log' => $log,
'analyzeURI' => (string)$this
->getRequestURI()
->alter('__analyze__', true),
'didAnalyze' => isset($_REQUEST['__analyze__']),
); );
} }
public function render() { public function renderPanel() {
$data = $this->getData(); $data = $this->getData();
$log = $data['log']; $log = $data['log'];
$results = array(); $results = array();
@ -149,8 +154,8 @@ final class DarkConsoleServicesPlugin extends DarkConsolePlugin {
phutil_tag( phutil_tag(
'a', 'a',
array( array(
'href' => $this->getRequestURI()->alter('__analyze__', true), 'href' => $data['analyzeURI'],
'class' => isset($_REQUEST['__analyze__']) 'class' => $data['didAnalyze']
? 'disabled button' ? 'disabled button'
: 'green button', : 'green button',
), ),

View file

@ -8,28 +8,40 @@ final class DarkConsoleXHProfPlugin extends DarkConsolePlugin {
protected $xhprofID; protected $xhprofID;
public function getName() { public function getName() {
$run = $this->getData();
if ($run) {
return '<span style="color: #ff00ff;">&bull;</span> XHProf';
}
return 'XHProf'; return 'XHProf';
} }
public function getColor() {
$data = $this->getData();
if ($data['xhprofID']) {
return '#ff00ff';
}
return null;
}
public function getDescription() { public function getDescription() {
return 'Provides detailed PHP profiling information through XHProf.'; return 'Provides detailed PHP profiling information through XHProf.';
} }
public function generateData() { public function generateData() {
return $this->xhprofID; return array(
'xhprofID' => $this->xhprofID,
'profileURI' => (string)$this
->getRequestURI()
->alter('__profile__', 'page'),
);
} }
public function getXHProfRunID() { public function getXHProfRunID() {
return $this->xhprofID; return $this->xhprofID;
} }
public function render() { public function renderPanel() {
$data = $this->getData();
$run = $data['xhprofID'];
$profile_uri = $data['profileURI'];
if (!DarkConsoleXHProfPluginAPI::isProfilerAvailable()) { if (!DarkConsoleXHProfPluginAPI::isProfilerAvailable()) {
$href = PhabricatorEnv::getDoclink('article/Installation_Guide.html'); $href = PhabricatorEnv::getDoclink('article/Installation_Guide.html');
$install_guide = phutil_tag( $install_guide = phutil_tag(
@ -49,14 +61,12 @@ final class DarkConsoleXHProfPlugin extends DarkConsolePlugin {
$result = array(); $result = array();
$run = $this->getXHProfRunID();
$header = $header =
'<div class="dark-console-panel-header">'. '<div class="dark-console-panel-header">'.
phutil_tag( phutil_tag(
'a', 'a',
array( array(
'href' => $this->getRequestURI()->alter('__profile__', 'page'), 'href' => $profile_uri,
'class' => $run 'class' => $run
? 'disabled button' ? 'disabled button'
: 'green button', : 'green button',

View file

@ -38,10 +38,10 @@ final class AphrontAjaxResponse extends AphrontResponse {
$console = $this->getConsole(); $console = $this->getConsole();
if ($console) { if ($console) {
Javelin::initBehavior( Javelin::initBehavior(
'dark-console-ajax', 'dark-console',
array( array(
'console' => $console->render($this->getRequest()), 'uri' => (string)$this->getRequest()->getRequestURI(),
'uri' => (string) $this->getRequest()->getRequestURI(), 'key' => $console->getKey($this->getRequest()),
)); ));
} }

View file

@ -164,8 +164,9 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
Javelin::initBehavior( Javelin::initBehavior(
'dark-console', 'dark-console',
array( array(
'uri' => '/~/', 'uri' => $request ? (string)$request->getRequestURI() : '?',
'request_uri' => $request ? (string) $request->getRequestURI() : '/', 'selected' => $user ? $user->getConsoleTab() : null,
'visible' => $user ? (int)$user->getConsoleVisible() : true,
)); ));
// Change this to initBehavior when there is some behavior to initialize // Change this to initBehavior when there is some behavior to initialize
@ -225,13 +226,15 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
} }
protected function willSendResponse($response) { protected function willSendResponse($response) {
$request = $this->getRequest();
$response = parent::willSendResponse($response); $response = parent::willSendResponse($response);
$console = $this->getRequest()->getApplicationConfiguration()->getConsole(); $console = $request->getApplicationConfiguration()->getConsole();
if ($console) { if ($console) {
$response = str_replace( $response = str_replace(
'<darkconsole />', '<darkconsole />',
$console->render($this->getRequest()), $console->render($request),
$response); $response);
} }

View file

@ -3,7 +3,7 @@
*/ */
.dark-console { .dark-console {
background: #555555; background: #444444;
color: #eeeeee; color: #eeeeee;
width: 100%; width: 100%;
font-family: "Verdana"; font-family: "Verdana";
@ -11,54 +11,101 @@
position: relative; position: relative;
} }
.dark-console a:link { .dark-console-requests,
color: inherit; .dark-console-tabs {
position: absolute;
overflow-y: auto;
top: 0;
left: 0;
bottom: 0;
width: 15%;
padding: 8px 0;
}
.dark-console-requests,
.dark-console-tabs,
.dark-console-panel,
.dark-console-load {
border-left: 1px solid #111111;
box-shadow: -2px 0px 2px rgba(0, 0, 0, 0.25);
}
.dark-console-requests {
background: #222222;
} }
.dark-console-tabs { .dark-console-tabs {
width: 180px; background: #333333;
background: #222222; left: 15%;
border-right: 1px solid #888888;
padding: 2.5em 0em;
} }
.dark-console-panel,
.dark-console-load {
position: relative;
min-height: 320px;
}
a.dark-console-tab { .dark-console-panel {
padding: .75em 12px; margin-left: 30%;
text-align: right; background: #444444;
background: #444444; }
position: relative;
border: 1px solid #666666; .dark-console-requests a.dark-console-request,
.dark-console-tabs a.dark-console-tab {
display: block;
padding: 6px;
overflow: hidden;
background: #444444;
margin: 3px 0;
color: #cccccc;
border-color: #666666;
border-width: 1px 0; border-width: 1px 0;
border-right-color: #888888; border-style: solid;
margin-bottom: 2px;
display: block;
color: #cccccc;
} }
a.dark-console-tab-selected { .dark-console-requests a.dark-selected,
margin-right: -1px; .dark-console-tabs a.dark-selected {
padding-right: 13px; background: #0066aa;
background: #555555;
border-color: #888888;
border-right-color: #555555;
color: #eeeeee;
} }
.dark-console-requests a.dark-console-request:hover,
.dark-console-tabs a.dark-console-tab:hover {
background: #1188cc;
}
.dark-console-tabs a.dark-console-tab {
text-align: right;
}
.dark-console-load {
background-image: url(/rsrc/image/darkload.gif);
background-position: center center;
background-repeat: no-repeat;
background-color: #000;
margin-left: 15%;
}
.dark-console .aphront-table-view { .dark-console .aphront-table-view {
font-size: 11px;
background: #888888; background: #888888;
color: #eeeeee; color: #eeeeee;
margin: 1em 1%; width: 100%;
width: 98%;
border-color: #333333; border-color: #333333;
margin: 8px 0;
} }
.dark-console .aphront-table-view th { .dark-console .aphront-table-view th {
text-shadow: none;
font-family: "Verdana";
font-size: 11px;
background: #333333; background: #333333;
color: #ffffff; color: #ffffff;
} }
.dark-console .aphront-table-view td {
font-size: 11px;
}
.dark-console .aphront-table-view td.header { .dark-console .aphront-table-view td.header {
background: #444444; background: #444444;
color: #ffffff; color: #ffffff;
@ -77,13 +124,8 @@ a.dark-console-tab-selected {
color: #dddddd; color: #dddddd;
} }
.dark-console-panel-ErrorLog { .dark-console-panel-core {
max-height: 500px; padding: 12px;
overflow: auto;
}
.dark-console-panel-error-details {
display: none;
} }
.explain-sev-1 { .explain-sev-1 {
@ -119,15 +161,11 @@ a.dark-console-tab-selected {
} }
.dark-console-panel-header { .dark-console-panel-header {
background: #606060; padding: 8px 4px 0;
border-bottom: 1px solid #505050;
padding: .25em 1em .25em 0;
} }
.dark-console-panel-header h1 { .dark-console-panel-header h1 {
padding: 1em; font-size: 15px;
font-size: 12px;
font-weight: normal;
} }
.dark-console-panel-header .button { .dark-console-panel-header .button {
@ -168,4 +206,11 @@ a.dark-console-tab-selected {
height: 2px; height: 2px;
} }
.dark-console-panel-ErrorLog {
max-height: 500px;
overflow: auto;
}
.dark-console-panel-error-details {
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -1,49 +0,0 @@
/**
* @provides javelin-behavior-dark-console-ajax
* @requires javelin-behavior
* javelin-dom
*/
JX.behavior('dark-console-ajax', function(config) {
var requestLog = JX.DOM.find(document.body,
'table',
'dark-console-request-log');
var requestTable = JX.DOM.find(requestLog, 'table');
var requestRows = JX.DOM.scry(requestTable, 'tr');
var requestNumber = requestRows.length - 1; // header don't count
var requestURI = config.uri;
var console = JX.$H(config.console);
var newRowType = 'ajax';
var newRowNumber = JX.$N(
'a',
{
'sigil' : 'request-log-number',
'meta' : { 'console' : console }
},
requestNumber
);
var newRowURI = JX.$N(
'a',
{
'sigil' : 'request-log-uri',
'meta' : { 'console' : console }
},
requestURI
);
var newRow = JX.$N(
'tr',
{
'className' : requestNumber % 2 ? 'alt' : ''
},
[
JX.$N('td', {}, newRowNumber),
JX.$N('td', {}, newRowType),
JX.$N('td', {}, newRowURI)
]
);
JX.DOM.appendContent(requestTable, newRow);
});

View file

@ -6,55 +6,221 @@
* javelin-dom * javelin-dom
* javelin-request * javelin-request
* phabricator-keyboard-shortcut * phabricator-keyboard-shortcut
* javelin-behavior-dark-console-ajax
*/ */
JX.behavior('dark-console', function(config) { JX.behavior('dark-console', function(config, statics) {
var selected_tab = null; var root = statics.root || setup_console();
JX.Stratcom.listen( config.key = config.key || root.getAttribute('data-console-key');
'click', add_request(config);
['dark-console', 'dark-console-tab'],
function(e) {
var console = e.getNode('dark-console'); // Do first-time setup.
var tabs = JX.DOM.scry(console, 'a', 'dark-console-tab'); function setup_console() {
var panels = JX.DOM.scry(console, 'div', 'dark-console-panel'); statics.root = JX.$('darkconsole');
var target = e.getTarget(); statics.req = {all: {}, current: null};
for (var ii = 0; ii < tabs.length; ii++) { statics.tab = {all: {}, current: null};
JX.DOM.alterClass(
tabs[ii], statics.el = {};
'dark-console-tab-selected',
tabs[ii] == target); statics.el.reqs = JX.$N('div', {className: 'dark-console-requests'});
(tabs[ii] != target ? JX.DOM.hide : JX.DOM.show)(panels[ii]); statics.root.appendChild(statics.el.reqs);
statics.el.tabs = JX.$N('div', {className: 'dark-console-tabs'});
statics.root.appendChild(statics.el.tabs);
statics.el.panel = JX.$N('div', {className: 'dark-console-panel'});
statics.root.appendChild(statics.el.panel);
statics.el.load = JX.$N('div', {className: 'dark-console-load'});
statics.root.appendChild(statics.el.load);
statics.cache = {};
statics.visible = config.visible;
statics.selected = config.selected;
return statics.root;
}
// Add a new request to the console (initial page load, or new Ajax response).
function add_request(config) {
// Ignore DarkConsole data requests.
if (config.uri.match(new RegExp('^/~/data/'))) {
return;
}
var attr = {
className: 'dark-console-request',
sigil: 'dark-console-request',
title: config.uri,
meta: config,
href: '#'
};
var link = JX.$N('a', attr, config.uri);
statics.el.reqs.appendChild(link);
statics.req.all[config.key] = link;
if (!statics.req.current) {
select_request(config.key);
}
}
// Select a request (on load, or when the user clicks one).
function select_request(key) {
var req = statics.req;
if (req.current) {
JX.DOM.alterClass(req.all[req.current], 'dark-selected', false);
}
statics.req.current = key;
JX.DOM.alterClass(req.all[req.current], 'dark-selected', true);
if (statics.visible) {
JX.log('visible!');
draw_request(key);
}
}
// When the user clicks a request, select it.
JX.Stratcom.listen('click', 'dark-console-request', function(e) {
e.kill();
select_request(e.getNodeData('dark-console-request').key);
});
// After the user selects a request, draw its tabs.
function draw_request(key) {
var cache = statics.cache;
if (cache[key]) {
render_request(key);
return;
}
new JX.Request(
'/~/data/' + key + '/',
function(r) {
cache[key] = r;
if (statics.req.current == key) {
render_request(key);
}
})
.send();
show_loading();
}
// Show the loading indicator.
function show_loading() {
JX.DOM.hide(statics.el.tabs);
JX.DOM.hide(statics.el.panel);
JX.DOM.show(statics.el.load);
}
// Hide the loading indicator.
function hide_loading() {
JX.DOM.show(statics.el.tabs);
JX.DOM.show(statics.el.panel);
JX.DOM.hide(statics.el.load);
}
function render_request(key) {
var data = statics.cache[key];
statics.tab.all = {};
var links = [];
var first = null;
for (var ii = 0; ii < data.tabs.length; ii++) {
var tab = data.tabs[ii];
var attr = {
className: 'dark-console-tab',
sigil: 'dark-console-tab',
meta: tab,
href: '#'
};
var bullet = null;
if (tab.color) {
bullet = JX.$N('span', {style: {color: tab.color}}, "\u2022");
} }
selected_tab = target.id.replace('dark-console-tab-', ''); var link = JX.$N('a', attr, [bullet, ' ', tab.name]);
links.push(link);
statics.tab.all[tab['class']] = link;
first = first || tab['class'];
}
new JX.Request(config.uri, JX.bag) JX.DOM.setContent(statics.el.tabs, links);
.setData({ tab : selected_tab })
if (statics.tab.current in statics.tab.all) {
select_tab(statics.tab.current);
} else if (statics.selected in statics.tab.all) {
select_tab(statics.selected);
} else {
select_tab(first);
}
hide_loading();
}
function select_tab(tclass) {
var tabs = statics.tab;
if (tabs.current) {
JX.DOM.alterClass(tabs.current, 'dark-selected', false);
}
tabs.current = tabs.all[tclass];
JX.DOM.alterClass(tabs.current, 'dark-selected', true);
if (tclass != statics.selected) {
// Save user preference.
new JX.Request('/~/', JX.bag)
.setData({ tab : tclass })
.send(); .send();
}); }
draw_panel();
}
// When the user clicks a tab, select it.
JX.Stratcom.listen('click', 'dark-console-tab', function(e) {
e.kill();
select_tab(e.getNodeData('dark-console-tab')['class']);
});
function draw_panel() {
var data = statics.cache[statics.req.current];
var tclass = JX.Stratcom.getData(statics.tab.current)['class'];
var html = data.panel[tclass];
var div = JX.$N('div', {className: 'dark-console-panel-core'}, JX.$H(html));
JX.DOM.setContent(statics.el.panel, div);
}
// Install keyboard shortcut.
var desc = 'Toggle visibility of DarkConsole.'; var desc = 'Toggle visibility of DarkConsole.';
new JX.KeyboardShortcut('`', desc) new JX.KeyboardShortcut('`', desc)
.setHandler(function(manager) { .setHandler(function(manager) {
var console = JX.DOM.find(document.body, 'table', 'dark-console'); statics.visible = !statics.visible;
var requestLog = JX.DOM.find(
document.body,
'table',
'dark-console-request-log');
config.visible = !config.visible; if (statics.visible) {
if (config.visible) { JX.DOM.show(root);
JX.DOM.show(console); if (statics.req.current) {
JX.DOM.show(requestLog); draw_request(statics.req.current);
}
} else { } else {
JX.DOM.hide(console); JX.DOM.hide(root);
JX.DOM.hide(requestLog);
} }
new JX.Request(config.uri, JX.bag) // Save user preference.
.setData({visible: config.visible ? 1 : 0}) new JX.Request('/~/', JX.bag)
.setData({visible: statics.visible ? 1 : 0})
.send(); .send();
// Force resize listeners to take effect. // Force resize listeners to take effect.
@ -62,89 +228,4 @@ JX.behavior('dark-console', function(config) {
}) })
.register(); .register();
var initRequestLog = function() {
var console = JX.DOM.find(document.body,
'table',
'dark-console');
var requestLog = JX.DOM.find(document.body,
'table',
'dark-console-request-log');
var requestTable = JX.DOM.find(requestLog, 'table');
var rows = JX.DOM.scry(requestTable, 'tr');
var tableHeader = rows[0];
var newRowNumber = JX.$N(
'a',
{
'sigil' : 'request-log-number',
'meta' : { 'console' : console }
},
"0"
);
var newRowURI = JX.$N(
'a',
{
'sigil' : 'request-log-uri',
'meta' : { 'console' : console }
},
config.request_uri
);
var newRow = JX.$N(
'tr',
{
'className' : 'highlight'
},
[
JX.$N('td', {}, newRowNumber),
JX.$N('td', {}, 'main'),
JX.$N('td', {}, newRowURI)
]
);
JX.DOM.setContent(requestTable, [tableHeader, newRow]);
}
initRequestLog();
var updateActiveRequest = function(e) {
var log = e.getNode('dark-console-request-log');
var table = JX.DOM.find(log, 'table');
var rows = JX.DOM.scry(table, 'tr');
var targetRow = e.getTarget().parentNode.parentNode;
var data = JX.Stratcom.getData(e.getTarget());
var newConsole = data.console;
for (var ii = 0; ii < rows.length; ii++) {
JX.DOM.alterClass(
rows[ii],
'highlight',
rows[ii] == targetRow);
}
var console = JX.DOM.find(document.body, 'table', 'dark-console');
JX.DOM.replace(console, newConsole);
if (selected_tab) {
console = JX.DOM.find(document.body, 'table', 'dark-console');
var s_id = 'dark-console-tab-' + selected_tab;
var tabs = JX.DOM.scry(console, 'a', 'dark-console-tab');
var panels = JX.DOM.scry(console, 'div', 'dark-console-panel');
for (var ii = 0; ii < tabs.length; ii++) {
JX.DOM.alterClass(
tabs[ii],
'dark-console-tab-selected',
tabs[ii].id == s_id);
(tabs[ii].id != s_id ? JX.DOM.hide : JX.DOM.show)(panels[ii]);
}
}
}
JX.Stratcom.listen(
'click',
['dark-console-request-log', 'request-log-number'],
updateActiveRequest
);
JX.Stratcom.listen(
'click',
['dark-console-request-log', 'request-log-uri'],
updateActiveRequest
);
}); });