From f736ca047ae15135a2c4b1b6d4fb541490a2801a Mon Sep 17 00:00:00 2001 From: Alan Huang Date: Tue, 14 Aug 2012 19:19:23 -0700 Subject: [PATCH] Make countdowns (internally) embeddable Summary: You can now embed countdowns in Remarkup! Not sure what it's useful for, but there you have it. Also I may have made a hash of the markup code; I don't really know what I'm doing. Test Plan: Make a new countdown, put `{C###}` in a Differential comment. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T1053 Differential Revision: https://secure.phabricator.com/D3290 --- src/__celerity_resource_map__.php | 2 +- src/__phutil_library_map__.php | 2 + .../PhabricatorCountdownViewController.php | 21 +++-- .../markup/PhabricatorMarkupEngine.php | 2 + .../rule/PhabricatorRemarkupRuleCountdown.php | 84 +++++++++++++++++++ .../rsrc/js/application/countdown/timer.js | 46 +++++----- 6 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 src/infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 065dcaf26a..5ed5040c3d 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -969,7 +969,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-countdown-timer' => array( - 'uri' => '/res/5ee9cb13/rsrc/js/application/countdown/timer.js', + 'uri' => '/res/7468acb7/rsrc/js/application/countdown/timer.js', 'type' => 'js', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index d41d493f13..889838b867 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -928,6 +928,7 @@ phutil_register_library_map(array( 'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php', 'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php', 'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php', + 'PhabricatorRemarkupRuleCountdown' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php', 'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleDifferential.php', 'PhabricatorRemarkupRuleDifferentialHandle' => 'infrastructure/markup/rule/handle/PhabricatorRemarkupRuleDifferentialHandle.php', 'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleDiffusion.php', @@ -2015,6 +2016,7 @@ phutil_register_library_map(array( 'PhabricatorProjectUpdateController' => 'PhabricatorProjectController', 'PhabricatorRedirectController' => 'PhabricatorController', 'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController', + 'PhabricatorRemarkupRuleCountdown' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName', 'PhabricatorRemarkupRuleDifferentialHandle' => 'PhabricatorRemarkupRuleObjectHandle', 'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule', diff --git a/src/applications/countdown/controller/PhabricatorCountdownViewController.php b/src/applications/countdown/controller/PhabricatorCountdownViewController.php index 74179be04b..90cf629d15 100644 --- a/src/applications/countdown/controller/PhabricatorCountdownViewController.php +++ b/src/applications/countdown/controller/PhabricatorCountdownViewController.php @@ -47,8 +47,9 @@ final class PhabricatorCountdownViewController ), $chrome_visible ? 'Disable Chrome' : 'Enable Chrome'); + $container = celerity_generate_unique_node_id(); $content = - '
+ '

'. phutil_escape_html($timer->getTitle()).' · '. phabricator_datetime($timer->getDatePoint(), $user). @@ -61,18 +62,24 @@ final class PhabricatorCountdownViewController Minutes Seconds - - - - - + '. + javelin_render_tag('td', + array('sigil' => 'phabricator-timer-days'), ''). + javelin_render_tag('td', + array('sigil' => 'phabricator-timer-hours'), ''). + javelin_render_tag('td', + array('sigil' => 'phabricator-timer-minutes'), ''). + javelin_render_tag('td', + array('sigil' => 'phabricator-timer-seconds'), ''). + '

'. $chrome_link. '
'; Javelin::initBehavior('countdown-timer', array( - 'timestamp' => $timer->getDatepoint() + 'timestamp' => $timer->getDatepoint(), + 'container' => $container, )); $panel = $content; diff --git a/src/infrastructure/markup/PhabricatorMarkupEngine.php b/src/infrastructure/markup/PhabricatorMarkupEngine.php index 0073e565b3..f9e11d520d 100644 --- a/src/infrastructure/markup/PhabricatorMarkupEngine.php +++ b/src/infrastructure/markup/PhabricatorMarkupEngine.php @@ -411,6 +411,8 @@ final class PhabricatorMarkupEngine { $rules[] = new PhabricatorRemarkupRuleManiphest(); $rules[] = new PhabricatorRemarkupRulePaste(); + $rules[] = new PhabricatorRemarkupRuleCountdown(); + $rules[] = new PonderRuleQuestion(); if ($options['macros']) { diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php new file mode 100644 index 0000000000..2d67ba270c --- /dev/null +++ b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php @@ -0,0 +1,84 @@ +load($matches[1]); + if (!$countdown) { + return $matches[0]; + } + $id = celerity_generate_unique_node_id(); + + $engine = $this->getEngine(); + $token = $engine->storeText(''); + + $metadata_key = self::KEY_RULE_COUNTDOWN; + $metadata = $engine->getTextMetadata($metadata_key, array()); + $metadata[$id] = array($countdown->getDatepoint(), $token); + $engine->setTextMetadata($metadata_key, $metadata); + + return $token; + } + + public function didMarkupText() { + $engine = $this->getEngine(); + + $metadata_key = self::KEY_RULE_COUNTDOWN; + $metadata = $engine->getTextMetadata($metadata_key, array()); + + require_celerity_resource('javelin-behavior-countdown-timer'); + + foreach ($metadata as $id => $info) { + list($time, $token) = $info; + $count = phutil_render_tag( + 'span', + array( + 'id' => $id, + ), + javelin_render_tag('span', + array('sigil' => 'phabricator-timer-days'), '').'d'. + javelin_render_tag('span', + array('sigil' => 'phabricator-timer-hours'), '').'h'. + javelin_render_tag('span', + array('sigil' => 'phabricator-timer-minutes'), '').'m'. + javelin_render_tag('span', + array('sigil' => 'phabricator-timer-seconds'), '').'s'); + Javelin::initBehavior('countdown-timer', array( + 'timestamp' => $time, + 'container' => $id, + )); + $engine->overwriteStoredText($token, $count); + } + + $engine->setTextMetadata($metadata_key, array()); + } + +} diff --git a/webroot/rsrc/js/application/countdown/timer.js b/webroot/rsrc/js/application/countdown/timer.js index c7de7b7582..1b404b4609 100644 --- a/webroot/rsrc/js/application/countdown/timer.js +++ b/webroot/rsrc/js/application/countdown/timer.js @@ -7,8 +7,14 @@ JX.behavior('countdown-timer', function(config) { + var container = JX.$(config.container); calculateTimeLeft(); + function setComponent(which, content) { + var component = JX.DOM.find(container, '*', 'phabricator-timer-' + which); + JX.DOM.setContent(component, content); + } + function calculateTimeLeft() { var days = 0; var hours = 0; @@ -18,31 +24,25 @@ JX.behavior('countdown-timer', function(config) { var current_timestamp = Math.round(new Date() / 1000); var delta = config.timestamp - current_timestamp; - if (delta <= 0) { - JX.DOM.setContent(JX.$('phabricator-timer-days'), days); - JX.DOM.setContent(JX.$('phabricator-timer-hours'), hours); - JX.DOM.setContent(JX.$('phabricator-timer-minutes'), minutes); - JX.DOM.setContent(JX.$('phabricator-timer-seconds'), seconds); - return; + if (delta > 0) { + days = Math.floor(delta/86400); + delta -= days * 86400; + + hours = Math.floor(delta/3600); + delta -= hours * 3600; + + minutes = Math.floor(delta / 60); + delta -= minutes * 60; + + seconds = delta; + + setTimeout(calculateTimeLeft, 1000); } - days = Math.floor(delta/86400); - delta -= days * 86400; - - hours = Math.floor(delta/3600); - delta -= hours * 3600; - - minutes = Math.floor(delta / 60); - delta -= minutes * 60; - - seconds = delta; - - JX.DOM.setContent(JX.$('phabricator-timer-days'), days); - JX.DOM.setContent(JX.$('phabricator-timer-hours'), hours); - JX.DOM.setContent(JX.$('phabricator-timer-minutes'), minutes); - JX.DOM.setContent(JX.$('phabricator-timer-seconds'), seconds); - - setTimeout(calculateTimeLeft, 1000); + setComponent('days', days); + setComponent('hours', hours); + setComponent('minutes', minutes); + setComponent('seconds', seconds); } });