Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/node_modules
.tern-port
/dist/*
/notes.txt
/demo/*-built.js
webpack.config.js
webpack.config.js
110 changes: 110 additions & 0 deletions dist/collab/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var _edit = require("../edit");

var _rebase = require("./rebase");

exports.rebaseSteps = _rebase.rebaseSteps;

(0, _edit.defineOption)("collab", false, function (pm, value) {
if (pm.mod.collab) {
pm.mod.collab.detach();
pm.mod.collab = null;
}

if (value) {
pm.mod.collab = new Collab(pm, value);
}
});

var Collab = (function () {
function Collab(pm, options) {
var _this = this;

_classCallCheck(this, Collab);

this.pm = pm;
this.options = options;

this.version = options.version || 0;
this.versionDoc = pm.doc;

this.unconfirmedSteps = [];
this.unconfirmedMaps = [];

pm.on("transform", this.onTransform = function (transform) {
for (var i = 0; i < transform.steps.length; i++) {
_this.unconfirmedSteps.push(transform.steps[i]);
_this.unconfirmedMaps.push(transform.maps[i]);
}
_this.signal("mustSend");
});
pm.on("beforeSetDoc", this.onSetDoc = function () {
throw new Error("setDoc is not supported on a collaborative editor");
});
pm.history.allowCollapsing = false;
}

_createClass(Collab, [{
key: "detach",
value: function detach() {
this.pm.off("transform", this.onTransform);
this.pm.off("beforeSetDoc", this.onSetDoc);
this.pm.history.allowCollapsing = true;
}
}, {
key: "hasSendableSteps",
value: function hasSendableSteps() {
return this.unconfirmedSteps.length > 0;
}
}, {
key: "sendableSteps",
value: function sendableSteps() {
return {
version: this.version,
doc: this.pm.doc,
steps: this.unconfirmedSteps.slice()
};
}
}, {
key: "confirmSteps",
value: function confirmSteps(sendable) {
this.unconfirmedSteps.splice(0, sendable.steps.length);
this.unconfirmedMaps.splice(0, sendable.steps.length);
this.version += sendable.steps.length;
this.versionDoc = sendable.doc;
}
}, {
key: "receive",
value: function receive(steps) {
var doc = this.versionDoc;
var maps = steps.map(function (step) {
var result = step.apply(doc);
doc = result.doc;
return result.map;
});
this.version += steps.length;
this.versionDoc = doc;

var rebased = (0, _rebase.rebaseSteps)(doc, maps, this.unconfirmedSteps, this.unconfirmedMaps);
this.unconfirmedSteps = rebased.transform.steps.slice();
this.unconfirmedMaps = rebased.transform.maps.slice();

this.pm.updateDoc(rebased.doc, rebased.mapping);
this.pm.history.rebased(maps, rebased.transform, rebased.positions);
return maps;
}
}]);

return Collab;
})();

(0, _edit.eventMixin)(Collab);
27 changes: 27 additions & 0 deletions dist/collab/rebase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.rebaseSteps = rebaseSteps;

var _transform = require("../transform");

function rebaseSteps(doc, forward, steps, maps) {
var remap = new _transform.Remapping([], forward.slice());
var transform = new _transform.Transform(doc);
var positions = [];

for (var i = 0; i < steps.length; i++) {
var step = (0, _transform.mapStep)(steps[i], remap);
var result = step && transform.step(step);
var id = remap.addToFront(maps[i].invert());
if (result) {
remap.addToBack(result.map, id);
positions.push(transform.steps.length - 1);
} else {
positions.push(-1);
}
}
return { doc: transform.doc, transform: transform, mapping: remap, positions: positions };
}
85 changes: 85 additions & 0 deletions dist/dom/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.elt = elt;
exports.requestAnimationFrame = requestAnimationFrame;
exports.rmClass = rmClass;
exports.addClass = addClass;
exports.contains = contains;
exports.insertCSS = insertCSS;

function elt(tag, attrs) {
var result = document.createElement(tag);
if (attrs) for (var _name in attrs) {
if (_name == "style") result.style.cssText = attrs[_name];else if (attrs[_name] != null) result.setAttribute(_name, attrs[_name]);
}

for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}

for (var i = 0; i < args.length; i++) {
add(args[i], result);
}return result;
}

function add(value, target) {
if (typeof value == "string") value = document.createTextNode(value);
if (Array.isArray(value)) {
for (var i = 0; i < value.length; i++) {
add(value[i], target);
}
} else {
target.appendChild(value);
}
}

var reqFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

function requestAnimationFrame(f) {
if (reqFrame) reqFrame(f);else setTimeout(f, 10);
}

var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);

var browser = {
mac: /Mac/.test(navigator.platform),
ie_upto10: ie_upto10,
ie_11up: ie_11up,
ie: ie_upto10 || ie_11up,
gecko: /gecko\/\d/i.test(navigator.userAgent)
};

exports.browser = browser;
function classTest(cls) {
return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*");
}

function rmClass(node, cls) {
var current = node.className;
var match = classTest(cls).exec(current);
if (match) {
var after = current.slice(match.index + match[0].length);
node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
}
}

function addClass(node, cls) {
var current = node.className;
if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls;
}

function contains(parent, child) {
// Android browser and IE will return false if child is a text node.
if (child.nodeType != 1) child = child.parentNode;
return child && parent.contains(child);
}

function insertCSS(css) {
var style = document.createElement("style");
style.textContent = css;
document.head.insertBefore(style, document.head.firstChild);
}
62 changes: 62 additions & 0 deletions dist/edit/capturekeys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});

var _selection = require("./selection");

var _dom = require("../dom");

var _keys = require("./keys");

function nothing() {}

function ensureSelection(pm) {
if (pm.selection.node) {
var found = (0, _selection.findSelectionNear)(pm.doc, pm.selection.from, 1, true);
if (found) (0, _selection.setDOMSelectionToPos)(pm, found.head);
}
return false;
}

// A backdrop keymap used to make sure we always suppress keys that
// have a dangerous default effect, even if the commands they are
// bound to return false, and to make sure that cursor-motion keys
// find a cursor (as opposed to a node selection) when pressed.

var keys = {
"Enter": nothing,
"Mod-Enter": nothing,
"Shift-Enter": nothing,
"Backspace": nothing,
"Delete": nothing,
"Mod-B": nothing,
"Mod-I": nothing,
"Mod-Backspace": nothing,
"Mod-Delete": nothing,
"Shift-Backspace": nothing,
"Shift-Delete": nothing,
"Shift-Mod-Backspace": nothing,
"Shift-Mod-Delete": nothing,
"Mod-Z": nothing,
"Mod-Y": nothing,
"Shift-Mod-Z": nothing,
"Ctrl-D": nothing,
"Ctrl-H": nothing,
"Ctrl-Alt-Backspace": nothing,
"Alt-D": nothing,
"Alt-Delete": nothing,
"Alt-Backspace": nothing,

"Mod-A": ensureSelection
};["Left", "Right", "Up", "Down", "Home", "End", "PageUp", "PageDown"].forEach(function (key) {
keys[key] = keys["Shift-" + key] = keys["Mod-" + key] = keys["Shift-Mod-" + key] = keys["Alt-" + key] = keys["Shift-Alt-" + key] = ensureSelection;
});["Left", "Mod-Left", "Right", "Mod-Right", "Up", "Down"].forEach(function (key) {
return delete keys[key];
});

if (_dom.browser.mac) keys["Ctrl-F"] = keys["Ctrl-B"] = keys["Ctrl-P"] = keys["Ctrl-N"] = keys["Alt-F"] = keys["Alt-B"] = keys["Ctrl-A"] = keys["Ctrl-E"] = keys["Ctrl-V"] = keys["goPageUp"] = ensureSelection;

var captureKeys = new _keys.Keymap(keys);
exports.captureKeys = captureKeys;
38 changes: 38 additions & 0 deletions dist/edit/char.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isWordChar = isWordChar;
exports.charCategory = charCategory;
exports.isExtendingChar = isExtendingChar;
var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;

// Extending unicode characters. A series of a non-extending char +
// any number of extending chars is treated as a single unit as far
// as editing and measuring is concerned. This is not fully correct,
// since some scripts/fonts/browsers also treat other configurations
// of code points as a group.
var extendingChar = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;

function isWordChar(ch) {
return (/\w/.test(ch) || isExtendingChar(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
);
}

/**
* Get the category of a given character. Either a "space",
* a character that can be part of a word ("word"), or anything else ("other").
*
* @param {string} ch The character.
* @return {string}
*/

function charCategory(ch) {
return (/\s/.test(ch) ? "space" : isWordChar(ch) ? "word" : "other"
);
}

function isExtendingChar(ch) {
return ch.charCodeAt(0) >= 768 && extendingChar.test(ch);
}
Loading