mirror of
https://github.com/convergencelabs/monaco-collab-ext.git
synced 2026-03-02 03:49:21 +00:00
Initial commit.
This commit is contained in:
2
example/README.md
Normal file
2
example/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Monaco Collaborative Extensions Example
|
||||
This directory contains a vanilla javascript example of using this library. Simply run `npm run dist` and then open the index.html in a web browser.
|
||||
84
example/editor_contents.js
Normal file
84
example/editor_contents.js
Normal file
@@ -0,0 +1,84 @@
|
||||
var editorContents = `var observableProto;
|
||||
|
||||
/**
|
||||
* Represents a push-style collection.
|
||||
*/
|
||||
var Observable = Rx.Observable = (function () {
|
||||
|
||||
function makeSubscribe(self, subscribe) {
|
||||
return function (o) {
|
||||
var oldOnError = o.onError;
|
||||
o.onError = function (e) {
|
||||
makeStackTraceLong(e, self);
|
||||
oldOnError.call(o, e);
|
||||
};
|
||||
|
||||
return subscribe.call(self, o);
|
||||
};
|
||||
}
|
||||
|
||||
function Observable() {
|
||||
if (Rx.config.longStackSupport && hasStacks) {
|
||||
var oldSubscribe = this._subscribe;
|
||||
var e = tryCatch(thrower)(new Error()).e;
|
||||
this.stack = e.stack.substring(e.stack.indexOf('\\n') + 1);
|
||||
this._subscribe = makeSubscribe(this, oldSubscribe);
|
||||
}
|
||||
}
|
||||
|
||||
observableProto = Observable.prototype;
|
||||
|
||||
/**
|
||||
* Determines whether the given object is an Observable
|
||||
* @param {Any} An object to determine whether it is an Observable
|
||||
* @returns {Boolean} true if an Observable, else false.
|
||||
*/
|
||||
Observable.isObservable = function (o) {
|
||||
return o && isFunction(o.subscribe);
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribes an o to the observable sequence.
|
||||
* @param {Mixed} [oOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence.
|
||||
* @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence.
|
||||
* @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence.
|
||||
* @returns {Diposable} A disposable handling the subscriptions and unsubscriptions.
|
||||
*/
|
||||
observableProto.subscribe = observableProto.forEach = function (oOrOnNext, onError, onCompleted) {
|
||||
return this._subscribe(typeof oOrOnNext === 'object' ?
|
||||
oOrOnNext :
|
||||
observerCreate(oOrOnNext, onError, onCompleted));
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribes to the next value in the sequence with an optional "this" argument.
|
||||
* @param {Function} onNext The function to invoke on each element in the observable sequence.
|
||||
* @param {Any} [thisArg] Object to use as this when executing callback.
|
||||
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
|
||||
*/
|
||||
observableProto.subscribeOnNext = function (onNext, thisArg) {
|
||||
return this._subscribe(observerCreate(typeof thisArg !== 'undefined' ? function(x) { onNext.call(thisArg, x); } : onNext));
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribes to an exceptional condition in the sequence with an optional "this" argument.
|
||||
* @param {Function} onError The function to invoke upon exceptional termination of the observable sequence.
|
||||
* @param {Any} [thisArg] Object to use as this when executing callback.
|
||||
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
|
||||
*/
|
||||
observableProto.subscribeOnError = function (onError, thisArg) {
|
||||
return this._subscribe(observerCreate(null, typeof thisArg !== 'undefined' ? function(e) { onError.call(thisArg, e); } : onError));
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribes to the next value in the sequence with an optional "this" argument.
|
||||
* @param {Function} onCompleted The function to invoke upon graceful termination of the observable sequence.
|
||||
* @param {Any} [thisArg] Object to use as this when executing callback.
|
||||
* @returns {Disposable} A disposable handling the subscriptions and unsubscriptions.
|
||||
*/
|
||||
observableProto.subscribeOnCompleted = function (onCompleted, thisArg) {
|
||||
return this._subscribe(observerCreate(null, null, typeof thisArg !== 'undefined' ? function() { onCompleted.call(thisArg); } : onCompleted));
|
||||
};
|
||||
|
||||
return Observable;
|
||||
})();`;
|
||||
19
example/example.css
Normal file
19
example/example.css
Normal file
@@ -0,0 +1,19 @@
|
||||
.body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.editors {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.editor-column {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.editor {
|
||||
height: 500px;
|
||||
border: 1px solid grey;
|
||||
margin-right: 20px;
|
||||
}
|
||||
80
example/example.js
Normal file
80
example/example.js
Normal file
@@ -0,0 +1,80 @@
|
||||
const sourceUser = {
|
||||
id: "source",
|
||||
label: "Source User",
|
||||
color: "orange"
|
||||
};
|
||||
|
||||
const staticUser = {
|
||||
id: "static",
|
||||
label: "Static User",
|
||||
color: "blue"
|
||||
};
|
||||
|
||||
require.config({ paths: { 'vs': '../node_modules/monaco-editor/min/vs' }});
|
||||
require(['vs/editor/editor.main', 'MonacoCollabExt'], function(m, MonacoCollabExt) {
|
||||
|
||||
//
|
||||
// Create the target editor where events will be played into.
|
||||
//
|
||||
const target = monaco.editor.create(document.getElementById("target-editor"), {
|
||||
value: editorContents,
|
||||
theme: "vs-dark'",
|
||||
language: 'javascript'
|
||||
});
|
||||
|
||||
const remoteCursorManager = new MonacoCollabExt.RemoteCursorManager({
|
||||
editor: target,
|
||||
tooltips: true,
|
||||
tooltipDuration: 2
|
||||
});
|
||||
const sourceUserCursor = remoteCursorManager.addCursor(sourceUser.id, sourceUser.color, sourceUser.label);
|
||||
const staticUserCursor = remoteCursorManager.addCursor(staticUser.id, staticUser.color, staticUser.label);
|
||||
|
||||
const remoteSelectionManager = new MonacoCollabExt.RemoteSelectionManager({editor: target});
|
||||
remoteSelectionManager.addSelection(sourceUser.id, sourceUser.color);
|
||||
remoteSelectionManager.addSelection(staticUser.id, staticUser.color);
|
||||
|
||||
const targetContentManager = new MonacoCollabExt.EditorContentManager({
|
||||
editor: target
|
||||
});
|
||||
|
||||
//
|
||||
// Faked other user.
|
||||
//
|
||||
staticUserCursor.setOffset(50);
|
||||
remoteSelectionManager.setSelectionOffsets(staticUser.id, 40, 50);
|
||||
|
||||
|
||||
//
|
||||
// Create the source editor were events will be generated.
|
||||
//
|
||||
const source = monaco.editor.create(document.getElementById("source-editor"), {
|
||||
value: editorContents,
|
||||
theme: "vs-dark'",
|
||||
language: 'javascript'
|
||||
});
|
||||
|
||||
source.onDidChangeCursorPosition(e => {
|
||||
const offset = source.getModel().getOffsetAt(e.position);
|
||||
sourceUserCursor.setOffset(offset);
|
||||
});
|
||||
|
||||
source.onDidChangeCursorSelection(e => {
|
||||
const startOffset = source.getModel().getOffsetAt(e.selection.getStartPosition());
|
||||
const endOffset = source.getModel().getOffsetAt(e.selection.getEndPosition());
|
||||
remoteSelectionManager.setSelectionOffsets(sourceUser.id, startOffset, endOffset);
|
||||
});
|
||||
|
||||
const sourceContentManager = new MonacoCollabExt.EditorContentManager({
|
||||
editor: source,
|
||||
onInsert(index, text) {
|
||||
targetContentManager.insert(index, text);
|
||||
},
|
||||
onReplace(index, length, text) {
|
||||
targetContentManager.replace(index, length, text);
|
||||
},
|
||||
onDelete(index, length) {
|
||||
targetContentManager.delete(index, length);
|
||||
}
|
||||
});
|
||||
});
|
||||
29
example/index.html
Normal file
29
example/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main"
|
||||
href="../node_modules/monaco-editor/min/vs/editor/editor.main.css"/>
|
||||
<link rel="stylesheet" href="../dist/css/monaco-collab-ext.css">
|
||||
<link rel="stylesheet" href="./example.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="editors">
|
||||
<div class="editor-column">
|
||||
<div class="editor" id="source-editor"></div>
|
||||
</div>
|
||||
<div class="editor-column">
|
||||
<div class="editor" id="target-editor"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="editor_contents.js"></script>
|
||||
<script>var require = {paths: {'vs': '../node_modules/monaco-editor/min/vs'}};</script>
|
||||
<script src="../node_modules/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="../node_modules/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script src="../node_modules/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="../dist/umd/monaco-collab-ext.js"></script>
|
||||
<script src="./example.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user