diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 53b5069337..d4e992531b 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,7 +8,7 @@ return array( 'names' => array( 'core.pkg.css' => 'ca3f6a60', - 'core.pkg.js' => '74e57ea0', + 'core.pkg.js' => 'ff529dc7', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => 'bb338e4b', 'differential.pkg.js' => '3cfa26f9', @@ -205,7 +205,7 @@ return array( 'rsrc/externals/javelin/lib/JSON.js' => '69adf288', 'rsrc/externals/javelin/lib/Leader.js' => '331b1611', 'rsrc/externals/javelin/lib/Mask.js' => '8a41885b', - 'rsrc/externals/javelin/lib/Quicksand.js' => '977e1f47', + 'rsrc/externals/javelin/lib/Quicksand.js' => '4cebc641', 'rsrc/externals/javelin/lib/Request.js' => '94b750d2', 'rsrc/externals/javelin/lib/Resource.js' => '44959b73', 'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692', @@ -397,8 +397,8 @@ return array( 'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3', 'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc', 'rsrc/js/application/phame/phame-post-preview.js' => 'be807912', - 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '9c2623f4', - 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'a4fc6fe5', + 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '246dc085', + 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'fbe497e7', 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf', 'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c', 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef', @@ -626,8 +626,8 @@ return array( 'javelin-behavior-phabricator-transaction-list' => '13c739ea', 'javelin-behavior-phabricator-watch-anchor' => '9f36c42d', 'javelin-behavior-phame-post-preview' => 'be807912', - 'javelin-behavior-pholio-mock-edit' => '9c2623f4', - 'javelin-behavior-pholio-mock-view' => 'a4fc6fe5', + 'javelin-behavior-pholio-mock-edit' => '246dc085', + 'javelin-behavior-pholio-mock-view' => 'fbe497e7', 'javelin-behavior-phui-object-box-tabs' => '2bfa2836', 'javelin-behavior-phui-timeline-dropdown-menu' => '4d94d9c3', 'javelin-behavior-policy-control' => '9a340b3d', @@ -668,7 +668,7 @@ return array( 'javelin-leader' => '331b1611', 'javelin-magical-init' => '3010e992', 'javelin-mask' => '8a41885b', - 'javelin-quicksand' => '977e1f47', + 'javelin-quicksand' => '4cebc641', 'javelin-reactor' => '2b8de964', 'javelin-reactor-dom' => 'c90a04fc', 'javelin-reactor-node-calmer' => '76f4ebed', @@ -972,6 +972,16 @@ return array( 'javelin-workflow', 'javelin-util', ), + '246dc085' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-workflow', + 'javelin-quicksand', + 'phabricator-phtize', + 'phabricator-drag-and-drop-file-upload', + 'phabricator-draggable-list', + ), '2529c82d' => array( 'javelin-dom', 'javelin-util', @@ -1117,6 +1127,9 @@ return array( 'javelin-request', 'javelin-util', ), + '4cebc641' => array( + 'javelin-install', + ), '4d94d9c3' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1578,9 +1591,6 @@ return array( 'javelin-resource', 'javelin-routable', ), - '977e1f47' => array( - 'javelin-install', - ), '988040b4' => array( 'javelin-install', 'javelin-dom', @@ -1595,15 +1605,6 @@ return array( 'phuix-action-view', 'javelin-workflow', ), - '9c2623f4' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-workflow', - 'phabricator-phtize', - 'phabricator-drag-and-drop-file-upload', - 'phabricator-draggable-list', - ), '9f36c42d' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1650,20 +1651,6 @@ return array( 'javelin-uri', 'phabricator-notification', ), - 'a4fc6fe5' => array( - 'javelin-behavior', - 'javelin-util', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-vector', - 'javelin-magical-init', - 'javelin-request', - 'javelin-history', - 'javelin-workflow', - 'javelin-mask', - 'javelin-behavior-device', - 'phabricator-keyboard-shortcut', - ), 'a80d0378' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2022,6 +2009,20 @@ return array( 'javelin-vector', 'javelin-magical-init', ), + 'fbe497e7' => array( + 'javelin-behavior', + 'javelin-util', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-vector', + 'javelin-magical-init', + 'javelin-request', + 'javelin-history', + 'javelin-workflow', + 'javelin-mask', + 'javelin-behavior-device', + 'phabricator-keyboard-shortcut', + ), 'fc91ab6c' => array( 'javelin-behavior', 'javelin-dom', diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php index 357f4e49da..7cfa0b35b4 100644 --- a/src/applications/pholio/controller/PholioMockEditController.php +++ b/src/applications/pholio/controller/PholioMockEditController.php @@ -383,6 +383,8 @@ final class PholioMockEditController extends PholioController { $form_box, ); + $this->addExtraQuicksandConfig( + array('mockEditConfig' => true)); return $this->buildApplicationPage( $content, array( diff --git a/webroot/rsrc/externals/javelin/lib/Quicksand.js b/webroot/rsrc/externals/javelin/lib/Quicksand.js index f72eb23cbc..adf451ac44 100644 --- a/webroot/rsrc/externals/javelin/lib/Quicksand.js +++ b/webroot/rsrc/externals/javelin/lib/Quicksand.js @@ -25,7 +25,7 @@ JX.install('Quicksand', { statics: { - _id: 0, + _id: null, _onpage: 0, _cursor: 0, _current: 0, @@ -71,7 +71,11 @@ JX.install('Quicksand', { getCurrentPageID: function() { - return JX.Quicksand._id; + var self = JX.Quicksand; + if (self._id === null) { + self._id = window.history.state || 0; + } + return self._id; }, /** diff --git a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js index 4977bf0a13..8a62f7d0db 100644 --- a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js +++ b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js @@ -4,19 +4,13 @@ * javelin-stratcom * javelin-dom * javelin-workflow + * javelin-quicksand * phabricator-phtize * phabricator-drag-and-drop-file-upload * phabricator-draggable-list */ -JX.behavior('pholio-mock-edit', function(config) { +JX.behavior('pholio-mock-edit', function(config, statics) { var pht = JX.phtize(config.pht); - - var nodes = { - list: JX.$(config.listID), - drop: JX.$(config.dropID), - order: JX.$(config.orderID) - }; - var uploading = []; @@ -26,7 +20,7 @@ JX.behavior('pholio-mock-edit', function(config) { // When the user clicks the "X" on an image, we replace it with a "click to // undo" element. If they click to undo, we put the original node back in the // DOM. - JX.Stratcom.listen('click', 'pholio-drop-remove', function(e) { + var pholio_drop_remove = function(e) { e.kill(); var node = e.getNode('pholio-drop-image'); @@ -40,37 +34,39 @@ JX.behavior('pholio-mock-edit', function(config) { JX.DOM.replace(node, undo); synchronize_order(); - }); + }; /* -( Reordering Images )-------------------------------------------------- */ - var draglist = new JX.DraggableList('pholio-drop-image', nodes.list) - .setGhostNode(JX.$N('div', {className: 'drag-ghost'})) - .setFindItemsHandler(function() { - return JX.DOM.scry(nodes.list, 'div', 'pholio-drop-image'); - }); - - // Only let the user drag images by the handle, not the whole entry. - draglist.listen('shouldBeginDrag', function(e) { - if (!e.getNode('pholio-drag-handle')) { - JX.Stratcom.context().prevent(); - } - }); - // Reflect the display order in a hidden input. var synchronize_order = function() { - var items = draglist.findItems(); + var items = statics.draglist.findItems(); var order = []; for (var ii = 0; ii < items.length; ii++) { order.push(JX.Stratcom.getData(items[ii]).filePHID); } - nodes.order.value = order.join(','); + statics.nodes.order.value = order.join(','); }; - draglist.listen('didDrop', synchronize_order); - synchronize_order(); + + var build_draglist = function(node) { + var draglist = new JX.DraggableList('pholio-drop-image', node) + .setGhostNode(JX.$N('div', {className: 'drag-ghost'})) + .setFindItemsHandler(function() { + return JX.DOM.scry(node, 'div', 'pholio-drop-image'); + }); + + // Only let the user drag images by the handle, not the whole entry. + draglist.listen('shouldBeginDrag', function(e) { + if (!e.getNode('pholio-drag-handle')) { + JX.Stratcom.context().prevent(); + } + }); + draglist.listen('didDrop', synchronize_order); + return draglist; + }; /* -( Build )-------------------------------------------------------------- */ @@ -97,7 +93,7 @@ JX.behavior('pholio-mock-edit', function(config) { drop.listen('willUpload', function(file) { var node = render_uploading(); uploading.push({node: node, file: file}); - nodes.list.appendChild(node); + statics.nodes.list.appendChild(node); }); drop.listen('didUpload', function(file) { @@ -191,7 +187,55 @@ JX.behavior('pholio-mock-edit', function(config) { /* -( Init )--------------------------------------------------------------- */ - build_add_control(nodes.drop); - build_list_controls(nodes.list); + function update_statics(data, page_id, no_build) { + statics.nodes = { + list: JX.$(data.listID), + drop: JX.$(data.dropID), + order: JX.$(data.orderID) + }; + + if (!statics.mockEditCache[page_id]) { + statics.mockEditCache[page_id] = {}; + } + statics.mockEditCache[page_id].config = config; + statics.mockEditCache[page_id].nodes = statics.nodes; + + if (no_build !== true) { + build_add_control(statics.nodes.drop); + build_list_controls(statics.nodes.list); + statics.draglist = build_draglist(statics.nodes.list); + statics.mockEditCache[page_id].draglist = statics.draglist; + } else { + statics.draglist = statics.mockEditCache[page_id].draglist; + } + synchronize_order(); + } + + function install() { + statics.mockEditCache = {}; + JX.Stratcom.listen('click', 'pholio-drop-remove', pholio_drop_remove); + JX.Stratcom.listen( + 'quicksand-redraw', + null, + function (e) { + e.kill(); + + var data = e.getData(); + if (!data.newResponse.mockEditConfig) { + return; + } + if (data.fromServer) { + // we ran update_statics(config) below already + } else { + var page_id = data.newResponseID; + var new_config = statics.mockEditCache[page_id].config; + update_statics(new_config, page_id, true); + } + }); + return true; + } + + statics.installed = statics.installed || install(); + update_statics(config, JX.Quicksand.getCurrentPageID(), false); }); diff --git a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js index d873ea060e..3991f4cc4e 100644 --- a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js +++ b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js @@ -233,6 +233,10 @@ JX.behavior('pholio-mock-view', function(config, statics) { } function redraw_inlines(id) { + if (!statics.enabled) { + return; + } + if (!active_image) { return; } @@ -306,6 +310,10 @@ JX.behavior('pholio-mock-view', function(config, statics) { } function redraw_selection() { + if (!statics.enabled) { + return; + } + var classes = ['pholio-mock-reticle-selection']; selection_reticle = selection_reticle || render_reticle(classes, '');