autocode
Version:
the ultimate developer platform
1,772 lines (1,574 loc) • 130 kB
JavaScript
jQuery.fn.extend({
visibleHeight: function() {
var o = $(this);
if (o.is(':hidden')) {
return 0;
} else {
return o.outerHeight();
}
},
visibleWidth: function() {
var o = $(this);
if (o.is(':hidden')) {
return 0;
} else {
return o.outerWidth();
}
}
});
var autocode = {
action: {},
config: {},
data: {
current: {
pin: true
}
},
state: {},
user: {},
initState: function() {
$('a').each(function() {
if ($(this).data('state')) {
return;
}
$(this).data('state', true);
if (navigator.userAgent.match(/mobile/i)) {
$(this).bind({
touchstart: function() {
$(window).removeData('scrolled');
},
touchend: function(e) {
if ($(window).data('scrolled')) {
return false;
}
return autocode.initStateCallback(e, $(this));
}
});
} else {
$(this).click(autocode.initStateCallback);
}
});
},
initStateCallback: function(e, o) {
var o = o || $(this);
var href = o.attr('href');
if (!href) {
return false;
} else if (href.match(/^https?:/)) {
// open new window
window.open(href, '_blank');
// close popover
autocode.popover.close();
return false;
}
e.preventDefault();
// get query
var query = href.split('?');
href = query[0];
query = autocode.query.search(query[1]);
console.log(href);
// get name
var name = href.split('/').splice(0, 2).join('/');
// get state name
var state_name = href;
if (name == autocode.repo) {
state_name = state_name.split('/').splice(2).join('/');
}
var state = autocode.state[state_name];
if (state) {
$('input:focus').blur();
state(query);
autocode.initState();
} else if (!state) {
autocode.action.loadProject({ name: name });
}
history.pushState(null, null, href);
if (autocode.listener.listeners[state_name]) {
for (var listener_name in autocode.listener.listeners[state_name]) {
autocode.listener.listeners[state_name][listener_name](query);
}
}
autocode.resize.all();
return false;
}
};
$(window).load(autocode.init);
$(window).resize(autocode.resize);;autocode.api = {
url: null,
ajax: function(opts) {
opts = opts || {};
if (!opts.url) {
opts.url = autocode.api.url;
}
opts.url += opts.uri;
var ajax = {
contentType: 'application/json',
dataType: 'json',
method: opts.method,
url: opts.url,
complete: opts.complete,
error: function(data) {
if (opts.error) {
opts.error(data.responseJSON);
}
},
success: opts.success,
xhrFields: {
withCredentials: true
}
};
if (opts.data) {
if (opts.method == 'get') {
for (var name in opts.data) {
if (ajax.url.match(/\?/)) {
ajax.url += '&';
} else {
ajax.url += '?';
}
ajax.url += name + '=' + opts.data[name];
}
} else {
ajax.data = JSON.stringify(opts.data);
}
}
$.ajax(ajax);
},
get: function(opts) {
opts.method = 'get';
return autocode.api.ajax(opts);
},
post: function(opts) {
opts.method = 'post';
return autocode.api.ajax(opts);
}
};;autocode.console = {
init: function() {
var showConsole = autocode.storage.get('showConsole');
if (showConsole) {
$('#console').show();
} else {
$('#console').hide();
}
}
};;autocode.element = {};;autocode.fuzzy = {
close: function() {
$('#fuzzy').remove();
},
open: function(opts) {
var fuzzy = $('#fuzzy');
if (!fuzzy.length) {
fuzzy = $(document.createElement('div'));
$('body').append(fuzzy);
}
fuzzy.attr('id', 'fuzzy');
fuzzy.data('target', opts.target);
var icons_exist = false;
for (var i = 0; i < opts.rows.length; i++) {
if (opts.rows[i].icon) {
icons_exist = true;
break;
}
}
var table = $(document.createElement('div'));
table.addClass('table');
var row_icon,
row_link,
row_text;
for (var i = 0; i < opts.rows.length; i++) {
row = opts.rows[i];
row_link = $(document.createElement('a'));
if (row.state) {
row_link.attr('href', row.state);
} else if (typeof(row.action) == 'object') {
row_link.attr('onclick', 'autocode.action[\'' + row.action.name + '\'](' + JSON.stringify(row.action.data) + ')');
} else if (typeof(row.action) == 'string') {
row_link.attr('onclick', 'autocode.action[\'' + row.action + '\']()');
}
table.append(row_link);
if (icons_exist) {
row_icon = $(document.createElement('span'));
row_icon.addClass('icon');
if (row.icon) {
if (row.icon.match(/^https?:/)) {
row_icon.css('background-image', 'url(' + row.icon + ')');
} else {
row_icon.addClass(row.icon);
}
}
row_link.append(row_icon);
}
row_text = $(document.createElement('span'));
row_text.addClass('text');
row_text.html(row.text.replace(new RegExp('(' + opts.value + ')', 'i'), '<b>$1</b>'));
row_link.append(row_text);
}
fuzzy.html(table);
autocode.initState();
autocode.resize.fuzzy();
}
};;autocode.hint = {
timer: null,
close: function(opts) {
opts = opts || {};
if (opts.animated === false) {
$('#hint, #hint-arrow').remove();
} else {
$('#hint, #hint-arrow').remove();
/*
$('#hint, #hint-arrow').fadeOut(function() {
$('#hint, #hint-arrow').remove();
});
*/
}
},
init: function() {
$('*[data-hint]').each(function() {
$(this).bind({
mouseenter: function() {
autocode.hint.open({
minTop: $(this).data('hint-min-top'),
target: $(this),
text: $(this).data('hint')
});
autocode.resize.hint();
},
mouseleave: function() {
autocode.hint.close();
}
});
});
},
open: function(opts) {
clearTimeout(autocode.hint.timer);
var hint = $('#hint');
if (!hint.length) {
hint = $(document.createElement('div'));
hint.attr('id', 'hint');
$('body').append(hint);
}
if (opts.minTop !== undefined) {
hint.data('minTop', opts.minTop);
} else {
hint.removeData('minTop');
}
if (opts.offsetTop !== undefined) {
hint.data('offsetTop', opts.offsetTop);
} else {
hint.removeData('offsetTop');
}
hint.data('originalText', opts.text);
if (opts.scrollUp) {
hint.data('scrollUp', opts.scrollUp);
} else {
hint.removeData('scrollUp');
}
if (opts.top !== undefined) {
hint.data('top', opts.top);
} else {
hint.removeData('top');
}
var hint_arrow = $('#hint-arrow');
if (!hint_arrow.length) {
hint_arrow = $(document.createElement('div'));
hint_arrow.attr('id', 'hint-arrow');
$('body').append(hint_arrow);
}
hint.data('target', opts.target);
hint.html(opts.text);
if (opts.timer) {
autocode.hint.timer = setTimeout(function() {
autocode.hint.close();
}, opts.timer);
}
}
};;autocode.init = function() {
autocode.api.url = autocode.url.api();
autocode.resize.loader();
$('#loader').animate({ opacity: 1 });
autocode.console.init();
autocode.hint.init();
autocode.shortcut.init()
autocode.initState();
$(window).bind({
keyup: function(e) {
if (e.keyCode == 9 || e.keyCode == 27) {
autocode.fuzzy.close();
}
},
mousedown: function(e) {
var target = $(e.target);
if (
target.attr('id') != 'popover' && !target.parents('#popover').length
&& target.attr('id') != 'menu' && !target.parents('#menu').length
&& target.attr('id') != 'more-icon' && !target.parents('#more-icon').length
&& target.attr('id') != 'user' && !target.parents('#user').length
) {
autocode.popover.close();
}
if (target.attr('id') != 'fuzzy' && !target.parents('#fuzzy').length) {
autocode.fuzzy.close();
}
},
popstate: function() {
var hash = location.hash.split('#')[1];
if (autocode.state[hash]) {
autocode.state[hash]();
}
},
scroll: function() {
$(this).data('scrolled', true);
}
});
$('#content .content-center').bind('scroll', function() {
if ($('#fuzzy').length) {
autocode.resize.fuzzy();
}
if ($('#hint').length) {
autocode.resize.hint();
}
});
var code = autocode.query.get('code');
if (code) {
history.pushState(null, null, '/');
autocode.api.login.post({
data: {
code: code,
provider: 1
},
error: function(data) {
alert('Unable to login.');
autocode.load();
},
success: autocode.load
});
} else {
autocode.load();
}
autocode.resize.all();
};
$(window).load(autocode.init);;autocode.listener = {
listeners: {},
add: function(name, state, callback) {
if (!autocode.listener.listeners[state]) {
autocode.listener.listeners[state] = {};
}
autocode.listener.listeners[state][name] = callback;
},
remove: function(name, state) {
if (state) {
autocode.listener.listeners[state].splice(
autocode.listener.listeners[state].indexOf(name),
1
);
if (!Object.keys(autocode.listener.listeners[state]).length) {
delete(autocode.listener.listeners[state]);
}
} else {
var listeners;
for (var listener_state in autocode.listener.listeners) {
delete(autocode.listener.listeners[listener_state][name]);
if (!Object.keys(autocode.listener.listeners[listener_state]).length) {
delete(autocode.listener.listeners[listener_state]);
}
}
}
}
};;autocode.load = function() {
autocode.api.auth.get({
error: function(data) {
console.log(data);
alert('Unable to load Autocode. Please contact support.');
},
success: function(data) {
autocode.data.auth = data;
autocode.api.config.get({
data: {
repo: 'crystal/autocode'
},
error: function(data) {
console.log(data);
alert('Unable to load Autocode. Please contact support.');
},
success: function(data) {
autocode.config = jsyaml.safeLoad(data.config);
autocode.api.user.get({
complete: function() {
autocode.action.updateRecent();
var repo = autocode.storage.get('repo');
if (!repo) {
repo = location.pathname.substr(1);
}
if (!repo) {
$('#loader').fadeOut(function() {
$('#loader').remove();
$('#container').show();
$('#menu-project, #welcome').hide();
autocode.resize.all();
$('#container').animate({ opacity: 1 },{
complete: function() {
var config = autocode.query.get('config');
if (config) {
config = jsyaml.safeLoad(atob(config));
autocode.action.loadProject({
name: '(Untitled)',
config: config
});
} else {
$('#welcome').css({ opacity: 0 }).show().animate({ opacity: 1 });
}
autocode.resize.all();
}
});
});
return;
}
$('#loader').fadeOut(function() {
$('#loader').remove();
$('#container').show();
$('#welcome').hide();
autocode.resize.all();
$('#container').animate({
opacity: 1
},{
complete: function() {
var name = repo.split('/').splice(0, 2).join('/');
var state = repo.split('/').splice(2).join('/');
autocode.action.loadProject({
name: name,
callback: state ? autocode.state[state] : null
});
}
});
});
},
error: function() {
$('#new-option, #load-option').hide();
$('#recent').hide();
},
success: function(data) {
autocode.data.user = data;
autocode.data.user.isLoggedIn = true;
$('#login-option').hide();
$('#user .icon').css('background-image', 'url(' + data.avatar + ')');
$('#user .text').text(data.username);
var initBox = function() {
autocode.api.box.post({
error: function(data) {
console.log(data);
$('#target-icon .text').text('Target not found');
},
success: function(data) {
if (data.ready) {
if (!autocode.ws.ip) {
autocode.status.pending();
autocode.ws.ip = data.ip;
autocode.ws.init();
}
$('#target-icon .text').text(data.ip);
}
}
});
};
initBox();
setInterval(initBox, 10 * 1000);
}
});
}
});
}
});
};;autocode.loader = {
close: function() {
$('#loader').remove();
},
open: function(opts) {
autocode.loader.close();
var loader = $(document.createElement('div'));
loader.attr('id', 'loader');
loader.html('<img class="icon" src="images/loader.svg" />');
$('body').append(loader);
autocode.resize.all(['loader']);
loader.animate({ opacity: 1 });
}
};;autocode.mobile = {
minWidth: 900
};;autocode.object = {
clone: function(o) {
return JSON.parse(JSON.stringify(o));
},
sort: function(o) {
var sorted = {}, key, a = [];
for (key in o) {
if (o.hasOwnProperty(key)) {
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = o[a[key]];
}
return sorted;
}
};;autocode.popover = {
close: function() {
$('#popover').remove();
},
open: function(opts) {
var popover = $(document.createElement('div'));
popover.attr('id', 'popover');
if (opts.bottom !== undefined) {
popover.css('bottom', opts.bottom);
}
if (opts.left !== undefined) {
popover.css('left', opts.left);
}
if (opts.right !== undefined) {
popover.css('right', opts.right);
}
if (opts.top !== undefined) {
popover.css('top', opts.top);
}
popover.data('target', opts.target);
if (!opts.content) {
switch (opts.style) {
case 'table':
opts.content = '<div class="table">';
var row_action;
for (var row_i = 0; row_i < opts.rows.length; row_i++) {
if (opts.rows[row_i].state) {
row_action = ' href="' + opts.rows[row_i].state + '"';
} else if (typeof(opts.rows[row_i].action) == 'object') {
row_action = ' onclick="autocode.action.' + opts.rows[row_i].action.name + '(' + JSON.stringify(opts.rows[row_i].action.data) + ')"';
} else if (typeof(opts.rows[row_i].action) == 'string') {
row_action = ' onclick="autocode.action.' + opts.rows[row_i].action + '()"';
} else {
row_action = '';
}
opts.content += '<a' + row_action + '>'
+ '<span class="icon ' + opts.rows[row_i].icon + '"' + (opts.rows[row_i].style == 'divider' ? ' style="border-top: 1px #CCC solid"' : '') + '></span>'
+ '<span class="text"' + (opts.rows[row_i].style == 'divider' ? ' style="border-top: 1px #CCC solid"' : '') + '>' + opts.rows[row_i].text + '</span>'
+ '</a>';
}
opts.content += '</div>';
break;
}
}
popover.html(opts.content);
popover.hide();
$('body').append(popover);
popover.slideDown();
},
toggle: function(opts) {
if ($('#popover').length) {
var target = $('#popover').data('target')
$('#popover').remove();
if (opts.target.attr('id') != target.attr('id')) {
autocode.popover.open(opts);
}
} else {
autocode.popover.open(opts);
}
}
};;autocode.popup = {
close: function() {
$('#popup, #overlay').remove();
},
error: function(msg) {
if (msg === false) {
$('#popup .error').hide();
} else {
$('#popup .error').text(msg).show();
}
autocode.resize.all();
return false;
},
open: function(opts) {
autocode.popup.close();
var popup = $(document.createElement('div'));
popup.attr('id', 'popup');
popup.hide();
var html = '';
if (opts.title) {
html += '<div class="title"' + (opts.content ? '' : ' style="padding-bottom: 0px"') + '>' + opts.title + '</div>';
}
html += '<div class="error"></div>';
if (!opts.content) {
switch (opts.style) {
case 'table':
opts.content = '<div class="table">';
var row_action;
for (var row_i = 0; row_i < opts.rows.length; row_i++) {
if (opts.rows[row_i].state) {
row_action = ' href="' + opts.rows[row_i].state + '"';
} else if (typeof(opts.rows[row_i].action) == 'object') {
row_action = ' onclick="autocode.action.' + opts.rows[row_i].action.name + '(' + JSON.stringify(opts.rows[row_i].action.data) + ')"';
} else if (typeof(opts.rows[row_i].action) == 'string') {
row_action = ' onclick="autocode.action.' + opts.rows[row_i].action + '()"';
} else {
row_action = '';
}
opts.content += '<a' + row_action + '>'
+ '<span class="icon' + (!opts.rows[row_i].icon.match(/^http/) ? ' ' + opts.rows[row_i].icon : '') + '" style="' + (!!opts.rows[row_i].icon.match(/^http/) ? 'background-image: url(' + opts.rows[row_i].icon + ');' : '') + (opts.rows[row_i].style == 'divider' ? 'border-top: 1px #CCC solid' : '') + '"></span>'
+ '<span class="text"' + (opts.rows[row_i].style == 'divider' ? ' style="border-top: 1px #CCC solid"' : '') + '>' + opts.rows[row_i].text + '</span>'
+ '</a>';
}
opts.content += '</div>';
break;
}
}
if (opts.content) {
html += '<div class="content">' + opts.content + '</div>';
}
popup.html(html);
$('body').append(popup);
if (opts.overlay !== false) {
var overlay = $(document.createElement('div'));
overlay.attr('id', 'overlay');
overlay.click(function() {
autocode.popup.close();
});
overlay.hide();
$('body').append(overlay);
$('#overlay').fadeIn();
}
$('#popup').css('opacity', 0.01).show();
$('#popup input').first().focus().keyup();
$('#popup').animate({ opacity: 1 });
autocode.resize.all(['fuzzy', 'overlay', 'popup']);
autocode.initState();
}
};;autocode.query = {
get: function(variable, search) {
var query = search ? search : window.location.search.substring(1);
var vars = query.split('&');
var data = {};
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (variable && decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
},
search: function(search) {
var query = search ? search : window.location.search.substring(1);
var vars = query.split('&');
var data = {};
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
data[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return data;
}
};;autocode.resize = {
all: function(resize) {
if (typeof(resize) == 'string') {
resize = [resize];
}
var parts = [
'body',
'content',
'config',
'exports',
'exportsInit',
'footer',
'header',
'hint',
'init',
'loader',
'output',
'outputInit',
'outputsInit',
'overlay',
'popup',
'scriptsInit',
'fuzzy',
'welcome'
];
var part;
for (var i = 0; i < parts.length; i++) {
part = parts[i];
if (resize && resize.indexOf(part) === -1) {
continue;
}
autocode.resize[part]();
}
}
};
$(window).resize(function() { autocode.resize.all(); });;autocode.shortcut = {
init: function() {
$(window).bind('keydown', function(e) {
if (e.keyCode == 27) {
if ($('#popup').length) {
autocode.action.closePopup();
} else {
autocode.action.closeProject();
}
return;
} else if (!e.ctrlKey || !e.shiftKey) {
return;
}
switch (e.keyCode) {
// 1
case 49: {
autocode.state['overview']();
break;
}
// 2
case 50: {
autocode.state['imports']();
break;
}
// 3
case 51: {
autocode.state['config']();
break;
}
// 4
case 52: {
autocode.state['output']();
break;
}
// b
case 66: {
autocode.action.build();
break;
}
// c
case 67: {
autocode.action.toggleConsole();
break;
}
// n
case 78: {
autocode.action.newProject();
break;
}
// o
case 79: {
autocode.action.loadProject();
break;
}
// r
case 82: {
autocode.action.run();
break;
}
// s
case 83: {
autocode.action.saveProject();
break;
}
// u
case 85: {
autocode.action.update();
break;
}
// w
case 87: {
autocode.action.closeProject();
break;
}
}
autocode.resize.all();
return false;
});
}
};;autocode.status = {
offline: function() {
$('#status-icon').removeClass('online pending');
$('#status-icon').data('hint', 'Offline');
},
online: function() {
$('#status-icon').removeClass('pending').addClass('online');
$('#status-icon').data('hint', 'Online');
},
pending: function() {
$('#status-icon').removeClass('online').addClass('pending');
$('#status-icon').data('hint', 'Pending');
}
};;autocode.storage = {
get: function(name, default_item) {
var item = localStorage.getItem(name);
if (item && item.match(/^json:\/\//)) {
item = JSON.parse(item.substr(7));
}
return item || default_item;
},
remove: function(name, item) {
return localStorage.removeItem(name);
},
set: function(name, item) {
if (typeof(item) == 'object') {
item = 'json://' + JSON.stringify(item);
}
return localStorage.setItem(name, item);
}
};;autocode.string = {
escape: function(str) {
return str.replace(/"/g, '"');
}
};;autocode.unload = {
callback: function() {
return 'You will lose any unsaved changes';
},
disable: function() {
if (location.hostname.match(/^alpha/)) {
return;
}
$(window).unbind('beforeunload', autocode.unload.callback);
},
enable: function() {
if (location.hostname.match(/^alpha/)) {
return;
}
$(window).bind('beforeunload', autocode.unload.callback);
}
};;autocode.url = {
api: function(uri) {
if (location.host.match(/^alpha/)) {
return 'http://alpha.api.autocode.run:3000/' + (uri ? uri : '');
} else {
return 'https://api.autocode.run/' + (uri ? uri : '');
}
}
};;autocode.ws = {
ip: null,
io: null,
init: function() {
if (!autocode.ws.ip) {
return;
}
$('#console .content').append('<div>Connecting...</div>');
if (autocode.data.current.pin) {
$('#console .content').scrollTop($('#console .content')[0].scrollHeight);
}
autocode.ws.io = io('http://' + autocode.ws.ip + ':12345');
autocode.ws.io.on('connect', function(socket) {
$('#console .content').append('<div>Connected.</div>');
if (autocode.data.current.pin) {
$('#console .content').scrollTop($('#console .content')[0].scrollHeight);
}
autocode.status.online();
$('#usage-on').show();
$('#usage-off').hide();
});
autocode.ws.io.on('message', function(data) {
if (!data.data) {
return;
}
data = data.data.split("\n");
for (var i = 0; i < data.length; i++) {
$('#console .content').append('<div>' + (data[i].length ? data[i] : ' ') + '</div>');
if (autocode.data.current.pin) {
$('#console .content').scrollTop($('#console .content')[0].scrollHeight);
}
}
});
autocode.ws.io.on('disconnect', function(data) {
$('#console .content').append('<div>Disconnected.</div>');
if (autocode.data.current.pin) {
$('#console .content').scrollTop($('#console .content')[0].scrollHeight);
}
autocode.status.pending();
$('#usage-on').hide();
$('#usage-off').show();
});
}
};;;;autocode.action.addCommand = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
formula: 'formulas/forms/AddCommand.json',
xhr: true,
ready: function(form) {
form.fields.command.autocomplete = false;
form.fields.command.keyup = function() {
var rows = [], command_name, commands = ['build','run','stop'];
for (var i in commands) {
command_name = commands[i];
if (command_name.match(new RegExp(value, 'i'))) {
rows.push({
action: {
name: 'addCommandName',
data: { name: command_name }
},
icon: command_name + '-icon black',
text: command_name
});
}
}
autocode.fuzzy.open({
rows: rows,
target: $('#popup input[name="command"]'),
value: value
});
};
autocode.popup.open({
title: 'Add Command',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
autocode.project.scripts.build.push({
command: data.command,
description: data.description,
title: data.title
});
$('#popup, #overlay').fadeOut(function() {
autocode.popup.close();
});
autocode.state['commands']();
return false;
}
});
};;autocode.action.addImport = function(opts) {
autocode.fuzzy.close();
if (!autocode.project.imports) {
autocode.project.imports = {};
}
autocode.project.imports[opts.repo] = 'Loading...';
autocode.state['imports']({ disableSelected: true });
$('#imports-search').val('');
$('#imports-content-readme').text('');
var add = function() {
autocode.api.releases.get({
data: {
repo: opts.repo
},
success: function(data) {
autocode.project.imports[opts.repo] = '~' + data[0].substr(1);
autocode.api.config.get({
data: {
repo: opts.repo
},
success: function(data) {
var imported = this.url.split('?')[1];
imported = autocode.query.search(imported);
data.config = jsyaml.safeLoad(data.config)
autocode.imports[imported.repo] = data.config;
if (data.config.exports) {
for (var export_name in data.config.exports) {
switch (data.config.exports[export_name].type) {
case 'generator': {
autocode.data.generators[imported.repo.split('/')[1] + '.' + export_name] = JSON.parse(JSON.stringify(data.config.exports[export_name]));
break;
}
}
}
}
}
});
autocode.state['imports']({ disableSelected: true });
if ($(window).width() > autocode.mobile.minWidth) {
autocode.action.loadImport({ repo: opts.repo });
}
$('#imports-init').fadeOut(function() {
$('#imports-content-container').fadeIn();
});
}
});
};
if ($('#popup').length) {
$('#popup, #overlay').fadeOut(add);
} else {
add();
}
};;autocode.action.addOutput = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
formula: 'formulas/forms/AddOutput.json',
xhr: true,
ready: function(form) {
form.fields.filename.autocomplete = false;
form.fields.generator.autocomplete = false;
form.fields.generator.keyup = function() {
var value = $('#popup input[name="generator"]').val();
var generator, generators = [];
for (var generator_name in autocode.data.generators) {
generator = autocode.data.generators[generator_name];
if (generator_name.match(new RegExp(value, 'i'))) {
generators.push({
icon: 'https://cdn.rawgit.com/crystal/' + generator_name.split('.')[0] + '/master/.autocode/icon.svg',
state: 'outputs/add/generator?name=' + generator_name,
text: generator_name
});
}
}
autocode.fuzzy.open({
rows: generators,
target: $('#popup input[name="generator"]'),
value: value
});
$('#popup input[name="filename"]').attr('placeholder', autocode.data.generators[value] && autocode.data.generators[value].filename ? autocode.data.generators[value].filename : '');
};
autocode.popup.open({
title: 'Add Output',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
// validate generator
if (!autocode.data.generators[data.generator]) {
autocode.popup.error('Generator does not exist.');
return false;
}
// normalize filename
if (!data.filename) {
data.filename = autocode.data.generators[data.generator].filename;
}
// validate filename
var output;
for (var output_i in autocode.project.outputs) {
output = autocode.project.outputs[output_i];
if (
(output.filename && output.filename == data.filename)
||
(!output.filename && autocode.data.generators[output.generator].filename == data.filename)
) {
autocode.popup.error('Filename must be unique.');
return false;
}
}
if (data.filename == autocode.data.generators[data.generator].filename) {
delete(data.filename);
}
if (!autocode.project.outputs) {
autocode.project.outputs = [];
}
autocode.project.outputs.push(data);
$('#popup, #overlay').fadeOut(function() {
autocode.popup.close();
});
autocode.state['outputs']();
return false;
}
});
};;autocode.action.addProperty = function() {
new formulator({
formula: 'formulas/forms/AddProperty.json',
xhr: true,
ready: function(form) {
form.fields.property.autocomplete = false;
form.fields.property.keyup = function() {
var value = $('#popup input[name="property"]').val();
var property, properties = [];
for (var property_name in autocode.object.sort(autocode.data.generators[autocode.data.current.generator].schema.properties)) {
property = autocode.data.generators[autocode.data.current.generator].schema.properties[property_name];
if (property_name.match(new RegExp(value, 'i'))) {
properties.push({
state: 'outputs/property/add/choose?name=' + property_name,
text: property_name
});
}
}
autocode.fuzzy.open({
rows: properties,
target: $('#popup input[name="property"]'),
value: value
});
};
autocode.popup.open({
title: 'Add Property',
content: form.toString()
});
},
submit: function() {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
// validate name
if (!autocode.data.generators[autocode.data.current.generator].schema.properties[data.property]) {
autocode.popup.error('Property does not exist.');
return false;
}
// validate value
if (autocode.data.generators[autocode.data.current.generator].schema.properties[data.property].type == 'boolean' && data.value != 'true' && data.value != 'false') {
autocode.popup.error('Value must be a boolean.');
return false;
} else if (autocode.data.generators[autocode.data.current.generator].schema.properties[data.property].type == 'number' && !data.value.match(/^\d+$/)) {
autocode.popup.error('Value must be a number.');
return false;
}
if (autocode.data.generators[autocode.data.current.generator].schema.properties[data.property].type == 'boolean') {
if (data.value == 'true') {
data.value = true;
} else {
data.value = false;
}
}
if (!autocode.project.outputs[autocode.data.current.output].spec) {
autocode.project.outputs[autocode.data.current.output].spec = {};
}
autocode.project.outputs[autocode.data.current.output].spec[data.property] = data.value;
autocode.popup.close();
autocode.state['outputs/output']({ output: autocode.data.current.output });
return false;
}
});
};;autocode.action.addScript = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
formula: 'formulas/forms/AddScript.json',
xhr: true,
ready: function(form) {
form.fields.script.autocomplete = false;
form.fields.script.keyup = function() {
var rows = [], script_name, scripts = ['build','run','stop'];
for (var i in scripts) {
script_name = scripts[i];
if (script_name.match(new RegExp(value, 'i'))) {
rows.push({
action: {
name: 'addScriptName',
data: { name: script_name }
},
icon: script_name + '-icon black',
text: script_name
});
}
}
autocode.fuzzy.open({
rows: rows,
target: $('#popup input[name="script"]'),
value: value
});
};
autocode.popup.open({
title: 'Add Script',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
// validate script
if (['build','run','stop'].indexOf(data.script) === -1) {
autocode.popup.error('Script does not exist.');
return false;
}
if (!autocode.project.scripts) {
autocode.project.scripts = {};
}
autocode.project.scripts[data.script] = [];
$('#popup, #overlay').fadeOut(function() {
autocode.popup.close();
});
autocode.state['scripts']();
return false;
}
});
};;autocode.action.addScriptName = function(opts) {
$('#popup input[name="script"]').val(opts.name);
autocode.fuzzy.close();
};;autocode.action.build = function() {
if (autocode.data.current.tab == 'config') {
var config = $('#config-content .CodeMirror')[0].CodeMirror.getValue();
autocode.project = jsyaml.safeLoad(config);
autocode.storage.set('config', config)
}
if (!autocode.project.outputs || !autocode.project.imports) {
if (!autocode.project.imports) {
autocode.popup.open({
title: 'Unable to Build Project',
content: '<div style="padding-bottom: 10px">You haven\'t imported any modules yet.</div>'
+ '<a class="button" href="imports">Import a Module</a> <button class="secondary" onclick="autocode.action.closePopup()">Cancel</button>'
});
} else {
autocode.popup.open({
title: 'Unable to Build Project',
content: '<div style="padding-bottom: 10px">You haven\'t added any outputs to your Autocode configuration.</div>'
+ '<a class="button" href="config">Add an Output</a> <button class="secondary" onclick="autocode.action.closePopup()">Cancel</button>'
});
}
return;
}
$('span span.icon.loader-icon').addClass('loading');
autocode.ws.io.emit('build', {
config: autocode.project,
project: autocode.repo.split('/')[1],
user: autocode.repo.split('/')[0]
});
};;autocode.action.clearConsole = function() {
$('#console .content').text('');
};;autocode.action.closePopup = function() {
autocode.popup.close();
};;autocode.action.closeProject = function(opts) {
opts = opts || {};
autocode.popover.close();
if (opts.confirm !== true && autocode.data.originalConfig != jsyaml.safeDump(autocode.project)) {
autocode.popup.open({
title: 'Close Project',
content: '<div style="padding-bottom: 15px">Are you sure you want to close this project? <b>You will lose all unsaved changes.</b></div>'
+ '<button onclick="autocode.action.closePopup()">No, Keep It Open</button> <button class="secondary" onclick="autocode.action.closeProject({ confirm: true })">Yes, Close Project</button> <button class="secondary" onclick="autocode.action.diff()">View Unsaved Changes</button>'
});
return;
}
autocode.unload.disable();
autocode.data.current = {};
delete(autocode.project);
autocode.popup.close();
$('#menu-project').hide();
$('.app, #init').fadeOut(function() {
$('#menu .text').text('Menu');
$('#welcome').fadeIn();
});
};;autocode.action.diff = function() {
autocode.popup.open({
title: 'Review Changes',
content: '<div class="diff"></div><a class="button" href="project/save">Save Project</a> <button class="secondary" onclick="autocode.action.closePopup()">Close</button>'
});
CodeMirror.MergeView($('#popup .diff')[0], {
value: jsyaml.safeDump(autocode.project),
orig: autocode.data.originalConfig,
lineNumbers: true,
mode: 'yaml',
readOnly: true,
revertButtons: false
});
autocode.resize.popup();
};;autocode.action.editAuthorEmail = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
email: autocode.project.author.email
},
formula: 'formulas/forms/Email.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Author Email',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.email && data.email.length) {
if (!autocode.project.author) {
autocode.project.author = {};
}
autocode.project.author.email = data.email;
} else {
delete(autocode.project.author.email);
}
autocode.popup.close();
autocode.state['overview/author']();
return false;
}
});
};;autocode.action.editAuthorName = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
name: autocode.project.author.name
},
formula: 'formulas/forms/Name.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Author Name',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.name && data.name.length) {
if (!autocode.project.author) {
autocode.project.author = {};
}
autocode.project.author.name = data.name;
} else {
delete(autocode.project.author.name);
}
autocode.popup.close();
autocode.state['overview/author']();
return false;
}
});
};;autocode.action.editAuthorURL = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
url: autocode.project.author.url
},
formula: 'formulas/forms/URL.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Author URL',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.url && data.url.length) {
if (!autocode.project.author) {
autocode.project.author = {};
}
autocode.project.author.url = data.url;
} else {
delete(autocode.project.author.url);
}
autocode.popup.close();
autocode.state['overview/author']();
return false;
}
});
};;autocode.action.editDescription = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: autocode.project,
formula: 'formulas/forms/Description.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Project Description',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.description && data.description.length) {
autocode.project.description = data.description;
} else {
delete(autocode.project.description);
}
autocode.popup.close();
autocode.state['overview/general']();
return false;
}
});
};;autocode.action.editImportName = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
name: autocode.data.current.import
},
formula: 'formulas/forms/Name.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Import Name',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.name != autocode.data.current.import) {
autocode.project.imports[data.name] = autocode.object.clone(autocode.project.imports[autocode.data.current.import]);
delete(autocode.project.imports[autocode.data.current.import]);
}
autocode.popup.close();
autocode.state['imports']({ disableSelected: true });
autocode.action.loadImport({ repo: data.name });
return false;
}
});
};;autocode.action.editImportVersion = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
version: autocode.project.imports[autocode.data.current.import]
},
formula: 'formulas/forms/Version.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Import Name',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (!data.version || !data.version.length) {
return autocode.popup.error('Version is required.');
}
autocode.project.imports[autocode.data.current.import] = data.version;
autocode.popup.close();
autocode.state['imports']({ disableSelected: true });
autocode.action.loadImport({ repo: autocode.data.current.import });
return false;
}
});
};;autocode.action.editName = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: autocode.project,
formula: 'formulas/forms/Name.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Project Name',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.name && data.name.length) {
autocode.project.name = data.name;
} else {
delete(autocode.project.name);
}
autocode.popup.close();
autocode.state['overview/general']();
return false;
}
});
};;autocode.action.editProjectCopyright = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: {
copyright: autocode.project.copyright
},
formula: 'formulas/forms/Copyright.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Project Copyright',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.copyright && data.copyright.length) {
autocode.project.copyright = data.copyright;
} else {
delete(autocode.project.copyright);
}
autocode.popup.close();
autocode.state['overview/general']();
return false;
}
});
};;autocode.action.editURL = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: autocode.project,
formula: 'formulas/forms/URL.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Project URL',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.url && data.url.length) {
autocode.project.url = data.url;
} else {
delete(autocode.project.url);
}
autocode.popup.close();
autocode.state['overview/general']();
return false;
}
});
};;autocode.action.editVersion = function() {
autocode.popup.open({
title: 'Loading...'
});
autocode.popover.close();
new formulator({
data: autocode.project,
formula: 'formulas/forms/Version.json',
xhr: true,
ready: function(form) {
autocode.popup.open({
title: 'Edit Project Version',
content: form.toString()
});
},
submit: function(data) {
var data = {};
$('#popup input, #popup select, #popup textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
if (data.version && data.version.length) {
autocode.project.version = data.version;
} else {
delete(autocode.project.version);
}
autocode.popup.close();
autocode.state['overview/general']();
return false;
}
});
};;autocode.action.generate = function() {
if (!autocode.project.outputs || !autocode.project.imports) {
if (!autocode.project.imports) {
autocode.popup.open({
title: 'Unable to Generate Project',
content: '<div style="paddi