motion
Version:
motion - moving development forward
598 lines (459 loc) • 14.5 kB
JavaScript
webpackJsonp([0],{
/***/ 0:
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _interopRequireDefault = __webpack_require__(1)['default'];
var _errors = __webpack_require__(2);
var _errors2 = _interopRequireDefault(_errors);
var _messages = __webpack_require__(3);
var _messages2 = _interopRequireDefault(_messages);
var _eventEmitter = __webpack_require__(60);
var _eventEmitter2 = _interopRequireDefault(_eventEmitter);
var emitter = (0, _eventEmitter2['default'])({});
window._DT = {
emitter: emitter,
data: null, // should be error
on: function on(name, cb) {
emitter.on(name, cb);
},
timer: {
// received info through script:add so we can time
lastMsgInfo: null,
//maps views to original time
timing: {},
lastTimes: {},
hasLogged: false,
done: function done(view) {
var timing = Motion.timer.timing[view];
var time = +Date.now() - timing.start;
if (!time) return;
if (timing) {
Motion.timer.lastTimes[view] = time;
delete Motion.timer.timing[view];
}
if (!Motion.timer.hasLogged) {
setTimeout(function () {
return Motion.timer.hasLogged = false;
});
Motion.timer.lastTimes[view] = +Date.now() - timing.start;
on.event('hot:finished', { time: time });
}
Motion.timer.hasLogged = true;
},
time: function time(view, info) {
Motion.timer.timing[view] = info;
}
}
};
var opts = {
websocketPort: window._MOTION_WEBSOCKET_PORT
};
(0, _errors2['default'])(window._DT, opts);
(0, _messages2['default'])(window._DT, opts);
/***/ },
/***/ 2:
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = run;
exports.compileError = compileError;
exports.compileSuccess = compileSuccess;
var browser = undefined;
var browserData = function browserData(data) {
browser.data = data;
};
// this is for using in runview
function motionRuntimeError(message, file, line, col, error) {
browserData({ message: message, file: file, line: line, col: col, stack: error && error.stack });
// console.log('got err', message, file, line, col, error)
browser.emitter.emit('runtime:error');
}
window.motionRuntimeError = motionRuntimeError;
function run(b, opts) {
browser = b;
window.onViewLoaded = function () {
return browserData('success', null);
};
}
function compileError(error) {
if (error.loc) {
var message = error.message;
var fileName = error.fileName;
var loc = error.loc;
var stack = error.stack;
browserData({ message: message, stack: stack, file: fileName, line: loc.line, col: loc.column });
} else if (error.lineNumber) {
var message = error.message;
var stack = error.stack;
var fileName = error.fileName;
var lineNumber = error.lineNumber;
var column = error.column;
browserData({ message: message, stack: stack, file: fileName, line: lineNumber, col: column });
}
}
function compileSuccess() {
browserData(null);
}
/***/ },
/***/ 3:
/***/ function(module, exports, __webpack_require__) {
'use strict';
var _Promise = __webpack_require__(4)['default'];
var _interopRequireDefault = __webpack_require__(1)['default'];
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = run;
var _errors = __webpack_require__(2);
var _socket = __webpack_require__(59);
var _socket2 = _interopRequireDefault(_socket);
function run(browser, opts) {
(0, _socket2['default'])(browser, opts, {
'editor:location': function editorLocation(msg) {
browser.editorLocation = msg;
},
'view:locations': function viewLocations(msg) {
browser.viewLocations = msg;
},
'script:add': function scriptAdd(msg) {
// Motion.timer.lastMsgInfo = { start: msg.startTime }
replaceScript(msg);
},
'stylesheet:add': function stylesheetAdd(msg) {
addSheet(msg.view);
},
'stylesheet:remove': function stylesheetRemove(msg) {
removeSheet(msg.view);
},
'compile:error': function compileError(msg) {
(0, _errors.compileError)(msg.error);
},
'compile:success': function compileSuccess(msg) {
(0, _errors.compileSuccess)();
},
'packages:reload': reloadScript('__motionExternals'),
'internals:reload': reloadScript('__motionInternals', { reloadAll: true }),
'file:delete': function fileDelete(_ref) {
var name = _ref.name;
if (!Motion) return; // if attempting before initial load
var views = _Motion.getFile(name);
views.map(removeSheet);
removeScript(name);
Motion.deleteFile(name);
},
'file:outsideChange': function fileOutsideChange(_ref2) {
var name = _ref2.name;
var changed = _ref2.changed;
_Motion.fileChanged[name] = changed;
},
'motion:opts': function motionOpts(opts) {
window.__motionopts = opts;
},
// coming from editor to browser
'editor:state': function editorState(state) {
browser.editor = state;
browser.emitter.emit('editor:state');
}
});
}
// tag loader is a throttler
// it accepts requests to load tags
// and once those tags load, it will continue
function TagLoader() {
var last = {};
var loading = {};
var wait = {};
return function (name, load) {
var oldTag = last[name];
if (wait[name]) {
return;
}
if (loading[name]) {
wait[name] = true;
return;
}
loading[name] = true;
load(oldTag, onDone);
function onDone(newTag) {
last[name] = newTag;
loading[name] = false;
if (wait[name]) {
wait[name] = false;
load(last[name], onDone);
}
}
};
}
/*
This should be a closed async loop for hot loading files.
ws:add => addScript => tagloader => replaceTag =>
replaceTag => (tagLoader|null)
*/
var scriptSelector = function scriptSelector(src) {
return 'script[src^="' + removeTime(removeBase(src)) + '"]';
};
var scriptUrl = function scriptUrl(name) {
return '/_/' + name + '.js';
};
var findScript = function findScript(name) {
return document.querySelector(scriptSelector(scriptUrl(name)));
};
var sheetSelector = function sheetSelector(href) {
return 'link[href^="' + removeTime(removeBase(href)) + '"]';
};
var sheetUrl = function sheetUrl(name) {
return '/__/styles/' + name + '.css';
};
var findSheet = function findSheet(name) {
return document.querySelector(sheetSelector(sheetUrl(name)));
};
var scrLoad = TagLoader();
var cssLoad = TagLoader();
function addScript(src) {
var path = src.replace('/_/', '');
var start = Date.now();
_socket2['default'].send('script:load', { path: path });
scrLoad(src, function (lastTag, done) {
var script = lastTag || document.querySelector(scriptSelector(src)) || createScript(src);
replaceTag(script, 'src', function finish() {
// console.log('script load took', Date.now() - start)
_socket2['default'].send('script:done', { path: path });
done();
});
});
}
function addSheet(name) {
cssLoad(name, function (lastTag, done) {
replaceTag(lastTag || findSheet(name) || createSheet(sheetUrl(name)), 'href', done);
});
}
function getParent(tag) {
if (tag.parentNode) return tag.parentNode;
if (tag.nodeName == 'SCRIPT') return document.body;else return document.head;
}
function replaceTag(tag, attr) {
var after = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2];
if (!tag) return;
var parent = getParent(tag);
var clone = cloneNode(tag, attr);
var already = false;
var cielTimeout = undefined;
var afterFinish = function afterFinish() {
if (already) return;
clearTimeout(cielTimeout);
already = true;
removeTag(tag, parent, function () {
return after(clone);
});
};
clone.onerror = afterFinish;
clone.onload = afterFinish;
parent.appendChild(clone);
// ceil for slow loads
cielTimeout = setTimeout(function () {
if (already) return;
removeTag(tag, tag.parentNode, afterFinish, { leftover: 1 });
}, 120);
}
function removeTag(tag, parent, cb) {
var _ref3 = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3];
var _ref3$leftover = _ref3.leftover;
var leftover = _ref3$leftover === undefined ? 2 : _ref3$leftover;
try {
parent.removeChild(tag);
setTimeout(cb);
} catch (e) {
var isScript = tag.nodeName == 'SCRIPT';
var tags = document.querySelectorAll(isScript ? scriptSelector(tag.src) : sheetSelector(tag.href));
// attempt force removal
for (var i = 0; i < tags.length - leftover; i++) {
var _tag = tags[i];
try {
_tag.parentNode.removeChild(_tag);
} catch (e) {
try {
document.body.removeChild(_tag);
document.head.removeChild(_tag);
} catch (e) {/* oh well */}
}
}
// wait a bit longer after recovery
setTimeout(cb, 30);
}
}
function reloadScript(id) {
var opts = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
return function (data) {
var el = document.getElementById(id);
if (!el) return;
var finish = opts.reloadAll ? function () {
return reloadImportScripts(data);
} : renderMotion;
var tag = replaceTag(el, 'src', finish);
};
}
function replaceScript(_ref4, cb) {
var name = _ref4.name;
var timestamp = _ref4.timestamp;
var src = _ref4.src;
addScript(src || '/_' + name);
}
var getScriptsByPaths = function getScriptsByPaths(paths) {
return paths.map(function (path) {
return document.querySelector('.__motionScript[src*="' + path + '"]');
});
};
function reloadImportScripts() {
var _ref5 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var importers = _ref5.importers;
// only reload stuff thats changed with imports, if possible
var removeByImporter = importers && importers.length;
var scripts = removeByImporter ? getScriptsByPaths(importers) : document.querySelectorAll('.__motionScript');
if (!scripts.length) return;
var total = scripts.length;
if (removeByImporter) importers.forEach(_Motion.resetViewsInFile);else _Motion.resetViewState();
var scriptLoaders = [];[].forEach.call(scripts, function (script) {
return scriptLoaders.push(new _Promise(function (resolve) {
return replaceTag(script, 'src', resolve);
}));
});
_Promise.all(scriptLoaders).then(function () {
Motion.render();
});
}
var renderAttempts = 0;
function renderMotion() {
if (renderAttempts > 10) {
renderAttempts = 0;
return;
}
if (typeof Motion != 'undefined') {
setTimeout(Motion.render);
renderAttempts = 0;
} else {
renderAttempts++;
setTimeout(renderMotion, 50);
}
}
function removeBase(str) {
return str.replace(/^http\:\/\/[^/]+/, '');
}
function removeTime(str) {
return str.replace(/\?[0-9]+$/, '');
}
function replaceTime(str) {
return removeTime(str) + ('?' + Date.now());
}
function createScript(src) {
var tag = document.createElement('script');
tag.src = src;
return tag;
}
function createSheet(href) {
var tag = document.createElement('link');
tag.href = href;
tag.rel = "stylesheet";
return tag;
}
function cloneNode(node, attr) {
var clone = undefined;
if (node.tagName != 'SCRIPT') {
clone = node.cloneNode(false);
} else {
clone = document.createElement('script');
var attrs = node.attributes;
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name != 'src') clone.setAttribute(attrs[i].name, attrs[i].value);
}
}
clone.setAttribute(attr, replaceTime(node.getAttribute(attr)));
return clone;
}
function removeSheet(name) {
var tag = findSheet(name);
if (tag && tag.parentNode) tag.parentNode.removeChild(tag);
}
function removeScript(name) {
var tag = findScript(name.replace('.js', ''));
if (tag && tag.parentNode) {
tag.parentNode.removeChild(tag);
Motion.removeFile(name);
}
}
module.exports = exports['default'];
/***/ },
/***/ 59:
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = socket;
var opts = undefined;
var browser = undefined;
var actions = undefined;
var isOpening = false;
var isOpen = false;
var ws = null;
function socket(_browser, _opts, _actions) {
opts = _opts;
browser = _browser;
actions = _actions;
open();
browser.messageEditor = function (obj) {
socket.send('editor', obj);
};
}
socket.send = function send(type, obj) {
obj = obj || {};
obj._type = type;
ws.send(JSON.stringify(obj));
};
function open() {
if (isOpening) return;
isOpening = true;
ws = new WebSocket('ws://localhost:' + opts.websocketPort + '/');
ws.onopen = onOpen;
ws.onmessage = onMessage;
ws.onerror = reconnect;
ws.onclose = reconnect;
}
function onOpen() {
isOpen = true;
isOpening = false;
reconnecting = false;
}
function onMessage(message) {
message = JSON.parse(message.data);
if (localStorage.getItem('__motionLog')) console.log('socket', 'onMessage', 'message', message && message._type, message);
if (!message) return;
var action = actions[message._type];
if (action) action(message);
browser.data = message;
browser.emitter.emit(message._type);
}
var tries = undefined;
var reconnecting = false;
function reconnect() {
isOpening = false;
isOpen = false;
if (ws) ws.close();
if (reconnecting) return;
reconnecting = true;
tries = 0;
reconnector();
}
function reconnector() {
if (isOpen || tries > 50) return;
open();
// delay more and more in between
tries++;
var delay = tries * 1000;
setTimeout(reconnector, delay);
}
module.exports = exports['default'];
/***/ }
});
//# sourceMappingURL=devtools.dev.js.map