Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions site/examples/acecursors/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>ACE in Action</title>
<style type="text/css" media="screen">
*{
margin: 0;
padding: 0;
}
#editor {
width:600px;
height:700px;
}
</style>
</head>
<body>

<div id="editor">function foo(items) {
var x = "All this is syntax highlighted";
return x;
}</div>

<button id="start-togetherjs" type="button"
onclick="TogetherJS(this); return false"
data-end-togetherjs-html="End TogetherJS">
Start TogetherJS
</button>


<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js" type="text/javascript" charset="utf-8"></script>

<script>
// TogetherJS configuration would go here, but we'll talk about that
// later
TogetherJSConfig_hubBase = "http://127.0.0.1:8080";
TogetherJSConfig_dontShowClicks = '#editor'

</script>
<script src="/togetherjs/build/togetherjs-min.js"></script>
<script>
var editor = ace.edit("editor");
var session = editor.getSession()
editor.setTheme("ace/theme/monokai");
session.setMode("ace/mode/javascript");
</script>
</body>
</html>
80 changes: 77 additions & 3 deletions togetherjs/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

define(["jquery", "util", "session", "elementFinder", "eventMaker", "templating", "ot"], function ($, util, session, elementFinder, eventMaker, templating, ot) {
define(["jquery", "util", "session", "elementFinder", "eventMaker", "templating", "ot", "peers"], function ($, util, session, elementFinder, eventMaker, templating, ot, peers) {
var forms = util.Module("forms");
var assert = util.assert;

Expand Down Expand Up @@ -101,8 +101,14 @@ define(["jquery", "util", "session", "elementFinder", "eventMaker", "templating"
constructor: function (el) {
this.element = $(el);
assert(this.element.hasClass("ace_editor"));
this.cursorMarkers= {};
this._change = this._change.bind(this);
this._changeCursor = this._changeCursor.bind(this);
this._editor().document.on("change", this._change);
this._editor().document.getSelection().on("changeCursor", this._changeCursor);
this.peerUpdate = this.peerUpdate.bind(this);

peers.on("new-peer identity-updated status-updated", this.peerUpdate);
},

tracked: function (el) {
Expand All @@ -111,14 +117,65 @@ define(["jquery", "util", "session", "elementFinder", "eventMaker", "templating"

destroy: function (el) {
this._editor().document.removeListener("change", this._change);
this._editor()
.document
.getSelection()
.removeListener("change", this._changeCursor);
},

update: function (msg) {
if (msg.value) {
this.init(msg);
return;
}
this._editor().document.getDocument().applyDeltas([msg.delta]);

if(msg.hasOwnProperty('delta')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a space after if here and below

this._editor().document.getDocument().applyDeltas([msg.delta]);
}

if(msg.hasOwnProperty('cursor')) {
this.updateCursorMarker(msg);
}
},

peerUpdate: function (peer) {
if( this.cursorMarkers.hasOwnProperty(peer.id)) {
var msg = {
peer: peer,
cursor: this.cursorMarkers[peer.id].cursor
};
this.updateCursorMarker(msg);
}
},

updateCursorMarker: function (msg) {
if ("undefined" == typeof msg) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just do if (msg === undefined) here

return;
}

if( this.cursorMarkers.hasOwnProperty(msg.peer.id)) {
this._editor()
.document
.removeMarker(this.cursorMarkers[msg.peer.id].markerId);
}

var Range = ace.require('ace/range').Range;
var range = new Range(msg.cursor.row, msg.cursor.column,
msg.cursor.row, msg.cursor.column + 1);

var markerId = this._editor()
.document
.addMarker(range, "ace_selection", drawMarker, false);

this.cursorMarkers[msg.clientId] = {
markerId:markerId,
cursor:msg.cursor
};

function drawMarker(stringBuilder, range, left, top, config) {
var color = "background-color:"+ msg.peer.color;
stringBuilder.push("<div class='ace_selection' style='", "left:", left, "px;", "top:", top + 2, "px;", "height:", config.lineHeight - 2, "px;", "width:", 2, "px;", color || "", "'></div>", "<div class='ace_selection' style='", "left:", left - 2, "px;", "top:", top, "px;", "height:", 5, "px;", "width:", 6, "px;", color || "", "'></div>");
}
},

init: function (update, msg) {
Expand Down Expand Up @@ -149,7 +206,24 @@ define(["jquery", "util", "session", "elementFinder", "eventMaker", "templating"
type: "form-update",
tracker: this.trackerName,
element: elementFinder.elementLocation(this.element),
delta: JSON.parse(JSON.stringify(e.data))
delta: JSON.parse(JSON.stringify(e.data)),
cursor: this._editor().document.getSelection().getCursor()
});
},

_changeCursor: function (e) {
// FIXME: I should have an internal .send() function that automatically
// asserts !inRemoteUpdate, among other things
if (inRemoteUpdate) {
return;
}
// FIXME: I want to use a more normalized version of replace instead of
// ACE's native delta
session.send({
type: "form-update",
tracker: this.trackerName,
element: elementFinder.elementLocation(this.element),
cursor: this._editor().document.getSelection().getCursor()
});
}
});
Expand Down
2 changes: 1 addition & 1 deletion togetherjs/youtubeVideos.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function ($, util, session, elementFinder) {
// if the iframe's unique id is already set, skip it
if (($(iframe).attr("src") || "").indexOf("youtube") != -1 && !$(iframe).attr("id")) {
$(iframe).attr("id", "youtube-player"+i);
$(iframe).attr("ensablejsapi", 1);
$(iframe).attr("enablejsapi", 1);
youTubeIframes[i] = iframe;
}
});
Expand Down