Compare commits

...

10 Commits

Author SHA1 Message Date
John McLear 375ac50e14 docs w/ improved method 2016-03-26 11:03:51 +08:00
John McLear add21368f9 much cleaner 2016-03-26 11:00:00 +08:00
John McLear 1d1354e212 extend it further so it's exposed to DAM 2016-03-26 10:38:39 +08:00
John McLear 0e0d040108 removing this 2016-03-26 09:23:12 +08:00
John McLear 62be430203 extending get attribute on selection 2016-03-26 09:19:53 +08:00
John McLear 47f43e7094 bump ueber for a version that supports remove in couch 2016-03-25 07:41:52 +00:00
John McLear 3e2914831c remove sessions script 2016-03-25 07:33:27 +00:00
John McLear 459f252db9 notes 2016-03-24 14:32:17 +00:00
John McLear 7001b3b0c7 whee 2016-03-24 14:29:55 +00:00
John McLear f725e36523 a script to remove old pad data, needs full testing 2016-03-24 14:13:34 +00:00
6 changed files with 288 additions and 6 deletions

96
bin/removeOldPadData.js Normal file
View File

@ -0,0 +1,96 @@
/*
This is a debug tool. It removes old pad data from a non-dirty database
It also removes previous pad history so use it carefully.
*/
//get the padID
var padId = process.argv[2];
//initalize the variables
var db, settings, keys, values;
var npm = require("../src/node_modules/npm");
var async = require("../src/node_modules/async");
// Setup a removal count
var removalCount = 0;
async.series([
//load npm
function(callback) {
npm.load({}, function(er) {
callback(er);
})
},
//load modules
function(callback) {
settings = require('../src/node/utils/Settings');
db = require('../src/node/db/DB');
//intallize the database
db.init(callback);
},
//get the session info
function (callback){
db.db.findKeys("pad:*",null, function(err, dbkeys){
keys = dbkeys;
callback();
});
},
function (callback)
{
values = {};
async.eachSeries(keys, function(key, cb){
// only get main pad data not any revisions
if(key.indexOf(":revs") === -1){
db.db.get(key, function(err, value){
// console.log("get value", key, value);
values[key] = value;
cb();
});
}else{
cb();
}
}, function(){
callback();
});
},
// Removing all old pad data record
function (callback){
async.each(keys, function(key, cb){
if(key.indexOf(":revs") !== -1){
console.log("Removing", key);
db.db.remove(key, function(err){
removalCount++;
if(err) console.log("err", err);
cb();
});
}else{
cb();
}
}, function(){
callback();
});
},
// Add latest data back in for a pad
function (callback){
async.eachSeries(keys, function(key, cb){
var sauce = values[key];
if(key.indexOf(":revs") === -1){
// console.log("Adding data back in for", key, sauce);
db.db.set(key, values[key]);
}
cb();
}, function(){
callback();
});
}
], function (err)
{
if(err) throw err;
else{
console.log("finished, total database records removed "+removalCount);
process.exit(0);
}
});

87
bin/removeOldSessions.js Normal file
View File

@ -0,0 +1,87 @@
/*
This is a debug tool. It removes old sessions from a couch database
*/
/*
if(process.argv.length != 3)
{
console.error("Use: node bin/checkPad.js $PADID");
process.exit(1);
}
*/
//get the padID
var padId = process.argv[2];
//initalize the variables
var db, settings, keys, values;
var npm = require("../src/node_modules/npm");
var async = require("../src/node_modules/async");
async.series([
//load npm
function(callback) {
npm.load({}, function(er) {
callback(er);
})
},
//load modules
function(callback) {
settings = require('../src/node/utils/Settings');
db = require('../src/node/db/DB');
//intallize the database
db.init(callback);
},
//get the session info
function (callback){
db.db.findKeys("sessionstorage:*",null, function(err, dbkeys){
keys = dbkeys;
callback();
});
},
function (callback)
{
values = {};
async.eachSeries(keys, function(key, cb){
db.db.get(key, function(err, value){
// console.log("err", err);
// console.log("value", key, value);
values[key] = value;
cb();
});
}, function(){
callback();
});
},
// Removing a session record
function (callback){
async.each(keys, function(key, cb){
console.log("Removing", key);
db.db.remove(key, function(err){
if(err) console.log("err", err);
cb();
});
}, function(){
callback();
});
},
// Add latest data back in for a session
function (callback){
async.eachSeries(keys, function(key, cb){
console.log("Adding data back in for", key);
db.db.set(key, values[key]);
cb();
}, function(){
callback();
});
}
], function (err)
{
if(err) throw err;
else{
console.log("finished");
process.exit(0);
}
});

View File

