Changeset - 2bfcec6a3985
[Not reviewed]
beta
0 12 0
Marcin Kuzminski - 13 years ago 2012-10-29 21:18:14
marcin@python-works.com
new tooltip implementation
- added lazy loading of changeset tooltips for journal data
12 files changed with 203 insertions and 39 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
@@ -433,12 +433,15 @@ def make_map(config):
 

	
 
    rmap.connect('raw_changeset_home',
 
                 '/{repo_name:.*?}/raw-changeset/{revision}',
 
                 controller='changeset', action='raw_changeset',
 
                 revision='tip', conditions=dict(function=check_repo))
 

	
 
    rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
 
                 controller='changeset', action='changeset_info')
 

	
 
    rmap.connect('compare_url',
 
                 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
 
                 controller='compare', action='index',
 
                 conditions=dict(function=check_repo),
 
                 requirements=dict(
 
                            org_ref_type='(branch|book|tag|rev|org_ref_type)',
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -23,13 +23,13 @@
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
import traceback
 
from collections import defaultdict
 
from webob.exc import HTTPForbidden
 
from webob.exc import HTTPForbidden, HTTPBadRequest
 

	
 
from pylons import tmpl_context as c, url, request, response
 
from pylons.i18n.translation import _
 
from pylons.controllers.util import redirect
 
from pylons.decorators import jsonify
 

	
 
@@ -442,6 +442,13 @@ class ChangesetController(BaseRepoContro
 
        if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
 
            ChangesetCommentsModel().delete(comment=co)
 
            Session().commit()
 
            return True
 
        else:
 
            raise HTTPForbidden()
 

	
 
    @jsonify
 
    def changeset_info(self, repo_name, revision):
 
        if request.is_xhr or 1:
 
            return c.rhodecode_repo.get_changeset(revision)
 
        else:
 
            raise HTTPBadRequest()
rhodecode/lib/helpers.py
Show inline comments
 
@@ -529,13 +529,14 @@ def action_parser(user_log, feed=False, 
 
                ## changeset cannot be found/striped/removed etc.
 
                lbl = ('%s' % rev)[:12]
 
                _url = '#'
 
                title = _('Changeset not found')
 
            if parse_cs:
 
                return link_to(lbl, _url, title=title, class_='tooltip')
 
            return link_to(lbl, _url, raw_id=rev.raw_id, class_='journal-cs')
 
            return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
 
                           class_='lazy-cs')
 

	
 
        revs = []
 
        if len(filter(lambda v: v != '', revs_ids)) > 0:
 
            repo = None
 
            for rev in revs_ids[:revs_top_limit]:
 
                # we want parsed changesets, or new log store format is bad
rhodecode/lib/vcs/backends/base.py
Show inline comments
 
@@ -369,12 +369,21 @@ class BaseChangeset(object):
 
    def __unicode__(self):
 
        return u'%s:%s' % (self.revision, self.short_id)
 

	
 
    def __eq__(self, other):
 
        return self.raw_id == other.raw_id
 

	
 
    def __json__(self):
 
        return dict(
 
            short_id=self.short_id,
 
            raw_id=self.raw_id,
 
            message=self.message,
 
            date=self.date,
 
            author=self.author,
 
        )
 

	
 
    @LazyProperty
 
    def last(self):
 
        if self.repository is None:
 
            raise ChangesetError("Cannot check if it's most recent revision")
 
        return self.raw_id == self.repository.revisions[-1]
 

	
rhodecode/public/css/style.css
Show inline comments
 
@@ -2998,28 +2998,30 @@ table.code-browser .submodule-dir {
 
.yui-overlay,.yui-panel-container {
 
	visibility: hidden;
 
	position: absolute;
 
	z-index: 2;
 
}
 
 
.yui-tt {
 
	visibility: hidden;
 
#tip-box {
 
	position: absolute;
 
	color: #666;
 
	
 
	background-color: #FFF;
 
	border: 2px solid #003367;
 
	font: 100% sans-serif;
 
	width: auto;
 
	opacity: 1px;
 
	padding: 8px;
 
	
 
	white-space: pre-wrap;
 
	-webkit-border-radius: 8px 8px 8px 8px;
 
	-khtml-border-radius: 8px 8px 8px 8px;
 
	-moz-border-radius: 8px 8px 8px 8px;
 
	border-radius: 8px 8px 8px 8px;
 
	box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
	-moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
	-webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
 
}
 
 
.mentions-container{
 
	width: 90% !important;
 
}
 
.mentions-container .yui-ac-content{
rhodecode/public/js/rhodecode.js
Show inline comments
 
@@ -247,12 +247,30 @@ function ypjax(url,container,s_call,f_ca
 
		},
 
		cache:false
 
	},args);
 
	
 
};
 

	
 
var ajaxGET = function(url,success) {
 
	// Set special header for ajax == HTTP_X_PARTIAL_XHR
 
	YUC.initHeader('X-PARTIAL-XHR',true);
 

	
 
    var sUrl = url;
 
    var callback = {
 
        success: success,
 
        failure: function (o) {
 
            alert("error");
 
        },
 
    };
 

	
 
    var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
 
    return request;
 
};
 

	
 

	
 

	
 
var ajaxPOST = function(url,postData,success) {
 
	// Set special header for ajax == HTTP_X_PARTIAL_XHR
 
	YUC.initHeader('X-PARTIAL-XHR',true);
 
	
 
	var toQueryString = function(o) {
 
	    if(typeof o !== 'object') {
 
@@ -279,33 +297,14 @@ var ajaxPOST = function(url,postData,suc
 

	
 

	
 
/**
 
 * tooltip activate
 
 */
 
var tooltip_activate = function(){
 
    function toolTipsId(){
 
        var ids = [];
 
        var tts = YUQ('.tooltip');
 
        for (var i = 0; i < tts.length; i++) {
 
            // if element doesn't not have and id 
 
        	//  autogenerate one for tooltip 
 
            if (!tts[i].id){
 
                tts[i].id='tt'+((i*100)+tts.length);
 
            }
 
            ids.push(tts[i].id);
 
        }
 
        return ids
 
    };
 
    var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
 
        context: [[toolTipsId()],"tl","bl",null,[0,5]],
 
        monitorresize:false,
 
        xyoffset :[0,0],
 
        autodismissdelay:300000,
 
        hidedelay:5,
 
        showdelay:20,
 
    });
 
	yt = YAHOO.yuitip.main;
 
	YUE.onDOMReady(yt.init);
 
};
 

	
 
/**
 
 * show more
 
 */
 
var show_more_event = function(){
 
@@ -313,12 +312,146 @@ var show_more_event = function(){
 
        var el = e.target;
 
        YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
 
        YUD.setStyle(el.parentNode,'display','none');
 
    });
 
};
 

	
 
/**
 
 * show changeset tooltip
 
 */
 
var show_changeset_tooltip = function(){
 
	YUE.on(YUD.getElementsByClassName('lazy-cs'), 'mouseover', function(e){
 
		var target = e.currentTarget;
 
		var rid = YUD.getAttribute(target,'raw_id');
 
		var repo_name = YUD.getAttribute(target,'repo_name');
 
		var ttid = 'tt-'+rid;
 
		var success = function(o){
 
			console.log(o.responseText);
 
			var json = JSON.parse(o.responseText);
 
			YUD.addClass(target,'tooltip')
 
			YUD.setAttribute(target, 'title',json['message']);
 
			YAHOO.yuitip.main.show_yuitip(e, target);
 
		}
 
		if(rid && !YUD.hasClass(target, 'tooltip')){
 
			YUD.setAttribute(target,'id',ttid);
 
			ajaxGET('/changeset_info/{0}/{1}'.format(repo_name,rid), success)
 
		}
 
	});
 
};
 

	
 

	
 
/**
 
 * TOOLTIP IMPL.
 
 */
 
YAHOO.namespace('yuitip');
 
YAHOO.yuitip.main = {
 

	
 
	YE:			YAHOO.util.Event,
 
	Dom:		YAHOO.util.Dom,
 
	$:			YAHOO.util.Dom.get,
 

	
 
	bgColor:	'#000',
 
	speed:		0.3,
 
	opacity:	0.9,
 
	offset:		[15,15],
 
	useAnim:	false,
 
	maxWidth:	200,
 
	add_links:	true,
 

	
 
	init: function(){
 
		yt._tooltip = '';
 
		yt.tipBox = yt.$('tip-box');
 
		if(!yt.tipBox){
 
			yt.tipBox = document.createElement('div');
 
			document.body.appendChild(yt.tipBox);
 
			yt.tipBox.id = 'tip-box';
 
		}
 

	
 
		yt.Dom.setStyle(yt.tipBox, 'display', 'none');
 
		yt.Dom.setStyle(yt.tipBox, 'position', 'absolute');
 
		if(yt.maxWidth !== null){
 
			yt.Dom.setStyle(yt.tipBox, 'max-width', yt.maxWidth+'px');
 
		}
 

	
 
		var yuitips = yt.Dom.getElementsByClassName('tooltip');
 

	
 
		if(yt.add_links === true){
 
			var links = document.getElementsByTagName('a');
 
			var linkLen = links.length;
 
			for(i=0;i<linkLen;i++){
 
				yuitips.push(links[i]);
 
			}
 
		}
 

	
 
		var yuiLen = yuitips.length;
 

	
 
		for(i=0;i<yuiLen;i++){
 
			yt.YE.on(yuitips[i], 'mouseover', yt.show_yuitip, yuitips[i]);
 
			yt.YE.on(yuitips[i], 'mousemove', yt.move_yuitip, yuitips[i]);
 
			yt.YE.on(yuitips[i], 'mouseout', yt.close_yuitip, yuitips[i]);
 
		}
 
	},
 

	
 
	show_yuitip: function(e, el){
 
		yt.YE.stopEvent(e);
 
		if(el.tagName.toLowerCase() === 'img'){
 
			yt.tipText = el.alt ? el.alt : '';
 
		} else {
 
			yt.tipText = el.title ? el.title : '';
 
		}
 

	
 
		
 
		if(yt.tipText !== ''){
 
			// save org title
 
			yt._tooltip = yt.tipText;
 
			// reset title to not show org tooltips
 
			YUD.setAttribute(el, 'title', '');
 

	
 
			var newTipText = yt.tipText.split(' - ');
 
			var tipLen = newTipText.length;
 
			yt.tipText = '';
 
			for(var i=0;i<tipLen;i++){
 
				yt.tipText+= newTipText[i]+"<br/>";
 
			}
 
			yt.tipBox.innerHTML = yt.tipText;
 
			yt.Dom.setStyle(yt.tipBox, 'display', 'block');
 
			if(yt.useAnim === true){
 
				yt.Dom.setStyle(yt.tipBox, 'opacity', '0');
 
				var newAnim = new YAHOO.util.Anim(yt.tipBox,
 
					{
 
						opacity: { to: yt.opacity }
 
					}, yt.speed, YAHOO.util.Easing.easeOut
 
				);
 
				newAnim.animate();
 
			}
 
		}
 
	},
 

	
 
	move_yuitip: function(e, el){
 
		yt.YE.stopEvent(e);
 
		var movePos = yt.YE.getXY(e);
 
		yt.Dom.setStyle(yt.tipBox, 'top', (movePos[1] + yt.offset[1]) + 'px');
 
		yt.Dom.setStyle(yt.tipBox, 'left', (movePos[0] + yt.offset[0]) + 'px');
 
	},
 

	
 
	close_yuitip: function(e, el){
 
		yt.YE.stopEvent(e);
 
	
 
		if(yt.useAnim === true){
 
			var newAnim = new YAHOO.util.Anim(yt.tipBox,
 
				{
 
					opacity: { to: 0 }
 
				}, yt.speed, YAHOO.util.Easing.easeOut
 
			);
 
			newAnim.animate();
 
		} else {
 
			yt.Dom.setStyle(yt.tipBox, 'display', 'none');
 
		}
 
		YUD.setAttribute(el,'title', yt._tooltip);
 
	}
 
}
 

	
 
/**
 
 * Quick filter widget
 
 * 
 
 * @param target: filter input target
 
 * @param nodes: list of nodes in html we want to filter.
rhodecode/templates/base/root.html
Show inline comments
 
@@ -127,12 +127,13 @@
 
                },args);
 
                return false;
 
            }
 
           YUE.onDOMReady(function(){
 
             tooltip_activate();
 
             show_more_event();
 
             show_changeset_tooltip();
 

	
 
             YUE.on('quick_login_link','click',function(e){
 
                 // make sure we don't redirect
 
                 YUE.preventDefault(e);
 

	
 
                 if(YUD.hasClass('quick_login_link','enabled')){
rhodecode/templates/followers/followers_data.html
Show inline comments
 
@@ -16,13 +16,17 @@
 
% endfor
 

	
 
<div class="pagination-wh pagination-left">
 
<script type="text/javascript">
 
YUE.onDOMReady(function(){
 
    YUE.delegate("followers","click",function(e, matchedEl, container){
 
        ypjax(e.target.href,"followers",function(){show_more_event();tooltip_activate();});
 
        ypjax(e.target.href,"followers",function(){
 
        	show_more_event();
 
        	tooltip_activate();
 
        	show_changeset_tooltip();	
 
        });
 
        YUE.preventDefault(e);
 
    },'.pager_link');
 
});
 
</script>
 
${c.followers_pager.pager('$link_previous ~2~ $link_next')}
 
</div>
rhodecode/templates/forks/forks_data.html
Show inline comments
 
@@ -24,13 +24,17 @@
 
	    </div>
 
	% endfor
 
  <div class="pagination-wh pagination-left">
 
  <script type="text/javascript">
 
  YUE.onDOMReady(function(){
 
      YUE.delegate("forks","click",function(e, matchedEl, container){
 
          ypjax(e.target.href,"forks",function(){show_more_event();tooltip_activate();});
 
          ypjax(e.target.href,"forks",function(){
 
        	  show_more_event();
 
        	  tooltip_activate();
 
        	  show_changeset_tooltip(); 
 
          });
 
          YUE.preventDefault(e);
 
      },'.pager_link');
 
  });
 
  </script>
 
  ${c.forks_pager.pager('$link_previous ~2~ $link_next')}
 
  </div>
rhodecode/templates/journal/journal.html
Show inline comments
 
@@ -150,13 +150,17 @@
 
        //We have a hash
 
        var tabHash = url[1];
 
        tabs[tabHash]();
 
    }    
 
    
 
    YUE.on('refresh','click',function(e){
 
        ypjax(e.currentTarget.href,"journal",function(){show_more_event();tooltip_activate();});
 
        ypjax(e.currentTarget.href,"journal",function(){
 
        	show_more_event();
 
        	tooltip_activate();
 
        	show_changeset_tooltip();
 
        	});
 
        YUE.preventDefault(e);
 
    });
 

	
 

	
 
    // main table sorting
 
    var myColumnDefs = [
rhodecode/templates/journal/journal_data.html
Show inline comments
 
@@ -32,13 +32,17 @@
 
    %endfor
 

	
 
  <div class="pagination-wh pagination-left">
 
    <script type="text/javascript">
 
    YUE.onDOMReady(function(){
 
        YUE.delegate("journal","click",function(e, matchedEl, container){
 
        	ypjax(e.target.href,"journal",function(){show_more_event();tooltip_activate();});
 
        	ypjax(e.target.href,"journal",function(){
 
        		show_more_event();
 
        		tooltip_activate();
 
        		show_changeset_tooltip();
 
        		});
 
            YUE.preventDefault(e);
 
        },'.pager_link');
 
    });
 
    </script>
 
  ${c.journal_pager.pager('$link_previous ~2~ $link_next')}
 
  </div>
rhodecode/templates/journal/public_journal.html
Show inline comments
 
@@ -25,19 +25,11 @@
 
     </li>
 
     <li>
 
       <span><a href="${h.url('public_journal_atom')}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
 
     </li>
 
     </ul>
 
  </div>
 
  <script type="text/javascript">
 
  function show_more_event(){
 
  YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
 
      var el = e.target;
 
      YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
 
      YUD.setStyle(el.parentNode,'display','none');
 
  });
 
  }
 
  </script>
 

	
 
  <div id="journal">${c.journal_data}</div>
 
</div>
 

	
 
</%def>
0 comments (0 inline, 0 general)