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")
//run trough all revisions
async.forEachSeries(revisions, function(revNum, callback)
{
async.forEachSeries(revisions, function(revNum, callback) {
//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);
//check if there is a atext in the keyRevisions

View File

@ -49,25 +49,20 @@ var padIDs;
async.series([
//get all padids out of the database...
function(callback)
{
function(callback) {
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;
callback(err);
});
},
function(callback)
{
function(callback) {
log("done");
//create a queue with a concurrency 100
var queue = async.queue(function (padId, callback)
{
convertPad(padId, function(err)
{
var queue = async.queue(function (padId, callback) {
convertPad(padId, function(err) {
incrementPadStats();
callback(err);
});
@ -82,8 +77,7 @@ async.series([
queue.push(padIDs[i].ID);
}
}
], function(err)
{
], function(err) {
if(err) throw err;
//write the groups
@ -108,15 +102,13 @@ async.series([
process.exit(0);
});
function log(str)
{
function log(str) {
console.log((Date.now() - startTime)/1000 + "\t" + str);
}
var padsDone = 0;
function incrementPadStats()
{
function incrementPadStats() {
padsDone++;
if(padsDone%100 == 0)
@ -130,8 +122,7 @@ var proID2groupID = {};
var proID2subdomain = {};
var groups = {};
function convertPad(padId, callback)
{
function convertPad(padId, callback) {
var changesets = [];
var changesetsMeta = [];
var chatMessages = [];
@ -142,16 +133,13 @@ function convertPad(padId, callback)
async.series([
//get all needed db values
function(callback)
{
function(callback) {
async.parallel([
//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=?)";
etherpadDB.query(sql, [padId], function(err, results)
{
etherpadDB.query(sql, [padId], function(err, results) {
if(!err)
{
try
@ -168,12 +156,10 @@ function convertPad(padId, callback)
});
},
//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=?)";
etherpadDB.query(sql, [padId], function(err, results)
{
etherpadDB.query(sql, [padId], function(err, results) {
if(!err)
{
try
@ -190,12 +176,10 @@ function convertPad(padId, callback)
});
},
//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=?)";
etherpadDB.query(sql, [padId], function(err, results)
{
etherpadDB.query(sql, [padId], function(err, results) {
if(!err)
{
try
@ -212,12 +196,10 @@ function convertPad(padId, callback)
});
},
//get the attribute pool of this pad
function(callback)
{
function(callback) {
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)
{
try
@ -230,12 +212,10 @@ function convertPad(padId, callback)
});
},
//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=?)";
etherpadDB.query(sql, [padId], function(err, results)
{
etherpadDB.query(sql, [padId], function(err, results) {
if(!err)
{
try
@ -252,12 +232,10 @@ function convertPad(padId, callback)
});
},
//get the pad information
function(callback)
{
function(callback) {
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)
{
try
@ -270,8 +248,7 @@ function convertPad(padId, callback)
});
},
//get the subdomain
function(callback)
{
function(callback) {
//skip if this is no proPad
if(padId.indexOf("$") == -1)
{
@ -284,8 +261,7 @@ function convertPad(padId, callback)
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)
{
subdomain = results[0].subDomain;
@ -296,8 +272,7 @@ function convertPad(padId, callback)
}
], callback);
},
function(callback)
{
function(callback) {
//saves all values that should be written to the database
var values = {};
@ -425,8 +400,7 @@ function convertPad(padId, callback)
* The offsets describes the length of a unit in the page, the data are
* all values behind each other
*/
function parsePage(array, pageStart, offsets, data, json)
{
function parsePage(array, pageStart, offsets, data, json) {
var start = 0;
var lengths = offsets.split(",");

View File

@ -25,8 +25,7 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
}
log("initializing db");
db.init(function(err)
{
db.init(function(err) {
//there was an error while initializing the database, output it and stop
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);
}

View File

@ -101,8 +101,7 @@ Example returns:
}
*/
exports.getAttributePool = async function(padID)
{
exports.getAttributePool = async function(padID) {
let pad = await getPadSafe(padID, true);
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
if (rev !== undefined) {
rev = checkValidRev(rev);
@ -155,8 +153,7 @@ Example returns:
{code: 0, message:"ok", data: {text:"Welcome Text"}}
{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
if (rev !== undefined) {
rev = checkValidRev(rev);
@ -193,8 +190,7 @@ Example returns:
{code: 1, message:"padID does not exist", 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
if (typeof text !== "string") {
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:"text too long", data: null}
*/
exports.appendText = async function(padID, text)
{
exports.appendText = async function(padID, text) {
// text is required
if (typeof text !== "string") {
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: 1, message:"padID does not exist", data: null}
*/
exports.getHTML = async function(padID, rev)
{
exports.getHTML = async function(padID, rev) {
if (rev !== undefined) {
rev = checkValidRev(rev);
}
@ -273,8 +267,7 @@ Example returns:
{code: 0, message:"ok", 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
if (typeof html !== "string") {
throw new customError("html is not a string", "apierror");
@ -310,8 +303,7 @@ Example returns:
{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 < 0) {
throw new customError("start is below zero", "apierror");
@ -356,8 +348,7 @@ Example returns:
{code: 0, message:"ok", 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
if (typeof text !== "string") {
throw new customError("text is not a string", "apierror");
@ -386,8 +377,7 @@ Example returns:
{code: 0, message:"ok", data: {revisions: 56}}
{code: 1, message:"padID does not exist", data: null}
*/
exports.getRevisionsCount = async function(padID)
{
exports.getRevisionsCount = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
return { revisions: pad.getHeadRevisionNumber() };
@ -401,8 +391,7 @@ Example returns:
{code: 0, message:"ok", data: {savedRevisions: 42}}
{code: 1, message:"padID does not exist", data: null}
*/
exports.getSavedRevisionsCount = async function(padID)
{
exports.getSavedRevisionsCount = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
return { savedRevisions: pad.getSavedRevisionsNumber() };
@ -416,8 +405,7 @@ Example returns:
{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}}
{code: 1, message:"padID does not exist", data: null}
*/
exports.listSavedRevisions = async function(padID)
{
exports.listSavedRevisions = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
return { savedRevisions: pad.getSavedRevisionsList() };
@ -431,8 +419,7 @@ Example returns:
{code: 0, message:"ok", 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
if (rev !== undefined) {
rev = checkValidRev(rev);
@ -463,8 +450,7 @@ Example returns:
{code: 0, message:"ok", data: {lastEdited: 1340815946602}}
{code: 1, message:"padID does not exist", data: null}
*/
exports.getLastEdited = async function(padID)
{
exports.getLastEdited = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
let lastEdited = await pad.getLastEdit();
@ -479,8 +465,7 @@ Example returns:
{code: 0, message:"ok", 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) {
// ensure there is no $ in the padID
if (padID.indexOf("$") !== -1) {
@ -505,8 +490,7 @@ Example returns:
{code: 0, message:"ok", 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);
await pad.remove();
}
@ -519,8 +503,7 @@ exports.deletePad = async function(padID)
{code:0, message:"ok", 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
if (rev === undefined) {
throw new customError("rev is not defined", "apierror");
@ -588,8 +571,7 @@ Example returns:
{code: 0, message:"ok", data: {padID: destinationID}}
{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);
await pad.copy(destinationID, force);
}
@ -603,8 +585,7 @@ Example returns:
{code: 0, message:"ok", data: {padID: destinationID}}
{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);
await pad.copyPadWithoutHistory(destinationID, force);
}
@ -618,8 +599,7 @@ Example returns:
{code: 0, message:"ok", data: {padID: destinationID}}
{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);
await pad.copy(destinationID, force);
await pad.remove();
@ -633,8 +613,7 @@ Example returns:
{code: 0, message:"ok", 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
await getPadSafe(padID, true);
@ -652,8 +631,7 @@ Example returns:
{code: 0, message:"ok", data: {padID: padID}}
{code: 1, message:"padID does not exist", data: null}
*/
exports.getPadID = async function(roID)
{
exports.getPadID = async function(roID) {
// get the PadId
let padID = await readOnlyManager.getPadId(roID);
if (padID === null) {
@ -671,8 +649,7 @@ Example returns:
{code: 0, message:"ok", 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
checkGroupPad(padID, "publicStatus");
@ -695,8 +672,7 @@ Example returns:
{code: 0, message:"ok", data: {publicStatus: true}}
{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
checkGroupPad(padID, "publicStatus");
@ -713,8 +689,7 @@ Example returns:
{code: 0, message:"ok", data: {authorIDs : ["a.s8oes9dhwrvt0zif", "a.akf8finncvomlqva"]}
{code: 1, message:"padID does not exist", data: null}
*/
exports.listAuthorsOfPad = async function(padID)
{
exports.listAuthorsOfPad = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
let authorIDs = pad.getAllAuthors();
@ -757,8 +732,7 @@ Example returns:
{"code":0,"message":"ok","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: 1, message:"padID does not exist", data: null}
*/
exports.getChatHead = async function(padID)
{
exports.getChatHead = async function(padID) {
// get the pad
let pad = await getPadSafe(padID, true);
return { chatHead: pad.chatHead };
@ -843,14 +816,12 @@ exports.getStats = async function() {
/******************************/
// checks if a number is an int
function is_int(value)
{
function is_int(value) {
return (parseFloat(value) == parseInt(value, 10)) && !isNaN(value)
}
// gets a pad safe
async function getPadSafe(padID, shouldExist, text)
{
async function getPadSafe(padID, shouldExist, text) {
// check if padID is a string
if (typeof padID !== "string") {
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
// pre-condition is that `rev` is not undefined
function checkValidRev(rev)
{
function checkValidRev(rev) {
if (typeof rev !== "number") {
rev = parseInt(rev, 10);
}
@ -905,8 +875,7 @@ function checkValidRev(rev)
}
// checks if a padID is part of a group
function checkGroupPad(padID, field)
{
function checkGroupPad(padID, field) {
// ensure this is a group pad
if (padID && padID.indexOf("$") === -1) {
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
*/
exports.doesAuthorExist = async function(authorID)
{
exports.doesAuthorExist = async function(authorID) {
let author = await db.get("globalAuthor:" + authorID);
return author !== null;
@ -52,8 +51,7 @@ exports.doesAuthorExists = exports.doesAuthorExist;
* Returns the AuthorID for a token.
* @param {String} token The token
*/
exports.getAuthor4Token = async function(token)
{
exports.getAuthor4Token = async function(token) {
let author = await mapAuthorWithDBKey("token2author", token);
// return only the sub value authorID
@ -65,8 +63,7 @@ exports.getAuthor4Token = async function(token)
* @param {String} token The mapper
* @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);
if (name) {
@ -83,8 +80,7 @@ exports.createAuthorIfNotExistsFor = async function(authorMapper, name)
* @param {String} mapperkey The database key name for this mapper
* @param {String} mapper The mapper
*/
async function mapAuthorWithDBKey (mapperkey, mapper)
{
async function mapAuthorWithDBKey (mapperkey, mapper) {
// try to map to an author
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
* @param {String} name The name of the author
*/
exports.createAuthor = function(name)
{
exports.createAuthor = function(name) {
// create the new author name
let author = "a." + randomString(16);
@ -134,8 +129,7 @@ exports.createAuthor = function(name)
* Returns the Author Obj 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
return db.get("globalAuthor:" + author);
}
@ -144,8 +138,7 @@ exports.getAuthor = function(author)
* Returns the color 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"]);
}
@ -154,8 +147,7 @@ exports.getAuthorColorId = function(author)
* @param {String} author The 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);
}
@ -163,8 +155,7 @@ exports.setAuthorColorId = function(author, colorId)
* Returns the name 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"]);
}
@ -173,8 +164,7 @@ exports.getAuthorName = function(author)
* @param {String} author The id 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);
}
@ -182,8 +172,7 @@ exports.setAuthorName = function(author, name)
* Returns an array of all pads this author contributed to
* @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:
* (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
@ -208,8 +197,7 @@ exports.listPadsOfAuthor = async function(authorID)
* @param {String} author The id of the author
* @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
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} 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);
if (author === null) return;

View File

@ -24,8 +24,7 @@ var db = require("./DB");
var padManager = require("./PadManager");
var sessionManager = require("./SessionManager");
exports.listAllGroups = async function()
{
exports.listAllGroups = async function() {
let groups = await db.get("groups");
groups = groups || {};
@ -33,8 +32,7 @@ exports.listAllGroups = async function()
return { groupIDs };
}
exports.deleteGroup = async function(groupID)
{
exports.deleteGroup = async function(groupID) {
let group = await db.get("group:" + groupID);
// ensure group exists
@ -82,16 +80,14 @@ exports.deleteGroup = async function(groupID)
await db.set("groups", newGroups);
}
exports.doesGroupExist = async function(groupID)
{
exports.doesGroupExist = async function(groupID) {
// try to get the group entry
let group = await db.get("group:" + groupID);
return (group != null);
}
exports.createGroup = async function()
{
exports.createGroup = async function() {
// search for non existing groupID
var groupID = "g." + randomString(16);
@ -111,8 +107,7 @@ exports.createGroup = async function()
return { groupID };
}
exports.createGroupIfNotExistsFor = async function(groupMapper)
{
exports.createGroupIfNotExistsFor = async function(groupMapper) {
// ensure mapper is optional
if (typeof groupMapper !== "string") {
throw new customError("groupMapper is not a string", "apierror");
@ -137,8 +132,7 @@ exports.createGroupIfNotExistsFor = async function(groupMapper)
return result;
}
exports.createGroupPad = async function(groupID, padName, text)
{
exports.createGroupPad = async function(groupID, padName, text) {
// create the padID
let padID = groupID + "$" + padName;
@ -166,8 +160,7 @@ exports.createGroupPad = async function(groupID, padName, text)
return { padID };
}
exports.listPads = async function(groupID)
{
exports.listPads = async function(groupID) {
let exists = await exports.doesGroupExist(groupID);
// ensure the group exists

View File

@ -109,8 +109,7 @@ let padList = {
* @param id A String with the id of the pad
* @param {Function} callback
*/
exports.getPad = async function(id, text)
{
exports.getPad = async function(id, text) {
// check if this is a valid padId
if (!exports.isValidPadId(id)) {
throw new customError(id + " is not a valid padId", "apierror");
@ -147,16 +146,14 @@ exports.getPad = async function(id, text)
return pad;
}
exports.listAllPads = async function()
{
exports.listAllPads = async function() {
let padIDs = await padList.getPads();
return { padIDs };
}
// checks if a pad exists
exports.doesPadExist = async function(padId)
{
exports.doesPadExist = async function(padId) {
let value = await db.get("pad:" + padId);
return (value != null && value.atext);
@ -192,8 +189,7 @@ exports.sanitizePadId = async function sanitizePadId(padId) {
return padId;
}
exports.isValidPadId = function(padId)
{
exports.isValidPadId = function(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
exports.unloadPad = function(padId)
{
exports.unloadPad = function(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
* @param {String} the pad's id
*/
exports.isReadOnlyId = function(id)
{
exports.isReadOnlyId = function(id) {
return id.indexOf("r.") === 0;
}
@ -36,8 +35,7 @@ exports.isReadOnlyId = function(id)
* returns a read only id for a 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
let readOnlyId = await db.get("pad2readonly:" + padId);
@ -55,8 +53,7 @@ exports.getReadOnlyId = async function (padId)
* returns the padId for a read only id
* @param {String} readOnlyId read only id
*/
exports.getPadId = function(readOnlyId)
{
exports.getPadId = function(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
* 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) {
authLogger.debug('access denied: missing padID');
return DENY;

View File

@ -78,8 +78,7 @@ exports.findAuthorID = async (groupID, sessionCookie) => {
return sessionInfo.authorID;
};
exports.doesSessionExist = async function(sessionID)
{
exports.doesSessionExist = async function(sessionID) {
//check if the database entry of this session exists
let session = await db.get("session:" + sessionID);
return (session !== null);
@ -88,8 +87,7 @@ exports.doesSessionExist = async function(sessionID)
/**
* 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
let groupExists = await groupManager.doesGroupExist(groupID);
if (!groupExists) {
@ -172,8 +170,7 @@ exports.createSession = async function(groupID, authorID, validUntil)
return { sessionID };
}
exports.getSessionInfo = async function(sessionID)
{
exports.getSessionInfo = async function(sessionID) {
// check if the database entry of this session exists
let session = await db.get("session:" + sessionID);
@ -189,8 +186,7 @@ exports.getSessionInfo = async function(sessionID)
/**
* Deletes a session
*/
exports.deleteSession = async function(sessionID)
{
exports.deleteSession = async function(sessionID) {
// ensure that the session exists
let session = await db.get("session:" + sessionID);
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
let exists = await groupManager.doesGroupExist(groupID);
if (!exists) {
@ -233,8 +228,7 @@ exports.listSessionsOfGroup = async function(groupID)
return sessions;
}
exports.listSessionsOfAuthor = async function(authorID)
{
exports.listSessionsOfAuthor = async function(authorID) {
// check that the author exists
let exists = await authorManager.doesAuthorExist(authorID)
if (!exists) {
@ -247,8 +241,7 @@ exports.listSessionsOfAuthor = async function(authorID)
// 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
async function listSessionsWithDBKey(dbkey)
{
async function listSessionsWithDBKey(dbkey) {
// get the group2sessions entry
let sessionObject = await db.get(dbkey);
let sessions = sessionObject ? sessionObject.sessionIDs : null;
@ -272,7 +265,6 @@ async function listSessionsWithDBKey(dbkey)
}
// checks if a number is an int
function is_int(value)
{
function is_int(value) {
return (parseFloat(value) == parseInt(value)) && !isNaN(value);
}

View File

@ -158,8 +158,7 @@ exports.version = version;
* @req express request 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
if (!(apiVersion in version)) {
throw new createHTTPError.NotFound('no such api version');

View File

@ -49,8 +49,7 @@ const tempDirectory = os.tmpdir();
/**
* 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
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 => {
if (err !== "stop") {
throw err;

View File

@ -57,8 +57,7 @@ const tmpDirectory = os.tmpdir();
/**
* do a requested import
*/
async function doImport(req, res, padId)
{
async function doImport(req, res, padId) {
var apiLogger = log4js.getLogger("ImportHandler");
// 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
* '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
* @param socket_io The Socket
*/
exports.setSocketIO = function(socket_io)
{
exports.setSocketIO = function(socket_io) {
socketio=socket_io;
}
@ -99,8 +98,7 @@ exports.handleConnect = (socket) => {
/**
* Kicks all sessions from a pad
*/
exports.kickSessionsFromPad = function(padID)
{
exports.kickSessionsFromPad = function(padID) {
if(typeof socketio.sockets['clients'] !== 'function')
return;
@ -355,8 +353,7 @@ async function handleChatMessage(socket, message) {
* @param text the text of the chat message
* @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
let pad = await padManager.getPad(padId);
@ -688,8 +685,7 @@ async function handleUserChanges(socket, message) {
stopWatch.end();
}
exports.updatePadClients = async function(pad)
{
exports.updatePadClients = async function(pad) {
// skip this if no-one is on this pad
const roomSockets = _getRoomSockets(pad.id);
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.
function createSessionInfoAuth(sessionInfo, message)
{
function createSessionInfoAuth(sessionInfo, message) {
// Remember this information since we won't
// have the cookie in further socket.io messages.
// 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
* 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 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
* 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);
// get the atext
@ -1367,8 +1360,7 @@ async function getPadLines(padId, revNum)
* 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
*/
async function composePadChangesets (padId, startNum, endNum)
{
async function composePadChangesets (padId, startNum, endNum) {
let pad = await padManager.getPad(padId);
// fetch all changesets we need

View File

@ -37,8 +37,7 @@ var socket;
/**
* adds a component
*/
exports.addComponent = function(moduleName, module)
{
exports.addComponent = function(moduleName, module) {
// save the component
components[moduleName] = module;
@ -53,8 +52,7 @@ exports.setSocketIO = function(_socket) {
// save this socket internaly
socket = _socket;
socket.sockets.on('connection', function(client)
{
socket.sockets.on('connection', function(client) {
// wrap the original send function to log the messages
client._send = client.send;
client.send = function(message) {

View File

@ -12,24 +12,20 @@ exports.expressCreateServer = function (hook_name, args, cb) {
})
//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}));
});
//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}));
});
//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");
res.sendFile(filePath, function(err)
{
res.sendFile(filePath, function(err) {
//there is no custom robots.txt, send the default robots.txt which dissallows all
if(err)
{
@ -40,8 +36,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
});
//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
const isReadOnly =
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
args.app.get('/p/:pad/timeslider', function(req, res, next)
{
args.app.get('/p/:pad/timeslider', function(req, res, next) {
hooks.callAll("padInitToolbar", {
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
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");
res.sendFile(filePath, function(err)
{
res.sendFile(filePath, function(err) {
//there is no custom favicon, send the default favicon
if(err)
{

View File

@ -30,27 +30,23 @@ if(os.type().indexOf("Windows") > -1)
{
var stdoutBuffer = "";
doConvertTask = function(task, callback)
{
doConvertTask = function(task, callback) {
//span an abiword process to perform the conversion
var abiword = spawn(settings.abiword, ["--to=" + task.destFile, task.srcFile]);
//delegate the processing of stdout to another function
abiword.stdout.on('data', function (data)
{
abiword.stdout.on('data', function (data) {
//add data to buffer
stdoutBuffer+=data.toString();
});
//append error messages to the buffer
abiword.stderr.on('data', function (data)
{
abiword.stderr.on('data', function (data) {
stdoutBuffer += data.toString();
});
//throw exceptions if abiword is dieing
abiword.on('exit', function (code)
{
abiword.on('exit', function (code) {
if(code != 0) {
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);
};
}
@ -82,21 +77,18 @@ else
var firstPrompt = true;
//append error messages to the buffer
abiword.stderr.on('data', function (data)
{
abiword.stderr.on('data', function (data) {
stdoutBuffer += data.toString();
});
//abiword died, let's restart abiword and return an error with the callback
abiword.on('exit', function (code)
{
abiword.on('exit', function (code) {
spawnAbiword();
stdoutCallback(`Abiword died with exit code ${code}`);
});
//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
stdoutBuffer+=data.toString();
@ -123,12 +115,10 @@ else
};
spawnAbiword();
doConvertTask = function(task, callback)
{
doConvertTask = function(task, callback) {
abiword.stdin.write("convert " + task.srcFile + " " + task.destFile + " " + task.type + "\n");
//create a callback that calls the task callback and the caller callback
stdoutCallback = function (err)
{
stdoutCallback = function (err) {
callback();
console.log("queue continue");
try{
@ -141,8 +131,7 @@ else
//Queue with the converts we have to do
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});
};
}

View File

@ -23,8 +23,7 @@ var eejs = require('ep_etherpad-lite/node/eejs');
var _analyzeLine = require('./ExportHelper')._analyzeLine;
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
async function getPadHTML(pad, revNum)
{
async function getPadHTML(pad, revNum) {
let atext = pad.atext;
// fetch revision atext
@ -39,8 +38,7 @@ async function getPadHTML(pad, revNum)
exports.getPadHTML = getPadHTML;
exports.getHTMLFromAtext = getHTMLFromAtext;
async function getHTMLFromAtext(pad, atext, authorColors)
{
async function getHTMLFromAtext(pad, atext, authorColors) {
var apool = pad.apool();
var textLines = atext.text.slice(0, -1).split('\n');
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
// 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];
if (_.isArray(propName)) {
// 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
// and decent nesting. For example,
// <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);
}
function emitOpenTag(i)
{
function emitOpenTag(i) {
openTags.unshift(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
function emitCloseTag(i)
{
function emitCloseTag(i) {
openTags.shift();
var spanClass = getSpanClassFor(i);
var spanWithData = isSpanWithData(i);
@ -202,8 +196,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
var idx = 0;
function processNextChars(numChars)
{
function processNextChars(numChars) {
if (numChars <= 0)
{
return;
@ -220,8 +213,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
var usedAttribs = [];
// mark all attribs as used
Changeset.eachAttribNumber(o.attribs, function (a)
{
Changeset.eachAttribNumber(o.attribs, function (a) {
if (a in anumMap)
{
usedAttribs.push(anumMap[a]); // i = 0 => bold, etc.
@ -280,8 +272,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
} // end processNextChars
if (urls)
{
urls.forEach(function (urlData)
{
urls.forEach(function (urlData) {
var startIndex = urlData[0];
var url = urlData[1];
var urlLength = url.length;
@ -341,8 +332,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
//To create list parent elements
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);
});
if (!exists) {
@ -445,8 +435,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
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;
});
@ -485,8 +474,7 @@ async function getHTMLFromAtext(pad, atext, authorColors)
return pieces.join('');
}
exports.getPadHTMLDocument = async function (padId, revNum)
{
exports.getPadHTMLDocument = async function (padId, revNum) {
let pad = await padManager.getPad(padId);
// 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], ...]
function _findURLs(text)
{
function _findURLs(text) {
_REGEX_URL.lastIndex = 0;
var urls = null;
var execResult;

View File

@ -23,8 +23,7 @@ var padManager = require("../db/PadManager");
var _analyzeLine = require('./ExportHelper')._analyzeLine;
// 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;
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
// functionality that is designed specifically for TXT exports
function getTXTFromAtext(pad, atext, authorColors)
{
function getTXTFromAtext(pad, atext, authorColors) {
var apool = pad.apool();
var textLines = atext.text.slice(0, -1).split('\n');
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
@ -259,8 +257,7 @@ function getTXTFromAtext(pad, atext, authorColors)
exports.getTXTFromAtext = getTXTFromAtext;
exports.getPadTXTDocument = async function(padId, revNum)
{
exports.getPadTXTDocument = async function(padId, revNum) {
let pad = await padManager.getPad(padId);
return getPadTXT(pad, revNum);
}

View File

@ -18,8 +18,7 @@ var log4js = require('log4js');
const db = require("../db/DB");
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
exports.setPadRaw = function(padId, records)
{
exports.setPadRaw = function(padId, records) {
records = JSON.parse(records);
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 res the Express response
*/
function minify(req, res)
{
function minify(req, res) {
var filename = req.params['filename'];
// 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 latestModification = 0;
//go trough this two folders
async.forEach(folders2check, function(path, callback)
{
async.forEach(folders2check, function(path, callback) {
//read the files in the folder
fs.readdir(path, function(err, files)
{
fs.readdir(path, function(err, files) {
if(ERR(err, callback)) return;
//we wanna check the directory itself for changes too
files.push(".");
//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
fs.stat(path + "/" + filename, function(err, stats)
{
fs.stat(path + "/" + filename, function(err, stats) {
if(ERR(err, callback)) return;
//get the modification time

View File

@ -7,13 +7,11 @@ var Terser = require("terser");
var path = require('path');
var Threads = require('threads')
function compressJS(content)
{
function compressJS(content) {
return Terser.minify(content);
}
function compressCSS(filename, ROOT_DIR)
{
function compressCSS(filename, ROOT_DIR) {
return new Promise((res, rej) => {
try {
const absPath = path.join(ROOT_DIR, filename);

View File

@ -381,8 +381,7 @@ exports.commitRateLimiting = {
exports.importMaxFileSize = 50 * 1024 * 1024;
// checks if abiword is avaiable
exports.abiwordAvailable = function()
{
exports.abiwordAvailable = function() {
if (exports.abiword != null) {
return os.type().indexOf("Windows") != -1 ? "withoutPDF" : "yes";
} else {

View File

@ -3,8 +3,7 @@
*/
var crypto = require('crypto');
var randomString = function(len)
{
var randomString = function(len) {
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.
*/
var AttributeManager = function(rep, applyChangesetCallback)
{
var AttributeManager = function(rep, applyChangesetCallback) {
this.rep = rep;
this.applyChangesetCallback = applyChangesetCallback;
this.author = '';
@ -62,8 +61,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
@param end [row, col] tuple pointing to the end of the range
@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
// 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
@ -87,8 +85,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
return this.applyChangeset(allChangesets);
},
_findRowRange: function(row, start, end)
{
_findRowRange: function(row, start, end) {
var startCol, endCol;
var startLineOffset = this.rep.lines.offsetOfIndex(row);
@ -119,8 +116,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
@param endCol column where range ends
@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());
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
ChangesetUtils.buildKeepRange(this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
@ -209,8 +205,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
[attributeName, 'true']
], rep.apool);
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
function hasIt(attribs)
{
function hasIt(attribs) {
return withItRegex.test(attribs);
}

View File

@ -18,8 +18,7 @@
* See the License for the specific language governing permissions and
* 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 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 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]);
builder.keep(startLineOffset, start[0]);

View File

@ -41,8 +41,7 @@ function scriptTag(source) {
)
}
function Ace2Editor()
{
function Ace2Editor() {
var ace2 = Ace2Editor;
var editor = {};
@ -54,14 +53,11 @@ function Ace2Editor()
var actionsPendingInit = [];
function pendingInit(func, optDoNow)
{
return function()
{
function pendingInit(func, optDoNow) {
return function() {
var that = this;
var args = arguments;
var action = function()
{
var action = function() {
func.apply(that, args);
}
if (optDoNow)
@ -79,8 +75,7 @@ function Ace2Editor()
};
}
function doActionsPendingInit()
{
function doActionsPendingInit() {
_.each(actionsPendingInit, function(fn,i){
fn()
});
@ -114,24 +109,20 @@ function Ace2Editor()
});
});
editor.exportText = function()
{
editor.exportText = function() {
if (!loaded) return "(awaiting init)\n";
return info.ace_exportText();
};
editor.getFrame = function()
{
editor.getFrame = function() {
return info.frame || null;
};
editor.getDebugProperty = function(prop)
{
editor.getDebugProperty = function(prop) {
return info.ace_getDebugProperty(prop);
};
editor.getInInternationalComposition = function()
{
editor.getInInternationalComposition = function() {
if (!loaded) return false;
return info.ace_getInInternationalComposition();
};
@ -145,14 +136,12 @@ function Ace2Editor()
// to prepareUserChangeset will return an updated changeset that takes into account the
// latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
// accordingly.
editor.prepareUserChangeset = function()
{
editor.prepareUserChangeset = function() {
if (!loaded) return null;
return info.ace_prepareUserChangeset();
};
editor.getUnhandledErrors = function()
{
editor.getUnhandledErrors = function() {
if (!loaded) return [];
// returns array of {error: <browser Error object>, time: +new Date()}
return info.ace_getUnhandledErrors();
@ -198,28 +187,24 @@ function Ace2Editor()
}
}
editor.destroy = pendingInit(function()
{
editor.destroy = pendingInit(function() {
info.ace_dispose();
info.frame.parentNode.removeChild(info.frame);
delete ace2.registry[info.id];
info = null; // prevent IE 6 closure memory leaks
});
editor.init = function(containerId, initialCode, doneFunc)
{
editor.init = function(containerId, initialCode, doneFunc) {
editor.importText(initialCode);
info.onEditorReady = function()
{
info.onEditorReady = function() {
loaded = true;
doActionsPendingInit();
doneFunc();
};
(function()
{
(function() {
var doctype = "<!doctype html>";
var iframeHTML = [];

View File

@ -22,25 +22,21 @@
var Security = require('./security');
function isNodeText(node)
{
function isNodeText(node) {
return (node.nodeType == 3);
}
function object(o)
{
function object(o) {
var f = function(){};
f.prototype = o;
return new f();
}
function getAssoc(obj, name)
{
function getAssoc(obj, 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
// copied to new nodes that are spawned during editing; also,
// 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.
function binarySearch(numItems, func)
{
function binarySearch(numItems, func) {
if (numItems < 1) return 0;
if (func(0)) return 0;
if (!func(numItems - 1)) return numItems;
@ -68,15 +63,13 @@ function binarySearch(numItems, func)
return high;
}
function binarySearchInfinite(expectedLength, func)
{
function binarySearchInfinite(expectedLength, func) {
var i = 0;
while (!func(i)) i += expectedLength;
return binarySearch(i, func);
}
function htmlPrettyEscape(str)
{
function htmlPrettyEscape(str) {
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
// Timeslider controller would probably be more appropriate.
function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider)
{
function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider) {
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
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/ )
{
Array.prototype.indexOf = function(elt /*, from*/ ) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
@ -54,8 +52,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
};
}
function debugLog()
{
function debugLog() {
try
{
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),
// generates a jquery element containing HTML for a line
lineToElement: function(line, aline)
{
lineToElement: function(line, aline) {
var element = document.createElement("div");
var emptyLine = (line == '\n');
var domInfo = domline.createDomLine(!emptyLine, true);
@ -95,8 +91,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
return $(element);
},
applySpliceToDivs: function(start, numRemoved, newLines)
{
applySpliceToDivs: function(start, numRemoved, newLines) {
// remove spliced-out lines from DOM
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: function(start, numRemoved, newLinesVA)
{
splice: function(start, numRemoved, newLinesVA) {
var newLines = _.map(Array.prototype.slice.call(arguments, 2), function(s) {
return s;
});
@ -152,26 +146,22 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
this.currentLines.splice.apply(this.currentLines, arguments);
},
// returns the contents of the specified line I
get: function(i)
{
get: function(i) {
return this.currentLines[i];
},
// returns the number of lines in the document
length: function()
{
length: function() {
return this.currentLines.length;
},
getActiveAuthors: function()
{
getActiveAuthors: function() {
var self = this;
var authors = [];
var seenNums = {};
var alines = self.alines;
for (var i = 0; i < alines.length; i++)
{
Changeset.eachAttribNumber(alines[i], function(n)
{
Changeset.eachAttribNumber(alines[i], function(n) {
if (!seenNums[n])
{
seenNums[n] = true;
@ -191,8 +181,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
};
function callCatchingErrors(catcher, func)
{
function callCatchingErrors(catcher, func) {
try
{
wrapRecordingErrors(catcher, func)();
@ -202,10 +191,8 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
}
function wrapRecordingErrors(catcher, func)
{
return function()
{
function wrapRecordingErrors(catcher, func) {
return function() {
try
{
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);
revisionInfo.addChangeset(revision, revision + 1, changesetForward, changesetBackward, timeDelta);
BroadcastSlider.setSliderLength(revisionInfo.latest);
@ -236,8 +222,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
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
if (!preventSliderMovement)
{
@ -283,18 +268,15 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
updateTimer();
var authors = _.map(padContents.getActiveAuthors(), function(name)
{
var authors = _.map(padContents.getActiveAuthors(), function(name) {
return authorData[name];
});
BroadcastSlider.setAuthors(authors);
}
function updateTimer()
{
var zpad = function(str, length)
{
function updateTimer() {
var zpad = function(str, length) {
str = str + "";
while (str.length < length)
str = '0' + str;
@ -302,8 +284,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
var date = new Date(padContents.currentTime);
var dateFormat = function()
{
var dateFormat = function() {
var month = zpad(date.getMonth() + 1, 2);
var day = zpad(date.getDate(), 2);
var year = (date.getFullYear());
@ -349,8 +330,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
updateTimer();
function goToRevision(newRevision)
{
function goToRevision(newRevision) {
padContents.targetRevision = newRevision;
var self = this;
var path = revisionInfo.getPath(padContents.currentRevision, newRevision);
@ -376,8 +356,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var sliderLocation = padContents.currentRevision;
// callback is called after changeset information is pulled from server
// 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
goToRevision(padContents.targetRevision);
};
@ -431,8 +410,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
requestQueue2: [],
requestQueue3: [],
reqCallbacks: [],
queueUp: function(revision, width, callback)
{
queueUp: function(revision, width, callback) {
if (revision < 0) revision = 0;
// if(changesetLoader.requestQueue.indexOf(revision) != -1)
// return; // already in the queue.
@ -452,8 +430,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
setTimeout(changesetLoader.loadFromQueue, 10);
}
},
loadFromQueue: function()
{
loadFromQueue: function() {
var self = changesetLoader;
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;
},
handleSocketResponse: function(message)
{
handleSocketResponse: function(message) {
var self = changesetLoader;
var start = message.data.start;
@ -489,8 +465,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
self.handleResponse(message.data, start, granularity, callback);
setTimeout(self.loadFromQueue, 10);
},
handleResponse: function(data, start, granularity, callback)
{
handleResponse: function(data, start, granularity, callback) {
var pool = (new AttribPool()).fromJsonable(data.apool);
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);
},
handleMessageFromServer: function (obj)
{
handleMessageFromServer: function (obj) {
if (obj.type == "COLLABROOM")
{
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
//window['onloadFuncts'].push(setUpSocket);
//window['onloadFuncts'].push(function ()
fireWhenAllScriptsAreLoaded.push(function()
{
fireWhenAllScriptsAreLoaded.push(function() {
// set up the currentDivs and DOM
padContents.currentDivs = [];
$("#innerdocbody").html("");
@ -588,8 +561,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
var dynamicCSS = makeCSSManager('dynamicsyntax');
var authorData = {};
function receiveAuthorData(newAuthorData)
{
function receiveAuthorData(newAuthorData) {
for (var author in newAuthorData)
{
var data = newAuthorData[author];

View File

@ -23,34 +23,28 @@
// of the document. These revisions are connected together by various
// changesets, or deltas, between any two revisions.
function loadBroadcastRevisionsJS()
{
function Revision(revNum)
{
function loadBroadcastRevisionsJS() {
function Revision(revNum) {
this.rev = revNum;
this.changesets = [];
}
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta)
{
Revision.prototype.addChangeset = function(destIndex, changeset, timeDelta) {
var changesetWrapper = {
deltaRev: destIndex - this.rev,
deltaTime: timeDelta,
getValue: function()
{
getValue: function() {
return changeset;
}
};
this.changesets.push(changesetWrapper);
this.changesets.sort(function(a, b)
{
this.changesets.sort(function(a, b) {
return (b.deltaRev - a.deltaRev)
});
}
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 endRevision = revisionInfo[toIndex] || revisionInfo.createNew(toIndex);
startRevision.addChangeset(toIndex, changeset, timeDelta);
@ -59,8 +53,7 @@ function loadBroadcastRevisionsJS()
revisionInfo.latest = clientVars.collab_client_vars.rev || -1;
revisionInfo.createNew = function(index)
{
revisionInfo.createNew = function(index) {
revisionInfo[index] = new Revision(index);
if (index > revisionInfo.latest)
{
@ -72,8 +65,7 @@ function loadBroadcastRevisionsJS()
// assuming that there is a path from fromIndex to toIndex, and that the links
// are laid out in a skip-list format
revisionInfo.getPath = function(fromIndex, toIndex)
{
revisionInfo.getPath = function(fromIndex, toIndex) {
var changesets = [];
var spans = [];
var times = [];

View File

@ -26,15 +26,13 @@ var _ = require('./underscore');
var padmodals = require('./pad_modals').padmodals;
var colorutils = require('./colorutils').colorutils;
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
{
function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) {
var BroadcastSlider;
// Hack to ensure timeslider i18n values are in
$("[data-key='timeslider_returnToPad'] > a > span").html(html10n.get("timeslider.toolbar.returnbutton"));
(function()
{ // wrap this code in its own namespace
(function() { // wrap this code in its own namespace
var sliderLength = 1000;
var sliderPos = 0;
var sliderActive = false;
@ -42,8 +40,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
var savedRevisions = [];
var sliderPlaying = false;
var _callSliderCallbacks = function(newval)
{
var _callSliderCallbacks = function(newval) {
sliderPos = newval;
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++)
{
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));
}
var addSavedRevision = function(position, info)
{
var addSavedRevision = function(position, info) {
var newSavedRevision = $('<div></div>');
newSavedRevision.addClass("star");
newSavedRevision.attr('pos', position);
newSavedRevision.css('left', (position * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)) - 1);
$("#ui-slider-bar").append(newSavedRevision);
newSavedRevision.mouseup(function(evt)
{
newSavedRevision.mouseup(function(evt) {
BroadcastSlider.setSliderPosition(position);
});
savedRevisions.push(newSavedRevision);
};
var removeSavedRevision = function(position)
{
var removeSavedRevision = function(position) {
var element = $("div.star [pos=" + position + "]");
savedRevisions.remove(element);
element.remove();
@ -86,18 +79,15 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
/* Begin small 'API' */
function onSlider(callback)
{
function onSlider(callback) {
slidercallbacks.push(callback);
}
function getSliderPosition()
{
function getSliderPosition() {
return sliderPos;
}
function setSliderPosition(newpos)
{
function setSliderPosition(newpos) {
newpos = Number(newpos);
if (newpos < 0 || newpos > sliderLength) return;
if(!newpos){
@ -105,8 +95,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
}
window.location.hash = "#" + newpos;
$("#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));
});
@ -119,33 +108,28 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
_callSliderCallbacks(newpos);
}
function getSliderLength()
{
function getSliderLength() {
return sliderLength;
}
function setSliderLength(newlength)
{
function setSliderLength(newlength) {
sliderLength = newlength;
updateSliderElements();
}
// just take over the whole slider screen with a reconnect message
function showReconnectUI()
{
function showReconnectUI() {
padmodals.showModal("disconnected");
}
function setAuthors(authors)
{
function setAuthors(authors) {
var authorsList = $("#authorsList");
authorsList.empty();
var numAnonymous = 0;
var numNamed = 0;
var colorsAnonymous = [];
_.each(authors, function(author)
{
_.each(authors, function(author) {
if(author)
{
var authorColor = clientVars.colorPalette[author.colorId] || author.colorId;
@ -204,8 +188,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
setSliderPosition: setSliderPosition,
getSliderLength: getSliderLength,
setSliderLength: setSliderLength,
isSliderActive: function()
{
isSliderActive: function() {
return sliderActive;
},
playpause: playpause,
@ -214,8 +197,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
setAuthors: setAuthors
}
function playButtonUpdater()
{
function playButtonUpdater() {
if (sliderPlaying)
{
if (getSliderPosition() + 1 > sliderLength)
@ -230,8 +212,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
}
}
function playpause()
{
function playpause() {
$("#playpause_button_icon").toggleClass('pause');
if (!sliderPlaying)
@ -247,10 +228,8 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
}
// assign event handlers to html UI elements after page load
fireWhenAllScriptsAreLoaded.push(function()
{
$(document).keyup(function(e)
{
fireWhenAllScriptsAreLoaded.push(function() {
$(document).keyup(function(e) {
if (!e) var e = window.event;
var code = e.keyCode || e.which;
@ -277,27 +256,23 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
});
// Resize
$(window).resize(function()
{
$(window).resize(function() {
updateSliderElements();
});
// 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").trigger(evt);
});
// Slider dragging
$("#ui-slider-handle").mousedown(function(evt)
{
$("#ui-slider-handle").mousedown(function(evt) {
this.startLoc = evt.clientX;
this.currentLoc = parseInt($(this).css('left'));
var self = this;
sliderActive = true;
$(document).mousemove(function(evt2)
{
$(document).mousemove(function(evt2) {
$(self).css('pointer', 'move')
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
if (newloc < 0) newloc = 0;
@ -306,8 +281,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
$(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)))
});
$(document).mouseup(function(evt2)
{
$(document).mouseup(function(evt2) {
$(document).unbind('mousemove');
$(document).unbind('mouseup');
sliderActive = false;
@ -326,14 +300,12 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
})
// play/pause toggling
$("#playpause_button_icon").click(function(evt)
{
$("#playpause_button_icon").click(function(evt) {
BroadcastSlider.playpause();
});
// next/prev saved revision and changeset
$('.stepper').click(function(evt)
{
$('.stepper').click(function(evt) {
switch ($(this).attr("id")) {
case "leftstep":
setSliderPosition(getSliderPosition() - 1);
@ -380,8 +352,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
setSliderLength(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);
})
@ -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");
})

View File

@ -1,8 +1,7 @@
// 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
// is represented by the browser
exports.getPosition = function ()
{
exports.getPosition = function () {
var rect, line;
var editor = $('#innerdocbody')[0];
var range = getSelectionRange();
@ -98,8 +97,7 @@ exports.getPositionTopOfPreviousBrowserLine = function(caretLinePosition, rep) {
return previousLineTop;
}
function caretLineIsFirstBrowserLine(caretLineTop, rep)
{
function caretLineIsFirstBrowserLine(caretLineTop, rep) {
var caretRepLine = rep.selStart[0];
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
var firstRootNode = getFirstRootChildNode(lineNode);
@ -110,8 +108,7 @@ function caretLineIsFirstBrowserLine(caretLineTop, rep)
}
// find the first root node, usually it is a text node
function getFirstRootChildNode(node)
{
function getFirstRootChildNode(node) {
if(!node.firstChild){
return node;
}else{
@ -120,8 +117,7 @@ function getFirstRootChildNode(node)
}
function getPreviousVisibleLine(line, rep)
{
function getPreviousVisibleLine(line, rep) {
if (line < 0) {
return 0;
}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 lastRootChildNode = getLastRootChildNode(lineNode);
@ -141,8 +136,7 @@ function getDimensionOfLastBrowserLineOfRepLine(line, rep)
return lastRootChildNodePosition;
}
function getLastRootChildNode(node)
{
function getLastRootChildNode(node) {
if(!node.lastChild){
return {
node: node,
@ -158,8 +152,7 @@ function getLastRootChildNode(node)
// 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
// 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 isCaretLineLastBrowserLine = caretLineIsLastBrowserLineOfRepLine(caretLinePosition.top, rep);
@ -174,8 +167,7 @@ exports.getBottomOfNextBrowserLine = function(caretLinePosition, rep)
return nextLineBottom;
}
function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep)
{
function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep) {
var caretRepLine = rep.selStart[0];
var lineNode = rep.lines.atIndex(caretRepLine).lineNode;
var lastRootChildNode = getLastRootChildNode(lineNode);
@ -185,8 +177,7 @@ function caretLineIsLastBrowserLineOfRepLine(caretLineTop, rep)
return lastRootChildNodePosition.top === caretLineTop;
}
function getPreviousVisibleLine(line, rep)
{
function getPreviousVisibleLine(line, rep) {
var firstLineOfPad = 0;
if (line <= firstLineOfPad) {
return firstLineOfPad;
@ -198,8 +189,7 @@ function getPreviousVisibleLine(line, rep)
}
exports.getPreviousVisibleLine = getPreviousVisibleLine;
function getNextVisibleLine(line, rep)
{
function getNextVisibleLine(line, rep) {
var lastLineOfThePad = rep.lines.length() - 1;
if (line >= lastLineOfThePad) {
return lastLineOfThePad;
@ -211,13 +201,11 @@ function getNextVisibleLine(line, rep)
}
exports.getNextVisibleLine = getNextVisibleLine;
function isLineVisible(line, rep)
{
function isLineVisible(line, rep) {
return rep.lines.atIndex(line).lineNode.offsetHeight > 0;
}
function getDimensionOfFirstBrowserLineOfRepLine(line, rep)
{
function getDimensionOfFirstBrowserLineOfRepLine(line, rep) {
var lineNode = rep.lines.atIndex(line).lineNode;
var firstRootChildNode = getFirstRootChildNode(lineNode);
@ -226,8 +214,7 @@ function getDimensionOfFirstBrowserLineOfRepLine(line, rep)
return firstRootChildNodePosition;
}
function getSelectionRange()
{
function getSelectionRange() {
var selection;
if (!window.getSelection) {
return;

View File

@ -23,8 +23,7 @@
var AttributePool = require('./AttributePool');
var Changeset = require('./Changeset');
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
{
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) {
// latest official text from server
var baseAText = Changeset.makeAText("\n");
@ -44,15 +43,13 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
var changeCallbackTimeout = null;
function setChangeCallbackTimeout()
{
function setChangeCallbackTimeout() {
// can call this multiple times per call-stack, because
// we only schedule a call to changeCallback if it exists
// and if there isn't a timeout already scheduled.
if (changeCallback && changeCallbackTimeout === null)
{
changeCallbackTimeout = scheduler.setTimeout(function()
{
changeCallbackTimeout = scheduler.setTimeout(function() {
try
{
changeCallback();
@ -68,18 +65,14 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
var self;
return self = {
isTracking: function()
{
isTracking: function() {
return tracking;
},
setBaseText: function(text)
{
setBaseText: function(text) {
self.setBaseAttributedText(Changeset.makeAText(text), null);
},
setBaseAttributedText: function(atext, apoolJsonObj)
{
aceCallbacksProvider.withCallbacks("setBaseText", function(callbacks)
{
setBaseAttributedText: function(atext, apoolJsonObj) {
aceCallbacksProvider.withCallbacks("setBaseText", function(callbacks) {
tracking = true;
baseAText = Changeset.cloneAText(atext);
if (apoolJsonObj)
@ -100,8 +93,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
}
});
},
composeUserChangeset: function(c)
{
composeUserChangeset: function(c) {
if (!tracking) return;
if (applyingNonUserChanges) return;
if (Changeset.isIdentity(c)) return;
@ -109,12 +101,10 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
setChangeCallbackTimeout();
},
applyChangesToBase: function(c, optAuthor, apoolJsonObj)
{
applyChangesToBase: function(c, optAuthor, apoolJsonObj) {
if (!tracking) return;
aceCallbacksProvider.withCallbacks("applyChangesToBase", function(callbacks)
{
aceCallbacksProvider.withCallbacks("applyChangesToBase", function(callbacks) {
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
// changeset, else it will be null.
var toSubmit;
@ -237,8 +226,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
};
return data;
},
applyPreparedChangesetToBase: function()
{
applyPreparedChangesetToBase: function() {
if (!submittedChangeset)
{
// violation of protocol; use prepareUserChangeset first
@ -248,12 +236,10 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
baseAText = Changeset.applyToAText(submittedChangeset, baseAText, apool);
submittedChangeset = null;
},
setUserChangeNotificationCallback: function(callback)
{
setUserChangeNotificationCallback: function(callback) {
changeCallback = callback;
},
hasUncommittedChanges: function()
{
hasUncommittedChanges: function() {
return !!(submittedChangeset || (!Changeset.isIdentity(userChangeset)));
}
};

View File

@ -20,16 +20,14 @@ var Tinycon = require('tinycon/tinycon');
var hooks = require('./pluginfw/hooks');
var padeditor = require('./pad_editor').padeditor;
var chat = (function()
{
var chat = (function() {
var isStuck = false;
var userAndChat = false;
var gotInitialMessages = false;
var historyPointer = 0;
var chatMentions = 0;
var self = {
show: function ()
{
show: function () {
$("#chaticon").removeClass('visible');
$("#chatbox").addClass('visible');
self.scrollDown(true);
@ -39,14 +37,12 @@ var chat = (function()
$.gritter.remove(this.id);
});
},
focus: function ()
{
focus: function () {
setTimeout(function(){
$("#chatinput").focus();
},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){
return;
}
@ -62,8 +58,7 @@ var chat = (function()
padcookie.setPref("chatAlwaysVisible", isStuck);
$('#options-stickychat').prop('checked', isStuck);
},
chatAndUsers: function(fromInitialCall)
{
chatAndUsers: function(fromInitialCall) {
var toEnable = $('#options-chatandusers').is(":checked");
if(toEnable || !userAndChat || fromInitialCall){
chat.stickToScreen(true);
@ -79,8 +74,7 @@ var chat = (function()
$('#users, .sticky-container').toggleClass("chatAndUsers popup-show stickyUsers", userAndChat);
$("#chatbox").toggleClass("chatAndUsersChat", userAndChat);
},
hide: function ()
{
hide: function () {
// decide on hide logic based on chat window being maximized or not
if ($('#options-stickychat').prop('checked')) {
chat.stickToScreen();
@ -92,8 +86,7 @@ var chat = (function()
$("#chatbox").removeClass('visible');
}
},
scrollDown: function(force)
{
scrollDown: function(force) {
if ($('#chatbox').hasClass('visible')) {
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
@ -103,16 +96,14 @@ var chat = (function()
}
}
},
send: function()
{
send: function() {
var text = $("#chatinput").val();
if(text.replace(/\s+/,'').length == 0)
return;
this._pad.collabClient.sendMessage({"type": "CHAT_MESSAGE", "text": text});
$("#chatinput").val("");
},
addMessage: function(msg, increment, isHistoryAdd)
{
addMessage: function(msg, increment, isHistoryAdd) {
//correct the time
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.');
}
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 "-";
return 'z' + c.charCodeAt(0) + 'z';
});
@ -214,8 +204,7 @@ var chat = (function()
if(!isHistoryAdd)
self.scrollDown();
},
init: function(pad)
{
init: function(pad) {
this._pad = pad;
$("#chatinput").on("keydown", function(evt){
// 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
$("#chatcounter").text(0);
$("#chatloadmessagesbutton").click(function()
{
$("#chatloadmessagesbutton").click(function() {
var start = Math.max(self.historyPointer - 20, 0);
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.
ACE's ready callback does not need to have fired yet.
"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;
pad = _pad; // Inject pad to avoid a circular dependency.
@ -66,29 +65,20 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
tellAceActiveAuthorInfo(initialUserInfo);
var callbacks = {
onUserJoin: function()
{},
onUserLeave: function()
{},
onUpdateUserInfo: function()
{},
onChannelStateChange: function()
{},
onClientMessage: function()
{},
onInternalAction: function()
{},
onConnectionTrouble: function()
{},
onServerMessage: function()
{}
onUserJoin: function() {},
onUserLeave: function() {},
onUpdateUserInfo: function() {},
onChannelStateChange: function() {},
onClientMessage: function() {},
onInternalAction: function() {},
onConnectionTrouble: function() {},
onServerMessage: function() {}
};
if (browser.firefox)
{
// Prevent "escape" from taking effect and canceling a comet connection;
// doesn't work if focus is on an iframe.
$(window).bind("keydown", function(evt)
{
$(window).bind("keydown", function(evt) {
if (evt.which == 27)
{
evt.preventDefault()
@ -100,14 +90,12 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
editor.setBaseAttributedText(serverVars.initialAttributedText, serverVars.apool);
editor.setUserChangeNotificationCallback(wrapRecordingErrors("handleUserChanges", handleUserChanges));
function dmesg(str)
{
function dmesg(str) {
if (typeof window.ajlog == "string") window.ajlog += str + '\n';
debugMessages.push(str);
}
function handleUserChanges()
{
function handleUserChanges() {
if (editor.getInInternationalComposition()) return;
if ((!getSocket()) || channelState == "CONNECTING")
{
@ -161,12 +149,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
{
editor.applyPreparedChangesetToBase();
setStateIdle();
callCatchingErrors("onInternalAction", function()
{
callCatchingErrors("onInternalAction", function() {
callbacks.onInternalAction("commitAcceptedByServer");
});
callCatchingErrors("onConnectionTrouble", function()
{
callCatchingErrors("onConnectionTrouble", function() {
callbacks.onConnectionTrouble("OK");
});
handleUserChanges();
@ -219,8 +205,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
}
function setUpSocket()
{
function setUpSocket() {
hiccupCount = 0;
setChannelState("CONNECTED");
doDeferredActions();
@ -230,8 +215,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
var hiccupCount = 0;
function sendMessage(msg)
{
function sendMessage(msg) {
getSocket().json.send(
{
type: "COLLABROOM",
@ -240,10 +224,8 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
});
}
function wrapRecordingErrors(catcher, func)
{
return function()
{
function wrapRecordingErrors(catcher, func) {
return function() {
try
{
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
{
wrapRecordingErrors(catcher, func)();
@ -270,8 +251,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
}
function handleMessageFromServer(evt)
{
function handleMessageFromServer(evt) {
if (!getSocket()) return;
if (!evt.data) return;
var wrapper = evt;
@ -334,12 +314,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
rev = newRev;
editor.applyPreparedChangesetToBase();
setStateIdle();
callCatchingErrors("onInternalAction", function()
{
callCatchingErrors("onInternalAction", function() {
callbacks.onInternalAction("commitAcceptedByServer");
});
callCatchingErrors("onConnectionTrouble", function()
{
callCatchingErrors("onConnectionTrouble", function() {
callbacks.onConnectionTrouble("OK");
});
handleUserChanges();
@ -386,12 +364,10 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
{
editor.applyPreparedChangesetToBase();
setStateIdle();
callCatchingErrors("onInternalAction", function()
{
callCatchingErrors("onInternalAction", function() {
callbacks.onInternalAction("commitAcceptedByServer");
});
callCatchingErrors("onConnectionTrouble", function()
{
callCatchingErrors("onConnectionTrouble", function() {
callbacks.onConnectionTrouble("OK");
});
handleUserChanges();
@ -503,8 +479,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
hooks.callAll('handleClientMessage_' + msg.type, {payload: msg.payload});
}
function updateUserInfo(userInfo)
{
function updateUserInfo(userInfo) {
userInfo.userId = userId;
userSet[userId] = 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);
}
function tellAceAuthorInfo(userId, colorId, inactive)
{
function tellAceAuthorInfo(userId, colorId, inactive) {
if(typeof colorId == "number")
{
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);
}
function getConnectedUsers()
{
function getConnectedUsers() {
return valuesArray(userSet);
}
function tellAceAboutHistoricalAuthors(hadata)
{
function tellAceAboutHistoricalAuthors(hadata) {
for (var author in hadata)
{
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)
{
channelState = newChannelState;
@ -575,11 +544,9 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
}
function valuesArray(obj)
{
function valuesArray(obj) {
var array = [];
$.each(obj, function(k, v)
{
$.each(obj, function(k, v) {
array.push(v);
});
return array;
@ -589,15 +556,12 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
// is connected for the first time.
var deferredActions = [];
function defer(func, tag)
{
return function()
{
function defer(func, tag) {
return function() {
var that = this;
var args = arguments;
function action()
{
function action() {
func.apply(that, args);
}
action.tag = tag;
@ -612,8 +576,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
}
function doDeferredActions(tag)
{
function doDeferredActions(tag) {
var newArray = [];
for (var i = 0; i < deferredActions.length; i++)
{
@ -630,8 +593,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
deferredActions = newArray;
}
function sendClientMessage(msg)
{
function sendClientMessage(msg) {
sendMessage(
{
type: "CLIENT_MESSAGE",
@ -639,13 +601,11 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
});
}
function getCurrentRevisionNumber()
{
function getCurrentRevisionNumber() {
return rev;
}
function getMissedChanges()
{
function getMissedChanges() {
var obj = {};
obj.userInfo = userSet[userId];
obj.baseRev = rev;
@ -664,30 +624,25 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
return obj;
}
function setStateIdle()
{
function setStateIdle() {
state = "IDLE";
callbacks.onInternalAction("newlyIdle");
schedulePerhapsCallIdleFuncs();
}
function setIsPendingRevision(value)
{
function setIsPendingRevision(value) {
isPendingRevision = value;
}
function callWhenNotCommitting(func)
{
function callWhenNotCommitting(func) {
idleFuncs.push(func);
schedulePerhapsCallIdleFuncs();
}
var idleFuncs = [];
function schedulePerhapsCallIdleFuncs()
{
setTimeout(function()
{
function schedulePerhapsCallIdleFuncs() {
setTimeout(function() {
if (state == "IDLE")
{
while (idleFuncs.length > 0)
@ -700,36 +655,28 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
}
var self = {
setOnUserJoin: function(cb)
{
setOnUserJoin: function(cb) {
callbacks.onUserJoin = cb;
},
setOnUserLeave: function(cb)
{
setOnUserLeave: function(cb) {
callbacks.onUserLeave = cb;
},
setOnUpdateUserInfo: function(cb)
{
setOnUpdateUserInfo: function(cb) {
callbacks.onUpdateUserInfo = cb;
},
setOnChannelStateChange: function(cb)
{
setOnChannelStateChange: function(cb) {
callbacks.onChannelStateChange = cb;
},
setOnClientMessage: function(cb)
{
setOnClientMessage: function(cb) {
callbacks.onClientMessage = cb;
},
setOnInternalAction: function(cb)
{
setOnInternalAction: function(cb) {
callbacks.onInternalAction = cb;
},
setOnConnectionTrouble: function(cb)
{
setOnConnectionTrouble: function(cb) {
callbacks.onConnectionTrouble = cb;
},
setOnServerMessage: function(cb)
{
setOnServerMessage: function(cb) {
callbacks.onServerMessage = cb;
},
updateUserInfo: defer(updateUserInfo),

View File

@ -26,26 +26,22 @@ var colorutils = {};
// Check that a given value is a css hex color value, e.g.
// "#ffffff" or "#fff"
colorutils.isCssHex = function(cssColor)
{
colorutils.isCssHex = function(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]
colorutils.css2triple = function(cssColor)
{
colorutils.css2triple = function(cssColor) {
var sixHex = colorutils.css2sixhex(cssColor);
function hexToFloat(hh)
{
function hexToFloat(hh) {
return Number("0x" + hh) / 255;
}
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"
colorutils.css2sixhex = function(cssColor)
{
colorutils.css2sixhex = function(cssColor) {
var h = /[0-9a-fA-F]+/.exec(cssColor)[0];
if (h.length != 6)
{
@ -58,10 +54,8 @@ colorutils.css2sixhex = function(cssColor)
}
// [1.0, 1.0, 1.0] -> "#ffffff"
colorutils.triple2css = function(triple)
{
function floatToHex(n)
{
colorutils.triple2css = function(triple) {
function floatToHex(n) {
var n2 = colorutils.clamp(Math.round(n * 255), 0, 255);
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);
};
colorutils.min3 = function(a, b, c)
{
colorutils.min3 = function(a, 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);
};
colorutils.colorMin = function(c)
{
colorutils.colorMin = function(c) {
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]);
};
colorutils.scale = function(v, bot, top)
{
colorutils.scale = function(v, bot, top) {
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);
};
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)];
}
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)];
}
colorutils.luminosity = function(c)
{
colorutils.luminosity = function(c) {
// rule of thumb for RGB brightness; 1.0 is white
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 max = colorutils.colorMax(c);
if (max - min <= 0) return [1.0, 1.0, 1.0];
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])];
}
colorutils.invert = function(c)
{
colorutils.invert = function(c) {
return [1 - c[0], 1 - c[1], 1- c[2]];
}
colorutils.complementary = function(c)
{
colorutils.complementary = function(c) {
var inv = colorutils.invert(c);
return [
(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 black = skinName == 'colibris' ? 'var(--super-dark-color)' : '#222';

View File

@ -30,53 +30,43 @@ var Changeset = require('./Changeset');
var hooks = require('./pluginfw/hooks');
var _ = require('./underscore');
function sanitizeUnicode(s)
{
function sanitizeUnicode(s) {
return UNorm.nfc(s);
}
function makeContentCollector(collectStyles, abrowser, apool, domInterface, className2Author)
{
function makeContentCollector(collectStyles, abrowser, apool, domInterface, className2Author) {
abrowser = abrowser || {};
// I don't like the above.
var dom = domInterface || {
isNodeText: function(n)
{
isNodeText: function(n) {
return (n.nodeType == 3);
},
nodeTagName: function(n)
{
nodeTagName: function(n) {
return n.tagName;
},
nodeValue: function(n)
{
nodeValue: function(n) {
return n.nodeValue;
},
nodeNumChildren: function(n)
{
nodeNumChildren: function(n) {
if(n.childNodes == null) return 0;
return n.childNodes.length;
},
nodeChild: function(n, i)
{
nodeChild: function(n, i) {
if(n.childNodes.item == null){
return n.childNodes[i];
}
return n.childNodes.item(i);
},
nodeProp: function(n, p)
{
nodeProp: function(n, p) {
return n[p];
},
nodeAttr: function(n, a)
{
nodeAttr: function(n, a) {
if(n.getAttribute != null) return n.getAttribute(a);
if(n.attribs != null) return n.attribs[a];
return null;
},
optNodeInnerHTML: function(n)
{
optNodeInnerHTML: function(n) {
return n.innerHTML;
}
};
@ -92,66 +82,54 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
_blockElems[element] = 1;
});
function isBlockElement(n)
{
function isBlockElement(n) {
return !!_blockElems[(dom.nodeTagName(n) || "").toLowerCase()];
}
function textify(str)
{
function textify(str) {
return sanitizeUnicode(
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);
}
var lines = (function()
{
var lines = (function() {
var textArray = [];
var attribsArray = [];
var attribsBuilder = null;
var op = Changeset.newOp('+');
var self = {
length: function()
{
length: function() {
return textArray.length;
},
atColumnZero: function()
{
atColumnZero: function() {
return textArray[textArray.length - 1] === "";
},
startNew: function()
{
startNew: function() {
textArray.push("");
self.flush(true);
attribsBuilder = Changeset.smartOpAssembler();
},
textOfLine: function(i)
{
textOfLine: function(i) {
return textArray[i];
},
appendText: function(txt, attrString)
{
appendText: function(txt, attrString) {
textArray[textArray.length - 1] += txt;
//dmesg(txt+" / "+attrString);
op.attribs = attrString;
op.chars = txt.length;
attribsBuilder.append(op);
},
textLines: function()
{
textLines: function() {
return textArray.slice();
},
attribLines: function()
{
attribLines: function() {
return attribsArray;
},
// call flush only when you're done
flush: function(withNewline)
{
flush: function(withNewline) {
if (attribsBuilder)
{
attribsArray.push(attribsBuilder.toString());
@ -164,8 +142,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
}());
var cc = {};
function _ensureColumnZero(state)
{
function _ensureColumnZero(state) {
if (!lines.atColumnZero())
{
cc.startNewLine(state);
@ -174,8 +151,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
var selection, startPoint, endPoint;
var selStart = [-1, -1],
selEnd = [-1, -1];
function _isEmpty(node, state)
{
function _isEmpty(node, state) {
// consider clean blank lines pasted in IE to be empty
if (dom.nodeNumChildren(node) == 0) return true;
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;
}
function _pointHere(charsAfter, state)
{
function _pointHere(charsAfter, state) {
var ln = lines.length() - 1;
var chr = lines.textOfLine(ln).length;
if (chr == 0 && !_.isEmpty(state.lineAttributes))
@ -203,13 +178,11 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
return [ln, chr];
}
function _reachBlockPoint(nd, idx, state)
{
function _reachBlockPoint(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)
{
selStart = _pointHere(0, state);
@ -219,16 +192,13 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
selEnd = _pointHere(0, state);
}
}
cc.incrementFlag = function(state, flagName)
{
cc.incrementFlag = function(state, flagName) {
state.flags[flagName] = (state.flags[flagName] || 0) + 1;
}
cc.decrementFlag = function(state, flagName)
{
cc.decrementFlag = function(state, flagName) {
state.flags[flagName]--;
}
cc.incrementAttrib = function(state, attribName)
{
cc.incrementAttrib = function(state, attribName) {
if (!state.attribs[attribName])
{
state.attribs[attribName] = 1;
@ -239,14 +209,12 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
}
_recalcAttribString(state);
}
cc.decrementAttrib = function(state, attribName)
{
cc.decrementAttrib = function(state, attribName) {
state.attribs[attribName]--;
_recalcAttribString(state);
}
function _enterList(state, listType)
{
function _enterList(state, listType) {
if(!listType) return;
var oldListType = state.lineAttributes['list'];
if (listType != 'none')
@ -268,8 +236,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
return oldListType;
}
function _exitList(state, oldListType)
{
function _exitList(state, oldListType) {
if (state.lineAttributes['list']) {
state.listNesting--;
}
@ -283,8 +250,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
_recalcAttribString(state);
}
function _enterAuthor(state, author)
{
function _enterAuthor(state, author) {
var oldAuthor = state.author;
state.authorLevel = (state.authorLevel || 0) + 1;
state.author = author;
@ -292,15 +258,13 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
return oldAuthor;
}
function _exitAuthor(state, oldAuthor)
{
function _exitAuthor(state, oldAuthor) {
state.authorLevel--;
state.author = oldAuthor;
_recalcAttribString(state);
}
function _recalcAttribString(state)
{
function _recalcAttribString(state) {
var lst = [];
for (var a in state.attribs)
{
@ -338,8 +302,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
state.attribString = Changeset.makeAttribsString('+', lst, apool);
}
function _produceLineAttributesMarker(state)
{
function _produceLineAttributesMarker(state) {
// TODO: This has to go to AttributeManager.
var attributes = [
['lmkr', '1'],
@ -351,8 +314,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
);
lines.appendText('*', Changeset.makeAttribsString('+', attributes , apool));
}
cc.startNewLine = function(state)
{
cc.startNewLine = function(state) {
if (state)
{
var atBeginningOfLine = lines.textOfLine(lines.length() - 1).length == 0;
@ -363,8 +325,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
}
lines.startNew();
}
cc.notifySelection = function(sel)
{
cc.notifySelection = function(sel) {
if (sel)
{
selection = sel;
@ -372,14 +333,12 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
endPoint = selection.endPoint;
}
};
cc.doAttrib = function(state, na)
{
cc.doAttrib = function(state, na) {
state.localAttribs = (state.localAttribs || []);
state.localAttribs.push(na);
cc.incrementAttrib(state, na);
};
cc.collectContent = function(node, state)
{
cc.collectContent = function(node, state) {
if (!state)
{
state = {
@ -746,8 +705,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
state.localAttribs = localAttribs;
};
// 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
// 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.
@ -759,25 +717,21 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
}
};
// each returns [line, char] or [-1,-1]
var getSelectionStart = function()
{
var getSelectionStart = function() {
return selStart;
};
var getSelectionEnd = function()
{
var getSelectionEnd = function() {
return selEnd;
};
// 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).
// can be called at any point
cc.getLines = function()
{
cc.getLines = function() {
return lines.textLines();
};
cc.finish = function()
{
cc.finish = function() {
lines.flush();
var lineAttribs = lines.attribLines();
var lineStrings = cc.getLines();
@ -788,8 +742,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
var ss = getSelectionStart();
var se = getSelectionEnd();
function fixLongLines()
{
function fixLongLines() {
// design mode does not deal with with really long lines!
var lineLimit = 2000; // chars
var buffer = 10; // chars allowed over before wrapping
@ -819,8 +772,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas
newAttribStrings.push(oldAttribString);
}
function fixLineNumber(lineChar)
{
function fixLineNumber(lineChar) {
if (lineChar[0] < 0) return;
var n = lineChar[0];
var c = lineChar[1];

View File

@ -20,8 +20,7 @@
* limitations under the License.
*/
function makeCSSManager(emptyStylesheetTitle, doc)
{
function makeCSSManager(emptyStylesheetTitle, doc) {
if (doc === true)
{
doc = 'parent';
@ -29,8 +28,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
doc = 'inner';
}
function getSheetByTitle(title)
{
function getSheetByTitle(title) {
if (doc === 'parent')
{
win = window.parent.parent;
@ -59,26 +57,22 @@ function makeCSSManager(emptyStylesheetTitle, doc)
var browserSheet = getSheetByTitle(emptyStylesheetTitle);
function browserRules()
{
function browserRules() {
return (browserSheet.cssRules || browserSheet.rules);
}
function browserDeleteRule(i)
{
function browserDeleteRule(i) {
if (browserSheet.deleteRule) browserSheet.deleteRule(i);
else browserSheet.removeRule(i);
}
function browserInsertRule(i, selector)
{
function browserInsertRule(i, selector) {
if (browserSheet.insertRule) browserSheet.insertRule(selector + ' {}', i);
else browserSheet.addRule(selector, null, i);
}
var selectorList = [];
function indexOfSelector(selector)
{
function indexOfSelector(selector) {
for (var i = 0; i < selectorList.length; i++)
{
if (selectorList[i] == selector)
@ -89,8 +83,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
return -1;
}
function selectorStyle(selector)
{
function selectorStyle(selector) {
var i = indexOfSelector(selector);
if (i < 0)
{
@ -102,8 +95,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
return browserRules().item(i).style;
}
function removeSelectorStyle(selector)
{
function removeSelectorStyle(selector) {
var i = indexOfSelector(selector);
if (i >= 0)
{
@ -115,8 +107,7 @@ function makeCSSManager(emptyStylesheetTitle, doc)
return {
selectorStyle: selectorStyle,
removeSelectorStyle: removeSelectorStyle,
info: function()
{
info: function() {
return selectorList.length + ":" + browserRules().length;
}
};

View File

@ -35,13 +35,11 @@ var noop = function(){};
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
// the line, using line:className. otherwise, we ignore
// the span.
cls.replace(/\S+/g, function(c)
{
cls.replace(/\S+/g, function(c) {
if (c.indexOf("line:") == 0)
{
// 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
// an object with innerHTML and className
domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
{
domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) {
var result = {
node: null,
appendSpan: noop,
@ -84,8 +81,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
postHtml = '';
var curHTML = null;
function processSpaces(s)
{
function processSpaces(s) {
return domline.processSpaces(s, doesWrap);
}
@ -93,8 +89,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
var perHtmlLineProcess = (doesWrap ? processSpaces : _.identity);
var lineClass = 'ace-line';
result.appendSpan = function(txt, cls)
{
result.appendSpan = function(txt, cls) {
var processedMarker = false;
// Handle lineAttributeMarker, if present
@ -106,8 +101,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
_.map(hooks.callAll("aceDomLinePreProcessLineAttributes", {
domline: domline,
cls: cls
}), function(modifier)
{
}), function(modifier) {
preHtml += modifier.preHtml;
postHtml += modifier.postHtml;
processedMarker |= modifier.processedMarker;
@ -141,8 +135,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
_.map(hooks.callAll("aceDomLineProcessLineAttributes", {
domline: domline,
cls: cls
}), function(modifier)
{
}), function(modifier) {
preHtml += modifier.preHtml;
postHtml += modifier.postHtml;
processedMarker |= modifier.processedMarker;
@ -156,16 +149,14 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
var simpleTags = null;
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;
return space + "url";
});
}
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 = [];
simpleTags.push(tag.toLowerCase());
return space + tag;
@ -178,8 +169,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
_.map(hooks.callAll("aceCreateDomLine", {
domline: domline,
cls: cls
}), function(modifier)
{
}), function(modifier) {
cls = modifier.cls;
extraOpenTags = extraOpenTags + modifier.extraOpenTags;
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>');
}
};
result.clearSpans = function()
{
result.clearSpans = function() {
html = [];
lineClass = 'ace-line';
result.lineMarker = 0;
};
function writeHTML()
{
function writeHTML() {
var newHTML = perHtmlLineProcess(html.join(''));
if (!newHTML)
{
@ -257,23 +245,20 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
}
result.prepareForAdd = writeHTML;
result.finishUpdate = writeHTML;
result.getInnerHTML = function()
{
result.getInnerHTML = function() {
return curHTML || '';
};
return result;
};
domline.processSpaces = function(s, doesWrap)
{
domline.processSpaces = function(s, doesWrap) {
if (s.indexOf("<") < 0 && !doesWrap)
{
// short-cut
return s.replace(/ /g, '&nbsp;');
}
var parts = [];
s.replace(/<[^>]*>?| |[^ <]+/g, function(m)
{
s.replace(/<[^>]*>?| |[^ <]+/g, function(m) {
parts.push(m);
});
if (doesWrap)

View File

@ -44,10 +44,8 @@ linestylefilter.ATTRIB_CLASSES = {
var lineAttributeMarker = 'lineAttribMarker';
exports.lineAttributeMarker = lineAttributeMarker;
linestylefilter.getAuthorClassName = function(author)
{
return "author-" + author.replace(/[^a-y0-9]/g, function(c)
{
linestylefilter.getAuthorClassName = function(author) {
return "author-" + author.replace(/[^a-y0-9]/g, function(c) {
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
@ -55,8 +53,7 @@ linestylefilter.getAuthorClassName = function(author)
// lineLength is without newline; aline includes newline,
// 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
for (const attribClasses of hooks.callAll('aceAttribClasses', linestylefilter.ATTRIB_CLASSES)) {
@ -67,21 +64,18 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
var nextAfterAuthorColors = textAndClassFunc;
var authorColorFunc = (function()
{
var authorColorFunc = (function() {
var lineEnd = lineLength;
var curIndex = 0;
var extraClasses;
var leftInAuthor;
function attribsToClasses(attribs)
{
function attribsToClasses(attribs) {
var classes = '';
var isLineAttribMarker = false;
// For each attribute number
Changeset.eachAttribNumber(attribs, function(n)
{
Changeset.eachAttribNumber(attribs, function(n) {
// Give us this attributes key
var key = apool.getAttribKey(n);
if (key)
@ -127,15 +121,13 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
var attributionIter = Changeset.opIterator(aline);
var nextOp, nextOpClasses;
function goNextOp()
{
function goNextOp() {
nextOp = attributionIter.next();
nextOpClasses = (nextOp.opcode && attribsToClasses(nextOp.attribs));
}
goNextOp();
function nextClasses()
{
function nextClasses() {
if (curIndex < lineEnd)
{
extraClasses = nextOpClasses;
@ -150,8 +142,7 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
}
nextClasses();
return function(txt, cls)
{
return function(txt, cls) {
var disableAuthColorForThisLine = hooks.callAll("disableAuthorColorsForThisLine", {
linestylefilter: linestylefilter,
@ -186,8 +177,7 @@ linestylefilter.getLineStyleFilter = function(lineLength, aline, textAndClassFun
return authorColorFunc;
};
linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc)
{
linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc) {
var at = /@/g;
at.lastIndex = 0;
var splitPoints = null;
@ -206,10 +196,8 @@ linestylefilter.getAtSignSplitterFilter = function(lineText, textAndClassFunc)
return linestylefilter.textAndClassFuncSplitter(textAndClassFunc, splitPoints);
};
linestylefilter.getRegexpFilter = function(regExp, tag)
{
return function(lineText, textAndClassFunc)
{
linestylefilter.getRegexpFilter = function(regExp, tag) {
return function(lineText, textAndClassFunc) {
regExp.lastIndex = 0;
var regExpMatchs = null;
var splitPoints = null;
@ -229,8 +217,7 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
if (!regExpMatchs) return textAndClassFunc;
function regExpMatchForIndex(idx)
{
function regExpMatchForIndex(idx) {
for (var k = 0; k < regExpMatchs.length; k++)
{
var u = regExpMatchs[k];
@ -242,11 +229,9 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
return false;
}
var handleRegExpMatchsAfterSplit = (function()
{
var handleRegExpMatchsAfterSplit = (function() {
var curIndex = 0;
return function(txt, cls)
{
return function(txt, cls) {
var txtlen = txt.length;
var newCls = cls;
var regExpMatch = regExpMatchForIndex(curIndex);
@ -270,8 +255,7 @@ linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|(
linestylefilter.getURLFilter = linestylefilter.getRegexpFilter(
linestylefilter.REGEX_URL, 'url');
linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
{
linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) {
var nextPointIndex = 0;
var idx = 0;
@ -281,8 +265,7 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
nextPointIndex++;
}
function spanHandler(txt, cls)
{
function spanHandler(txt, cls) {
if ((!splitPointsOpt) || nextPointIndex >= splitPointsOpt.length)
{
func(txt, cls);
@ -318,16 +301,14 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
return spanHandler;
};
linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser)
{
linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser) {
var func = linestylefilter.getURLFilter(lineText, textAndClassFunc);
var hookFilters = hooks.callAll("aceGetFilterStack", {
linestylefilter: linestylefilter,
browser: abrowser
});
_.map(hookFilters ,function(hookFilter)
{
_.map(hookFilters ,function(hookFilter) {
func = hookFilter(lineText, func);
});
@ -343,8 +324,7 @@ linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser)
};
// 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
var text = textLine;
if (text.slice(-1) == '\n')
@ -352,8 +332,7 @@ linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj)
text = text.substring(0, text.length - 1);
}
function textAndClassFunc(tokenText, tokenClass)
{
function textAndClassFunc(tokenText, tokenClass) {
domLineObj.appendSpan(tokenText, tokenClass);
}

View File

@ -50,8 +50,7 @@ var hooks = require('./pluginfw/hooks');
var receivedClientVars = false;
function randomString()
{
function randomString() {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var string_length = 20;
var randomstring = '';
@ -85,8 +84,7 @@ var getParameters = [
{ 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..
for(var i = 0; i < getParameters.length; i++)
{
@ -113,8 +111,7 @@ function getParams()
}
}
function getUrlVars()
{
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
@ -126,8 +123,7 @@ function getUrlVars()
return vars;
}
function sendClientReady(isReconnect, messageType)
{
function sendClientReady(isReconnect, messageType) {
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1);
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);
}
function handshake()
{
function handshake() {
var loc = document.location;
//get the correct port
var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port;
@ -225,8 +220,7 @@ function handshake()
var initalized = false;
socket.on('message', function(obj)
{
socket.on('message', function(obj) {
//the access was not granted, give the user a message
if(obj.accessStatus)
{
@ -354,48 +348,37 @@ var pad = {
padOptions: {},
// these don't require init; clientVars should all go through here
getPadId: function()
{
getPadId: function() {
return clientVars.padId;
},
getClientIp: function()
{
getClientIp: function() {
return clientVars.clientIp;
},
getColorPalette: function()
{
getColorPalette: function() {
return clientVars.colorPalette;
},
getDisplayUserAgent: function()
{
getDisplayUserAgent: function() {
return padutils.uaDisplay(clientVars.userAgent);
},
getIsDebugEnabled: function()
{
getIsDebugEnabled: function() {
return clientVars.debugEnabled;
},
getPrivilege: function(name)
{
getPrivilege: function(name) {
return clientVars.accountPrivs[name];
},
getUserIsGuest: function()
{
getUserIsGuest: function() {
return clientVars.userIsGuest;
},
getUserId: function()
{
getUserId: function() {
return pad.myUserInfo.userId;
},
getUserName: function()
{
getUserName: function() {
return pad.myUserInfo.name;
},
userList: function()
{
userList: function() {
return paduserlist.users();
},
switchToPad: function(padId)
{
switchToPad: function(padId) {
var newHref = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId;
newHref = newHref[0];
@ -430,17 +413,14 @@ var pad = {
window.location.href = newHref;
}
},
sendClientMessage: function(msg)
{
sendClientMessage: function(msg) {
pad.collabClient.sendClientMessage(msg);
},
init: function()
{
init: function() {
padutils.setupGlobalExceptionHandler();
$(document).ready(function()
{
$(document).ready(function() {
// start the custom js
if (typeof customStart == "function") customStart();
handshake();
@ -451,8 +431,7 @@ var pad = {
padcookie.init();
});
},
_afterHandshake: function()
{
_afterHandshake: function() {
pad.clientTimeOffset = Date.now() - clientVars.serverTimestamp;
//initialize the chat
chat.init(this);
@ -514,11 +493,9 @@ var pad = {
$("#chatloadmessagesbutton").css("display", "none");
}
function postAceInit()
{
function postAceInit() {
padeditbar.init();
setTimeout(function()
{
setTimeout(function() {
padeditor.ace.focus();
}, 0);
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});
}
},
dispose: function()
{
dispose: function() {
padeditor.dispose();
},
notifyChangeName: function(newName)
{
notifyChangeName: function(newName) {
pad.myUserInfo.name = newName;
pad.collabClient.updateUserInfo(pad.myUserInfo);
},
notifyChangeColor: function(newColorId)
{
notifyChangeColor: function(newColorId) {
pad.myUserInfo.colorId = newColorId;
pad.collabClient.updateUserInfo(pad.myUserInfo);
},
changePadOption: function(key, value)
{
changePadOption: function(key, value) {
var options = {};
options[key] = value;
pad.handleOptionsChange(options);
@ -583,16 +556,14 @@ var pad = {
changedBy: pad.myUserInfo.name || "unnamed"
});
},
changeViewOption: function(key, value)
{
changeViewOption: function(key, value) {
var options = {
view: {}
};
options.view[key] = value;
pad.handleOptionsChange(options);
},
handleOptionsChange: function(opts)
{
handleOptionsChange: function(opts) {
// opts object is a full set of options or just
// some options to change
if (opts.view)
@ -614,17 +585,14 @@ var pad = {
pad.padOptions.guestPolicy = opts.guestPolicy;
}
},
getPadOptions: function()
{
getPadOptions: function() {
// caller shouldn't mutate the object
return pad.padOptions;
},
isPadPublic: function()
{
isPadPublic: function() {
return pad.getPadOptions().guestPolicy == 'allow';
},
suggestUserName: function(userId, name)
{
suggestUserName: function(userId, name) {
pad.collabClient.sendClientMessage(
{
type: 'suggestUserName',
@ -632,20 +600,16 @@ var pad = {
newName: name
});
},
handleUserJoin: function(userInfo)
{
handleUserJoin: function(userInfo) {
paduserlist.userJoinOrUpdate(userInfo);
},
handleUserUpdate: function(userInfo)
{
handleUserUpdate: function(userInfo) {
paduserlist.userJoinOrUpdate(userInfo);
},
handleUserLeave: function(userInfo)
{
handleUserLeave: function(userInfo) {
paduserlist.userLeave(userInfo);
},
handleClientMessage: function(msg)
{
handleClientMessage: function(msg) {
if (msg.type == 'suggestUserName')
{
if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name)
@ -673,8 +637,7 @@ var pad = {
paduserlist.removeGuestPrompt(msg.guestId);
}
},
dmesg: function(m)
{
dmesg: function(m) {
if (pad.getIsDebugEnabled())
{
var djs = $('#djs').get(0);
@ -686,14 +649,12 @@ var pad = {
}
}
},
handleServerMessage: function(m)
{
handleServerMessage: function(m) {
if (m.type == 'NOTICE')
{
if (m.text)
{
alertBar.displayMessage(function(abar)
{
alertBar.displayMessage(function(abar) {
abar.find("#servermsgdate").text(" (" + padutils.simpleDateTime(new Date) + ")");
abar.find("#servermsgtext").text(m.text);
});
@ -708,8 +669,7 @@ var pad = {
paduserlist.showGuestPrompt(m.userId, m.displayName);
}
},
handleChannelStateChange: function(newState, message)
{
handleChannelStateChange: function(newState, message) {
var oldFullyConnected = !! padconnectionstatus.isFullyConnected();
var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
if (newState == "CONNECTED")
@ -762,8 +722,7 @@ var pad = {
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
}
},
handleIsFullyConnected: function(isConnected, isInitialConnect)
{
handleIsFullyConnected: function(isConnected, isInitialConnect) {
pad.determineChatVisibility(isConnected && !isInitialConnect);
pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
pad.determineAuthorshipColorsVisibility();
@ -801,8 +760,7 @@ var pad = {
$('#options-colorscheck').prop("checked", false);
}
},
handleCollabAction: function(action)
{
handleCollabAction: function(action) {
if (action == "commitPerformed")
{
padeditbar.setSyncStatus("syncing");
@ -812,14 +770,11 @@ var pad = {
padeditbar.setSyncStatus("done");
}
},
hideServerMessage: function()
{
hideServerMessage: function() {
alertBar.hideMessage();
},
asyncSendDiagnosticInfo: function()
{
window.setTimeout(function()
{
asyncSendDiagnosticInfo: function() {
window.setTimeout(function() {
$.ajax(
{
type: 'post',
@ -827,15 +782,12 @@ var pad = {
data: {
diagnosticInfo: JSON.stringify(pad.diagnosticInfo)
},
success: function()
{},
error: function()
{}
success: function() {},
error: function() {}
});
}, 0);
},
forceReconnect: function()
{
forceReconnect: function() {
$('form#reconnectform input.padId').val(pad.getPadId());
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
$('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
@ -843,28 +795,22 @@ var pad = {
$('form#reconnectform').submit();
},
// 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));
},
callWhenNotCommitting: function(f)
{
callWhenNotCommitting: function(f) {
pad.collabClient.callWhenNotCommitting(f);
},
getCollabRevisionNumber: function()
{
getCollabRevisionNumber: function() {
return pad.collabClient.getCurrentRevisionNumber();
},
isFullyConnected: function()
{
isFullyConnected: function() {
return padconnectionstatus.isFullyConnected();
},
addHistoricalAuthors: function(data)
{
addHistoricalAuthors: function(data) {
if (!pad.collabClient)
{
window.setTimeout(function()
{
window.setTimeout(function() {
pad.addHistoricalAuthors(data);
}, 1000);
}
@ -875,13 +821,11 @@ var pad = {
}
};
var alertBar = (function()
{
var alertBar = (function() {
var animator = padutils.makeShowHideAnimator(arriveAtAnimationState, false, 25, 400);
function arriveAtAnimationState(state)
{
function arriveAtAnimationState(state) {
if (state == -1)
{
$("#alertbar").css('opacity', 0).css('display', 'block');
@ -905,13 +849,11 @@ var alertBar = (function()
}
var self = {
displayMessage: function(setupFunc)
{
displayMessage: function(setupFunc) {
animator.show();
setupFunc($("#alertbar"));
},
hideMessage: function()
{
hideMessage: function() {
animator.hide();
}
};

View File

@ -22,31 +22,26 @@
var padmodals = require('./pad_modals').padmodals;
var padconnectionstatus = (function()
{
var padconnectionstatus = (function() {
var status = {
what: 'connecting'
};
var self = {
init: function()
{
$('button#forcereconnect').click(function()
{
init: function() {
$('button#forcereconnect').click(function() {
window.location.reload();
});
},
connected: function()
{
connected: function() {
status = {
what: 'connected'
};
padmodals.showModal('connected');
padmodals.hideOverlay();
},
reconnecting: function()
{
reconnecting: function() {
status = {
what: 'reconnecting'
};
@ -54,8 +49,7 @@ var padconnectionstatus = (function()
padmodals.showModal('reconnecting');
padmodals.showOverlay();
},
disconnected: function(msg)
{
disconnected: function(msg) {
if(status.what == "disconnected")
return;
@ -89,12 +83,10 @@ var padconnectionstatus = (function()
padmodals.showModal(k);
padmodals.showOverlay();
},
isFullyConnected: function()
{
isFullyConnected: function() {
return status.what == 'connected';
},
getStatus: function()
{
getStatus: function() {
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 DONE = 100;
var state = DONE;
@ -92,8 +90,7 @@ var padeditbar = (function()
var T_START = -0.5;
var T_FADE = 1.0;
var T_GONE = 1.5;
var animator = padutils.makeAnimationScheduler(function()
{
var animator = padutils.makeAnimationScheduler(function() {
if (state == SYNCING || state == DONE)
{
return false;
@ -126,14 +123,12 @@ var padeditbar = (function()
}
}, step * 1000);
return {
syncing: function()
{
syncing: function() {
state = SYNCING;
$("#syncstatussyncing").css('display', 'block');
$("#syncstatusdone").css('display', 'none');
},
done: function()
{
done: function() {
state = T_START;
animator.scheduleAnimation();
}
@ -186,16 +181,13 @@ var padeditbar = (function()
$('#editbar').toggleClass('editor-scrolled', $(this).scrollTop() > 2);
})
},
isEnabled: function()
{
isEnabled: function() {
return true;
},
disable: function()
{
disable: function() {
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
},
enable: function()
{
enable: function() {
$('#editbar').addClass('enabledtoolbar').removeClass('disabledtoolbar');
},
commands: {},
@ -223,8 +215,7 @@ var padeditbar = (function()
}
if(padeditor.ace) padeditor.ace.focus();
},
toggleDropDown: function(moduleName, cb)
{
toggleDropDown: function(moduleName, cb) {
// do nothing if users are sticked
if (moduleName === "users" && $('#users').hasClass('stickyUsers')) {
return;
@ -284,8 +275,7 @@ var padeditbar = (function()
}
}
},
setSyncStatus: function(status)
{
setSyncStatus: function(status) {
if (status == "syncing")
{
syncAnimation.syncing();
@ -295,8 +285,7 @@ var padeditbar = (function()
syncAnimation.done();
}
},
setEmbedLinks: function()
{
setEmbedLinks: function() {
var padUrl = window.location.href.split("?")[0];
if ($('#readonlyinput').is(':checked'))
@ -313,8 +302,7 @@ var padeditbar = (function()
$('#linkinput').val(padUrl);
}
},
checkAllIconsAreDisplayedInToolbar: function()
{
checkAllIconsAreDisplayedInToolbar: function() {
// reset style
$('.toolbar').removeClass('cropped')
$('body').removeClass('mobile-layout');

View File

@ -24,8 +24,7 @@ const Cookies = require('./pad_utils').Cookies;
var padcookie = require('./pad_cookie').padcookie;
var padutils = require('./pad_utils').padutils;
var padeditor = (function()
{
var padeditor = (function() {
var Ace2Editor = undefined;
var pad = undefined;
var settings = undefined;
@ -34,14 +33,12 @@ var padeditor = (function()
ace: null,
// this is accessed directly from other files
viewZoom: 100,
init: function(readyFunc, initialViewOptions, _pad)
{
init: function(readyFunc, initialViewOptions, _pad) {
Ace2Editor = require('./ace').Ace2Editor;
pad = _pad;
settings = pad.settings;
function aceReady()
{
function aceReady() {
$("#editorloadingbox").hide();
if (readyFunc)
{
@ -62,24 +59,20 @@ var padeditor = (function()
// view bar
$("#viewbarcontents").show();
},
initViewOptions: function()
{
initViewOptions: function() {
// Line numbers
padutils.bindCheckboxChange($("#options-linenoscheck"), function()
{
padutils.bindCheckboxChange($("#options-linenoscheck"), function() {
pad.changeViewOption('showLineNumbers', padutils.getCheckbox($("#options-linenoscheck")));
});
// Author colors
padutils.bindCheckboxChange($("#options-colorscheck"), function()
{
padutils.bindCheckboxChange($("#options-colorscheck"), function() {
padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck"));
pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck"));
});
// Right to left
padutils.bindCheckboxChange($("#options-rtlcheck"), function()
{
padutils.bindCheckboxChange($("#options-rtlcheck"), function() {
pad.changeViewOption('rtlIsTrue', padutils.getCheckbox($("#options-rtlcheck")))
});
html10n.bind('localized', function() {
@ -88,8 +81,7 @@ var padeditor = (function()
})
// font family change
$("#viewfontmenu").change(function()
{
$("#viewfontmenu").change(function() {
pad.changeViewOption('padFontFamily', $("#viewfontmenu").val());
});
@ -113,10 +105,8 @@ var padeditor = (function()
window.html10n.localize([$("#languagemenu").val(), 'en']);
});
},
setViewOptions: function(newOptions)
{
function getOption(key, defaultValue)
{
setViewOptions: function(newOptions) {
function getOption(key, defaultValue) {
var value = String(newOptions[key]);
if (value == "true") return true;
if (value == "false") return false;
@ -146,31 +136,27 @@ var padeditor = (function()
self.ace.setProperty("textface", newOptions['padFontFamily'] || "");
},
dispose: function()
{
dispose: function() {
if (self.ace)
{
self.ace.destroy();
self.ace = null;
}
},
enable: function()
{
enable: function() {
if (self.ace)
{
self.ace.setEditable(true);
}
},
disable: function()
{
disable: function() {
if (self.ace)
{
self.ace.setProperty("grayedOut", true);
self.ace.setEditable(false);
}
},
restoreRevisionText: function(dataFromServer)
{
restoreRevisionText: function(dataFromServer) {
pad.addHistoricalAuthors(dataFromServer.historicalAuthorData);
self.ace.importAText(dataFromServer.atext, dataFromServer.apool, true);
}

View File

@ -20,35 +20,30 @@
* limitations under the License.
*/
var padimpexp = (function()
{
var padimpexp = (function() {
///// import
var currentImportTimer = null;
function addImportFrames()
{
function addImportFrames() {
$("#import .importframe").remove();
var iframe = $('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>');
$('#import').append(iframe);
}
function fileInputUpdated()
{
function fileInputUpdated() {
$('#importsubmitinput').addClass('throbbold');
$('#importformfilediv').addClass('importformenabled');
$('#importsubmitinput').removeAttr('disabled');
$('#importmessagefail').fadeOut('fast');
}
function fileInputSubmit()
{
function fileInputSubmit() {
$('#importmessagefail').fadeOut("fast");
var ret = window.confirm(html10n.get("pad.impexp.confirmimport"));
if (ret)
{
currentImportTimer = window.setTimeout(function()
{
currentImportTimer = window.setTimeout(function() {
if (!currentImportTimer)
{
return;
@ -62,8 +57,7 @@ var padimpexp = (function()
disabled: true
}).val(html10n.get("pad.impexp.importing"));
window.setTimeout(function()
{
window.setTimeout(function() {
$('#importfileinput').attr(
{
disabled: true
@ -75,16 +69,13 @@ var padimpexp = (function()
return ret;
}
function importFailed(msg)
{
function importFailed(msg) {
importErrorMessage(msg);
}
function importDone()
{
function importDone() {
$('#importsubmitinput').removeAttr('disabled').val(html10n.get("pad.impexp.importbutton"));
window.setTimeout(function()
{
window.setTimeout(function() {
$('#importfileinput').removeAttr('disabled');
}, 0);
$('#importstatusball').hide();
@ -92,8 +83,7 @@ var padimpexp = (function()
addImportFrames();
}
function importClearTimeout()
{
function importClearTimeout() {
if (currentImportTimer)
{
window.clearTimeout(currentImportTimer);
@ -101,8 +91,7 @@ var padimpexp = (function()
}
}
function importErrorMessage(status)
{
function importErrorMessage(status) {
var msg="";
if(status === "convertFailed"){
@ -117,16 +106,14 @@ var padimpexp = (function()
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")]();
}
if ($('#importexport .importmessage').is(':visible'))
{
$('#importmessagesuccess').fadeOut("fast");
$('#importmessagefail').fadeOut("fast", function()
{
$('#importmessagefail').fadeOut("fast", function() {
showError(true);
});
}
@ -136,8 +123,7 @@ var padimpexp = (function()
}
}
function importSuccessful(token)
{
function importSuccessful(token) {
$.ajax(
{
type: 'post',
@ -153,16 +139,14 @@ var padimpexp = (function()
addImportFrames();
}
function importApplicationFailed(xhr, textStatus, errorThrown)
{
function importApplicationFailed(xhr, textStatus, errorThrown) {
importErrorMessage("Error during conversion.");
importDone();
}
///// export
function cantExport()
{
function cantExport() {
var type = $(this);
if (type.hasClass("exporthrefpdf"))
{
@ -187,8 +171,7 @@ var padimpexp = (function()
/////
var pad = undefined;
var self = {
init: function(_pad)
{
init: function(_pad) {
pad = _pad;
//get /p/padname
@ -242,8 +225,7 @@ var padimpexp = (function()
$('#importform').unbind("submit").submit(fileInputSubmit);
$('.disabledexport').click(cantExport);
},
handleFrameCall: function(directDatabaseAccess, status)
{
handleFrameCall: function(directDatabaseAccess, status) {
if(directDatabaseAccess === "undefined") directDatabaseAccess = false;
if (status !== "ok")
{
@ -262,14 +244,12 @@ var padimpexp = (function()
importDone();
},
disable: function()
{
disable: function() {
$("#impexp-disabled-clickcatcher").show();
$("#import").css('opacity', 0.5);
$("#impexp-export").css('opacity', 0.5);
},
enable: function()
{
enable: function() {
$("#impexp-disabled-clickcatcher").hide();
$("#import").css('opacity', 1);
$("#impexp-export").css('opacity', 1);

View File

@ -23,16 +23,13 @@
var padeditbar = require('./pad_editbar').padeditbar;
var automaticReconnect = require('./pad_automatic_reconnect');
var padmodals = (function()
{
var padmodals = (function() {
var pad = undefined;
var self = {
init: function(_pad)
{
init: function(_pad) {
pad = _pad;
},
showModal: function(messageId)
{
showModal: function(messageId) {
padeditbar.toggleDropDown("none", function() {
$("#connectivity .visible").removeClass('visible');
$("#connectivity ."+messageId).addClass('visible');

View File

@ -30,17 +30,14 @@ var colorPickerSetup = false;
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
// their insertion, removal, and reordering. It manipulates TD height
// and TD opacity.
function nextRowId()
{
function nextRowId() {
return "usertr" + (nextRowId.counter++);
}
nextRowId.counter = 1;
@ -52,8 +49,7 @@ var paduserlist = (function()
var ANIMATION_END = 12; // just finishing fading out
function getAnimationHeight(step, power)
{
function getAnimationHeight(step, power) {
var a = Math.abs(step / 12);
if (power == 2) 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
// 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>';
}
function isNameEditable(data)
{
function isNameEditable(data) {
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);
if (isNameEditable(data) && tr.find("td.usertdname input:enabled").length > 0)
{
@ -104,8 +97,7 @@ var paduserlist = (function()
return tr;
}
function getUserRowHtml(height, data)
{
function getUserRowHtml(height, data) {
var nameHtml;
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('');
}
function getRowHtml(id, innerHtml, authorId)
{
function getRowHtml(id, innerHtml, authorId) {
return '<tr data-authorId="'+authorId+'" id="' + id + '">' + innerHtml + '</tr>';
}
function rowNode(row)
{
function rowNode(row) {
return $("#" + row.domId);
}
function handleRowData(row)
{
function handleRowData(row) {
if (row.data && row.data.status == 'Disconnected')
{
row.opacity = 0.5;
@ -141,13 +130,11 @@ var paduserlist = (function()
}
}
function handleRowNode(tr, data)
{
function handleRowNode(tr, data) {
if (data.titleText)
{
var titleText = data.titleText;
window.setTimeout(function()
{
window.setTimeout(function() {
/* tr.attr('title', titleText)*/
}, 0);
}
@ -157,11 +144,9 @@ var paduserlist = (function()
}
}
function handleOtherUserInputs()
{
function handleOtherUserInputs() {
// handle 'INPUT' elements for naming other unnamed users
$("#otheruserstable input.newinput").each(function()
{
$("#otheruserstable input.newinput").each(function() {
var input = $(this);
var tr = input.closest("tr");
if (tr.length > 0)
@ -179,8 +164,7 @@ var paduserlist = (function()
// 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));
animationPower = (animationPower === undefined ? 4 : animationPower);
@ -227,8 +211,7 @@ var paduserlist = (function()
return row;
}
function updateRow(position, data)
{
function updateRow(position, data) {
var row = rowsPresent[position];
if (row)
{
@ -245,8 +228,7 @@ var paduserlist = (function()
}
}
function removeRow(position, animationPower)
{
function removeRow(position, animationPower) {
animationPower = (animationPower === undefined ? 4 : animationPower);
var row = rowsPresent[position];
if (row)
@ -272,8 +254,7 @@ var paduserlist = (function()
// 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
var row = rowsPresent[oldPosition];
if (row && oldPosition != newPosition)
@ -284,8 +265,7 @@ var paduserlist = (function()
}
}
function animateStep()
{
function animateStep() {
// animation must be symmetrical
for (var i = rowsFadingIn.length - 1; i >= 0; i--)
{ // backwards to allow removal
@ -357,10 +337,8 @@ var paduserlist = (function()
var otherUsersInfo = [];
var otherUsersData = [];
function rowManagerMakeNameEditor(jnode, userId)
{
setUpEditable(jnode, function()
{
function rowManagerMakeNameEditor(jnode, userId) {
setUpEditable(jnode, function() {
var existingIndex = findExistingIndex(userId);
if (existingIndex >= 0)
{
@ -370,8 +348,7 @@ var paduserlist = (function()
{
return '';
}
}, function(newName)
{
}, function(newName) {
if (!newName)
{
jnode.addClass("editempty");
@ -385,8 +362,7 @@ var paduserlist = (function()
});
}
function findExistingIndex(userId)
{
function findExistingIndex(userId) {
var existingIndex = -1;
for (var i = 0; i < otherUsersInfo.length; i++)
{
@ -399,10 +375,8 @@ var paduserlist = (function()
return existingIndex;
}
function setUpEditable(jqueryNode, valueGetter, valueSetter)
{
jqueryNode.bind('focus', function(evt)
{
function setUpEditable(jqueryNode, valueGetter, valueSetter) {
jqueryNode.bind('focus', function(evt) {
var oldValue = valueGetter();
if (jqueryNode.val() !== oldValue)
{
@ -410,16 +384,13 @@ var paduserlist = (function()
}
jqueryNode.addClass("editactive").removeClass("editempty");
});
jqueryNode.bind('blur', function(evt)
{
jqueryNode.bind('blur', function(evt) {
var newValue = jqueryNode.removeClass("editactive").val();
valueSetter(newValue);
});
padutils.bindEnterAndEscape(jqueryNode, function onEnter()
{
padutils.bindEnterAndEscape(jqueryNode, function onEnter() {
jqueryNode.blur();
}, function onEscape()
{
}, function onEscape() {
jqueryNode.val(valueGetter()).blur();
});
jqueryNode.removeAttr('disabled').addClass('editable');
@ -429,8 +400,7 @@ var paduserlist = (function()
var guestPromptFlashState = 0;
var guestPromptFlash = padutils.makeAnimationScheduler(
function()
{
function() {
var prompts = $("#guestprompts .guestprompt");
if (prompts.length == 0)
{
@ -452,8 +422,7 @@ var paduserlist = (function()
var pad = undefined;
var self = {
init: function(myInitialUserInfo, _pad)
{
init: function(myInitialUserInfo, _pad) {
pad = _pad;
self.setMyUserInfo(myInitialUserInfo);
@ -465,17 +434,14 @@ var paduserlist = (function()
if (pad.getUserIsGuest())
{
$("#myusernameedit").addClass('myusernameedithoverable');
setUpEditable($("#myusernameedit"), function()
{
setUpEditable($("#myusernameedit"), function() {
return myUserInfo.name || '';
}, function(newValue)
{
}, function(newValue) {
myUserInfo.name = newValue;
pad.notifyChangeName(newValue);
// wrap with setTimeout to do later because we get
// a double "blur" fire in IE...
window.setTimeout(function()
{
window.setTimeout(function() {
self.renderMyUserInfo();
}, 0);
});
@ -483,23 +449,19 @@ var paduserlist = (function()
// color picker
$("#myswatchbox").click(showColorPicker);
$("#mycolorpicker .pickerswatchouter").click(function()
{
$("#mycolorpicker .pickerswatchouter").click(function() {
$("#mycolorpicker .pickerswatchouter").removeClass('picked');
$(this).addClass('picked');
});
$("#mycolorpickersave").click(function()
{
$("#mycolorpickersave").click(function() {
closeColorPicker(true);
});
$("#mycolorpickercancel").click(function()
{
$("#mycolorpickercancel").click(function() {
closeColorPicker(false);
});
//
},
usersOnline: function()
{
usersOnline: function() {
// 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
// Now we need to add ourselves..
@ -527,8 +489,7 @@ var paduserlist = (function()
}
return userList;
},
setMyUserInfo: function(info)
{
setMyUserInfo: function(info) {
//translate the colorId
if(typeof info.colorId == "number")
{
@ -540,8 +501,7 @@ var paduserlist = (function()
self.renderMyUserInfo();
},
userJoinOrUpdate: function(info)
{
userJoinOrUpdate: function(info) {
if ((!info.userId) || (info.userId == myUserInfo.userId))
{
// not sure how this would happen
@ -568,8 +528,7 @@ var paduserlist = (function()
{
numUsersBesides--;
}
var newIndex = padutils.binarySearch(numUsersBesides, function(n)
{
var newIndex = padutils.binarySearch(numUsersBesides, function(n) {
if (existingIndex >= 0 && n >= existingIndex)
{
// pretend existingIndex isn't there
@ -611,8 +570,7 @@ var paduserlist = (function()
self.updateNumberOfOnlineUsers();
},
updateNumberOfOnlineUsers: function()
{
updateNumberOfOnlineUsers: function() {
var online = 1; // you are always online!
for (var i = 0; i < otherUsersData.length; i++)
{
@ -626,8 +584,7 @@ var paduserlist = (function()
return online;
},
userLeave: function(info)
{
userLeave: function(info) {
var existingIndex = findExistingIndex(info.userId);
if (existingIndex >= 0)
{
@ -642,8 +599,7 @@ var paduserlist = (function()
// joins, or updates happen for this user in the
// next N seconds, to remove the user from the list.
var thisUserId = info.userId;
var thisLeaveTimer = window.setTimeout(function()
{
var thisLeaveTimer = window.setTimeout(function() {
var newExistingIndex = findExistingIndex(thisUserId);
if (newExistingIndex >= 0)
{
@ -664,8 +620,7 @@ var paduserlist = (function()
self.updateNumberOfOnlineUsers();
},
showGuestPrompt: function(userId, displayName)
{
showGuestPrompt: function(userId, displayName) {
if (knocksToIgnore[userId])
{
return;
@ -688,30 +643,25 @@ var paduserlist = (function()
// update display name
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);
});
window.setTimeout(hideLater, 15000); // time-out with no knock
guestPromptFlash.scheduleAnimation();
},
removeGuestPrompt: function(userId)
{
removeGuestPrompt: function(userId) {
var box = $("#guestprompt-" + padutils.encodeUserId(userId));
// 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();
});
knocksToIgnore[userId] = true;
window.setTimeout(function()
{
window.setTimeout(function() {
delete knocksToIgnore[userId];
}, 5000);
},
answerGuestPrompt: function(encodedUserId, approve)
{
answerGuestPrompt: function(encodedUserId, approve) {
var guestId = padutils.decodeUserId(encodedUserId);
var msg = {
@ -724,8 +674,7 @@ var paduserlist = (function()
self.removeGuestPrompt(guestId);
},
renderMyUserInfo: function()
{
renderMyUserInfo: function() {
if (myUserInfo.name)
{
$("#myusernameedit").removeClass("editempty").val(myUserInfo.name);
@ -757,14 +706,12 @@ var paduserlist = (function()
return self;
}());
function getColorPickerSwatchIndex(jnode)
{
function getColorPickerSwatchIndex(jnode) {
// return Number(jnode.get(0).className.match(/\bn([0-9]+)\b/)[1])-1;
return $("#colorpickerswatches li").index(jnode);
}
function closeColorPicker(accept)
{
function closeColorPicker(accept) {
if (accept)
{
var newColor = $("#mycolorpickerpreview").css("background-color");
@ -792,8 +739,7 @@ function closeColorPicker(accept)
$("#mycolorpicker").removeClass('popup-show');
}
function showColorPicker()
{
function showColorPicker() {
previousColorId = myUserInfo.colorId;
$.farbtastic('#colorpicker').setColor(myUserInfo.colorId)
@ -813,8 +759,7 @@ function showColorPicker()
li.appendTo(colorsList);
li.bind('click', function(event)
{
li.bind('click', function(event) {
$("#colorpickerswatches li").removeClass('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
*/
function randomString(len)
{
function randomString(len) {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var randomstring = '';
len = len || 20
@ -40,27 +39,22 @@ function randomString(len)
}
var padutils = {
escapeHtml: function(x)
{
escapeHtml: function(x) {
return Security.escapeHTML(String(x));
},
uniqueId: function()
{
uniqueId: function() {
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
// and taking rightmost digits
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('.');
},
uaDisplay: function(ua)
{
uaDisplay: function(ua) {
var m;
function clean(a)
{
function clean(a) {
var maxlen = 16;
a = a.replace(/[^a-zA-Z0-9\.]/g, '');
if (a.length > maxlen)
@ -70,8 +64,7 @@ var padutils = {
return a;
}
function checkver(name)
{
function checkver(name) {
var m = ua.match(RegExp(name + '\\/([\\d\\.]+)'));
if (m && m.length > 1)
{
@ -123,8 +116,7 @@ var padutils = {
return clean(x);
},
// 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 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()];
@ -133,8 +125,7 @@ var padutils = {
var hourmin = d.getHours() + ":" + ("0" + d.getMinutes()).slice(-2);
return dayOfWeek + ' ' + month + ' ' + dayOfMonth + ' ' + year + ' ' + hourmin;
},
findURLs: function(text)
{
findURLs: function(text) {
// 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_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], ...]
function _findURLs(text)
{
function _findURLs(text) {
_REGEX_URL.lastIndex = 0;
var urls = null;
var execResult;
@ -161,14 +151,12 @@ var padutils = {
return _findURLs(text);
},
escapeHtmlWithClickableLinks: function(text, target)
{
escapeHtmlWithClickableLinks: function(text, target) {
var idx = 0;
var pieces = [];
var urls = padutils.findURLs(text);
function advanceTo(i)
{
function advanceTo(i) {
if (i > idx)
{
pieces.push(Security.escapeHTML(text.substring(idx, i)));
@ -197,8 +185,7 @@ var padutils = {
advanceTo(text.length);
return pieces.join('');
},
bindEnterAndEscape: function(node, onEnter, onEscape)
{
bindEnterAndEscape: function(node, onEnter, onEscape) {
// Use keypress instead of keyup in bindEnterAndEscape
// 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).
if (onEnter)
{
node.keypress(function(evt)
{
node.keypress(function(evt) {
if (evt.which == 13)
{
onEnter(evt);
@ -217,8 +203,7 @@ var padutils = {
if (onEscape)
{
node.keydown(function(evt)
{
node.keydown(function(evt) {
if (evt.which == 27)
{
onEscape(evt);
@ -226,11 +211,9 @@ var padutils = {
});
}
},
timediff: function(d)
{
timediff: function(d) {
var pad = require('./pad').pad; // Sidestep circular dependency
function format(n, word)
{
function format(n, word) {
n = Math.round(n);
return ('' + n + ' ' + word + (n != 1 ? 's' : '') + ' ago');
}
@ -252,8 +235,7 @@ var padutils = {
d /= 24;
return format(d, 'day');
},
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce)
{
makeAnimationScheduler: function(funcToAnimateOneStep, stepTime, stepsAtOnce) {
if (stepsAtOnce === undefined)
{
stepsAtOnce = 1;
@ -261,12 +243,10 @@ var padutils = {
var animationTimer = null;
function scheduleAnimation()
{
function scheduleAnimation() {
if (!animationTimer)
{
animationTimer = window.setTimeout(function()
{
animationTimer = window.setTimeout(function() {
animationTimer = null;
var n = stepsAtOnce;
var moreToDo = true;
@ -287,23 +267,20 @@ var padutils = {
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 animationFrameDelay = 1000 / fps;
var animationStep = animationFrameDelay / totalMs;
var scheduleAnimation = padutils.makeAnimationScheduler(animateOneStep, animationFrameDelay).scheduleAnimation;
function doShow()
{
function doShow() {
animationState = -1;
funcToArriveAtState(animationState);
scheduleAnimation();
}
function doQuickShow()
{ // start showing without losing any fade-in progress
function doQuickShow() { // start showing without losing any fade-in progress
if (animationState < -1)
{
animationState = -1;
@ -316,8 +293,7 @@ var padutils = {
scheduleAnimation();
}
function doHide()
{
function doHide() {
if (animationState >= -1 && animationState <= 0)
{
animationState = 1e-6;
@ -325,8 +301,7 @@ var padutils = {
}
}
function animateOneStep()
{
function animateOneStep() {
if (animationState < -1 || animationState == 0)
{
return false;
@ -374,8 +349,7 @@ var padutils = {
},
_nextActionId: 1,
uncanceledActions: {},
getCancellableAction: function(actionType, actionFunc)
{
getCancellableAction: function(actionType, actionFunc) {
var o = padutils.uncanceledActions[actionType];
if (!o)
{
@ -384,8 +358,7 @@ var padutils = {
}
var actionId = (padutils._nextActionId++);
o[actionId] = true;
return function()
{
return function() {
var p = padutils.uncanceledActions[actionType];
if (p && p[actionId])
{
@ -393,8 +366,7 @@ var padutils = {
}
};
},
cancelActions: function(actionType)
{
cancelActions: function(actionType) {
var o = padutils.uncanceledActions[actionType];
if (o)
{
@ -402,25 +374,21 @@ var padutils = {
delete padutils.uncanceledActions[actionType];
}
},
makeFieldLabeledWhenEmpty: function(field, labelText)
{
makeFieldLabeledWhenEmpty: function(field, labelText) {
field = $(field);
function clear()
{
function clear() {
field.addClass('editempty');
field.val(labelText);
}
field.focus(function()
{
field.focus(function() {
if (field.hasClass('editempty'))
{
field.val('');
}
field.removeClass('editempty');
});
field.blur(function()
{
field.blur(function() {
if (!field.val())
{
clear();
@ -430,12 +398,10 @@ var padutils = {
clear: clear
};
},
getCheckbox: function(node)
{
getCheckbox: function(node) {
return $(node).is(':checked');
},
setCheckbox: function(node, value)
{
setCheckbox: function(node, value) {
if (value)
{
$(node).attr('checked', 'checked');
@ -445,22 +411,17 @@ var padutils = {
$(node).removeAttr('checked');
}
},
bindCheckboxChange: function(node, func)
{
bindCheckboxChange: function(node, func) {
$(node).change(func);
},
encodeUserId: function(userId)
{
return userId.replace(/[^a-y0-9]/g, function(c)
{
encodeUserId: function(userId) {
return userId.replace(/[^a-y0-9]/g, function(c) {
if (c == ".") return "-";
return 'z' + c.charCodeAt(0) + 'z';
});
},
decodeUserId: function(encodedUserId)
{
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc)
{
decodeUserId: function(encodedUserId) {
return encodedUserId.replace(/[a-y0-9]+|-|z.+?z/g, function(cc) {
if (cc == '-') return '.';
else if (cc.charAt(0) == 'z')
{

View File

@ -17,8 +17,7 @@ function Scroll(outerWin) {
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?
// And if so, do we need to scroll the editor, as defined on the settings.json?
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
// rep line on the top of the viewport
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
// 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.
Scroll.prototype._isCaretAtTheBottomOfViewport = function(rep)
{
Scroll.prototype._isCaretAtTheBottomOfViewport = function(rep) {
// computing a line position using getBoundingClientRect() is expensive.
// (obs: getBoundingClientRect() is called on caretPosition.getPosition())
// 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;
}
Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep)
{
Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep) {
var lineNode = rep.lines.atIndex(lineNumber);
var linePosition = this._getLineEntryTopBottom(lineNode);
var lineTop = linePosition.top;
@ -98,8 +94,7 @@ Scroll.prototype._isLinePartiallyVisibleOnViewport = function(lineNumber, rep)
(bottomOfLineIsAboveViewportBottom && bottomOfLineIsBelowViewportTop);
}
Scroll.prototype._getViewPortTopBottom = function()
{
Scroll.prototype._getViewPortTopBottom = function() {
var theTop = this.getScrollY();
var doc = this.doc;
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 editorPositionTop = editor[0].offsetTop;
return editorPositionTop;
}
// 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 aceOuterPaddingTop = parseInt($(aceOuter).css("padding-top"));
return aceOuterPaddingTop;
}
Scroll.prototype._getScrollXY = function()
{
Scroll.prototype._getScrollXY = function() {
var win = this.outerWin;
var odoc = this.doc;
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;
}
Scroll.prototype.getScrollY = function()
{
Scroll.prototype.getScrollY = function() {
return this._getScrollXY().y;
}
Scroll.prototype.setScrollX = function(x)
{
Scroll.prototype.setScrollX = function(x) {
this.outerWin.scrollTo(x, this.getScrollY());
}
Scroll.prototype.setScrollY = function(y)
{
Scroll.prototype.setScrollY = function(y) {
this.outerWin.scrollTo(this.getScrollX(), y);
}
Scroll.prototype.setScrollXY = function(x, y)
{
Scroll.prototype.setScrollXY = function(x, y) {
this.outerWin.scrollTo(x, y);
}
Scroll.prototype._isCaretAtTheTopOfViewport = function(rep)
{
Scroll.prototype._isCaretAtTheTopOfViewport = function(rep) {
var caretLine = rep.selStart[0];
var linePrevCaretLine = caretLine - 1;
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
// 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.
Scroll.prototype._getPixelsRelativeToPercentageOfViewport = function(innerHeight, aboveOfViewport)
{
Scroll.prototype._getPixelsRelativeToPercentageOfViewport = function(innerHeight, aboveOfViewport) {
var pixels = 0;
var scrollPercentageRelativeToViewport = this._getPercentageToScroll(aboveOfViewport);
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
// 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;
if(aboveOfViewport){
percentageToScroll = this.scrollSettings.percentage.editionAboveViewport;
@ -222,8 +206,7 @@ Scroll.prototype._getPercentageToScroll = function(aboveOfViewport)
return percentageToScroll;
}
Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight)
{
Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight) {
var pixels = 0;
var percentageToScrollUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
if(percentageToScrollUp > 0 && percentageToScrollUp <= 1){
@ -232,8 +215,7 @@ Scroll.prototype._getPixelsToScrollWhenUserPressesArrowUp = function(innerHeight
return pixels;
}
Scroll.prototype._scrollYPage = function(pixelsToScroll)
{
Scroll.prototype._scrollYPage = function(pixelsToScroll) {
var durationOfAnimationToShowFocusline = this.scrollSettings.duration;
if(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);
}
Scroll.prototype._scrollYPageWithAnimation = function(pixelsToScroll, durationOfAnimationToShowFocusline)
{
Scroll.prototype._scrollYPageWithAnimation = function(pixelsToScroll, durationOfAnimationToShowFocusline) {
var outerDocBody = this.doc.getElementById("outerdocbody");
// 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
// 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
$elem.stop("scrollanimation");
$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,
// besides of scrolling the minimum needed to be visible, it scrolls additionally
// (viewport height * scrollAmountWhenFocusLineIsOutOfViewport) pixels
Scroll.prototype.scrollNodeVerticallyIntoView = function(rep, innerHeight)
{
Scroll.prototype.scrollNodeVerticallyIntoView = function(rep, innerHeight) {
var viewport = this._getViewPortTopBottom();
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 line = rep.lines.atIndex(focusLine);
var linePosition = this._getLineEntryTopBottom(line);
@ -315,8 +292,7 @@ Scroll.prototype._partOfRepLineIsOutOfViewport = function(viewportPosition, rep)
return lineIsBelowOfViewport || lineIsAboveOfViewport;
}
Scroll.prototype._getLineEntryTopBottom = function(entry, destObj)
{
Scroll.prototype._getLineEntryTopBottom = function(entry, destObj) {
var dom = entry.lineNode;
var top = dom.offsetTop;
var height = dom.offsetHeight;
@ -326,24 +302,20 @@ Scroll.prototype._getLineEntryTopBottom = function(entry, destObj)
return obj;
}
Scroll.prototype._arrowUpWasPressedInTheFirstLineOfTheViewport = function(arrowUp, rep)
{
Scroll.prototype._arrowUpWasPressedInTheFirstLineOfTheViewport = function(arrowUp, rep) {
var percentageScrollArrowUp = this.scrollSettings.percentageToScrollWhenUserPressesArrowUp;
return percentageScrollArrowUp && arrowUp && this._isCaretAtTheTopOfViewport(rep);
}
Scroll.prototype.getVisibleLineRange = function(rep)
{
Scroll.prototype.getVisibleLineRange = function(rep) {
var viewport = this._getViewPortTopBottom();
//console.log("viewport top/bottom: %o", viewport);
var obj = {};
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;
});
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
// 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.
@ -354,13 +326,11 @@ Scroll.prototype.getVisibleLineRange = function(rep)
return [start, end - 1];
}
Scroll.prototype.getVisibleCharRange = function(rep)
{
Scroll.prototype.getVisibleCharRange = function(rep) {
var lineRange = this.getVisibleLineRange(rep);
return [rep.lines.offsetOfIndex(lineRange[0]), rep.lines.offsetOfIndex(lineRange[1])];
}
exports.init = function(outerWin)
{
exports.init = function(outerWin) {
return new Scroll(outerWin);
}

View File

@ -25,13 +25,11 @@ var Ace2Common = require('./ace2_common'),
var noop = Ace2Common.noop;
function SkipList()
{
function SkipList() {
var PROFILER = window.PROFILER;
if (!PROFILER)
{
PROFILER = function()
{
PROFILER = function() {
return {
start: noop,
mark: noop,
@ -71,8 +69,7 @@ function SkipList()
// this point.
function _getPoint(targetLoc)
{
function _getPoint(targetLoc) {
var numLevels = start.levels;
var lvl = numLevels - 1;
var i = -1,
@ -106,15 +103,13 @@ function SkipList()
idxs: idxs,
loc: targetLoc,
widthSkips: widthSkips,
toString: function()
{
toString: function() {
return "getPoint(" + targetLoc + ")";
}
};
}
function _getNodeAtOffset(targetOffset)
{
function _getNodeAtOffset(targetOffset) {
var i = 0;
var n = start;
var lvl = start.levels - 1;
@ -132,13 +127,11 @@ function SkipList()
return n;
}
function _entryWidth(e)
{
function _entryWidth(e) {
return (e && e.width) || 0;
}
function _insertKeyAtPoint(point, newKey, entry)
{
function _insertKeyAtPoint(point, newKey, entry) {
var p = PROFILER("insertKey", false);
var newNode = {
key: newKey,
@ -207,13 +200,11 @@ function SkipList()
p.end();
}
function _getNodeAtPoint(point)
{
function _getNodeAtPoint(point) {
return point.nodes[0].downPtrs[0];
}
function _incrementPoint(point)
{
function _incrementPoint(point) {
point.loc++;
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 elemWidth = _entryWidth(elem.entry);
for (var i = 0; i < point.nodes.length; i++)
@ -256,8 +246,7 @@ function SkipList()
totalWidth -= elemWidth;
}
function _propagateWidthChange(node)
{
function _propagateWidthChange(node) {
var oldWidth = node.downSkipWidths[0];
var newWidth = _entryWidth(node.entry);
var widthChange = newWidth - oldWidth;
@ -275,8 +264,7 @@ function SkipList()
totalWidth += widthChange;
}
function _getNodeIndex(node, byWidth)
{
function _getNodeIndex(node, byWidth) {
var dist = (byWidth ? 0 : -1);
var n = node;
while (n !== start)
@ -289,8 +277,7 @@ function SkipList()
return dist;
}
function _getNodeByKey(key)
{
function _getNodeByKey(key) {
return keyToNodeMap['$KEY$' + key];
}
@ -299,14 +286,12 @@ function SkipList()
// all truthy entries.
function _search(entryFunc)
{
function _search(entryFunc) {
var low = start;
var lvl = start.levels - 1;
var lowIndex = -1;
function f(node)
{
function f(node) {
if (node === start) return false;
else if (node === end) return true;
else return entryFunc(node.entry);
@ -331,19 +316,16 @@ that is a string.
*/
var self = this;
_.extend(this, {
length: function()
{
length: function() {
return numNodes;
},
atIndex: function(i)
{
atIndex: function(i) {
if (i < 0) console.warn("atIndex(" + i + ")");
if (i >= numNodes) console.warn("atIndex(" + i + ">=" + numNodes + ")");
return _getNodeAtPoint(_getPoint(i)).entry;
},
// 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 + deleteCount > numNodes)
{
@ -366,20 +348,16 @@ that is a string.
node.entry = entry;
}
},
next: function(entry)
{
next: function(entry) {
return _getNodeByKey(entry.key).downPtrs[0].entry || null;
},
prev: function(entry)
{
prev: function(entry) {
return _getNodeByKey(entry.key).upPtrs[0].entry || null;
},
push: function(entry)
{
push: function(entry) {
self.splice(numNodes, 0, [entry]);
},
slice: function(start, end)
{
slice: function(start, end) {
// act like Array.slice()
if (start === undefined) start = 0;
else if (start < 0) start += numNodes;
@ -402,68 +380,54 @@ that is a string.
}
return array;
},
atKey: function(key)
{
atKey: function(key) {
return _getNodeByKey(key).entry;
},
indexOfKey: function(key)
{
indexOfKey: function(key) {
return _getNodeIndex(_getNodeByKey(key));
},
indexOfEntry: function(entry)
{
indexOfEntry: function(entry) {
return self.indexOfKey(entry.key);
},
containsKey: function(key)
{
containsKey: function(key) {
return !!(_getNodeByKey(key));
},
// gets the last entry starting at or before the offset
atOffset: function(offset)
{
atOffset: function(offset) {
return _getNodeAtOffset(offset).entry;
},
keyAtOffset: function(offset)
{
keyAtOffset: function(offset) {
return self.atOffset(offset).key;
},
offsetOfKey: function(key)
{
offsetOfKey: function(key) {
return _getNodeIndex(_getNodeByKey(key), true);
},
offsetOfEntry: function(entry)
{
offsetOfEntry: function(entry) {
return self.offsetOfKey(entry.key);
},
setEntryWidth: function(entry, width)
{
setEntryWidth: function(entry, width) {
entry.width = width;
_propagateWidthChange(_getNodeByKey(entry.key));
},
totalWidth: function()
{
totalWidth: function() {
return totalWidth;
},
offsetOfIndex: function(i)
{
offsetOfIndex: function(i) {
if (i < 0) return 0;
if (i >= numNodes) return totalWidth;
return self.offsetOfEntry(self.atIndex(i));
},
indexOfOffset: function(offset)
{
indexOfOffset: function(offset) {
if (offset <= 0) return 0;
if (offset >= totalWidth) return numNodes;
return self.indexOfEntry(self.atOffset(offset));
},
search: function(entryFunc)
{
search: function(entryFunc) {
return _search(entryFunc);
},
//debugToString: _debugToString,
debugGetPoint: _getPoint,
debugDepth: function()
{
debugDepth: function() {
return start.levels;
}
});

View File

@ -31,8 +31,7 @@ var hooks = require('./pluginfw/hooks');
var token, padId, export_links;
function init() {
$(document).ready(function ()
{
$(document).ready(function () {
// start the custom js
if (typeof customStart == "function") customStart();
@ -63,19 +62,16 @@ function init() {
socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
//send the ready message once we're connected
socket.on('connect', function()
{
socket.on('connect', function() {
sendSocketMsg("CLIENT_READY", {});
});
socket.on('disconnect', function()
{
socket.on('disconnect', function() {
BroadcastSlider.showReconnectUI();
});
//route the incoming messages
socket.on('message', function(message)
{
socket.on('message', function(message) {
if(message.type == "CLIENT_VARS")
{
handleClientVars(message);
@ -91,8 +87,7 @@ function init() {
//get all the export links
export_links = $('#export > .exportlink')
$('button#forcereconnect').click(function()
{
$('button#forcereconnect').click(function() {
window.location.reload();
});
@ -104,8 +99,7 @@ function init() {
}
//sends a message over the socket
function sendSocketMsg(type, data)
{
function sendSocketMsg(type, data) {
socket.json.send({
component: 'pad', // FIXME: Remove this stupidity!
type,
@ -120,8 +114,7 @@ function sendSocketMsg(type, data)
var fireWhenAllScriptsAreLoaded = [];
var changesetLoader;
function handleClientVars(message)
{
function handleClientVars(message) {
//save the client Vars
clientVars = message.data;
@ -137,11 +130,9 @@ function handleClientVars(message)
var baseURI = document.location.pathname;
//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.each(function()
{
export_links.each(function() {
// Modified from regular expression to fix:
// https://github.com/ether/etherpad-lite/issues/4071
// Where a padId that was numeric would create the wrong export link

View File

@ -23,10 +23,8 @@
var Changeset = require('./Changeset');
var _ = require('./underscore');
var undoModule = (function()
{
var stack = (function()
{
var undoModule = (function() {
var stack = (function() {
var stackElements = [];
// two types of stackElements:
// 1) { elementType: UNDOABLE_EVENT, eventType: "anything", [backset: <changeset>,]
@ -38,8 +36,7 @@ var undoModule = (function()
var UNDOABLE_EVENT = "undoableEvent";
var EXTERNAL_CHANGE = "externalChange";
function clearStack()
{
function clearStack() {
stackElements.length = 0;
stackElements.push(
{
@ -50,8 +47,7 @@ var undoModule = (function()
}
clearStack();
function pushEvent(event)
{
function pushEvent(event) {
var e = _.extend(
{}, event);
e.elementType = UNDOABLE_EVENT;
@ -60,8 +56,7 @@ var undoModule = (function()
//dmesg("pushEvent backset: "+event.backset);
}
function pushExternalChange(cs)
{
function pushExternalChange(cs) {
var idx = stackElements.length - 1;
if (stackElements[idx].elementType == EXTERNAL_CHANGE)
{
@ -77,8 +72,7 @@ var undoModule = (function()
}
}
function _exposeEvent(nthFromTop)
{
function _exposeEvent(nthFromTop) {
// precond: 0 <= nthFromTop < numUndoableEvents
var targetIndex = stackElements.length - 1 - nthFromTop;
var idx = stackElements.length - 1;
@ -121,20 +115,17 @@ var undoModule = (function()
}
}
function getNthFromTop(n)
{
function getNthFromTop(n) {
// precond: 0 <= n < numEvents()
_exposeEvent(n);
return stackElements[stackElements.length - 1 - n];
}
function numEvents()
{
function numEvents() {
return numUndoableEvents;
}
function popEvent()
{
function popEvent() {
// precond: numEvents() > 0
_exposeEvent(0);
numUndoableEvents--;
@ -154,14 +145,12 @@ var undoModule = (function()
// invariant: stack always has at least one undoable event
var undoPtr = 0; // zero-index from top of stack, 0 == top
function clearHistory()
{
function clearHistory() {
stack.clearStack();
undoPtr = 0;
}
function _charOccurrences(str, c)
{
function _charOccurrences(str, c) {
var i = 0;
var count = 0;
while (i >= 0 && i < str.length)
@ -176,13 +165,11 @@ var undoModule = (function()
return count;
}
function _opcodeOccurrences(cs, opcode)
{
function _opcodeOccurrences(cs, opcode) {
return _charOccurrences(Changeset.unpack(cs).ops, opcode);
}
function _mergeChangesets(cs1, cs2)
{
function _mergeChangesets(cs1, cs2) {
if (!cs1) return cs2;
if (!cs2) return cs1;
@ -219,12 +206,10 @@ var undoModule = (function()
return null;
}
function reportEvent(event)
{
function reportEvent(event) {
var topEvent = stack.getNthFromTop(0);
function applySelectionToTop()
{
function applySelectionToTop() {
if ((typeof event.selStart) == "number")
{
topEvent.selStart = event.selStart;
@ -268,16 +253,14 @@ var undoModule = (function()
}
function reportExternalChange(changeset)
{
function reportExternalChange(changeset) {
if (changeset && !Changeset.isIdentity(changeset))
{
stack.pushExternalChange(changeset);
}
}
function _getSelectionInfo(event)
{
function _getSelectionInfo(event) {
if ((typeof event.selStart) != "number")
{
return null;
@ -298,8 +281,7 @@ var undoModule = (function()
// or can be called with no arguments to mean that no undo is possible.
// "eventFunc" will be called exactly once.
function performUndo(eventFunc)
{
function performUndo(eventFunc) {
if (undoPtr < stack.numEvents() - 1)
{
var backsetEvent = stack.getNthFromTop(undoPtr);
@ -311,8 +293,7 @@ var undoModule = (function()
else eventFunc();
}
function performRedo(eventFunc)
{
function performRedo(eventFunc) {
if (undoPtr >= 2)
{
var backsetEvent = stack.getNthFromTop(0);
@ -324,8 +305,7 @@ var undoModule = (function()
else eventFunc();
}
function getAPool()
{
function getAPool() {
return undoModule.apool;
}

View File

@ -1,5 +1,4 @@
function customStart()
{
function customStart() {
//define your javascript here
//jquery is available - except index.js
//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();
$('.buttonicon').mousedown(function() { $(this).parent().addClass('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 possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -98,8 +98,7 @@ var endPoint = function(point, version){
return '/api/'+version+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -101,8 +101,7 @@ var endPoint = function(point){
return '/api/'+apiVersion+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

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

View File

@ -140,8 +140,7 @@ var endPoint = function(point, version){
return '/api/'+version+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -361,8 +361,7 @@ var endPoint = function(point, version){
return `/api/${version}/${point}?apikey=${apiKey}`;
};
function makeid()
{
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -804,8 +804,7 @@ var endPoint = function(point, version){
return '/api/'+version+'/'+point+'?apikey='+apiKey;
}
function makeid()
{
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

View File

@ -289,8 +289,7 @@ const endPoint = function(point) {
return `/api/${apiVersion}/${point}?apikey=${apiKey}`;
};
function makeid()
{
function makeid() {
let text = '';
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 randomstring = '';
for (var i = 0; i < len; i++)

View File

@ -1,6 +1,5 @@
describe("embed links", function(){
var objectify = function (str)
{
var objectify = function (str) {
var hash = {};
var parts = str.split('&');
for(var i = 0; i < parts.length; i++)