phorge/webroot/rsrc/js/core/Hovercard.js
epriestley 0569218201 Use JsShrink if jsxmin is not available
Summary: If `jsxmin` is not available, use a pure PHP implementation instead (JsShrink).

Test Plan:
  - Ran `arc lint --lintall` on all JS and fixed every relevant warning.
  - Forced minification on and browsed around the site using JS behaviors. Didn't hit anything problematic.

Reviewers: vrana, btrahan

Reviewed By: vrana

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D5670
2013-05-18 17:04:22 -07:00

159 lines
3.9 KiB
JavaScript

/**
* @requires javelin-install
* javelin-dom
* javelin-vector
* javelin-request
* javelin-uri
* @provides phabricator-hovercard
* @javelin
*/
JX.install('Hovercard', {
statics : {
_node : null,
_activeRoot : null,
_visiblePHID : null,
fetchUrl : '/search/hovercard/retrieve/',
/**
* Hovercard storage. {"PHID-XXXX-YYYY":"<...>", ...}
*/
_cards : {},
getAnchor : function() {
return this._activeRoot;
},
getCard : function() {
var self = JX.Hovercard;
return self._node;
},
show : function(root, phid) {
var self = JX.Hovercard;
// Already displaying
if (self.getCard() && phid == self._visiblePHID) {
return;
}
self.hide();
self._visiblePHID = phid;
self._activeRoot = root;
if (!(phid in self._cards)) {
self._load([phid]);
} else {
self._drawCard(phid);
}
},
_drawCard : function(phid) {
var self = JX.Hovercard;
// card is loading...
if (self._cards[phid] === true) {
return;
}
// Not the current requested card
if (phid != self._visiblePHID) {
return;
}
// Not loaded
if (!(phid in self._cards)) {
return;
}
var root = self._activeRoot;
var node = JX.$N('div',
{ className: 'jx-hovercard-container' },
JX.$H(self._cards[phid]));
self._node = node;
// Append the card to the document, but offscreen, so we can measure it.
node.style.left = '-10000px';
document.body.appendChild(node);
// Retrieve size from child (wrapper), since node gives wrong dimensions?
var child = node.firstChild;
var p = JX.$V(root);
var d = JX.Vector.getDim(root);
var n = JX.Vector.getDim(child);
// Move the tip so it's nicely aligned.
// I'm just doing north/south alignment for now
// TODO: Fix southern graceful align
var margin = 20;
// We can't shift left by ~$margin or more here due to Pholio, Phriction
var x = parseInt(p.x, 10) - margin / 2;
var y = parseInt(p.y - n.y, 10) - margin;
// If more in the center, we can safely center
if (x > (n.x / 2) + margin) {
x = parseInt(p.x - (n.x / 2) + d.x, 10);
}
// Temporarily disabled, since it gives weird results (you can only see
// a hovercard once, as soon as it's hidden, it cannot be shown again)
// if (y < n.y) {
// // Place it southern, since northern is not enough space
// y = p.y + d.y + margin;
// }
node.style.left = x + 'px';
node.style.top = y + 'px';
},
hide : function() {
var self = JX.Hovercard;
self._visiblePHID = null;
self._activeRoot = null;
if (self._node) {
JX.DOM.remove(self._node);
self._node = null;
}
},
/**
* Pass it an array of phids to load them into storage
*
* @param list phids
*/
_load : function(phids) {
var self = JX.Hovercard;
var uri = JX.$U(self.fetchUrl);
var send = false;
for (var ii = 0; ii < phids.length; ii++) {
var phid = phids[ii];
if (phid in self._cards) {
continue;
}
self._cards[phid] = true; // means "loading"
uri.setQueryParam("phids["+ii+"]", phids[ii]);
send = true;
}
if (!send) {
// already loaded / loading everything!
return;
}
new JX.Request(uri, function(r) {
for (var phid in r.cards) {
self._cards[phid] = r.cards[phid];
// Don't draw if the user is faster than the browser
// Only draw if the user is still requesting the original card
if (self.getCard() && phid != self._visiblePHID) {
continue;
}
self._drawCard(phid);
}
}).send();
}
}
});