Continue working on filters

This commit is contained in:
calzoneman 2013-06-18 11:51:42 -04:00
parent 25862acd72
commit 6eaa9a45d0
7 changed files with 201 additions and 61 deletions

View File

@ -1491,17 +1491,32 @@ Channel.prototype.tryToggleLock = function(user) {
this.setLock(this.openqueue); this.setLock(this.openqueue);
} }
Channel.prototype.tryRemoveFilter = function(user, f) {
if(!this.hasPermission(user, "filteredit"))
return false;
this.removeFilter(f);
}
Channel.prototype.removeFilter = function(filter) {
for(var i = 0; i < this.filters.length; i++) {
if(this.filters[i].name == filter.name) {
this.filters.splice(i, 1);
break;
}
}
this.broadcastChatFilters();
}
Channel.prototype.updateFilter = function(filter) { Channel.prototype.updateFilter = function(filter) {
if(filter.name == "")
filter.name = filter.source;
var found = false; var found = false;
for(var i = 0; i < this.filters.length; i++) { for(var i = 0; i < this.filters.length; i++) {
if(this.filters[i].name == "" && filter.name == "" if(this.filters[i].name == filter.name) {
&& this.filters[i].source == filter.source) {
found = true;
this.filters[i] = filter;
}
else if(filter.name != "" && this.filters[i].name == filter.name) {
found = true; found = true;
this.filters[i] = filter; this.filters[i] = filter;
break;
} }
} }
if(!found) { if(!found) {
@ -1510,45 +1525,45 @@ Channel.prototype.updateFilter = function(filter) {
this.broadcastChatFilters(); this.broadcastChatFilters();
} }
Channel.prototype.removeFilter = function(name, source) { Channel.prototype.tryUpdateFilter = function(user, f) {
for(var i = 0; i < this.filters.length; i++) {
if(this.filters[i].name == name
&& this.filters[i].source == source) {
this.filters.splice(i, 1);
break;
}
}
this.broadcastChatFilters();
}
Channel.prototype.tryChangeFilter = function(user, data) {
if(!this.hasPermission(user, "filteredit")) { if(!this.hasPermission(user, "filteredit")) {
return; return;
} }
if(data.cmd == undefined || data.filter == undefined) { var re = f.source;
var flags = f.flags;
try {
new RegExp(re, flags);
}
catch(e) {
return; return;
} }
var filter = new Filter(f.name, f.source, f.flags, f.replace);
filter.active = f.active;
filter.filterlinks = f.filterlinks;
this.updateFilter(filter);
}
if(data.cmd == "update") { Channel.prototype.moveFilter = function(data) {
var re = data.filter.source; if(data.from < 0 || data.to < 0 || data.from >= this.filters.length ||
var flags = data.filter.flags; data.to > this.filters.length) {
try { return;
new RegExp(re, flags);
}
catch(e) {
return;
}
var f = new Filter(data.filter.name,
data.filter.source,
data.filter.flags,
data.filter.replace);
f.active = data.filter.active;
this.updateFilter(f);
}
else if(data.cmd == "remove") {
this.removeFilter(data.filter.name, data.filter.source);
} }
var f = this.filters[data.from];
var to = data.to > data.from ? data.to + 1 : data.to;
var from = data.to > data.from ? data.from : data.from + 1;
this.filters.splice(to, 0, f);
this.filters.splice(from, 1);
this.broadcastChatFilters();
}
Channel.prototype.tryMoveFilter = function(user, data) {
if(!this.hasPermission(user, "filteredit"))
return;
if(typeof data.to !== "number" || typeof data.from !== "number")
return;
this.moveFilter(data);
} }
Channel.prototype.tryUpdatePermissions = function(user, perms) { Channel.prototype.tryUpdatePermissions = function(user, perms) {
@ -1676,6 +1691,11 @@ Channel.prototype.filterMessage = function(msg) {
for(var j = 0; j < subs.length; j++) { for(var j = 0; j < subs.length; j++) {
if(this.opts.enable_link_regex && subs[j].match(link)) { if(this.opts.enable_link_regex && subs[j].match(link)) {
subs[j] = subs[j].replace(link, "<a href=\"$1\" target=\"_blank\">$1</a>"); subs[j] = subs[j].replace(link, "<a href=\"$1\" target=\"_blank\">$1</a>");
for(var i = 0; i < this.filters.length; i++) {
if(!this.filters[i].filterlinks || !this.filters[i].active)
continue;
subs[j] = this.filters[i].filter(subs[j]);
}
continue; continue;
} }
for(var i = 0; i < this.filters.length; i++) { for(var i = 0; i < this.filters.length; i++) {

View File

@ -16,6 +16,7 @@ var Filter = function(name, regex, flags, replace) {
this.regex = new RegExp(this.source, this.flags); this.regex = new RegExp(this.source, this.flags);
this.replace = replace; this.replace = replace;
this.active = true; this.active = true;
this.filterlinks = false;
} }
Filter.prototype.pack = function() { Filter.prototype.pack = function() {
@ -24,7 +25,8 @@ Filter.prototype.pack = function() {
source: this.source, source: this.source,
flags: this.flags, flags: this.flags,
replace: this.replace, replace: this.replace,
active: this.active active: this.active,
filterlinks: this.filterlinks
} }
} }

16
user.js
View File

@ -367,9 +367,21 @@ User.prototype.initCallbacks = function() {
} }
}.bind(this)); }.bind(this));
this.socket.on("chatFilter", function(data) { this.socket.on("updateFilter", function(data) {
if(this.channel != null) { if(this.channel != null) {
this.channel.tryChangeFilter(this, data); this.channel.tryUpdateFilter(this, data);
}
}.bind(this));
this.socket.on("removeFilter", function(data) {
if(this.channel != null) {
this.channel.tryRemoveFilter(this, data);
}
}.bind(this));
this.socket.on("moveFilter", function(data) {
if(this.channel != null) {
this.channel.tryMoveFilter(this, data);
} }
}.bind(this)); }.bind(this));

View File

@ -154,7 +154,7 @@ html, body {
border-left: 0; border-left: 0;
} }
#messagebuffer div, #messagebuffer code { #messagebuffer div, #messagebuffer code, #filteredit code {
white-space: pre-wrap; /* css-3 */ white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */ white-space: -pre-wrap; /* Opera 4-6 */
@ -162,6 +162,10 @@ html, body {
word-wrap: break-word; /* Internet Explorer 5.5+ */ word-wrap: break-word; /* Internet Explorer 5.5+ */
} }
#filteredit td {
max-width: 200px;
}
.userlist_siteadmin { .userlist_siteadmin {
color: #cc0000; color: #cc0000;
font-weight: bold; font-weight: bold;

View File

@ -133,34 +133,133 @@ Callbacks = {
.appendTo($("<td/>").appendTo(tr)); .appendTo($("<td/>").appendTo(tr));
var linktd = $("<td/>").appendTo(tr); var linktd = $("<td/>").appendTo(tr);
var link = $("<input/>").attr("type", "checkbox") var link = $("<input/>").attr("type", "checkbox")
.prop("checked", false).appendTo(linktd); .prop("checked", f.filterlinks).appendTo(linktd);
var activetd = $("<td/>").appendTo(tr); var activetd = $("<td/>").appendTo(tr);
var active = $("<input/>").attr("type", "checkbox") var active = $("<input/>").attr("type", "checkbox")
.prop("checked", f.active).appendTo(activetd); .prop("checked", f.active).appendTo(activetd);
(function(f) {
regex.click(function() {
if(this.find(".filter-regex-edit").length > 0)
return;
var r = this.text();
this.text("");
var edit = $("<input/>").attr("type", "text")
.css("font-family", "Monospace")
.attr("placeholder", r)
.val(r)
.addClass("filter-regex-edit")
.appendTo(this)
.focus();
var remcallback = (function(filter) { return function() { function save() {
socket.emit("chatFilter", { var r = this.val();
cmd: "remove", var r2 = r;
filter: filter if(r.trim() == "")
}); r = this.attr("placeholder");
} })(f); this.parent().text(r);
remove.click(remcallback); f.source = r;
socket.emit("updateFilter", f);
}
edit.blur(save.bind(edit));
edit.keydown(function(ev) {
if(ev.keyCode == 13)
save.bind(edit)();
});
}.bind(regex));
flags.click(function() {
if(this.find(".filter-flags-edit").length > 0)
return;
var r = this.text();
this.text("");
var edit = $("<input/>").attr("type", "text")
.css("font-family", "Monospace")
.attr("placeholder", r)
.val(r)
.addClass("filter-flags-edit")
.appendTo(this)
.focus();
var actcallback = (function(filter) { return function() { function save() {
// Apparently when you check a checkbox, its value is changed var r = this.val();
// before this callback. When you uncheck it, its value is not var r2 = r;
// changed before this callback if(r.trim() == "")
// [](/amgic) r = this.attr("placeholder");
var enabled = active.prop("checked"); this.parent().text(r);
filter.active = (filter.active == enabled) ? !enabled : enabled; f.flags = r;
socket.emit("chatFilter", { socket.emit("updateFilter", f);
cmd: "update", }
filter: filter edit.blur(save.bind(edit));
edit.keydown(function(ev) {
if(ev.keyCode == 13)
save.bind(edit)();
});
}.bind(flags));
replace.click(function() {
if(this.find(".filter-replace-edit").length > 0)
return;
var r = this.text();
this.text("");
var edit = $("<input/>").attr("type", "text")
.css("font-family", "Monospace")
.attr("placeholder", r)
.val(r)
.addClass("filter-replace-edit")
.appendTo(this)
.focus();
function save() {
var r = this.val();
var r2 = r;
if(r.trim() == "")
r = this.attr("placeholder");
this.parent().text(r);
f.replace = r;
socket.emit("updateFilter", f);
}
edit.blur(save.bind(edit));
edit.keydown(function(ev) {
if(ev.keyCode == 13)
save.bind(edit)();
});
}.bind(replace));
remove.click(function() {
socket.emit("removeFilter", f);
}); });
} })(f);
active.click(actcallback); active.click(function() {
// Apparently when you check a checkbox, its value is changed
// before this callback. When you uncheck it, its value is not
// changed before this callback
// [](/amgic)
var enabled = active.prop("checked");
f.active = (f.active == enabled) ? !enabled : enabled;
socket.emit("updateFilter", f);
});
link.click(function() {
var enabled = link.prop("checked");
f.filterlinks = (f.filterlinks == enabled) ? !enabled : enabled;
socket.emit("updateFilter", f);
});
})(f);
} }
$(tbl.children()[1]).sortable({
start: function(ev, ui) {
FILTER_FROM = ui.item.prevAll().length;
},
update: function(ev, ui) {
FILTER_TO = ui.item.prevAll().length;
if(FILTER_TO != FILTER_FROM) {
socket.emit("moveFilter", {
from: FILTER_FROM,
to: FILTER_TO
});
console.log("moveFilter", FILTER_FROM, FILTER_TO);
}
}
});
var newfilt = $("<tr/>");//.appendTo(tbl); var newfilt = $("<tr/>");//.appendTo(tbl);
$("<td/>").appendTo(newfilt); $("<td/>").appendTo(newfilt);
var name = $("<input/>").attr("type", "text") var name = $("<input/>").attr("type", "text")

View File

@ -42,6 +42,8 @@ var SESSION = readCookie("cytube_session");
var LEADTMR = false; var LEADTMR = false;
var PL_FROM = 0; var PL_FROM = 0;
var PL_TO = 0; var PL_TO = 0;
var FILTER_FROM = 0;
var FILTER_TO = 0;
function getOrDefault(k, def) { function getOrDefault(k, def) {
var v = localStorage.getItem(k); var v = localStorage.getItem(k);

View File

@ -91,6 +91,7 @@
<button class="btn btn-primary" id="save_motd">Save</button> <button class="btn btn-primary" id="save_motd">Save</button>
</div> </div>
<div id="filteredit" class="span12"> <div id="filteredit" class="span12">
<p>Filters will be processed in the order that they are listed here. Click and drag a row to rearrange the order. Click a regex, flags, or replacement field to edit a filter. Changes are automatically saved when you finish editing.</p>
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>