@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.

Quicksand and Pholio - make mock edit work

Summary: Fixes T8036. In addition to making the mock edit work, this tightens quicksand code such that the correct page id is returned even if start() has not been called yet. It also tightens mock view where some functions should respect statics.enabled a bit more.

Test Plan:
clicked edit mock, mock crumb, edit mock, mock crum, edit mock, made edits and they worked! clicked edit mock, mock crumb, edit mock, mock crumb, edit mock, profile icon, hit browser back to edit mock, made edits and they worked!

also observed mock view page not occasionally wigging out from image_onload race not having statics.enabled respect during the above

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T8036

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

+124 -65
+34 -33
resources/celerity/map.php
··· 8 8 return array( 9 9 'names' => array( 10 10 'core.pkg.css' => 'ca3f6a60', 11 - 'core.pkg.js' => '74e57ea0', 11 + 'core.pkg.js' => 'ff529dc7', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => 'bb338e4b', 14 14 'differential.pkg.js' => '3cfa26f9', ··· 205 205 'rsrc/externals/javelin/lib/JSON.js' => '69adf288', 206 206 'rsrc/externals/javelin/lib/Leader.js' => '331b1611', 207 207 'rsrc/externals/javelin/lib/Mask.js' => '8a41885b', 208 - 'rsrc/externals/javelin/lib/Quicksand.js' => '977e1f47', 208 + 'rsrc/externals/javelin/lib/Quicksand.js' => '4cebc641', 209 209 'rsrc/externals/javelin/lib/Request.js' => '94b750d2', 210 210 'rsrc/externals/javelin/lib/Resource.js' => '44959b73', 211 211 'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692', ··· 397 397 'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3', 398 398 'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc', 399 399 'rsrc/js/application/phame/phame-post-preview.js' => 'be807912', 400 - 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '9c2623f4', 401 - 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'a4fc6fe5', 400 + 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '246dc085', 401 + 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'fbe497e7', 402 402 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf', 403 403 'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c', 404 404 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef', ··· 626 626 'javelin-behavior-phabricator-transaction-list' => '13c739ea', 627 627 'javelin-behavior-phabricator-watch-anchor' => '9f36c42d', 628 628 'javelin-behavior-phame-post-preview' => 'be807912', 629 - 'javelin-behavior-pholio-mock-edit' => '9c2623f4', 630 - 'javelin-behavior-pholio-mock-view' => 'a4fc6fe5', 629 + 'javelin-behavior-pholio-mock-edit' => '246dc085', 630 + 'javelin-behavior-pholio-mock-view' => 'fbe497e7', 631 631 'javelin-behavior-phui-object-box-tabs' => '2bfa2836', 632 632 'javelin-behavior-phui-timeline-dropdown-menu' => '4d94d9c3', 633 633 'javelin-behavior-policy-control' => '9a340b3d', ··· 668 668 'javelin-leader' => '331b1611', 669 669 'javelin-magical-init' => '3010e992', 670 670 'javelin-mask' => '8a41885b', 671 - 'javelin-quicksand' => '977e1f47', 671 + 'javelin-quicksand' => '4cebc641', 672 672 'javelin-reactor' => '2b8de964', 673 673 'javelin-reactor-dom' => 'c90a04fc', 674 674 'javelin-reactor-node-calmer' => '76f4ebed', ··· 972 972 'javelin-workflow', 973 973 'javelin-util', 974 974 ), 975 + '246dc085' => array( 976 + 'javelin-behavior', 977 + 'javelin-stratcom', 978 + 'javelin-dom', 979 + 'javelin-workflow', 980 + 'javelin-quicksand', 981 + 'phabricator-phtize', 982 + 'phabricator-drag-and-drop-file-upload', 983 + 'phabricator-draggable-list', 984 + ), 975 985 '2529c82d' => array( 976 986 'javelin-dom', 977 987 'javelin-util', ··· 1116 1126 'javelin-dom', 1117 1127 'javelin-request', 1118 1128 'javelin-util', 1129 + ), 1130 + '4cebc641' => array( 1131 + 'javelin-install', 1119 1132 ), 1120 1133 '4d94d9c3' => array( 1121 1134 'javelin-behavior', ··· 1578 1591 'javelin-resource', 1579 1592 'javelin-routable', 1580 1593 ), 1581 - '977e1f47' => array( 1582 - 'javelin-install', 1583 - ), 1584 1594 '988040b4' => array( 1585 1595 'javelin-install', 1586 1596 'javelin-dom', ··· 1595 1605 'phuix-action-view', 1596 1606 'javelin-workflow', 1597 1607 ), 1598 - '9c2623f4' => array( 1599 - 'javelin-behavior', 1600 - 'javelin-stratcom', 1601 - 'javelin-dom', 1602 - 'javelin-workflow', 1603 - 'phabricator-phtize', 1604 - 'phabricator-drag-and-drop-file-upload', 1605 - 'phabricator-draggable-list', 1606 - ), 1607 1608 '9f36c42d' => array( 1608 1609 'javelin-behavior', 1609 1610 'javelin-stratcom', ··· 1649 1650 'javelin-behavior', 1650 1651 'javelin-uri', 1651 1652 'phabricator-notification', 1652 - ), 1653 - 'a4fc6fe5' => array( 1654 - 'javelin-behavior', 1655 - 'javelin-util', 1656 - 'javelin-stratcom', 1657 - 'javelin-dom', 1658 - 'javelin-vector', 1659 - 'javelin-magical-init', 1660 - 'javelin-request', 1661 - 'javelin-history', 1662 - 'javelin-workflow', 1663 - 'javelin-mask', 1664 - 'javelin-behavior-device', 1665 - 'phabricator-keyboard-shortcut', 1666 1653 ), 1667 1654 'a80d0378' => array( 1668 1655 'javelin-behavior', ··· 2021 2008 'javelin-dom', 2022 2009 'javelin-vector', 2023 2010 'javelin-magical-init', 2011 + ), 2012 + 'fbe497e7' => array( 2013 + 'javelin-behavior', 2014 + 'javelin-util', 2015 + 'javelin-stratcom', 2016 + 'javelin-dom', 2017 + 'javelin-vector', 2018 + 'javelin-magical-init', 2019 + 'javelin-request', 2020 + 'javelin-history', 2021 + 'javelin-workflow', 2022 + 'javelin-mask', 2023 + 'javelin-behavior-device', 2024 + 'phabricator-keyboard-shortcut', 2024 2025 ), 2025 2026 'fc91ab6c' => array( 2026 2027 'javelin-behavior',
+2
src/applications/pholio/controller/PholioMockEditController.php
··· 383 383 $form_box, 384 384 ); 385 385 386 + $this->addExtraQuicksandConfig( 387 + array('mockEditConfig' => true)); 386 388 return $this->buildApplicationPage( 387 389 $content, 388 390 array(
+6 -2
webroot/rsrc/externals/javelin/lib/Quicksand.js
··· 25 25 JX.install('Quicksand', { 26 26 27 27 statics: { 28 - _id: 0, 28 + _id: null, 29 29 _onpage: 0, 30 30 _cursor: 0, 31 31 _current: 0, ··· 71 71 72 72 73 73 getCurrentPageID: function() { 74 - return JX.Quicksand._id; 74 + var self = JX.Quicksand; 75 + if (self._id === null) { 76 + self._id = window.history.state || 0; 77 + } 78 + return self._id; 75 79 }, 76 80 77 81 /**
+74 -30
webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js
··· 4 4 * javelin-stratcom 5 5 * javelin-dom 6 6 * javelin-workflow 7 + * javelin-quicksand 7 8 * phabricator-phtize 8 9 * phabricator-drag-and-drop-file-upload 9 10 * phabricator-draggable-list 10 11 */ 11 - JX.behavior('pholio-mock-edit', function(config) { 12 + JX.behavior('pholio-mock-edit', function(config, statics) { 12 13 var pht = JX.phtize(config.pht); 13 - 14 - var nodes = { 15 - list: JX.$(config.listID), 16 - drop: JX.$(config.dropID), 17 - order: JX.$(config.orderID) 18 - }; 19 - 20 14 var uploading = []; 21 15 22 16 ··· 26 20 // When the user clicks the "X" on an image, we replace it with a "click to 27 21 // undo" element. If they click to undo, we put the original node back in the 28 22 // DOM. 29 - JX.Stratcom.listen('click', 'pholio-drop-remove', function(e) { 23 + var pholio_drop_remove = function(e) { 30 24 e.kill(); 31 25 32 26 var node = e.getNode('pholio-drop-image'); ··· 40 34 41 35 JX.DOM.replace(node, undo); 42 36 synchronize_order(); 43 - }); 37 + }; 44 38 45 39 46 40 /* -( Reordering Images )-------------------------------------------------- */ 47 41 48 42 49 - var draglist = new JX.DraggableList('pholio-drop-image', nodes.list) 50 - .setGhostNode(JX.$N('div', {className: 'drag-ghost'})) 51 - .setFindItemsHandler(function() { 52 - return JX.DOM.scry(nodes.list, 'div', 'pholio-drop-image'); 53 - }); 54 - 55 - // Only let the user drag images by the handle, not the whole entry. 56 - draglist.listen('shouldBeginDrag', function(e) { 57 - if (!e.getNode('pholio-drag-handle')) { 58 - JX.Stratcom.context().prevent(); 59 - } 60 - }); 61 - 62 43 // Reflect the display order in a hidden input. 63 44 var synchronize_order = function() { 64 - var items = draglist.findItems(); 45 + var items = statics.draglist.findItems(); 65 46 var order = []; 66 47 for (var ii = 0; ii < items.length; ii++) { 67 48 order.push(JX.Stratcom.getData(items[ii]).filePHID); 68 49 } 69 - nodes.order.value = order.join(','); 50 + statics.nodes.order.value = order.join(','); 70 51 }; 71 52 72 - draglist.listen('didDrop', synchronize_order); 73 - synchronize_order(); 53 + 54 + var build_draglist = function(node) { 55 + var draglist = new JX.DraggableList('pholio-drop-image', node) 56 + .setGhostNode(JX.$N('div', {className: 'drag-ghost'})) 57 + .setFindItemsHandler(function() { 58 + return JX.DOM.scry(node, 'div', 'pholio-drop-image'); 59 + }); 60 + 61 + // Only let the user drag images by the handle, not the whole entry. 62 + draglist.listen('shouldBeginDrag', function(e) { 63 + if (!e.getNode('pholio-drag-handle')) { 64 + JX.Stratcom.context().prevent(); 65 + } 66 + }); 67 + draglist.listen('didDrop', synchronize_order); 68 + return draglist; 69 + }; 74 70 75 71 76 72 /* -( Build )-------------------------------------------------------------- */ ··· 97 93 drop.listen('willUpload', function(file) { 98 94 var node = render_uploading(); 99 95 uploading.push({node: node, file: file}); 100 - nodes.list.appendChild(node); 96 + statics.nodes.list.appendChild(node); 101 97 }); 102 98 103 99 drop.listen('didUpload', function(file) { ··· 191 187 192 188 /* -( Init )--------------------------------------------------------------- */ 193 189 194 - build_add_control(nodes.drop); 195 - build_list_controls(nodes.list); 190 + 191 + function update_statics(data, page_id, no_build) { 192 + statics.nodes = { 193 + list: JX.$(data.listID), 194 + drop: JX.$(data.dropID), 195 + order: JX.$(data.orderID) 196 + }; 197 + 198 + if (!statics.mockEditCache[page_id]) { 199 + statics.mockEditCache[page_id] = {}; 200 + } 201 + statics.mockEditCache[page_id].config = config; 202 + statics.mockEditCache[page_id].nodes = statics.nodes; 203 + 204 + if (no_build !== true) { 205 + build_add_control(statics.nodes.drop); 206 + build_list_controls(statics.nodes.list); 207 + statics.draglist = build_draglist(statics.nodes.list); 208 + statics.mockEditCache[page_id].draglist = statics.draglist; 209 + } else { 210 + statics.draglist = statics.mockEditCache[page_id].draglist; 211 + } 212 + synchronize_order(); 213 + } 196 214 215 + function install() { 216 + statics.mockEditCache = {}; 217 + JX.Stratcom.listen('click', 'pholio-drop-remove', pholio_drop_remove); 218 + JX.Stratcom.listen( 219 + 'quicksand-redraw', 220 + null, 221 + function (e) { 222 + e.kill(); 223 + 224 + var data = e.getData(); 225 + if (!data.newResponse.mockEditConfig) { 226 + return; 227 + } 228 + if (data.fromServer) { 229 + // we ran update_statics(config) below already 230 + } else { 231 + var page_id = data.newResponseID; 232 + var new_config = statics.mockEditCache[page_id].config; 233 + update_statics(new_config, page_id, true); 234 + } 235 + }); 236 + return true; 237 + } 238 + 239 + statics.installed = statics.installed || install(); 240 + update_statics(config, JX.Quicksand.getCurrentPageID(), false); 197 241 });
+8
webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
··· 233 233 } 234 234 235 235 function redraw_inlines(id) { 236 + if (!statics.enabled) { 237 + return; 238 + } 239 + 236 240 if (!active_image) { 237 241 return; 238 242 } ··· 306 310 } 307 311 308 312 function redraw_selection() { 313 + if (!statics.enabled) { 314 + return; 315 + } 316 + 309 317 var classes = ['pholio-mock-reticle-selection']; 310 318 selection_reticle = selection_reticle || render_reticle(classes, ''); 311 319