@ -37,13 +37,20 @@ Returns the `rep` object.
## editorInfo.ace_isCaret(?)
## editorInfo.ace_getLineAndCharForPoint(?)
## editorInfo.ace_performDocumentApplyAttributesToCharRange(?)
## editorInfo.ace_setAttributeOnSelection(?)
## editorInfo.ace_setAttributeOnSelection(attribute, enabled)
Sets an attribute on current range.
Example: `call.editorInfo.ace_setAttributeOnSelection("turkey::balls", true); // turkey is the attribute here, balls is the value
Notes: to remove the attribute pass enabled as false
## editorInfo.ace_toggleAttributeOnSelection(?)
## editorInfo.ace_getAttributeOnSelection(attribute)
## editorInfo.ace_getAttributeOnSelection(attribute, prevChar)
Returns a boolean if an attribute exists on a selected range.
prevChar value should be true if you want to get the previous Character attribute instead of the current selection for example
if the caret is at position 0,1 (after first character) it's probable you want the attributes on the character at 0,0
The attribute should be the string name of the attribute applied to the selection IE subscript
Example usage: Apply the activeButton Class to a button if an attribute is on a highlighted/selected caret position or range.
Example: `call.editorInfo.ace_getAttributeOnSelection("subscript");` // call here is the callstack from aceEditEvent.
Example `var isItThere = documentAttributeManager.getAttributeOnSelection("turkey::balls", true);`
See the ep_subscript plugin for an example of this function in action.
Notes: Does not work on first or last character of a line. Suffers from a race condition if called with aceEditEvent.
## editorInfo.ace_performSelectionChange(?)

View File

@ -17,7 +17,7 @@
"etherpad-require-kernel" : "1.0.9",
"resolve" : "1.1.6",
"socket.io" : "1.3.7",
"ueberdb2" : "0.3.0",
"ueberdb2" : "0.3.1",
"express" : "4.12.3",
"express-session" : "1.11.1",
"cookie-parser" : "1.3.4",

View File

@ -178,6 +178,88 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
}
return [];
},
/*
Gets a given attribute on a selection
@param attributeName
@param prevChar
returns true or false if an attribute is visible in range
*/
getAttributeOnSelection: function(attributeName, prevChar){
var rep = this.rep;
if (!(rep.selStart && rep.selEnd)) return
// If we're looking for the caret attribute not the selection
// has the user already got a selection or is this purely a caret location?
var isNotSelection = (rep.selStart[0] == rep.selEnd[0] && rep.selEnd[1] === rep.selStart[1]);
if(isNotSelection){
if(prevChar){
// If it's not the start of the line
if(rep.selStart[1] !== 0){
rep.selStart[1]--;
}
}
}
var withIt = Changeset.makeAttribsString('+', [
[attributeName, 'true']
], rep.apool);
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
function hasIt(attribs)
{
return withItRegex.test(attribs);
}
return rangeHasAttrib(rep.selStart, rep.selEnd)
function rangeHasAttrib(selStart, selEnd) {
// if range is collapsed -> no attribs in range
if(selStart[1] == selEnd[1] && selStart[0] == selEnd[0]) return false
if(selStart[0] != selEnd[0]) { // -> More than one line selected
var hasAttrib = true
// from selStart to the end of the first line
hasAttrib = hasAttrib && rangeHasAttrib(selStart, [selStart[0], rep.lines.atIndex(selStart[0]).text.length])
// for all lines in between
for(var n=selStart[0]+1; n < selEnd[0]; n++) {
hasAttrib = hasAttrib && rangeHasAttrib([n, 0], [n, rep.lines.atIndex(n).text.length])
}
// for the last, potentially partial, line
hasAttrib = hasAttrib && rangeHasAttrib([selEnd[0], 0], [selEnd[0], selEnd[1]])
return hasAttrib
}
// Logic tells us we now have a range on a single line
var lineNum = selStart[0]
, start = selStart[1]
, end = selEnd[1]
, hasAttrib = true
// Iterate over attribs on this line
var opIter = Changeset.opIterator(rep.alines[lineNum])
, indexIntoLine = 0
while (opIter.hasNext()) {
var op = opIter.next();
var opStartInLine = indexIntoLine;
var opEndInLine = opStartInLine + op.chars;
if (!hasIt(op.attribs)) {
// does op overlap selection?
if (!(opEndInLine <= start || opStartInLine >= end)) {
hasAttrib = false; // since it's overlapping but hasn't got the attrib -> range hasn't got it
break;
}
}
indexIntoLine = opEndInLine;
}
return hasAttrib
}
},
/*
Gets all attributes at a position containing line number and column

View File

@ -2337,9 +2337,19 @@ function Ace2Inner(){
}
editorInfo.ace_setAttributeOnSelection = setAttributeOnSelection;
function getAttributeOnSelection(attributeName){
// Get the the attribute on selection
// prevChar tells the function if it needs to look at the previous character
function getAttributeOnSelection(attributeName, prevChar){
if (!(rep.selStart && rep.selEnd)) return
var isNotSelection = (rep.selStart[0] == rep.selEnd[0] && rep.selEnd[1] === rep.selStart[1]);
if(isNotSelection){
if(prevChar){
// If it's not the start of the line
if(rep.selStart[1] !== 0){
rep.selStart[1]--;
}
}
}
var withIt = Changeset.makeAttribsString('+', [
[attributeName, 'true']