--- a/client/css/renkan.css Fri Apr 12 19:10:40 2013 +0200
+++ b/client/css/renkan.css Mon Apr 15 18:36:59 2013 +0200
@@ -526,7 +526,7 @@
cursor: move;
}
-.Rk-Bin-Item:hover {
+.Rk-Bin-Item:hover, .Rk-Bin-Item.hover {
background: -moz-linear-gradient(top, rgba(0,0,0,.1) 20%, rgba(128,128,128,.1) 80%);
background: -webkit-linear-gradient(top, rgba(0,0,0,.1) 20%, rgba(128,128,128,.1) 80%);
background: -ms-linear-gradient(top, rgba(0,0,0,.1) 20%, rgba(128,128,128,.1) 80%);
--- a/client/js/defaults.js Fri Apr 12 19:10:40 2013 +0200
+++ b/client/js/defaults.js Mon Apr 15 18:36:59 2013 +0200
@@ -23,6 +23,8 @@
show_top_bar: true,
/* Show the top bar, (title, buttons, users) */
default_user_color: "#303030",
+ size_bug_fix: true,
+ /* Resize the canvas after load (fixes a bug on iPad and FF Mac) */
/* MINI-MAP OPTIONS */
--- a/client/js/main.js Fri Apr 12 19:10:40 2013 +0200
+++ b/client/js/main.js Mon Apr 15 18:36:59 2013 +0200
@@ -183,6 +183,8 @@
}
});
+ var elementDropped = false;
+
this.$.find(".Rk-Bins")
.on("click",".Rk-Bin-Title,.Rk-Bin-Title-Icon", function() {
var _mainDiv = Rkns.$(this).siblings(".Rk-Bin-Main");
@@ -207,6 +209,30 @@
this.dragDrop();
}
catch(err) {}
+ }).on("touchstart", ".Rk-Bin-Item", function(e) {
+ elementDropped = false;
+ }).on("touchmove", ".Rk-Bin-Item", function(e) {
+ e.preventDefault();
+ var touch = e.originalEvent.changedTouches[0],
+ off = _this.renderer.canvas_$.offset(),
+ w = _this.renderer.canvas_$.width(),
+ h = _this.renderer.canvas_$.height();
+ if (touch.pageX >= off.left && touch.pageX < (off.left + w) && touch.pageY >= off.top && touch.pageY < (off.top + h)) {
+ if (elementDropped) {
+ _this.renderer.onMouseMove(touch, true);
+ } else {
+ elementDropped = true;
+ var div = document.createElement('div');
+ div.appendChild(this.cloneNode(true));
+ _this.renderer.dropData({"text/html": div.innerHTML}, touch);
+ _this.renderer.onMouseDown(touch, true);
+ }
+ }
+ }).on("touchend", ".Rk-Bin-Item", function(e) {
+ if (elementDropped) {
+ _this.renderer.onMouseUp(e.originalEvent.changedTouches[0], true);
+ }
+ elementDropped = false;
}).on("dragstart", ".Rk-Bin-Item", function(e) {
var div = document.createElement('div');
div.appendChild(this.cloneNode(true));
--- a/client/js/paper-renderer.js Fri Apr 12 19:10:40 2013 +0200
+++ b/client/js/paper-renderer.js Mon Apr 15 18:36:59 2013 +0200
@@ -222,6 +222,8 @@
Rkns.Renderer._BaseRepresentation.prototype.unhighlight = function() {}
+Rkns.Renderer._BaseRepresentation.prototype.mousedown = function() {}
+
Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {}
Rkns.Renderer._BaseRepresentation.prototype.destroy = function() {
@@ -507,14 +509,17 @@
}
}
+Rkns.Renderer.Node.prototype.mousedown = function(_event, _isTouch) {
+ if (_isTouch) {
+ this.toggleSelect();
+ }
+}
+
Rkns.Renderer.Node.prototype.mouseup = function(_event, _isTouch) {
if (this.renderer.isEditable() && this.renderer.is_dragging) {
this.saveCoords();
} else {
- if (_isTouch) {
- this.toggleSelect();
- paper.view.draw();
- } else {
+ if (!_isTouch) {
this.openEditor();
}
}
@@ -679,22 +684,23 @@
}
}
+Rkns.Renderer.Edge.prototype.mousedown = function(_event, _isTouch) {
+ if (_isTouch) {
+ this.toggleSelect();
+ }
+}
+
Rkns.Renderer.Edge.prototype.mouseup = function(_event, _isTouch) {
- if (!this.renkan.read_only) {
- if (this.renderer.is_dragging) {
- this.from_representation.saveCoords();
- this.to_representation.saveCoords();
- this.from_representation.is_dragging = false;
- this.to_representation.is_dragging = false;
- } else {
- if (_isTouch) {
- this.toggleSelect();
- paper.view.draw();
- } else {
- this.openEditor();
- }
+ if (!this.renkan.read_only && this.renderer.is_dragging) {
+ this.from_representation.saveCoords();
+ this.to_representation.saveCoords();
+ this.from_representation.is_dragging = false;
+ this.to_representation.is_dragging = false;
+ } else {
+ if (!_isTouch) {
+ this.openEditor();
}
- }
+ }
this.renderer.click_target = null;
this.renderer.is_dragging = false;
}
@@ -1234,6 +1240,19 @@
this.text = "Link to another node";
}
+Rkns.Renderer.NodeLinkButton.prototype.mousedown = function(_event, _isTouch) {
+ if (this.renderer.isEditable()) {
+ var _off = this.renderer.canvas_$.offset(),
+ _point = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]);
+ this.renderer.click_target = null;
+ this.renderer.removeRepresentationsOfType("editor");
+ this.renderer.addTempEdge(this.source_representation, _point);
+ }
+}
+
/* */
Rkns.Renderer.NodeEnlargeButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
@@ -1301,6 +1320,8 @@
}
Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
+ this.renderer.click_target = null;
+ this.renderer.is_dragging = false;
this.renderer.removeRepresentationsOfType("editor");
if (this.renderer.isEditable() && confirm(this.renkan.translate('Do you really wish to remove edge ') + '"' + this.source_representation.model.get("title") + '"?')) {
this.project.removeEdge(this.source_representation.model);
@@ -1332,10 +1353,6 @@
this.canvas_$ = this.$.find(".Rk-Canvas");
this.editor_$ = this.$.find(".Rk-Editor");
this.notif_$ = this.$.find(".Rk-Notifications");
- this.canvas_$.attr({
- width: this.canvas_$.width(),
- height: this.canvas_$.height()
- })
paper.setup(this.canvas_$[0]);
this.scale = 1;
this.offset = paper.view.center;
@@ -1413,7 +1430,8 @@
},
touchmove: function(_event) {
_event.preventDefault();
- if (_event.originalEvent.scale == 1) {
+ if (typeof _event.originalEvent.scale === "undefined" || _event.originalEvent.scale == 1) {
+ // On Android, scale is undefined, so no zooming..
_this.onMouseMove(_event.originalEvent.changedTouches[0], true);
} else {
if (!_zooming) {
@@ -1422,8 +1440,12 @@
_this.is_dragging = false;
_zooming = true;
}
- var _newScale = _event.originalEvent.scale * _originalScale;
- //TODO: Correct Offset !
+ var _newScale = _event.originalEvent.scale * _originalScale,
+ _scaleRatio = _newScale / _this.scale,
+ _newOffset = new paper.Point([
+ _this.canvas_$.width(),
+ _this.canvas_$.height()
+ ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));
_this.setScale(_newScale, _this.offset);
}
},
@@ -1450,145 +1472,47 @@
_allowScroll = true;
_event.preventDefault();
},
- drop: function(_event) {
- _event.preventDefault();
- _allowScroll = true;
- if (!_this.isEditable()) {
- return;
- }
- var res = {};
- Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
- try {
- res[t] = _event.originalEvent.dataTransfer.getData(t);
- } catch(e) {}
- });
- var text = _event.originalEvent.dataTransfer.getData("Text");
- if (typeof text === "string") {
- switch(text[0]) {
- case "{":
- case "[":
- try {
- var data = JSON.parse(text);
- _(res).extend(data);
- }
- catch(e) {
- if (!res["text/plain"]) {
- res["text/plain"] = text;
- }
- }
- break;
- case "<":
- if (!res["text/html"]) {
- res["text/html"] = text;
- }
- break;
- default:
- if (!res["text/plain"]) {
- res["text/plain"] = text;
- }
- }
- }
- var url = _event.originalEvent.dataTransfer.getData("URL");
- if (url && !res["text/uri-list"]) {
- res["text/uri-list"] = url;
- }
- if (res["text/json"] || res["application/json"]) {
- try {
- var data = JSON.parse(res["text/json"] || res["application/json"]);
- _(res).extend(data);
+ drop: function(_event) {
+ _event.preventDefault();
+ _allowScroll = true;
+ var res = {};
+ Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
+ try {
+ res[t] = _event.originalEvent.dataTransfer.getData(t);
+ } catch(e) {}
+ });
+ var text = _event.originalEvent.dataTransfer.getData("Text");
+ if (typeof text === "string") {
+ switch(text[0]) {
+ case "{":
+ case "[":
+ try {
+ var data = JSON.parse(text);
+ _(res).extend(data);
+ }
+ catch(e) {
+ if (!res["text/plain"]) {
+ res["text/plain"] = text;
+ }
+ }
+ break;
+ case "<":
+ if (!res["text/html"]) {
+ res["text/html"] = text;
+ }
+ break;
+ default:
+ if (!res["text/plain"]) {
+ res["text/plain"] = text;
+ }
+ }
}
- catch(e) {}
- }
- var newNode = {};
- switch(res["text/x-iri-specific-site"]) {
- case "twitter":
- var snippet = Rkns.$('<div>').html(res["text/x-iri-selected-html"]),
- tweetdiv = snippet.find(".tweet")
- newNode.title = _renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
- newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
- newNode.image = tweetdiv.find(".avatar").attr("src");
- newNode.description = tweetdiv.find(".js-tweet-text:first").text();
- break;
- case "google":
- var snippet = Rkns.$('<div>').html(res["text/x-iri-selected-html"]);
- newNode.title = snippet.find("h3:first").text().trim();
- newNode.uri = snippet.find("h3 a").attr("href");
- newNode.description = snippet.find(".st:first").text().trim();
- break;
- case undefined:
- default:
- if (res["text/x-iri-source-uri"]) {
- newNode.uri = res["text/x-iri-source-uri"];
- }
- if (res["text/plain"] || res["text/x-iri-selected-text"]) {
- newNode.description = (res["text/plain"] || res["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
- }
- if (res["text/html"] || res["text/x-iri-selected-html"]) {
- var snippet = Rkns.$('<div>').html(res["text/html"] || res["text/x-iri-selected-html"]);
- var _imgs = snippet.find("img");
- if (_imgs.length) {
- newNode.image = _imgs[0].src;
- }
- var _as = snippet.find("a");
- if (_as.length) {
- newNode.uri = _as[0].href;
- }
- newNode.title = snippet.find("[title]").attr("title") || newNode.title;
- newNode.description = snippet.text().replace(/[\s\n]+/gm,' ').trim();
- }
- if (res["text/uri-list"]) {
- newNode.uri = res["text/uri-list"];
- }
- if (res["text/x-moz-url"] && !newNode.title) {
- newNode.title = (res["text/x-moz-url"].split("\n")[1] || "").trim();
- if (newNode.title === newNode.uri) {
- newNode.title = false;
- }
- }
- if (res["text/x-iri-source-title"] && !newNode.title) {
- newNode.title = res["text/x-iri-source-title"];
- }
- if (res["text/html"] || res["text/x-iri-selected-html"]) {
- newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
- newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
- newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
- newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
- }
- }
- var fields = ["title", "description", "uri", "image"];
- for (var i = 0; i < fields.length; i++) {
- var f = fields[i];
- if (res["text/x-iri-" + f] || res[f]) {
- newNode[f] = res["text/x-iri-" + f] || res[f];
- }
- if (newNode[f] === "none" || newNode[f] === "null") {
- newNode[f] = undefined;
- }
- }
- if (newNode.title || newNode.description || newNode.uri) {
- var _off = _this.canvas_$.offset(),
- _point = new paper.Point([
- _event.originalEvent.pageX - _off.left,
- _event.originalEvent.pageY - _off.top
- ]),
- _coords = _this.toModelCoords(_point),
- _data = {
- id: Rkns.Utils.getUID('node'),
- created_by: _this.renkan.current_user,
- uri: newNode.uri || "",
- title: newNode.title || _this.renkan.translate("Dragged resource"),
- description: newNode.description || "",
- image: newNode.image || "",
- color: newNode.color || undefined,
- position: {
- x: _coords.x,
- y: _coords.y
- }
- };
- var _node = _this.renkan.project.addNode(_data);
- _this.getRepresentationByModel(_node).openEditor();
- }
- }
+ var url = _event.originalEvent.dataTransfer.getData("URL");
+ if (url && !res["text/uri-list"]) {
+ res["text/uri-list"] = url;
+ }
+ _this.dropData(res, _event.originalEvent);
+ }
});
this.editor_$.find(".Rk-ZoomOut").click(function() {
var _newScale = _this.scale * Math.SQRT1_2,
@@ -1725,7 +1649,7 @@
_thRedraw();
});
this.renkan.project.on("change:title", function(_model, _title) {
- var el = $(".Rk-PadTitle");
+ var el = _this.$.find(".Rk-PadTitle");
if (el.is("input")) {
if (el.val() !== _title) {
el.val(_title);
@@ -1735,6 +1659,26 @@
}
});
+ if (_renkan.options.size_bug_fix) {
+ window.setTimeout(
+ function() {
+ var w = _this.$.width(),
+ h = _this.$.height();
+ if (_renkan.options.show_top_bar) {
+ h -= _this.$.find(".Rk-TopBar").height();
+ }
+ _this.canvas_$.attr({
+ width: w,
+ height: h
+ });
+
+ paper.view.viewSize = new paper.Size([w, h]);
+ _this.autoScale();
+ },
+ 500
+ );
+ }
+
this.redraw();
if (this.minimap) {
@@ -1756,8 +1700,8 @@
+ '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div>'
+ '<div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents">'
+ '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a>'
- + '<div class="Rk-TopBar-Separator"></div></div>'
- + '<% } } %>'
+ + '<div class="Rk-TopBar-Separator"></div>'
+ + '<% } %></div><% } %>'
+ '<div class="Rk-Editing-Space<% if (!options.show_top_bar) { %> Rk-Editing-Space-Full<% } %>"><canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
+ '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">«</div><% } %>'
+ '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div></div>'
@@ -2002,8 +1946,8 @@
_point = new paper.Point([
_event.pageX - _off.left,
_event.pageY - _off.top
- ]);
- var _delta = _point.subtract(this.last_point);
+ ]),
+ _delta = _point.subtract(this.last_point);
this.last_point = _point;
if (!this.is_dragging && this.mouse_down && _delta.length > Rkns.Renderer._MIN_DRAG_DISTANCE) {
this.is_dragging = true;
@@ -2033,12 +1977,9 @@
this.removeRepresentationsOfType("editor");
this.is_dragging = false;
var _hitResult = paper.project.hitTest(_point);
- if (this.isEditable() && _hitResult && typeof _hitResult.item.__representation !== "undefined") {
+ if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
this.click_target = _hitResult.item.__representation;
- if (this.click_target.type === "Node-link-button") {
- this.removeRepresentationsOfType("editor");
- this.addTempEdge(this.click_target.source_representation, _point);
- }
+ this.click_target.mousedown(_event, _isTouch);
} else {
this.click_target = null;
if (this.isEditable() && this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
@@ -2069,6 +2010,7 @@
this.click_mode = false;
}
}
+ paper.view.draw();
}
Rkns.Renderer.Scene.prototype.onMouseUp = function(_event, _isTouch) {
@@ -2089,9 +2031,9 @@
this.is_dragging = false;
if (_isTouch) {
this.unselectAll();
- paper.view.draw();
}
}
+ paper.view.draw();
}
Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
@@ -2136,3 +2078,108 @@
}
paper.view.draw();
}
+
+Rkns.Renderer.Scene.prototype.dropData = function(_data, _event) {
+ if (!this.isEditable()) {
+ return;
+ }
+ if (_data["text/json"] || _data["application/json"]) {
+ try {
+ var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]);
+ _(_data).extend(jsondata);
+ }
+ catch(e) {}
+ }
+ var newNode = {};
+ switch(_data["text/x-iri-specific-site"]) {
+ case "twitter":
+ var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]),
+ tweetdiv = snippet.find(".tweet")
+ newNode.title = _renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
+ newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
+ newNode.image = tweetdiv.find(".avatar").attr("src");
+ newNode.description = tweetdiv.find(".js-tweet-text:first").text();
+ break;
+ case "google":
+ var snippet = Rkns.$('<div>').html(_data["text/x-iri-selected-html"]);
+ newNode.title = snippet.find("h3:first").text().trim();
+ newNode.uri = snippet.find("h3 a").attr("href");
+ newNode.description = snippet.find(".st:first").text().trim();
+ break;
+ case undefined:
+ default:
+ if (_data["text/x-iri-source-uri"]) {
+ newNode.uri = _data["text/x-iri-source-uri"];
+ }
+ if (_data["text/plain"] || _data["text/x-iri-selected-text"]) {
+ newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
+ }
+ if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
+ var snippet = Rkns.$('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
+ var _imgs = snippet.find("img");
+ if (_imgs.length) {
+ newNode.image = _imgs[0].src;
+ }
+ var _as = snippet.find("a");
+ if (_as.length) {
+ newNode.uri = _as[0].href;
+ }
+ newNode.title = snippet.find("[title]").attr("title") || newNode.title;
+ newNode.description = snippet.text().replace(/[\s\n]+/gm,' ').trim();
+ }
+ if (_data["text/uri-list"]) {
+ newNode.uri = _data["text/uri-list"];
+ }
+ if (_data["text/x-moz-url"] && !newNode.title) {
+ newNode.title = (_data["text/x-moz-url"].split("\n")[1] || "").trim();
+ if (newNode.title === newNode.uri) {
+ newNode.title = false;
+ }
+ }
+ if (_data["text/x-iri-source-title"] && !newNode.title) {
+ newNode.title = _data["text/x-iri-source-title"];
+ }
+ if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
+ newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
+ newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
+ newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
+ newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
+ }
+ }
+ var fields = ["title", "description", "uri", "image"];
+ for (var i = 0; i < fields.length; i++) {
+ var f = fields[i];
+ if (_data["text/x-iri-" + f] || _data[f]) {
+ newNode[f] = _data["text/x-iri-" + f] || _data[f];
+ }
+ if (newNode[f] === "none" || newNode[f] === "null") {
+ newNode[f] = undefined;
+ }
+ }
+ if (newNode.title || newNode.description || newNode.uri) {
+ var _off = this.canvas_$.offset(),
+ _point = new paper.Point([
+ _event.pageX - _off.left,
+ _event.pageY - _off.top
+ ]),
+ _coords = this.toModelCoords(_point),
+ _nodedata = {
+ id: Rkns.Utils.getUID('node'),
+ created_by: this.renkan.current_user,
+ uri: newNode.uri || "",
+ title: newNode.title || this.renkan.translate("Dragged resource"),
+ description: newNode.description || "",
+ image: newNode.image || "",
+ color: newNode.color || undefined,
+ position: {
+ x: _coords.x,
+ y: _coords.y
+ }
+ };
+ var _node = this.renkan.project.addNode(_nodedata),
+ _repr = this.getRepresentationByModel(_node);
+ if (_event.type === "drop") {
+ _repr.openEditor();
+ }
+ }
+}