diff --git a/www/padrtc/TextPatcher.js b/www/padrtc/TextPatcher.js deleted file mode 100644 index a5d9b9d01..000000000 --- a/www/padrtc/TextPatcher.js +++ /dev/null @@ -1,144 +0,0 @@ -define(function () { - -/* diff takes two strings, the old content, and the desired content - it returns the difference between these two strings in the form - of an 'Operation' (as defined in chainpad.js). - - diff is purely functional. -*/ -var diff = function (oldval, newval) { - // Strings are immutable and have reference equality. I think this test is O(1), so its worth doing. - if (oldval === newval) { - return; - } - - var commonStart = 0; - while (oldval.charAt(commonStart) === newval.charAt(commonStart)) { - commonStart++; - } - - var commonEnd = 0; - while (oldval.charAt(oldval.length - 1 - commonEnd) === newval.charAt(newval.length - 1 - commonEnd) && - commonEnd + commonStart < oldval.length && commonEnd + commonStart < newval.length) { - commonEnd++; - } - - var toRemove = 0; - var toInsert = ''; - - /* throw some assertions in here before dropping patches into the realtime */ - if (oldval.length !== commonStart + commonEnd) { - toRemove = oldval.length - commonStart - commonEnd; - } - if (newval.length !== commonStart + commonEnd) { - toInsert = newval.slice(commonStart, newval.length - commonEnd); - } - - return { - type: 'Operation', - offset: commonStart, - toInsert: toInsert, - toRemove: toRemove - }; -}; - -/* patch accepts a realtime facade and an operation (which might be falsey) - it applies the operation to the realtime as components (remove/insert) - - patch has no return value, and operates solely through side effects on - the realtime facade. -*/ -var patch = function (ctx, op) { - if (!op) { return; } - if (op.toRemove) { ctx.remove(op.offset, op.toRemove); } - if (op.toInsert) { ctx.insert(op.offset, op.toInsert); } -}; - -/* format has the same signature as log, but doesn't log to the console - use it to get the pretty version of a diff */ -var format = function (text, op) { - return op?{ - insert: op.toInsert, - remove: text.slice(op.offset, op.offset + op.toRemove) - }: { insert: '', remove: '' }; -}; - -/* log accepts a string and an operation, and prints an object to the console - the object will display the content which is to be removed, and the content - which will be inserted in its place. - - log is useful for debugging, but can otherwise be disabled. -*/ -var log = function (text, op) { - if (!op) { return; } - console.log(format(text, op)); -}; - -/* applyChange takes: - ctx: the context (aka the realtime) - oldval: the old value - newval: the new value - - it performs a diff on the two values, and generates patches - which are then passed into `ctx.remove` and `ctx.insert`. - - Due to its reliance on patch, applyChange has side effects on the supplied - realtime facade. -*/ -var applyChange = function(ctx, oldval, newval, logging) { - var op = diff(oldval, newval); - if (logging) { log(oldval, op); } - patch(ctx, op); -}; - -var transformCursor = function (cursor, op) { - if (!op) { return cursor; } - var pos = op.offset; - var remove = op.toRemove; - var insert = op.toInsert.length; - if (typeof cursor === 'undefined') { return; } - if (typeof remove === 'number' && pos < cursor) { - cursor -= Math.min(remove, cursor - pos); - } - if (typeof insert === 'number' && pos < cursor) { - cursor += insert; - } - return cursor; -}; - -var create = function(config) { - var ctx = config.realtime; - var logging = config.logging; - - // initial state will always fail the !== check in genop. - // because nothing will equal this object - var content = {}; - - // *** remote -> local changes - ctx.onPatch(function(pos, length) { - content = ctx.getUserDoc(); - }); - - // propogate() - return function (newContent, force) { - if (newContent !== content || force) { - applyChange(ctx, ctx.getUserDoc(), newContent, logging); - if (ctx.getUserDoc() !== newContent) { - console.log("Expected that: `ctx.getUserDoc() === newContent`!"); - } - return true; - } - return false; - }; -}; - -return { - create: create, // create a TextPatcher object - diff: diff, // diff two strings - patch: patch, // apply an operation to a chainpad's realtime facade - format: format, - log: log, // print the components of an operation - transformCursor: transformCursor, // transform the position of a cursor - applyChange: applyChange, // a convenient wrapper around diff/log/patch -}; -}); diff --git a/www/padrtc/index.html b/www/padrtc/index.html deleted file mode 100644 index fccdfff02..000000000 --- a/www/padrtc/index.html +++ /dev/null @@ -1,79 +0,0 @@ - - -
- - - - - - - - - - - - diff --git a/www/padrtc/inner.html b/www/padrtc/inner.html deleted file mode 100644 index bf79dcd0d..000000000 --- a/www/padrtc/inner.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/www/padrtc/main.js b/www/padrtc/main.js deleted file mode 100644 index f71fa5f1d..000000000 --- a/www/padrtc/main.js +++ /dev/null @@ -1,354 +0,0 @@ -define([ - '/api/config?cb=' + Math.random().toString(16).substring(2), - '/common/messages.js', - '/common/crypto.js', - '/padrtc/realtime-input.js', - '/bower_components/hyperjson/hyperjson.amd.js', - '/common/hyperscript.js', - '/common/toolbar.js', - '/common/cursor.js', - '/common/json-ot.js', - '/bower_components/diff-dom/diffDOM.js', - '/bower_components/jquery/dist/jquery.min.js', - '/customize/pad.js' -], function (Config, Messages, Crypto, realtimeInput, Hyperjson, Hyperscript, Toolbar, Cursor, JsonOT) { - var $ = window.jQuery; - var ifrw = $('#pad-iframe')[0].contentWindow; - var Ckeditor; // to be initialized later... - var DiffDom = window.diffDOM; - - window.Toolbar = Toolbar; - window.Hyperjson = Hyperjson; - - var hjsonToDom = function (H) { - return Hyperjson.callOn(H, Hyperscript); - }; - - var module = window.REALTIME_MODULE = { - localChangeInProgress: 0 - }; - - var userName = Crypto.rand64(8), - toolbar; - - var isNotMagicLine = function (el) { - // factor as: - // return !(el.tagName === 'SPAN' && el.contentEditable === 'false'); - var filter = (el.tagName === 'SPAN' && el.contentEditable === 'false'); - if (filter) { - console.log("[hyperjson.serializer] prevented an element" + - "from being serialized:", el); - return false; - } - return true; - }; - - var andThen = function (Ckeditor) { - // $(window).on('hashchange', function() { - // window.location.reload(); - // }); - var key; - var channel = ''; - if (window.location.href.indexOf('#') === -1) { - key = Crypto.genKey(); - // window.location.href = window.location.href + '#' + Crypto.genKey(); - // return; - } - else { - var hash = window.location.hash.substring(1); - var sep = hash.indexOf('|'); - channel = hash.substr(0,sep); - key = hash.substr(sep+1); - } - - var fixThings = false; - // var key = Crypto.parseKey(window.location.hash.substring(1)); - var editor = window.editor = Ckeditor.replace('editor1', { - // https://dev.ckeditor.com/ticket/10907 - needsBrFiller: fixThings, - needsNbspFiller: fixThings, - removeButtons: 'Source,Maximize', - // magicline plugin inserts html crap into the document which is not part of the - // document itself and causes problems when it's sent across the wire and reflected back - removePlugins: 'resize' - }); - - editor.on('instanceReady', function (Ckeditor) { - editor.execCommand('maximize'); - var documentBody = ifrw.$('iframe')[0].contentDocument.body; - - documentBody.innerHTML = Messages.initialState; - - var inner = window.inner = documentBody; - var cursor = window.cursor = Cursor(inner); - - var setEditable = function (bool) { - inner.setAttribute('contenteditable', - (typeof (bool) !== 'undefined'? bool : true)); - }; - - // don't let the user edit until the pad is ready - setEditable(false); - - var diffOptions = { - preDiffApply: function (info) { - /* Don't remove local instances of the magicline plugin */ - if (info.node && info.node.tagName === 'SPAN' && - info.node.getAttribute('contentEditable') === 'false') { - return true; - } - - if (!cursor.exists()) { return; } - var frame = info.frame = cursor.inNode(info.node); - if (!frame) { return; } - if (typeof info.diff.oldValue === 'string' && - typeof info.diff.newValue === 'string') { - var pushes = cursor.pushDelta(info.diff.oldValue, - info.diff.newValue); - if (frame & 1) { - if (pushes.commonStart < cursor.Range.start.offset) { - cursor.Range.start.offset += pushes.delta; - } - } - if (frame & 2) { - if (pushes.commonStart < cursor.Range.end.offset) { - cursor.Range.end.offset += pushes.delta; - } - } - } - }, - postDiffApply: function (info) { - if (info.frame) { - if (info.node) { - if (info.frame & 1) { cursor.fixStart(info.node); } - if (info.frame & 2) { cursor.fixEnd(info.node); } - } else { console.log("info.node did not exist"); } - - var sel = cursor.makeSelection(); - var range = cursor.makeRange(); - - cursor.fixSelection(sel, range); - } - } - }; - - var now = function () { return new Date().getTime(); }; - - var initializing = true; - var userList = {}; // List of pretty name of all users (mapped with their server ID) - var toolbarList; // List of users still connected to the channel (server IDs) - var addToUserList = function(data) { - for (var attrname in data) { userList[attrname] = data[attrname]; } - if(toolbarList && typeof toolbarList.onChange === "function") { - toolbarList.onChange(userList); - } - }; - - var myData = {}; - var myUserName = ''; // My "pretty name" - var myID; // My server ID - - var setMyID = function(info) { - myID = info.myID || null; - myUserName = myID; - }; - - var createChangeName = function(id, $container) { - var buttonElmt = $container.find('#'+id)[0]; - buttonElmt.addEventListener("click", function() { - var newName = prompt("Change your name :", myUserName) - if (newName && newName.trim()) { - var myUserNameTemp = newName.trim(); - if(newName.trim().length > 32) { - myUserNameTemp = myUserNameTemp.substr(0, 32); - } - myUserName = myUserNameTemp; - myData[myID] = { - name: myUserName - }; - addToUserList(myData); - editor.fire( 'change' ); - } - }); - }; - - var DD = new DiffDom(diffOptions); - - // apply patches, and try not to lose the cursor in the process! - var applyHjson = function (shjson) { - // var hjson = JSON.parse(shjson); - // var peerUserList = hjson[hjson.length-1]; - // if(peerUserList.metadata) { - // var userData = peerUserList.metadata; - // addToUserList(userData); - // delete hjson[hjson.length-1]; - // } - var userDocStateDom = hjsonToDom(JSON.parse(shjson)); - userDocStateDom.setAttribute("contenteditable", "true"); // lol wtf - var patch = (DD).diff(inner, userDocStateDom); - (DD).apply(inner, patch); - }; - - var realtimeOptions = { - // provide initialstate... - initialState: JSON.stringify(Hyperjson.fromDOM(inner, isNotMagicLine)), - - // the websocket URL (deprecated?) - websocketURL: Config.websocketURL, - webrtcURL: Config.webrtcURL, - - // our username - userName: userName, - - // the channel we will communicate over - channel: channel, - - // our encryption key - cryptKey: key, - - setMyID: setMyID, - - // really basic operational transform - transformFunction : JsonOT.validate, - - crypto: Crypto, - }; - - var onRemote = realtimeOptions.onRemote = function (info) { - if (initializing) { return; } - - var shjson = info.realtime.getUserDoc(); - - // remember where the cursor is - cursor.update(); - - // Extract the user list (metadata) from the hyperjson - var hjson = JSON.parse(shjson); - var peerUserList = hjson[hjson.length-1]; - if(peerUserList.metadata) { - var userData = peerUserList.metadata; - // Update the local user data - userList = userData; - // Send the new data to the toolbar - if(toolbarList && typeof toolbarList.onChange === "function") { - toolbarList.onChange(userList); - } - hjson.pop(); - } - - // build a dom from HJSON, diff, and patch the editor - applyHjson(shjson); - - // Build a new stringified Chainpad hyperjson without metadata to compare with the one build from the dom - shjson = JSON.stringify(hjson); - - var hjson2 = Hyperjson.fromDOM(inner); - var shjson2 = JSON.stringify(hjson2); - if (shjson2 !== shjson) { - console.error("shjson2 !== shjson"); - module.realtimeInput.patchText(shjson2); - } - }; - - var onInit = realtimeOptions.onInit = function (info) { - var $bar = $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox'); - toolbarList = info.userList; - var config = { - userData: userList, - changeNameID: 'cryptpad-changeName' - }; - toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.webChannel, info.userList, config); - createChangeName('cryptpad-changeName', $bar); - /* TODO handle disconnects and such*/ - }; - - var onReady = realtimeOptions.onReady = function (info) { - console.log("Unlocking editor"); - initializing = false; - setEditable(true); - var shjson = info.realtime.getUserDoc(); - applyHjson(shjson); - }; - - var onAbort = realtimeOptions.onAbort = function (info) { - console.log("Aborting the session!"); - // stop the user from continuing to edit - setEditable(false); - // TODO inform them that the session was torn down - toolbar.failed(); - }; - - - - - - var rti = module.realtimeInput = realtimeInput.start(realtimeOptions); - - /* catch `type="_moz"` before it goes over the wire */ - var brFilter = function (hj) { - if (hj[1].type === '_moz') { hj[1].type = undefined; } - return hj; - }; - - // $textarea.val(JSON.stringify(Convert.dom.to.hjson(inner))); - - /* It's incredibly important that you assign 'rti.onLocal' - It's used inside of realtimeInput to make sure that all changes - make it into chainpad. - - It's being assigned this way because it can't be passed in, and - and can't be easily returned from realtime input without making - the code less extensible. - */ - var propogate = rti.onLocal = function () { - /* if the problem were a matter of external patches being - applied while a local patch were in progress, then we would - expect to be able to check and find - 'module.localChangeInProgress' with a non-zero value while - we were applying a remote change. - */ - var hjson = Hyperjson.fromDOM(inner, isNotMagicLine, brFilter); - if(Object.keys(myData).length > 0) { - hjson[hjson.length] = {metadata: userList}; - } - var shjson = JSON.stringify(hjson); - if (!rti.patchText(shjson)) { - return; - } - rti.onEvent(shjson); - }; - - /* hitting enter makes a new line, but places the cursor inside - of the. This makes it such that you
- cannot type until you click, which is rather unnacceptable.
- If the cursor is ever inside such a
, you probably want
- to push it out to the parent element, which ought to be a
- paragraph tag. This needs to be done on keydown, otherwise
- the first such keypress will not be inserted into the P. */
- inner.addEventListener('keydown', cursor.brFix);
-
- editor.on('change', propogate);
- // editor.on('change', function () {
- // var hjson = Convert.core.hyperjson.fromDOM(inner);
- // if(myData !== {}) {
- // hjson[hjson.length] = {metadata: userList};
- // }
- // $textarea.val(JSON.stringify(hjson));
- // rti.bumpSharejs();
- // });
- });
- };
-
- var interval = 100;
- var first = function () {
- Ckeditor = ifrw.CKEDITOR;
- if (Ckeditor) {
- andThen(Ckeditor);
- } else {
- console.log("Ckeditor was not defined. Trying again in %sms",interval);
- setTimeout(first, interval);
- }
- };
-
- $(first);
-});
diff --git a/www/padrtc/netflux.js b/www/padrtc/netflux.js
deleted file mode 100644
index d01302980..000000000
--- a/www/padrtc/netflux.js
+++ /dev/null
@@ -1,1473 +0,0 @@
-(function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["nf"] = factory();
- else
- root["nf"] = factory();
-})(this, function() {
-return /******/ (function(modules) { // webpackBootstrap
-/******/ // The module cache
-/******/ var installedModules = {};
-
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-
-/******/ // Check if module is in cache
-/******/ if(installedModules[moduleId])
-/******/ return installedModules[moduleId].exports;
-
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = installedModules[moduleId] = {
-/******/ exports: {},
-/******/ id: moduleId,
-/******/ loaded: false
-/******/ };
-
-/******/ // Execute the module function
-/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
-
-/******/ // Flag the module as loaded
-/******/ module.loaded = true;
-
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-
-
-/******/ // expose the modules object (__webpack_modules__)
-/******/ __webpack_require__.m = modules;
-
-/******/ // expose the module cache
-/******/ __webpack_require__.c = installedModules;
-
-/******/ // __webpack_public_path__
-/******/ __webpack_require__.p = "";
-
-/******/ // Load entry module and return exports
-/******/ return __webpack_require__(0);
-/******/ })
-/************************************************************************/
-/******/ ([
-/* 0 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var _Facade = __webpack_require__(1);
-
- var _Facade2 = _interopRequireDefault(_Facade);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- module.exports = new _Facade2.default();
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _WebChannel = __webpack_require__(2);
-
- var _WebChannel2 = _interopRequireDefault(_WebChannel);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var Facade = function () {
- function Facade() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, Facade);
-
- this.defaults = {
- webrtc: {}
- };
- this.settings = Object.assign({}, this.defaults, options);
- }
-
- _createClass(Facade, [{
- key: 'create',
- value: function create() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- return new _WebChannel2.default();
- }
- }, {
- key: 'join',
- value: function join(key) {
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var defaults = {
- connector: 'WebRTCService',
- protocol: 'ExchangeProtocolService'
- };
- var settings = Object.assign({}, defaults, options);
- var connector = _ServiceProvider2.default.get(settings.connector);
- var protocol = _ServiceProvider2.default.get(settings.protocol);
- var connectorOptions = { signaling: settings.signaling, facade: this };
- return new Promise(function (resolve, reject) {
- connector.join(key, connectorOptions).then(function (channel) {
- var webChannel = new _WebChannel2.default(options);
- channel.webChannel = webChannel;
- channel.onmessage = protocol.onmessage;
- webChannel.channels.add(channel);
- webChannel.onopen = function () {
- resolve(webChannel);
- };
- }, reject);
- });
- }
- }, {
- key: 'invite',
- value: function invite() {
- // TODO
- }
- }, {
- key: '_onJoining',
- value: function _onJoining() {
- // TODO
- }
- }, {
- key: '_onLeaving',
- value: function _onLeaving() {
- // TODO
- }
- }, {
- key: '_onMessage',
- value: function _onMessage() {
- // TODO
- }
- }, {
- key: '_onPeerMessage',
- value: function _onPeerMessage() {
- // TODO
- }
- }, {
- key: '_onInvite',
- value: function _onInvite() {
- // TODO
- }
- }]);
-
- return Facade;
- }();
-
- exports.default = Facade;
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var WebChannel = function () {
- function WebChannel() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, WebChannel);
-
- this.defaults = {
- connector: cs.WEBRTC_SERVICE,
- topology: cs.FULLYCONNECTED_SERVICE,
- protocol: cs.EXCHANGEPROTOCOL_SERVICE
- };
- this.settings = Object.assign({}, this.defaults, options);
-
- // Private attributes
- this.protocol = cs.EXCHANGEPROTOCOL_SERVICE;
-
- // Public attributes
- this.id;
- this.myID = this._generateID();
- this.channels = new Set();
- this.onjoining;
- this.onleaving;
- this.onmessage;
- }
-
- _createClass(WebChannel, [{
- key: 'leave',
- value: function leave() {}
- }, {
- key: 'send',
- value: function send(data) {
- var channel = this;
- return new Promise(function (resolve, reject) {
- if (channel.channels.size === 0) {
- resolve();
- }
- var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
- channel.topologyService.broadcast(channel, protocol.message(cs.USER_DATA, { id: channel.myID, data: data })).then(resolve, reject);
- });
- }
- }, {
- key: 'sendPing',
- value: function sendPing() {
- var channel = this;
- return new Promise(function (resolve, reject) {
- if (channel.channels.size === 0) {
- resolve();
- }
- var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
- channel.topologyService.broadcast(channel, protocol.message(cs.PING, { data: '' })).then(resolve, reject);
- });
- }
- }, {
- key: 'getHistory',
- value: function getHistory(historyKeeperID) {
- var channel = this;
- return new Promise(function (resolve, reject) {
- var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
- channel.topologyService.sendTo(historyKeeperID, channel, protocol.message(cs.GET_HISTORY, { id: channel.myID, data: '' })).then(resolve, reject);
- });
- }
- }, {
- key: 'sendTo',
- value: function sendTo(id, msg) {
- var channel = this;
- return new Promise(function (resolve, reject) {
- var protocol = _ServiceProvider2.default.get(channel.settings.protocol);
- channel.topologyService.sendTo(id, channel, protocol.message(cs.USER_DATA, { id: channel.myID, data: msg })).then(resolve, reject);
- });
- }
- }, {
- key: 'openForJoining',
- value: function openForJoining() {
- var _this = this;
-
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- var settings = Object.assign({}, this.settings, options);
- var connector = _ServiceProvider2.default.get(settings.connector);
- return connector.open(function (channel) {
- // 1) New dataChannel connection established.
- // NEXT: add it to the network
- var protocol = _ServiceProvider2.default.get(_this.protocol);
- _this.topologyService = _ServiceProvider2.default.get(_this.settings.topology);
- channel.webChannel = _this;
- channel.onmessage = protocol.onmessage;
-
- // 2.1) Send to the new client the webChannel topology name
- channel.send(protocol.message(cs.JOIN_START, _this.settings.topology));
-
- // 2.2) Ask to topology to add the new client to this webChannel
- _this.topologyService.addStart(channel, _this).then(function (id) {
- _this.topologyService.broadcast(_this, protocol.message(cs.JOIN_FINISH, id));
- _this.onJoining(id);
- });
- }, settings).then(function (data) {
- return data;
- });
- }
- }, {
- key: 'closeForJoining',
- value: function closeForJoining() {}
- }, {
- key: 'isInviting',
- value: function isInviting() {}
- }, {
- key: '_generateID',
- value: function _generateID() {
- var MIN_LENGTH = 10;
- var DELTA_LENGTH = 10;
- var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- var result = '';
- var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
-
- for (var i = 0; i < length; i++) {
- result += MASK[Math.round(Math.random() * (MASK.length - 1))];
- }
- return result;
- }
- }, {
- key: 'topology',
- set: function set(topologyServiceName) {
- this.settings.topology = topologyServiceName;
- this.topologyService = _ServiceProvider2.default.get(topologyServiceName);
- },
- get: function get() {
- return this.settigns.topology;
- }
- }]);
-
- return WebChannel;
- }();
-
- exports.default = WebChannel;
-
-/***/ },
-/* 3 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- // API user's message
- var USER_DATA = exports.USER_DATA = 0;
- var GET_HISTORY = exports.GET_HISTORY = 6;
-
- // Internal messages
- var JOIN_START = exports.JOIN_START = 2;
- var JOIN_FINISH = exports.JOIN_FINISH = 4;
- var YOUR_NEW_ID = exports.YOUR_NEW_ID = 5;
- var PING = exports.PING = 7;
-
- // Internal message to a specific Service
- var SERVICE_DATA = exports.SERVICE_DATA = 3;
-
- var WEBRTC_SERVICE = exports.WEBRTC_SERVICE = 'WebRTCService';
- var WEBSOCKET_SERVICE = exports.WEBSOCKET_SERVICE = 'WebSocketService';
- var FULLYCONNECTED_SERVICE = exports.FULLYCONNECTED_SERVICE = 'FullyConnectedService';
- var STAR_SERVICE = exports.STAR_SERVICE = 'StarTopologyService';
- var EXCHANGEPROTOCOL_SERVICE = exports.EXCHANGEPROTOCOL_SERVICE = 'ExchangeProtocolService';
- var WSPROTOCOL_SERVICE = exports.WSPROTOCOL_SERVICE = 'WebSocketProtocolService';
-
-/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _FullyConnectedService = __webpack_require__(5);
-
- var _FullyConnectedService2 = _interopRequireDefault(_FullyConnectedService);
-
- var _StarTopologyService = __webpack_require__(6);
-
- var _StarTopologyService2 = _interopRequireDefault(_StarTopologyService);
-
- var _WebRTCService = __webpack_require__(7);
-
- var _WebRTCService2 = _interopRequireDefault(_WebRTCService);
-
- var _WebSocketService = __webpack_require__(8);
-
- var _WebSocketService2 = _interopRequireDefault(_WebSocketService);
-
- var _ExchangeProtocolService = __webpack_require__(9);
-
- var _ExchangeProtocolService2 = _interopRequireDefault(_ExchangeProtocolService);
-
- var _WebSocketProtocolService = __webpack_require__(10);
-
- var _WebSocketProtocolService2 = _interopRequireDefault(_WebSocketProtocolService);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var services = new Map();
-
- var ServiceProvider = function () {
- function ServiceProvider() {
- _classCallCheck(this, ServiceProvider);
- }
-
- _createClass(ServiceProvider, null, [{
- key: 'get',
- value: function get(code) {
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var service = undefined;
- switch (code) {
- case cs.WEBRTC_SERVICE:
- service = new _WebRTCService2.default(options);
- break;
- case cs.WEBSOCKET_SERVICE:
- service = new _WebSocketService2.default(options);
- break;
- case cs.FULLYCONNECTED_SERVICE:
- service = new _FullyConnectedService2.default(options);
- break;
- case cs.STAR_SERVICE:
- service = new _StarTopologyService2.default(options);
- break;
- case cs.EXCHANGEPROTOCOL_SERVICE:
- service = new _ExchangeProtocolService2.default(options);
- break;
- case cs.WSPROTOCOL_SERVICE:
- service = new _WebSocketProtocolService2.default(options);
- break;
- }
- services.set(code, service);
- return service;
- }
- }]);
-
- return ServiceProvider;
- }();
-
- exports.default = ServiceProvider;
-
-/***/ },
-/* 5 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var FullyConnectedService = function () {
- function FullyConnectedService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, FullyConnectedService);
- }
-
- _createClass(FullyConnectedService, [{
- key: 'addStart',
- value: function addStart(channel, webChannel) {
- var _this = this;
-
- var protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
- return new Promise(function (resolve, reject) {
- channel.peerID = _this._generateID();
- channel.send(protocol.message(cs.YOUR_NEW_ID, {
- newID: channel.peerID,
- myID: webChannel.myID
- }));
- if (Reflect.has(webChannel, 'aboutToJoin') && webChannel.aboutToJoin instanceof Map) {
- webChannel.aboutToJoin.set(channel.peerID, channel);
- } else {
- webChannel.aboutToJoin = new Map();
- }
-
- if (webChannel.channels.size === 0) {
- webChannel.channels.add(channel);
- channel.onclose = function () {
- webChannel.onLeaving(channel.peerID);
- webChannel.channels.delete(channel);
- };
- resolve(channel.peerID);
- } else {
- (function () {
- webChannel.successfullyConnected = new Map();
- webChannel.successfullyConnected.set(channel.peerID, 0);
- webChannel.connectionSucceed = function (id, withId) {
- var counter = webChannel.successfullyConnected.get(withId);
- webChannel.successfullyConnected.set(withId, ++counter);
- if (webChannel.successfullyConnected.get(withId) === webChannel.channels.size) {
- _this.addFinish(webChannel, withId);
- resolve(withId);
- }
- };
- var connector = _ServiceProvider2.default.get(cs.WEBRTC_SERVICE);
- webChannel.channels.forEach(function (c) {
- connector.connect(channel.peerID, webChannel, c.peerID);
- });
- })();
- }
- });
- }
- }, {
- key: 'addFinish',
- value: function addFinish(webChannel, id) {
- if (id != webChannel.myID) {
- (function () {
- var channel = webChannel.aboutToJoin.get(id);
- webChannel.channels.add(webChannel.aboutToJoin.get(id));
- channel.onclose = function () {
- webChannel.onLeaving(channel.peerID);
- webChannel.channels.delete(channel);
- };
- //webChannel.aboutToJoin.delete(id)
- if (Reflect.has(webChannel, 'successfullyConnected')) {
- webChannel.successfullyConnected.delete(id);
- }
- })();
- } else {
- webChannel.onopen();
- }
- }
- }, {
- key: 'broadcast',
- value: function broadcast(webChannel, data) {
- return new Promise(function (resolve, reject) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
-
- try {
- for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var c = _step.value;
-
- c.send(data);
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
-
- resolve();
- });
- }
- }, {
- key: 'sendTo',
- value: function sendTo(id, webChannel, data) {
- return new Promise(function (resolve, reject) {
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
-
- try {
- for (var _iterator2 = webChannel.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var c = _step2.value;
-
- if (c.peerID == id) {
- c.send(data);
- }
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
-
- resolve();
- });
- }
- }, {
- key: 'leave',
- value: function leave(webChannel) {
- this.broadcast(webChannel);
- }
- }, {
- key: '_generateID',
- value: function _generateID() {
- var MIN_LENGTH = 10;
- var DELTA_LENGTH = 10;
- var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
- var maskLastIndex = MASK.length - 1;
- var result = '';
-
- for (var i = 0; i < length; i++) {
- result += MASK[Math.round(Math.random() * maskLastIndex)];
- }
- return result;
- }
- }]);
-
- return FullyConnectedService;
- }();
-
- exports.default = FullyConnectedService;
-
-/***/ },
-/* 6 */
-/***/ function(module, exports) {
-
- '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 StarTopologyService = function () {
- function StarTopologyService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, StarTopologyService);
- }
-
- _createClass(StarTopologyService, [{
- key: 'broadcast',
- value: function broadcast(webChannel, data) {
- return new Promise(function (resolve, reject) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
-
- try {
- for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var c = _step.value;
-
- var msg = undefined;
- // Create the string message
- var date = new Date().getTime();
- if (data.type === 'PING') {
- msg = JSON.stringify([c.seq++, 'PING', date]);
- } else {
- msg = JSON.stringify([c.seq++, data.type, webChannel.id, data.msg]);
- }
- // Store the message with his sequence number to know what message has caused the reception of an ACK
- // This is used in WebSocketProtocolService
- var srvMsg = JSON.parse(msg);
- srvMsg.shift();
- srvMsg.unshift(webChannel.myID);
- srvMsg.unshift(0);
- webChannel.waitingAck[c.seq - 1] = { resolve: resolve, reject: reject, time: date, data: srvMsg };
- // Send the message to the server
- c.send(msg);
- }
- // resolve();
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- });
- }
- }, {
- key: 'sendTo',
- value: function sendTo(id, webChannel, data) {
- return new Promise(function (resolve, reject) {
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
-
- try {
- for (var _iterator2 = webChannel.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var c = _step2.value;
-
- var msg = JSON.stringify([c.seq++, data.type, id, data.msg]);
- c.send(msg);
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
-
- resolve();
- });
- }
- }]);
-
- return StarTopologyService;
- }();
-
- exports.default = StarTopologyService;
-
-/***/ },
-/* 7 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var WEBRTC_DATA = 0;
- var CONNECT_WITH = 1;
- var CONNECT_WITH_SUCCEED = 2;
-
- var WebRTCService = function () {
- function WebRTCService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, WebRTCService);
-
- this.NAME = this.constructor.name;
- this.protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
- this.defaults = {
- signaling: 'ws://localhost:8000',
- webRTCOptions: {
- iceServers: [{
- urls: ['stun:23.21.150.121', 'stun:stun.l.google.com:19302']
- }, {
- urls: 'turn:numb.viagenie.ca',
- credential: 'webrtcdemo',
- username: 'louis%40mozilla.com'
- }]
- }
- };
- this.settings = Object.assign({}, this.defaults, options);
-
- // Declare WebRTC related global(window) constructors
- this.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.msRTCPeerConnection;
-
- this.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.RTCIceCandidate || window.msRTCIceCandidate;
-
- this.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.msRTCSessionDescription;
- }
-
- _createClass(WebRTCService, [{
- key: 'connect',
- value: function connect(newPeerID, webChannel, peerID) {
- webChannel.topologyService.sendTo(peerID, webChannel, this._msg(CONNECT_WITH, { key: newPeerID, intermediaryID: webChannel.myID }));
- }
- }, {
- key: 'open',
- value: function open(onchannel) {
- var _this = this;
-
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var defaults = {
- key: this._randomKey()
- };
- var settings = Object.assign({}, this.settings, defaults, options);
-
- return new Promise(function (resolve, reject) {
- var connections = [];
- var socket = new window.WebSocket(settings.signaling);
- socket.onopen = function () {
- socket.send(JSON.stringify({ key: settings.key }));
- resolve({ url: _this.settings.signaling, key: settings.key });
- };
- socket.onmessage = function (e) {
- var msg = JSON.parse(e.data);
- if (Reflect.has(msg, 'id') && Reflect.has(msg, 'data')) {
- if (Reflect.has(msg.data, 'offer')) {
- (function () {
- var connection = new _this.RTCPeerConnection(settings.webRTCOptions);
- connections.push(connection);
- connection.ondatachannel = function (e) {
- e.channel.onopen = function () {
- onchannel(e.channel);
- };
- };
- connection.onicecandidate = function (e) {
- if (e.candidate !== null) {
- var candidate = {
- candidate: e.candidate.candidate,
- sdpMLineIndex: e.candidate.sdpMLineIndex
- };
- socket.send(JSON.stringify({ id: msg.id, data: { candidate: candidate } }));
- }
- };
- var sd = Object.assign(new _this.RTCSessionDescription(), msg.data.offer);
- connection.setRemoteDescription(sd, function () {
- connection.createAnswer(function (answer) {
- connection.setLocalDescription(answer, function () {
- socket.send(JSON.stringify({
- id: msg.id,
- data: { answer: connection.localDescription.toJSON() } }));
- }, function () {});
- }, function () {});
- }, function () {});
- })();
- } else if (Reflect.has(msg.data, 'candidate')) {
- var candidate = new _this.RTCIceCandidate(msg.data.candidate);
- connections[msg.id].addIceCandidate(candidate);
- }
- }
- };
- socket.onerror = reject;
- });
- }
- }, {
- key: 'join',
- value: function join(key) {
- var _this2 = this;
-
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var settings = Object.assign({}, this.settings, options);
- return new Promise(function (resolve, reject) {
- var connection = undefined;
- var socket = new window.WebSocket(settings.signaling);
- socket.onopen = function () {
- connection = new _this2.RTCPeerConnection(settings.webRTCOptions);
- connection.onicecandidate = function (e) {
- if (e.candidate !== null) {
- var candidate = {
- candidate: e.candidate.candidate,
- sdpMLineIndex: e.candidate.sdpMLineIndex
- };
- socket.send(JSON.stringify({ data: { candidate: candidate } }));
- }
- };
- var dc = connection.createDataChannel(key);
- dc.onopen = function () {
- resolve(dc);
- };
- connection.createOffer(function (offer) {
- connection.setLocalDescription(offer, function () {
- socket.send(JSON.stringify({ join: key, data: { offer: connection.localDescription.toJSON() } }));
- }, reject);
- }, reject);
- };
- socket.onclose = function (e) {
- reject(e);
- };
- socket.onmessage = function (e) {
- var msg = JSON.parse(e.data);
- if (Reflect.has(msg, 'data')) {
- if (Reflect.has(msg.data, 'answer')) {
- var sd = Object.assign(new _this2.RTCSessionDescription(), msg.data.answer);
- connection.setRemoteDescription(sd, function () {}, reject);
- } else if (Reflect.has(msg.data, 'candidate')) {
- var candidate = new _this2.RTCIceCandidate(msg.data.candidate);
- connection.addIceCandidate(candidate);
- } else {
- reject();
- }
- } else {
- reject();
- }
- };
- socket.onerror = reject;
- });
- }
- }, {
- key: '_randomKey',
- value: function _randomKey() {
- var MIN_LENGTH = 10;
- var DELTA_LENGTH = 10;
- var MASK = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- var result = '';
- var length = MIN_LENGTH + Math.round(Math.random() * DELTA_LENGTH);
-
- for (var i = 0; i < length; i++) {
- result += MASK[Math.round(Math.random() * (MASK.length - 1))];
- }
- return result;
- }
- }, {
- key: '_msg',
- value: function _msg(code, data) {
- var msg = { service: this.constructor.name };
- msg.data = {};
- msg.data.code = code;
- Object.assign(msg.data, data);
- return this.protocol.message(cs.SERVICE_DATA, msg);
- }
- }, {
- key: 'onmessage',
- value: function onmessage(channel, msg) {
- var _this3 = this;
-
- var webChannel = channel.webChannel;
- if (!Reflect.has(webChannel, 'connections')) {
- webChannel.connections = new Map();
- }
- switch (msg.code) {
- case WEBRTC_DATA:
- if (webChannel.myID === msg.recipientPeerID) {
- if (Reflect.has(msg, 'sdp')) {
- if (msg.sdp.type === 'offer') {
- (function () {
- var connection = new _this3.RTCPeerConnection(_this3.settings.webRTCOptions);
- webChannel.connections.set(msg.senderPeerID, connection);
- connection.ondatachannel = function (e) {
- e.channel.onopen = function () {
- e.channel.peerID = msg.senderPeerID;
- e.channel.webChannel = webChannel;
- e.channel.onmessage = _this3.protocol.onmessage;
- webChannel.channels.add(e.channel);
- e.channel.onclose = function () {
- webChannel.onLeaving(e.channel.peerID);
- webChannel.channels.delete(e.channel);
- };
- };
- };
- connection.onicecandidate = function (e) {
- if (e.candidate !== null) {
- var candidate = {
- candidate: e.candidate.candidate,
- sdpMLineIndex: e.candidate.sdpMLineIndex
- };
- channel.send(_this3._msg(WEBRTC_DATA, {
- senderPeerID: webChannel.myID,
- recipientPeerID: msg.senderPeerID,
- candidate: candidate
- }));
- }
- };
- var sd = Object.assign(new _this3.RTCSessionDescription(), msg.sdp);
- connection.setRemoteDescription(sd, function () {
- connection.createAnswer(function (answer) {
- connection.setLocalDescription(answer, function () {
- channel.send(_this3._msg(WEBRTC_DATA, {
- senderPeerID: webChannel.myID,
- recipientPeerID: msg.senderPeerID,
- sdp: connection.localDescription.toJSON()
- }));
- }, function () {});
- }, function () {});
- }, function () {});
- })();
- } else if (msg.sdp.type === 'answer') {
- var sd = Object.assign(new this.RTCSessionDescription(), msg.sdp);
- webChannel.connections.get(msg.senderPeerID).setRemoteDescription(sd, function () {}, function () {});
- }
- } else if (Reflect.has(msg, 'candidate')) {
- webChannel.connections.get(msg.senderPeerID).addIceCandidate(new this.RTCIceCandidate(msg.candidate));
- }
- } else {
- var data = this._msg(WEBRTC_DATA, msg);
- if (webChannel.aboutToJoin.has(msg.recipientPeerID)) {
- webChannel.aboutToJoin.get(msg.recipientPeerID).send(data);
- } else {
- webChannel.topologyService.sendTo(msg.recipientPeerID, webChannel, data);
- }
- }
- break;
- case CONNECT_WITH:
- var connection = new this.RTCPeerConnection(this.settings.webRTCOptions);
- connection.onicecandidate = function (e) {
- if (e.candidate !== null) {
- var candidate = {
- candidate: e.candidate.candidate,
- sdpMLineIndex: e.candidate.sdpMLineIndex
- };
- webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(WEBRTC_DATA, {
- senderPeerID: webChannel.myID,
- recipientPeerID: msg.key,
- candidate: candidate
- }));
- }
- };
- var dc = connection.createDataChannel(msg.key);
- dc.onopen = function () {
- if (!Reflect.has(webChannel, 'aboutToJoin')) {
- webChannel.aboutToJoin = new Map();
- }
- webChannel.aboutToJoin.set(dc.label, dc);
- dc.onmessage = _this3.protocol.onmessage;
- dc.peerID = dc.label;
- dc.webChannel = webChannel;
- webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(CONNECT_WITH_SUCCEED, {
- senderPeerID: webChannel.myID,
- recipientPeerID: dc.label
- }));
- };
- connection.createOffer(function (offer) {
- connection.setLocalDescription(offer, function () {
- webChannel.topologyService.sendTo(msg.intermediaryID, webChannel, _this3._msg(WEBRTC_DATA, {
- senderPeerID: webChannel.myID,
- recipientPeerID: msg.key,
- sdp: connection.localDescription.toJSON()
- }));
- webChannel.connections.set(msg.key, connection);
- }, function () {});
- }, function () {});
- break;
- case CONNECT_WITH_SUCCEED:
- webChannel.connectionSucceed(msg.senderPeerID, msg.recipientPeerID);
- break;
- }
- }
- }]);
-
- return WebRTCService;
- }();
-
- exports.default = WebRTCService;
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var WebSocketService = function () {
- function WebSocketService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, WebSocketService);
-
- this.NAME = this.constructor.name;
- this.protocol = _ServiceProvider2.default.get(cs.EXCHANGEPROTOCOL_SERVICE);
- this.defaults = {
- signaling: 'ws://localhost:9000',
- REQUEST_TIMEOUT: 5000
- };
- this.settings = Object.assign({}, this.defaults, options);
- }
-
- _createClass(WebSocketService, [{
- key: 'join',
- value: function join(key) {
- var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
-
- var settings = Object.assign({}, this.settings, options);
- return new Promise(function (resolve, reject) {
- var connection = undefined;
- var socket = new window.WebSocket(settings.signaling);
- setInterval(function () {
- if (socket.webChannel && socket.webChannel.waitingAck) {
- var waitingAck = socket.webChannel.waitingAck;
- for (var id in waitingAck) {
- var req = waitingAck[id];
- var now = new Date().getTime();
- if (now - req.time > settings.REQUEST_TIMEOUT) {
- delete socket.webChannel.waitingAck[id];
- req.reject({ type: 'TIMEOUT', message: 'waited ' + now - req.time + 'ms' });
- }
- }
- }
- }, 5000);
- socket.seq = 1;
- socket.facade = options.facade || null;
- socket.onopen = function () {
- if (key && key !== '') {
- socket.send(JSON.stringify([socket.seq++, 'JOIN', key]));
- } else {
- socket.send(JSON.stringify([socket.seq++, 'JOIN']));
- }
- resolve(socket);
- };
- socket.onerror = reject;
- });
- }
- }]);
-
- return WebSocketService;
- }();
-
- exports.default = WebSocketService;
-
-/***/ },
-/* 9 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var ExchangeProtocolService = function () {
- function ExchangeProtocolService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, ExchangeProtocolService);
- }
-
- _createClass(ExchangeProtocolService, [{
- key: 'onmessage',
- value: function onmessage(e) {
- var msg = JSON.parse(e.data);
- var channel = e.currentTarget;
- var webChannel = channel.webChannel;
-
- switch (msg.code) {
- case cs.USER_DATA:
- webChannel.onmessage(msg.id, msg.data);
- break;
- case cs.GET_HISTORY:
- webChannel.onPeerMessage(msg.id, msg.code);
- break;
- case cs.SERVICE_DATA:
- var service = _ServiceProvider2.default.get(msg.service);
- service.onmessage(channel, msg.data);
- break;
- case cs.YOUR_NEW_ID:
- // TODO: change names
- webChannel.myID = msg.newID;
- channel.peerID = msg.myID;
- break;
- case cs.JOIN_START:
- // 2.1) Send to the new client the webChannel topology
- webChannel.topology = msg.topology;
- webChannel.topologyService = _ServiceProvider2.default.get(msg.topology);
- break;
- case cs.JOIN_FINISH:
- webChannel.topologyService.addFinish(webChannel, msg.id);
- if (msg.id != webChannel.myID) {
- // A new user has just registered
- webChannel.onJoining(msg.id);
- } else {
- (function () {
- // We're fully synced, trigger onJoining for all existing users
- var waitForOnJoining = function waitForOnJoining() {
- if (typeof webChannel.onJoining !== "function") {
- setTimeout(waitForOnJoining, 500);
- return;
- }
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
-
- try {
- for (var _iterator = webChannel.channels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var c = _step.value;
-
- webChannel.onJoining(c.peerID);
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- };
- waitForOnJoining();
- })();
- }
- break;
- }
- }
- }, {
- key: 'message',
- value: function message(code, data) {
- var msg = { code: code };
- switch (code) {
- case cs.USER_DATA:
- msg.id = data.id;
- msg.data = data.data;
- break;
- case cs.GET_HISTORY:
- msg.id = data.id;
- break;
- case cs.SERVICE_DATA:
- msg.service = data.service;
- msg.data = Object.assign({}, data.data);
- break;
- case cs.YOUR_NEW_ID:
- msg.newID = data.newID;
- msg.myID = data.myID;
- break;
- case cs.JOIN_START:
- msg.topology = data;
- break;
- case cs.JOIN_FINISH:
- msg.id = data;
- break;
- }
- return JSON.stringify(msg);
- }
- }]);
-
- return ExchangeProtocolService;
- }();
-
- exports.default = ExchangeProtocolService;
-
-/***/ },
-/* 10 */
-/***/ function(module, exports, __webpack_require__) {
-
- '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; }; }();
-
- var _constants = __webpack_require__(3);
-
- var cs = _interopRequireWildcard(_constants);
-
- var _ServiceProvider = __webpack_require__(4);
-
- var _ServiceProvider2 = _interopRequireDefault(_ServiceProvider);
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
-
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
- var WebSocketProtocolService = function () {
- function WebSocketProtocolService() {
- var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
-
- _classCallCheck(this, WebSocketProtocolService);
- }
-
- _createClass(WebSocketProtocolService, [{
- key: 'onmessage',
- value: function onmessage(e) {
- var msg = JSON.parse(e.data);
- var socket = e.currentTarget;
- var webChannel = socket.webChannel;
- var topology = cs.STAR_SERVICE;
- var topologyService = _ServiceProvider2.default.get(topology);
- var history_keeper = webChannel.hc;
-
- if (msg[0] !== 0 && msg[1] !== 'ACK') {
- return;
- }
-
- if (msg[2] === 'IDENT' && msg[1] === '') {
- socket.uid = msg[3];
- webChannel.myID = msg[3];
- webChannel.peers = [];
- webChannel.waitingAck = [];
- webChannel.topology = topology;
- return;
- }
- if (msg[1] === 'PING') {
- msg[1] = 'PONG';
- socket.send(JSON.stringify(msg));
- return;
- }
- if (msg[1] === 'ACK') {
- var seq = msg[0];
- if (webChannel.waitingAck[seq]) {
- var waitingAck = webChannel.waitingAck[seq];
- waitingAck.resolve();
- var newMsg = waitingAck.data;
- if (newMsg[2] === 'PING') {
- // PING message : set the lag
- var lag = new Date().getTime() - newMsg[3];
- webChannel.getLag = function () {
- return lag;
- };
- }
- delete webChannel.waitingAck[seq];
- }
- return;
- }
- // We have received a new direct message from another user
- if (msg[2] === 'MSG' && msg[3] === socket.uid) {
- // If it comes from the history keeper, send it to the user
- if (msg[1] === history_keeper) {
- if (msg[4] === 0) {
- webChannel.onmessage(msg[1], msg[4]);
- return;
- }
- var msgHistory = JSON.parse(msg[4]);
- webChannel.onmessage(msgHistory[1], msgHistory[4]);
- }
- return;
- }
- if (msg[2] === 'JOIN' && (webChannel.id == null || webChannel.id === msg[3])) {
- if (!webChannel.id) {
- // New unnamed channel : get its name from the first "JOIN" message
- if (!window.location.hash) {
- var chanName = window.location.hash = msg[3];
- }
- webChannel.id = msg[3];
- }
-
- if (msg[1] === socket.uid) {
- // If the user catches himself registering, he is synchronized with the server
- webChannel.onopen();
- } else {
- // Trigger onJoining() when another user is joining the channel
- // Register the user in the list of peers in the channel
- if (webChannel.peers.length === 0 && msg[1].length === 16) {
- // We've just catched the history keeper (16 characters length name)
- history_keeper = msg[1];
- webChannel.hc = history_keeper;
- }
- var linkQuality = msg[1] === history_keeper ? 1000 : 0;
- var sendToPeer = function sendToPeer(data) {
- topologyService.sendTo(msg[1], webChannel, { type: 'MSG', msg: data });
- };
- var peer = { id: msg[1], connector: socket, linkQuality: linkQuality, send: sendToPeer };
- if (webChannel.peers.indexOf(peer) === -1) {
- webChannel.peers.push(peer);
- }
-
- if (msg[1] !== history_keeper) {
- // Trigger onJoining with that peer once the function is loaded (i.e. once the channel is synced)
- var waitForOnJoining = function waitForOnJoining() {
- if (typeof webChannel.onJoining !== "function") {
- setTimeout(waitForOnJoining, 500);
- return;
- }
- webChannel.onJoining(msg[1]);
- };
- waitForOnJoining();
- }
- }
- return;
- }
- // We have received a new message in that channel from another peer
- if (msg[2] === 'MSG' && msg[3] === webChannel.id) {
- // Find the peer who sent the message and display it
- //TODO Use Peer instead of peer.id (msg[1]) :
- if (typeof webChannel.onmessage === "function") webChannel.onmessage(msg[1], msg[4]);
- return;
- }
- // Someone else has left the channel, remove him from the list of peers
- if (msg[2] === 'LEAVE' && msg[3] === webChannel.id) {
- //TODO Use Peer instead of peer.id (msg[1]) :
- if (typeof webChannel.onLeaving === "function") webChannel.onLeaving(msg[1], webChannel);
- return;
- }
- }
- }, {
- key: 'message',
- value: function message(code, data) {
- var type = undefined;
- switch (code) {
- case cs.USER_DATA:
- type = 'MSG';
- break;
- case cs.JOIN_START:
- type = 'JOIN';
- break;
- case cs.PING:
- type = 'PING';
- break;
- }
- return { type: type, msg: data.data };
- }
- }]);
-
- return WebSocketProtocolService;
- }();
-
- exports.default = WebSocketProtocolService;
-
-/***/ }
-/******/ ])
-});
-;
\ No newline at end of file
diff --git a/www/padrtc/realtime-input.js b/www/padrtc/realtime-input.js
deleted file mode 100644
index 568781209..000000000
--- a/www/padrtc/realtime-input.js
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright 2014 XWiki SAS
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see