@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix "Actions" button on Phame standalone/live pages (bonus: JX.sprintf())

Summary:
See <https://discourse.phabricator-community.org/t/non-functional-actions-menu-on-live-phame-views/2593>. Several layers here:

The "Actions" button is broken because a menu behavior is failing, since we aren't rendering the menu.

When a behavior fails to initialize, catch and log the exception and continue. Previously, we stopped initializing behaviors if any failed, but behaviors are usually independent and continuing with an explicit exception seems reasonable.

Give "JX.log()" some "sprintf()" semantics to make logging the behavior failure easier. We can probably afford these extra 200 bytes now in 2019.

This fixes the button and gives us explicit errors in the log. So far, so good.

Then, when a page won't render chrome, don't try to render the main menu. This fixes the actual errors (we no longer try to initialize menu behaviors for nodes which don't exist).

Completely hide the "Actions" and "Comment" flows if the viewer isn't logged in. Although this isn't completely consistent with other applications, I think it's more appropriate for Phame. In applications like Maniphest, we show a full set of controls (but disable them) so that users who are not currently logged in have a clear path to interact with the content, under the assumption that this is a relatively common workflow. This is probably less common for Phame, where we expect most anonymous viewers not to log in or interact.

Finally, parametrize a one-off border color and add a border under the crumbs at the top of the page.

Test Plan:
- Viewed a "Live" Phame blog post page, clicked "Actions", got a dropdown.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20378

+91 -15
+11 -11
resources/celerity/map.php
··· 10 10 'conpherence.pkg.css' => '3c8a0668', 11 11 'conpherence.pkg.js' => '020aebcf', 12 12 'core.pkg.css' => 'a1c2d49b', 13 - 'core.pkg.js' => 'a747b035', 13 + 'core.pkg.js' => 'a568e834', 14 14 'differential.pkg.css' => '8d8360fb', 15 15 'differential.pkg.js' => '67e02996', 16 16 'diffusion.pkg.css' => '42c75c37', ··· 86 86 'rsrc/css/application/paste/paste.css' => 'b37bcd38', 87 87 'rsrc/css/application/people/people-picture-menu-item.css' => 'fe8e07cf', 88 88 'rsrc/css/application/people/people-profile.css' => '2ea2daa1', 89 - 'rsrc/css/application/phame/phame.css' => '799febf9', 89 + 'rsrc/css/application/phame/phame.css' => 'bb442327', 90 90 'rsrc/css/application/pholio/pholio-edit.css' => '4df55b3b', 91 91 'rsrc/css/application/pholio/pholio-inline-comments.css' => '722b48c2', 92 92 'rsrc/css/application/pholio/pholio.css' => '88ef5ef1', ··· 217 217 'rsrc/externals/javelin/core/init.js' => '98e6504a', 218 218 'rsrc/externals/javelin/core/init_node.js' => '16961339', 219 219 'rsrc/externals/javelin/core/install.js' => '5902260c', 220 - 'rsrc/externals/javelin/core/util.js' => '22ae1776', 220 + 'rsrc/externals/javelin/core/util.js' => 'edb4d8c9', 221 221 'rsrc/externals/javelin/docs/Base.js' => '5a401d7d', 222 222 'rsrc/externals/javelin/docs/onload.js' => 'ee58fb62', 223 223 'rsrc/externals/javelin/ext/fx/Color.js' => '78f811c9', ··· 259 259 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae', 260 260 'rsrc/externals/javelin/lib/__tests__/URI.js' => '6fff0c2b', 261 261 'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb', 262 - 'rsrc/externals/javelin/lib/behavior.js' => 'fce5d170', 262 + 'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a', 263 263 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a', 264 264 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'a4356cde', 265 265 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a', ··· 571 571 'herald-test-css' => 'e004176f', 572 572 'inline-comment-summary-css' => '81eb368d', 573 573 'javelin-aphlict' => '022516b4', 574 - 'javelin-behavior' => 'fce5d170', 574 + 'javelin-behavior' => '1b6acc2a', 575 575 'javelin-behavior-aphlict-dropdown' => 'e9a2940f', 576 576 'javelin-behavior-aphlict-listen' => '4e61fa88', 577 577 'javelin-behavior-aphlict-status' => 'c3703a16', ··· 729 729 'javelin-typeahead-source' => '8badee71', 730 730 'javelin-typeahead-static-source' => '80bff3af', 731 731 'javelin-uri' => '2e255291', 732 - 'javelin-util' => '22ae1776', 732 + 'javelin-util' => 'edb4d8c9', 733 733 'javelin-vector' => 'e9c80beb', 734 734 'javelin-view' => '289bf236', 735 735 'javelin-view-html' => 'f8c4e135', ··· 798 798 'phabricator-tooltip' => '83754533', 799 799 'phabricator-ui-example-css' => 'b4795059', 800 800 'phabricator-zindex-css' => '99c0f5eb', 801 - 'phame-css' => '799febf9', 801 + 'phame-css' => 'bb442327', 802 802 'pholio-css' => '88ef5ef1', 803 803 'pholio-edit-css' => '4df55b3b', 804 804 'pholio-inline-comments-css' => '722b48c2', ··· 1027 1027 'javelin-behavior', 1028 1028 'javelin-dom', 1029 1029 'javelin-stratcom', 1030 + 'javelin-util', 1031 + ), 1032 + '1b6acc2a' => array( 1033 + 'javelin-magical-init', 1030 1034 'javelin-util', 1031 1035 ), 1032 1036 '1c850a26' => array( ··· 2174 2178 'javelin-quicksand', 2175 2179 'phabricator-keyboard-shortcut', 2176 2180 'conpherence-thread-manager', 2177 - ), 2178 - 'fce5d170' => array( 2179 - 'javelin-magical-init', 2180 - 'javelin-util', 2181 2181 ), 2182 2182 'fdc13e4e' => array( 2183 2183 'javelin-install',
+1
src/applications/celerity/postprocessor/CelerityDefaultPostprocessor.php
··· 238 238 'grey.button.gradient' => 'linear-gradient(to bottom, #ffffff, #f1f0f1)', 239 239 'grey.button.hover' => 'linear-gradient(to bottom, #ffffff, #eeebec)', 240 240 241 + 'document.border' => '#dedee1', 241 242 242 243 ); 243 244 }
+2 -2
src/applications/phame/controller/post/PhamePostViewController.php
··· 24 24 25 25 $hero = $this->buildPhamePostHeader($post); 26 26 27 - if (!$is_external) { 27 + if (!$is_external && $viewer->isLoggedIn()) { 28 28 $actions = $this->renderActions($post); 29 29 $header->setPolicyObject($post); 30 30 $header->setActionList($actions); ··· 136 136 ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))); 137 137 $timeline->setQuoteRef($monogram); 138 138 139 - if ($is_external) { 139 + if ($is_external || !$viewer->isLoggedIn()) { 140 140 $add_comment = null; 141 141 } else { 142 142 $add_comment = $this->buildCommentForm($post, $timeline);
+7
src/view/page/PhabricatorStandardPageView.php
··· 304 304 )); 305 305 } 306 306 307 + // If we aren't showing the page chrome, skip rendering DarkConsole and the 308 + // main menu, since they won't be visible on the page. 309 + if (!$this->getShowChrome()) { 310 + return; 311 + } 312 + 307 313 if ($console) { 308 314 require_celerity_resource('aphront-dark-console-css'); 309 315 ··· 346 352 347 353 $menu->setApplicationMenu($application_menu); 348 354 } 355 + 349 356 350 357 $this->menuContent = $menu->render(); 351 358 }
+1
webroot/rsrc/css/application/phame/phame.css
··· 284 284 text-align: center; 285 285 background: {$page.content}; 286 286 padding: 16px 0 24px; 287 + border-top: 1px solid {$document.border}; 287 288 } 288 289 289 290 .device-phone .phame-mega-header {
+1 -1
webroot/rsrc/css/phui/phui-document-pro.css
··· 56 56 .phui-document-container { 57 57 background-color: {$page.content}; 58 58 position: relative; 59 - border-bottom: 1px solid #dedee1; 59 + border-bottom: 1px solid {$document.border}; 60 60 } 61 61 62 62 .phui-document-view-pro-box,
+60
webroot/rsrc/externals/javelin/core/util.js
··· 295 295 * @return void 296 296 */ 297 297 JX.log = function(message) { 298 + // "JX.log()" accepts "Error" in addition to "string". Only try to 299 + // treat the argument as a "sprintf()" pattern if it's a string. 300 + if (typeof message === 'string') { 301 + message = JX.sprintf.apply(null, arguments); 302 + } 298 303 window.console.log(message); 299 304 }; 300 305 306 + JX.sprintf = function(pattern) { 307 + var argv = Array.prototype.slice.call(arguments); 308 + argv.reverse(); 309 + 310 + // Pop off the pattern argument. 311 + argv.pop(); 312 + 313 + var len = pattern.length; 314 + var output = ''; 315 + for (var ii = 0; ii < len; ii++) { 316 + var c = pattern.charAt(ii); 317 + 318 + if (c !== '%') { 319 + output += c; 320 + continue; 321 + } 322 + 323 + ii++; 324 + 325 + var next = pattern.charAt(ii); 326 + if (next === '%') { 327 + // This is "%%" (that is, an escaped "%" symbol), so just add a literal 328 + // "%" to the result. 329 + output += '%'; 330 + continue; 331 + } 332 + 333 + if (next === 's') { 334 + if (!argv.length) { 335 + throw new Error( 336 + 'Too few arguments to "JX.sprintf(...)" for pattern: ' + pattern); 337 + } 338 + 339 + output += '' + argv.pop(); 340 + 341 + continue; 342 + } 343 + 344 + if (next === '') { 345 + throw new Error( 346 + 'Pattern passed to "JX.sprintf(...)" ends with "%": ' + pattern); 347 + } 348 + 349 + throw new Error( 350 + 'Unknown conversion "%' + c + '" passed to "JX.sprintf(...)" in ' + 351 + 'pattern: ' + pattern); 352 + } 353 + 354 + if (argv.length) { 355 + throw new Error( 356 + 'Too many arguments to "JX.sprintf()" for pattern: ' + pattern); 357 + } 358 + 359 + return output; 360 + }; 301 361 302 362 if (__DEV__) { 303 363 window.alert = (function(native_alert) {
+8 -1
webroot/rsrc/externals/javelin/lib/behavior.js
··· 91 91 configs = [null]; 92 92 } 93 93 for (var ii = 0; ii < configs.length; ii++) { 94 - JX.behavior._behaviors[name](configs[ii], JX.behavior._statics[name]); 94 + try { 95 + JX.behavior._behaviors[name](configs[ii], JX.behavior._statics[name]); 96 + } catch (behavior_exception) { 97 + JX.log( 98 + 'JX.initBehaviors(...): behavior "%s" raised an error during setup.', 99 + name); 100 + JX.log(behavior_exception); 101 + } 95 102 } 96 103 JX.behavior._initialized[name] = true; 97 104 }