/* --- Tags ---------------------------------------------------------------- */
/*
These are sorted unique tags. Each tag is mapped to the array of notes
tagged with it. A note is described with ID of the corresponding HTML element
having 'note' class.
We may use this associative array to perform some kind of optimization.
*/
Tags = {
"emacs":new Array(
"3078076044"
),
"Qt":new Array(
"3078076812"
),
"style guide":new Array(
"3078077068"
),
"win32":new Array(
"3078076940"
),
"XML":new Array(
"3078076556","3078077196"
),
"XML Schema":new Array(
"3078076556"
),
"XSLT":new Array(
"3078076172","3078077196"
),
"zvon.org":new Array(
"3078076172"
),
"валидатор":new Array(
"3078076556"
),
"веб-разработка":new Array(
"3078076428"
),
"вёрстка":new Array(
"3078076428"
),
"книга":new Array(
"3078076684"
),
"программирование":new Array(
"3078076812","3078076940"
),
"сайт":new Array(
"3078075884","3078076300","3078076556","3078076684","3078077196"
),
"софт":new Array(
"3078077324"
),
};
/* --- Utils ---------------------------------------------------------------- */
jQuery.fn.exists = function(fn){
var ret = false;
$(this).each(function(){
this.fn = fn; // 'this' must be available in 'fn'
if (this.fn()){
ret = true;
return false; // break from 'each'
}
});
return ret;
}
jQuery.fn.existsText = function(text){
return $(this).exists(function(){
return $(this).text() == text;
});
}
jQuery.fn.select = function(fn, callback){
$(this).each(function(){
this.fn = fn; // 'this' must be available in 'fn'
if (this.fn()){
this.callback = callback;
return this.callback(); // 'this' must be available in 'callback'
}
});
}
function array_remove(array, element){
for(i in array)
if (element == array[i])
array.splice(i, 1);
}
/* --- Cloud ---------------------------------------------------------------- */
var Cloud = new function(){
this.addTag = function(tag, size){
var code = "<a href='' class='note_tag tag_size_" + size + "'>" + tag + "</a> "
$("#all_tags").append(code);
tag_setClickHandler($("#all_tags > .note_tag").slice(-1));
// "#all_tags > .note_tag :last" does not work
if (size < 3){
$("#popular_tags").append("<a href='' class='note_tag tag_size_" + size + "'>" + tag + "</a> ");
tag_setClickHandler($("#popular_tags > .note_tag").slice(-1));
// "#popular_tags > .note_tag :last" does not work
}
}
this.recalculate = function(){
$("#all_tags .note_tag").remove();
$("#popular_tags .note_tag").remove();
var tags = new Object();
for (tag in Tags)
if (!Filter.isTagChosen(tag)){
tags[tag] = 0;
note_ids=Tags[tag]
for (index in note_ids)
if (document.getElementById(note_ids[index]).style.display != 'none')
tags[tag]++
}
var notesCount = $(".note:visible").length;
for (tag in Tags)
if (!Filter.isTagChosen(tag) && tags[tag] > 0) {
var _size = tags[tag] / notesCount;
if (_size > 0.05)
_size = 1;
else if (_size > 0.01)
_size = 2;
else
_size = 3;
this.addTag(tag, _size);
}
}
}();
/* --- Filter --------------------------------------------------------------- */
var Filter = new function(){
this.chosenTags = new Array();
this.isEmpty = function(){
return this.chosenTags.length == 0;
}
this.addTag = function(tag){
this.chosenTags.push(tag);
$("#chosen_tags").show();
$("#chosen_tags").append("<a href='' class='chosen_tag'>" + tag + "</a> ");
tag_setClickHandler($("#chosen_tags .chosen_tag").slice(-1));
// "#chosen_tags .chosen_tag :last" does not work
Notes.updateForSelectedTag(tag);
Cloud.recalculate();
}
this.removeTag = function(tag){
var jqueryTag = $("#chosen_tags .chosen_tag").select(
function(){
return $(this).text() == tag;
},
function(){
$(this).remove();
return false; // break (select only one)
}
);
array_remove(this.chosenTags, tag);
if (this.chosenTags.length == 0){
$("#chosen_tags").hide();
}
Notes.updateForDeselectedTag(tag);
Cloud.recalculate();
}
this.isTagChosen = function(tag){
return this.chosenTags.indexOf(tag) != -1;
}
}();
/* --- Notes ---------------------------------------------------------------- */
var Notes = new function(){
this.updateForSelectedTag = function(tag){
$(".note:visible").each(function(){
if (! $(this).find(".note_tag").existsText(tag)){
$(this).hide();
}
});
$(".note .note_tag").select(
function(){
return $(this).text() == tag;
},
function(){
$(this).addClass("chosen_tag");
}
);
}
this.updateForDeselectedTag = function(tag){
$(".note:hidden").each(function(){
var jqueryTags = $(this).find(".note_tag");
for (var i = 0; i < Filter.chosenTags.length; i++){
if (! jqueryTags.existsText(Filter.chosenTags[i])){
return;
}
}
$(this).show();
});
$(".note .note_tag").select(
function(){
return $(this).text() == tag;
},
function(){
$(this).removeClass("chosen_tag");
}
);
}
this.update = function(){
$(".note").each(function(){
var jqueryTags = $(this).find(".note_tag");
for (var i = 0; i < Filter.chosenTags.length; i++){
if (! jqueryTags.existsText(Filter.chosenTags[i])){
$(this).hide();
return;
}
}
$(this).show();
});
$(".note .note_tag").each(function(){
if (Filter.isTagChosen($(this).text())){
$(this).addClass("chosen_tag");
}
else{
$(this).removeClass("chosen_tag");
}
});
}
}();
/* --- Tag utils ------------------------------------------------------------ */
function tag_setClickHandler(jqueryTags){
jqueryTags.unbind("click").click(function(){
if ($(this).hasClass("chosen_tag")){
Filter.removeTag($(this).text());
}
else{
Filter.addTag($(this).text());
}
return false;
});
}
/* --- Startup -------------------------------------------------------------- */
$(document).ready(function(){
tag_setClickHandler($(".note_tag"));
Cloud.recalculate();
$("#toggle_tags").click(function(){
if (!$(this).hasClass("active_link")){
$("#toggle_popular_tags").removeClass("active_link");
$("#toggle_all_tags").removeClass("active_link");
$(this).addClass("active_link");
$("#all_tags").hide();
$("#popular_tags").hide();
}
return false;
});
$("#toggle_popular_tags").click(function(){
if (!$(this).hasClass("active_link")){
$("#toggle_tags").removeClass("active_link");
$("#toggle_all_tags").removeClass("active_link");
$(this).addClass("active_link");
$("#all_tags").hide();
$("#popular_tags").show();
}
return false;
});
$("#toggle_all_tags").click(function(){
if (!$(this).hasClass("active_link")){
$("#toggle_tags").removeClass("active_link");
$("#toggle_popular_tags").removeClass("active_link");
$(this).addClass("active_link");
$("#popular_tags").hide();
$("#all_tags").show();
}
return false;
});
});