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:
Richard Hansen 2020-11-21 13:37:57 -05:00 committed by John McLear
parent cc988bd67b
commit 7df3ded66f
66 changed files with 1036 additions and 2072 deletions

View file

@ -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

View file

@ -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(",");

View file

@ -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);
} }

View file

@ -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");

View file

@ -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;

View file

@ -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

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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;

View file

@ -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);
} }

View file

@ -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');

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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)
{ {

View file

@ -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});
}; };
} }

View file

@ -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;

View file

@ -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);
} }

View file

@ -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) {

View file

@ -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

View file

@ -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);

View file

@ -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 {

View file

@ -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')
}; };

View file

@ -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);
} }

View file

@ -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]);

View file

@ -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 = [];

View file

@ -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

View file

@ -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];

View file

@ -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 = [];

View file

@ -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");
}) })

View file

@ -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;

View file

@ -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)));
} }
}; };

View file

@ -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;

View file

@ -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),

View file

@ -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';

View file

@ -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) == "&nbsp;" && !getAssoc(node, "unpasted")) if (dom.nodeNumChildren(node) == 1 && getAssoc(node, "shouldBeEmpty") && dom.optNodeInnerHTML(node) == "&nbsp;" && !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];

View file

@ -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;
} }
}; };

View file

@ -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, '&nbsp;'); return s.replace(/ /g, '&nbsp;');
} }
var parts = []; var parts = [];
s.replace(/<[^>]*>?| |[^ <]+/g, function(m) s.replace(/<[^>]*>?| |[^ <]+/g, function(m) {
{
parts.push(m); parts.push(m);
}); });
if (doesWrap) if (doesWrap)

View file

@ -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);
} }

View file

@ -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();
} }
}; };

View file

@ -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;
} }
}; };

View file

@ -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');

View file

@ -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);
} }

View file

@ -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);

View file

@ -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');

View file

@ -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) + '">&nbsp;</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) + '">&nbsp;</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");

View file

@ -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')
{ {

View file

@ -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);
} }

View file

@ -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;
} }
}); });

View file

@ -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

View file

@ -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;
} }

View file

@ -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/

View file

@ -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'); })

View file

@ -1,3 +1,2 @@
function customStart() function customStart() {
{
} }

View file

@ -58,8 +58,7 @@ function runTest(number){
}); });
} }
function makeid() function makeid() {
{
var text = ""; var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View file

@ -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";

View file

@ -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";

View file

@ -58,8 +58,7 @@ console.log("here");
}); });
} }
function makeid() function makeid() {
{
var text = ""; var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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';

View file

@ -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++)

View file

@ -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++)