change.text = change.text.join("\n");
}
session.send({
type: "form-update",
tracker: this.trackerName,
element: elementFinder.elementLocation(this.element),
change: change
});
if (next) {
this._change(editor, next);
}
},
_editor: function () {
return this.element[0].CodeMirror;
}
});
CodeMirrorEditor.scan = function () {
var result = [];
var els = document.body.getElementsByTagName("*");
var _len = els.length;
for (var i=0; i<_len; i++) {
var el = els[i];
if (el.CodeMirror) {
result.push(el);
}
}
return $(result);
};
CodeMirrorEditor.tracked = function (el) {
el = $(el)[0];
while (el) {
if (el.CodeMirror) {
return true;
}
el = el.parentNode;
}
return false;
};
TogetherJS.addTracker(CodeMirrorEditor, true );
function buildTrackers() {
assert(! liveTrackers.length);
util.forEachAttr(editTrackers, function (TrackerClass) {
var els = TrackerClass.scan();
$.each(els, function () {
liveTrackers.push(new TrackerClass(this));
});
});
}
function destroyTrackers() {
liveTrackers.forEach(function (tracker) {
tracker.destroy();
});
liveTrackers = [];
}
function elementTracked(el) {
var result = false;
util.forEachAttr(editTrackers, function (TrackerClass) {
if (TrackerClass.tracked(el)) {
result = true;
}
});
return result;
}
function getTracker(el, name) {
el = $(el)[0];
for (var i=0; i<liveTrackers.length; i++) {
var tracker = liveTrackers[i];
if (tracker.tracked(el)) {
assert((! name) || name == tracker.trackerName, "Expected to map to a tracker type", name, "but got", tracker.trackerName);
return tracker;
}
}
return null;
}
var TEXT_TYPES = (
"color date datetime datetime-local email " +
"tel text time week").split(/ /g);
function isText(el) {
el = $(el);
var tag = el.prop("tagName");
var type = (el.prop("type") || "text").toLowerCase();
if (tag == "TEXTAREA") {
return true;
}
if (tag == "INPUT" && TEXT_TYPES.indexOf(type) != -1) {
return true;
}
return false;
}
function getValue(el) {
el = $(el);
if (isCheckable(el)) {
return el.prop("checked");
} else {
return el.val();
}
}
function setValue(el, value) {
el = $(el);
if (isCheckable(el)) {
el.prop("checked", value);
} else {
el.val(value);
}
eventMaker.fireChange(el);
}
function maybeSendUpdate(element, history) {
var change = history.getNextToSend();
if (! change) {
return;
}
var msg = {
type: "form-update",
element: element,
"server-echo": true,
replace: {
id: change.id,
basis: change.basis,
delta: {
start: change.delta.start,
del: change.delta.del,
text: change.delta.text
}
}
};
session.send(msg);
}
session.hub.on("form-update", function (msg) {
if (! msg.sameUrl) {
return;
}
var el = $(elementFinder.findElement(msg.element));
if (msg.tracker) {
var tracker = getTracker(el, msg.tracker);
assert(tracker);
inRemoteUpdate = true;
try {
tracker.update(msg);
} finally {
inRemoteUpdate = false;
}
return;
}
var text = isText(el);
var selection;
if (text) {
selection = [el[0].selectionStart, el[0].selectionEnd];
}
var value;
if (msg.replace) {
var history = el.data("togetherjsHistory");
if (!history) {
console.warn("form update received for uninitialized form element");
return;
}
history.setSelection(selection);