diff -r d3737b90a66b -r aff7eb118f7d client/js/paper-renderer.js --- a/client/js/paper-renderer.js Mon Aug 19 11:47:29 2013 +0200 +++ b/client/js/paper-renderer.js Thu Oct 03 19:22:28 2013 +0200 @@ -8,20 +8,31 @@ _ = Rkns._, $ = Rkns.$; +/* Rkns.Renderer Object */ + +/* This object contains constants, utility functions and classes for Renkan's Graph Manipulation GUI */ + var Renderer = Rkns.Renderer = {}, + /* The minimum distance (in pixels) the mouse has to move to consider an element was dragged */ _MIN_DRAG_DISTANCE = 2, + /* Distance between the inner and outer radius of buttons that appear when hovering on a node */ _NODE_BUTTON_WIDTH = 40, _EDGE_BUTTON_INNER = 2, _EDGE_BUTTON_OUTER = 40, + /* Constants used to know if a specific action is to be performed when clicking on the canvas */ _CLICKMODE_ADDNODE = 1, _CLICKMODE_STARTEDGE = 2, _CLICKMODE_ENDEDGE = 3, + /* Node size step: Used to calculate the size change when clicking the +/- buttons */ _NODE_SIZE_STEP = Math.LN2/4, _MIN_SCALE = 1/20, _MAX_SCALE = 20, _MOUSEMOVE_RATE = 80, _DOUBLETAP_DELAY = 800, + /* Maximum distance in pixels (squared, to reduce calculations) + * between two taps when double-tapping on a touch terminal */ _DOUBLETAP_DISTANCE = 20*20, + /* A placeholder so a default colour is displayed when a node has a null value for its user property */ _USER_PLACEHOLDER = function(_renkan) { return { color: _renkan.options.default_user_color, @@ -31,14 +42,20 @@ } }; }, + /* The code for the "Drag and Add Bookmarklet", slightly minified and with whitespaces removed, though + * it doesn't seem that it's still a requirement in newer browsers (i.e. the ones compatibles with canvas drawing) + */ _BOOKMARKLET_CODE = function(_renkan) { return "(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='" + _renkan.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_") + "

'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"; }, + /* Shortens text to the required length then adds ellipsis */ shortenText = function(_text, _maxlength) { return (_text.length > _maxlength ? (_text.substr(0,_maxlength) + '…') : _text); }, + /* Drawing an edit box with an arrow and positioning the edit box according to the position of the node/edge being edited + * Called by Rkns.Renderer.NodeEditor and Rkns.Renderer.EdgeEditor */ drawEditBox = function(_options, _coords, _path, _xmargin, _selector) { _selector.css({ width: ( _options.tooltip_width - 2* _options.tooltip_padding ), @@ -83,6 +100,12 @@ return _path; }; +/* Rkns.Renderer._BaseRepresentation Class */ + +/* In Renkan, a "Representation" is a sort of ViewModel (in the MVVM paradigm) and bridges the gap between + * models (written with Backbone.js) and the view (written with Paper.js) + * Renkan's representations all inherit from Rkns.Renderer._BaseRepresentation '*/ + var _BaseRepresentation = Renderer._BaseRepresentation = function(_renderer, _model) { if (typeof _renderer !== "undefined") { this.renderer = _renderer; @@ -115,6 +138,8 @@ } }; +/* Rkns.Renderer._BaseRepresentation Methods */ + _(_BaseRepresentation.prototype).extend({ _super: function(_func) { return _BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1)); @@ -151,7 +176,11 @@ } }); -/* */ +/* End of Rkns.Renderer._BaseRepresentation Class */ + +/* Rkns.Renderer._BaseButton Class */ + +/* BaseButton is extended by contextual buttons that appear when hovering on nodes and edges */ var _BaseButton = Renderer._BaseButton = Rkns.Utils.inherit(_BaseRepresentation); @@ -179,7 +208,13 @@ } }); -/* */ +/* End of Rkns.Renderer._BaseButton Class */ + +/* Rkns.Renderer.Node Class */ + +/* The representation for the node : A circle, with an image inside and a text label underneath. + * The circle and the image are drawn on canvas and managed by Paper.js. + * The text label is an HTML node, managed by jQuery. */ var NodeRepr = Renderer.Node = Rkns.Utils.inherit(_BaseRepresentation); @@ -385,7 +420,7 @@ }); lastCoords = newCoords.slice(-2); return newCoords; - } + }; instructions.forEach(function(instr) { var coords = instr.match(/([a-z]|[0-9.-]+)/ig) || [""]; @@ -1086,7 +1121,7 @@ } else { closeEditor(); } - } + }; this.editor_$.find(".Rk-Edit-Size-Down").click(function() { shiftSize(-1); @@ -1101,7 +1136,7 @@ var titlehtml = this.source_representation.highlighted.replace(_(_model.get("title")).escape(),'$1'); this.editor_$.find(".Rk-Display-Title" + (_model.get("uri") ? " a" : "")).html(titlehtml); if (this.options.show_node_tooltip_description) { - this.editor_$.find(".Rk-Display-Description").html(this.source_representation.highlighted.replace(_(_model.get("description")).escape(),'$1')) + this.editor_$.find(".Rk-Display-Description").html(this.source_representation.highlighted.replace(_(_model.get("description")).escape(),'$1')); } } } @@ -1748,7 +1783,7 @@ _this[fname](evt); return false; }); - } + }; bindClick(".Rk-ZoomOut", "zoomOut"); bindClick(".Rk-ZoomIn", "zoomIn");