# # # patch "static/viewmtn.js" # from [1594a2d8fd9177e86b70c50aa28c444fb99fbdf0] # to [ae8fd3bf21855360e73af1cad004484f400b49fa] # # patch "viewmtn.py" # from [444f150598d7cee254bf16fb29ab1a16abcd8b20] # to [01dc582e6e292d4f11ce0a526a4f143d13169d48] # ============================================================ --- static/viewmtn.js 1594a2d8fd9177e86b70c50aa28c444fb99fbdf0 +++ static/viewmtn.js ae8fd3bf21855360e73af1cad004484f400b49fa @@ -6,108 +6,101 @@ function installCallbacks() function installCallbacks() { - if (callbacksInstalled != false) { - return; - } - callbacksInstalled = true; + if (callbacksInstalled != false) { + return; + } + callbacksInstalled = true; - cbinst = function (e) { - updateNodeAttributes(e, { "onmouseover" : partial(mouseOverHandler, e), - 'onmouseout' : partial(mouseOutHandler, e) } ); - } + cbinst = function (e) { + updateNodeAttributes(e, { "onmouseover" : partial(mouseOverHandler, e), + 'onmouseout' : partial(mouseOutHandler, e) } ); + } - var elems = getElementsByTagAndClassName(null, "BranchLink"); - map(cbinst, elems); + var elems = getElementsByTagAndClassName(null, "BranchLink"); + map(cbinst, elems); - var elems = getElementsByTagAndClassName(null, "RevisionLink"); - map(cbinst, elems); + var elems = getElementsByTagAndClassName(null, "RevisionLink"); + map(cbinst, elems); - var elems = getElementsByTagAndClassName(null, "ManifestLink"); - map(cbinst, elems); + var elems = getElementsByTagAndClassName(null, "ManifestLink"); + map(cbinst, elems); - theBox = $("popupBox"); + theBox = $("popupBox"); } function updatePopup(boundTo, className) { - jsonData = boundTo.jsonData; + jsonData = boundTo.jsonData; - var pos = elementPosition(boundTo); - var newBox; + var pos = elementPosition(boundTo); + var newBox; - info = null; - if (jsonData.type == "branch") { - info = "branch last updated " + jsonData.ago + " by " + jsonData.author; - } else if (jsonData.type == "revision") { - info = jsonData.ago + " ago by " + jsonData.author; - } else if (jsonData.type == "manifest") { - info = "manifest contains " + jsonData.file_count + " files in " + jsonData.directory_count + " directories."; - } else { - info = "unknown type: " + jsonData.type; - } + info = null; + if (jsonData.type == "branch") { + info = "branch changed " + jsonData.ago + " ago by " + jsonData.author; + } else if (jsonData.type == "revision") { + info = jsonData.ago + " ago by " + jsonData.author; + } else if (jsonData.type == "manifest") { + info = "manifest contains " + jsonData.file_count + " files in " + jsonData.directory_count + " directories."; + } else { + info = "unknown type: " + jsonData.type; + } - newBox = DIV({ 'id' : 'popupBox'}, - info); + newBox = DIV({ 'id' : 'popupBox', 'style' : 'font-size: small'}, info); - if (boundTo.offsetHeight) { - offset_height = boundTo.offsetHeight; - } else { - offset_height = 24; // yick - } + if (boundTo.offsetHeight) { + offset_height = boundTo.offsetHeight; + } else { + offset_height = 24; // yick + } - newY = pos.y + offset_height + 20; - newX = pos.x + 20; + newY = pos.y + offset_height + 20; + newX = pos.x + 20; - newBox.style.top = newY + 'px'; - newBox.style.left = newX + 'px'; - swapDOM(theBox, newBox); - theBox = newBox; + newBox.style.top = newY + 'px'; + newBox.style.left = newX + 'px'; + swapDOM(theBox, newBox); + theBox = newBox; } function jsonLoadComplete(boundTo, className, jsonData) { - boundTo.jsonData = jsonData; - updatePopup(boundTo, className); - pendingDeferred = null; - pendingFor = null; + boundTo.jsonData = jsonData; + updatePopup(boundTo, className); + pendingDeferred = null; + pendingFor = null; } function mouseOverHandler(boundTo, evt) { - var className = getNodeAttribute(boundTo, "class"); - - if ((pendingFor != null) && (pendingFor == boundTo)) { - return; - } else { - pendingFor = boundTo; - } - - if (boundTo.jsonData) { - return updatePopup(boundTo, className); - } + var className = getNodeAttribute(boundTo, "class"); - links = getElementsByTagAndClassName('a', null, boundTo); + if ((pendingFor != null) && (pendingFor == boundTo)) { + return; + } else { + pendingFor = boundTo; + } - if (links.length > 0) { - linkHref = links[0].href; - } else { - return; - } + if (boundTo.jsonData) { + return updatePopup(boundTo, className); + } + + if (boundTo.id) { + var uri = "/json/" + encodeURIComponent(className) + "/" + encodeURIComponent(boundTo.id); + var d = loadJSONDoc(uri); - var uri = "/json/" + encodeURIComponent(className) + "/" + encodeURIComponent(linkHref); - var d = loadJSONDoc(uri); - - d.addCallback(jsonLoadComplete, boundTo, className); - pendingDeferred = d; + d.addCallback(jsonLoadComplete, boundTo, className); + pendingDeferred = d; + } } function mouseOutHandler(boundTo, evt) { - if (pendingDeferred != null) { - pendingDeferred.cancel(); - pendingDeferred = null; - } - var newBox = DIV({'id' : 'popupBox', 'class' : 'invisible'}); - swapDOM(theBox, newBox); - theBox = newBox; + if (pendingDeferred != null) { + pendingDeferred.cancel(); + pendingDeferred = null; + } + var newBox = DIV({'id' : 'popupBox', 'class' : 'invisible'}); + swapDOM(theBox, newBox); + theBox = newBox; } ============================================================ --- viewmtn.py 444f150598d7cee254bf16fb29ab1a16abcd8b20 +++ viewmtn.py 01dc582e6e292d4f11ce0a526a4f143d13169d48 @@ -6,6 +6,7 @@ import web import sha import sys import web +import json import struct import string import rfc822 @@ -91,6 +92,7 @@ class Link: self.absolute_uri = None self.relative_uri = None self.description = description + self.json_args = None def uri(self): return dynamic_join(self.relative_uri) def html(self, override_description=None, force_nbsp=False): @@ -107,7 +109,11 @@ class Link: uri = self.absolute_uri else: return self.description - return '%s' % (hq(str(self.__class__).split('.')[-1]), uri, d) + rv = '%s' % (uri, d) + if self.json_args != None: + rv = '' % (hq(urllib.quote(json.write(self.json_args))), + hq(str(self.__class__).split('.')[-1])) + rv + '' + return rv class AuthorLink(Link): def __init__(self, author, **kwargs): @@ -139,6 +145,7 @@ class BranchLink(Link): class BranchLink(Link): def __init__(self, branch, **kwargs): Link.__init__(*(self, ), **kwargs) + self.json_args = [branch.name] from_change, to_change = kwargs.get('from_change'), kwargs.get('to_change') if from_change and to_change: self.relative_uri = 'branch/changes/%s/from/%d/to/%d' % (urllib.quote(branch.name), from_change, to_change) @@ -347,6 +354,7 @@ class BranchChanges: if len(revs) == 0: raise Exception("get_last_changes() unable to find somewhere to start - probably a non-existent branch?") to_parent = revs+[] # copy + new_to_parent = [] count = to_change def on_our_branch(r): @@ -934,9 +942,36 @@ class Json: return web.notfound() class Json: - def GET(self, method, data): - print "Bah." + def BranchLink(self, for_branch): + rv = { + 'type' : 'branch', + 'branch' : for_branch, + } + branch = mtn.Branch(for_branch) + changes = BranchChanges().get_last_changes(branch, [t for t in ops.heads(branch.name)], 0, 1) + if len(changes) < 1: + return web.notfound() + changes, new_starting_point = changes + for rev, certs in changes: + for cert in certs: + if cert[4] != 'name': + continue + if cert[5] == 'author': + rv['author'] = cert[7] + if cert[5] == 'date': + revdate = common.parse_timecert(cert[7]) + rv['ago'] = common.ago(revdate) + return rv + def GET(self, method, encoded_args): + writer = json.JsonWriter() + args = json.read(urllib.unquote(encoded_args)) + if hasattr(self, method): + rv = getattr(self, method)(*args) + else: + return web.notfound() + print writer.write(rv) + class BranchHead: def GET(self, head_method, proxy_to, branch, extra_path): branch = mtn.Branch(branch) @@ -996,7 +1031,7 @@ urls = ( r'/about', 'About', #done r'/tags', 'Tags', #done r'/help', 'Help', #done - r'/json/(A-Za-z)/(.*)', 'Json', + r'/json/([A-Za-z]+)/(.*)', 'Json', r'/revision/browse/('+mtn.revision_re+')/(.*)', 'RevisionBrowse', r'/revision/browse/('+mtn.revision_re+')()', 'RevisionBrowse',