', {
'class': 'remove',
'title': Messages.poll_removeOptionTitle,
}).text('✖').click(function () {
var msg = Messages.poll_removeOption;
Cryptpad.confirm(msg, function (yes) {
if (!yes) { return; }
removeRow(proxy, id);
table.removeRow(id);
});
});
if (readOnly) {
$edit = '';
$remove = '';
}
var $wrapper = $('', {
'class': 'text-cell',
})
.append($edit)
.append($option)
.append($remove);
proxy.table.rows[id] = value || "";
addIfAbsent(proxy.table.rowsOrder, id);
var $row = table.addRow($wrapper, Checkbox, id);
if (module.ready) {
scrollDown($row.height());
}
return $option;
};
$('#adduser').click(function () {
if (!module.isEditable) { return; }
var id = coluid();
var msg = Messages.poll_addUser;
Cryptpad.prompt(msg, "", function (name) {
if (name === null) { return; }
makeUser(module.rt.proxy, id, name).val(name);
makeUserEditable(id, true).focus();
});
});
$('#addoption').click(function () {
if (!module.isEditable) { return; }
var id = rowuid();
var msg = Messages.poll_addOption;
Cryptpad.prompt(msg, "", function (option) {
if (option === null || !option) { return; }
makeOption(module.rt.proxy, id, option).val(option).focus();
});
//makeOption(module.rt.proxy, id).focus();
});
Wizard.$getOptions.click(function () {
Cryptpad.confirm(Messages.wizardConfirm, function (yes) {
if (!yes) { return; }
var options = Wizard.computeSlots(function (a, b) {
return a + ' ('+ b + ')';
});
var proxy = module.rt.proxy;
options.forEach(function (text) {
var id = rowuid();
makeOption(proxy, id, text).val(text);
});
Wizard.hide();
});
});
// notifications
var unnotify = function () {
if (!(module.tabNotification &&
typeof(module.tabNotification.cancel) === 'function')) { return; }
module.tabNotification.cancel();
};
var notify = function () {
if (!(Visible.isSupported() && !Visible.currently())) { return; }
unnotify();
module.tabNotification = Notify.tab(1000, 10);
};
var updateTitle = function (newTitle) {
if (newTitle === document.title) { return; }
// Change the title now, and set it back to the old value if there is an error
var oldTitle = document.title;
document.title = newTitle;
Cryptpad.setPadTitle(newTitle, function (err, data) {
if (err) {
console.log("Couldn't set pad title");
console.error(err);
document.title = oldTitle;
return;
}
});
};
// don't make changes until the interface is ready
setEditable(false);
var ready = function (info) {
module.users = info.userList.users;
console.log("Your realtime object is ready");
module.ready = true;
var proxy = module.rt.proxy;
var First = false;
if (proxy.metadata && proxy.metadata.title) {
updateTitle(proxy.metadata.title);
}
// ensure that proxy.info and proxy.table exist
['info', 'table'].forEach(function (k) {
if (typeof(proxy[k]) === 'undefined') {
// you seem to be the first person to have visited this pad...
First = true;
proxy[k] = {};
}
});
// table{cols,rows,cells}
['cols', 'rows', 'cells'].forEach(function (k) {
if (typeof(proxy.table[k]) === 'undefined') { proxy.table[k] = {}; }
});
// table{rowsOrder,colsOrder}
['rows', 'cols'].forEach(function (k) {
var K = k + 'Order';
if (typeof(proxy.table[K]) === 'undefined') {
//console.log("Creating %s", K);
proxy.table[K] = [];
Object.keys(proxy.table[k]).forEach(function (uid) {
addIfAbsent(proxy.table[K], uid);
});
}
});
// HERE TODO make this idempotent so you can call it again
// cols
proxy.table.colsOrder.forEach(function (uid) {
var val = proxy.table.cols[uid];
makeUser(proxy, uid, val).val(val);
});
// rows
proxy.table.rowsOrder.forEach(function (uid) {
var val = proxy.table.rows[uid];
makeOption(proxy, uid, val).val(val);
});
// cells
Object.keys(proxy.table.cells).forEach(function (uid) {
//var p = parseXY(uid);
var box = document.getElementById(uid);
if (!box) {
console.log("Couldn't find an element with uid [%s]", uid);
return;
}
var checked = box.checked = proxy.table.cells[uid] ? true : false;
if (checked) {
$(box).closest('.checkbox-contain').find('.cover').addClass('yes');
}
});
items.forEach(function ($item) {
var id = $item.attr('id');
$item.on('change keyup', function () {
var val = $item.val();
proxy.info[id] = val;
});
if (typeof(proxy.info[id]) !== 'undefined') {
$item.val(proxy.info[id]);
}
});
// listen for visibility changes
if (Visible.isSupported()) {
Visible.onChange(function (yes) {
if (yes) { unnotify(); }
});
}
proxy
.on('change', [], function () {
notify();
})
.on('change', ['info'], function (o, n, p) {
var $target = $('#' + p[1]);
var el = $target[0];
var selects;
var op;
if (el && ['textarea', 'text'].indexOf(el.type) !== -1) {
op = TextPatcher.diff(o, n);
selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
var before = el[attr];
var after = TextPatcher.transformCursor(el[attr], op);
return after;
});
$target.val(n);
if (op) {
el.selectionStart = selects[0];
el.selectionEnd = selects[1];
}
}
console.log("change: (%s, %s, [%s])", o, n, p.join(', '));
})
.on('change', ['table'], function (o, n, p) {
var id = p[p.length -1];
var type = p[1];
if (typeof(o) === 'undefined' &&
['cols', 'rows', 'cells'].indexOf(type) !== -1) {
switch (type) {
case 'cols':
makeUser(proxy, id, n);
break;
case 'rows':
makeOption(proxy, id, n);
break;
case 'cells':
//
break;
default:
console.log("Unhandled table element creation");
break;
}
}
var el = document.getElementById(id);
if (!el) {
console.log("Couldn't find the element you wanted!");
return;
}
switch (p[1]) {
case 'cols':
console.log("[Table.cols change] %s (%s => %s)@[%s]", id, o, n, p.slice(0, -1).join(', '));
el.value = n;
break;
case 'rows':
console.log("[Table.rows change] %s (%s => %s)@[%s]", id, o, n, p.slice(0, -1).join(', '));
el.value = n;
break;
case 'cells':
console.log("[Table.cell change] %s (%s => %s)@[%s]", id, o, n, p.slice(0, -1).join(', '));
var checked = el.checked = proxy.table.cells[id] ? true: false;
var $parent = $(el).closest('.checkbox-contain');
if (!$parent.length) { console.log("couldn't find parent element of checkbox"); return; }
if (checked) {
$parent.find('.cover').addClass('yes');
} else {
$parent.find('.cover').removeClass('yes');
}
break;
default:
console.log("[Table change] (%s => %s)@[%s]", o, n, p.join(', '));
break;
}
})
.on('change', ['metadata'], function (o, n, p) {
var newTitle = proxy.metadata.title;
updateTitle(newTitle);
})
.on('remove', [], function (o, p, root) {
//console.log("remove: (%s, [%s])", o, p.join(', '));
//console.log(p, o, p.length);
switch (p[1]) {
case 'cols':
console.log("[Table.cols removal] [%s]", p[2]);
table.removeColumn(p[2]);
return false;
case 'rows':
console.log("[Table.rows removal] [%s]", p[2]);
table.removeRow(p[2]);
return false;
case 'rowsOrder':
Object.keys(proxy.table.rows)
.forEach(function (rowId) {
if (proxy.table.rowsOrder.indexOf(rowId) === -1) {
proxy.table.rows[rowId] = undefined;
delete proxy.table.rows[rowId];
}
});
break;
case 'colsOrder':
Object.keys(proxy.table.cols)
.forEach(function (colId) {
if (proxy.table.colsOrder.indexOf(colId) === -1) {
proxy.table.cols[colId] = undefined;
delete proxy.table.cols[colId];
}
});
break;
case 'cells':
// cool story bro
break;
default:
console.log("[Table removal] [%s]", p.join(', '));
break;
}
})
.on('disconnect', function (info) {
setEditable(false);
});
var $toolbar = $('#toolbar');
var Button = function (opt) {
return $('