mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
lint: Put opening brace on same line as function
Normally I would let `eslint --fix` do this for me, but there's a bug that causes: const x = function () { // ... }; to become: const x = () => { // ... }; which ESLint thinks is a syntax error. (It probably is; I don't know enough about the automatic semicolon insertion rules to be confident.)
This commit is contained in:
parent
cc988bd67b
commit
7df3ded66f
66 changed files with 1036 additions and 2072 deletions
|
@ -59,11 +59,9 @@ npm.load({}, async function() {
|
||||||
var atext = Changeset.makeAText("\n")
|
var atext = Changeset.makeAText("\n")
|
||||||
|
|
||||||
//run trough all revisions
|
//run trough all revisions
|
||||||
async.forEachSeries(revisions, function(revNum, callback)
|
async.forEachSeries(revisions, function(revNum, callback) {
|
||||||
{
|
|
||||||
//console.log('Fetching', revNum)
|
//console.log('Fetching', revNum)
|
||||||
db.db.get("pad:"+padId+":revs:" + revNum, function(err, revision)
|
db.db.get("pad:"+padId+":revs:" + revNum, function(err, revision) {
|
||||||
{
|
|
||||||
if(err) return callback(err);
|
if(err) return callback(err);
|
||||||
|
|
||||||
//check if there is a atext in the keyRevisions
|
//check if there is a atext in the keyRevisions
|
||||||
|
|
|
@ -49,25 +49,20 @@ var padIDs;
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
//get all padids out of the database...
|
//get all padids out of the database...
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
log("get all padIds out of the database...");
|
log("get all padIds out of the database...");
|
||||||
|
|
||||||
etherpadDB.query("SELECT ID FROM PAD_META", [], function(err, _padIDs)
|
etherpadDB.query("SELECT ID FROM PAD_META", [], function(err, _padIDs) {
|
||||||
{
|
|
||||||
padIDs = _padIDs;
|
padIDs = _padIDs;
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
log("done");
|
log("done");
|
||||||
|
|
||||||
//create a queue with a concurrency 100
|
//create a queue with a concurrency 100
|
||||||
var queue = async.queue(function (padId, callback)
|
var queue = async.queue(function (padId, callback) {
|
||||||
{
|
convertPad(padId, function(err) {
|
||||||
convertPad(padId, function(err)
|
|
||||||
{
|
|
||||||
incrementPadStats();
|
incrementPadStats();
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
|
@ -82,8 +77,7 @@ async.series([
|
||||||
queue.push(padIDs[i].ID);
|
queue.push(padIDs[i].ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
], function(err)
|
], function(err) {
|
||||||
{
|
|
||||||
if(err) throw err;
|
if(err) throw err;
|
||||||
|
|
||||||
//write the groups
|
//write the groups
|
||||||
|
@ -108,15 +102,13 @@ async.series([
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
function log(str)
|
function log(str) {
|
||||||
{
|
|
||||||
console.log((Date.now() - startTime)/1000 + "\t" + str);
|
console.log((Date.now() - startTime)/1000 + "\t" + str);
|
||||||
}
|
}
|
||||||
|
|
||||||
var padsDone = 0;
|
var padsDone = 0;
|
||||||
|
|
||||||
function incrementPadStats()
|
function incrementPadStats() {
|
||||||
{
|
|
||||||
padsDone++;
|
padsDone++;
|
||||||
|
|
||||||
if(padsDone%100 == 0)
|
if(padsDone%100 == 0)
|
||||||
|
@ -130,8 +122,7 @@ var proID2groupID = {};
|
||||||
var proID2subdomain = {};
|
var proID2subdomain = {};
|
||||||
var groups = {};
|
var groups = {};
|
||||||
|
|
||||||
function convertPad(padId, callback)
|
function convertPad(padId, callback) {
|
||||||
{
|
|
||||||
var changesets = [];
|
var changesets = [];
|
||||||
var changesetsMeta = [];
|
var changesetsMeta = [];
|
||||||
var chatMessages = [];
|
var chatMessages = [];
|
||||||
|
@ -142,16 +133,13 @@ function convertPad(padId, callback)
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
//get all needed db values
|
//get all needed db values
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
async.parallel([
|
async.parallel([
|
||||||
//get the pad revisions
|
//get the pad revisions
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT * FROM `PAD_CHAT_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_CHAT_META` WHERE ID=?)";
|
var sql = "SELECT * FROM `PAD_CHAT_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_CHAT_META` WHERE ID=?)";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -168,12 +156,10 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the chat entries
|
//get the chat entries
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT * FROM `PAD_REVS_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_REVS_META` WHERE ID=?)";
|
var sql = "SELECT * FROM `PAD_REVS_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_REVS_META` WHERE ID=?)";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -190,12 +176,10 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the pad revisions meta data
|
//get the pad revisions meta data
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT * FROM `PAD_REVMETA_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_REVMETA_META` WHERE ID=?)";
|
var sql = "SELECT * FROM `PAD_REVMETA_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_REVMETA_META` WHERE ID=?)";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -212,12 +196,10 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the attribute pool of this pad
|
//get the attribute pool of this pad
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT `JSON` FROM `PAD_APOOL` WHERE `ID` = ?";
|
var sql = "SELECT `JSON` FROM `PAD_APOOL` WHERE `ID` = ?";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -230,12 +212,10 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the authors informations
|
//get the authors informations
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT * FROM `PAD_AUTHORS_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_AUTHORS_META` WHERE ID=?)";
|
var sql = "SELECT * FROM `PAD_AUTHORS_TEXT` WHERE NUMID = (SELECT `NUMID` FROM `PAD_AUTHORS_META` WHERE ID=?)";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -252,12 +232,10 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the pad information
|
//get the pad information
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
var sql = "SELECT JSON FROM `PAD_META` WHERE ID=?";
|
var sql = "SELECT JSON FROM `PAD_META` WHERE ID=?";
|
||||||
|
|
||||||
etherpadDB.query(sql, [padId], function(err, results)
|
etherpadDB.query(sql, [padId], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -270,8 +248,7 @@ function convertPad(padId, callback)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//get the subdomain
|
//get the subdomain
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
//skip if this is no proPad
|
//skip if this is no proPad
|
||||||
if(padId.indexOf("$") == -1)
|
if(padId.indexOf("$") == -1)
|
||||||
{
|
{
|
||||||
|
@ -284,8 +261,7 @@ function convertPad(padId, callback)
|
||||||
|
|
||||||
var sql = "SELECT subDomain FROM pro_domains WHERE ID = ?";
|
var sql = "SELECT subDomain FROM pro_domains WHERE ID = ?";
|
||||||
|
|
||||||
etherpadDB.query(sql, [proID], function(err, results)
|
etherpadDB.query(sql, [proID], function(err, results) {
|
||||||
{
|
|
||||||
if(!err)
|
if(!err)
|
||||||
{
|
{
|
||||||
subdomain = results[0].subDomain;
|
subdomain = results[0].subDomain;
|
||||||
|
@ -296,8 +272,7 @@ function convertPad(padId, callback)
|
||||||
}
|
}
|
||||||
], callback);
|
], callback);
|
||||||
},
|
},
|
||||||
function(callback)
|
function(callback) {
|
||||||
{
|
|
||||||
//saves all values that should be written to the database
|
//saves all values that should be written to the database
|
||||||
var values = {};
|
var values = {};
|
||||||
|
|
||||||
|
@ -425,8 +400,7 @@ function convertPad(padId, callback)
|
||||||
* The offsets describes the length of a unit in the page, the data are
|
* The offsets describes the length of a unit in the page, the data are
|
||||||
* all values behind each other
|
* all values behind each other
|
||||||
*/
|
*/
|
||||||
function parsePage(array, pageStart, offsets, data, json)
|
function parsePage(array, pageStart, offsets, data, json) {
|
||||||
{
|
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var lengths = offsets.split(",");
|
var lengths = offsets.split(",");
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,7 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log("initializing db");
|
log("initializing db");
|
||||||
db.init(function(err)
|
db.init(function(err) {
|
||||||
{
|
|
||||||
//there was an error while initializing the database, output it and stop
|
//there was an error while initializing the database, output it and stop
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
|
@ -71,8 +70,7 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function log(str)
|
function log(str) {
|
||||||
{
|
|
||||||
console.log((Date.now() - startTime)/1000 + "\t" + str);
|
console.log((Date.now() - startTime)/1000 + "\t" + str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,7 @@ Example returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
exports.getAttributePool = async function(padID)
|
exports.getAttributePool = async function(padID) {
|
||||||
{
|
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
return { pool: pad.pool };
|
return { pool: pad.pool };
|
||||||
}
|
}
|
||||||
|
@ -120,8 +119,7 @@ Example returns:
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
exports.getRevisionChangeset = async function(padID, rev)
|
exports.getRevisionChangeset = async function(padID, rev) {
|
||||||
{
|
|
||||||
// try to parse the revision number
|
// try to parse the revision number
|
||||||
if (rev !== undefined) {
|
if (rev !== undefined) {
|
||||||
rev = checkValidRev(rev);
|
rev = checkValidRev(rev);
|
||||||
|
@ -155,8 +153,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {text:"Welcome Text"}}
|
{code: 0, message:"ok", data: {text:"Welcome Text"}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getText = async function(padID, rev)
|
exports.getText = async function(padID, rev) {
|
||||||
{
|
|
||||||
// try to parse the revision number
|
// try to parse the revision number
|
||||||
if (rev !== undefined) {
|
if (rev !== undefined) {
|
||||||
rev = checkValidRev(rev);
|
rev = checkValidRev(rev);
|
||||||
|
@ -193,8 +190,7 @@ Example returns:
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
{code: 1, message:"text too long", data: null}
|
{code: 1, message:"text too long", data: null}
|
||||||
*/
|
*/
|
||||||
exports.setText = async function(padID, text)
|
exports.setText = async function(padID, text) {
|
||||||
{
|
|
||||||
// text is required
|
// text is required
|
||||||
if (typeof text !== "string") {
|
if (typeof text !== "string") {
|
||||||
throw new customError("text is not a string", "apierror");
|
throw new customError("text is not a string", "apierror");
|
||||||
|
@ -218,8 +214,7 @@ Example returns:
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
{code: 1, message:"text too long", data: null}
|
{code: 1, message:"text too long", data: null}
|
||||||
*/
|
*/
|
||||||
exports.appendText = async function(padID, text)
|
exports.appendText = async function(padID, text) {
|
||||||
{
|
|
||||||
// text is required
|
// text is required
|
||||||
if (typeof text !== "string") {
|
if (typeof text !== "string") {
|
||||||
throw new customError("text is not a string", "apierror");
|
throw new customError("text is not a string", "apierror");
|
||||||
|
@ -240,8 +235,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {text:"Welcome <strong>Text</strong>"}}
|
{code: 0, message:"ok", data: {text:"Welcome <strong>Text</strong>"}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getHTML = async function(padID, rev)
|
exports.getHTML = async function(padID, rev) {
|
||||||
{
|
|
||||||
if (rev !== undefined) {
|
if (rev !== undefined) {
|
||||||
rev = checkValidRev(rev);
|
rev = checkValidRev(rev);
|
||||||
}
|
}
|
||||||
|
@ -273,8 +267,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.setHTML = async function(padID, html)
|
exports.setHTML = async function(padID, html) {
|
||||||
{
|
|
||||||
// html string is required
|
// html string is required
|
||||||
if (typeof html !== "string") {
|
if (typeof html !== "string") {
|
||||||
throw new customError("html is not a string", "apierror");
|
throw new customError("html is not a string", "apierror");
|
||||||
|
@ -310,8 +303,7 @@ Example returns:
|
||||||
|
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getChatHistory = async function(padID, start, end)
|
exports.getChatHistory = async function(padID, start, end) {
|
||||||
{
|
|
||||||
if (start && end) {
|
if (start && end) {
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
throw new customError("start is below zero", "apierror");
|
throw new customError("start is below zero", "apierror");
|
||||||
|
@ -356,8 +348,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.appendChatMessage = async function(padID, text, authorID, time)
|
exports.appendChatMessage = async function(padID, text, authorID, time) {
|
||||||
{
|
|
||||||
// text is required
|
// text is required
|
||||||
if (typeof text !== "string") {
|
if (typeof text !== "string") {
|
||||||
throw new customError("text is not a string", "apierror");
|
throw new customError("text is not a string", "apierror");
|
||||||
|
@ -386,8 +377,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {revisions: 56}}
|
{code: 0, message:"ok", data: {revisions: 56}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getRevisionsCount = async function(padID)
|
exports.getRevisionsCount = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
return { revisions: pad.getHeadRevisionNumber() };
|
return { revisions: pad.getHeadRevisionNumber() };
|
||||||
|
@ -401,8 +391,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {savedRevisions: 42}}
|
{code: 0, message:"ok", data: {savedRevisions: 42}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getSavedRevisionsCount = async function(padID)
|
exports.getSavedRevisionsCount = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
return { savedRevisions: pad.getSavedRevisionsNumber() };
|
return { savedRevisions: pad.getSavedRevisionsNumber() };
|
||||||
|
@ -416,8 +405,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}}
|
{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.listSavedRevisions = async function(padID)
|
exports.listSavedRevisions = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
return { savedRevisions: pad.getSavedRevisionsList() };
|
return { savedRevisions: pad.getSavedRevisionsList() };
|
||||||
|
@ -431,8 +419,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.saveRevision = async function(padID, rev)
|
exports.saveRevision = async function(padID, rev) {
|
||||||
{
|
|
||||||
// check if rev is a number
|
// check if rev is a number
|
||||||
if (rev !== undefined) {
|
if (rev !== undefined) {
|
||||||
rev = checkValidRev(rev);
|
rev = checkValidRev(rev);
|
||||||
|
@ -463,8 +450,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {lastEdited: 1340815946602}}
|
{code: 0, message:"ok", data: {lastEdited: 1340815946602}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getLastEdited = async function(padID)
|
exports.getLastEdited = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
let lastEdited = await pad.getLastEdit();
|
let lastEdited = await pad.getLastEdit();
|
||||||
|
@ -479,8 +465,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"pad does already exist", data: null}
|
{code: 1, message:"pad does already exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.createPad = async function(padID, text)
|
exports.createPad = async function(padID, text) {
|
||||||
{
|
|
||||||
if (padID) {
|
if (padID) {
|
||||||
// ensure there is no $ in the padID
|
// ensure there is no $ in the padID
|
||||||
if (padID.indexOf("$") !== -1) {
|
if (padID.indexOf("$") !== -1) {
|
||||||
|
@ -505,8 +490,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.deletePad = async function(padID)
|
exports.deletePad = async function(padID) {
|
||||||
{
|
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
await pad.remove();
|
await pad.remove();
|
||||||
}
|
}
|
||||||
|
@ -519,8 +503,7 @@ exports.deletePad = async function(padID)
|
||||||
{code:0, message:"ok", data:null}
|
{code:0, message:"ok", data:null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.restoreRevision = async function(padID, rev)
|
exports.restoreRevision = async function(padID, rev) {
|
||||||
{
|
|
||||||
// check if rev is a number
|
// check if rev is a number
|
||||||
if (rev === undefined) {
|
if (rev === undefined) {
|
||||||
throw new customError("rev is not defined", "apierror");
|
throw new customError("rev is not defined", "apierror");
|
||||||
|
@ -588,8 +571,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {padID: destinationID}}
|
{code: 0, message:"ok", data: {padID: destinationID}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.copyPad = async function(sourceID, destinationID, force)
|
exports.copyPad = async function(sourceID, destinationID, force) {
|
||||||
{
|
|
||||||
let pad = await getPadSafe(sourceID, true);
|
let pad = await getPadSafe(sourceID, true);
|
||||||
await pad.copy(destinationID, force);
|
await pad.copy(destinationID, force);
|
||||||
}
|
}
|
||||||
|
@ -603,8 +585,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {padID: destinationID}}
|
{code: 0, message:"ok", data: {padID: destinationID}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.copyPadWithoutHistory = async function(sourceID, destinationID, force)
|
exports.copyPadWithoutHistory = async function(sourceID, destinationID, force) {
|
||||||
{
|
|
||||||
let pad = await getPadSafe(sourceID, true);
|
let pad = await getPadSafe(sourceID, true);
|
||||||
await pad.copyPadWithoutHistory(destinationID, force);
|
await pad.copyPadWithoutHistory(destinationID, force);
|
||||||
}
|
}
|
||||||
|
@ -618,8 +599,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {padID: destinationID}}
|
{code: 0, message:"ok", data: {padID: destinationID}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.movePad = async function(sourceID, destinationID, force)
|
exports.movePad = async function(sourceID, destinationID, force) {
|
||||||
{
|
|
||||||
let pad = await getPadSafe(sourceID, true);
|
let pad = await getPadSafe(sourceID, true);
|
||||||
await pad.copy(destinationID, force);
|
await pad.copy(destinationID, force);
|
||||||
await pad.remove();
|
await pad.remove();
|
||||||
|
@ -633,8 +613,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getReadOnlyID = async function(padID)
|
exports.getReadOnlyID = async function(padID) {
|
||||||
{
|
|
||||||
// we don't need the pad object, but this function does all the security stuff for us
|
// we don't need the pad object, but this function does all the security stuff for us
|
||||||
await getPadSafe(padID, true);
|
await getPadSafe(padID, true);
|
||||||
|
|
||||||
|
@ -652,8 +631,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {padID: padID}}
|
{code: 0, message:"ok", data: {padID: padID}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getPadID = async function(roID)
|
exports.getPadID = async function(roID) {
|
||||||
{
|
|
||||||
// get the PadId
|
// get the PadId
|
||||||
let padID = await readOnlyManager.getPadId(roID);
|
let padID = await readOnlyManager.getPadId(roID);
|
||||||
if (padID === null) {
|
if (padID === null) {
|
||||||
|
@ -671,8 +649,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: null}
|
{code: 0, message:"ok", data: null}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.setPublicStatus = async function(padID, publicStatus)
|
exports.setPublicStatus = async function(padID, publicStatus) {
|
||||||
{
|
|
||||||
// ensure this is a group pad
|
// ensure this is a group pad
|
||||||
checkGroupPad(padID, "publicStatus");
|
checkGroupPad(padID, "publicStatus");
|
||||||
|
|
||||||
|
@ -695,8 +672,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {publicStatus: true}}
|
{code: 0, message:"ok", data: {publicStatus: true}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getPublicStatus = async function(padID)
|
exports.getPublicStatus = async function(padID) {
|
||||||
{
|
|
||||||
// ensure this is a group pad
|
// ensure this is a group pad
|
||||||
checkGroupPad(padID, "publicStatus");
|
checkGroupPad(padID, "publicStatus");
|
||||||
|
|
||||||
|
@ -713,8 +689,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {authorIDs : ["a.s8oes9dhwrvt0zif", "a.akf8finncvomlqva"]}
|
{code: 0, message:"ok", data: {authorIDs : ["a.s8oes9dhwrvt0zif", "a.akf8finncvomlqva"]}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.listAuthorsOfPad = async function(padID)
|
exports.listAuthorsOfPad = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
let authorIDs = pad.getAllAuthors();
|
let authorIDs = pad.getAllAuthors();
|
||||||
|
@ -757,8 +732,7 @@ Example returns:
|
||||||
{"code":0,"message":"ok","data":null}
|
{"code":0,"message":"ok","data":null}
|
||||||
{"code":4,"message":"no or wrong API Key","data":null}
|
{"code":4,"message":"no or wrong API Key","data":null}
|
||||||
*/
|
*/
|
||||||
exports.checkToken = async function()
|
exports.checkToken = async function() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -769,8 +743,7 @@ Example returns:
|
||||||
{code: 0, message:"ok", data: {chatHead: 42}}
|
{code: 0, message:"ok", data: {chatHead: 42}}
|
||||||
{code: 1, message:"padID does not exist", data: null}
|
{code: 1, message:"padID does not exist", data: null}
|
||||||
*/
|
*/
|
||||||
exports.getChatHead = async function(padID)
|
exports.getChatHead = async function(padID) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await getPadSafe(padID, true);
|
let pad = await getPadSafe(padID, true);
|
||||||
return { chatHead: pad.chatHead };
|
return { chatHead: pad.chatHead };
|
||||||
|
@ -843,14 +816,12 @@ exports.getStats = async function() {
|
||||||
/******************************/
|
/******************************/
|
||||||
|
|
||||||
// checks if a number is an int
|
// checks if a number is an int
|
||||||
function is_int(value)
|
function is_int(value) {
|
||||||
{
|
|
||||||
return (parseFloat(value) == parseInt(value, 10)) && !isNaN(value)
|
return (parseFloat(value) == parseInt(value, 10)) && !isNaN(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets a pad safe
|
// gets a pad safe
|
||||||
async function getPadSafe(padID, shouldExist, text)
|
async function getPadSafe(padID, shouldExist, text) {
|
||||||
{
|
|
||||||
// check if padID is a string
|
// check if padID is a string
|
||||||
if (typeof padID !== "string") {
|
if (typeof padID !== "string") {
|
||||||
throw new customError("padID is not a string", "apierror");
|
throw new customError("padID is not a string", "apierror");
|
||||||
|
@ -880,8 +851,7 @@ async function getPadSafe(padID, shouldExist, text)
|
||||||
|
|
||||||
// checks if a rev is a legal number
|
// checks if a rev is a legal number
|
||||||
// pre-condition is that `rev` is not undefined
|
// pre-condition is that `rev` is not undefined
|
||||||
function checkValidRev(rev)
|
function checkValidRev(rev) {
|
||||||
{
|
|
||||||
if (typeof rev !== "number") {
|
if (typeof rev !== "number") {
|
||||||
rev = parseInt(rev, 10);
|
rev = parseInt(rev, 10);
|
||||||
}
|
}
|
||||||
|
@ -905,8 +875,7 @@ function checkValidRev(rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if a padID is part of a group
|
// checks if a padID is part of a group
|
||||||
function checkGroupPad(padID, field)
|
function checkGroupPad(padID, field) {
|
||||||
{
|
|
||||||
// ensure this is a group pad
|
// ensure this is a group pad
|
||||||
if (padID && padID.indexOf("$") === -1) {
|
if (padID && padID.indexOf("$") === -1) {
|
||||||
throw new customError(`You can only get/set the ${field} of pads that belong to a group`, "apierror");
|
throw new customError(`You can only get/set the ${field} of pads that belong to a group`, "apierror");
|
||||||
|
|
|
@ -38,8 +38,7 @@ exports.getColorPalette = function() {
|
||||||
/**
|
/**
|
||||||
* Checks if the author exists
|
* Checks if the author exists
|
||||||
*/
|
*/
|
||||||
exports.doesAuthorExist = async function(authorID)
|
exports.doesAuthorExist = async function(authorID) {
|
||||||
{
|
|
||||||
let author = await db.get("globalAuthor:" + authorID);
|
let author = await db.get("globalAuthor:" + authorID);
|
||||||
|
|
||||||
return author !== null;
|
return author !== null;
|
||||||
|
@ -52,8 +51,7 @@ exports.doesAuthorExists = exports.doesAuthorExist;
|
||||||
* Returns the AuthorID for a token.
|
* Returns the AuthorID for a token.
|
||||||
* @param {String} token The token
|
* @param {String} token The token
|
||||||
*/
|
*/
|
||||||
exports.getAuthor4Token = async function(token)
|
exports.getAuthor4Token = async function(token) {
|
||||||
{
|
|
||||||
let author = await mapAuthorWithDBKey("token2author", token);
|
let author = await mapAuthorWithDBKey("token2author", token);
|
||||||
|
|
||||||
// return only the sub value authorID
|
// return only the sub value authorID
|
||||||
|
@ -65,8 +63,7 @@ exports.getAuthor4Token = async function(token)
|
||||||
* @param {String} token The mapper
|
* @param {String} token The mapper
|
||||||
* @param {String} name The name of the author (optional)
|
* @param {String} name The name of the author (optional)
|
||||||
*/
|
*/
|
||||||
exports.createAuthorIfNotExistsFor = async function(authorMapper, name)
|
exports.createAuthorIfNotExistsFor = async function(authorMapper, name) {
|
||||||
{
|
|
||||||
let author = await mapAuthorWithDBKey("mapper2author", authorMapper);
|
let author = await mapAuthorWithDBKey("mapper2author", authorMapper);
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -83,8 +80,7 @@ exports.createAuthorIfNotExistsFor = async function(authorMapper, name)
|
||||||
* @param {String} mapperkey The database key name for this mapper
|
* @param {String} mapperkey The database key name for this mapper
|
||||||
* @param {String} mapper The mapper
|
* @param {String} mapper The mapper
|
||||||
*/
|
*/
|
||||||
async function mapAuthorWithDBKey (mapperkey, mapper)
|
async function mapAuthorWithDBKey (mapperkey, mapper) {
|
||||||
{
|
|
||||||
// try to map to an author
|
// try to map to an author
|
||||||
let author = await db.get(mapperkey + ":" + mapper);
|
let author = await db.get(mapperkey + ":" + mapper);
|
||||||
|
|
||||||
|
@ -111,8 +107,7 @@ async function mapAuthorWithDBKey (mapperkey, mapper)
|
||||||
* Internal function that creates the database entry for an author
|
* Internal function that creates the database entry for an author
|
||||||
* @param {String} name The name of the author
|
* @param {String} name The name of the author
|
||||||
*/
|
*/
|
||||||
exports.createAuthor = function(name)
|
exports.createAuthor = function(name) {
|
||||||
{
|
|
||||||
// create the new author name
|
// create the new author name
|
||||||
let author = "a." + randomString(16);
|
let author = "a." + randomString(16);
|
||||||
|
|
||||||
|
@ -134,8 +129,7 @@ exports.createAuthor = function(name)
|
||||||
* Returns the Author Obj of the author
|
* Returns the Author Obj of the author
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
*/
|
*/
|
||||||
exports.getAuthor = function(author)
|
exports.getAuthor = function(author) {
|
||||||
{
|
|
||||||
// NB: result is already a Promise
|
// NB: result is already a Promise
|
||||||
return db.get("globalAuthor:" + author);
|
return db.get("globalAuthor:" + author);
|
||||||
}
|
}
|
||||||
|
@ -144,8 +138,7 @@ exports.getAuthor = function(author)
|
||||||
* Returns the color Id of the author
|
* Returns the color Id of the author
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
*/
|
*/
|
||||||
exports.getAuthorColorId = function(author)
|
exports.getAuthorColorId = function(author) {
|
||||||
{
|
|
||||||
return db.getSub("globalAuthor:" + author, ["colorId"]);
|
return db.getSub("globalAuthor:" + author, ["colorId"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +147,7 @@ exports.getAuthorColorId = function(author)
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
* @param {String} colorId The color id of the author
|
* @param {String} colorId The color id of the author
|
||||||
*/
|
*/
|
||||||
exports.setAuthorColorId = function(author, colorId)
|
exports.setAuthorColorId = function(author, colorId) {
|
||||||
{
|
|
||||||
return db.setSub("globalAuthor:" + author, ["colorId"], colorId);
|
return db.setSub("globalAuthor:" + author, ["colorId"], colorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +155,7 @@ exports.setAuthorColorId = function(author, colorId)
|
||||||
* Returns the name of the author
|
* Returns the name of the author
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
*/
|
*/
|
||||||
exports.getAuthorName = function(author)
|
exports.getAuthorName = function(author) {
|
||||||
{
|
|
||||||
return db.getSub("globalAuthor:" + author, ["name"]);
|
return db.getSub("globalAuthor:" + author, ["name"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,8 +164,7 @@ exports.getAuthorName = function(author)
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
* @param {String} name The name of the author
|
* @param {String} name The name of the author
|
||||||
*/
|
*/
|
||||||
exports.setAuthorName = function(author, name)
|
exports.setAuthorName = function(author, name) {
|
||||||
{
|
|
||||||
return db.setSub("globalAuthor:" + author, ["name"], name);
|
return db.setSub("globalAuthor:" + author, ["name"], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +172,7 @@ exports.setAuthorName = function(author, name)
|
||||||
* Returns an array of all pads this author contributed to
|
* Returns an array of all pads this author contributed to
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
*/
|
*/
|
||||||
exports.listPadsOfAuthor = async function(authorID)
|
exports.listPadsOfAuthor = async function(authorID) {
|
||||||
{
|
|
||||||
/* There are two other places where this array is manipulated:
|
/* There are two other places where this array is manipulated:
|
||||||
* (1) When the author is added to a pad, the author object is also updated
|
* (1) When the author is added to a pad, the author object is also updated
|
||||||
* (2) When a pad is deleted, each author of that pad is also updated
|
* (2) When a pad is deleted, each author of that pad is also updated
|
||||||
|
@ -208,8 +197,7 @@ exports.listPadsOfAuthor = async function(authorID)
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
* @param {String} padID The id of the pad the author contributes to
|
* @param {String} padID The id of the pad the author contributes to
|
||||||
*/
|
*/
|
||||||
exports.addPad = async function(authorID, padID)
|
exports.addPad = async function(authorID, padID) {
|
||||||
{
|
|
||||||
// get the entry
|
// get the entry
|
||||||
let author = await db.get("globalAuthor:" + authorID);
|
let author = await db.get("globalAuthor:" + authorID);
|
||||||
|
|
||||||
|
@ -236,8 +224,7 @@ exports.addPad = async function(authorID, padID)
|
||||||
* @param {String} author The id of the author
|
* @param {String} author The id of the author
|
||||||
* @param {String} padID The id of the pad the author contributes to
|
* @param {String} padID The id of the pad the author contributes to
|
||||||
*/
|
*/
|
||||||
exports.removePad = async function(authorID, padID)
|
exports.removePad = async function(authorID, padID) {
|
||||||
{
|
|
||||||
let author = await db.get("globalAuthor:" + authorID);
|
let author = await db.get("globalAuthor:" + authorID);
|
||||||
|
|
||||||
if (author === null) return;
|
if (author === null) return;
|
||||||
|
|
|
@ -24,8 +24,7 @@ var db = require("./DB");
|
||||||
var padManager = require("./PadManager");
|
var padManager = require("./PadManager");
|
||||||
var sessionManager = require("./SessionManager");
|
var sessionManager = require("./SessionManager");
|
||||||
|
|
||||||
exports.listAllGroups = async function()
|
exports.listAllGroups = async function() {
|
||||||
{
|
|
||||||
let groups = await db.get("groups");
|
let groups = await db.get("groups");
|
||||||
groups = groups || {};
|
groups = groups || {};
|
||||||
|
|
||||||
|
@ -33,8 +32,7 @@ exports.listAllGroups = async function()
|
||||||
return { groupIDs };
|
return { groupIDs };
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.deleteGroup = async function(groupID)
|
exports.deleteGroup = async function(groupID) {
|
||||||
{
|
|
||||||
let group = await db.get("group:" + groupID);
|
let group = await db.get("group:" + groupID);
|
||||||
|
|
||||||
// ensure group exists
|
// ensure group exists
|
||||||
|
@ -82,16 +80,14 @@ exports.deleteGroup = async function(groupID)
|
||||||
await db.set("groups", newGroups);
|
await db.set("groups", newGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.doesGroupExist = async function(groupID)
|
exports.doesGroupExist = async function(groupID) {
|
||||||
{
|
|
||||||
// try to get the group entry
|
// try to get the group entry
|
||||||
let group = await db.get("group:" + groupID);
|
let group = await db.get("group:" + groupID);
|
||||||
|
|
||||||
return (group != null);
|
return (group != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.createGroup = async function()
|
exports.createGroup = async function() {
|
||||||
{
|
|
||||||
// search for non existing groupID
|
// search for non existing groupID
|
||||||
var groupID = "g." + randomString(16);
|
var groupID = "g." + randomString(16);
|
||||||
|
|
||||||
|
@ -111,8 +107,7 @@ exports.createGroup = async function()
|
||||||
return { groupID };
|
return { groupID };
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.createGroupIfNotExistsFor = async function(groupMapper)
|
exports.createGroupIfNotExistsFor = async function(groupMapper) {
|
||||||
{
|
|
||||||
// ensure mapper is optional
|
// ensure mapper is optional
|
||||||
if (typeof groupMapper !== "string") {
|
if (typeof groupMapper !== "string") {
|
||||||
throw new customError("groupMapper is not a string", "apierror");
|
throw new customError("groupMapper is not a string", "apierror");
|
||||||
|
@ -137,8 +132,7 @@ exports.createGroupIfNotExistsFor = async function(groupMapper)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.createGroupPad = async function(groupID, padName, text)
|
exports.createGroupPad = async function(groupID, padName, text) {
|
||||||
{
|
|
||||||
// create the padID
|
// create the padID
|
||||||
let padID = groupID + "$" + padName;
|
let padID = groupID + "$" + padName;
|
||||||
|
|
||||||
|
@ -166,8 +160,7 @@ exports.createGroupPad = async function(groupID, padName, text)
|
||||||
return { padID };
|
return { padID };
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.listPads = async function(groupID)
|
exports.listPads = async function(groupID) {
|
||||||
{
|
|
||||||
let exists = await exports.doesGroupExist(groupID);
|
let exists = await exports.doesGroupExist(groupID);
|
||||||
|
|
||||||
// ensure the group exists
|
// ensure the group exists
|
||||||
|
|
|
@ -109,8 +109,7 @@ let padList = {
|
||||||
* @param id A String with the id of the pad
|
* @param id A String with the id of the pad
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
exports.getPad = async function(id, text)
|
exports.getPad = async function(id, text) {
|
||||||
{
|
|
||||||
// check if this is a valid padId
|
// check if this is a valid padId
|
||||||
if (!exports.isValidPadId(id)) {
|
if (!exports.isValidPadId(id)) {
|
||||||
throw new customError(id + " is not a valid padId", "apierror");
|
throw new customError(id + " is not a valid padId", "apierror");
|
||||||
|
@ -147,16 +146,14 @@ exports.getPad = async function(id, text)
|
||||||
return pad;
|
return pad;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.listAllPads = async function()
|
exports.listAllPads = async function() {
|
||||||
{
|
|
||||||
let padIDs = await padList.getPads();
|
let padIDs = await padList.getPads();
|
||||||
|
|
||||||
return { padIDs };
|
return { padIDs };
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if a pad exists
|
// checks if a pad exists
|
||||||
exports.doesPadExist = async function(padId)
|
exports.doesPadExist = async function(padId) {
|
||||||
{
|
|
||||||
let value = await db.get("pad:" + padId);
|
let value = await db.get("pad:" + padId);
|
||||||
|
|
||||||
return (value != null && value.atext);
|
return (value != null && value.atext);
|
||||||
|
@ -192,8 +189,7 @@ exports.sanitizePadId = async function sanitizePadId(padId) {
|
||||||
return padId;
|
return padId;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.isValidPadId = function(padId)
|
exports.isValidPadId = function(padId) {
|
||||||
{
|
|
||||||
return /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId);
|
return /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +204,6 @@ exports.removePad = async (padId) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes a pad from the cache
|
// removes a pad from the cache
|
||||||
exports.unloadPad = function(padId)
|
exports.unloadPad = function(padId) {
|
||||||
{
|
|
||||||
globalPads.remove(padId);
|
globalPads.remove(padId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,7 @@ var randomString = require("../utils/randomstring");
|
||||||
* checks if the id pattern matches a read-only pad id
|
* checks if the id pattern matches a read-only pad id
|
||||||
* @param {String} the pad's id
|
* @param {String} the pad's id
|
||||||
*/
|
*/
|
||||||
exports.isReadOnlyId = function(id)
|
exports.isReadOnlyId = function(id) {
|
||||||
{
|
|
||||||
return id.indexOf("r.") === 0;
|
return id.indexOf("r.") === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +35,7 @@ exports.isReadOnlyId = function(id)
|
||||||
* returns a read only id for a pad
|
* returns a read only id for a pad
|
||||||
* @param {String} padId the id of the pad
|
* @param {String} padId the id of the pad
|
||||||
*/
|
*/
|
||||||
exports.getReadOnlyId = async function (padId)
|
exports.getReadOnlyId = async function (padId) {
|
||||||
{
|
|
||||||
// check if there is a pad2readonly entry
|
// check if there is a pad2readonly entry
|
||||||
let readOnlyId = await db.get("pad2readonly:" + padId);
|
let readOnlyId = await db.get("pad2readonly:" + padId);
|
||||||
|
|
||||||
|
@ -55,8 +53,7 @@ exports.getReadOnlyId = async function (padId)
|
||||||
* returns the padId for a read only id
|
* returns the padId for a read only id
|
||||||
* @param {String} readOnlyId read only id
|
* @param {String} readOnlyId read only id
|
||||||
*/
|
*/
|
||||||
exports.getPadId = function(readOnlyId)
|
exports.getPadId = function(readOnlyId) {
|
||||||
{
|
|
||||||
return db.get("readonly2pad:" + readOnlyId);
|
return db.get("readonly2pad:" + readOnlyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ const DENY = Object.freeze({accessStatus: 'deny'});
|
||||||
* WARNING: Tokens and session IDs MUST be kept secret, otherwise users will be able to impersonate
|
* WARNING: Tokens and session IDs MUST be kept secret, otherwise users will be able to impersonate
|
||||||
* each other (which might allow them to gain privileges).
|
* each other (which might allow them to gain privileges).
|
||||||
*/
|
*/
|
||||||
exports.checkAccess = async function(padID, sessionCookie, token, userSettings)
|
exports.checkAccess = async function(padID, sessionCookie, token, userSettings) {
|
||||||
{
|
|
||||||
if (!padID) {
|
if (!padID) {
|
||||||
authLogger.debug('access denied: missing padID');
|
authLogger.debug('access denied: missing padID');
|
||||||
return DENY;
|
return DENY;
|
||||||
|
|
|
@ -78,8 +78,7 @@ exports.findAuthorID = async (groupID, sessionCookie) => {
|
||||||
return sessionInfo.authorID;
|
return sessionInfo.authorID;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.doesSessionExist = async function(sessionID)
|
exports.doesSessionExist = async function(sessionID) {
|
||||||
{
|
|
||||||
//check if the database entry of this session exists
|
//check if the database entry of this session exists
|
||||||
let session = await db.get("session:" + sessionID);
|
let session = await db.get("session:" + sessionID);
|
||||||
return (session !== null);
|
return (session !== null);
|
||||||
|
@ -88,8 +87,7 @@ exports.doesSessionExist = async function(sessionID)
|
||||||
/**
|
/**
|
||||||
* Creates a new session between an author and a group
|
* Creates a new session between an author and a group
|
||||||
*/
|
*/
|
||||||
exports.createSession = async function(groupID, authorID, validUntil)
|
exports.createSession = async function(groupID, authorID, validUntil) {
|
||||||
{
|
|
||||||
// check if the group exists
|
// check if the group exists
|
||||||
let groupExists = await groupManager.doesGroupExist(groupID);
|
let groupExists = await groupManager.doesGroupExist(groupID);
|
||||||
if (!groupExists) {
|
if (!groupExists) {
|
||||||
|
@ -172,8 +170,7 @@ exports.createSession = async function(groupID, authorID, validUntil)
|
||||||
return { sessionID };
|
return { sessionID };
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getSessionInfo = async function(sessionID)
|
exports.getSessionInfo = async function(sessionID) {
|
||||||
{
|
|
||||||
// check if the database entry of this session exists
|
// check if the database entry of this session exists
|
||||||
let session = await db.get("session:" + sessionID);
|
let session = await db.get("session:" + sessionID);
|
||||||
|
|
||||||
|
@ -189,8 +186,7 @@ exports.getSessionInfo = async function(sessionID)
|
||||||
/**
|
/**
|
||||||
* Deletes a session
|
* Deletes a session
|
||||||
*/
|
*/
|
||||||
exports.deleteSession = async function(sessionID)
|
exports.deleteSession = async function(sessionID) {
|
||||||
{
|
|
||||||
// ensure that the session exists
|
// ensure that the session exists
|
||||||
let session = await db.get("session:" + sessionID);
|
let session = await db.get("session:" + sessionID);
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
|
@ -221,8 +217,7 @@ exports.deleteSession = async function(sessionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.listSessionsOfGroup = async function(groupID)
|
exports.listSessionsOfGroup = async function(groupID) {
|
||||||
{
|
|
||||||
// check that the group exists
|
// check that the group exists
|
||||||
let exists = await groupManager.doesGroupExist(groupID);
|
let exists = await groupManager.doesGroupExist(groupID);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
|
@ -233,8 +228,7 @@ exports.listSessionsOfGroup = async function(groupID)
|
||||||
return sessions;
|
return sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.listSessionsOfAuthor = async function(authorID)
|
exports.listSessionsOfAuthor = async function(authorID) {
|
||||||
{
|
|
||||||
// check that the author exists
|
// check that the author exists
|
||||||
let exists = await authorManager.doesAuthorExist(authorID)
|
let exists = await authorManager.doesAuthorExist(authorID)
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
|
@ -247,8 +241,7 @@ exports.listSessionsOfAuthor = async function(authorID)
|
||||||
|
|
||||||
// this function is basically the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
// this function is basically the code listSessionsOfAuthor and listSessionsOfGroup has in common
|
||||||
// required to return null rather than an empty object if there are none
|
// required to return null rather than an empty object if there are none
|
||||||
async function listSessionsWithDBKey(dbkey)
|
async function listSessionsWithDBKey(dbkey) {
|
||||||
{
|
|
||||||
// get the group2sessions entry
|
// get the group2sessions entry
|
||||||
let sessionObject = await db.get(dbkey);
|
let sessionObject = await db.get(dbkey);
|
||||||
let sessions = sessionObject ? sessionObject.sessionIDs : null;
|
let sessions = sessionObject ? sessionObject.sessionIDs : null;
|
||||||
|
@ -272,7 +265,6 @@ async function listSessionsWithDBKey(dbkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if a number is an int
|
// checks if a number is an int
|
||||||
function is_int(value)
|
function is_int(value) {
|
||||||
{
|
|
||||||
return (parseFloat(value) == parseInt(value)) && !isNaN(value);
|
return (parseFloat(value) == parseInt(value)) && !isNaN(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,8 +158,7 @@ exports.version = version;
|
||||||
* @req express request object
|
* @req express request object
|
||||||
* @res express response object
|
* @res express response object
|
||||||
*/
|
*/
|
||||||
exports.handle = async function(apiVersion, functionName, fields, req, res)
|
exports.handle = async function(apiVersion, functionName, fields, req, res) {
|
||||||
{
|
|
||||||
// say goodbye if this is an unknown API version
|
// say goodbye if this is an unknown API version
|
||||||
if (!(apiVersion in version)) {
|
if (!(apiVersion in version)) {
|
||||||
throw new createHTTPError.NotFound('no such api version');
|
throw new createHTTPError.NotFound('no such api version');
|
||||||
|
|
|
@ -49,8 +49,7 @@ const tempDirectory = os.tmpdir();
|
||||||
/**
|
/**
|
||||||
* do a requested export
|
* do a requested export
|
||||||
*/
|
*/
|
||||||
async function doExport(req, res, padId, readOnlyId, type)
|
async function doExport(req, res, padId, readOnlyId, type) {
|
||||||
{
|
|
||||||
// avoid naming the read-only file as the original pad's id
|
// avoid naming the read-only file as the original pad's id
|
||||||
var fileName = readOnlyId ? readOnlyId : padId;
|
var fileName = readOnlyId ? readOnlyId : padId;
|
||||||
|
|
||||||
|
@ -131,8 +130,7 @@ async function doExport(req, res, padId, readOnlyId, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.doExport = function(req, res, padId, readOnlyId, type)
|
exports.doExport = function(req, res, padId, readOnlyId, type) {
|
||||||
{
|
|
||||||
doExport(req, res, padId, readOnlyId, type).catch(err => {
|
doExport(req, res, padId, readOnlyId, type).catch(err => {
|
||||||
if (err !== "stop") {
|
if (err !== "stop") {
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
@ -57,8 +57,7 @@ const tmpDirectory = os.tmpdir();
|
||||||
/**
|
/**
|
||||||
* do a requested import
|
* do a requested import
|
||||||
*/
|
*/
|
||||||
async function doImport(req, res, padId)
|
async function doImport(req, res, padId) {
|
||||||
{
|
|
||||||
var apiLogger = log4js.getLogger("ImportHandler");
|
var apiLogger = log4js.getLogger("ImportHandler");
|
||||||
|
|
||||||
// pipe to a file
|
// pipe to a file
|
||||||
|
@ -265,8 +264,7 @@ async function doImport(req, res, padId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.doImport = function (req, res, padId)
|
exports.doImport = function (req, res, padId) {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* NB: abuse the 'req' object by storing an additional
|
* NB: abuse the 'req' object by storing an additional
|
||||||
* 'directDatabaseAccess' property on it so that it can
|
* 'directDatabaseAccess' property on it so that it can
|
||||||
|
|
|
@ -80,8 +80,7 @@ let socketio;
|
||||||
* This Method is called by server.js to tell the message handler on which socket it should send
|
* This Method is called by server.js to tell the message handler on which socket it should send
|
||||||
* @param socket_io The Socket
|
* @param socket_io The Socket
|
||||||
*/
|
*/
|
||||||
exports.setSocketIO = function(socket_io)
|
exports.setSocketIO = function(socket_io) {
|
||||||
{
|
|
||||||
socketio=socket_io;
|
socketio=socket_io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +98,7 @@ exports.handleConnect = (socket) => {
|
||||||
/**
|
/**
|
||||||
* Kicks all sessions from a pad
|
* Kicks all sessions from a pad
|
||||||
*/
|
*/
|
||||||
exports.kickSessionsFromPad = function(padID)
|
exports.kickSessionsFromPad = function(padID) {
|
||||||
{
|
|
||||||
if(typeof socketio.sockets['clients'] !== 'function')
|
if(typeof socketio.sockets['clients'] !== 'function')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -355,8 +353,7 @@ async function handleChatMessage(socket, message) {
|
||||||
* @param text the text of the chat message
|
* @param text the text of the chat message
|
||||||
* @param padId the padId to send the chat message to
|
* @param padId the padId to send the chat message to
|
||||||
*/
|
*/
|
||||||
exports.sendChatMessageToPadClients = async function(time, userId, text, padId)
|
exports.sendChatMessageToPadClients = async function(time, userId, text, padId) {
|
||||||
{
|
|
||||||
// get the pad
|
// get the pad
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
|
|
||||||
|
@ -688,8 +685,7 @@ async function handleUserChanges(socket, message) {
|
||||||
stopWatch.end();
|
stopWatch.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.updatePadClients = async function(pad)
|
exports.updatePadClients = async function(pad) {
|
||||||
{
|
|
||||||
// skip this if no-one is on this pad
|
// skip this if no-one is on this pad
|
||||||
const roomSockets = _getRoomSockets(pad.id);
|
const roomSockets = _getRoomSockets(pad.id);
|
||||||
if (roomSockets.length === 0) return;
|
if (roomSockets.length === 0) return;
|
||||||
|
@ -837,8 +833,7 @@ async function handleSwitchToPad(socket, message, _authorID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates/replaces the auth object in the given session info.
|
// Creates/replaces the auth object in the given session info.
|
||||||
function createSessionInfoAuth(sessionInfo, message)
|
function createSessionInfoAuth(sessionInfo, message) {
|
||||||
{
|
|
||||||
// Remember this information since we won't
|
// Remember this information since we won't
|
||||||
// have the cookie in further socket.io messages.
|
// have the cookie in further socket.io messages.
|
||||||
// This information will be used to check if
|
// This information will be used to check if
|
||||||
|
@ -1250,8 +1245,7 @@ async function handleChangesetRequest(socket, message) {
|
||||||
* Tries to rebuild the getChangestInfo function of the original Etherpad
|
* Tries to rebuild the getChangestInfo function of the original Etherpad
|
||||||
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L144
|
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L144
|
||||||
*/
|
*/
|
||||||
async function getChangesetInfo(padId, startNum, endNum, granularity)
|
async function getChangesetInfo(padId, startNum, endNum, granularity) {
|
||||||
{
|
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
let head_revision = pad.getHeadRevisionNumber();
|
let head_revision = pad.getHeadRevisionNumber();
|
||||||
|
|
||||||
|
@ -1344,8 +1338,7 @@ async function getChangesetInfo(padId, startNum, endNum, granularity)
|
||||||
* Tries to rebuild the getPadLines function of the original Etherpad
|
* Tries to rebuild the getPadLines function of the original Etherpad
|
||||||
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L263
|
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L263
|
||||||
*/
|
*/
|
||||||
async function getPadLines(padId, revNum)
|
async function getPadLines(padId, revNum) {
|
||||||
{
|
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
|
|
||||||
// get the atext
|
// get the atext
|
||||||
|
@ -1367,8 +1360,7 @@ async function getPadLines(padId, revNum)
|
||||||
* Tries to rebuild the composePadChangeset function of the original Etherpad
|
* Tries to rebuild the composePadChangeset function of the original Etherpad
|
||||||
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L241
|
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L241
|
||||||
*/
|
*/
|
||||||
async function composePadChangesets (padId, startNum, endNum)
|
async function composePadChangesets (padId, startNum, endNum) {
|
||||||
{
|
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
|
|
||||||
// fetch all changesets we need
|
// fetch all changesets we need
|
||||||
|
|
|
@ -37,8 +37,7 @@ var socket;
|
||||||
/**
|
/**
|
||||||
* adds a component
|
* adds a component
|
||||||
*/
|
*/
|
||||||
exports.addComponent = function(moduleName, module)
|
exports.addComponent = function(moduleName, module) {
|
||||||
{
|
|
||||||
// save the component
|
// save the component
|
||||||
components[moduleName] = module;
|
components[moduleName] = module;
|
||||||
|
|
||||||
|
@ -53,8 +52,7 @@ exports.setSocketIO = function(_socket) {
|
||||||
// save this socket internaly
|
// save this socket internaly
|
||||||
socket = _socket;
|
socket = _socket;
|
||||||
|
|
||||||
socket.sockets.on('connection', function(client)
|
socket.sockets.on('connection', function(client) {
|
||||||
{
|
|
||||||
// wrap the original send function to log the messages
|
// wrap the original send function to log the messages
|
||||||
client._send = client.send;
|
client._send = client.send;
|
||||||
client.send = function(message) {
|
client.send = function(message) {
|
||||||
|
|
|
@ -12,24 +12,20 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
})
|
})
|
||||||
|
|
||||||
//serve index.html under /
|
//serve index.html under /
|
||||||
args.app.get('/', function(req, res)
|
args.app.get('/', function(req, res) {
|
||||||
{
|
|
||||||
res.send(eejs.require('ep_etherpad-lite/templates/index.html', {req}));
|
res.send(eejs.require('ep_etherpad-lite/templates/index.html', {req}));
|
||||||
});
|
});
|
||||||
|
|
||||||
//serve javascript.html
|
//serve javascript.html
|
||||||
args.app.get('/javascript', function(req, res)
|
args.app.get('/javascript', function(req, res) {
|
||||||
{
|
|
||||||
res.send(eejs.require('ep_etherpad-lite/templates/javascript.html', {req}));
|
res.send(eejs.require('ep_etherpad-lite/templates/javascript.html', {req}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//serve robots.txt
|
//serve robots.txt
|
||||||
args.app.get('/robots.txt', function(req, res)
|
args.app.get('/robots.txt', function(req, res) {
|
||||||
{
|
|
||||||
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "robots.txt");
|
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "robots.txt");
|
||||||
res.sendFile(filePath, function(err)
|
res.sendFile(filePath, function(err) {
|
||||||
{
|
|
||||||
//there is no custom robots.txt, send the default robots.txt which dissallows all
|
//there is no custom robots.txt, send the default robots.txt which dissallows all
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
|
@ -40,8 +36,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
});
|
});
|
||||||
|
|
||||||
//serve pad.html under /p
|
//serve pad.html under /p
|
||||||
args.app.get('/p/:pad', function(req, res, next)
|
args.app.get('/p/:pad', function(req, res, next) {
|
||||||
{
|
|
||||||
// The below might break for pads being rewritten
|
// The below might break for pads being rewritten
|
||||||
const isReadOnly =
|
const isReadOnly =
|
||||||
req.url.indexOf("/p/r.") === 0 || !webaccess.userCanModify(req.params.pad, req);
|
req.url.indexOf("/p/r.") === 0 || !webaccess.userCanModify(req.params.pad, req);
|
||||||
|
@ -59,8 +54,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
});
|
});
|
||||||
|
|
||||||
//serve timeslider.html under /p/$padname/timeslider
|
//serve timeslider.html under /p/$padname/timeslider
|
||||||
args.app.get('/p/:pad/timeslider', function(req, res, next)
|
args.app.get('/p/:pad/timeslider', function(req, res, next) {
|
||||||
{
|
|
||||||
hooks.callAll("padInitToolbar", {
|
hooks.callAll("padInitToolbar", {
|
||||||
toolbar: toolbar
|
toolbar: toolbar
|
||||||
});
|
});
|
||||||
|
@ -72,12 +66,10 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
});
|
});
|
||||||
|
|
||||||
//serve favicon.ico from all path levels except as a pad name
|
//serve favicon.ico from all path levels except as a pad name
|
||||||
args.app.get( /\/favicon.ico$/, function(req, res)
|
args.app.get( /\/favicon.ico$/, function(req, res) {
|
||||||
{
|
|
||||||
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "favicon.ico");
|
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "favicon.ico");
|
||||||
|
|
||||||
res.sendFile(filePath, function(err)
|
res.sendFile(filePath, function(err) {
|
||||||
{
|
|
||||||
//there is no custom favicon, send the default favicon
|
//there is no custom favicon, send the default favicon
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,27 +30,23 @@ if(os.type().indexOf("Windows") > -1)
|
||||||
{
|
{
|
||||||
var stdoutBuffer = "";
|
var stdoutBuffer = "";
|
||||||
|
|
||||||
doConvertTask = function(task, callback)
|
doConvertTask = function(task, callback) {
|
||||||
{
|
|
||||||
//span an abiword process to perform the conversion
|
//span an abiword process to perform the conversion
|
||||||
var abiword = spawn(settings.abiword, ["--to=" + task.destFile, task.srcFile]);
|
var abiword = spawn(settings.abiword, ["--to=" + task.destFile, task.srcFile]);
|
||||||
|
|
||||||
//delegate the processing of stdout to another function
|
//delegate the processing of stdout to another function
|
||||||
abiword.stdout.on('data', function (data)
|
abiword.stdout.on('data', function (data) {
|
||||||
{
|
|
||||||
//add data to buffer
|
//add data to buffer
|
||||||
stdoutBuffer+=data.toString();
|
stdoutBuffer+=data.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
//append error messages to the buffer
|
//append error messages to the buffer
|
||||||
abiword.stderr.on('data', function (data)
|
abiword.stderr.on('data', function (data) {
|
||||||
{
|
|
||||||
stdoutBuffer += data.toString();
|
stdoutBuffer += data.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
//throw exceptions if abiword is dieing
|
//throw exceptions if abiword is dieing
|
||||||
abiword.on('exit', function (code)
|
abiword.on('exit', function (code) {
|
||||||
{
|
|
||||||
if(code != 0) {
|
if(code != 0) {
|
||||||
return callback(`Abiword died with exit code ${code}`);
|
return callback(`Abiword died with exit code ${code}`);
|
||||||
}
|
}
|
||||||
|
@ -64,8 +60,7 @@ if(os.type().indexOf("Windows") > -1)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.convertFile = function(srcFile, destFile, type, callback)
|
exports.convertFile = function(srcFile, destFile, type, callback) {
|
||||||
{
|
|
||||||
doConvertTask({"srcFile": srcFile, "destFile": destFile, "type": type}, callback);
|
doConvertTask({"srcFile": srcFile, "destFile": destFile, "type": type}, callback);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -82,21 +77,18 @@ else
|
||||||
var firstPrompt = true;
|
var firstPrompt = true;
|
||||||
|
|
||||||
//append error messages to the buffer
|
//append error messages to the buffer
|
||||||
abiword.stderr.on('data', function (data)
|
abiword.stderr.on('data', function (data) {
|
||||||
{
|
|
||||||
stdoutBuffer += data.toString();
|
stdoutBuffer += data.toString();
|
||||||
});
|
});
|
||||||
|
|
||||||
//abiword died, let's restart abiword and return an error with the callback
|
//abiword died, let's restart abiword and return an error with the callback
|
||||||
abiword.on('exit', function (code)
|
abiword.on('exit', function (code) {
|
||||||
{
|
|
||||||
spawnAbiword();
|
spawnAbiword();
|
||||||
stdoutCallback(`Abiword died with exit code ${code}`);
|
stdoutCallback(`Abiword died with exit code ${code}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
//delegate the processing of stdout to a other function
|
//delegate the processing of stdout to a other function
|
||||||
abiword.stdout.on('data',function (data)
|
abiword.stdout.on('data',function (data) {
|
||||||
{
|
|
||||||
//add data to buffer
|
//add data to buffer
|
||||||
stdoutBuffer+=data.toString();
|
stdoutBuffer+=data.toString();
|
||||||
|
|
||||||
|
@ -123,12 +115,10 @@ else
|
||||||
};
|
};
|
||||||
spawnAbiword();
|
spawnAbiword();
|
||||||
|
|
||||||
doConvertTask = function(task, callback)
|
doConvertTask = function(task, callback) {
|
||||||
{
|
|
||||||
abiword.stdin.write("convert " + task.srcFile + " " + task.destFile + " " + task.type + "\n");
|
abiword.stdin.write("convert " + task.srcFile + " " + task.destFile + " " + task.type + "\n");
|
||||||
//create a callback that calls the task callback and the caller callback
|
//create a callback that calls the task callback and the caller callback
|
||||||
stdoutCallback = function (err)
|
stdoutCallback = function (err) {
|
||||||
{
|
|
||||||
callback();
|
callback();
|
||||||
console.log("queue continue");
|
console.log("queue continue");
|
||||||
try{
|
try{
|
||||||
|
@ -141,8 +131,7 @@ else
|
||||||
|
|
||||||
//Queue with the converts we have to do
|
//Queue with the converts we have to do
|
||||||
var queue = async.queue(doConvertTask, 1);
|
var queue = async.queue(doConvertTask, 1);
|
||||||
exports.convertFile = function(srcFile, destFile, type, callback)
|
exports.convertFile = function(srcFile, destFile, type, callback) {
|
||||||
{
|
|
||||||
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback});
|
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@ var eejs = require('ep_etherpad-lite/node/eejs');
|
||||||
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
||||||
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
|
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
|
||||||
|
|
||||||
async function getPadHTML(pad, revNum)
|
async function getPadHTML(pad, revNum) {
|
||||||
{
|
|
||||||
let atext = pad.atext;
|
let atext = pad.atext;
|
||||||
|
|
||||||
// fetch revision atext
|
// fetch revision atext
|
||||||
|
@ -39,8 +38,7 @@ async function getPadHTML(pad, revNum)
|
||||||
exports.getPadHTML = getPadHTML;
|
exports.getPadHTML = getPadHTML;
|
||||||
exports.getHTMLFromAtext = getHTMLFromAtext;
|
exports.getHTMLFromAtext = getHTMLFromAtext;
|
||||||
|
|
||||||
async function getHTMLFromAtext(pad, atext, authorColors)
|
async function getHTMLFromAtext(pad, atext, authorColors) {
|
||||||
{
|
|
||||||
var apool = pad.apool();
|
var apool = pad.apool();
|
||||||
var textLines = atext.text.slice(0, -1).split('\n');
|
var textLines = atext.text.slice(0, -1).split('\n');
|
||||||
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
||||||
|
@ -110,8 +108,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
|
|
||||||
// iterates over all props(h1,h2,strong,...), checks if it is used in
|
// iterates over all props(h1,h2,strong,...), checks if it is used in
|
||||||
// this pad, and if yes puts its attrib id->props value into anumMap
|
// this pad, and if yes puts its attrib id->props value into anumMap
|
||||||
props.forEach(function (propName, i)
|
props.forEach(function (propName, i) {
|
||||||
{
|
|
||||||
var attrib = [propName, true];
|
var attrib = [propName, true];
|
||||||
if (_.isArray(propName)) {
|
if (_.isArray(propName)) {
|
||||||
// propName can be in the form of ['color', 'red'],
|
// propName can be in the form of ['color', 'red'],
|
||||||
|
@ -125,8 +122,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function getLineHTML(text, attribs)
|
function getLineHTML(text, attribs) {
|
||||||
{
|
|
||||||
// Use order of tags (b/i/u) as order of nesting, for simplicity
|
// Use order of tags (b/i/u) as order of nesting, for simplicity
|
||||||
// and decent nesting. For example,
|
// and decent nesting. For example,
|
||||||
// <b>Just bold<b> <b><i>Bold and italics</i></b> <i>Just italics</i>
|
// <b>Just bold<b> <b><i>Bold and italics</i></b> <i>Just italics</i>
|
||||||
|
@ -166,8 +162,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
return _.isArray(property);
|
return _.isArray(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitOpenTag(i)
|
function emitOpenTag(i) {
|
||||||
{
|
|
||||||
openTags.unshift(i);
|
openTags.unshift(i);
|
||||||
var spanClass = getSpanClassFor(i);
|
var spanClass = getSpanClassFor(i);
|
||||||
|
|
||||||
|
@ -183,8 +178,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this closes an open tag and removes its reference from openTags
|
// this closes an open tag and removes its reference from openTags
|
||||||
function emitCloseTag(i)
|
function emitCloseTag(i) {
|
||||||
{
|
|
||||||
openTags.shift();
|
openTags.shift();
|
||||||
var spanClass = getSpanClassFor(i);
|
var spanClass = getSpanClassFor(i);
|
||||||
var spanWithData = isSpanWithData(i);
|
var spanWithData = isSpanWithData(i);
|
||||||
|
@ -202,8 +196,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
|
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
|
|
||||||
function processNextChars(numChars)
|
function processNextChars(numChars) {
|
||||||
{
|
|
||||||
if (numChars <= 0)
|
if (numChars <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -220,8 +213,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
var usedAttribs = [];
|
var usedAttribs = [];
|
||||||
|
|
||||||
// mark all attribs as used
|
// mark all attribs as used
|
||||||
Changeset.eachAttribNumber(o.attribs, function (a)
|
Changeset.eachAttribNumber(o.attribs, function (a) {
|
||||||
{
|
|
||||||
if (a in anumMap)
|
if (a in anumMap)
|
||||||
{
|
{
|
||||||
usedAttribs.push(anumMap[a]); // i = 0 => bold, etc.
|
usedAttribs.push(anumMap[a]); // i = 0 => bold, etc.
|
||||||
|
@ -280,8 +272,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
} // end processNextChars
|
} // end processNextChars
|
||||||
if (urls)
|
if (urls)
|
||||||
{
|
{
|
||||||
urls.forEach(function (urlData)
|
urls.forEach(function (urlData) {
|
||||||
{
|
|
||||||
var startIndex = urlData[0];
|
var startIndex = urlData[0];
|
||||||
var url = urlData[1];
|
var url = urlData[1];
|
||||||
var urlLength = url.length;
|
var urlLength = url.length;
|
||||||
|
@ -341,8 +332,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
//To create list parent elements
|
//To create list parent elements
|
||||||
if ((!prevLine || prevLine.listLevel !== line.listLevel) || (prevLine && line.listTypeName !== prevLine.listTypeName))
|
if ((!prevLine || prevLine.listLevel !== line.listLevel) || (prevLine && line.listTypeName !== prevLine.listTypeName))
|
||||||
{
|
{
|
||||||
var exists = _.find(openLists, function (item)
|
var exists = _.find(openLists, function (item) {
|
||||||
{
|
|
||||||
return (item.level === line.listLevel && item.type === line.listTypeName);
|
return (item.level === line.listLevel && item.type === line.listTypeName);
|
||||||
});
|
});
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
|
@ -445,8 +435,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
|
|
||||||
for (var diff = nextLevel; diff < line.listLevel; diff++)
|
for (var diff = nextLevel; diff < line.listLevel; diff++)
|
||||||
{
|
{
|
||||||
openLists = openLists.filter(function(el)
|
openLists = openLists.filter(function(el) {
|
||||||
{
|
|
||||||
return el.level !== diff && el.type !== line.listTypeName;
|
return el.level !== diff && el.type !== line.listTypeName;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -485,8 +474,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
|
||||||
return pieces.join('');
|
return pieces.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getPadHTMLDocument = async function (padId, revNum)
|
exports.getPadHTMLDocument = async function (padId, revNum) {
|
||||||
{
|
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
|
|
||||||
// Include some Styles into the Head for Export
|
// Include some Styles into the Head for Export
|
||||||
|
@ -518,8 +506,7 @@ var _REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|g
|
||||||
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
||||||
|
|
||||||
|
|
||||||
function _findURLs(text)
|
function _findURLs(text) {
|
||||||
{
|
|
||||||
_REGEX_URL.lastIndex = 0;
|
_REGEX_URL.lastIndex = 0;
|
||||||
var urls = null;
|
var urls = null;
|
||||||
var execResult;
|
var execResult;
|
||||||
|
|
|
@ -23,8 +23,7 @@ var padManager = require("../db/PadManager");
|
||||||
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
||||||
|
|
||||||
// This is slightly different than the HTML method as it passes the output to getTXTFromAText
|
// This is slightly different than the HTML method as it passes the output to getTXTFromAText
|
||||||
var getPadTXT = async function(pad, revNum)
|
var getPadTXT = async function(pad, revNum) {
|
||||||
{
|
|
||||||
let atext = pad.atext;
|
let atext = pad.atext;
|
||||||
|
|
||||||
if (revNum != undefined) {
|
if (revNum != undefined) {
|
||||||
|
@ -38,8 +37,7 @@ var getPadTXT = async function(pad, revNum)
|
||||||
|
|
||||||
// This is different than the functionality provided in ExportHtml as it provides formatting
|
// This is different than the functionality provided in ExportHtml as it provides formatting
|
||||||
// functionality that is designed specifically for TXT exports
|
// functionality that is designed specifically for TXT exports
|
||||||
function getTXTFromAtext(pad, atext, authorColors)
|
function getTXTFromAtext(pad, atext, authorColors) {
|
||||||
{
|
|
||||||
var apool = pad.apool();
|
var apool = pad.apool();
|
||||||
var textLines = atext.text.slice(0, -1).split('\n');
|
var textLines = atext.text.slice(0, -1).split('\n');
|
||||||
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
||||||
|
@ -259,8 +257,7 @@ function getTXTFromAtext(pad, atext, authorColors)
|
||||||
|
|
||||||
exports.getTXTFromAtext = getTXTFromAtext;
|
exports.getTXTFromAtext = getTXTFromAtext;
|
||||||
|
|
||||||
exports.getPadTXTDocument = async function(padId, revNum)
|
exports.getPadTXTDocument = async function(padId, revNum) {
|
||||||
{
|
|
||||||
let pad = await padManager.getPad(padId);
|
let pad = await padManager.getPad(padId);
|
||||||
return getPadTXT(pad, revNum);
|
return getPadTXT(pad, revNum);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@ var log4js = require('log4js');
|
||||||
const db = require("../db/DB");
|
const db = require("../db/DB");
|
||||||
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||||
|
|
||||||
exports.setPadRaw = function(padId, records)
|
exports.setPadRaw = function(padId, records) {
|
||||||
{
|
|
||||||
records = JSON.parse(records);
|
records = JSON.parse(records);
|
||||||
|
|
||||||
Object.keys(records).forEach(async function(key) {
|
Object.keys(records).forEach(async function(key) {
|
||||||
|
|
|
@ -145,8 +145,7 @@ function requestURIs(locations, method, headers, callback) {
|
||||||
* @param req the Express request
|
* @param req the Express request
|
||||||
* @param res the Express response
|
* @param res the Express response
|
||||||
*/
|
*/
|
||||||
function minify(req, res)
|
function minify(req, res) {
|
||||||
{
|
|
||||||
var filename = req.params['filename'];
|
var filename = req.params['filename'];
|
||||||
|
|
||||||
// No relative paths, especially if they may go up the file hierarchy.
|
// No relative paths, especially if they may go up the file hierarchy.
|
||||||
|
@ -318,22 +317,18 @@ function lastModifiedDateOfEverything(callback) {
|
||||||
var folders2check = [ROOT_DIR + 'js/', ROOT_DIR + 'css/'];
|
var folders2check = [ROOT_DIR + 'js/', ROOT_DIR + 'css/'];
|
||||||
var latestModification = 0;
|
var latestModification = 0;
|
||||||
//go trough this two folders
|
//go trough this two folders
|
||||||
async.forEach(folders2check, function(path, callback)
|
async.forEach(folders2check, function(path, callback) {
|
||||||
{
|
|
||||||
//read the files in the folder
|
//read the files in the folder
|
||||||
fs.readdir(path, function(err, files)
|
fs.readdir(path, function(err, files) {
|
||||||
{
|
|
||||||
if(ERR(err, callback)) return;
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
//we wanna check the directory itself for changes too
|
//we wanna check the directory itself for changes too
|
||||||
files.push(".");
|
files.push(".");
|
||||||
|
|
||||||
//go trough all files in this folder
|
//go trough all files in this folder
|
||||||
async.forEach(files, function(filename, callback)
|
async.forEach(files, function(filename, callback) {
|
||||||
{
|
|
||||||
//get the stat data of this file
|
//get the stat data of this file
|
||||||
fs.stat(path + "/" + filename, function(err, stats)
|
fs.stat(path + "/" + filename, function(err, stats) {
|
||||||
{
|
|
||||||
if(ERR(err, callback)) return;
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
//get the modification time
|
//get the modification time
|
||||||
|
|
|
@ -7,13 +7,11 @@ var Terser = require("terser");
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var Threads = require('threads')
|
var Threads = require('threads')
|
||||||
|
|
||||||
function compressJS(content)
|
function compressJS(content) {
|
||||||
{
|
|
||||||
return Terser.minify(content);
|
return Terser.minify(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compressCSS(filename, ROOT_DIR)
|
function compressCSS(filename, ROOT_DIR) {
|
||||||
{
|
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
try {
|
try {
|
||||||
const absPath = path.join(ROOT_DIR, filename);
|
const absPath = path.join(ROOT_DIR, filename);
|
||||||
|
|
|
@ -381,8 +381,7 @@ exports.commitRateLimiting = {
|
||||||
exports.importMaxFileSize = 50 * 1024 * 1024;
|
exports.importMaxFileSize = 50 * 1024 * 1024;
|
||||||
|
|
||||||
// checks if abiword is avaiable
|
// checks if abiword is avaiable
|
||||||
exports.abiwordAvailable = function()
|
exports.abiwordAvailable = function() {
|
||||||
{
|
|
||||||
if (exports.abiword != null) {
|
if (exports.abiword != null) {
|
||||||
return os.type().indexOf("Windows") != -1 ? "withoutPDF" : "yes";
|
return os.type().indexOf("Windows") != -1 ? "withoutPDF" : "yes";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
*/
|
*/
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
|
|
||||||
var randomString = function(len)
|
var randomString = function(len) {
|
||||||
{
|
|
||||||
return crypto.randomBytes(len).toString('hex')
|
return crypto.randomBytes(len).toString('hex')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ var lineAttributes = [lineMarkerAttribute,'list'];
|
||||||
- a SkipList `lines` containing the text lines of the document.
|
- a SkipList `lines` containing the text lines of the document.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var AttributeManager = function(rep, applyChangesetCallback)
|
var AttributeManager = function(rep, applyChangesetCallback) {
|
||||||
{
|
|
||||||
this.rep = rep;
|
this.rep = rep;
|
||||||
this.applyChangesetCallback = applyChangesetCallback;
|
this.applyChangesetCallback = applyChangesetCallback;
|
||||||
this.author = '';
|
this.author = '';
|
||||||
|
@ -62,8 +61,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||||
@param end [row, col] tuple pointing to the end of the range
|
@param end [row, col] tuple pointing to the end of the range
|
||||||
@param attribs: an array of attributes
|
@param attribs: an array of attributes
|
||||||
*/
|
*/
|
||||||
setAttributesOnRange: function(start, end, attribs)
|
setAttributesOnRange: function(start, end, attribs) {
|
||||||
{
|
|
||||||
// instead of applying the attributes to the whole range at once, we need to apply them
|
// instead of applying the attributes to the whole range at once, we need to apply them
|
||||||
// line by line, to be able to disregard the "*" used as line marker. For more details,
|
// line by line, to be able to disregard the "*" used as line marker. For more details,
|
||||||
// see https://github.com/ether/etherpad-lite/issues/2772
|
// see https://github.com/ether/etherpad-lite/issues/2772
|
||||||
|
@ -87,8 +85,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||||
return this.applyChangeset(allChangesets);
|
return this.applyChangeset(allChangesets);
|
||||||
},
|
},
|
||||||
|
|
||||||
_findRowRange: function(row, start, end)
|
_findRowRange: function(row, start, end) {
|
||||||
{
|
|
||||||
var startCol, endCol;
|
var startCol, endCol;
|
||||||
|
|
||||||
var startLineOffset = this.rep.lines.offsetOfIndex(row);
|
var startLineOffset = this.rep.lines.offsetOfIndex(row);
|
||||||
|
@ -119,8 +116,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||||
@param endCol column where range ends
|
@param endCol column where range ends
|
||||||
@param attribs: an array of attributes
|
@param attribs: an array of attributes
|
||||||
*/
|
*/
|
||||||
_setAttributesOnRangeByLine: function(row, startCol, endCol, attribs)
|
_setAttributesOnRangeByLine: function(row, startCol, endCol, attribs) {
|
||||||
{
|
|
||||||
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
var builder = Changeset.builder(this.rep.lines.totalWidth());
|
||||||
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
|
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
|
||||||
ChangesetUtils.buildKeepRange(this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
|
ChangesetUtils.buildKeepRange(this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
|
||||||
|
@ -209,8 +205,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
|
||||||
[attributeName, 'true']
|
[attributeName, 'true']
|
||||||
], rep.apool);
|
], rep.apool);
|
||||||
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
|
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
|
||||||
function hasIt(attribs)
|
function hasIt(attribs) {
|
||||||
{
|
|
||||||
return withItRegex.test(attribs);
|
return withItRegex.test(attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
exports.buildRemoveRange = function(rep, builder, start, end)
|
exports.buildRemoveRange = function(rep, builder, start, end) {
|
||||||
{
|
|
||||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||||
|
|
||||||
|
@ -34,8 +33,7 @@ exports.buildRemoveRange = function(rep, builder, start, end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.buildKeepRange = function(rep, builder, start, end, attribs, pool)
|
exports.buildKeepRange = function(rep, builder, start, end, attribs, pool) {
|
||||||
{
|
|
||||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||||
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
var endLineOffset = rep.lines.offsetOfIndex(end[0]);
|
||||||
|
|
||||||
|
@ -50,8 +48,7 @@ exports.buildKeepRange = function(rep, builder, start, end, attribs, pool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.buildKeepToStartOfRange = function(rep, builder, start)
|
exports.buildKeepToStartOfRange = function(rep, builder, start) {
|
||||||
{
|
|
||||||
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
var startLineOffset = rep.lines.offsetOfIndex(start[0]);
|
||||||
|
|
||||||
builder.keep(startLineOffset, start[0]);
|
builder.keep(startLineOffset, start[0]);
|
||||||
|
|
|
@ -41,8 +41,7 @@ function scriptTag(source) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ace2Editor()
|
function Ace2Editor() {
|
||||||
{
|
|
||||||
var ace2 = Ace2Editor;
|
var ace2 = Ace2Editor;
|
||||||
|
|
||||||
var editor = {};
|
var editor = {};
|
||||||
|
@ -54,14 +53,11 @@ function Ace2Editor()
|
||||||
|
|
||||||
var actionsPendingInit = [];
|
var actionsPendingInit = [];
|
||||||
|
|
||||||
function pendingInit(func, optDoNow)
|
function pendingInit(func, optDoNow) {
|
||||||
{
|
return function() {
|
||||||
return function()
|
|
||||||
{
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
var action = function()
|
var action = function() {
|
||||||
{
|
|
||||||
func.apply(that, args);
|
func.apply(that, args);
|
||||||
}
|
}
|
||||||
if (optDoNow)
|
if (optDoNow)
|
||||||
|
@ -79,8 +75,7 @@ function Ace2Editor()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function doActionsPendingInit()
|
function doActionsPendingInit() {
|
||||||
{
|
|
||||||
_.each(actionsPendingInit, function(fn,i){
|
_.each(actionsPendingInit, function(fn,i){
|
||||||
fn()
|
fn()
|
||||||
});
|
});
|
||||||
|
@ -114,24 +109,20 @@ function Ace2Editor()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.exportText = function()
|
editor.exportText = function() {
|
||||||
{
|
|
||||||
if (!loaded) return "(awaiting init)\n";
|
if (!loaded) return "(awaiting init)\n";
|
||||||
return info.ace_exportText();
|
return info.ace_exportText();
|
||||||
};
|
};
|
||||||
|
|
||||||
editor.getFrame = function()
|
editor.getFrame = function() {
|
||||||
{
|
|
||||||
return info.frame || null;
|
return info.frame || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
editor.getDebugProperty = function(prop)
|
editor.getDebugProperty = function(prop) {
|
||||||
{
|
|
||||||
return info.ace_getDebugProperty(prop);
|
return info.ace_getDebugProperty(prop);
|
||||||
};
|
};
|
||||||
|
|
||||||
editor.getInInternationalComposition = function()
|
editor.getInInternationalComposition = function() {
|
||||||
{
|
|
||||||
if (!loaded) return false;
|
if (!loaded) return false;
|
||||||
return info.ace_getInInternationalComposition();
|
return info.ace_getInInternationalComposition();
|
||||||
};
|
};
|
||||||
|
@ -145,14 +136,12 @@ function Ace2Editor()
|
||||||
// to prepareUserChangeset will return an updated changeset that takes into account the
|
// to prepareUserChangeset will return an updated changeset that takes into account the
|
||||||
// latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
|
// latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
|
||||||
// accordingly.
|
// accordingly.
|
||||||
editor.prepareUserChangeset = function()
|
editor.prepareUserChangeset = function() {
|
||||||
{
|
|
||||||
if (!loaded) return null;
|
if (!loaded) return null;
|
||||||
return info.ace_prepareUserChangeset();
|
return info.ace_prepareUserChangeset();
|
||||||
};
|
};
|
||||||
|
|
||||||
editor.getUnhandledErrors = function()
|
editor.getUnhandledErrors = function() {
|
||||||
{
|
|
||||||
if (!loaded) return [];
|
if (!loaded) return [];
|
||||||
// returns array of {error: <browser Error object>, time: +new Date()}
|
// returns array of {error: <browser Error object>, time: +new Date()}
|
||||||
return info.ace_getUnhandledErrors();
|
return info.ace_getUnhandledErrors();
|
||||||
|
@ -198,28 +187,24 @@ function Ace2Editor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.destroy = pendingInit(function()
|
editor.destroy = pendingInit(function() {
|
||||||
{
|
|
||||||
info.ace_dispose();
|
info.ace_dispose();
|
||||||
info.frame.parentNode.removeChild(info.frame);
|
info.frame.parentNode.removeChild(info.frame);
|
||||||
delete ace2.registry[info.id];
|
delete ace2.registry[info.id];
|
||||||
info = null; // prevent IE 6 closure memory leaks
|
info = null; // prevent IE 6 closure memory leaks
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.init = function(containerId, initialCode, doneFunc)
|
editor.init = function(containerId, initialCode, doneFunc) {
|
||||||
{
|
|
||||||
|
|
||||||
editor.importText(initialCode);
|
editor.importText(initialCode);
|
||||||
|
|
||||||
info.onEditorReady = function()
|
info.onEditorReady = function() {
|
||||||
{
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
doActionsPendingInit();
|
doActionsPendingInit();
|
||||||
doneFunc();
|
doneFunc();
|
||||||
};
|
};
|
||||||
|
|
||||||
(function()
|
(function() {
|
||||||
{
|
|
||||||
var doctype = "<!doctype html>";
|
var doctype = "<!doctype html>";
|
||||||
|
|
||||||
var iframeHTML = [];
|
var iframeHTML = [];
|
||||||
|
|
|
@ -22,25 +22,21 @@
|
||||||
|
|
||||||
var Security = require('./security');
|
var Security = require('./security');
|
||||||
|
|
||||||
function isNodeText(node)
|
function isNodeText(node) {
|
||||||
{
|
|
||||||
return (node.nodeType == 3);
|
return (node.nodeType == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function object(o)
|
function object(o) {
|
||||||
{
|
|
||||||
var f = function(){};
|
var f = function(){};
|
||||||
f.prototype = o;
|
f.prototype = o;
|
||||||
return new f();
|
return new f();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAssoc(obj, name)
|
function getAssoc(obj, name) {
|
||||||
{
|
|
||||||
return obj["_magicdom_" + name];
|
return obj["_magicdom_" + name];
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAssoc(obj, name, value)
|
function setAssoc(obj, name, value) {
|
||||||
{
|
|
||||||
// note that in IE designMode, properties of a node can get
|
// note that in IE designMode, properties of a node can get
|
||||||
// copied to new nodes that are spawned during editing; also,
|
// copied to new nodes that are spawned during editing; also,
|
||||||
// properties representable in HTML text can survive copy-and-paste
|
// properties representable in HTML text can survive copy-and-paste
|
||||||
|
@ -52,8 +48,7 @@ function setAssoc(obj, name, value)
|
||||||
// between false and true, a number between 0 and numItems inclusive.
|
// between false and true, a number between 0 and numItems inclusive.
|
||||||
|
|
||||||
|
|
||||||
function binarySearch(numItems, func)
|
function binarySearch(numItems, func) {
|
||||||
{
|
|
||||||
if (numItems < 1) return 0;
|
if (numItems < 1) return 0;
|
||||||
if (func(0)) return 0;
|
if (func(0)) return 0;
|
||||||
if (!func(numItems - 1)) return numItems;
|
if (!func(numItems - 1)) return numItems;
|
||||||
|
@ -68,15 +63,13 @@ function binarySearch(numItems, func)
|
||||||
return high;
|
return high;
|
||||||
}
|
}
|
||||||
|
|
||||||
function binarySearchInfinite(expectedLength, func)
|
function binarySearchInfinite(expectedLength, func) {
|
||||||
{
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (!func(i)) i += expectedLength;
|
while (!func(i)) i += expectedLength;
|
||||||
return binarySearch(i, func);
|
return binarySearch(i, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
function htmlPrettyEscape(str)
|
function htmlPrettyEscape(str) {
|
||||||
{
|
|
||||||
return Security.escapeHTML(str).replace(/\r?\n/g, '\\n');
|
return Security.escapeHTML(str).replace(/\r?\n/g, '\\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,15 +31,13 @@ var hooks = require('./pluginfw/hooks');
|
||||||
|
|
||||||
// These parameters were global, now they are injected. A reference to the
|
// These parameters were global, now they are injected. A reference to the
|
||||||
// Timeslider controller would probably be more appropriate.
|
// Timeslider controller would probably be more appropriate.
|
||||||
function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider)
|
function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider) {
|
||||||
{
|
|
||||||
var changesetLoader = undefined;
|
var changesetLoader = undefined;
|
||||||
|
|
||||||
// Below Array#indexOf code was direct pasted by AppJet/Etherpad, licence unknown. Possible source: http://www.tutorialspoint.com/javascript/array_indexof.htm
|
// Below Array#indexOf code was direct pasted by AppJet/Etherpad, licence unknown. Possible source: http://www.tutorialspoint.com/javascript/array_indexof.htm
|
||||||
if (!Array.prototype.indexOf)
|
if (!Array.prototype.indexOf)
|
||||||
{
|
{
|
||||||
Array.prototype.indexOf = function(elt /*, from*/ )
|
Array.prototype.indexOf = function(elt /*, from*/ ) {
|
||||||
{
|
|
||||||
var len = this.length >>> 0;
|
var len = this.length >>> 0;
|
||||||
|
|
||||||
var from = Number(arguments[1]) || 0;
|
var from = Number(arguments[1]) || 0;
|
||||||
|
@ -54,8 +52,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function debugLog()
|
function debugLog() {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (window.console) console.log.apply(console, arguments);
|
if (window.console) console.log.apply(console, arguments);
|
||||||
|
@ -82,8 +79,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
clientVars.collab_client_vars.initialAttributedText.attribs, clientVars.collab_client_vars.initialAttributedText.text),
|
clientVars.collab_client_vars.initialAttributedText.attribs, clientVars.collab_client_vars.initialAttributedText.text),
|
||||||
|
|
||||||
// generates a jquery element containing HTML for a line
|
// generates a jquery element containing HTML for a line
|
||||||
lineToElement: function(line, aline)
|
lineToElement: function(line, aline) {
|
||||||
{
|
|
||||||
var element = document.createElement("div");
|
var element = document.createElement("div");
|
||||||
var emptyLine = (line == '\n');
|
var emptyLine = (line == '\n');
|
||||||
var domInfo = domline.createDomLine(!emptyLine, true);
|
var domInfo = domline.createDomLine(!emptyLine, true);
|
||||||
|
@ -95,8 +91,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
return $(element);
|
return $(element);
|
||||||
},
|
},
|
||||||
|
|
||||||
applySpliceToDivs: function(start, numRemoved, newLines)
|
applySpliceToDivs: function(start, numRemoved, newLines) {
|
||||||
{
|
|
||||||
// remove spliced-out lines from DOM
|
// remove spliced-out lines from DOM
|
||||||
for (var i = start; i < start + numRemoved && i < this.currentDivs.length; i++)
|
for (var i = start; i < start + numRemoved && i < this.currentDivs.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -137,8 +132,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
},
|
},
|
||||||
|
|
||||||
// splice the lines
|
// splice the lines
|
||||||
splice: function(start, numRemoved, newLinesVA)
|
splice: function(start, numRemoved, newLinesVA) {
|
||||||
{
|
|
||||||
var newLines = _.map(Array.prototype.slice.call(arguments, 2), function(s) {
|
var newLines = _.map(Array.prototype.slice.call(arguments, 2), function(s) {
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
@ -152,26 +146,22 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
this.currentLines.splice.apply(this.currentLines, arguments);
|
this.currentLines.splice.apply(this.currentLines, arguments);
|
||||||
},
|
},
|
||||||
// returns the contents of the specified line I
|
// returns the contents of the specified line I
|
||||||
get: function(i)
|
get: function(i) {
|
||||||
{
|
|
||||||
return this.currentLines[i];
|
return this.currentLines[i];
|
||||||
},
|
},
|
||||||
// returns the number of lines in the document
|
// returns the number of lines in the document
|
||||||
length: function()
|
length: function() {
|
||||||
{
|
|
||||||
return this.currentLines.length;
|
return this.currentLines.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
getActiveAuthors: function()
|
getActiveAuthors: function() {
|
||||||
{
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var authors = [];
|
var authors = [];
|
||||||
var seenNums = {};
|
var seenNums = {};
|
||||||
var alines = self.alines;
|
var alines = self.alines;
|
||||||
for (var i = 0; i < alines.length; i++)
|
for (var i = 0; i < alines.length; i++)
|
||||||
{
|
{
|
||||||
Changeset.eachAttribNumber(alines[i], function(n)
|
Changeset.eachAttribNumber(alines[i], function(n) {
|
||||||
{
|
|
||||||
if (!seenNums[n])
|
if (!seenNums[n])
|
||||||
{
|
{
|
||||||
seenNums[n] = true;
|
seenNums[n] = true;
|
||||||
|
@ -191,8 +181,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function callCatchingErrors(catcher, func)
|
function callCatchingErrors(catcher, func) {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wrapRecordingErrors(catcher, func)();
|
wrapRecordingErrors(catcher, func)();
|
||||||
|
@ -202,10 +191,8 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapRecordingErrors(catcher, func)
|
function wrapRecordingErrors(catcher, func) {
|
||||||
{
|
return function() {
|
||||||
return function()
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return func.apply(this, Array.prototype.slice.call(arguments));
|
return func.apply(this, Array.prototype.slice.call(arguments));
|
||||||
|
@ -222,8 +209,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadedNewChangeset(changesetForward, changesetBackward, revision, timeDelta)
|
function loadedNewChangeset(changesetForward, changesetBackward, revision, timeDelta) {
|
||||||
{
|
|
||||||
var broadcasting = (BroadcastSlider.getSliderPosition() == revisionInfo.latest);
|
var broadcasting = (BroadcastSlider.getSliderPosition() == revisionInfo.latest);
|
||||||
revisionInfo.addChangeset(revision, revision + 1, changesetForward, changesetBackward, timeDelta);
|
revisionInfo.addChangeset(revision, revision + 1, changesetForward, changesetBackward, timeDelta);
|
||||||
BroadcastSlider.setSliderLength(revisionInfo.latest);
|
BroadcastSlider.setSliderLength(revisionInfo.latest);
|
||||||
|
@ -236,8 +222,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
cause the whole slider to get out of sync.
|
cause the whole slider to get out of sync.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function applyChangeset(changeset, revision, preventSliderMovement, timeDelta)
|
function applyChangeset(changeset, revision, preventSliderMovement, timeDelta) {
|
||||||
{
|
|
||||||
// disable the next 'gotorevision' call handled by a timeslider update
|
// disable the next 'gotorevision' call handled by a timeslider update
|
||||||
if (!preventSliderMovement)
|
if (!preventSliderMovement)
|
||||||
{
|
{
|
||||||
|
@ -283,18 +268,15 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
|
|
||||||
updateTimer();
|
updateTimer();
|
||||||
|
|
||||||
var authors = _.map(padContents.getActiveAuthors(), function(name)
|
var authors = _.map(padContents.getActiveAuthors(), function(name) {
|
||||||
{
|
|
||||||
return authorData[name];
|
return authorData[name];
|
||||||
});
|
});
|
||||||
|
|
||||||
BroadcastSlider.setAuthors(authors);
|
BroadcastSlider.setAuthors(authors);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimer()
|
function updateTimer() {
|
||||||
{
|
var zpad = function(str, length) {
|
||||||
var zpad = function(str, length)
|
|
||||||
{
|
|
||||||
str = str + "";
|
str = str + "";
|
||||||
while (str.length < length)
|
while (str.length < length)
|
||||||
str = '0' + str;
|
str = '0' + str;
|
||||||
|
@ -302,8 +284,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
}
|
}
|
||||||
|
|
||||||
var date = new Date(padContents.currentTime);
|
var date = new Date(padContents.currentTime);
|
||||||
var dateFormat = function()
|
var dateFormat = function() {
|
||||||
{
|
|
||||||
var month = zpad(date.getMonth() + 1, 2);
|
var month = zpad(date.getMonth() + 1, 2);
|
||||||
var day = zpad(date.getDate(), 2);
|
var day = zpad(date.getDate(), 2);
|
||||||
var year = (date.getFullYear());
|
var year = (date.getFullYear());
|
||||||
|
@ -349,8 +330,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
|
|
||||||
updateTimer();
|
updateTimer();
|
||||||
|
|
||||||
function goToRevision(newRevision)
|
function goToRevision(newRevision) {
|
||||||
{
|
|
||||||
padContents.targetRevision = newRevision;
|
padContents.targetRevision = newRevision;
|
||||||
var self = this;
|
var self = this;
|
||||||
var path = revisionInfo.getPath(padContents.currentRevision, newRevision);
|
var path = revisionInfo.getPath(padContents.currentRevision, newRevision);
|
||||||
|
@ -376,8 +356,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
var sliderLocation = padContents.currentRevision;
|
var sliderLocation = padContents.currentRevision;
|
||||||
// callback is called after changeset information is pulled from server
|
// callback is called after changeset information is pulled from server
|
||||||
// this may never get called, if the changeset has already been loaded
|
// this may never get called, if the changeset has already been loaded
|
||||||
var update = function(start, end)
|
var update = function(start, end) {
|
||||||
{
|
|
||||||
// if we've called goToRevision in the time since, don't goToRevision
|
// if we've called goToRevision in the time since, don't goToRevision
|
||||||
goToRevision(padContents.targetRevision);
|
goToRevision(padContents.targetRevision);
|
||||||
};
|
};
|
||||||
|
@ -431,8 +410,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
requestQueue2: [],
|
requestQueue2: [],
|
||||||
requestQueue3: [],
|
requestQueue3: [],
|
||||||
reqCallbacks: [],
|
reqCallbacks: [],
|
||||||
queueUp: function(revision, width, callback)
|
queueUp: function(revision, width, callback) {
|
||||||
{
|
|
||||||
if (revision < 0) revision = 0;
|
if (revision < 0) revision = 0;
|
||||||
// if(changesetLoader.requestQueue.indexOf(revision) != -1)
|
// if(changesetLoader.requestQueue.indexOf(revision) != -1)
|
||||||
// return; // already in the queue.
|
// return; // already in the queue.
|
||||||
|
@ -452,8 +430,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
setTimeout(changesetLoader.loadFromQueue, 10);
|
setTimeout(changesetLoader.loadFromQueue, 10);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadFromQueue: function()
|
loadFromQueue: function() {
|
||||||
{
|
|
||||||
var self = changesetLoader;
|
var self = changesetLoader;
|
||||||
var requestQueue = self.requestQueue1.length > 0 ? self.requestQueue1 : self.requestQueue2.length > 0 ? self.requestQueue2 : self.requestQueue3.length > 0 ? self.requestQueue3 : null;
|
var requestQueue = self.requestQueue1.length > 0 ? self.requestQueue1 : self.requestQueue2.length > 0 ? self.requestQueue2 : self.requestQueue3.length > 0 ? self.requestQueue3 : null;
|
||||||
|
|
||||||
|
@ -477,8 +454,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
|
|
||||||
self.reqCallbacks[requestID] = callback;
|
self.reqCallbacks[requestID] = callback;
|
||||||
},
|
},
|
||||||
handleSocketResponse: function(message)
|
handleSocketResponse: function(message) {
|
||||||
{
|
|
||||||
var self = changesetLoader;
|
var self = changesetLoader;
|
||||||
|
|
||||||
var start = message.data.start;
|
var start = message.data.start;
|
||||||
|
@ -489,8 +465,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
self.handleResponse(message.data, start, granularity, callback);
|
self.handleResponse(message.data, start, granularity, callback);
|
||||||
setTimeout(self.loadFromQueue, 10);
|
setTimeout(self.loadFromQueue, 10);
|
||||||
},
|
},
|
||||||
handleResponse: function(data, start, granularity, callback)
|
handleResponse: function(data, start, granularity, callback) {
|
||||||
{
|
|
||||||
var pool = (new AttribPool()).fromJsonable(data.apool);
|
var pool = (new AttribPool()).fromJsonable(data.apool);
|
||||||
for (var i = 0; i < data.forwardsChangesets.length; i++)
|
for (var i = 0; i < data.forwardsChangesets.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -504,8 +479,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
}
|
}
|
||||||
if (callback) callback(start - 1, start + data.forwardsChangesets.length * granularity - 1);
|
if (callback) callback(start - 1, start + data.forwardsChangesets.length * granularity - 1);
|
||||||
},
|
},
|
||||||
handleMessageFromServer: function (obj)
|
handleMessageFromServer: function (obj) {
|
||||||
{
|
|
||||||
if (obj.type == "COLLABROOM")
|
if (obj.type == "COLLABROOM")
|
||||||
{
|
{
|
||||||
obj = obj.data;
|
obj = obj.data;
|
||||||
|
@ -556,8 +530,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
// to start upon window load, just push a function onto this array
|
// to start upon window load, just push a function onto this array
|
||||||
//window['onloadFuncts'].push(setUpSocket);
|
//window['onloadFuncts'].push(setUpSocket);
|
||||||
//window['onloadFuncts'].push(function ()
|
//window['onloadFuncts'].push(function ()
|
||||||
fireWhenAllScriptsAreLoaded.push(function()
|
fireWhenAllScriptsAreLoaded.push(function() {
|
||||||
{
|
|
||||||
// set up the currentDivs and DOM
|
// set up the currentDivs and DOM
|
||||||
padContents.currentDivs = [];
|
padContents.currentDivs = [];
|
||||||
$("#innerdocbody").html("");
|
$("#innerdocbody").html("");
|
||||||
|
@ -588,8 +561,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
||||||
var dynamicCSS = makeCSSManager('dynamicsyntax');
|
var dynamicCSS = makeCSSManager('dynamicsyntax');
|
||||||
var authorData = {};
|
var authorData = {};
|
||||||
|
|
||||||
function receiveAuthorData(newAuthorData)
|
function receiveAuthorData(newAuthorData) {
|
||||||
{
|
|
||||||
for (var author in newAuthorData)
|
for (var author in newAuthorData)
|
||||||
{
|
{
|
||||||
var data = newAuthorData[author];
|
var data = newAuthorData[author];
|
||||||
|
|
|
@ -23,34 +23,28 @@
|
||||||
// of the document. These revisions are connected together by various
|
// of the document. These revisions are connected together by various
|
||||||
// changesets, or deltas, between any two revisions.
|
// changesets, or deltas, between any two revisions.
|
||||||
|
|
||||||
function loadBroadcastRevisionsJS()
|
function loadBroadcastRevisionsJS() {
|
||||||
{
|
function Revision(revNum) {
|
||||||
function Revision(revNum)
|
|
||||||
{
|
|
||||||
this.rev = revNum;
|
this.rev = revNum;
|
||||||
this.changesets = [];
|
this.changesets = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta)
|
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) {
|
||||||
{
|
|
||||||
var changesetWrapper = {
|
var changesetWrapper = {
|
||||||
deltaRev: destIndex - this.rev,
|
deltaRev: destIndex - this.rev,
|
||||||
deltaTime: timeDelta,
|
deltaTime: timeDelta,
|
||||||
getValue: function()
|
getValue: function() {
|
||||||
{
|
|
||||||
return changeset;
|
return changeset;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.changesets.push(changesetWrapper);
|
this.changesets.push(changesetWrapper);
|
||||||
this.changesets.sort(function(a, b)
|
this.changesets.sort(function(a, b) {
|
||||||
{
|
|
||||||
return (b.deltaRev - a.deltaRev)
|
return (b.deltaRev - a.deltaRev)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
revisionInfo = {};
|
revisionInfo = {};
|
||||||
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta)
|
revisionInfo.addChangeset = function(fromIndex, toIndex, changeset, backChangeset, timeDelta) {
|
||||||
{
|
|
||||||
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
|
var startRevision = revisionInfo[fromIndex] || revisionInfo.createNew(fromIndex);
|
||||||
var endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
|
var endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
|
||||||
startRevision.addChangeset(toIndex, changeset, timeDelta);
|
startRevision.addChangeset(toIndex, changeset, timeDelta);
|
||||||
|
@ -59,8 +53,7 @@ function loadBroadcastRevisionsJS()
|
||||||
|
|
||||||
revisionInfo.latest = clientVars.collab_client_vars.rev || -1;
|
revisionInfo.latest = clientVars.collab_client_vars.rev || -1;
|
||||||
|
|
||||||
revisionInfo.createNew = function(index)
|
revisionInfo.createNew = function(index) {
|
||||||
{
|
|
||||||
revisionInfo[index] = new Revision(index);
|
revisionInfo[index] = new Revision(index);
|
||||||
if (index > revisionInfo.latest)
|
if (index > revisionInfo.latest)
|
||||||
{
|
{
|
||||||
|
@ -72,8 +65,7 @@ function loadBroadcastRevisionsJS()
|
||||||
|
|
||||||
// assuming that there is a path from fromIndex to toIndex, and that the links
|
// assuming that there is a path from fromIndex to toIndex, and that the links
|
||||||
// are laid out in a skip-list format
|
// are laid out in a skip-list format
|
||||||
revisionInfo.getPath = function(fromIndex, toIndex)
|
revisionInfo.getPath = function(fromIndex, toIndex) {
|
||||||
{
|
|
||||||
var changesets = [];
|
var changesets = [];
|
||||||
var spans = [];
|
var spans = [];
|
||||||
var times = [];
|
var times = [];
|
||||||
|
|
|
@ -26,15 +26,13 @@ var _ = require('./underscore');
|
||||||
var padmodals = require('./pad_modals').padmodals;
|
var padmodals = require('./pad_modals').padmodals;
|
||||||
var colorutils = require('./colorutils').colorutils;
|
var colorutils = require('./colorutils').colorutils;
|
||||||
|
|
||||||
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) {
|
||||||
{
|
|
||||||
var BroadcastSlider;
|
var BroadcastSlider;
|
||||||
|
|
||||||
// Hack to ensure timeslider i18n values are in
|
// Hack to ensure timeslider i18n values are in
|
||||||
$("[data-key='timeslider_returnToPad'] > a > span").html(html10n.get("timeslider.toolbar.returnbutton"));
|
$("[data-key='timeslider_returnToPad'] > a > span").html(html10n.get("timeslider.toolbar.returnbutton"));
|
||||||
|
|
||||||
(function()
|
(function() { // wrap this code in its own namespace
|
||||||
{ // wrap this code in its own namespace
|
|
||||||
var sliderLength = 1000;
|
var sliderLength = 1000;
|
||||||
var sliderPos = 0;
|
var sliderPos = 0;
|
||||||
var sliderActive = false;
|
var sliderActive = false;
|
||||||
|
@ -42,8 +40,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
var savedRevisions = [];
|
var savedRevisions = [];
|
||||||
var sliderPlaying = false;
|
var sliderPlaying = false;
|
||||||
|
|
||||||
var _callSliderCallbacks = function(newval)
|
var _callSliderCallbacks = function(newval) {
|
||||||
{
|
|
||||||
sliderPos = newval;
|
sliderPos = newval;
|
||||||
for (var i = 0; i < slidercallbacks.length; i++)
|
for (var i = 0; i < slidercallbacks.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -51,8 +48,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateSliderElements = function()
|
var updateSliderElements = function() {
|
||||||
{
|
|
||||||
for (var i = 0; i < savedRevisions.length; i++)
|
for (var i = 0; i < savedRevisions.length; i++)
|
||||||
{
|
{
|
||||||
var position = parseInt(savedRevisions[i].attr('pos'));
|
var position = parseInt(savedRevisions[i].attr('pos'));
|
||||||
|
@ -61,23 +57,20 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
$("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
|
$("#ui-slider-handle").css('left', sliderPos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
var addSavedRevision = function(position, info)
|
var addSavedRevision = function(position, info) {
|
||||||
{
|
|
||||||
var newSavedRevision = $('<div></div>');
|
var newSavedRevision = $('<div></div>');
|
||||||
newSavedRevision.addClass("star");
|
newSavedRevision.addClass("star");
|
||||||
|
|
||||||
newSavedRevision.attr('pos', position);
|
newSavedRevision.attr('pos', position);
|
||||||
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
|
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
|
||||||
$("#ui-slider-bar").append(newSavedRevision);
|
$("#ui-slider-bar").append(newSavedRevision);
|
||||||
newSavedRevision.mouseup(function(evt)
|
newSavedRevision.mouseup(function(evt) {
|
||||||
{
|
|
||||||
BroadcastSlider.setSliderPosition(position);
|
BroadcastSlider.setSliderPosition(position);
|
||||||
});
|
});
|
||||||
savedRevisions.push(newSavedRevision);
|
savedRevisions.push(newSavedRevision);
|
||||||
};
|
};
|
||||||
|
|
||||||
var removeSavedRevision = function(position)
|
var removeSavedRevision = function(position) {
|
||||||
{
|
|
||||||
var element = $("div.star [pos=" + position + "]");
|
var element = $("div.star [pos=" + position + "]");
|
||||||
savedRevisions.remove(element);
|
savedRevisions.remove(element);
|
||||||
element.remove();
|
element.remove();
|
||||||
|
@ -86,18 +79,15 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
|
|
||||||
/* Begin small 'API' */
|
/* Begin small 'API' */
|
||||||
|
|
||||||
function onSlider(callback)
|
function onSlider(callback) {
|
||||||
{
|
|
||||||
slidercallbacks.push(callback);
|
slidercallbacks.push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSliderPosition()
|
function getSliderPosition() {
|
||||||
{
|
|
||||||
return sliderPos;
|
return sliderPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSliderPosition(newpos)
|
function setSliderPosition(newpos) {
|
||||||
{
|
|
||||||
newpos = Number(newpos);
|
newpos = Number(newpos);
|
||||||
if (newpos < 0 || newpos > sliderLength) return;
|
if (newpos < 0 || newpos > sliderLength) return;
|
||||||
if(!newpos){
|
if(!newpos){
|
||||||
|
@ -105,8 +95,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
}
|
}
|
||||||
window.location.hash = "#" + newpos;
|
window.location.hash = "#" + newpos;
|
||||||
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
|
$("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0));
|
||||||
$("a.tlink").map(function()
|
$("a.tlink").map(function() {
|
||||||
{
|
|
||||||
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
|
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,33 +108,28 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
_callSliderCallbacks(newpos);
|
_callSliderCallbacks(newpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSliderLength()
|
function getSliderLength() {
|
||||||
{
|
|
||||||
return sliderLength;
|
return sliderLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSliderLength(newlength)
|
function setSliderLength(newlength) {
|
||||||
{
|
|
||||||
sliderLength = newlength;
|
sliderLength = newlength;
|
||||||
updateSliderElements();
|
updateSliderElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
// just take over the whole slider screen with a reconnect message
|
// just take over the whole slider screen with a reconnect message
|
||||||
|
|
||||||
function showReconnectUI()
|
function showReconnectUI() {
|
||||||
{
|
|
||||||
padmodals.showModal("disconnected");
|
padmodals.showModal("disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAuthors(authors)
|
function setAuthors(authors) {
|
||||||
{
|
|
||||||
var authorsList = $("#authorsList");
|
var authorsList = $("#authorsList");
|
||||||
authorsList.empty();
|
authorsList.empty();
|
||||||
var numAnonymous = 0;
|
var numAnonymous = 0;
|
||||||
var numNamed = 0;
|
var numNamed = 0;
|
||||||
var colorsAnonymous = [];
|
var colorsAnonymous = [];
|
||||||
_.each(authors, function(author)
|
_.each(authors, function(author) {
|
||||||
{
|
|
||||||
if(author)
|
if(author)
|
||||||
{
|
{
|
||||||
var authorColor = clientVars.colorPalette[author.colorId] || author.colorId;
|
var authorColor = clientVars.colorPalette[author.colorId] || author.colorId;
|
||||||
|
@ -204,8 +188,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
setSliderPosition: setSliderPosition,
|
setSliderPosition: setSliderPosition,
|
||||||
getSliderLength: getSliderLength,
|
getSliderLength: getSliderLength,
|
||||||
setSliderLength: setSliderLength,
|
setSliderLength: setSliderLength,
|
||||||
isSliderActive: function()
|
isSliderActive: function() {
|
||||||
{
|
|
||||||
return sliderActive;
|
return sliderActive;
|
||||||
},
|
},
|
||||||
playpause: playpause,
|
playpause: playpause,
|
||||||
|
@ -214,8 +197,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
setAuthors: setAuthors
|
setAuthors: setAuthors
|
||||||
}
|
}
|
||||||
|
|
||||||
function playButtonUpdater()
|
function playButtonUpdater() {
|
||||||
{
|
|
||||||
if (sliderPlaying)
|
if (sliderPlaying)
|
||||||
{
|
{
|
||||||
if (getSliderPosition() + 1 > sliderLength)
|
if (getSliderPosition() + 1 > sliderLength)
|
||||||
|
@ -230,8 +212,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function playpause()
|
function playpause() {
|
||||||
{
|
|
||||||
$("#playpause_button_icon").toggleClass('pause');
|
$("#playpause_button_icon").toggleClass('pause');
|
||||||
|
|
||||||
if (!sliderPlaying)
|
if (!sliderPlaying)
|
||||||
|
@ -247,10 +228,8 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign event handlers to html UI elements after page load
|
// assign event handlers to html UI elements after page load
|
||||||
fireWhenAllScriptsAreLoaded.push(function()
|
fireWhenAllScriptsAreLoaded.push(function() {
|
||||||
{
|
$(document).keyup(function(e) {
|
||||||
$(document).keyup(function(e)
|
|
||||||
{
|
|
||||||
if (!e) var e = window.event;
|
if (!e) var e = window.event;
|
||||||
var code = e.keyCode || e.which;
|
var code = e.keyCode || e.which;
|
||||||
|
|
||||||
|
@ -277,27 +256,23 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
$(window).resize(function()
|
$(window).resize(function() {
|
||||||
{
|
|
||||||
updateSliderElements();
|
updateSliderElements();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Slider click
|
// Slider click
|
||||||
$("#ui-slider-bar").mousedown(function(evt)
|
$("#ui-slider-bar").mousedown(function(evt) {
|
||||||
{
|
|
||||||
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left));
|
$("#ui-slider-handle").css('left', (evt.clientX - $("#ui-slider-bar").offset().left));
|
||||||
$("#ui-slider-handle").trigger(evt);
|
$("#ui-slider-handle").trigger(evt);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Slider dragging
|
// Slider dragging
|
||||||
$("#ui-slider-handle").mousedown(function(evt)
|
$("#ui-slider-handle").mousedown(function(evt) {
|
||||||
{
|
|
||||||
this.startLoc = evt.clientX;
|
this.startLoc = evt.clientX;
|
||||||
this.currentLoc = parseInt($(this).css('left'));
|
this.currentLoc = parseInt($(this).css('left'));
|
||||||
var self = this;
|
var self = this;
|
||||||
sliderActive = true;
|
sliderActive = true;
|
||||||
$(document).mousemove(function(evt2)
|
$(document).mousemove(function(evt2) {
|
||||||
{
|
|
||||||
$(self).css('pointer', 'move')
|
$(self).css('pointer', 'move')
|
||||||
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
|
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
|
||||||
if (newloc < 0) newloc = 0;
|
if (newloc < 0) newloc = 0;
|
||||||
|
@ -306,8 +281,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
$(self).css('left', newloc);
|
$(self).css('left', newloc);
|
||||||
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
|
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
|
||||||
});
|
});
|
||||||
$(document).mouseup(function(evt2)
|
$(document).mouseup(function(evt2) {
|
||||||
{
|
|
||||||
$(document).unbind('mousemove');
|
$(document).unbind('mousemove');
|
||||||
$(document).unbind('mouseup');
|
$(document).unbind('mouseup');
|
||||||
sliderActive = false;
|
sliderActive = false;
|
||||||
|
@ -326,14 +300,12 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
})
|
})
|
||||||
|
|
||||||
// play/pause toggling
|
// play/pause toggling
|
||||||
$("#playpause_button_icon").click(function(evt)
|
$("#playpause_button_icon").click(function(evt) {
|
||||||
{
|
|
||||||
BroadcastSlider.playpause();
|
BroadcastSlider.playpause();
|
||||||
});
|
});
|
||||||
|
|
||||||
// next/prev saved revision and changeset
|
// next/prev saved revision and changeset
|
||||||
$('.stepper').click(function(evt)
|
$('.stepper').click(function(evt) {
|
||||||
{
|
|
||||||
switch ($(this).attr("id")) {
|
switch ($(this).attr("id")) {
|
||||||
case "leftstep":
|
case "leftstep":
|
||||||
setSliderPosition(getSliderPosition() - 1);
|
setSliderPosition(getSliderPosition() - 1);
|
||||||
|
@ -380,8 +352,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
setSliderLength(clientVars.collab_client_vars.rev);
|
setSliderLength(clientVars.collab_client_vars.rev);
|
||||||
setSliderPosition(clientVars.collab_client_vars.rev);
|
setSliderPosition(clientVars.collab_client_vars.rev);
|
||||||
|
|
||||||
_.each(clientVars.savedRevisions, function(revision)
|
_.each(clientVars.savedRevisions, function(revision) {
|
||||||
{
|
|
||||||
addSavedRevision(revision.revNum, revision);
|
addSavedRevision(revision.revNum, revision);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -389,8 +360,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
BroadcastSlider.onSlider(function(loc)
|
BroadcastSlider.onSlider(function(loc) {
|
||||||
{
|
|
||||||
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content");
|
$("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// One rep.line(div) can be broken in more than one line in the browser.
|
// One rep.line(div) can be broken in more than one line in the browser.
|
||||||
// This function is useful to get the caret position of the line as
|
// This function is useful to get the caret position of the line as
|
||||||
// is represented by the browser
|
// is represented by the browser
|
||||||
exports.getPosition = function ()
|
exports.getPosition = function () {
|
||||||
{
|
|
||||||
var rect, line;
|
var rect, line;
|
||||||
var editor = $('#innerdocbody')[0];
|
var editor = $('#innerdocbody')[0];
|
||||||
var range = getSelectionRange();
|
var range = getSelectionRange();
|
||||||
|
@ -98,8 +97,7 @@ exports.getPositionTopOfPreviousBrowserLine = function(caretLinePosition, rep) {
|
||||||
return previousLineTop;
|
return previousLineTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
function caretLineIsFirstBrowserLine(caretLineTop, rep)
|
function caretLineIsFirstBrowserLine(caretLineTop, rep) {
|
||||||
{
|
|
||||||
var caretRepLine = rep.selStart[0];
|
var caretRepLine = rep.selStart[0];
|
||||||
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
|
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
|
||||||
var firstRootNode = getFirstRootChildNode(lineNode);
|
var firstRootNode = getFirstRootChildNode(lineNode);
|
||||||
|
@ -110,8 +108,7 @@ function caretLineIsFirstBrowserLine(caretLineTop, rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the first root node, usually it is a text node
|
// find the first root node, usually it is a text node
|
||||||
function getFirstRootChildNode(node)
|
function getFirstRootChildNode(node) {
|
||||||
{
|
|
||||||
if(!node.firstChild){
|
if(!node.firstChild){
|
||||||
return node;
|
return node;
|
||||||
}else{
|
}else{
|
||||||
|
@ -120,8 +117,7 @@ function getFirstRootChildNode(node)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreviousVisibleLine(line, rep)
|
function getPreviousVisibleLine(line, rep) {
|
||||||
{
|
|
||||||
if (line < 0) {
|
if (line < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}else if (isLineVisible(line, rep)) {
|
}else if (isLineVisible(line, rep)) {
|
||||||
|
@ -131,8 +127,7 @@ function getPreviousVisibleLine(line, rep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDimensionOfLastBrowserLineOfRepLine(line, rep)
|
function getDimensionOfLastBrowserLineOfRepLine(line, rep) {
|
||||||
{
|
|
||||||
var lineNode = rep.lines.atIndex(line).lineNode;
|
var lineNode = rep.lines.atIndex(line).lineNode;
|
||||||
var lastRootChildNode = getLastRootChildNode(lineNode);
|
var lastRootChildNode = getLastRootChildNode(lineNode);
|
||||||
|
|
||||||
|
@ -141,8 +136,7 @@ function getDimensionOfLastBrowserLineOfRepLine(line, rep)
|
||||||
return lastRootChildNodePosition;
|
return lastRootChildNodePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastRootChildNode(node)
|
function getLastRootChildNode(node) {
|
||||||
{
|
|
||||||
if(!node.lastChild){
|
if(!node.lastChild){
|
||||||
return {
|
return {
|
||||||
node: node,
|
node: node,
|
||||||
|
@ -158,8 +152,7 @@ function getLastRootChildNode(node)
|
||||||
// So, we can use the caret line to calculate the bottom of the line.
|
// So, we can use the caret line to calculate the bottom of the line.
|
||||||
// [2] the next line is part of another rep line. It's possible this line has different dimensions, so we
|
// [2] the next line is part of another rep line. It's possible this line has different dimensions, so we
|
||||||
// have to get the exactly dimension of it
|
// have to get the exactly dimension of it
|
||||||
exports.getBottomOfNextBrowserLine = function(caretLinePosition, rep)
|
exports.getBottomOfNextBrowserLine = function(caretLinePosition, rep) {
|
||||||
{
|
|
||||||
var nextLineBottom = caretLinePosition.bottom + caretLinePosition.height; //[1]
|
var nextLineBottom = caretLinePosition.bottom + caretLinePosition.height; //[1]
|
||||||
var isCaretLineLastBrowserLine = caretLineIsLastBrowserLineOfRepLine(caretLinePosition.top, rep);
|
var isCaretLineLastBrowserLine = caretLineIsLastBrowserLineOfRepLine(caretLinePosition.top, rep);
|
||||||
|
|
||||||
|
@ -174,8 +167,7 @@ exports.getBottomOfNextBrowserLine = function(caretLinePosition, rep)
|
||||||
return nextLineBottom;
|
return nextLineBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep)
|
function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep) {
|
||||||
{
|
|
||||||
var caretRepLine = rep.selStart[0];
|
var caretRepLine = rep.selStart[0];
|
||||||
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
|
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
|
||||||
var lastRootChildNode = getLastRootChildNode(lineNode);
|
var lastRootChildNode = getLastRootChildNode(lineNode);
|
||||||
|
@ -185,8 +177,7 @@ function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep)
|
||||||
return lastRootChildNodePosition.top === caretLineTop;
|
return lastRootChildNodePosition.top === caretLineTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreviousVisibleLine(line, rep)
|
function getPreviousVisibleLine(line, rep) {
|
||||||
{
|
|
||||||
var firstLineOfPad = 0;
|
var firstLineOfPad = 0;
|
||||||
if (line <= firstLineOfPad) {
|
if (line <= firstLineOfPad) {
|
||||||
return firstLineOfPad;
|
return firstLineOfPad;
|
||||||
|
@ -198,8 +189,7 @@ function getPreviousVisibleLine(line, rep)
|
||||||
}
|
}
|
||||||
exports.getPreviousVisibleLine = getPreviousVisibleLine;
|
exports.getPreviousVisibleLine = getPreviousVisibleLine;
|
||||||
|
|
||||||
function getNextVisibleLine(line, rep)
|
function getNextVisibleLine(line, rep) {
|
||||||
{
|
|
||||||
var lastLineOfThePad = rep.lines.length() - 1;
|
var lastLineOfThePad = rep.lines.length() - 1;
|
||||||
if (line >= lastLineOfThePad) {
|
if (line >= lastLineOfThePad) {
|
||||||
return lastLineOfThePad;
|
return lastLineOfThePad;
|
||||||
|
@ -211,13 +201,11 @@ function getNextVisibleLine(line, rep)
|
||||||
}
|
}
|
||||||
exports.getNextVisibleLine = getNextVisibleLine;
|
exports.getNextVisibleLine = getNextVisibleLine;
|
||||||
|
|
||||||
function isLineVisible(line, rep)
|
function isLineVisible(line, rep) {
|
||||||
{
|
|
||||||
return rep.lines.atIndex(line).lineNode.offsetHeight > 0;
|
return rep.lines.atIndex(line).lineNode.offsetHeight > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDimensionOfFirstBrowserLineOfRepLine(line, rep)
|
function getDimensionOfFirstBrowserLineOfRepLine(line, rep) {
|
||||||
{
|
|
||||||
var lineNode = rep.lines.atIndex(line).lineNode;
|
var lineNode = rep.lines.atIndex(line).lineNode;
|
||||||
var firstRootChildNode = getFirstRootChildNode(lineNode);
|
var firstRootChildNode = getFirstRootChildNode(lineNode);
|
||||||
|
|
||||||
|
@ -226,8 +214,7 @@ function getDimensionOfFirstBrowserLineOfRepLine(line, rep)
|
||||||
return firstRootChildNodePosition;
|
return firstRootChildNodePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectionRange()
|
function getSelectionRange() {
|
||||||
{
|
|
||||||
var selection;
|
var selection;
|
||||||
if (!window.getSelection) {
|
if (!window.getSelection) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
var AttributePool = require('./AttributePool');
|
var AttributePool = require('./AttributePool');
|
||||||
var Changeset = require('./Changeset');
|
var Changeset = require('./Changeset');
|
||||||
|
|
||||||
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) {
|
||||||
{
|
|
||||||
|
|
||||||
// latest official text from server
|
// latest official text from server
|
||||||
var baseAText = Changeset.makeAText("\n");
|
var baseAText = Changeset.makeAText("\n");
|
||||||
|
@ -44,15 +43,13 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
|
|
||||||
var changeCallbackTimeout = null;
|
var changeCallbackTimeout = null;
|
||||||
|
|
||||||
function setChangeCallbackTimeout()
|
function setChangeCallbackTimeout() {
|
||||||
{
|
|
||||||
// can call this multiple times per call-stack, because
|
// can call this multiple times per call-stack, because
|
||||||
// we only schedule a call to changeCallback if it exists
|
// we only schedule a call to changeCallback if it exists
|
||||||
// and if there isn't a timeout already scheduled.
|
// and if there isn't a timeout already scheduled.
|
||||||
if (changeCallback && changeCallbackTimeout === null)
|
if (changeCallback && changeCallbackTimeout === null)
|
||||||
{
|
{
|
||||||
changeCallbackTimeout = scheduler.setTimeout(function()
|
changeCallbackTimeout = scheduler.setTimeout(function() {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
changeCallback();
|
changeCallback();
|
||||||
|
@ -68,18 +65,14 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
|
|
||||||
var self;
|
var self;
|
||||||
return self = {
|
return self = {
|
||||||
isTracking: function()
|
isTracking: function() {
|
||||||
{
|
|
||||||
return tracking;
|
return tracking;
|
||||||
},
|
},
|
||||||
setBaseText: function(text)
|
setBaseText: function(text) {
|
||||||
{
|
|
||||||
self.setBaseAttributedText(Changeset.makeAText(text), null);
|
self.setBaseAttributedText(Changeset.makeAText(text), null);
|
||||||
},
|
},
|
||||||
setBaseAttributedText: function(atext, apoolJsonObj)
|
setBaseAttributedText: function(atext, apoolJsonObj) {
|
||||||
{
|
aceCallbacksProvider.withCallbacks("setBaseText", function(callbacks) {
|
||||||
aceCallbacksProvider.withCallbacks("setBaseText", function(callbacks)
|
|
||||||
{
|
|
||||||
tracking = true;
|
tracking = true;
|
||||||
baseAText = Changeset.cloneAText(atext);
|
baseAText = Changeset.cloneAText(atext);
|
||||||
if (apoolJsonObj)
|
if (apoolJsonObj)
|
||||||
|
@ -100,8 +93,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
composeUserChangeset: function(c)
|
composeUserChangeset: function(c) {
|
||||||
{
|
|
||||||
if (!tracking) return;
|
if (!tracking) return;
|
||||||
if (applyingNonUserChanges) return;
|
if (applyingNonUserChanges) return;
|
||||||
if (Changeset.isIdentity(c)) return;
|
if (Changeset.isIdentity(c)) return;
|
||||||
|
@ -109,12 +101,10 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
|
|
||||||
setChangeCallbackTimeout();
|
setChangeCallbackTimeout();
|
||||||
},
|
},
|
||||||
applyChangesToBase: function(c, optAuthor, apoolJsonObj)
|
applyChangesToBase: function(c, optAuthor, apoolJsonObj) {
|
||||||
{
|
|
||||||
if (!tracking) return;
|
if (!tracking) return;
|
||||||
|
|
||||||
aceCallbacksProvider.withCallbacks("applyChangesToBase", function(callbacks)
|
aceCallbacksProvider.withCallbacks("applyChangesToBase", function(callbacks) {
|
||||||
{
|
|
||||||
|
|
||||||
if (apoolJsonObj)
|
if (apoolJsonObj)
|
||||||
{
|
{
|
||||||
|
@ -149,8 +139,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
prepareUserChangeset: function()
|
prepareUserChangeset: function() {
|
||||||
{
|
|
||||||
// If there are user changes to submit, 'changeset' will be the
|
// If there are user changes to submit, 'changeset' will be the
|
||||||
// changeset, else it will be null.
|
// changeset, else it will be null.
|
||||||
var toSubmit;
|
var toSubmit;
|
||||||
|
@ -237,8 +226,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
};
|
};
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
applyPreparedChangesetToBase: function()
|
applyPreparedChangesetToBase: function() {
|
||||||
{
|
|
||||||
if (!submittedChangeset)
|
if (!submittedChangeset)
|
||||||
{
|
{
|
||||||
// violation of protocol; use prepareUserChangeset first
|
// violation of protocol; use prepareUserChangeset first
|
||||||
|
@ -248,12 +236,10 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
baseAText = Changeset.applyToAText(submittedChangeset, baseAText, apool);
|
baseAText = Changeset.applyToAText(submittedChangeset, baseAText, apool);
|
||||||
submittedChangeset = null;
|
submittedChangeset = null;
|
||||||
},
|
},
|
||||||
setUserChangeNotificationCallback: function(callback)
|
setUserChangeNotificationCallback: function(callback) {
|
||||||
{
|
|
||||||
changeCallback = callback;
|
changeCallback = callback;
|
||||||
},
|
},
|
||||||
hasUncommittedChanges: function()
|
hasUncommittedChanges: function() {
|
||||||
{
|
|
||||||
return !!(submittedChangeset || (!Changeset.isIdentity(userChangeset)));
|
return !!(submittedChangeset || (!Changeset.isIdentity(userChangeset)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,16 +20,14 @@ var Tinycon = require('tinycon/tinycon');
|
||||||
var hooks = require('./pluginfw/hooks');
|
var hooks = require('./pluginfw/hooks');
|
||||||
var padeditor = require('./pad_editor').padeditor;
|
var padeditor = require('./pad_editor').padeditor;
|
||||||
|
|
||||||
var chat = (function()
|
var chat = (function() {
|
||||||
{
|
|
||||||
var isStuck = false;
|
var isStuck = false;
|
||||||
var userAndChat = false;
|
var userAndChat = false;
|
||||||
var gotInitialMessages = false;
|
var gotInitialMessages = false;
|
||||||
var historyPointer = 0;
|
var historyPointer = 0;
|
||||||
var chatMentions = 0;
|
var chatMentions = 0;
|
||||||
var self = {
|
var self = {
|
||||||
show: function ()
|
show: function () {
|
||||||
{
|
|
||||||
$("#chaticon").removeClass('visible');
|
$("#chaticon").removeClass('visible');
|
||||||
$("#chatbox").addClass('visible');
|
$("#chatbox").addClass('visible');
|
||||||
self.scrollDown(true);
|
self.scrollDown(true);
|
||||||
|
@ -39,14 +37,12 @@ var chat = (function()
|
||||||
$.gritter.remove(this.id);
|
$.gritter.remove(this.id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
focus: function ()
|
focus: function () {
|
||||||
{
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
$("#chatinput").focus();
|
$("#chatinput").focus();
|
||||||
},100);
|
},100);
|
||||||
},
|
},
|
||||||
stickToScreen: function(fromInitialCall) // Make chat stick to right hand side of screen
|
stickToScreen: function(fromInitialCall) { // Make chat stick to right hand side of screen
|
||||||
{
|
|
||||||
if(pad.settings.hideChat){
|
if(pad.settings.hideChat){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -62,8 +58,7 @@ var chat = (function()
|
||||||
padcookie.setPref("chatAlwaysVisible", isStuck);
|
padcookie.setPref("chatAlwaysVisible", isStuck);
|
||||||
$('#options-stickychat').prop('checked', isStuck);
|
$('#options-stickychat').prop('checked', isStuck);
|
||||||
},
|
},
|
||||||
chatAndUsers: function(fromInitialCall)
|
chatAndUsers: function(fromInitialCall) {
|
||||||
{
|
|
||||||
var toEnable = $('#options-chatandusers').is(":checked");
|
var toEnable = $('#options-chatandusers').is(":checked");
|
||||||
if(toEnable || !userAndChat || fromInitialCall){
|
if(toEnable || !userAndChat || fromInitialCall){
|
||||||
chat.stickToScreen(true);
|
chat.stickToScreen(true);
|
||||||
|
@ -79,8 +74,7 @@ var chat = (function()
|
||||||
$('#users, .sticky-container').toggleClass("chatAndUsers popup-show stickyUsers", userAndChat);
|
$('#users, .sticky-container').toggleClass("chatAndUsers popup-show stickyUsers", userAndChat);
|
||||||
$("#chatbox").toggleClass("chatAndUsersChat", userAndChat);
|
$("#chatbox").toggleClass("chatAndUsersChat", userAndChat);
|
||||||
},
|
},
|
||||||
hide: function ()
|
hide: function () {
|
||||||
{
|
|
||||||
// decide on hide logic based on chat window being maximized or not
|
// decide on hide logic based on chat window being maximized or not
|
||||||
if ($('#options-stickychat').prop('checked')) {
|
if ($('#options-stickychat').prop('checked')) {
|
||||||
chat.stickToScreen();
|
chat.stickToScreen();
|
||||||
|
@ -92,8 +86,7 @@ var chat = (function()
|
||||||
$("#chatbox").removeClass('visible');
|
$("#chatbox").removeClass('visible');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollDown: function(force)
|
scrollDown: function(force) {
|
||||||
{
|
|
||||||
if ($('#chatbox').hasClass('visible')) {
|
if ($('#chatbox').hasClass('visible')) {
|
||||||
if (force || !self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < ($('#chattext').outerHeight() + 20)) {
|
if (force || !self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < ($('#chattext').outerHeight() + 20)) {
|
||||||
// if we use a slow animate here we can have a race condition when a users focus can not be moved away
|
// if we use a slow animate here we can have a race condition when a users focus can not be moved away
|
||||||
|
@ -103,16 +96,14 @@ var chat = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
send: function()
|
send: function() {
|
||||||
{
|
|
||||||
var text = $("#chatinput").val();
|
var text = $("#chatinput").val();
|
||||||
if(text.replace(/\s+/,'').length == 0)
|
if(text.replace(/\s+/,'').length == 0)
|
||||||
return;
|
return;
|
||||||
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text});
|
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text});
|
||||||
$("#chatinput").val("");
|
$("#chatinput").val("");
|
||||||
},
|
},
|
||||||
addMessage: function(msg, increment, isHistoryAdd)
|
addMessage: function(msg, increment, isHistoryAdd) {
|
||||||
{
|
|
||||||
//correct the time
|
//correct the time
|
||||||
msg.time += this._pad.clientTimeOffset;
|
msg.time += this._pad.clientTimeOffset;
|
||||||
|
|
||||||
|
@ -136,8 +127,7 @@ var chat = (function()
|
||||||
console.warn('The "userId" field of a chat message coming from the server was not present. Replacing with "unknown". This may be a bug or a database corruption.');
|
console.warn('The "userId" field of a chat message coming from the server was not present. Replacing with "unknown". This may be a bug or a database corruption.');
|
||||||
}
|
}
|
||||||
|
|
||||||
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c)
|
var authorClass = "author-" + msg.userId.replace(/[^a-y0-9]/g, function(c) {
|
||||||
{
|
|
||||||
if (c == ".") return "-";
|
if (c == ".") return "-";
|
||||||
return 'z' + c.charCodeAt(0) + 'z';
|
return 'z' + c.charCodeAt(0) + 'z';
|
||||||
});
|
});
|
||||||
|
@ -214,8 +204,7 @@ var chat = (function()
|
||||||
if(!isHistoryAdd)
|
if(!isHistoryAdd)
|
||||||
self.scrollDown();
|
self.scrollDown();
|
||||||
},
|
},
|
||||||
init: function(pad)
|
init: function(pad) {
|
||||||
{
|
|
||||||
this._pad = pad;
|
this._pad = pad;
|
||||||
$("#chatinput").on("keydown", function(evt){
|
$("#chatinput").on("keydown", function(evt){
|
||||||
// If the event is Alt C or Escape & we're already in the chat menu
|
// If the event is Alt C or Escape & we're already in the chat menu
|
||||||
|
@ -251,8 +240,7 @@ var chat = (function()
|
||||||
// initial messages are loaded in pad.js' _afterHandshake
|
// initial messages are loaded in pad.js' _afterHandshake
|
||||||
|
|
||||||
$("#chatcounter").text(0);
|
$("#chatcounter").text(0);
|
||||||
$("#chatloadmessagesbutton").click(function()
|
$("#chatloadmessagesbutton").click(function() {
|
||||||
{
|
|
||||||
var start = Math.max(self.historyPointer - 20, 0);
|
var start = Math.max(self.historyPointer - 20, 0);
|
||||||
var end = self.historyPointer;
|
var end = self.historyPointer;
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@ function getSocket() {
|
||||||
/** Call this when the document is ready, and a new Ace2Editor() has been created and inited.
|
/** Call this when the document is ready, and a new Ace2Editor() has been created and inited.
|
||||||
ACE's ready callback does not need to have fired yet.
|
ACE's ready callback does not need to have fired yet.
|
||||||
"serverVars" are from calling doc.getCollabClientVars() on the server. */
|
"serverVars" are from calling doc.getCollabClientVars() on the server. */
|
||||||
function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) {
|
||||||
{
|
|
||||||
var editor = ace2editor;
|
var editor = ace2editor;
|
||||||
pad = _pad; // Inject pad to avoid a circular dependency.
|
pad = _pad; // Inject pad to avoid a circular dependency.
|
||||||
|
|
||||||
|
@ -66,29 +65,20 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
tellAceActiveAuthorInfo(initialUserInfo);
|
tellAceActiveAuthorInfo(initialUserInfo);
|
||||||
|
|
||||||
var callbacks = {
|
var callbacks = {
|
||||||
onUserJoin: function()
|
onUserJoin: function() {},
|
||||||
{},
|
onUserLeave: function() {},
|
||||||
onUserLeave: function()
|
onUpdateUserInfo: function() {},
|
||||||
{},
|
onChannelStateChange: function() {},
|
||||||
onUpdateUserInfo: function()
|
onClientMessage: function() {},
|
||||||
{},
|
onInternalAction: function() {},
|
||||||
onChannelStateChange: function()
|
onConnectionTrouble: function() {},
|
||||||
{},
|
onServerMessage: function() {}
|
||||||
onClientMessage: function()
|
|
||||||
{},
|
|
||||||
onInternalAction: function()
|
|
||||||
{},
|
|
||||||
onConnectionTrouble: function()
|
|
||||||
{},
|
|
||||||
onServerMessage: function()
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
if (browser.firefox)
|
if (browser.firefox)
|
||||||
{
|
{
|
||||||
// Prevent "escape" from taking effect and canceling a comet connection;
|
// Prevent "escape" from taking effect and canceling a comet connection;
|
||||||
// doesn't work if focus is on an iframe.
|
// doesn't work if focus is on an iframe.
|
||||||
$(window).bind("keydown", function(evt)
|
$(window).bind("keydown", function(evt) {
|
||||||
{
|
|
||||||
if (evt.which == 27)
|
if (evt.which == 27)
|
||||||
{
|
{
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
@ -100,14 +90,12 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
editor.setBaseAttributedText(serverVars.initialAttributedText, serverVars.apool);
|
editor.setBaseAttributedText(serverVars.initialAttributedText, serverVars.apool);
|
||||||
editor.setUserChangeNotificationCallback(wrapRecordingErrors("handleUserChanges", handleUserChanges));
|
editor.setUserChangeNotificationCallback(wrapRecordingErrors("handleUserChanges", handleUserChanges));
|
||||||
|
|
||||||
function dmesg(str)
|
function dmesg(str) {
|
||||||
{
|
|
||||||
if (typeof window.ajlog == "string") window.ajlog += str + '\n';
|
if (typeof window.ajlog == "string") window.ajlog += str + '\n';
|
||||||
debugMessages.push(str);
|
debugMessages.push(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUserChanges()
|
function handleUserChanges() {
|
||||||
{
|
|
||||||
if (editor.getInInternationalComposition()) return;
|
if (editor.getInInternationalComposition()) return;
|
||||||
if ((!getSocket()) || channelState == "CONNECTING")
|
if ((!getSocket()) || channelState == "CONNECTING")
|
||||||
{
|
{
|
||||||
|
@ -161,12 +149,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
{
|
{
|
||||||
editor.applyPreparedChangesetToBase();
|
editor.applyPreparedChangesetToBase();
|
||||||
setStateIdle();
|
setStateIdle();
|
||||||
callCatchingErrors("onInternalAction", function()
|
callCatchingErrors("onInternalAction", function() {
|
||||||
{
|
|
||||||
callbacks.onInternalAction("commitAcceptedByServer");
|
callbacks.onInternalAction("commitAcceptedByServer");
|
||||||
});
|
});
|
||||||
callCatchingErrors("onConnectionTrouble", function()
|
callCatchingErrors("onConnectionTrouble", function() {
|
||||||
{
|
|
||||||
callbacks.onConnectionTrouble("OK");
|
callbacks.onConnectionTrouble("OK");
|
||||||
});
|
});
|
||||||
handleUserChanges();
|
handleUserChanges();
|
||||||
|
@ -219,8 +205,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUpSocket()
|
function setUpSocket() {
|
||||||
{
|
|
||||||
hiccupCount = 0;
|
hiccupCount = 0;
|
||||||
setChannelState("CONNECTED");
|
setChannelState("CONNECTED");
|
||||||
doDeferredActions();
|
doDeferredActions();
|
||||||
|
@ -230,8 +215,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
|
|
||||||
var hiccupCount = 0;
|
var hiccupCount = 0;
|
||||||
|
|
||||||
function sendMessage(msg)
|
function sendMessage(msg) {
|
||||||
{
|
|
||||||
getSocket().json.send(
|
getSocket().json.send(
|
||||||
{
|
{
|
||||||
type: "COLLABROOM",
|
type: "COLLABROOM",
|
||||||
|
@ -240,10 +224,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapRecordingErrors(catcher, func)
|
function wrapRecordingErrors(catcher, func) {
|
||||||
{
|
return function() {
|
||||||
return function()
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return func.apply(this, Array.prototype.slice.call(arguments));
|
return func.apply(this, Array.prototype.slice.call(arguments));
|
||||||
|
@ -259,8 +241,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function callCatchingErrors(catcher, func)
|
function callCatchingErrors(catcher, func) {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wrapRecordingErrors(catcher, func)();
|
wrapRecordingErrors(catcher, func)();
|
||||||
|
@ -270,8 +251,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMessageFromServer(evt)
|
function handleMessageFromServer(evt) {
|
||||||
{
|
|
||||||
if (!getSocket()) return;
|
if (!getSocket()) return;
|
||||||
if (!evt.data) return;
|
if (!evt.data) return;
|
||||||
var wrapper = evt;
|
var wrapper = evt;
|
||||||
|
@ -334,12 +314,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
rev = newRev;
|
rev = newRev;
|
||||||
editor.applyPreparedChangesetToBase();
|
editor.applyPreparedChangesetToBase();
|
||||||
setStateIdle();
|
setStateIdle();
|
||||||
callCatchingErrors("onInternalAction", function()
|
callCatchingErrors("onInternalAction", function() {
|
||||||
{
|
|
||||||
callbacks.onInternalAction("commitAcceptedByServer");
|
callbacks.onInternalAction("commitAcceptedByServer");
|
||||||
});
|
});
|
||||||
callCatchingErrors("onConnectionTrouble", function()
|
callCatchingErrors("onConnectionTrouble", function() {
|
||||||
{
|
|
||||||
callbacks.onConnectionTrouble("OK");
|
callbacks.onConnectionTrouble("OK");
|
||||||
});
|
});
|
||||||
handleUserChanges();
|
handleUserChanges();
|
||||||
|
@ -386,12 +364,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
{
|
{
|
||||||
editor.applyPreparedChangesetToBase();
|
editor.applyPreparedChangesetToBase();
|
||||||
setStateIdle();
|
setStateIdle();
|
||||||
callCatchingErrors("onInternalAction", function()
|
callCatchingErrors("onInternalAction", function() {
|
||||||
{
|
|
||||||
callbacks.onInternalAction("commitAcceptedByServer");
|
callbacks.onInternalAction("commitAcceptedByServer");
|
||||||
});
|
});
|
||||||
callCatchingErrors("onConnectionTrouble", function()
|
callCatchingErrors("onConnectionTrouble", function() {
|
||||||
{
|
|
||||||
callbacks.onConnectionTrouble("OK");
|
callbacks.onConnectionTrouble("OK");
|
||||||
});
|
});
|
||||||
handleUserChanges();
|
handleUserChanges();
|
||||||
|
@ -503,8 +479,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
hooks.callAll('handleClientMessage_' + msg.type, {payload: msg.payload});
|
hooks.callAll('handleClientMessage_' + msg.type, {payload: msg.payload});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUserInfo(userInfo)
|
function updateUserInfo(userInfo) {
|
||||||
{
|
|
||||||
userInfo.userId = userId;
|
userInfo.userId = userId;
|
||||||
userSet[userId] = userInfo;
|
userSet[userId] = userInfo;
|
||||||
tellAceActiveAuthorInfo(userInfo);
|
tellAceActiveAuthorInfo(userInfo);
|
||||||
|
@ -516,13 +491,11 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function tellAceActiveAuthorInfo(userInfo)
|
function tellAceActiveAuthorInfo(userInfo) {
|
||||||
{
|
|
||||||
tellAceAuthorInfo(userInfo.userId, userInfo.colorId);
|
tellAceAuthorInfo(userInfo.userId, userInfo.colorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tellAceAuthorInfo(userId, colorId, inactive)
|
function tellAceAuthorInfo(userId, colorId, inactive) {
|
||||||
{
|
|
||||||
if(typeof colorId == "number")
|
if(typeof colorId == "number")
|
||||||
{
|
{
|
||||||
colorId = clientVars.colorPalette[colorId];
|
colorId = clientVars.colorPalette[colorId];
|
||||||
|
@ -544,18 +517,15 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fadeAceAuthorInfo(userInfo)
|
function fadeAceAuthorInfo(userInfo) {
|
||||||
{
|
|
||||||
tellAceAuthorInfo(userInfo.userId, userInfo.colorId, true);
|
tellAceAuthorInfo(userInfo.userId, userInfo.colorId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConnectedUsers()
|
function getConnectedUsers() {
|
||||||
{
|
|
||||||
return valuesArray(userSet);
|
return valuesArray(userSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tellAceAboutHistoricalAuthors(hadata)
|
function tellAceAboutHistoricalAuthors(hadata) {
|
||||||
{
|
|
||||||
for (var author in hadata)
|
for (var author in hadata)
|
||||||
{
|
{
|
||||||
var data = hadata[author];
|
var data = hadata[author];
|
||||||
|
@ -566,8 +536,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setChannelState(newChannelState, moreInfo)
|
function setChannelState(newChannelState, moreInfo) {
|
||||||
{
|
|
||||||
if (newChannelState != channelState)
|
if (newChannelState != channelState)
|
||||||
{
|
{
|
||||||
channelState = newChannelState;
|
channelState = newChannelState;
|
||||||
|
@ -575,11 +544,9 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function valuesArray(obj)
|
function valuesArray(obj) {
|
||||||
{
|
|
||||||
var array = [];
|
var array = [];
|
||||||
$.each(obj, function(k, v)
|
$.each(obj, function(k, v) {
|
||||||
{
|
|
||||||
array.push(v);
|
array.push(v);
|
||||||
});
|
});
|
||||||
return array;
|
return array;
|
||||||
|
@ -589,15 +556,12 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
// is connected for the first time.
|
// is connected for the first time.
|
||||||
var deferredActions = [];
|
var deferredActions = [];
|
||||||
|
|
||||||
function defer(func, tag)
|
function defer(func, tag) {
|
||||||
{
|
return function() {
|
||||||
return function()
|
|
||||||
{
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
|
|
||||||
function action()
|
function action() {
|
||||||
{
|
|
||||||
func.apply(that, args);
|
func.apply(that, args);
|
||||||
}
|
}
|
||||||
action.tag = tag;
|
action.tag = tag;
|
||||||
|
@ -612,8 +576,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doDeferredActions(tag)
|
function doDeferredActions(tag) {
|
||||||
{
|
|
||||||
var newArray = [];
|
var newArray = [];
|
||||||
for (var i = 0; i < deferredActions.length; i++)
|
for (var i = 0; i < deferredActions.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -630,8 +593,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
deferredActions = newArray;
|
deferredActions = newArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendClientMessage(msg)
|
function sendClientMessage(msg) {
|
||||||
{
|
|
||||||
sendMessage(
|
sendMessage(
|
||||||
{
|
{
|
||||||
type: "CLIENT_MESSAGE",
|
type: "CLIENT_MESSAGE",
|
||||||
|
@ -639,13 +601,11 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentRevisionNumber()
|
function getCurrentRevisionNumber() {
|
||||||
{
|
|
||||||
return rev;
|
return rev;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMissedChanges()
|
function getMissedChanges() {
|
||||||
{
|
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.userInfo = userSet[userId];
|
obj.userInfo = userSet[userId];
|
||||||
obj.baseRev = rev;
|
obj.baseRev = rev;
|
||||||
|
@ -664,30 +624,25 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStateIdle()
|
function setStateIdle() {
|
||||||
{
|
|
||||||
state = "IDLE";
|
state = "IDLE";
|
||||||
callbacks.onInternalAction("newlyIdle");
|
callbacks.onInternalAction("newlyIdle");
|
||||||
schedulePerhapsCallIdleFuncs();
|
schedulePerhapsCallIdleFuncs();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIsPendingRevision(value)
|
function setIsPendingRevision(value) {
|
||||||
{
|
|
||||||
isPendingRevision = value;
|
isPendingRevision = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function callWhenNotCommitting(func)
|
function callWhenNotCommitting(func) {
|
||||||
{
|
|
||||||
idleFuncs.push(func);
|
idleFuncs.push(func);
|
||||||
schedulePerhapsCallIdleFuncs();
|
schedulePerhapsCallIdleFuncs();
|
||||||
}
|
}
|
||||||
|
|
||||||
var idleFuncs = [];
|
var idleFuncs = [];
|
||||||
|
|
||||||
function schedulePerhapsCallIdleFuncs()
|
function schedulePerhapsCallIdleFuncs() {
|
||||||
{
|
setTimeout(function() {
|
||||||
setTimeout(function()
|
|
||||||
{
|
|
||||||
if (state == "IDLE")
|
if (state == "IDLE")
|
||||||
{
|
{
|
||||||
while (idleFuncs.length > 0)
|
while (idleFuncs.length > 0)
|
||||||
|
@ -700,36 +655,28 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = {
|
var self = {
|
||||||
setOnUserJoin: function(cb)
|
setOnUserJoin: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onUserJoin = cb;
|
callbacks.onUserJoin = cb;
|
||||||
},
|
},
|
||||||
setOnUserLeave: function(cb)
|
setOnUserLeave: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onUserLeave = cb;
|
callbacks.onUserLeave = cb;
|
||||||
},
|
},
|
||||||
setOnUpdateUserInfo: function(cb)
|
setOnUpdateUserInfo: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onUpdateUserInfo = cb;
|
callbacks.onUpdateUserInfo = cb;
|
||||||
},
|
},
|
||||||
setOnChannelStateChange: function(cb)
|
setOnChannelStateChange: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onChannelStateChange = cb;
|
callbacks.onChannelStateChange = cb;
|
||||||
},
|
},
|
||||||
setOnClientMessage: function(cb)
|
setOnClientMessage: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onClientMessage = cb;
|
callbacks.onClientMessage = cb;
|
||||||
},
|
},
|
||||||
setOnInternalAction: function(cb)
|
setOnInternalAction: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onInternalAction = cb;
|
callbacks.onInternalAction = cb;
|
||||||
},
|
},
|
||||||
setOnConnectionTrouble: function(cb)
|
setOnConnectionTrouble: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onConnectionTrouble = cb;
|
callbacks.onConnectionTrouble = cb;
|
||||||
},
|
},
|
||||||
setOnServerMessage: function(cb)
|
setOnServerMessage: function(cb) {
|
||||||
{
|
|
||||||
callbacks.onServerMessage = cb;
|
callbacks.onServerMessage = cb;
|
||||||
},
|
},
|
||||||
updateUserInfo: defer(updateUserInfo),
|
updateUserInfo: defer(updateUserInfo),
|
||||||
|
|
|
@ -26,26 +26,22 @@ var colorutils = {};
|
||||||
|
|
||||||
// Check that a given value is a css hex color value, e.g.
|
// Check that a given value is a css hex color value, e.g.
|
||||||
// "#ffffff" or "#fff"
|
// "#ffffff" or "#fff"
|
||||||
colorutils.isCssHex = function(cssColor)
|
colorutils.isCssHex = function(cssColor) {
|
||||||
{
|
|
||||||
return /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(cssColor);
|
return /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(cssColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "#ffffff" or "#fff" or "ffffff" or "fff" to [1.0, 1.0, 1.0]
|
// "#ffffff" or "#fff" or "ffffff" or "fff" to [1.0, 1.0, 1.0]
|
||||||
colorutils.css2triple = function(cssColor)
|
colorutils.css2triple = function(cssColor) {
|
||||||
{
|
|
||||||
var sixHex = colorutils.css2sixhex(cssColor);
|
var sixHex = colorutils.css2sixhex(cssColor);
|
||||||
|
|
||||||
function hexToFloat(hh)
|
function hexToFloat(hh) {
|
||||||
{
|
|
||||||
return Number("0x" + hh) / 255;
|
return Number("0x" + hh) / 255;
|
||||||
}
|
}
|
||||||
return [hexToFloat(sixHex.substr(0, 2)), hexToFloat(sixHex.substr(2, 2)), hexToFloat(sixHex.substr(4, 2))];
|
return [hexToFloat(sixHex.substr(0, 2)), hexToFloat(sixHex.substr(2, 2)), hexToFloat(sixHex.substr(4, 2))];
|
||||||
}
|
}
|
||||||
|
|
||||||
// "#ffffff" or "#fff" or "ffffff" or "fff" to "ffffff"
|
// "#ffffff" or "#fff" or "ffffff" or "fff" to "ffffff"
|
||||||
colorutils.css2sixhex = function(cssColor)
|
colorutils.css2sixhex = function(cssColor) {
|
||||||
{
|
|
||||||
var h = /[0-9a-fA-F]+/.exec(cssColor)[0];
|
var h = /[0-9a-fA-F]+/.exec(cssColor)[0];
|
||||||
if (h.length != 6)
|
if (h.length != 6)
|
||||||
{
|
{
|
||||||
|
@ -58,10 +54,8 @@ colorutils.css2sixhex = function(cssColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// [1.0, 1.0, 1.0] -> "#ffffff"
|
// [1.0, 1.0, 1.0] -> "#ffffff"
|
||||||
colorutils.triple2css = function(triple)
|
colorutils.triple2css = function(triple) {
|
||||||
{
|
function floatToHex(n) {
|
||||||
function floatToHex(n)
|
|
||||||
{
|
|
||||||
var n2 = colorutils.clamp(Math.round(n * 255), 0, 255);
|
var n2 = colorutils.clamp(Math.round(n * 255), 0, 255);
|
||||||
return ("0" + n2.toString(16)).slice(-2);
|
return ("0" + n2.toString(16)).slice(-2);
|
||||||
}
|
}
|
||||||
|
@ -69,71 +63,57 @@ colorutils.triple2css = function(triple)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
colorutils.clamp = function(v, bot, top)
|
colorutils.clamp = function(v, bot, top) {
|
||||||
{
|
|
||||||
return v < bot ? bot : (v > top ? top : v);
|
return v < bot ? bot : (v > top ? top : v);
|
||||||
};
|
};
|
||||||
colorutils.min3 = function(a, b, c)
|
colorutils.min3 = function(a, b, c) {
|
||||||
{
|
|
||||||
return (a < b) ? (a < c ? a : c) : (b < c ? b : c);
|
return (a < b) ? (a < c ? a : c) : (b < c ? b : c);
|
||||||
};
|
};
|
||||||
colorutils.max3 = function(a, b, c)
|
colorutils.max3 = function(a, b, c) {
|
||||||
{
|
|
||||||
return (a > b) ? (a > c ? a : c) : (b > c ? b : c);
|
return (a > b) ? (a > c ? a : c) : (b > c ? b : c);
|
||||||
};
|
};
|
||||||
colorutils.colorMin = function(c)
|
colorutils.colorMin = function(c) {
|
||||||
{
|
|
||||||
return colorutils.min3(c[0], c[1], c[2]);
|
return colorutils.min3(c[0], c[1], c[2]);
|
||||||
};
|
};
|
||||||
colorutils.colorMax = function(c)
|
colorutils.colorMax = function(c) {
|
||||||
{
|
|
||||||
return colorutils.max3(c[0], c[1], c[2]);
|
return colorutils.max3(c[0], c[1], c[2]);
|
||||||
};
|
};
|
||||||
colorutils.scale = function(v, bot, top)
|
colorutils.scale = function(v, bot, top) {
|
||||||
{
|
|
||||||
return colorutils.clamp(bot + v * (top - bot), 0, 1);
|
return colorutils.clamp(bot + v * (top - bot), 0, 1);
|
||||||
};
|
};
|
||||||
colorutils.unscale = function(v, bot, top)
|
colorutils.unscale = function(v, bot, top) {
|
||||||
{
|
|
||||||
return colorutils.clamp((v - bot) / (top - bot), 0, 1);
|
return colorutils.clamp((v - bot) / (top - bot), 0, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
colorutils.scaleColor = function(c, bot, top)
|
colorutils.scaleColor = function(c, bot, top) {
|
||||||
{
|
|
||||||
return [colorutils.scale(c[0], bot, top), colorutils.scale(c[1], bot, top), colorutils.scale(c[2], bot, top)];
|
return [colorutils.scale(c[0], bot, top), colorutils.scale(c[1], bot, top), colorutils.scale(c[2], bot, top)];
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.unscaleColor = function(c, bot, top)
|
colorutils.unscaleColor = function(c, bot, top) {
|
||||||
{
|
|
||||||
return [colorutils.unscale(c[0], bot, top), colorutils.unscale(c[1], bot, top), colorutils.unscale(c[2], bot, top)];
|
return [colorutils.unscale(c[0], bot, top), colorutils.unscale(c[1], bot, top), colorutils.unscale(c[2], bot, top)];
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.luminosity = function(c)
|
colorutils.luminosity = function(c) {
|
||||||
{
|
|
||||||
// rule of thumb for RGB brightness; 1.0 is white
|
// rule of thumb for RGB brightness; 1.0 is white
|
||||||
return c[0] * 0.30 + c[1] * 0.59 + c[2] * 0.11;
|
return c[0] * 0.30 + c[1] * 0.59 + c[2] * 0.11;
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.saturate = function(c)
|
colorutils.saturate = function(c) {
|
||||||
{
|
|
||||||
var min = colorutils.colorMin(c);
|
var min = colorutils.colorMin(c);
|
||||||
var max = colorutils.colorMax(c);
|
var max = colorutils.colorMax(c);
|
||||||
if (max - min <= 0) return [1.0, 1.0, 1.0];
|
if (max - min <= 0) return [1.0, 1.0, 1.0];
|
||||||
return colorutils.unscaleColor(c, min, max);
|
return colorutils.unscaleColor(c, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.blend = function(c1, c2, t)
|
colorutils.blend = function(c1, c2, t) {
|
||||||
{
|
|
||||||
return [colorutils.scale(t, c1[0], c2[0]), colorutils.scale(t, c1[1], c2[1]), colorutils.scale(t, c1[2], c2[2])];
|
return [colorutils.scale(t, c1[0], c2[0]), colorutils.scale(t, c1[1], c2[1]), colorutils.scale(t, c1[2], c2[2])];
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.invert = function(c)
|
colorutils.invert = function(c) {
|
||||||
{
|
|
||||||
return [1 - c[0], 1 - c[1], 1- c[2]];
|
return [1 - c[0], 1 - c[1], 1- c[2]];
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.complementary = function(c)
|
colorutils.complementary = function(c) {
|
||||||
{
|
|
||||||
var inv = colorutils.invert(c);
|
var inv = colorutils.invert(c);
|
||||||
return [
|
return [
|
||||||
(inv[0] >= c[0]) ? Math.min(inv[0] * 1.30, 1) : (c[0] * 0.30),
|
(inv[0] >= c[0]) ? Math.min(inv[0] * 1.30, 1) : (c[0] * 0.30),
|
||||||
|
@ -142,8 +122,7 @@ colorutils.complementary = function(c)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
colorutils.textColorFromBackgroundColor = function(bgcolor, skinName)
|
colorutils.textColorFromBackgroundColor = function(bgcolor, skinName) {
|
||||||
{
|
|
||||||
var white = skinName == 'colibris' ? 'var(--super-light-color)' : '#fff';
|
var white = skinName == 'colibris' ? 'var(--super-light-color)' : '#fff';
|
||||||
var black = skinName == 'colibris' ? 'var(--super-dark-color)' : '#222';
|
var black = skinName == 'colibris' ? 'var(--super-dark-color)' : '#222';
|
||||||
|
|
||||||
|
|
|
@ -30,53 +30,43 @@ var Changeset = require('./Changeset');
|
||||||
var hooks = require('./pluginfw/hooks');
|
var hooks = require('./pluginfw/hooks');
|
||||||
var _ = require('./underscore');
|
var _ = require('./underscore');
|
||||||
|
|
||||||
function sanitizeUnicode(s)
|
function sanitizeUnicode(s) {
|
||||||
{
|
|
||||||
return UNorm.nfc(s);
|
return UNorm.nfc(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeContentCollector(collectStyles, abrowser, apool, domInterface, className2Author)
|
function makeContentCollector(collectStyles, abrowser, apool, domInterface, className2Author) {
|
||||||
{
|
|
||||||
abrowser = abrowser || {};
|
abrowser = abrowser || {};
|
||||||
// I don't like the above.
|
// I don't like the above.
|
||||||
|
|
||||||
var dom = domInterface || {
|
var dom = domInterface || {
|
||||||
isNodeText: function(n)
|
isNodeText: function(n) {
|
||||||
{
|
|
||||||
return (n.nodeType == 3);
|
return (n.nodeType == 3);
|
||||||
},
|
},
|
||||||
nodeTagName: function(n)
|
nodeTagName: function(n) {
|
||||||
{
|
|
||||||
return n.tagName;
|
return n.tagName;
|
||||||
},
|
},
|
||||||
nodeValue: function(n)
|
nodeValue: function(n) {
|
||||||
{
|
|
||||||
return n.nodeValue;
|
return n.nodeValue;
|
||||||
},
|
},
|
||||||
nodeNumChildren: function(n)
|
nodeNumChildren: function(n) {
|
||||||
{
|
|
||||||
if(n.childNodes == null) return 0;
|
if(n.childNodes == null) return 0;
|
||||||
return n.childNodes.length;
|
return n.childNodes.length;
|
||||||
},
|
},
|
||||||
nodeChild: function(n, i)
|
nodeChild: function(n, i) {
|
||||||
{
|
|
||||||
if(n.childNodes.item == null){
|
if(n.childNodes.item == null){
|
||||||
return n.childNodes[i];
|
return n.childNodes[i];
|
||||||
}
|
}
|
||||||
return n.childNodes.item(i);
|
return n.childNodes.item(i);
|
||||||
},
|
},
|
||||||
nodeProp: function(n, p)
|
nodeProp: function(n, p) {
|
||||||
{
|
|
||||||
return n[p];
|
return n[p];
|
||||||
},
|
},
|
||||||
nodeAttr: function(n, a)
|
nodeAttr: function(n, a) {
|
||||||
{
|
|
||||||
if(n.getAttribute != null) return n.getAttribute(a);
|
if(n.getAttribute != null) return n.getAttribute(a);
|
||||||
if(n.attribs != null) return n.attribs[a];
|
if(n.attribs != null) return n.attribs[a];
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
optNodeInnerHTML: function(n)
|
optNodeInnerHTML: function(n) {
|
||||||
{
|
|
||||||
return n.innerHTML;
|
return n.innerHTML;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -92,66 +82,54 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
_blockElems[element] = 1;
|
_blockElems[element] = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
function isBlockElement(n)
|
function isBlockElement(n) {
|
||||||
{
|
|
||||||
return !!_blockElems[(dom.nodeTagName(n) || "").toLowerCase()];
|
return !!_blockElems[(dom.nodeTagName(n) || "").toLowerCase()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function textify(str)
|
function textify(str) {
|
||||||
{
|
|
||||||
return sanitizeUnicode(
|
return sanitizeUnicode(
|
||||||
str.replace(/(\n | \n)/g, ' ').replace(/[\n\r ]/g, ' ').replace(/\xa0/g, ' ').replace(/\t/g, ' '));
|
str.replace(/(\n | \n)/g, ' ').replace(/[\n\r ]/g, ' ').replace(/\xa0/g, ' ').replace(/\t/g, ' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAssoc(node, name)
|
function getAssoc(node, name) {
|
||||||
{
|
|
||||||
return dom.nodeProp(node, "_magicdom_" + name);
|
return dom.nodeProp(node, "_magicdom_" + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
var lines = (function()
|
var lines = (function() {
|
||||||
{
|
|
||||||
var textArray = [];
|
var textArray = [];
|
||||||
var attribsArray = [];
|
var attribsArray = [];
|
||||||
var attribsBuilder = null;
|
var attribsBuilder = null;
|
||||||
var op = Changeset.newOp('+');
|
var op = Changeset.newOp('+');
|
||||||
var self = {
|
var self = {
|
||||||
length: function()
|
length: function() {
|
||||||
{
|
|
||||||
return textArray.length;
|
return textArray.length;
|
||||||
},
|
},
|
||||||
atColumnZero: function()
|
atColumnZero: function() {
|
||||||
{
|
|
||||||
return textArray[textArray.length - 1] === "";
|
return textArray[textArray.length - 1] === "";
|
||||||
},
|
},
|
||||||
startNew: function()
|
startNew: function() {
|
||||||
{
|
|
||||||
textArray.push("");
|
textArray.push("");
|
||||||
self.flush(true);
|
self.flush(true);
|
||||||
attribsBuilder = Changeset.smartOpAssembler();
|
attribsBuilder = Changeset.smartOpAssembler();
|
||||||
},
|
},
|
||||||
textOfLine: function(i)
|
textOfLine: function(i) {
|
||||||
{
|
|
||||||
return textArray[i];
|
return textArray[i];
|
||||||
},
|
},
|
||||||
appendText: function(txt, attrString)
|
appendText: function(txt, attrString) {
|
||||||
{
|
|
||||||
textArray[textArray.length - 1] += txt;
|
textArray[textArray.length - 1] += txt;
|
||||||
//dmesg(txt+" / "+attrString);
|
//dmesg(txt+" / "+attrString);
|
||||||
op.attribs = attrString;
|
op.attribs = attrString;
|
||||||
op.chars = txt.length;
|
op.chars = txt.length;
|
||||||
attribsBuilder.append(op);
|
attribsBuilder.append(op);
|
||||||
},
|
},
|
||||||
textLines: function()
|
textLines: function() {
|
||||||
{
|
|
||||||
return textArray.slice();
|
return textArray.slice();
|
||||||
},
|
},
|
||||||
attribLines: function()
|
attribLines: function() {
|
||||||
{
|
|
||||||
return attribsArray;
|
return attribsArray;
|
||||||
},
|
},
|
||||||
// call flush only when you're done
|
// call flush only when you're done
|
||||||
flush: function(withNewline)
|
flush: function(withNewline) {
|
||||||
{
|
|
||||||
if (attribsBuilder)
|
if (attribsBuilder)
|
||||||
{
|
{
|
||||||
attribsArray.push(attribsBuilder.toString());
|
attribsArray.push(attribsBuilder.toString());
|
||||||
|
@ -164,8 +142,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
}());
|
}());
|
||||||
var cc = {};
|
var cc = {};
|
||||||
|
|
||||||
function _ensureColumnZero(state)
|
function _ensureColumnZero(state) {
|
||||||
{
|
|
||||||
if (!lines.atColumnZero())
|
if (!lines.atColumnZero())
|
||||||
{
|
{
|
||||||
cc.startNewLine(state);
|
cc.startNewLine(state);
|
||||||
|
@ -174,8 +151,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
var selection, startPoint, endPoint;
|
var selection, startPoint, endPoint;
|
||||||
var selStart = [-1, -1],
|
var selStart = [-1, -1],
|
||||||
selEnd = [-1, -1];
|
selEnd = [-1, -1];
|
||||||
function _isEmpty(node, state)
|
function _isEmpty(node, state) {
|
||||||
{
|
|
||||||
// consider clean blank lines pasted in IE to be empty
|
// consider clean blank lines pasted in IE to be empty
|
||||||
if (dom.nodeNumChildren(node) == 0) return true;
|
if (dom.nodeNumChildren(node) == 0) return true;
|
||||||
if (dom.nodeNumChildren(node) == 1 && getAssoc(node, "shouldBeEmpty") && dom.optNodeInnerHTML(node) == " " && !getAssoc(node, "unpasted"))
|
if (dom.nodeNumChildren(node) == 1 && getAssoc(node, "shouldBeEmpty") && dom.optNodeInnerHTML(node) == " " && !getAssoc(node, "unpasted"))
|
||||||
|
@ -191,8 +167,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _pointHere(charsAfter, state)
|
function _pointHere(charsAfter, state) {
|
||||||
{
|
|
||||||
var ln = lines.length() - 1;
|
var ln = lines.length() - 1;
|
||||||
var chr = lines.textOfLine(ln).length;
|
var chr = lines.textOfLine(ln).length;
|
||||||
if (chr == 0 && !_.isEmpty(state.lineAttributes))
|
if (chr == 0 && !_.isEmpty(state.lineAttributes))
|
||||||
|
@ -203,13 +178,11 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
return [ln, chr];
|
return [ln, chr];
|
||||||
}
|
}
|
||||||
|
|
||||||
function _reachBlockPoint(nd, idx, state)
|
function _reachBlockPoint(nd, idx, state) {
|
||||||
{
|
|
||||||
if (!dom.isNodeText(nd)) _reachPoint(nd, idx, state);
|
if (!dom.isNodeText(nd)) _reachPoint(nd, idx, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _reachPoint(nd, idx, state)
|
function _reachPoint(nd, idx, state) {
|
||||||
{
|
|
||||||
if (startPoint && nd == startPoint.node && startPoint.index == idx)
|
if (startPoint && nd == startPoint.node && startPoint.index == idx)
|
||||||
{
|
{
|
||||||
selStart = _pointHere(0, state);
|
selStart = _pointHere(0, state);
|
||||||
|
@ -219,16 +192,13 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
selEnd = _pointHere(0, state);
|
selEnd = _pointHere(0, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cc.incrementFlag = function(state, flagName)
|
cc.incrementFlag = function(state, flagName) {
|
||||||
{
|
|
||||||
state.flags[flagName] = (state.flags[flagName] || 0) + 1;
|
state.flags[flagName] = (state.flags[flagName] || 0) + 1;
|
||||||
}
|
}
|
||||||
cc.decrementFlag = function(state, flagName)
|
cc.decrementFlag = function(state, flagName) {
|
||||||
{
|
|
||||||
state.flags[flagName]--;
|
state.flags[flagName]--;
|
||||||
}
|
}
|
||||||
cc.incrementAttrib = function(state, attribName)
|
cc.incrementAttrib = function(state, attribName) {
|
||||||
{
|
|
||||||
if (!state.attribs[attribName])
|
if (!state.attribs[attribName])
|
||||||
{
|
{
|
||||||
state.attribs[attribName] = 1;
|
state.attribs[attribName] = 1;
|
||||||
|
@ -239,14 +209,12 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
}
|
}
|
||||||
_recalcAttribString(state);
|
_recalcAttribString(state);
|
||||||
}
|
}
|
||||||
cc.decrementAttrib = function(state, attribName)
|
cc.decrementAttrib = function(state, attribName) {
|
||||||
{
|
|
||||||
state.attribs[attribName]--;
|
state.attribs[attribName]--;
|
||||||
_recalcAttribString(state);
|
_recalcAttribString(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _enterList(state, listType)
|
function _enterList(state, listType) {
|
||||||
{
|
|
||||||
if(!listType) return;
|
if(!listType) return;
|
||||||
var oldListType = state.lineAttributes['list'];
|
var oldListType = state.lineAttributes['list'];
|
||||||
if (listType != 'none')
|
if (listType != 'none')
|
||||||
|
@ -268,8 +236,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
return oldListType;
|
return oldListType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _exitList(state, oldListType)
|
function _exitList(state, oldListType) {
|
||||||
{
|
|
||||||
if (state.lineAttributes['list']) {
|
if (state.lineAttributes['list']) {
|
||||||
state.listNesting--;
|
state.listNesting--;
|
||||||
}
|
}
|
||||||
|
@ -283,8 +250,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
_recalcAttribString(state);
|
_recalcAttribString(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _enterAuthor(state, author)
|
function _enterAuthor(state, author) {
|
||||||
{
|
|
||||||
var oldAuthor = state.author;
|
var oldAuthor = state.author;
|
||||||
state.authorLevel = (state.authorLevel || 0) + 1;
|
state.authorLevel = (state.authorLevel || 0) + 1;
|
||||||
state.author = author;
|
state.author = author;
|
||||||
|
@ -292,15 +258,13 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
return oldAuthor;
|
return oldAuthor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _exitAuthor(state, oldAuthor)
|
function _exitAuthor(state, oldAuthor) {
|
||||||
{
|
|
||||||
state.authorLevel--;
|
state.authorLevel--;
|
||||||
state.author = oldAuthor;
|
state.author = oldAuthor;
|
||||||
_recalcAttribString(state);
|
_recalcAttribString(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _recalcAttribString(state)
|
function _recalcAttribString(state) {
|
||||||
{
|
|
||||||
var lst = [];
|
var lst = [];
|
||||||
for (var a in state.attribs)
|
for (var a in state.attribs)
|
||||||
{
|
{
|
||||||
|
@ -338,8 +302,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
state.attribString = Changeset.makeAttribsString('+', lst, apool);
|
state.attribString = Changeset.makeAttribsString('+', lst, apool);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _produceLineAttributesMarker(state)
|
function _produceLineAttributesMarker(state) {
|
||||||
{
|
|
||||||
// TODO: This has to go to AttributeManager.
|
// TODO: This has to go to AttributeManager.
|
||||||
var attributes = [
|
var attributes = [
|
||||||
['lmkr', '1'],
|
['lmkr', '1'],
|
||||||
|
@ -351,8 +314,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
);
|
);
|
||||||
lines.appendText('*', Changeset.makeAttribsString('+', attributes , apool));
|
lines.appendText('*', Changeset.makeAttribsString('+', attributes , apool));
|
||||||
}
|
}
|
||||||
cc.startNewLine = function(state)
|
cc.startNewLine = function(state) {
|
||||||
{
|
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
var atBeginningOfLine = lines.textOfLine(lines.length() - 1).length == 0;
|
var atBeginningOfLine = lines.textOfLine(lines.length() - 1).length == 0;
|
||||||
|
@ -363,8 +325,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
}
|
}
|
||||||
lines.startNew();
|
lines.startNew();
|
||||||
}
|
}
|
||||||
cc.notifySelection = function(sel)
|
cc.notifySelection = function(sel) {
|
||||||
{
|
|
||||||
if (sel)
|
if (sel)
|
||||||
{
|
{
|
||||||
selection = sel;
|
selection = sel;
|
||||||
|
@ -372,14 +333,12 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
endPoint = selection.endPoint;
|
endPoint = selection.endPoint;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cc.doAttrib = function(state, na)
|
cc.doAttrib = function(state, na) {
|
||||||
{
|
|
||||||
state.localAttribs = (state.localAttribs || []);
|
state.localAttribs = (state.localAttribs || []);
|
||||||
state.localAttribs.push(na);
|
state.localAttribs.push(na);
|
||||||
cc.incrementAttrib(state, na);
|
cc.incrementAttrib(state, na);
|
||||||
};
|
};
|
||||||
cc.collectContent = function(node, state)
|
cc.collectContent = function(node, state) {
|
||||||
{
|
|
||||||
if (!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
state = {
|
state = {
|
||||||
|
@ -746,8 +705,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
state.localAttribs = localAttribs;
|
state.localAttribs = localAttribs;
|
||||||
};
|
};
|
||||||
// can pass a falsy value for end of doc
|
// can pass a falsy value for end of doc
|
||||||
cc.notifyNextNode = function(node)
|
cc.notifyNextNode = function(node) {
|
||||||
{
|
|
||||||
// an "empty block" won't end a line; this addresses an issue in IE with
|
// an "empty block" won't end a line; this addresses an issue in IE with
|
||||||
// typing into a blank line at the end of the document. typed text
|
// typing into a blank line at the end of the document. typed text
|
||||||
// goes into the body, and the empty line div still looks clean.
|
// goes into the body, and the empty line div still looks clean.
|
||||||
|
@ -759,25 +717,21 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// each returns [line, char] or [-1,-1]
|
// each returns [line, char] or [-1,-1]
|
||||||
var getSelectionStart = function()
|
var getSelectionStart = function() {
|
||||||
{
|
|
||||||
return selStart;
|
return selStart;
|
||||||
};
|
};
|
||||||
var getSelectionEnd = function()
|
var getSelectionEnd = function() {
|
||||||
{
|
|
||||||
return selEnd;
|
return selEnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns array of strings for lines found, last entry will be "" if
|
// returns array of strings for lines found, last entry will be "" if
|
||||||
// last line is complete (i.e. if a following span should be on a new line).
|
// last line is complete (i.e. if a following span should be on a new line).
|
||||||
// can be called at any point
|
// can be called at any point
|
||||||
cc.getLines = function()
|
cc.getLines = function() {
|
||||||
{
|
|
||||||
return lines.textLines();
|
return lines.textLines();
|
||||||
};
|
};
|
||||||
|
|
||||||
cc.finish = function()
|
cc.finish = function() {
|
||||||
{
|
|
||||||
lines.flush();
|
lines.flush();
|
||||||
var lineAttribs = lines.attribLines();
|
var lineAttribs = lines.attribLines();
|
||||||
var lineStrings = cc.getLines();
|
var lineStrings = cc.getLines();
|
||||||
|
@ -788,8 +742,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
var ss = getSelectionStart();
|
var ss = getSelectionStart();
|
||||||
var se = getSelectionEnd();
|
var se = getSelectionEnd();
|
||||||
|
|
||||||
function fixLongLines()
|
function fixLongLines() {
|
||||||
{
|
|
||||||
// design mode does not deal with with really long lines!
|
// design mode does not deal with with really long lines!
|
||||||
var lineLimit = 2000; // chars
|
var lineLimit = 2000; // chars
|
||||||
var buffer = 10; // chars allowed over before wrapping
|
var buffer = 10; // chars allowed over before wrapping
|
||||||
|
@ -819,8 +772,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
|
||||||
newAttribStrings.push(oldAttribString);
|
newAttribStrings.push(oldAttribString);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixLineNumber(lineChar)
|
function fixLineNumber(lineChar) {
|
||||||
{
|
|
||||||
if (lineChar[0] < 0) return;
|
if (lineChar[0] < 0) return;
|
||||||
var n = lineChar[0];
|
var n = lineChar[0];
|
||||||
var c = lineChar[1];
|
var c = lineChar[1];
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function makeCSSManager(emptyStylesheetTitle, doc)
|
function makeCSSManager(emptyStylesheetTitle, doc) {
|
||||||
{
|
|
||||||
if (doc === true)
|
if (doc === true)
|
||||||
{
|
{
|
||||||
doc = 'parent';
|
doc = 'parent';
|
||||||
|
@ -29,8 +28,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
|
||||||
doc = 'inner';
|
doc = 'inner';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSheetByTitle(title)
|
function getSheetByTitle(title) {
|
||||||
{
|
|
||||||
if (doc === 'parent')
|
if (doc === 'parent')
|
||||||
{
|
{
|
||||||
win = window.parent.parent;
|
win = window.parent.parent;
|
||||||
|
@ -59,26 +57,22 @@ function makeCSSManager(emptyStylesheetTitle, doc)
|
||||||
|
|
||||||
var browserSheet = getSheetByTitle(emptyStylesheetTitle);
|
var browserSheet = getSheetByTitle(emptyStylesheetTitle);
|
||||||
|
|
||||||
function browserRules()
|
function browserRules() {
|
||||||
{
|
|
||||||
return (browserSheet.cssRules || browserSheet.rules);
|
return (browserSheet.cssRules || browserSheet.rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
function browserDeleteRule(i)
|
function browserDeleteRule(i) {
|
||||||
{
|
|
||||||
if (browserSheet.deleteRule) browserSheet.deleteRule(i);
|
if (browserSheet.deleteRule) browserSheet.deleteRule(i);
|
||||||
else browserSheet.removeRule(i);
|
else browserSheet.removeRule(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
function browserInsertRule(i, selector)
|
function browserInsertRule(i, selector) {
|
||||||
{
|
|
||||||
if (browserSheet.insertRule) browserSheet.insertRule(selector + ' {}', i);
|
if (browserSheet.insertRule) browserSheet.insertRule(selector + ' {}', i);
|
||||||
else browserSheet.addRule(selector, null, i);
|
else browserSheet.addRule(selector, null, i);
|
||||||
}
|
}
|
||||||
var selectorList = [];
|
var selectorList = [];
|
||||||
|
|
||||||
function indexOfSelector(selector)
|
function indexOfSelector(selector) {
|
||||||
{
|
|
||||||
for (var i = 0; i < selectorList.length; i++)
|
for (var i = 0; i < selectorList.length; i++)
|
||||||
{
|
{
|
||||||
if (selectorList[i] == selector)
|
if (selectorList[i] == selector)
|
||||||
|
@ -89,8 +83,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectorStyle(selector)
|
function selectorStyle(selector) {
|
||||||
{
|
|
||||||
var i = indexOfSelector(selector);
|
var i = indexOfSelector(selector);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
{
|
{
|
||||||
|
@ -102,8 +95,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
|
||||||
return browserRules().item(i).style;
|
return browserRules().item(i).style;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSelectorStyle(selector)
|
function removeSelectorStyle(selector) {
|
||||||
{
|
|
||||||
var i = indexOfSelector(selector);
|
var i = indexOfSelector(selector);
|
||||||
if (i >= 0)
|
if (i >= 0)
|
||||||
{
|
{
|
||||||
|
@ -115,8 +107,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
|
||||||
return {
|
return {
|
||||||
selectorStyle: selectorStyle,
|
selectorStyle: selectorStyle,
|
||||||
removeSelectorStyle: removeSelectorStyle,
|
removeSelectorStyle: removeSelectorStyle,
|
||||||
info: function()
|
info: function() {
|
||||||
{
|
|
||||||
return selectorList.length + ":" + browserRules().length;
|
return selectorList.length + ":" + browserRules().length;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,13 +35,11 @@ var noop = function(){};
|
||||||
|
|
||||||
var domline = {};
|
var domline = {};
|
||||||
|
|
||||||
domline.addToLineClass = function(lineClass, cls)
|
domline.addToLineClass = function(lineClass, cls) {
|
||||||
{
|
|
||||||
// an "empty span" at any point can be used to add classes to
|
// an "empty span" at any point can be used to add classes to
|
||||||
// the line, using line:className. otherwise, we ignore
|
// the line, using line:className. otherwise, we ignore
|
||||||
// the span.
|
// the span.
|
||||||
cls.replace(/\S+/g, function(c)
|
cls.replace(/\S+/g, function(c) {
|
||||||
{
|
|
||||||
if (c.indexOf("line:") == 0)
|
if (c.indexOf("line:") == 0)
|
||||||
{
|
{
|
||||||
// add class to line
|
// add class to line
|
||||||
|
@ -53,8 +51,7 @@ domline.addToLineClass = function(lineClass, cls)
|
||||||
|
|
||||||
// if "document" is falsy we don't create a DOM node, just
|
// if "document" is falsy we don't create a DOM node, just
|
||||||
// an object with innerHTML and className
|
// an object with innerHTML and className
|
||||||
domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) {
|
||||||
{
|
|
||||||
var result = {
|
var result = {
|
||||||
node: null,
|
node: null,
|
||||||
appendSpan: noop,
|
appendSpan: noop,
|
||||||
|
@ -84,8 +81,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
postHtml = '';
|
postHtml = '';
|
||||||
var curHTML = null;
|
var curHTML = null;
|
||||||
|
|
||||||
function processSpaces(s)
|
function processSpaces(s) {
|
||||||
{
|
|
||||||
return domline.processSpaces(s, doesWrap);
|
return domline.processSpaces(s, doesWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +89,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
var perHtmlLineProcess = (doesWrap ? processSpaces : _.identity);
|
var perHtmlLineProcess = (doesWrap ? processSpaces : _.identity);
|
||||||
var lineClass = 'ace-line';
|
var lineClass = 'ace-line';
|
||||||
|
|
||||||
result.appendSpan = function(txt, cls)
|
result.appendSpan = function(txt, cls) {
|
||||||
{
|
|
||||||
|
|
||||||
var processedMarker = false;
|
var processedMarker = false;
|
||||||
// Handle lineAttributeMarker, if present
|
// Handle lineAttributeMarker, if present
|
||||||
|
@ -106,8 +101,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
_.map(hooks.callAll("aceDomLinePreProcessLineAttributes", {
|
_.map(hooks.callAll("aceDomLinePreProcessLineAttributes", {
|
||||||
domline: domline,
|
domline: domline,
|
||||||
cls: cls
|
cls: cls
|
||||||
}), function(modifier)
|
}), function(modifier) {
|
||||||
{
|
|
||||||
preHtml += modifier.preHtml;
|
preHtml += modifier.preHtml;
|
||||||
postHtml += modifier.postHtml;
|
postHtml += modifier.postHtml;
|
||||||
processedMarker |= modifier.processedMarker;
|
processedMarker |= modifier.processedMarker;
|
||||||
|
@ -141,8 +135,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
_.map(hooks.callAll("aceDomLineProcessLineAttributes", {
|
_.map(hooks.callAll("aceDomLineProcessLineAttributes", {
|
||||||
domline: domline,
|
domline: domline,
|
||||||
cls: cls
|
cls: cls
|
||||||
}), function(modifier)
|
}), function(modifier) {
|
||||||
{
|
|
||||||
preHtml += modifier.preHtml;
|
preHtml += modifier.preHtml;
|
||||||
postHtml += modifier.postHtml;
|
postHtml += modifier.postHtml;
|
||||||
processedMarker |= modifier.processedMarker;
|
processedMarker |= modifier.processedMarker;
|
||||||
|
@ -156,16 +149,14 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
var simpleTags = null;
|
var simpleTags = null;
|
||||||
if (cls.indexOf('url') >= 0)
|
if (cls.indexOf('url') >= 0)
|
||||||
{
|
{
|
||||||
cls = cls.replace(/(^| )url:(\S+)/g, function(x0, space, url)
|
cls = cls.replace(/(^| )url:(\S+)/g, function(x0, space, url) {
|
||||||
{
|
|
||||||
href = url;
|
href = url;
|
||||||
return space + "url";
|
return space + "url";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (cls.indexOf('tag') >= 0)
|
if (cls.indexOf('tag') >= 0)
|
||||||
{
|
{
|
||||||
cls = cls.replace(/(^| )tag:(\S+)/g, function(x0, space, tag)
|
cls = cls.replace(/(^| )tag:(\S+)/g, function(x0, space, tag) {
|
||||||
{
|
|
||||||
if (!simpleTags) simpleTags = [];
|
if (!simpleTags) simpleTags = [];
|
||||||
simpleTags.push(tag.toLowerCase());
|
simpleTags.push(tag.toLowerCase());
|
||||||
return space + tag;
|
return space + tag;
|
||||||
|
@ -178,8 +169,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
_.map(hooks.callAll("aceCreateDomLine", {
|
_.map(hooks.callAll("aceCreateDomLine", {
|
||||||
domline: domline,
|
domline: domline,
|
||||||
cls: cls
|
cls: cls
|
||||||
}), function(modifier)
|
}), function(modifier) {
|
||||||
{
|
|
||||||
cls = modifier.cls;
|
cls = modifier.cls;
|
||||||
extraOpenTags = extraOpenTags + modifier.extraOpenTags;
|
extraOpenTags = extraOpenTags + modifier.extraOpenTags;
|
||||||
extraCloseTags = modifier.extraCloseTags + extraCloseTags;
|
extraCloseTags = modifier.extraCloseTags + extraCloseTags;
|
||||||
|
@ -218,15 +208,13 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
html.push('<span class="', Security.escapeHTMLAttribute(cls || ''), '">', extraOpenTags, perTextNodeProcess(Security.escapeHTML(txt)), extraCloseTags, '</span>');
|
html.push('<span class="', Security.escapeHTMLAttribute(cls || ''), '">', extraOpenTags, perTextNodeProcess(Security.escapeHTML(txt)), extraCloseTags, '</span>');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
result.clearSpans = function()
|
result.clearSpans = function() {
|
||||||
{
|
|
||||||
html = [];
|
html = [];
|
||||||
lineClass = 'ace-line';
|
lineClass = 'ace-line';
|
||||||
result.lineMarker = 0;
|
result.lineMarker = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
function writeHTML()
|
function writeHTML() {
|
||||||
{
|
|
||||||
var newHTML = perHtmlLineProcess(html.join(''));
|
var newHTML = perHtmlLineProcess(html.join(''));
|
||||||
if (!newHTML)
|
if (!newHTML)
|
||||||
{
|
{
|
||||||
|
@ -257,23 +245,20 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
}
|
}
|
||||||
result.prepareForAdd = writeHTML;
|
result.prepareForAdd = writeHTML;
|
||||||
result.finishUpdate = writeHTML;
|
result.finishUpdate = writeHTML;
|
||||||
result.getInnerHTML = function()
|
result.getInnerHTML = function() {
|
||||||
{
|
|
||||||
return curHTML || '';
|
return curHTML || '';
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
domline.processSpaces = function(s, doesWrap)
|
domline.processSpaces = function(s, doesWrap) {
|
||||||
{
|
|
||||||
if (s.indexOf("<") < 0 && !doesWrap)
|
if (s.indexOf("<") < 0 && !doesWrap)
|
||||||
{
|
{
|
||||||
// short-cut
|
// short-cut
|
||||||
return s.replace(/ /g, ' ');
|
return s.replace(/ /g, ' ');
|
||||||
}
|
}
|
||||||
var parts = [];
|
var parts = [];
|
||||||
s.replace(/<[^>]*>?| |[^ <]+/g, function(m)
|
s.replace(/<[^>]*>?| |[^ <]+/g, function(m) {
|
||||||
{
|
|
||||||
parts.push(m);
|
parts.push(m);
|
||||||
});
|
});
|
||||||
if (doesWrap)
|
if (doesWrap)
|
||||||
|
|
|
@ -44,10 +44,8 @@ linestylefilter.ATTRIB_CLASSES = {
|
||||||
var lineAttributeMarker = 'lineAttribMarker';
|
var lineAttributeMarker = 'lineAttribMarker';
|
||||||
exports.lineAttributeMarker = lineAttributeMarker;
|
exports.lineAttributeMarker = lineAttributeMarker;
|
||||||
|
|
||||||
linestylefilter.getAuthorClassName = function(author)
|
linestylefilter.getAuthorClassName = function(author) {
|
||||||
{
|
return "author-" + author.replace(/[^a-y0-9]/g, function(c) {
|
||||||
return "author-" + author.replace(/[^a-y0-9]/g, function(c)
|
|
||||||
{
|
|
||||||
if (c == ".") return "-";
|
if (c == ".") return "-";
|
||||||
return 'z' + c.charCodeAt(0) + 'z';
|
return 'z' + c.charCodeAt(0) + 'z';
|
||||||
});
|
});
|
||||||
|
@ -55,8 +53,7 @@ linestylefilter.getAuthorClassName = function(author)
|
||||||
|
|
||||||
// lineLength is without newline; aline includes newline,
|
// lineLength is without newline; aline includes newline,
|
||||||
// but may be falsy if lineLength == 0
|
// but may be falsy if lineLength == 0
|
||||||
linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFunc, apool)
|
linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFunc, apool) {
|
||||||
{
|
|
||||||
|
|
||||||
// Plugin Hook to add more Attrib Classes
|
// Plugin Hook to add more Attrib Classes
|
||||||
for (const attribClasses of hooks.callAll('aceAttribClasses', linestylefilter.ATTRIB_CLASSES)) {
|
for (const attribClasses of hooks.callAll('aceAttribClasses', linestylefilter.ATTRIB_CLASSES)) {
|
||||||
|
@ -67,21 +64,18 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
|
||||||
|
|
||||||
var nextAfterAuthorColors = textAndClassFunc;
|
var nextAfterAuthorColors = textAndClassFunc;
|
||||||
|
|
||||||
var authorColorFunc = (function()
|
var authorColorFunc = (function() {
|
||||||
{
|
|
||||||
var lineEnd = lineLength;
|
var lineEnd = lineLength;
|
||||||
var curIndex = 0;
|
var curIndex = 0;
|
||||||
var extraClasses;
|
var extraClasses;
|
||||||
var leftInAuthor;
|
var leftInAuthor;
|
||||||
|
|
||||||
function attribsToClasses(attribs)
|
function attribsToClasses(attribs) {
|
||||||
{
|
|
||||||
var classes = '';
|
var classes = '';
|
||||||
var isLineAttribMarker = false;
|
var isLineAttribMarker = false;
|
||||||
|
|
||||||
// For each attribute number
|
// For each attribute number
|
||||||
Changeset.eachAttribNumber(attribs, function(n)
|
Changeset.eachAttribNumber(attribs, function(n) {
|
||||||
{
|
|
||||||
// Give us this attributes key
|
// Give us this attributes key
|
||||||
var key = apool.getAttribKey(n);
|
var key = apool.getAttribKey(n);
|
||||||
if (key)
|
if (key)
|
||||||
|
@ -127,15 +121,13 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
|
||||||
var attributionIter = Changeset.opIterator(aline);
|
var attributionIter = Changeset.opIterator(aline);
|
||||||
var nextOp, nextOpClasses;
|
var nextOp, nextOpClasses;
|
||||||
|
|
||||||
function goNextOp()
|
function goNextOp() {
|
||||||
{
|
|
||||||
nextOp = attributionIter.next();
|
nextOp = attributionIter.next();
|
||||||
nextOpClasses = (nextOp.opcode && attribsToClasses(nextOp.attribs));
|
nextOpClasses = (nextOp.opcode && attribsToClasses(nextOp.attribs));
|
||||||
}
|
}
|
||||||
goNextOp();
|
goNextOp();
|
||||||
|
|
||||||
function nextClasses()
|
function nextClasses() {
|
||||||
{
|
|
||||||
if (curIndex < lineEnd)
|
if (curIndex < lineEnd)
|
||||||
{
|
{
|
||||||
extraClasses = nextOpClasses;
|
extraClasses = nextOpClasses;
|
||||||
|
@ -150,8 +142,7 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
|
||||||
}
|
}
|
||||||
nextClasses();
|
nextClasses();
|
||||||
|
|
||||||
return function(txt, cls)
|
return function(txt, cls) {
|
||||||
{
|
|
||||||
|
|
||||||
var disableAuthColorForThisLine = hooks.callAll("disableAuthorColorsForThisLine", {
|
var disableAuthColorForThisLine = hooks.callAll("disableAuthorColorsForThisLine", {
|
||||||
linestylefilter: linestylefilter,
|
linestylefilter: linestylefilter,
|
||||||
|
@ -186,8 +177,7 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
|
||||||
return authorColorFunc;
|
return authorColorFunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc)
|
linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc) {
|
||||||
{
|
|
||||||
var at = /@/g;
|
var at = /@/g;
|
||||||
at.lastIndex = 0;
|
at.lastIndex = 0;
|
||||||
var splitPoints = null;
|
var splitPoints = null;
|
||||||
|
@ -206,10 +196,8 @@ linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc)
|
||||||
return linestylefilter.textAndClassFuncSplitter(textAndClassFunc, splitPoints);
|
return linestylefilter.textAndClassFuncSplitter(textAndClassFunc, splitPoints);
|
||||||
};
|
};
|
||||||
|
|
||||||
linestylefilter.getRegexpFilter = function(regExp, tag)
|
linestylefilter.getRegexpFilter = function(regExp, tag) {
|
||||||
{
|
return function(lineText, textAndClassFunc) {
|
||||||
return function(lineText, textAndClassFunc)
|
|
||||||
{
|
|
||||||
regExp.lastIndex = 0;
|
regExp.lastIndex = 0;
|
||||||
var regExpMatchs = null;
|
var regExpMatchs = null;
|
||||||
var splitPoints = null;
|
var splitPoints = null;
|
||||||
|
@ -229,8 +217,7 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
|
||||||
|
|
||||||
if (!regExpMatchs) return textAndClassFunc;
|
if (!regExpMatchs) return textAndClassFunc;
|
||||||
|
|
||||||
function regExpMatchForIndex(idx)
|
function regExpMatchForIndex(idx) {
|
||||||
{
|
|
||||||
for (var k = 0; k < regExpMatchs.length; k++)
|
for (var k = 0; k < regExpMatchs.length; k++)
|
||||||
{
|
{
|
||||||
var u = regExpMatchs[k];
|
var u = regExpMatchs[k];
|
||||||
|
@ -242,11 +229,9 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var handleRegExpMatchsAfterSplit = (function()
|
var handleRegExpMatchsAfterSplit = (function() {
|
||||||
{
|
|
||||||
var curIndex = 0;
|
var curIndex = 0;
|
||||||
return function(txt, cls)
|
return function(txt, cls) {
|
||||||
{
|
|
||||||
var txtlen = txt.length;
|
var txtlen = txt.length;
|
||||||
var newCls = cls;
|
var newCls = cls;
|
||||||
var regExpMatch = regExpMatchForIndex(curIndex);
|
var regExpMatch = regExpMatchForIndex(curIndex);
|
||||||
|
@ -270,8 +255,7 @@ linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|(
|
||||||
linestylefilter.getURLFilter = linestylefilter.getRegexpFilter(
|
linestylefilter.getURLFilter = linestylefilter.getRegexpFilter(
|
||||||
linestylefilter.REGEX_URL, 'url');
|
linestylefilter.REGEX_URL, 'url');
|
||||||
|
|
||||||
linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
|
linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) {
|
||||||
{
|
|
||||||
var nextPointIndex = 0;
|
var nextPointIndex = 0;
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
|
|
||||||
|
@ -281,8 +265,7 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
|
||||||
nextPointIndex++;
|
nextPointIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
function spanHandler(txt, cls)
|
function spanHandler(txt, cls) {
|
||||||
{
|
|
||||||
if ((!splitPointsOpt) || nextPointIndex >= splitPointsOpt.length)
|
if ((!splitPointsOpt) || nextPointIndex >= splitPointsOpt.length)
|
||||||
{
|
{
|
||||||
func(txt, cls);
|
func(txt, cls);
|
||||||
|
@ -318,16 +301,14 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
|
||||||
return spanHandler;
|
return spanHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser)
|
linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser) {
|
||||||
{
|
|
||||||
var func = linestylefilter.getURLFilter(lineText, textAndClassFunc);
|
var func = linestylefilter.getURLFilter(lineText, textAndClassFunc);
|
||||||
|
|
||||||
var hookFilters = hooks.callAll("aceGetFilterStack", {
|
var hookFilters = hooks.callAll("aceGetFilterStack", {
|
||||||
linestylefilter: linestylefilter,
|
linestylefilter: linestylefilter,
|
||||||
browser: abrowser
|
browser: abrowser
|
||||||
});
|
});
|
||||||
_.map(hookFilters ,function(hookFilter)
|
_.map(hookFilters ,function(hookFilter) {
|
||||||
{
|
|
||||||
func = hookFilter(lineText, func);
|
func = hookFilter(lineText, func);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -343,8 +324,7 @@ linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser)
|
||||||
};
|
};
|
||||||
|
|
||||||
// domLineObj is like that returned by domline.createDomLine
|
// domLineObj is like that returned by domline.createDomLine
|
||||||
linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj)
|
linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj) {
|
||||||
{
|
|
||||||
// remove final newline from text if any
|
// remove final newline from text if any
|
||||||
var text = textLine;
|
var text = textLine;
|
||||||
if (text.slice(-1) == '\n')
|
if (text.slice(-1) == '\n')
|
||||||
|
@ -352,8 +332,7 @@ linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj)
|
||||||
text = text.substring(0, text.length - 1);
|
text = text.substring(0, text.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function textAndClassFunc(tokenText, tokenClass)
|
function textAndClassFunc(tokenText, tokenClass) {
|
||||||
{
|
|
||||||
domLineObj.appendSpan(tokenText, tokenClass);
|
domLineObj.appendSpan(tokenText, tokenClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ var hooks = require('./pluginfw/hooks');
|
||||||
|
|
||||||
var receivedClientVars = false;
|
var receivedClientVars = false;
|
||||||
|
|
||||||
function randomString()
|
function randomString() {
|
||||||
{
|
|
||||||
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
var string_length = 20;
|
var string_length = 20;
|
||||||
var randomstring = '';
|
var randomstring = '';
|
||||||
|
@ -85,8 +84,7 @@ var getParameters = [
|
||||||
{ name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); Cookies.set('language', val); } },
|
{ name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); Cookies.set('language', val); } },
|
||||||
];
|
];
|
||||||
|
|
||||||
function getParams()
|
function getParams() {
|
||||||
{
|
|
||||||
// Tries server enforced options first..
|
// Tries server enforced options first..
|
||||||
for(var i = 0; i < getParameters.length; i++)
|
for(var i = 0; i < getParameters.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -113,8 +111,7 @@ function getParams()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUrlVars()
|
function getUrlVars() {
|
||||||
{
|
|
||||||
var vars = [], hash;
|
var vars = [], hash;
|
||||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||||
for(var i = 0; i < hashes.length; i++)
|
for(var i = 0; i < hashes.length; i++)
|
||||||
|
@ -126,8 +123,7 @@ function getUrlVars()
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendClientReady(isReconnect, messageType)
|
function sendClientReady(isReconnect, messageType) {
|
||||||
{
|
|
||||||
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
|
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
|
||||||
var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1);
|
var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1);
|
||||||
padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces
|
padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces
|
||||||
|
@ -164,8 +160,7 @@ function sendClientReady(isReconnect, messageType)
|
||||||
socket.json.send(msg);
|
socket.json.send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handshake()
|
function handshake() {
|
||||||
{
|
|
||||||
var loc = document.location;
|
var loc = document.location;
|
||||||
//get the correct port
|
//get the correct port
|
||||||
var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port;
|
var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port;
|
||||||
|
@ -225,8 +220,7 @@ function handshake()
|
||||||
|
|
||||||
var initalized = false;
|
var initalized = false;
|
||||||
|
|
||||||
socket.on('message', function(obj)
|
socket.on('message', function(obj) {
|
||||||
{
|
|
||||||
//the access was not granted, give the user a message
|
//the access was not granted, give the user a message
|
||||||
if(obj.accessStatus)
|
if(obj.accessStatus)
|
||||||
{
|
{
|
||||||
|
@ -354,48 +348,37 @@ var pad = {
|
||||||
padOptions: {},
|
padOptions: {},
|
||||||
|
|
||||||
// these don't require init; clientVars should all go through here
|
// these don't require init; clientVars should all go through here
|
||||||
getPadId: function()
|
getPadId: function() {
|
||||||
{
|
|
||||||
return clientVars.padId;
|
return clientVars.padId;
|
||||||
},
|
},
|
||||||
getClientIp: function()
|
getClientIp: function() {
|
||||||
{
|
|
||||||
return clientVars.clientIp;
|
return clientVars.clientIp;
|
||||||
},
|
},
|
||||||
getColorPalette: function()
|
getColorPalette: function() {
|
||||||
{
|
|
||||||
return clientVars.colorPalette;
|
return clientVars.colorPalette;
|
||||||
},
|
},
|
||||||
getDisplayUserAgent: function()
|
getDisplayUserAgent: function() {
|
||||||
{
|
|
||||||
return padutils.uaDisplay(clientVars.userAgent);
|
return padutils.uaDisplay(clientVars.userAgent);
|
||||||
},
|
},
|
||||||
getIsDebugEnabled: function()
|
getIsDebugEnabled: function() {
|
||||||
{
|
|
||||||
return clientVars.debugEnabled;
|
return clientVars.debugEnabled;
|
||||||
},
|
},
|
||||||
getPrivilege: function(name)
|
getPrivilege: function(name) {
|
||||||
{
|
|
||||||
return clientVars.accountPrivs[name];
|
return clientVars.accountPrivs[name];
|
||||||
},
|
},
|
||||||
getUserIsGuest: function()
|
getUserIsGuest: function() {
|
||||||
{
|
|
||||||
return clientVars.userIsGuest;
|
return clientVars.userIsGuest;
|
||||||
},
|
},
|
||||||
getUserId: function()
|
getUserId: function() {
|
||||||
{
|
|
||||||
return pad.myUserInfo.userId;
|
return pad.myUserInfo.userId;
|
||||||
},
|
},
|
||||||
getUserName: function()
|
getUserName: function() {
|
||||||
{
|
|
||||||
return pad.myUserInfo.name;
|
return pad.myUserInfo.name;
|
||||||
},
|
},
|
||||||
userList: function()
|
userList: function() {
|
||||||
{
|
|
||||||
return paduserlist.users();
|
return paduserlist.users();
|
||||||
},
|
},
|
||||||
switchToPad: function(padId)
|
switchToPad: function(padId) {
|
||||||
{
|
|
||||||
var newHref = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId;
|
var newHref = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId;
|
||||||
newHref = newHref[0];
|
newHref = newHref[0];
|
||||||
|
|
||||||
|
@ -430,17 +413,14 @@ var pad = {
|
||||||
window.location.href = newHref;
|
window.location.href = newHref;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sendClientMessage: function(msg)
|
sendClientMessage: function(msg) {
|
||||||
{
|
|
||||||
pad.collabClient.sendClientMessage(msg);
|
pad.collabClient.sendClientMessage(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function()
|
init: function() {
|
||||||
{
|
|
||||||
padutils.setupGlobalExceptionHandler();
|
padutils.setupGlobalExceptionHandler();
|
||||||
|
|
||||||
$(document).ready(function()
|
$(document).ready(function() {
|
||||||
{
|
|
||||||
// start the custom js
|
// start the custom js
|
||||||
if (typeof customStart == "function") customStart();
|
if (typeof customStart == "function") customStart();
|
||||||
handshake();
|
handshake();
|
||||||
|
@ -451,8 +431,7 @@ var pad = {
|
||||||
padcookie.init();
|
padcookie.init();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_afterHandshake: function()
|
_afterHandshake: function() {
|
||||||
{
|
|
||||||
pad.clientTimeOffset = Date.now() - clientVars.serverTimestamp;
|
pad.clientTimeOffset = Date.now() - clientVars.serverTimestamp;
|
||||||
//initialize the chat
|
//initialize the chat
|
||||||
chat.init(this);
|
chat.init(this);
|
||||||
|
@ -514,11 +493,9 @@ var pad = {
|
||||||
$("#chatloadmessagesbutton").css("display", "none");
|
$("#chatloadmessagesbutton").css("display", "none");
|
||||||
}
|
}
|
||||||
|
|
||||||
function postAceInit()
|
function postAceInit() {
|
||||||
{
|
|
||||||
padeditbar.init();
|
padeditbar.init();
|
||||||
setTimeout(function()
|
setTimeout(function() {
|
||||||
{
|
|
||||||
padeditor.ace.focus();
|
padeditor.ace.focus();
|
||||||
}, 0);
|
}, 0);
|
||||||
if(padcookie.getPref("chatAlwaysVisible")){ // if we have a cookie for always showing chat then show it
|
if(padcookie.getPref("chatAlwaysVisible")){ // if we have a cookie for always showing chat then show it
|
||||||
|
@ -557,22 +534,18 @@ var pad = {
|
||||||
hooks.aCallAll("postAceInit", {ace: padeditor.ace, pad: pad});
|
hooks.aCallAll("postAceInit", {ace: padeditor.ace, pad: pad});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dispose: function()
|
dispose: function() {
|
||||||
{
|
|
||||||
padeditor.dispose();
|
padeditor.dispose();
|
||||||
},
|
},
|
||||||
notifyChangeName: function(newName)
|
notifyChangeName: function(newName) {
|
||||||
{
|
|
||||||
pad.myUserInfo.name = newName;
|
pad.myUserInfo.name = newName;
|
||||||
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
||||||
},
|
},
|
||||||
notifyChangeColor: function(newColorId)
|
notifyChangeColor: function(newColorId) {
|
||||||
{
|
|
||||||
pad.myUserInfo.colorId = newColorId;
|
pad.myUserInfo.colorId = newColorId;
|
||||||
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
pad.collabClient.updateUserInfo(pad.myUserInfo);
|
||||||
},
|
},
|
||||||
changePadOption: function(key, value)
|
changePadOption: function(key, value) {
|
||||||
{
|
|
||||||
var options = {};
|
var options = {};
|
||||||
options[key] = value;
|
options[key] = value;
|
||||||
pad.handleOptionsChange(options);
|
pad.handleOptionsChange(options);
|
||||||
|
@ -583,16 +556,14 @@ var pad = {
|
||||||
changedBy: pad.myUserInfo.name || "unnamed"
|
changedBy: pad.myUserInfo.name || "unnamed"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
changeViewOption: function(key, value)
|
changeViewOption: function(key, value) {
|
||||||
{
|
|
||||||
var options = {
|
var options = {
|
||||||
view: {}
|
view: {}
|
||||||
};
|
};
|
||||||
options.view[key] = value;
|
options.view[key] = value;
|
||||||
pad.handleOptionsChange(options);
|
pad.handleOptionsChange(options);
|
||||||
},
|
},
|
||||||
handleOptionsChange: function(opts)
|
handleOptionsChange: function(opts) {
|
||||||
{
|
|
||||||
// opts object is a full set of options or just
|
// opts object is a full set of options or just
|
||||||
// some options to change
|
// some options to change
|
||||||
if (opts.view)
|
if (opts.view)
|
||||||
|
@ -614,17 +585,14 @@ var pad = {
|
||||||
pad.padOptions.guestPolicy = opts.guestPolicy;
|
pad.padOptions.guestPolicy = opts.guestPolicy;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getPadOptions: function()
|
getPadOptions: function() {
|
||||||
{
|
|
||||||
// caller shouldn't mutate the object
|
// caller shouldn't mutate the object
|
||||||
return pad.padOptions;
|
return pad.padOptions;
|
||||||
},
|
},
|
||||||
isPadPublic: function()
|
isPadPublic: function() {
|
||||||
{
|
|
||||||
return pad.getPadOptions().guestPolicy == 'allow';
|
return pad.getPadOptions().guestPolicy == 'allow';
|
||||||
},
|
},
|
||||||
suggestUserName: function(userId, name)
|
suggestUserName: function(userId, name) {
|
||||||
{
|
|
||||||
pad.collabClient.sendClientMessage(
|
pad.collabClient.sendClientMessage(
|
||||||
{
|
{
|
||||||
type: 'suggestUserName',
|
type: 'suggestUserName',
|
||||||
|
@ -632,20 +600,16 @@ var pad = {
|
||||||
newName: name
|
newName: name
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleUserJoin: function(userInfo)
|
handleUserJoin: function(userInfo) {
|
||||||
{
|
|
||||||
paduserlist.userJoinOrUpdate(userInfo);
|
paduserlist.userJoinOrUpdate(userInfo);
|
||||||
},
|
},
|
||||||
handleUserUpdate: function(userInfo)
|
handleUserUpdate: function(userInfo) {
|
||||||
{
|
|
||||||
paduserlist.userJoinOrUpdate(userInfo);
|
paduserlist.userJoinOrUpdate(userInfo);
|
||||||
},
|
},
|
||||||
handleUserLeave: function(userInfo)
|
handleUserLeave: function(userInfo) {
|
||||||
{
|
|
||||||
paduserlist.userLeave(userInfo);
|
paduserlist.userLeave(userInfo);
|
||||||
},
|
},
|
||||||
handleClientMessage: function(msg)
|
handleClientMessage: function(msg) {
|
||||||
{
|
|
||||||
if (msg.type == 'suggestUserName')
|
if (msg.type == 'suggestUserName')
|
||||||
{
|
{
|
||||||
if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name)
|
if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name)
|
||||||
|
@ -673,8 +637,7 @@ var pad = {
|
||||||
paduserlist.removeGuestPrompt(msg.guestId);
|
paduserlist.removeGuestPrompt(msg.guestId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dmesg: function(m)
|
dmesg: function(m) {
|
||||||
{
|
|
||||||
if (pad.getIsDebugEnabled())
|
if (pad.getIsDebugEnabled())
|
||||||
{
|
{
|
||||||
var djs = $('#djs').get(0);
|
var djs = $('#djs').get(0);
|
||||||
|
@ -686,14 +649,12 @@ var pad = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleServerMessage: function(m)
|
handleServerMessage: function(m) {
|
||||||
{
|
|
||||||
if (m.type == 'NOTICE')
|
if (m.type == 'NOTICE')
|
||||||
{
|
{
|
||||||
if (m.text)
|
if (m.text)
|
||||||
{
|
{
|
||||||
alertBar.displayMessage(function(abar)
|
alertBar.displayMessage(function(abar) {
|
||||||
{
|
|
||||||
abar.find("#servermsgdate").text(" (" + padutils.simpleDateTime(new Date) + ")");
|
abar.find("#servermsgdate").text(" (" + padutils.simpleDateTime(new Date) + ")");
|
||||||
abar.find("#servermsgtext").text(m.text);
|
abar.find("#servermsgtext").text(m.text);
|
||||||
});
|
});
|
||||||
|
@ -708,8 +669,7 @@ var pad = {
|
||||||
paduserlist.showGuestPrompt(m.userId, m.displayName);
|
paduserlist.showGuestPrompt(m.userId, m.displayName);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleChannelStateChange: function(newState, message)
|
handleChannelStateChange: function(newState, message) {
|
||||||
{
|
|
||||||
var oldFullyConnected = !! padconnectionstatus.isFullyConnected();
|
var oldFullyConnected = !! padconnectionstatus.isFullyConnected();
|
||||||
var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
|
var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
|
||||||
if (newState == "CONNECTED")
|
if (newState == "CONNECTED")
|
||||||
|
@ -762,8 +722,7 @@ var pad = {
|
||||||
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
|
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleIsFullyConnected: function(isConnected, isInitialConnect)
|
handleIsFullyConnected: function(isConnected, isInitialConnect) {
|
||||||
{
|
|
||||||
pad.determineChatVisibility(isConnected && !isInitialConnect);
|
pad.determineChatVisibility(isConnected && !isInitialConnect);
|
||||||
pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
|
pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
|
||||||
pad.determineAuthorshipColorsVisibility();
|
pad.determineAuthorshipColorsVisibility();
|
||||||
|
@ -801,8 +760,7 @@ var pad = {
|
||||||
$('#options-colorscheck').prop("checked", false);
|
$('#options-colorscheck').prop("checked", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleCollabAction: function(action)
|
handleCollabAction: function(action) {
|
||||||
{
|
|
||||||
if (action == "commitPerformed")
|
if (action == "commitPerformed")
|
||||||
{
|
{
|
||||||
padeditbar.setSyncStatus("syncing");
|
padeditbar.setSyncStatus("syncing");
|
||||||
|
@ -812,14 +770,11 @@ var pad = {
|
||||||
padeditbar.setSyncStatus("done");
|
padeditbar.setSyncStatus("done");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideServerMessage: function()
|
hideServerMessage: function() {
|
||||||
{
|
|
||||||
alertBar.hideMessage();
|
alertBar.hideMessage();
|
||||||
},
|
},
|
||||||
asyncSendDiagnosticInfo: function()
|
asyncSendDiagnosticInfo: function() {
|
||||||
{
|
window.setTimeout(function() {
|
||||||
window.setTimeout(function()
|
|
||||||
{
|
|
||||||
$.ajax(
|
$.ajax(
|
||||||
{
|
{
|
||||||
type: 'post',
|
type: 'post',
|
||||||
|
@ -827,15 +782,12 @@ var pad = {
|
||||||
data: {
|
data: {
|
||||||
diagnosticInfo: JSON.stringify(pad.diagnosticInfo)
|
diagnosticInfo: JSON.stringify(pad.diagnosticInfo)
|
||||||
},
|
},
|
||||||
success: function()
|
success: function() {},
|
||||||
{},
|
error: function() {}
|
||||||
error: function()
|
|
||||||
{}
|
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
forceReconnect: function()
|
forceReconnect: function() {
|
||||||
{
|
|
||||||
$('form#reconnectform input.padId').val(pad.getPadId());
|
$('form#reconnectform input.padId').val(pad.getPadId());
|
||||||
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
|
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
|
||||||
$('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
|
$('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
|
||||||
|
@ -843,28 +795,22 @@ var pad = {
|
||||||
$('form#reconnectform').submit();
|
$('form#reconnectform').submit();
|
||||||
},
|
},
|
||||||
// this is called from code put into a frame from the server:
|
// this is called from code put into a frame from the server:
|
||||||
handleImportExportFrameCall: function(callName, varargs)
|
handleImportExportFrameCall: function(callName, varargs) {
|
||||||
{
|
|
||||||
padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1));
|
padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1));
|
||||||
},
|
},
|
||||||
callWhenNotCommitting: function(f)
|
callWhenNotCommitting: function(f) {
|
||||||
{
|
|
||||||
pad.collabClient.callWhenNotCommitting(f);
|
pad.collabClient.callWhenNotCommitting(f);
|
||||||
},
|
},
|
||||||
getCollabRevisionNumber: function()
|
getCollabRevisionNumber: function() {
|
||||||
{
|
|
||||||
return pad.collabClient.getCurrentRevisionNumber();
|
return pad.collabClient.getCurrentRevisionNumber();
|
||||||
},
|
},
|
||||||
isFullyConnected: function()
|
isFullyConnected: function() {
|
||||||
{
|
|
||||||
return padconnectionstatus.isFullyConnected();
|
return padconnectionstatus.isFullyConnected();
|
||||||
},
|
},
|
||||||
addHistoricalAuthors: function(data)
|
addHistoricalAuthors: function(data) {
|
||||||
{
|
|
||||||
if (!pad.collabClient)
|
if (!pad.collabClient)
|
||||||
{
|
{
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
pad.addHistoricalAuthors(data);
|
pad.addHistoricalAuthors(data);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
@ -875,13 +821,11 @@ var pad = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var alertBar = (function()
|
var alertBar = (function() {
|
||||||
{
|
|
||||||
|
|
||||||
var animator = padutils.makeShowHideAnimator(arriveAtAnimationState, false, 25, 400);
|
var animator = padutils.makeShowHideAnimator(arriveAtAnimationState, false, 25, 400);
|
||||||
|
|
||||||
function arriveAtAnimationState(state)
|
function arriveAtAnimationState(state) {
|
||||||
{
|
|
||||||
if (state == -1)
|
if (state == -1)
|
||||||
{
|
{
|
||||||
$("#alertbar").css('opacity', 0).css('display', 'block');
|
$("#alertbar").css('opacity', 0).css('display', 'block');
|
||||||
|
@ -905,13 +849,11 @@ var alertBar = (function()
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = {
|
var self = {
|
||||||
displayMessage: function(setupFunc)
|
displayMessage: function(setupFunc) {
|
||||||
{
|
|
||||||
animator.show();
|
animator.show();
|
||||||
setupFunc($("#alertbar"));
|
setupFunc($("#alertbar"));
|
||||||
},
|
},
|
||||||
hideMessage: function()
|
hideMessage: function() {
|
||||||
{
|
|
||||||
animator.hide();
|
animator.hide();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,31 +22,26 @@
|
||||||
|
|
||||||
var padmodals = require('./pad_modals').padmodals;
|
var padmodals = require('./pad_modals').padmodals;
|
||||||
|
|
||||||
var padconnectionstatus = (function()
|
var padconnectionstatus = (function() {
|
||||||
{
|
|
||||||
|
|
||||||
var status = {
|
var status = {
|
||||||
what: 'connecting'
|
what: 'connecting'
|
||||||
};
|
};
|
||||||
|
|
||||||
var self = {
|
var self = {
|
||||||
init: function()
|
init: function() {
|
||||||
{
|
$('button#forcereconnect').click(function() {
|
||||||
$('button#forcereconnect').click(function()
|
|
||||||
{
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
connected: function()
|
connected: function() {
|
||||||
{
|
|
||||||
status = {
|
status = {
|
||||||
what: 'connected'
|
what: 'connected'
|
||||||
};
|
};
|
||||||
padmodals.showModal('connected');
|
padmodals.showModal('connected');
|
||||||
padmodals.hideOverlay();
|
padmodals.hideOverlay();
|
||||||
},
|
},
|
||||||
reconnecting: function()
|
reconnecting: function() {
|
||||||
{
|
|
||||||
status = {
|
status = {
|
||||||
what: 'reconnecting'
|
what: 'reconnecting'
|
||||||
};
|
};
|
||||||
|
@ -54,8 +49,7 @@ var padconnectionstatus = (function()
|
||||||
padmodals.showModal('reconnecting');
|
padmodals.showModal('reconnecting');
|
||||||
padmodals.showOverlay();
|
padmodals.showOverlay();
|
||||||
},
|
},
|
||||||
disconnected: function(msg)
|
disconnected: function(msg) {
|
||||||
{
|
|
||||||
if(status.what == "disconnected")
|
if(status.what == "disconnected")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -89,12 +83,10 @@ var padconnectionstatus = (function()
|
||||||
padmodals.showModal(k);
|
padmodals.showModal(k);
|
||||||
padmodals.showOverlay();
|
padmodals.showOverlay();
|
||||||
},
|
},
|
||||||
isFullyConnected: function()
|
isFullyConnected: function() {
|
||||||
{
|
|
||||||
return status.what == 'connected';
|
return status.what == 'connected';
|
||||||
},
|
},
|
||||||
getStatus: function()
|
getStatus: function() {
|
||||||
{
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,11 +79,9 @@ ToolbarItem.prototype.bind = function (callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var padeditbar = (function()
|
var padeditbar = (function() {
|
||||||
{
|
|
||||||
|
|
||||||
var syncAnimation = (function()
|
var syncAnimation = (function() {
|
||||||
{
|
|
||||||
var SYNCING = -100;
|
var SYNCING = -100;
|
||||||
var DONE = 100;
|
var DONE = 100;
|
||||||
var state = DONE;
|
var state = DONE;
|
||||||
|
@ -92,8 +90,7 @@ var padeditbar = (function()
|
||||||
var T_START = -0.5;
|
var T_START = -0.5;
|
||||||
var T_FADE = 1.0;
|
var T_FADE = 1.0;
|
||||||
var T_GONE = 1.5;
|
var T_GONE = 1.5;
|
||||||
var animator = padutils.makeAnimationScheduler(function()
|
var animator = padutils.makeAnimationScheduler(function() {
|
||||||
{
|
|
||||||
if (state == SYNCING || state == DONE)
|
if (state == SYNCING || state == DONE)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -126,14 +123,12 @@ var padeditbar = (function()
|
||||||
}
|
}
|
||||||
}, step * 1000);
|
}, step * 1000);
|
||||||
return {
|
return {
|
||||||
syncing: function()
|
syncing: function() {
|
||||||
{
|
|
||||||
state = SYNCING;
|
state = SYNCING;
|
||||||
$("#syncstatussyncing").css('display', 'block');
|
$("#syncstatussyncing").css('display', 'block');
|
||||||
$("#syncstatusdone").css('display', 'none');
|
$("#syncstatusdone").css('display', 'none');
|
||||||
},
|
},
|
||||||
done: function()
|
done: function() {
|
||||||
{
|
|
||||||
state = T_START;
|
state = T_START;
|
||||||
animator.scheduleAnimation();
|
animator.scheduleAnimation();
|
||||||
}
|
}
|
||||||
|
@ -186,16 +181,13 @@ var padeditbar = (function()
|
||||||
$('#editbar').toggleClass('editor-scrolled', $(this).scrollTop() > 2);
|
$('#editbar').toggleClass('editor-scrolled', $(this).scrollTop() > 2);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
isEnabled: function()
|
isEnabled: function() {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
disable: function()
|
disable: function() {
|
||||||
{
|
|
||||||
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
|
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
|
||||||
},
|
},
|
||||||
enable: function()
|
enable: function() {
|
||||||
{
|
|
||||||
$('#editbar').addClass('enabledtoolbar').removeClass('disabledtoolbar');
|
$('#editbar').addClass('enabledtoolbar').removeClass('disabledtoolbar');
|
||||||
},
|
},
|
||||||
commands: {},
|
commands: {},
|
||||||
|
@ -223,8 +215,7 @@ var padeditbar = (function()
|
||||||
}
|
}
|
||||||
if(padeditor.ace) padeditor.ace.focus();
|
if(padeditor.ace) padeditor.ace.focus();
|
||||||
},
|
},
|
||||||
toggleDropDown: function(moduleName, cb)
|
toggleDropDown: function(moduleName, cb) {
|
||||||
{
|
|
||||||
// do nothing if users are sticked
|
// do nothing if users are sticked
|
||||||
if (moduleName === "users" && $('#users').hasClass('stickyUsers')) {
|
if (moduleName === "users" && $('#users').hasClass('stickyUsers')) {
|
||||||
return;
|
return;
|
||||||
|
@ -284,8 +275,7 @@ var padeditbar = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setSyncStatus: function(status)
|
setSyncStatus: function(status) {
|
||||||
{
|
|
||||||
if (status == "syncing")
|
if (status == "syncing")
|
||||||
{
|
{
|
||||||
syncAnimation.syncing();
|
syncAnimation.syncing();
|
||||||
|
@ -295,8 +285,7 @@ var padeditbar = (function()
|
||||||
syncAnimation.done();
|
syncAnimation.done();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setEmbedLinks: function()
|
setEmbedLinks: function() {
|
||||||
{
|
|
||||||
var padUrl = window.location.href.split("?")[0];
|
var padUrl = window.location.href.split("?")[0];
|
||||||
|
|
||||||
if ($('#readonlyinput').is(':checked'))
|
if ($('#readonlyinput').is(':checked'))
|
||||||
|
@ -313,8 +302,7 @@ var padeditbar = (function()
|
||||||
$('#linkinput').val(padUrl);
|
$('#linkinput').val(padUrl);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
checkAllIconsAreDisplayedInToolbar: function()
|
checkAllIconsAreDisplayedInToolbar: function() {
|
||||||
{
|
|
||||||
// reset style
|
// reset style
|
||||||
$('.toolbar').removeClass('cropped')
|
$('.toolbar').removeClass('cropped')
|
||||||
$('body').removeClass('mobile-layout');
|
$('body').removeClass('mobile-layout');
|
||||||
|
|
|
@ -24,8 +24,7 @@ const Cookies = require('./pad_utils').Cookies;
|
||||||
var padcookie = require('./pad_cookie').padcookie;
|
var padcookie = require('./pad_cookie').padcookie;
|
||||||
var padutils = require('./pad_utils').padutils;
|
var padutils = require('./pad_utils').padutils;
|
||||||
|
|
||||||
var padeditor = (function()
|
var padeditor = (function() {
|
||||||
{
|
|
||||||
var Ace2Editor = undefined;
|
var Ace2Editor = undefined;
|
||||||
var pad = undefined;
|
var pad = undefined;
|
||||||
var settings = undefined;
|
var settings = undefined;
|
||||||
|
@ -34,14 +33,12 @@ var padeditor = (function()
|
||||||
ace: null,
|
ace: null,
|
||||||
// this is accessed directly from other files
|
// this is accessed directly from other files
|
||||||
viewZoom: 100,
|
viewZoom: 100,
|
||||||
init: function(readyFunc, initialViewOptions, _pad)
|
init: function(readyFunc, initialViewOptions, _pad) {
|
||||||
{
|
|
||||||
Ace2Editor = require('./ace').Ace2Editor;
|
Ace2Editor = require('./ace').Ace2Editor;
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
settings = pad.settings;
|
settings = pad.settings;
|
||||||
|
|
||||||
function aceReady()
|
function aceReady() {
|
||||||
{
|
|
||||||
$("#editorloadingbox").hide();
|
$("#editorloadingbox").hide();
|
||||||
if (readyFunc)
|
if (readyFunc)
|
||||||
{
|
{
|
||||||
|
@ -62,24 +59,20 @@ var padeditor = (function()
|
||||||
// view bar
|
// view bar
|
||||||
$("#viewbarcontents").show();
|
$("#viewbarcontents").show();
|
||||||
},
|
},
|
||||||
initViewOptions: function()
|
initViewOptions: function() {
|
||||||
{
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
padutils.bindCheckboxChange($("#options-linenoscheck"), function()
|
padutils.bindCheckboxChange($("#options-linenoscheck"), function() {
|
||||||
{
|
|
||||||
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($("#options-linenoscheck")));
|
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($("#options-linenoscheck")));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Author colors
|
// Author colors
|
||||||
padutils.bindCheckboxChange($("#options-colorscheck"), function()
|
padutils.bindCheckboxChange($("#options-colorscheck"), function() {
|
||||||
{
|
|
||||||
padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck"));
|
padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck"));
|
||||||
pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck"));
|
pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck"));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Right to left
|
// Right to left
|
||||||
padutils.bindCheckboxChange($("#options-rtlcheck"), function()
|
padutils.bindCheckboxChange($("#options-rtlcheck"), function() {
|
||||||
{
|
|
||||||
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($("#options-rtlcheck")))
|
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($("#options-rtlcheck")))
|
||||||
});
|
});
|
||||||
html10n.bind('localized', function() {
|
html10n.bind('localized', function() {
|
||||||
|
@ -88,8 +81,7 @@ var padeditor = (function()
|
||||||
})
|
})
|
||||||
|
|
||||||
// font family change
|
// font family change
|
||||||
$("#viewfontmenu").change(function()
|
$("#viewfontmenu").change(function() {
|
||||||
{
|
|
||||||
pad.changeViewOption('padFontFamily', $("#viewfontmenu").val());
|
pad.changeViewOption('padFontFamily', $("#viewfontmenu").val());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,10 +105,8 @@ var padeditor = (function()
|
||||||
window.html10n.localize([$("#languagemenu").val(), 'en']);
|
window.html10n.localize([$("#languagemenu").val(), 'en']);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setViewOptions: function(newOptions)
|
setViewOptions: function(newOptions) {
|
||||||
{
|
function getOption(key, defaultValue) {
|
||||||
function getOption(key, defaultValue)
|
|
||||||
{
|
|
||||||
var value = String(newOptions[key]);
|
var value = String(newOptions[key]);
|
||||||
if (value == "true") return true;
|
if (value == "true") return true;
|
||||||
if (value == "false") return false;
|
if (value == "false") return false;
|
||||||
|
@ -146,31 +136,27 @@ var padeditor = (function()
|
||||||
|
|
||||||
self.ace.setProperty("textface", newOptions['padFontFamily'] || "");
|
self.ace.setProperty("textface", newOptions['padFontFamily'] || "");
|
||||||
},
|
},
|
||||||
dispose: function()
|
dispose: function() {
|
||||||
{
|
|
||||||
if (self.ace)
|
if (self.ace)
|
||||||
{
|
{
|
||||||
self.ace.destroy();
|
self.ace.destroy();
|
||||||
self.ace = null;
|
self.ace = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enable: function()
|
enable: function() {
|
||||||
{
|
|
||||||
if (self.ace)
|
if (self.ace)
|
||||||
{
|
{
|
||||||
self.ace.setEditable(true);
|
self.ace.setEditable(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disable: function()
|
disable: function() {
|
||||||
{
|
|
||||||
if (self.ace)
|
if (self.ace)
|
||||||
{
|
{
|
||||||
self.ace.setProperty("grayedOut", true);
|
self.ace.setProperty("grayedOut", true);
|
||||||
self.ace.setEditable(false);
|
self.ace.setEditable(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
restoreRevisionText: function(dataFromServer)
|
restoreRevisionText: function(dataFromServer) {
|
||||||
{
|
|
||||||
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
|
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
|
||||||
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
|
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,35 +20,30 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var padimpexp = (function()
|
var padimpexp = (function() {
|
||||||
{
|
|
||||||
|
|
||||||
///// import
|
///// import
|
||||||
var currentImportTimer = null;
|
var currentImportTimer = null;
|
||||||
|
|
||||||
function addImportFrames()
|
function addImportFrames() {
|
||||||
{
|
|
||||||
$("#import .importframe").remove();
|
$("#import .importframe").remove();
|
||||||
var iframe = $('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>');
|
var iframe = $('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>');
|
||||||
$('#import').append(iframe);
|
$('#import').append(iframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileInputUpdated()
|
function fileInputUpdated() {
|
||||||
{
|
|
||||||
$('#importsubmitinput').addClass('throbbold');
|
$('#importsubmitinput').addClass('throbbold');
|
||||||
$('#importformfilediv').addClass('importformenabled');
|
$('#importformfilediv').addClass('importformenabled');
|
||||||
$('#importsubmitinput').removeAttr('disabled');
|
$('#importsubmitinput').removeAttr('disabled');
|
||||||
$('#importmessagefail').fadeOut('fast');
|
$('#importmessagefail').fadeOut('fast');
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileInputSubmit()
|
function fileInputSubmit() {
|
||||||
{
|
|
||||||
$('#importmessagefail').fadeOut("fast");
|
$('#importmessagefail').fadeOut("fast");
|
||||||
var ret = window.confirm(html10n.get("pad.impexp.confirmimport"));
|
var ret = window.confirm(html10n.get("pad.impexp.confirmimport"));
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
currentImportTimer = window.setTimeout(function()
|
currentImportTimer = window.setTimeout(function() {
|
||||||
{
|
|
||||||
if (!currentImportTimer)
|
if (!currentImportTimer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -62,8 +57,7 @@ var padimpexp = (function()
|
||||||
disabled: true
|
disabled: true
|
||||||
}).val(html10n.get("pad.impexp.importing"));
|
}).val(html10n.get("pad.impexp.importing"));
|
||||||
|
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
$('#importfileinput').attr(
|
$('#importfileinput').attr(
|
||||||
{
|
{
|
||||||
disabled: true
|
disabled: true
|
||||||
|
@ -75,16 +69,13 @@ var padimpexp = (function()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function importFailed(msg)
|
function importFailed(msg) {
|
||||||
{
|
|
||||||
importErrorMessage(msg);
|
importErrorMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function importDone()
|
function importDone() {
|
||||||
{
|
|
||||||
$('#importsubmitinput').removeAttr('disabled').val(html10n.get("pad.impexp.importbutton"));
|
$('#importsubmitinput').removeAttr('disabled').val(html10n.get("pad.impexp.importbutton"));
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
$('#importfileinput').removeAttr('disabled');
|
$('#importfileinput').removeAttr('disabled');
|
||||||
}, 0);
|
}, 0);
|
||||||
$('#importstatusball').hide();
|
$('#importstatusball').hide();
|
||||||
|
@ -92,8 +83,7 @@ var padimpexp = (function()
|
||||||
addImportFrames();
|
addImportFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
function importClearTimeout()
|
function importClearTimeout() {
|
||||||
{
|
|
||||||
if (currentImportTimer)
|
if (currentImportTimer)
|
||||||
{
|
{
|
||||||
window.clearTimeout(currentImportTimer);
|
window.clearTimeout(currentImportTimer);
|
||||||
|
@ -101,8 +91,7 @@ var padimpexp = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function importErrorMessage(status)
|
function importErrorMessage(status) {
|
||||||
{
|
|
||||||
var msg="";
|
var msg="";
|
||||||
|
|
||||||
if(status === "convertFailed"){
|
if(status === "convertFailed"){
|
||||||
|
@ -117,16 +106,14 @@ var padimpexp = (function()
|
||||||
msg = html10n.get("pad.impexp.permission");
|
msg = html10n.get("pad.impexp.permission");
|
||||||
}
|
}
|
||||||
|
|
||||||
function showError(fade)
|
function showError(fade) {
|
||||||
{
|
|
||||||
$('#importmessagefail').html('<strong style="color: red">'+html10n.get('pad.impexp.importfailed')+':</strong> ' + (msg || html10n.get('pad.impexp.copypaste','')))[(fade ? "fadeIn" : "show")]();
|
$('#importmessagefail').html('<strong style="color: red">'+html10n.get('pad.impexp.importfailed')+':</strong> ' + (msg || html10n.get('pad.impexp.copypaste','')))[(fade ? "fadeIn" : "show")]();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#importexport .importmessage').is(':visible'))
|
if ($('#importexport .importmessage').is(':visible'))
|
||||||
{
|
{
|
||||||
$('#importmessagesuccess').fadeOut("fast");
|
$('#importmessagesuccess').fadeOut("fast");
|
||||||
$('#importmessagefail').fadeOut("fast", function()
|
$('#importmessagefail').fadeOut("fast", function() {
|
||||||
{
|
|
||||||
showError(true);
|
showError(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -136,8 +123,7 @@ var padimpexp = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function importSuccessful(token)
|
function importSuccessful(token) {
|
||||||
{
|
|
||||||
$.ajax(
|
$.ajax(
|
||||||
{
|
{
|
||||||
type: 'post',
|
type: 'post',
|
||||||
|
@ -153,16 +139,14 @@ var padimpexp = (function()
|
||||||
addImportFrames();
|
addImportFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
function importApplicationFailed(xhr, textStatus, errorThrown)
|
function importApplicationFailed(xhr, textStatus, errorThrown) {
|
||||||
{
|
|
||||||
importErrorMessage("Error during conversion.");
|
importErrorMessage("Error during conversion.");
|
||||||
importDone();
|
importDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
///// export
|
///// export
|
||||||
|
|
||||||
function cantExport()
|
function cantExport() {
|
||||||
{
|
|
||||||
var type = $(this);
|
var type = $(this);
|
||||||
if (type.hasClass("exporthrefpdf"))
|
if (type.hasClass("exporthrefpdf"))
|
||||||
{
|
{
|
||||||
|
@ -187,8 +171,7 @@ var padimpexp = (function()
|
||||||
/////
|
/////
|
||||||
var pad = undefined;
|
var pad = undefined;
|
||||||
var self = {
|
var self = {
|
||||||
init: function(_pad)
|
init: function(_pad) {
|
||||||
{
|
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
|
|
||||||
//get /p/padname
|
//get /p/padname
|
||||||
|
@ -242,8 +225,7 @@ var padimpexp = (function()
|
||||||
$('#importform').unbind("submit").submit(fileInputSubmit);
|
$('#importform').unbind("submit").submit(fileInputSubmit);
|
||||||
$('.disabledexport').click(cantExport);
|
$('.disabledexport').click(cantExport);
|
||||||
},
|
},
|
||||||
handleFrameCall: function(directDatabaseAccess, status)
|
handleFrameCall: function(directDatabaseAccess, status) {
|
||||||
{
|
|
||||||
if(directDatabaseAccess === "undefined") directDatabaseAccess = false;
|
if(directDatabaseAccess === "undefined") directDatabaseAccess = false;
|
||||||
if (status !== "ok")
|
if (status !== "ok")
|
||||||
{
|
{
|
||||||
|
@ -262,14 +244,12 @@ var padimpexp = (function()
|
||||||
|
|
||||||
importDone();
|
importDone();
|
||||||
},
|
},
|
||||||
disable: function()
|
disable: function() {
|
||||||
{
|
|
||||||
$("#impexp-disabled-clickcatcher").show();
|
$("#impexp-disabled-clickcatcher").show();
|
||||||
$("#import").css('opacity', 0.5);
|
$("#import").css('opacity', 0.5);
|
||||||
$("#impexp-export").css('opacity', 0.5);
|
$("#impexp-export").css('opacity', 0.5);
|
||||||
},
|
},
|
||||||
enable: function()
|
enable: function() {
|
||||||
{
|
|
||||||
$("#impexp-disabled-clickcatcher").hide();
|
$("#impexp-disabled-clickcatcher").hide();
|
||||||
$("#import").css('opacity', 1);
|
$("#import").css('opacity', 1);
|
||||||
$("#impexp-export").css('opacity', 1);
|
$("#impexp-export").css('opacity', 1);
|
||||||
|
|
|
@ -23,16 +23,13 @@
|
||||||
var padeditbar = require('./pad_editbar').padeditbar;
|
var padeditbar = require('./pad_editbar').padeditbar;
|
||||||
var automaticReconnect = require('./pad_automatic_reconnect');
|
var automaticReconnect = require('./pad_automatic_reconnect');
|
||||||
|
|
||||||
var padmodals = (function()
|
var padmodals = (function() {
|
||||||
{
|
|
||||||
var pad = undefined;
|
var pad = undefined;
|
||||||
var self = {
|
var self = {
|
||||||
init: function(_pad)
|
init: function(_pad) {
|
||||||
{
|
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
},
|
},
|
||||||
showModal: function(messageId)
|
showModal: function(messageId) {
|
||||||
{
|
|
||||||
padeditbar.toggleDropDown("none", function() {
|
padeditbar.toggleDropDown("none", function() {
|
||||||
$("#connectivity .visible").removeClass('visible');
|
$("#connectivity .visible").removeClass('visible');
|
||||||
$("#connectivity ."+messageId).addClass('visible');
|
$("#connectivity ."+messageId).addClass('visible');
|
||||||
|
|
|
@ -30,17 +30,14 @@ var colorPickerSetup = false;
|
||||||
var previousColorId = 0;
|
var previousColorId = 0;
|
||||||
|
|
||||||
|
|
||||||
var paduserlist = (function()
|
var paduserlist = (function() {
|
||||||
{
|
|
||||||
|
|
||||||
var rowManager = (function()
|
var rowManager = (function() {
|
||||||
{
|
|
||||||
// The row manager handles rendering rows of the user list and animating
|
// The row manager handles rendering rows of the user list and animating
|
||||||
// their insertion, removal, and reordering. It manipulates TD height
|
// their insertion, removal, and reordering. It manipulates TD height
|
||||||
// and TD opacity.
|
// and TD opacity.
|
||||||
|
|
||||||
function nextRowId()
|
function nextRowId() {
|
||||||
{
|
|
||||||
return "usertr" + (nextRowId.counter++);
|
return "usertr" + (nextRowId.counter++);
|
||||||
}
|
}
|
||||||
nextRowId.counter = 1;
|
nextRowId.counter = 1;
|
||||||
|
@ -52,8 +49,7 @@ var paduserlist = (function()
|
||||||
var ANIMATION_END = 12; // just finishing fading out
|
var ANIMATION_END = 12; // just finishing fading out
|
||||||
|
|
||||||
|
|
||||||
function getAnimationHeight(step, power)
|
function getAnimationHeight(step, power) {
|
||||||
{
|
|
||||||
var a = Math.abs(step / 12);
|
var a = Math.abs(step / 12);
|
||||||
if (power == 2) a = a * a;
|
if (power == 2) a = a * a;
|
||||||
else if (power == 3) a = a * a * a;
|
else if (power == 3) a = a * a * a;
|
||||||
|
@ -72,18 +68,15 @@ var paduserlist = (function()
|
||||||
// we do lots of manipulation of table rows and stuff that JQuery makes ok, despite
|
// we do lots of manipulation of table rows and stuff that JQuery makes ok, despite
|
||||||
// IE's poor handling when manipulating the DOM directly.
|
// IE's poor handling when manipulating the DOM directly.
|
||||||
|
|
||||||
function getEmptyRowHtml(height)
|
function getEmptyRowHtml(height) {
|
||||||
{
|
|
||||||
return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>';
|
return '<td colspan="' + NUMCOLS + '" style="border:0;height:' + height + 'px"><!-- --></td>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNameEditable(data)
|
function isNameEditable(data) {
|
||||||
{
|
|
||||||
return (!data.name) && (data.status != 'Disconnected');
|
return (!data.name) && (data.status != 'Disconnected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceUserRowContents(tr, height, data)
|
function replaceUserRowContents(tr, height, data) {
|
||||||
{
|
|
||||||
var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi);
|
var tds = getUserRowHtml(height, data).match(/<td.*?<\/td>/gi);
|
||||||
if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0)
|
if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0)
|
||||||
{
|
{
|
||||||
|
@ -104,8 +97,7 @@ var paduserlist = (function()
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserRowHtml(height, data)
|
function getUserRowHtml(height, data) {
|
||||||
{
|
|
||||||
var nameHtml;
|
var nameHtml;
|
||||||
if (data.name)
|
if (data.name)
|
||||||
{
|
{
|
||||||
|
@ -119,18 +111,15 @@ var paduserlist = (function()
|
||||||
return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + padutils.escapeHtml(data.color) + '"> </div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join('');
|
return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + padutils.escapeHtml(data.color) + '"> </div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRowHtml(id, innerHtml, authorId)
|
function getRowHtml(id, innerHtml, authorId) {
|
||||||
{
|
|
||||||
return '<tr data-authorId="'+authorId+'" id="' + id + '">' + innerHtml + '</tr>';
|
return '<tr data-authorId="'+authorId+'" id="' + id + '">' + innerHtml + '</tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function rowNode(row)
|
function rowNode(row) {
|
||||||
{
|
|
||||||
return $("#" + row.domId);
|
return $("#" + row.domId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRowData(row)
|
function handleRowData(row) {
|
||||||
{
|
|
||||||
if (row.data && row.data.status == 'Disconnected')
|
if (row.data && row.data.status == 'Disconnected')
|
||||||
{
|
{
|
||||||
row.opacity = 0.5;
|
row.opacity = 0.5;
|
||||||
|
@ -141,13 +130,11 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRowNode(tr, data)
|
function handleRowNode(tr, data) {
|
||||||
{
|
|
||||||
if (data.titleText)
|
if (data.titleText)
|
||||||
{
|
{
|
||||||
var titleText = data.titleText;
|
var titleText = data.titleText;
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
/* tr.attr('title', titleText)*/
|
/* tr.attr('title', titleText)*/
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
@ -157,11 +144,9 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOtherUserInputs()
|
function handleOtherUserInputs() {
|
||||||
{
|
|
||||||
// handle 'INPUT' elements for naming other unnamed users
|
// handle 'INPUT' elements for naming other unnamed users
|
||||||
$("#otheruserstable input.newinput").each(function()
|
$("#otheruserstable input.newinput").each(function() {
|
||||||
{
|
|
||||||
var input = $(this);
|
var input = $(this);
|
||||||
var tr = input.closest("tr");
|
var tr = input.closest("tr");
|
||||||
if (tr.length > 0)
|
if (tr.length > 0)
|
||||||
|
@ -179,8 +164,7 @@ var paduserlist = (function()
|
||||||
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
|
// animationPower is 0 to skip animation, 1 for linear, 2 for quadratic, etc.
|
||||||
|
|
||||||
|
|
||||||
function insertRow(position, data, animationPower)
|
function insertRow(position, data, animationPower) {
|
||||||
{
|
|
||||||
position = Math.max(0, Math.min(rowsPresent.length, position));
|
position = Math.max(0, Math.min(rowsPresent.length, position));
|
||||||
animationPower = (animationPower === undefined ? 4 : animationPower);
|
animationPower = (animationPower === undefined ? 4 : animationPower);
|
||||||
|
|
||||||
|
@ -227,8 +211,7 @@ var paduserlist = (function()
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRow(position, data)
|
function updateRow(position, data) {
|
||||||
{
|
|
||||||
var row = rowsPresent[position];
|
var row = rowsPresent[position];
|
||||||
if (row)
|
if (row)
|
||||||
{
|
{
|
||||||
|
@ -245,8 +228,7 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRow(position, animationPower)
|
function removeRow(position, animationPower) {
|
||||||
{
|
|
||||||
animationPower = (animationPower === undefined ? 4 : animationPower);
|
animationPower = (animationPower === undefined ? 4 : animationPower);
|
||||||
var row = rowsPresent[position];
|
var row = rowsPresent[position];
|
||||||
if (row)
|
if (row)
|
||||||
|
@ -272,8 +254,7 @@ var paduserlist = (function()
|
||||||
// newPosition is position after the row has been removed
|
// newPosition is position after the row has been removed
|
||||||
|
|
||||||
|
|
||||||
function moveRow(oldPosition, newPosition, animationPower)
|
function moveRow(oldPosition, newPosition, animationPower) {
|
||||||
{
|
|
||||||
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
|
animationPower = (animationPower === undefined ? 1 : animationPower); // linear is best
|
||||||
var row = rowsPresent[oldPosition];
|
var row = rowsPresent[oldPosition];
|
||||||
if (row && oldPosition != newPosition)
|
if (row && oldPosition != newPosition)
|
||||||
|
@ -284,8 +265,7 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateStep()
|
function animateStep() {
|
||||||
{
|
|
||||||
// animation must be symmetrical
|
// animation must be symmetrical
|
||||||
for (var i = rowsFadingIn.length - 1; i >= 0; i--)
|
for (var i = rowsFadingIn.length - 1; i >= 0; i--)
|
||||||
{ // backwards to allow removal
|
{ // backwards to allow removal
|
||||||
|
@ -357,10 +337,8 @@ var paduserlist = (function()
|
||||||
var otherUsersInfo = [];
|
var otherUsersInfo = [];
|
||||||
var otherUsersData = [];
|
var otherUsersData = [];
|
||||||
|
|
||||||
function rowManagerMakeNameEditor(jnode, userId)
|
function rowManagerMakeNameEditor(jnode, userId) {
|
||||||
{
|
setUpEditable(jnode, function() {
|
||||||
setUpEditable(jnode, function()
|
|
||||||
{
|
|
||||||
var existingIndex = findExistingIndex(userId);
|
var existingIndex = findExistingIndex(userId);
|
||||||
if (existingIndex >= 0)
|
if (existingIndex >= 0)
|
||||||
{
|
{
|
||||||
|
@ -370,8 +348,7 @@ var paduserlist = (function()
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}, function(newName)
|
}, function(newName) {
|
||||||
{
|
|
||||||
if (!newName)
|
if (!newName)
|
||||||
{
|
{
|
||||||
jnode.addClass("editempty");
|
jnode.addClass("editempty");
|
||||||
|
@ -385,8 +362,7 @@ var paduserlist = (function()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function findExistingIndex(userId)
|
function findExistingIndex(userId) {
|
||||||
{
|
|
||||||
var existingIndex = -1;
|
var existingIndex = -1;
|
||||||
for (var i = 0; i < otherUsersInfo.length; i++)
|
for (var i = 0; i < otherUsersInfo.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -399,10 +375,8 @@ var paduserlist = (function()
|
||||||
return existingIndex;
|
return existingIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUpEditable(jqueryNode, valueGetter, valueSetter)
|
function setUpEditable(jqueryNode, valueGetter, valueSetter) {
|
||||||
{
|
jqueryNode.bind('focus', function(evt) {
|
||||||
jqueryNode.bind('focus', function(evt)
|
|
||||||
{
|
|
||||||
var oldValue = valueGetter();
|
var oldValue = valueGetter();
|
||||||
if (jqueryNode.val() !== oldValue)
|
if (jqueryNode.val() !== oldValue)
|
||||||
{
|
{
|
||||||
|
@ -410,16 +384,13 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
jqueryNode.addClass("editactive").removeClass("editempty");
|
jqueryNode.addClass("editactive").removeClass("editempty");
|
||||||
});
|
});
|
||||||
jqueryNode.bind('blur', function(evt)
|
jqueryNode.bind('blur', function(evt) {
|
||||||
{
|
|
||||||
var newValue = jqueryNode.removeClass("editactive").val();
|
var newValue = jqueryNode.removeClass("editactive").val();
|
||||||
valueSetter(newValue);
|
valueSetter(newValue);
|
||||||
});
|
});
|
||||||
padutils.bindEnterAndEscape(jqueryNode, function onEnter()
|
padutils.bindEnterAndEscape(jqueryNode, function onEnter() {
|
||||||
{
|
|
||||||
jqueryNode.blur();
|
jqueryNode.blur();
|
||||||
}, function onEscape()
|
}, function onEscape() {
|
||||||
{
|
|
||||||
jqueryNode.val(valueGetter()).blur();
|
jqueryNode.val(valueGetter()).blur();
|
||||||
});
|
});
|
||||||
jqueryNode.removeAttr('disabled').addClass('editable');
|
jqueryNode.removeAttr('disabled').addClass('editable');
|
||||||
|
@ -429,8 +400,7 @@ var paduserlist = (function()
|
||||||
var guestPromptFlashState = 0;
|
var guestPromptFlashState = 0;
|
||||||
var guestPromptFlash = padutils.makeAnimationScheduler(
|
var guestPromptFlash = padutils.makeAnimationScheduler(
|
||||||
|
|
||||||
function()
|
function() {
|
||||||
{
|
|
||||||
var prompts = $("#guestprompts .guestprompt");
|
var prompts = $("#guestprompts .guestprompt");
|
||||||
if (prompts.length == 0)
|
if (prompts.length == 0)
|
||||||
{
|
{
|
||||||
|
@ -452,8 +422,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
var pad = undefined;
|
var pad = undefined;
|
||||||
var self = {
|
var self = {
|
||||||
init: function(myInitialUserInfo, _pad)
|
init: function(myInitialUserInfo, _pad) {
|
||||||
{
|
|
||||||
pad = _pad;
|
pad = _pad;
|
||||||
|
|
||||||
self.setMyUserInfo(myInitialUserInfo);
|
self.setMyUserInfo(myInitialUserInfo);
|
||||||
|
@ -465,17 +434,14 @@ var paduserlist = (function()
|
||||||
if (pad.getUserIsGuest())
|
if (pad.getUserIsGuest())
|
||||||
{
|
{
|
||||||
$("#myusernameedit").addClass('myusernameedithoverable');
|
$("#myusernameedit").addClass('myusernameedithoverable');
|
||||||
setUpEditable($("#myusernameedit"), function()
|
setUpEditable($("#myusernameedit"), function() {
|
||||||
{
|
|
||||||
return myUserInfo.name || '';
|
return myUserInfo.name || '';
|
||||||
}, function(newValue)
|
}, function(newValue) {
|
||||||
{
|
|
||||||
myUserInfo.name = newValue;
|
myUserInfo.name = newValue;
|
||||||
pad.notifyChangeName(newValue);
|
pad.notifyChangeName(newValue);
|
||||||
// wrap with setTimeout to do later because we get
|
// wrap with setTimeout to do later because we get
|
||||||
// a double "blur" fire in IE...
|
// a double "blur" fire in IE...
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
self.renderMyUserInfo();
|
self.renderMyUserInfo();
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
@ -483,23 +449,19 @@ var paduserlist = (function()
|
||||||
|
|
||||||
// color picker
|
// color picker
|
||||||
$("#myswatchbox").click(showColorPicker);
|
$("#myswatchbox").click(showColorPicker);
|
||||||
$("#mycolorpicker .pickerswatchouter").click(function()
|
$("#mycolorpicker .pickerswatchouter").click(function() {
|
||||||
{
|
|
||||||
$("#mycolorpicker .pickerswatchouter").removeClass('picked');
|
$("#mycolorpicker .pickerswatchouter").removeClass('picked');
|
||||||
$(this).addClass('picked');
|
$(this).addClass('picked');
|
||||||
});
|
});
|
||||||
$("#mycolorpickersave").click(function()
|
$("#mycolorpickersave").click(function() {
|
||||||
{
|
|
||||||
closeColorPicker(true);
|
closeColorPicker(true);
|
||||||
});
|
});
|
||||||
$("#mycolorpickercancel").click(function()
|
$("#mycolorpickercancel").click(function() {
|
||||||
{
|
|
||||||
closeColorPicker(false);
|
closeColorPicker(false);
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
usersOnline: function()
|
usersOnline: function() {
|
||||||
{
|
|
||||||
// Returns an object of users who are currently online on this pad
|
// Returns an object of users who are currently online on this pad
|
||||||
var userList = [].concat(otherUsersInfo); // Make a copy of the otherUsersInfo, otherwise every call to users modifies the referenced array
|
var userList = [].concat(otherUsersInfo); // Make a copy of the otherUsersInfo, otherwise every call to users modifies the referenced array
|
||||||
// Now we need to add ourselves..
|
// Now we need to add ourselves..
|
||||||
|
@ -527,8 +489,7 @@ var paduserlist = (function()
|
||||||
}
|
}
|
||||||
return userList;
|
return userList;
|
||||||
},
|
},
|
||||||
setMyUserInfo: function(info)
|
setMyUserInfo: function(info) {
|
||||||
{
|
|
||||||
//translate the colorId
|
//translate the colorId
|
||||||
if(typeof info.colorId == "number")
|
if(typeof info.colorId == "number")
|
||||||
{
|
{
|
||||||
|
@ -540,8 +501,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
self.renderMyUserInfo();
|
self.renderMyUserInfo();
|
||||||
},
|
},
|
||||||
userJoinOrUpdate: function(info)
|
userJoinOrUpdate: function(info) {
|
||||||
{
|
|
||||||
if ((!info.userId) || (info.userId == myUserInfo.userId))
|
if ((!info.userId) || (info.userId == myUserInfo.userId))
|
||||||
{
|
{
|
||||||
// not sure how this would happen
|
// not sure how this would happen
|
||||||
|
@ -568,8 +528,7 @@ var paduserlist = (function()
|
||||||
{
|
{
|
||||||
numUsersBesides--;
|
numUsersBesides--;
|
||||||
}
|
}
|
||||||
var newIndex = padutils.binarySearch(numUsersBesides, function(n)
|
var newIndex = padutils.binarySearch(numUsersBesides, function(n) {
|
||||||
{
|
|
||||||
if (existingIndex >= 0 && n >= existingIndex)
|
if (existingIndex >= 0 && n >= existingIndex)
|
||||||
{
|
{
|
||||||
// pretend existingIndex isn't there
|
// pretend existingIndex isn't there
|
||||||
|
@ -611,8 +570,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
self.updateNumberOfOnlineUsers();
|
self.updateNumberOfOnlineUsers();
|
||||||
},
|
},
|
||||||
updateNumberOfOnlineUsers: function()
|
updateNumberOfOnlineUsers: function() {
|
||||||
{
|
|
||||||
var online = 1; // you are always online!
|
var online = 1; // you are always online!
|
||||||
for (var i = 0; i < otherUsersData.length; i++)
|
for (var i = 0; i < otherUsersData.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -626,8 +584,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
return online;
|
return online;
|
||||||
},
|
},
|
||||||
userLeave: function(info)
|
userLeave: function(info) {
|
||||||
{
|
|
||||||
var existingIndex = findExistingIndex(info.userId);
|
var existingIndex = findExistingIndex(info.userId);
|
||||||
if (existingIndex >= 0)
|
if (existingIndex >= 0)
|
||||||
{
|
{
|
||||||
|
@ -642,8 +599,7 @@ var paduserlist = (function()
|
||||||
// joins, or updates happen for this user in the
|
// joins, or updates happen for this user in the
|
||||||
// next N seconds, to remove the user from the list.
|
// next N seconds, to remove the user from the list.
|
||||||
var thisUserId = info.userId;
|
var thisUserId = info.userId;
|
||||||
var thisLeaveTimer = window.setTimeout(function()
|
var thisLeaveTimer = window.setTimeout(function() {
|
||||||
{
|
|
||||||
var newExistingIndex = findExistingIndex(thisUserId);
|
var newExistingIndex = findExistingIndex(thisUserId);
|
||||||
if (newExistingIndex >= 0)
|
if (newExistingIndex >= 0)
|
||||||
{
|
{
|
||||||
|
@ -664,8 +620,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
self.updateNumberOfOnlineUsers();
|
self.updateNumberOfOnlineUsers();
|
||||||
},
|
},
|
||||||
showGuestPrompt: function(userId, displayName)
|
showGuestPrompt: function(userId, displayName) {
|
||||||
{
|
|
||||||
if (knocksToIgnore[userId])
|
if (knocksToIgnore[userId])
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -688,30 +643,25 @@ var paduserlist = (function()
|
||||||
// update display name
|
// update display name
|
||||||
box.find(".guestname").html('<strong>'+_('pad.userlist.guest')+':</strong> ' + padutils.escapeHtml(displayName));
|
box.find(".guestname").html('<strong>'+_('pad.userlist.guest')+':</strong> ' + padutils.escapeHtml(displayName));
|
||||||
}
|
}
|
||||||
var hideLater = padutils.getCancellableAction(actionName, function()
|
var hideLater = padutils.getCancellableAction(actionName, function() {
|
||||||
{
|
|
||||||
self.removeGuestPrompt(userId);
|
self.removeGuestPrompt(userId);
|
||||||
});
|
});
|
||||||
window.setTimeout(hideLater, 15000); // time-out with no knock
|
window.setTimeout(hideLater, 15000); // time-out with no knock
|
||||||
guestPromptFlash.scheduleAnimation();
|
guestPromptFlash.scheduleAnimation();
|
||||||
},
|
},
|
||||||
removeGuestPrompt: function(userId)
|
removeGuestPrompt: function(userId) {
|
||||||
{
|
|
||||||
var box = $("#guestprompt-" + padutils.encodeUserId(userId));
|
var box = $("#guestprompt-" + padutils.encodeUserId(userId));
|
||||||
// remove ID now so a new knock by same user gets new, unfaded box
|
// remove ID now so a new knock by same user gets new, unfaded box
|
||||||
box.removeAttr('id').fadeOut("fast", function()
|
box.removeAttr('id').fadeOut("fast", function() {
|
||||||
{
|
|
||||||
box.remove();
|
box.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
knocksToIgnore[userId] = true;
|
knocksToIgnore[userId] = true;
|
||||||
window.setTimeout(function()
|
window.setTimeout(function() {
|
||||||
{
|
|
||||||
delete knocksToIgnore[userId];
|
delete knocksToIgnore[userId];
|
||||||
}, 5000);
|
}, 5000);
|
||||||
},
|
},
|
||||||
answerGuestPrompt: function(encodedUserId, approve)
|
answerGuestPrompt: function(encodedUserId, approve) {
|
||||||
{
|
|
||||||
var guestId = padutils.decodeUserId(encodedUserId);
|
var guestId = padutils.decodeUserId(encodedUserId);
|
||||||
|
|
||||||
var msg = {
|
var msg = {
|
||||||
|
@ -724,8 +674,7 @@ var paduserlist = (function()
|
||||||
|
|
||||||
self.removeGuestPrompt(guestId);
|
self.removeGuestPrompt(guestId);
|
||||||
},
|
},
|
||||||
renderMyUserInfo: function()
|
renderMyUserInfo: function() {
|
||||||
{
|
|
||||||
if (myUserInfo.name)
|
if (myUserInfo.name)
|
||||||
{
|
{
|
||||||
$("#myusernameedit").removeClass("editempty").val(myUserInfo.name);
|
$("#myusernameedit").removeClass("editempty").val(myUserInfo.name);
|
||||||
|
@ -757,14 +706,12 @@ var paduserlist = (function()
|
||||||
return self;
|
return self;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
function getColorPickerSwatchIndex(jnode)
|
function getColorPickerSwatchIndex(jnode) {
|
||||||
{
|
|
||||||
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
|
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
|
||||||
return $("#colorpickerswatches li").index(jnode);
|
return $("#colorpickerswatches li").index(jnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeColorPicker(accept)
|
function closeColorPicker(accept) {
|
||||||
{
|
|
||||||
if (accept)
|
if (accept)
|
||||||
{
|
{
|
||||||
var newColor = $("#mycolorpickerpreview").css("background-color");
|
var newColor = $("#mycolorpickerpreview").css("background-color");
|
||||||
|
@ -792,8 +739,7 @@ function closeColorPicker(accept)
|
||||||
$("#mycolorpicker").removeClass('popup-show');
|
$("#mycolorpicker").removeClass('popup-show');
|
||||||
}
|
}
|
||||||
|
|
||||||
function showColorPicker()
|
function showColorPicker() {
|
||||||
{
|
|
||||||
previousColorId = myUserInfo.colorId;
|
previousColorId = myUserInfo.colorId;
|
||||||
$.farbtastic('#colorpicker').setColor(myUserInfo.colorId)
|
$.farbtastic('#colorpicker').setColor(myUserInfo.colorId)
|
||||||
|
|
||||||
|
@ -813,8 +759,7 @@ function showColorPicker()
|
||||||
|
|
||||||
li.appendTo(colorsList);
|
li.appendTo(colorsList);
|
||||||
|
|
||||||
li.bind('click', function(event)
|
li.bind('click', function(event) {
|
||||||
{
|
|
||||||
$("#colorpickerswatches li").removeClass('picked');
|
$("#colorpickerswatches li").removeClass('picked');
|
||||||
$(event.target).addClass("picked");
|
$(event.target).addClass("picked");
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,7 @@ var Security = require('./security');
|
||||||
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
|
* Generates a random String with the given length. Is needed to generate the Author, Group, readonly, session Ids
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function randomString(len)
|
function randomString(len) {
|
||||||
{
|
|
||||||
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
var randomstring = '';
|
var randomstring = '';
|
||||||
len = len || 20
|
len = len || 20
|
||||||
|
@ -40,27 +39,22 @@ function randomString(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
var padutils = {
|
var padutils = {
|
||||||
escapeHtml: function(x)
|
escapeHtml: function(x) {
|
||||||
{
|
|
||||||
return Security.escapeHTML(String(x));
|
return Security.escapeHTML(String(x));
|
||||||
},
|
},
|
||||||
uniqueId: function()
|
uniqueId: function() {
|
||||||
{
|
|
||||||
var pad = require('./pad').pad; // Sidestep circular dependency
|
var pad = require('./pad').pad; // Sidestep circular dependency
|
||||||
function encodeNum(n, width)
|
function encodeNum(n, width) {
|
||||||
{
|
|
||||||
// returns string that is exactly 'width' chars, padding with zeros
|
// returns string that is exactly 'width' chars, padding with zeros
|
||||||
// and taking rightmost digits
|
// and taking rightmost digits
|
||||||
return (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
|
return (Array(width + 1).join('0') + Number(n).toString(35)).slice(-width);
|
||||||
}
|
}
|
||||||
return [pad.getClientIp(), encodeNum(+new Date, 7), encodeNum(Math.floor(Math.random() * 1e9), 4)].join('.');
|
return [pad.getClientIp(), encodeNum(+new Date, 7), encodeNum(Math.floor(Math.random() * 1e9), 4)].join('.');
|
||||||
},
|
},
|
||||||
uaDisplay: function(ua)
|
uaDisplay: function(ua) {
|
||||||
{
|
|
||||||
var m;
|
var m;
|
||||||
|
|
||||||
function clean(a)
|
function clean(a) {
|
||||||
{
|
|
||||||
var maxlen = 16;
|
var maxlen = 16;
|
||||||
a = a.replace(/[^a-zA-Z0-9\.]/g, '');
|
a = a.replace(/[^a-zA-Z0-9\.]/g, '');
|
||||||
if (a.length > maxlen)
|
if (a.length > maxlen)
|
||||||
|
@ -70,8 +64,7 @@ var padutils = {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkver(name)
|
function checkver(name) {
|
||||||
{
|
|
||||||
var m = ua.match(RegExp(name + '\\/([\\d\\.]+)'));
|
var m = ua.match(RegExp(name + '\\/([\\d\\.]+)'));
|
||||||
if (m && m.length > 1)
|
if (m && m.length > 1)
|
||||||
{
|
{
|
||||||
|
@ -123,8 +116,7 @@ var padutils = {
|
||||||
return clean(x);
|
return clean(x);
|
||||||
},
|
},
|
||||||
// e.g. "Thu Jun 18 2009 13:09"
|
// e.g. "Thu Jun 18 2009 13:09"
|
||||||
simpleDateTime: function(date)
|
simpleDateTime: function(date) {
|
||||||
{
|
|
||||||
var d = new Date(+date); // accept either number or date
|
var d = new Date(+date); // accept either number or date
|
||||||
var dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
|
var dayOfWeek = (['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'])[d.getDay()];
|
||||||
var month = (['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])[d.getMonth()];
|
var month = (['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])[d.getMonth()];
|
||||||
|
@ -133,8 +125,7 @@ var padutils = {
|
||||||
var hourmin = d.getHours() + ":" + ("0" + d.getMinutes()).slice(-2);
|
var hourmin = d.getHours() + ":" + ("0" + d.getMinutes()).slice(-2);
|
||||||
return dayOfWeek + ' ' + month + ' ' + dayOfMonth + ' ' + year + ' ' + hourmin;
|
return dayOfWeek + ' ' + month + ' ' + dayOfMonth + ' ' + year + ' ' + hourmin;
|
||||||
},
|
},
|
||||||
findURLs: function(text)
|
findURLs: function(text) {
|
||||||
{
|
|
||||||
// copied from ACE
|
// copied from ACE
|
||||||
var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
|
var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
|
||||||
var _REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/?=&#;()$]/.source + '|' + _REGEX_WORDCHAR.source + ')');
|
var _REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/?=&#;()$]/.source + '|' + _REGEX_WORDCHAR.source + ')');
|
||||||
|
@ -143,8 +134,7 @@ var padutils = {
|
||||||
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
// returns null if no URLs, or [[startIndex1, url1], [startIndex2, url2], ...]
|
||||||
|
|
||||||
|
|
||||||
function _findURLs(text)
|
function _findURLs(text) {
|
||||||
{
|
|
||||||
_REGEX_URL.lastIndex = 0;
|
_REGEX_URL.lastIndex = 0;
|
||||||
var urls = null;
|
var urls = null;
|
||||||
var execResult;
|
var execResult;
|
||||||
|
@ -161,14 +151,12 @@ var padutils = {
|
||||||
|
|
||||||
return _findURLs(text);
|
return _findURLs(text);
|
||||||
},
|
},
|
||||||
escapeHtmlWithClickableLinks: function(text, target)
|
escapeHtmlWithClickableLinks: function(text, target) {
|
||||||
{
|
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
var pieces = [];
|
var pieces = [];
|
||||||
var urls = padutils.findURLs(text);
|
var urls = padutils.findURLs(text);
|
||||||
|
|
||||||
function advanceTo(i)
|
function advanceTo(i) {
|
||||||
{
|
|
||||||
if (i > idx)
|
if (i > idx)
|
||||||
{
|
{
|
||||||
pieces.push(Security.escapeHTML(text.substring(idx, i)));
|
pieces.push(Security.escapeHTML(text.substring(idx, i)));
|
||||||
|
@ -197,8 +185,7 @@ var padutils = {
|
||||||
advanceTo(text.length);
|
advanceTo(text.length);
|
||||||
return pieces.join('');
|
return pieces.join('');
|
||||||
},
|
},
|
||||||
bindEnterAndEscape: function(node, onEnter, onEscape)
|
bindEnterAndEscape: function(node, onEnter, onEscape) {
|
||||||
{
|
|
||||||
|
|
||||||
// Use keypress instead of keyup in bindEnterAndEscape
|
// Use keypress instead of keyup in bindEnterAndEscape
|
||||||
// Keyup event is fired on enter in IME (Input Method Editor), But
|
// Keyup event is fired on enter in IME (Input Method Editor), But
|
||||||
|
@ -206,8 +193,7 @@ var padutils = {
|
||||||
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
|
// It is work on Windows (IE8, Chrome 6.0.472), CentOs (Firefox 3.0) and Mac OSX (Firefox 3.6.10, Chrome 6.0.472, Safari 5.0).
|
||||||
if (onEnter)
|
if (onEnter)
|
||||||
{
|
{
|
||||||
node.keypress(function(evt)
|
node.keypress(function(evt) {
|
||||||
{
|
|
||||||
if (evt.which == 13)
|
if (evt.which == 13)
|
||||||
{
|
{
|
||||||
onEnter(evt);
|
onEnter(evt);
|
||||||
|
@ -217,8 +203,7 @@ var padutils = {
|
||||||
|
|
||||||
if (onEscape)
|
if (onEscape)
|
||||||
{
|
{
|
||||||
node.keydown(function(evt)
|
node.keydown(function(evt) {
|
||||||
{
|
|
||||||
if (evt.which == 27)
|
if (evt.which == 27)
|
||||||
{
|
{
|
||||||
onEscape(evt);
|
onEscape(evt);
|
||||||
|
@ -226,11 +211,9 @@ var padutils = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
timediff: function(d)
|
timediff: function(d) {
|
||||||
{
|
|
||||||
var pad = require('./pad').pad; // Sidestep circular dependency
|
var pad = require('./pad').pad; // Sidestep circular dependency
|
||||||
function format(n, word)
|
function format(n, word) {
|
||||||
{
|
|
||||||
n = Math.round(n);
|
n = Math.round(n);
|
||||||
return ('' + n + ' ' + word + (n != 1 ? 's' : '') + ' ago');
|
return ('' + n + ' ' + word + (n != 1 ? 's' : '') + ' ago');
|
||||||
}
|
}
|
||||||
|
@ -252,8 +235,7 @@ var padutils = {
|
||||||
d /= 24;
|
d /= 24;
|
||||||
return format(d, 'day');
|
return format(d, 'day');
|
||||||
},
|
},
|
||||||
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce)
|
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce) {
|
||||||
{
|
|
||||||
if (stepsAtOnce === undefined)
|
if (stepsAtOnce === undefined)
|
||||||
{
|
{
|
||||||
stepsAtOnce = 1;
|
stepsAtOnce = 1;
|
||||||
|
@ -261,12 +243,10 @@ var padutils = {
|
||||||
|
|
||||||
var animationTimer = null;
|
var animationTimer = null;
|
||||||
|
|
||||||
function scheduleAnimation()
|
function scheduleAnimation() {
|
||||||
{
|
|
||||||
if (!animationTimer)
|
if (!animationTimer)
|
||||||
{
|
{
|
||||||
animationTimer = window.setTimeout(function()
|
animationTimer = window.setTimeout(function() {
|
||||||
{
|
|
||||||
animationTimer = null;
|
animationTimer = null;
|
||||||
var n = stepsAtOnce;
|
var n = stepsAtOnce;
|
||||||
var moreToDo = true;
|
var moreToDo = true;
|
||||||
|
@ -287,23 +267,20 @@ var padutils = {
|
||||||
scheduleAnimation: scheduleAnimation
|
scheduleAnimation: scheduleAnimation
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
makeShowHideAnimator: function(funcToArriveAtState, initiallyShown, fps, totalMs)
|
makeShowHideAnimator: function(funcToArriveAtState, initiallyShown, fps, totalMs) {
|
||||||
{
|
|
||||||
var animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
|
var animationState = (initiallyShown ? 0 : -2); // -2 hidden, -1 to 0 fade in, 0 to 1 fade out
|
||||||
var animationFrameDelay = 1000 / fps;
|
var animationFrameDelay = 1000 / fps;
|
||||||
var animationStep = animationFrameDelay / totalMs;
|
var animationStep = animationFrameDelay / totalMs;
|
||||||
|
|
||||||
var scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
|
var scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
|
||||||
|
|
||||||
function doShow()
|
function doShow() {
|
||||||
{
|
|
||||||
animationState = -1;
|
animationState = -1;
|
||||||
funcToArriveAtState(animationState);
|
funcToArriveAtState(animationState);
|
||||||
scheduleAnimation();
|
scheduleAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
function doQuickShow()
|
function doQuickShow() { // start showing without losing any fade-in progress
|
||||||
{ // start showing without losing any fade-in progress
|
|
||||||
if (animationState < -1)
|
if (animationState < -1)
|
||||||
{
|
{
|
||||||
animationState = -1;
|
animationState = -1;
|
||||||
|
@ -316,8 +293,7 @@ var padutils = {
|
||||||
scheduleAnimation();
|
scheduleAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
function doHide()
|
function doHide() {
|
||||||
{
|
|
||||||
if (animationState >= -1 && animationState <= 0)
|
if (animationState >= -1 && animationState <= 0)
|
||||||
{
|
{
|
||||||
animationState = 1e-6;
|
animationState = 1e-6;
|
||||||
|
@ -325,8 +301,7 @@ var padutils = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateOneStep()
|
function animateOneStep() {
|
||||||
{
|
|
||||||
if (animationState < -1 || animationState == 0)
|
if (animationState < -1 || animationState == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -374,8 +349,7 @@ var padutils = {
|
||||||
},
|
},
|
||||||
_nextActionId: 1,
|
_nextActionId: 1,
|
||||||
uncanceledActions: {},
|
uncanceledActions: {},
|
||||||
getCancellableAction: function(actionType, actionFunc)
|
getCancellableAction: function(actionType, actionFunc) {
|
||||||
{
|
|
||||||
var o = padutils.uncanceledActions[actionType];
|
var o = padutils.uncanceledActions[actionType];
|
||||||
if (!o)
|
if (!o)
|
||||||
{
|
{
|
||||||
|
@ -384,8 +358,7 @@ var padutils = {
|
||||||
}
|
}
|
||||||
var actionId = (padutils._nextActionId++);
|
var actionId = (padutils._nextActionId++);
|
||||||
o[actionId] = true;
|
o[actionId] = true;
|
||||||
return function()
|
return function() {
|
||||||
{
|
|
||||||
var p = padutils.uncanceledActions[actionType];
|
var p = padutils.uncanceledActions[actionType];
|
||||||
if (p && p[actionId])
|
if (p && p[actionId])
|
||||||
{
|
{
|
||||||
|
@ -393,8 +366,7 @@ var padutils = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
cancelActions: function(actionType)
|
cancelActions: function(actionType) {
|
||||||
{
|
|
||||||
var o = padutils.uncanceledActions[actionType];
|
var o = padutils.uncanceledActions[actionType];
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
|
@ -402,25 +374,21 @@ var padutils = {
|
||||||
delete padutils.uncanceledActions[actionType];
|
delete padutils.uncanceledActions[actionType];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
makeFieldLabeledWhenEmpty: function(field, labelText)
|
makeFieldLabeledWhenEmpty: function(field, labelText) {
|
||||||
{
|
|
||||||
field = $(field);
|
field = $(field);
|
||||||
|
|
||||||
function clear()
|
function clear() {
|
||||||
{
|
|
||||||
field.addClass('editempty');
|
field.addClass('editempty');
|
||||||
field.val(labelText);
|
field.val(labelText);
|
||||||
}
|
}
|
||||||
field.focus(function()
|
field.focus(function() {
|
||||||
{
|
|
||||||
if (field.hasClass('editempty'))
|
if (field.hasClass('editempty'))
|
||||||
{
|
{
|
||||||
field.val('');
|
field.val('');
|
||||||
}
|
}
|
||||||
field.removeClass('editempty');
|
field.removeClass('editempty');
|
||||||
});
|
});
|
||||||
field.blur(function()
|
field.blur(function() {
|
||||||
{
|
|
||||||
if (!field.val())
|
if (!field.val())
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -430,12 +398,10 @@ var padutils = {
|
||||||
clear: clear
|
clear: clear
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getCheckbox: function(node)
|
getCheckbox: function(node) {
|
||||||
{
|
|
||||||
return $(node).is(':checked');
|
return $(node).is(':checked');
|
||||||
},
|
},
|
||||||
setCheckbox: function(node, value)
|
setCheckbox: function(node, value) {
|
||||||
{
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
$(node).attr('checked', 'checked');
|
$(node).attr('checked', 'checked');
|
||||||
|
@ -445,22 +411,17 @@ var padutils = {
|
||||||
$(node).removeAttr('checked');
|
$(node).removeAttr('checked');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bindCheckboxChange: function(node, func)
|
bindCheckboxChange: function(node, func) {
|
||||||
{
|
|
||||||
$(node).change(func);
|
$(node).change(func);
|
||||||
},
|
},
|
||||||
encodeUserId: function(userId)
|
encodeUserId: function(userId) {
|
||||||
{
|
return userId.replace(/[^a-y0-9]/g, function(c) {
|
||||||
return userId.replace(/[^a-y0-9]/g, function(c)
|
|
||||||
{
|
|
||||||
if (c == ".") return "-";
|
if (c == ".") return "-";
|
||||||
return 'z' + c.charCodeAt(0) + 'z';
|
return 'z' + c.charCodeAt(0) + 'z';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
decodeUserId: function(encodedUserId)
|
decodeUserId: function(encodedUserId) {
|
||||||
{
|
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc) {
|
||||||
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc)
|
|
||||||
{
|
|
||||||
if (cc == '-') return '.';
|
if (cc == '-') return '.';
|
||||||
else if (cc.charAt(0) == 'z')
|
else if (cc.charAt(0) == 'z')
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,8 +17,7 @@ function Scroll(outerWin) {
|
||||||
this.rootDocument = parent.parent.document;
|
this.rootDocument = parent.parent.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.scrollWhenCaretIsInTheLastLineOfViewportWhenNecessary = function (rep, isScrollableEvent, innerHeight)
|
Scroll.prototype.scrollWhenCaretIsInTheLastLineOfViewportWhenNecessary = function (rep, isScrollableEvent, innerHeight) {
|
||||||
{
|
|
||||||
// are we placing the caret on the line at the bottom of viewport?
|
// are we placing the caret on the line at the bottom of viewport?
|
||||||
// And if so, do we need to scroll the editor, as defined on the settings.json?
|
// And if so, do we need to scroll the editor, as defined on the settings.json?
|
||||||
var shouldScrollWhenCaretIsAtBottomOfViewport = this.scrollSettings.scrollWhenCaretIsInTheLastLineOfViewport;
|
var shouldScrollWhenCaretIsAtBottomOfViewport = this.scrollSettings.scrollWhenCaretIsInTheLastLineOfViewport;
|
||||||
|
@ -36,8 +35,7 @@ Scroll.prototype.scrollWhenCaretIsInTheLastLineOfViewportWhenNecessary = functio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.scrollWhenPressArrowKeys = function(arrowUp, rep, innerHeight)
|
Scroll.prototype.scrollWhenPressArrowKeys = function(arrowUp, rep, innerHeight) {
|
||||||
{
|
|
||||||
// if percentageScrollArrowUp is 0, let the scroll to be handled as default, put the previous
|
// if percentageScrollArrowUp is 0, let the scroll to be handled as default, put the previous
|
||||||
// rep line on the top of the viewport
|
// rep line on the top of the viewport
|
||||||
if(this._arrowUpWasPressedInTheFirstLineOfTheViewport(arrowUp, rep)){
|
if(this._arrowUpWasPressedInTheFirstLineOfTheViewport(arrowUp, rep)){
|
||||||
|
@ -54,8 +52,7 @@ Scroll.prototype.scrollWhenPressArrowKeys = function(arrowUp, rep, innerHeight)
|
||||||
// Some plugins might set a minimum height to the editor (ex: ep_page_view), so checking
|
// Some plugins might set a minimum height to the editor (ex: ep_page_view), so checking
|
||||||
// if (caretLine() === rep.lines.length() - 1) is not enough. We need to check if there are
|
// if (caretLine() === rep.lines.length() - 1) is not enough. We need to check if there are
|
||||||
// other lines after caretLine(), and all of them are out of viewport.
|
// other lines after caretLine(), and all of them are out of viewport.
|
||||||
Scroll.prototype._isCaretAtTheBottomOfViewport = function(rep)
|
Scroll.prototype._isCaretAtTheBottomOfViewport = function(rep) {
|
||||||
{
|
|
||||||
// computing a line position using getBoundingClientRect() is expensive.
|
// computing a line position using getBoundingClientRect() is expensive.
|
||||||
// (obs: getBoundingClientRect() is called on caretPosition.getPosition())
|
// (obs: getBoundingClientRect() is called on caretPosition.getPosition())
|
||||||
// To avoid that, we only call this function when it is possible that the
|
// To avoid that, we only call this function when it is possible that the
|
||||||
|
@ -76,8 +73,7 @@ Scroll.prototype._isCaretAtTheBottomOfViewport = function(rep)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep)
|
Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep) {
|
||||||
{
|
|
||||||
var lineNode = rep.lines.atIndex(lineNumber);
|
var lineNode = rep.lines.atIndex(lineNumber);
|
||||||
var linePosition = this._getLineEntryTopBottom(lineNode);
|
var linePosition = this._getLineEntryTopBottom(lineNode);
|
||||||
var lineTop = linePosition.top;
|
var lineTop = linePosition.top;
|
||||||
|
@ -98,8 +94,7 @@ Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep)
|
||||||
(bottomOfLineIsAboveViewportBottom && bottomOfLineIsBelowViewportTop);
|
(bottomOfLineIsAboveViewportBottom && bottomOfLineIsBelowViewportTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._getViewPortTopBottom = function()
|
Scroll.prototype._getViewPortTopBottom = function() {
|
||||||
{
|
|
||||||
var theTop = this.getScrollY();
|
var theTop = this.getScrollY();
|
||||||
var doc = this.doc;
|
var doc = this.doc;
|
||||||
var height = doc.documentElement.clientHeight; // includes padding
|
var height = doc.documentElement.clientHeight; // includes padding
|
||||||
|
@ -113,23 +108,20 @@ Scroll.prototype._getViewPortTopBottom = function()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._getEditorPositionTop = function()
|
Scroll.prototype._getEditorPositionTop = function() {
|
||||||
{
|
|
||||||
var editor = parent.document.getElementsByTagName('iframe');
|
var editor = parent.document.getElementsByTagName('iframe');
|
||||||
var editorPositionTop = editor[0].offsetTop;
|
var editorPositionTop = editor[0].offsetTop;
|
||||||
return editorPositionTop;
|
return editorPositionTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ep_page_view adds padding-top, which makes the viewport smaller
|
// ep_page_view adds padding-top, which makes the viewport smaller
|
||||||
Scroll.prototype._getPaddingTopAddedWhenPageViewIsEnable = function()
|
Scroll.prototype._getPaddingTopAddedWhenPageViewIsEnable = function() {
|
||||||
{
|
|
||||||
var aceOuter = this.rootDocument.getElementsByName("ace_outer");
|
var aceOuter = this.rootDocument.getElementsByName("ace_outer");
|
||||||
var aceOuterPaddingTop = parseInt($(aceOuter).css("padding-top"));
|
var aceOuterPaddingTop = parseInt($(aceOuter).css("padding-top"));
|
||||||
return aceOuterPaddingTop;
|
return aceOuterPaddingTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._getScrollXY = function()
|
Scroll.prototype._getScrollXY = function() {
|
||||||
{
|
|
||||||
var win = this.outerWin;
|
var win = this.outerWin;
|
||||||
var odoc = this.doc;
|
var odoc = this.doc;
|
||||||
if (typeof(win.pageYOffset) == "number")
|
if (typeof(win.pageYOffset) == "number")
|
||||||
|
@ -149,33 +141,27 @@ Scroll.prototype._getScrollXY = function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.getScrollX = function()
|
Scroll.prototype.getScrollX = function() {
|
||||||
{
|
|
||||||
return this._getScrollXY().x;
|
return this._getScrollXY().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.getScrollY = function()
|
Scroll.prototype.getScrollY = function() {
|
||||||
{
|
|
||||||
return this._getScrollXY().y;
|
return this._getScrollXY().y;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.setScrollX = function(x)
|
Scroll.prototype.setScrollX = function(x) {
|
||||||
{
|
|
||||||
this.outerWin.scrollTo(x, this.getScrollY());
|
this.outerWin.scrollTo(x, this.getScrollY());
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.setScrollY = function(y)
|
Scroll.prototype.setScrollY = function(y) {
|
||||||
{
|
|
||||||
this.outerWin.scrollTo(this.getScrollX(), y);
|
this.outerWin.scrollTo(this.getScrollX(), y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.setScrollXY = function(x, y)
|
Scroll.prototype.setScrollXY = function(x, y) {
|
||||||
{
|
|
||||||
this.outerWin.scrollTo(x, y);
|
this.outerWin.scrollTo(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._isCaretAtTheTopOfViewport = function(rep)
|
Scroll.prototype._isCaretAtTheTopOfViewport = function(rep) {
|
||||||
{
|
|
||||||
var caretLine = rep.selStart[0];
|
var caretLine = rep.selStart[0];
|
||||||
var linePrevCaretLine = caretLine - 1;
|
var linePrevCaretLine = caretLine - 1;
|
||||||
var firstLineVisibleBeforeCaretLine = caretPosition.getPreviousVisibleLine(linePrevCaretLine, rep);
|
var firstLineVisibleBeforeCaretLine = caretPosition.getPreviousVisibleLine(linePrevCaretLine, rep);
|
||||||
|
@ -201,8 +187,7 @@ Scroll.prototype._isCaretAtTheTopOfViewport = function(rep)
|
||||||
// By default, when user makes an edition in a line out of viewport, this line goes
|
// By default, when user makes an edition in a line out of viewport, this line goes
|
||||||
// to the edge of viewport. This function gets the extra pixels necessary to get the
|
// to the edge of viewport. This function gets the extra pixels necessary to get the
|
||||||
// caret line in a position X relative to Y% viewport.
|
// caret line in a position X relative to Y% viewport.
|
||||||
Scroll.prototype._getPixelsRelativeToPercentageOfViewport = function(innerHeight, aboveOfViewport)
|
Scroll.prototype._getPixelsRelativeToPercentageOfViewport = function(innerHeight, aboveOfViewport) {
|
||||||
{
|
|
||||||
var pixels = 0;
|
var pixels = 0;
|
||||||
var scrollPercentageRelativeToViewport = this._getPercentageToScroll(aboveOfViewport);
|
var scrollPercentageRelativeToViewport = this._getPercentageToScroll(aboveOfViewport);
|
||||||
if(scrollPercentageRelativeToViewport > 0 && scrollPercentageRelativeToViewport <= 1){
|
if(scrollPercentageRelativeToViewport > 0 && scrollPercentageRelativeToViewport <= 1){
|
||||||
|
@ -213,8 +198,7 @@ Scroll.prototype._getPixelsRelativeToPercentageOfViewport = function(innerHeight
|
||||||
|
|
||||||
// we use different percentages when change selection. It depends on if it is
|
// we use different percentages when change selection. It depends on if it is
|
||||||
// either above the top or below the bottom of the page
|
// either above the top or below the bottom of the page
|
||||||
Scroll.prototype._getPercentageToScroll = function(aboveOfViewport)
|
Scroll.prototype._getPercentageToScroll = function(aboveOfViewport) {
|
||||||
{
|
|
||||||
var percentageToScroll = this.scrollSettings.percentage.editionBelowViewport;
|
var percentageToScroll = this.scrollSettings.percentage.editionBelowViewport;
|
||||||
if(aboveOfViewport){
|
if(aboveOfViewport){
|
||||||
percentageToScroll = this.scrollSettings.percentage.editionAboveViewport;
|
percentageToScroll = this.scrollSettings.percentage.editionAboveViewport;
|
||||||
|
@ -222,8 +206,7 @@ Scroll.prototype._getPercentageToScroll = function(aboveOfViewport)
|
||||||
return percentageToScroll;
|
return percentageToScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight)
|
Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight) {
|
||||||
{
|
|
||||||
var pixels = 0;
|
var pixels = 0;
|
||||||
var percentageToScrollUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
|
var percentageToScrollUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
|
||||||
if(percentageToScrollUp > 0 && percentageToScrollUp <= 1){
|
if(percentageToScrollUp > 0 && percentageToScrollUp <= 1){
|
||||||
|
@ -232,8 +215,7 @@ Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight
|
||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._scrollYPage = function(pixelsToScroll)
|
Scroll.prototype._scrollYPage = function(pixelsToScroll) {
|
||||||
{
|
|
||||||
var durationOfAnimationToShowFocusline = this.scrollSettings.duration;
|
var durationOfAnimationToShowFocusline = this.scrollSettings.duration;
|
||||||
if(durationOfAnimationToShowFocusline){
|
if(durationOfAnimationToShowFocusline){
|
||||||
this._scrollYPageWithAnimation(pixelsToScroll, durationOfAnimationToShowFocusline);
|
this._scrollYPageWithAnimation(pixelsToScroll, durationOfAnimationToShowFocusline);
|
||||||
|
@ -242,13 +224,11 @@ Scroll.prototype._scrollYPage = function(pixelsToScroll)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._scrollYPageWithoutAnimation = function(pixelsToScroll)
|
Scroll.prototype._scrollYPageWithoutAnimation = function(pixelsToScroll) {
|
||||||
{
|
|
||||||
this.outerWin.scrollBy(0, pixelsToScroll);
|
this.outerWin.scrollBy(0, pixelsToScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._scrollYPageWithAnimation = function(pixelsToScroll, durationOfAnimationToShowFocusline)
|
Scroll.prototype._scrollYPageWithAnimation = function(pixelsToScroll, durationOfAnimationToShowFocusline) {
|
||||||
{
|
|
||||||
var outerDocBody = this.doc.getElementById("outerdocbody");
|
var outerDocBody = this.doc.getElementById("outerdocbody");
|
||||||
|
|
||||||
// it works on later versions of Chrome
|
// it works on later versions of Chrome
|
||||||
|
@ -262,8 +242,7 @@ Scroll.prototype._scrollYPageWithAnimation = function(pixelsToScroll, durationOf
|
||||||
|
|
||||||
// using a custom queue and clearing it, we avoid creating a queue of scroll animations. So if this function
|
// using a custom queue and clearing it, we avoid creating a queue of scroll animations. So if this function
|
||||||
// is called twice quickly, only the last one runs.
|
// is called twice quickly, only the last one runs.
|
||||||
Scroll.prototype._triggerScrollWithAnimation = function($elem, pixelsToScroll, durationOfAnimationToShowFocusline)
|
Scroll.prototype._triggerScrollWithAnimation = function($elem, pixelsToScroll, durationOfAnimationToShowFocusline) {
|
||||||
{
|
|
||||||
// clear the queue of animation
|
// clear the queue of animation
|
||||||
$elem.stop("scrollanimation");
|
$elem.stop("scrollanimation");
|
||||||
$elem.animate({
|
$elem.animate({
|
||||||
|
@ -278,8 +257,7 @@ Scroll.prototype._triggerScrollWithAnimation = function($elem, pixelsToScroll, d
|
||||||
// needed to be completely in view. If the value is greater than 0 and less than or equal to 1,
|
// needed to be completely in view. If the value is greater than 0 and less than or equal to 1,
|
||||||
// besides of scrolling the minimum needed to be visible, it scrolls additionally
|
// besides of scrolling the minimum needed to be visible, it scrolls additionally
|
||||||
// (viewport height * scrollAmountWhenFocusLineIsOutOfViewport) pixels
|
// (viewport height * scrollAmountWhenFocusLineIsOutOfViewport) pixels
|
||||||
Scroll.prototype.scrollNodeVerticallyIntoView = function(rep, innerHeight)
|
Scroll.prototype.scrollNodeVerticallyIntoView = function(rep, innerHeight) {
|
||||||
{
|
|
||||||
var viewport = this._getViewPortTopBottom();
|
var viewport = this._getViewPortTopBottom();
|
||||||
var isPartOfRepLineOutOfViewport = this._partOfRepLineIsOutOfViewport(viewport, rep);
|
var isPartOfRepLineOutOfViewport = this._partOfRepLineIsOutOfViewport(viewport, rep);
|
||||||
|
|
||||||
|
@ -304,8 +282,7 @@ Scroll.prototype.scrollNodeVerticallyIntoView = function(rep, innerHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._partOfRepLineIsOutOfViewport = function(viewportPosition, rep)
|
Scroll.prototype._partOfRepLineIsOutOfViewport = function(viewportPosition, rep) {
|
||||||
{
|
|
||||||
var focusLine = (rep.selFocusAtStart ? rep.selStart[0] : rep.selEnd[0]);
|
var focusLine = (rep.selFocusAtStart ? rep.selStart[0] : rep.selEnd[0]);
|
||||||
var line = rep.lines.atIndex(focusLine);
|
var line = rep.lines.atIndex(focusLine);
|
||||||
var linePosition = this._getLineEntryTopBottom(line);
|
var linePosition = this._getLineEntryTopBottom(line);
|
||||||
|
@ -315,8 +292,7 @@ Scroll.prototype._partOfRepLineIsOutOfViewport = function(viewportPosition, rep)
|
||||||
return lineIsBelowOfViewport || lineIsAboveOfViewport;
|
return lineIsBelowOfViewport || lineIsAboveOfViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._getLineEntryTopBottom = function(entry, destObj)
|
Scroll.prototype._getLineEntryTopBottom = function(entry, destObj) {
|
||||||
{
|
|
||||||
var dom = entry.lineNode;
|
var dom = entry.lineNode;
|
||||||
var top = dom.offsetTop;
|
var top = dom.offsetTop;
|
||||||
var height = dom.offsetHeight;
|
var height = dom.offsetHeight;
|
||||||
|
@ -326,24 +302,20 @@ Scroll.prototype._getLineEntryTopBottom = function(entry, destObj)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype._arrowUpWasPressedInTheFirstLineOfTheViewport = function(arrowUp, rep)
|
Scroll.prototype._arrowUpWasPressedInTheFirstLineOfTheViewport = function(arrowUp, rep) {
|
||||||
{
|
|
||||||
var percentageScrollArrowUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
|
var percentageScrollArrowUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
|
||||||
return percentageScrollArrowUp && arrowUp && this._isCaretAtTheTopOfViewport(rep);
|
return percentageScrollArrowUp && arrowUp && this._isCaretAtTheTopOfViewport(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.getVisibleLineRange = function(rep)
|
Scroll.prototype.getVisibleLineRange = function(rep) {
|
||||||
{
|
|
||||||
var viewport = this._getViewPortTopBottom();
|
var viewport = this._getViewPortTopBottom();
|
||||||
//console.log("viewport top/bottom: %o", viewport);
|
//console.log("viewport top/bottom: %o", viewport);
|
||||||
var obj = {};
|
var obj = {};
|
||||||
var self = this;
|
var self = this;
|
||||||
var start = rep.lines.search(function(e)
|
var start = rep.lines.search(function(e) {
|
||||||
{
|
|
||||||
return self._getLineEntryTopBottom(e, obj).bottom > viewport.top;
|
return self._getLineEntryTopBottom(e, obj).bottom > viewport.top;
|
||||||
});
|
});
|
||||||
var end = rep.lines.search(function(e)
|
var end = rep.lines.search(function(e) {
|
||||||
{
|
|
||||||
// return the first line that the top position is greater or equal than
|
// return the first line that the top position is greater or equal than
|
||||||
// the viewport. That is the first line that is below the viewport bottom.
|
// the viewport. That is the first line that is below the viewport bottom.
|
||||||
// So the line that is in the bottom of the viewport is the very previous one.
|
// So the line that is in the bottom of the viewport is the very previous one.
|
||||||
|
@ -354,13 +326,11 @@ Scroll.prototype.getVisibleLineRange = function(rep)
|
||||||
return [start, end - 1];
|
return [start, end - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Scroll.prototype.getVisibleCharRange = function(rep)
|
Scroll.prototype.getVisibleCharRange = function(rep) {
|
||||||
{
|
|
||||||
var lineRange = this.getVisibleLineRange(rep);
|
var lineRange = this.getVisibleLineRange(rep);
|
||||||
return [rep.lines.offsetOfIndex(lineRange[0]), rep.lines.offsetOfIndex(lineRange[1])];
|
return [rep.lines.offsetOfIndex(lineRange[0]), rep.lines.offsetOfIndex(lineRange[1])];
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.init = function(outerWin)
|
exports.init = function(outerWin) {
|
||||||
{
|
|
||||||
return new Scroll(outerWin);
|
return new Scroll(outerWin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,11 @@ var Ace2Common = require('./ace2_common'),
|
||||||
|
|
||||||
var noop = Ace2Common.noop;
|
var noop = Ace2Common.noop;
|
||||||
|
|
||||||
function SkipList()
|
function SkipList() {
|
||||||
{
|
|
||||||
var PROFILER = window.PROFILER;
|
var PROFILER = window.PROFILER;
|
||||||
if (!PROFILER)
|
if (!PROFILER)
|
||||||
{
|
{
|
||||||
PROFILER = function()
|
PROFILER = function() {
|
||||||
{
|
|
||||||
return {
|
return {
|
||||||
start: noop,
|
start: noop,
|
||||||
mark: noop,
|
mark: noop,
|
||||||
|
@ -71,8 +69,7 @@ function SkipList()
|
||||||
// this point.
|
// this point.
|
||||||
|
|
||||||
|
|
||||||
function _getPoint(targetLoc)
|
function _getPoint(targetLoc) {
|
||||||
{
|
|
||||||
var numLevels = start.levels;
|
var numLevels = start.levels;
|
||||||
var lvl = numLevels - 1;
|
var lvl = numLevels - 1;
|
||||||
var i = -1,
|
var i = -1,
|
||||||
|
@ -106,15 +103,13 @@ function SkipList()
|
||||||
idxs: idxs,
|
idxs: idxs,
|
||||||
loc: targetLoc,
|
loc: targetLoc,
|
||||||
widthSkips: widthSkips,
|
widthSkips: widthSkips,
|
||||||
toString: function()
|
toString: function() {
|
||||||
{
|
|
||||||
return "getPoint(" + targetLoc + ")";
|
return "getPoint(" + targetLoc + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getNodeAtOffset(targetOffset)
|
function _getNodeAtOffset(targetOffset) {
|
||||||
{
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var n = start;
|
var n = start;
|
||||||
var lvl = start.levels - 1;
|
var lvl = start.levels - 1;
|
||||||
|
@ -132,13 +127,11 @@ function SkipList()
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _entryWidth(e)
|
function _entryWidth(e) {
|
||||||
{
|
|
||||||
return (e && e.width) || 0;
|
return (e && e.width) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _insertKeyAtPoint(point, newKey, entry)
|
function _insertKeyAtPoint(point, newKey, entry) {
|
||||||
{
|
|
||||||
var p = PROFILER("insertKey", false);
|
var p = PROFILER("insertKey", false);
|
||||||
var newNode = {
|
var newNode = {
|
||||||
key: newKey,
|
key: newKey,
|
||||||
|
@ -207,13 +200,11 @@ function SkipList()
|
||||||
p.end();
|
p.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getNodeAtPoint(point)
|
function _getNodeAtPoint(point) {
|
||||||
{
|
|
||||||
return point.nodes[0].downPtrs[0];
|
return point.nodes[0].downPtrs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
function _incrementPoint(point)
|
function _incrementPoint(point) {
|
||||||
{
|
|
||||||
point.loc++;
|
point.loc++;
|
||||||
for (var i = 0; i < point.nodes.length; i++)
|
for (var i = 0; i < point.nodes.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -226,8 +217,7 @@ function SkipList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _deleteKeyAtPoint(point)
|
function _deleteKeyAtPoint(point) {
|
||||||
{
|
|
||||||
var elem = point.nodes[0].downPtrs[0];
|
var elem = point.nodes[0].downPtrs[0];
|
||||||
var elemWidth = _entryWidth(elem.entry);
|
var elemWidth = _entryWidth(elem.entry);
|
||||||
for (var i = 0; i < point.nodes.length; i++)
|
for (var i = 0; i < point.nodes.length; i++)
|
||||||
|
@ -256,8 +246,7 @@ function SkipList()
|
||||||
totalWidth -= elemWidth;
|
totalWidth -= elemWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _propagateWidthChange(node)
|
function _propagateWidthChange(node) {
|
||||||
{
|
|
||||||
var oldWidth = node.downSkipWidths[0];
|
var oldWidth = node.downSkipWidths[0];
|
||||||
var newWidth = _entryWidth(node.entry);
|
var newWidth = _entryWidth(node.entry);
|
||||||
var widthChange = newWidth - oldWidth;
|
var widthChange = newWidth - oldWidth;
|
||||||
|
@ -275,8 +264,7 @@ function SkipList()
|
||||||
totalWidth += widthChange;
|
totalWidth += widthChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getNodeIndex(node, byWidth)
|
function _getNodeIndex(node, byWidth) {
|
||||||
{
|
|
||||||
var dist = (byWidth ? 0 : -1);
|
var dist = (byWidth ? 0 : -1);
|
||||||
var n = node;
|
var n = node;
|
||||||
while (n !== start)
|
while (n !== start)
|
||||||
|
@ -289,8 +277,7 @@ function SkipList()
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getNodeByKey(key)
|
function _getNodeByKey(key) {
|
||||||
{
|
|
||||||
return keyToNodeMap['$KEY$' + key];
|
return keyToNodeMap['$KEY$' + key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,14 +286,12 @@ function SkipList()
|
||||||
// all truthy entries.
|
// all truthy entries.
|
||||||
|
|
||||||
|
|
||||||
function _search(entryFunc)
|
function _search(entryFunc) {
|
||||||
{
|
|
||||||
var low = start;
|
var low = start;
|
||||||
var lvl = start.levels - 1;
|
var lvl = start.levels - 1;
|
||||||
var lowIndex = -1;
|
var lowIndex = -1;
|
||||||
|
|
||||||
function f(node)
|
function f(node) {
|
||||||
{
|
|
||||||
if (node === start) return false;
|
if (node === start) return false;
|
||||||
else if (node === end) return true;
|
else if (node === end) return true;
|
||||||
else return entryFunc(node.entry);
|
else return entryFunc(node.entry);
|
||||||
|
@ -331,19 +316,16 @@ that is a string.
|
||||||
*/
|
*/
|
||||||
var self = this;
|
var self = this;
|
||||||
_.extend(this, {
|
_.extend(this, {
|
||||||
length: function()
|
length: function() {
|
||||||
{
|
|
||||||
return numNodes;
|
return numNodes;
|
||||||
},
|
},
|
||||||
atIndex: function(i)
|
atIndex: function(i) {
|
||||||
{
|
|
||||||
if (i < 0) console.warn("atIndex(" + i + ")");
|
if (i < 0) console.warn("atIndex(" + i + ")");
|
||||||
if (i >= numNodes) console.warn("atIndex(" + i + ">=" + numNodes + ")");
|
if (i >= numNodes) console.warn("atIndex(" + i + ">=" + numNodes + ")");
|
||||||
return _getNodeAtPoint(_getPoint(i)).entry;
|
return _getNodeAtPoint(_getPoint(i)).entry;
|
||||||
},
|
},
|
||||||
// differs from Array.splice() in that new elements are in an array, not varargs
|
// differs from Array.splice() in that new elements are in an array, not varargs
|
||||||
splice: function(start, deleteCount, newEntryArray)
|
splice: function(start, deleteCount, newEntryArray) {
|
||||||
{
|
|
||||||
if (start < 0) console.warn("splice(" + start + ", ...)");
|
if (start < 0) console.warn("splice(" + start + ", ...)");
|
||||||
if (start + deleteCount > numNodes)
|
if (start + deleteCount > numNodes)
|
||||||
{
|
{
|
||||||
|
@ -366,20 +348,16 @@ that is a string.
|
||||||
node.entry = entry;
|
node.entry = entry;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
next: function(entry)
|
next: function(entry) {
|
||||||
{
|
|
||||||
return _getNodeByKey(entry.key).downPtrs[0].entry || null;
|
return _getNodeByKey(entry.key).downPtrs[0].entry || null;
|
||||||
},
|
},
|
||||||
prev: function(entry)
|
prev: function(entry) {
|
||||||
{
|
|
||||||
return _getNodeByKey(entry.key).upPtrs[0].entry || null;
|
return _getNodeByKey(entry.key).upPtrs[0].entry || null;
|
||||||
},
|
},
|
||||||
push: function(entry)
|
push: function(entry) {
|
||||||
{
|
|
||||||
self.splice(numNodes, 0, [entry]);
|
self.splice(numNodes, 0, [entry]);
|
||||||
},
|
},
|
||||||
slice: function(start, end)
|
slice: function(start, end) {
|
||||||
{
|
|
||||||
// act like Array.slice()
|
// act like Array.slice()
|
||||||
if (start === undefined) start = 0;
|
if (start === undefined) start = 0;
|
||||||
else if (start < 0) start += numNodes;
|
else if (start < 0) start += numNodes;
|
||||||
|
@ -402,68 +380,54 @@ that is a string.
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
},
|
},
|
||||||
atKey: function(key)
|
atKey: function(key) {
|
||||||
{
|
|
||||||
return _getNodeByKey(key).entry;
|
return _getNodeByKey(key).entry;
|
||||||
},
|
},
|
||||||
indexOfKey: function(key)
|
indexOfKey: function(key) {
|
||||||
{
|
|
||||||
return _getNodeIndex(_getNodeByKey(key));
|
return _getNodeIndex(_getNodeByKey(key));
|
||||||
},
|
},
|
||||||
indexOfEntry: function(entry)
|
indexOfEntry: function(entry) {
|
||||||
{
|
|
||||||
return self.indexOfKey(entry.key);
|
return self.indexOfKey(entry.key);
|
||||||
},
|
},
|
||||||
containsKey: function(key)
|
containsKey: function(key) {
|
||||||
{
|
|
||||||
return !!(_getNodeByKey(key));
|
return !!(_getNodeByKey(key));
|
||||||
},
|
},
|
||||||
// gets the last entry starting at or before the offset
|
// gets the last entry starting at or before the offset
|
||||||
atOffset: function(offset)
|
atOffset: function(offset) {
|
||||||
{
|
|
||||||
return _getNodeAtOffset(offset).entry;
|
return _getNodeAtOffset(offset).entry;
|
||||||
},
|
},
|
||||||
keyAtOffset: function(offset)
|
keyAtOffset: function(offset) {
|
||||||
{
|
|
||||||
return self.atOffset(offset).key;
|
return self.atOffset(offset).key;
|
||||||
},
|
},
|
||||||
offsetOfKey: function(key)
|
offsetOfKey: function(key) {
|
||||||
{
|
|
||||||
return _getNodeIndex(_getNodeByKey(key), true);
|
return _getNodeIndex(_getNodeByKey(key), true);
|
||||||
},
|
},
|
||||||
offsetOfEntry: function(entry)
|
offsetOfEntry: function(entry) {
|
||||||
{
|
|
||||||
return self.offsetOfKey(entry.key);
|
return self.offsetOfKey(entry.key);
|
||||||
},
|
},
|
||||||
setEntryWidth: function(entry, width)
|
setEntryWidth: function(entry, width) {
|
||||||
{
|
|
||||||
entry.width = width;
|
entry.width = width;
|
||||||
_propagateWidthChange(_getNodeByKey(entry.key));
|
_propagateWidthChange(_getNodeByKey(entry.key));
|
||||||
},
|
},
|
||||||
totalWidth: function()
|
totalWidth: function() {
|
||||||
{
|
|
||||||
return totalWidth;
|
return totalWidth;
|
||||||
},
|
},
|
||||||
offsetOfIndex: function(i)
|
offsetOfIndex: function(i) {
|
||||||
{
|
|
||||||
if (i < 0) return 0;
|
if (i < 0) return 0;
|
||||||
if (i >= numNodes) return totalWidth;
|
if (i >= numNodes) return totalWidth;
|
||||||
return self.offsetOfEntry(self.atIndex(i));
|
return self.offsetOfEntry(self.atIndex(i));
|
||||||
},
|
},
|
||||||
indexOfOffset: function(offset)
|
indexOfOffset: function(offset) {
|
||||||
{
|
|
||||||
if (offset <= 0) return 0;
|
if (offset <= 0) return 0;
|
||||||
if (offset >= totalWidth) return numNodes;
|
if (offset >= totalWidth) return numNodes;
|
||||||
return self.indexOfEntry(self.atOffset(offset));
|
return self.indexOfEntry(self.atOffset(offset));
|
||||||
},
|
},
|
||||||
search: function(entryFunc)
|
search: function(entryFunc) {
|
||||||
{
|
|
||||||
return _search(entryFunc);
|
return _search(entryFunc);
|
||||||
},
|
},
|
||||||
//debugToString: _debugToString,
|
//debugToString: _debugToString,
|
||||||
debugGetPoint: _getPoint,
|
debugGetPoint: _getPoint,
|
||||||
debugDepth: function()
|
debugDepth: function() {
|
||||||
{
|
|
||||||
return start.levels;
|
return start.levels;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,8 +31,7 @@ var hooks = require('./pluginfw/hooks');
|
||||||
var token, padId, export_links;
|
var token, padId, export_links;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
$(document).ready(function ()
|
$(document).ready(function () {
|
||||||
{
|
|
||||||
// start the custom js
|
// start the custom js
|
||||||
if (typeof customStart == "function") customStart();
|
if (typeof customStart == "function") customStart();
|
||||||
|
|
||||||
|
@ -63,19 +62,16 @@ function init() {
|
||||||
socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
|
socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
|
||||||
|
|
||||||
//send the ready message once we're connected
|
//send the ready message once we're connected
|
||||||
socket.on('connect', function()
|
socket.on('connect', function() {
|
||||||
{
|
|
||||||
sendSocketMsg("CLIENT_READY", {});
|
sendSocketMsg("CLIENT_READY", {});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('disconnect', function()
|
socket.on('disconnect', function() {
|
||||||
{
|
|
||||||
BroadcastSlider.showReconnectUI();
|
BroadcastSlider.showReconnectUI();
|
||||||
});
|
});
|
||||||
|
|
||||||
//route the incoming messages
|
//route the incoming messages
|
||||||
socket.on('message', function(message)
|
socket.on('message', function(message) {
|
||||||
{
|
|
||||||
if(message.type == "CLIENT_VARS")
|
if(message.type == "CLIENT_VARS")
|
||||||
{
|
{
|
||||||
handleClientVars(message);
|
handleClientVars(message);
|
||||||
|
@ -91,8 +87,7 @@ function init() {
|
||||||
//get all the export links
|
//get all the export links
|
||||||
export_links = $('#export > .exportlink')
|
export_links = $('#export > .exportlink')
|
||||||
|
|
||||||
$('button#forcereconnect').click(function()
|
$('button#forcereconnect').click(function() {
|
||||||
{
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -104,8 +99,7 @@ function init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//sends a message over the socket
|
//sends a message over the socket
|
||||||
function sendSocketMsg(type, data)
|
function sendSocketMsg(type, data) {
|
||||||
{
|
|
||||||
socket.json.send({
|
socket.json.send({
|
||||||
component: 'pad', // FIXME: Remove this stupidity!
|
component: 'pad', // FIXME: Remove this stupidity!
|
||||||
type,
|
type,
|
||||||
|
@ -120,8 +114,7 @@ function sendSocketMsg(type, data)
|
||||||
var fireWhenAllScriptsAreLoaded = [];
|
var fireWhenAllScriptsAreLoaded = [];
|
||||||
|
|
||||||
var changesetLoader;
|
var changesetLoader;
|
||||||
function handleClientVars(message)
|
function handleClientVars(message) {
|
||||||
{
|
|
||||||
//save the client Vars
|
//save the client Vars
|
||||||
clientVars = message.data;
|
clientVars = message.data;
|
||||||
|
|
||||||
|
@ -137,11 +130,9 @@ function handleClientVars(message)
|
||||||
var baseURI = document.location.pathname;
|
var baseURI = document.location.pathname;
|
||||||
|
|
||||||
//change export urls when the slider moves
|
//change export urls when the slider moves
|
||||||
BroadcastSlider.onSlider(function(revno)
|
BroadcastSlider.onSlider(function(revno) {
|
||||||
{
|
|
||||||
// export_links is a jQuery Array, so .each is allowed.
|
// export_links is a jQuery Array, so .each is allowed.
|
||||||
export_links.each(function()
|
export_links.each(function() {
|
||||||
{
|
|
||||||
// Modified from regular expression to fix:
|
// Modified from regular expression to fix:
|
||||||
// https://github.com/ether/etherpad-lite/issues/4071
|
// https://github.com/ether/etherpad-lite/issues/4071
|
||||||
// Where a padId that was numeric would create the wrong export link
|
// Where a padId that was numeric would create the wrong export link
|
||||||
|
|
|
@ -23,10 +23,8 @@
|
||||||
var Changeset = require('./Changeset');
|
var Changeset = require('./Changeset');
|
||||||
var _ = require('./underscore');
|
var _ = require('./underscore');
|
||||||
|
|
||||||
var undoModule = (function()
|
var undoModule = (function() {
|
||||||
{
|
var stack = (function() {
|
||||||
var stack = (function()
|
|
||||||
{
|
|
||||||
var stackElements = [];
|
var stackElements = [];
|
||||||
// two types of stackElements:
|
// two types of stackElements:
|
||||||
// 1) { elementType: UNDOABLE_EVENT, eventType: "anything", [backset: <changeset>,]
|
// 1) { elementType: UNDOABLE_EVENT, eventType: "anything", [backset: <changeset>,]
|
||||||
|
@ -38,8 +36,7 @@ var undoModule = (function()
|
||||||
var UNDOABLE_EVENT = "undoableEvent";
|
var UNDOABLE_EVENT = "undoableEvent";
|
||||||
var EXTERNAL_CHANGE = "externalChange";
|
var EXTERNAL_CHANGE = "externalChange";
|
||||||
|
|
||||||
function clearStack()
|
function clearStack() {
|
||||||
{
|
|
||||||
stackElements.length = 0;
|
stackElements.length = 0;
|
||||||
stackElements.push(
|
stackElements.push(
|
||||||
{
|
{
|
||||||
|
@ -50,8 +47,7 @@ var undoModule = (function()
|
||||||
}
|
}
|
||||||
clearStack();
|
clearStack();
|
||||||
|
|
||||||
function pushEvent(event)
|
function pushEvent(event) {
|
||||||
{
|
|
||||||
var e = _.extend(
|
var e = _.extend(
|
||||||
{}, event);
|
{}, event);
|
||||||
e.elementType = UNDOABLE_EVENT;
|
e.elementType = UNDOABLE_EVENT;
|
||||||
|
@ -60,8 +56,7 @@ var undoModule = (function()
|
||||||
//dmesg("pushEvent backset: "+event.backset);
|
//dmesg("pushEvent backset: "+event.backset);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushExternalChange(cs)
|
function pushExternalChange(cs) {
|
||||||
{
|
|
||||||
var idx = stackElements.length - 1;
|
var idx = stackElements.length - 1;
|
||||||
if (stackElements[idx].elementType == EXTERNAL_CHANGE)
|
if (stackElements[idx].elementType == EXTERNAL_CHANGE)
|
||||||
{
|
{
|
||||||
|
@ -77,8 +72,7 @@ var undoModule = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _exposeEvent(nthFromTop)
|
function _exposeEvent(nthFromTop) {
|
||||||
{
|
|
||||||
// precond: 0 <= nthFromTop < numUndoableEvents
|
// precond: 0 <= nthFromTop < numUndoableEvents
|
||||||
var targetIndex = stackElements.length - 1 - nthFromTop;
|
var targetIndex = stackElements.length - 1 - nthFromTop;
|
||||||
var idx = stackElements.length - 1;
|
var idx = stackElements.length - 1;
|
||||||
|
@ -121,20 +115,17 @@ var undoModule = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNthFromTop(n)
|
function getNthFromTop(n) {
|
||||||
{
|
|
||||||
// precond: 0 <= n < numEvents()
|
// precond: 0 <= n < numEvents()
|
||||||
_exposeEvent(n);
|
_exposeEvent(n);
|
||||||
return stackElements[stackElements.length - 1 - n];
|
return stackElements[stackElements.length - 1 - n];
|
||||||
}
|
}
|
||||||
|
|
||||||
function numEvents()
|
function numEvents() {
|
||||||
{
|
|
||||||
return numUndoableEvents;
|
return numUndoableEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
function popEvent()
|
function popEvent() {
|
||||||
{
|
|
||||||
// precond: numEvents() > 0
|
// precond: numEvents() > 0
|
||||||
_exposeEvent(0);
|
_exposeEvent(0);
|
||||||
numUndoableEvents--;
|
numUndoableEvents--;
|
||||||
|
@ -154,14 +145,12 @@ var undoModule = (function()
|
||||||
// invariant: stack always has at least one undoable event
|
// invariant: stack always has at least one undoable event
|
||||||
var undoPtr = 0; // zero-index from top of stack, 0 == top
|
var undoPtr = 0; // zero-index from top of stack, 0 == top
|
||||||
|
|
||||||
function clearHistory()
|
function clearHistory() {
|
||||||
{
|
|
||||||
stack.clearStack();
|
stack.clearStack();
|
||||||
undoPtr = 0;
|
undoPtr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _charOccurrences(str, c)
|
function _charOccurrences(str, c) {
|
||||||
{
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
while (i >= 0 && i < str.length)
|
while (i >= 0 && i < str.length)
|
||||||
|
@ -176,13 +165,11 @@ var undoModule = (function()
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _opcodeOccurrences(cs, opcode)
|
function _opcodeOccurrences(cs, opcode) {
|
||||||
{
|
|
||||||
return _charOccurrences(Changeset.unpack(cs).ops, opcode);
|
return _charOccurrences(Changeset.unpack(cs).ops, opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _mergeChangesets(cs1, cs2)
|
function _mergeChangesets(cs1, cs2) {
|
||||||
{
|
|
||||||
if (!cs1) return cs2;
|
if (!cs1) return cs2;
|
||||||
if (!cs2) return cs1;
|
if (!cs2) return cs1;
|
||||||
|
|
||||||
|
@ -219,12 +206,10 @@ var undoModule = (function()
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportEvent(event)
|
function reportEvent(event) {
|
||||||
{
|
|
||||||
var topEvent = stack.getNthFromTop(0);
|
var topEvent = stack.getNthFromTop(0);
|
||||||
|
|
||||||
function applySelectionToTop()
|
function applySelectionToTop() {
|
||||||
{
|
|
||||||
if ((typeof event.selStart) == "number")
|
if ((typeof event.selStart) == "number")
|
||||||
{
|
{
|
||||||
topEvent.selStart = event.selStart;
|
topEvent.selStart = event.selStart;
|
||||||
|
@ -268,16 +253,14 @@ var undoModule = (function()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportExternalChange(changeset)
|
function reportExternalChange(changeset) {
|
||||||
{
|
|
||||||
if (changeset && !Changeset.isIdentity(changeset))
|
if (changeset && !Changeset.isIdentity(changeset))
|
||||||
{
|
{
|
||||||
stack.pushExternalChange(changeset);
|
stack.pushExternalChange(changeset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getSelectionInfo(event)
|
function _getSelectionInfo(event) {
|
||||||
{
|
|
||||||
if ((typeof event.selStart) != "number")
|
if ((typeof event.selStart) != "number")
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -298,8 +281,7 @@ var undoModule = (function()
|
||||||
// or can be called with no arguments to mean that no undo is possible.
|
// or can be called with no arguments to mean that no undo is possible.
|
||||||
// "eventFunc" will be called exactly once.
|
// "eventFunc" will be called exactly once.
|
||||||
|
|
||||||
function performUndo(eventFunc)
|
function performUndo(eventFunc) {
|
||||||
{
|
|
||||||
if (undoPtr < stack.numEvents() - 1)
|
if (undoPtr < stack.numEvents() - 1)
|
||||||
{
|
{
|
||||||
var backsetEvent = stack.getNthFromTop(undoPtr);
|
var backsetEvent = stack.getNthFromTop(undoPtr);
|
||||||
|
@ -311,8 +293,7 @@ var undoModule = (function()
|
||||||
else eventFunc();
|
else eventFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
function performRedo(eventFunc)
|
function performRedo(eventFunc) {
|
||||||
{
|
|
||||||
if (undoPtr >= 2)
|
if (undoPtr >= 2)
|
||||||
{
|
{
|
||||||
var backsetEvent = stack.getNthFromTop(0);
|
var backsetEvent = stack.getNthFromTop(0);
|
||||||
|
@ -324,8 +305,7 @@ var undoModule = (function()
|
||||||
else eventFunc();
|
else eventFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAPool()
|
function getAPool() {
|
||||||
{
|
|
||||||
return undoModule.apool;
|
return undoModule.apool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
function customStart()
|
function customStart() {
|
||||||
{
|
|
||||||
//define your javascript here
|
//define your javascript here
|
||||||
//jquery is available - except index.js
|
//jquery is available - except index.js
|
||||||
//you can load extra scripts with $.getScript http://api.jquery.com/jQuery.getScript/
|
//you can load extra scripts with $.getScript http://api.jquery.com/jQuery.getScript/
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
function customStart()
|
function customStart() {
|
||||||
{
|
|
||||||
$('#pad_title').show();
|
$('#pad_title').show();
|
||||||
$('.buttonicon').mousedown(function() { $(this).parent().addClass('pressed'); })
|
$('.buttonicon').mousedown(function() { $(this).parent().addClass('pressed'); })
|
||||||
$('.buttonicon').mouseup(function() { $(this).parent().removeClass('pressed'); })
|
$('.buttonicon').mouseup(function() { $(this).parent().removeClass('pressed'); })
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
function customStart()
|
function customStart() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,7 @@ function runTest(number){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -98,8 +98,7 @@ var endPoint = function(point, version){
|
||||||
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,7 @@ var endPoint = function(point){
|
||||||
return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
|
return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,7 @@ console.log("here");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,7 @@ var endPoint = function(point, version){
|
||||||
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -361,8 +361,7 @@ var endPoint = function(point, version){
|
||||||
return `/api/${version}/${point}?apikey=${apiKey}`;
|
return `/api/${version}/${point}?apikey=${apiKey}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -804,8 +804,7 @@ var endPoint = function(point, version){
|
||||||
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
return '/api/'+version+'/'+point+'?apikey='+apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
var text = "";
|
var text = "";
|
||||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
|
|
@ -289,8 +289,7 @@ const endPoint = function(point) {
|
||||||
return `/api/${apiVersion}/${point}?apikey=${apiKey}`;
|
return `/api/${apiVersion}/${point}?apikey=${apiKey}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeid()
|
function makeid() {
|
||||||
{
|
|
||||||
let text = '';
|
let text = '';
|
||||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@ var helper = {};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
helper.randomString = function randomString(len)
|
helper.randomString = function randomString(len) {
|
||||||
{
|
|
||||||
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
var randomstring = '';
|
var randomstring = '';
|
||||||
for (var i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
describe("embed links", function(){
|
describe("embed links", function(){
|
||||||
var objectify = function (str)
|
var objectify = function (str) {
|
||||||
{
|
|
||||||
var hash = {};
|
var hash = {};
|
||||||
var parts = str.split('&');
|
var parts = str.split('&');
|
||||||
for(var i = 0; i < parts.length; i++)
|
for(var i = 0; i < parts.length; i++)
|
||||||
|
|
Loading…
Reference in a new issue