[icon] 9
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
Фильтр френдов:Online Friends. Коммунити.
Мой жж:Tags.
You're looking at the latest 20 entries.
Missed some entries? Then simply jump back 20 entries

Tags:,
Subject:Очень уж маленькое поле для комментариев на хабре
Time:01:26 pm


Уж не знаю, неужели оно всех устраивает. Или же есть какая-то особая настройка в профиле, которая увеличивает высоту, и о которой только я не знаю? В общем, написал greasemonkey скрипт и теперь стало вот так:



Видимо, этого вполне хватит. Высота стала равна 120px. Возможно, более удобной будет какая-нибудь другая высота или в каких-нибудь других единицах измерения. Так же, вполне себе можно добавить вот такую штуку, как в Drupal'е:



Код )
comments: 5 comments or Leave a comment Add to Memories Tell a Friend

Tags:, , , ,
Current Music:Хочу перемен
Time:08:30 am
Сегодня ночью устроил трахи-трахи пытаясь объединить Google.Reader и bash.org.ru. Удалось^^. В ленту Google.Reader'а теперь добавляется быстрое голосование через ajax.

comments: 13 comments or Leave a comment Add to Memories Tell a Friend

Tags:, ,
Subject:GM_xmlhttpRequest и башорг
Time:04:13 am
Кусок кода из greasemonkey скрипта.
  GM_xmlhttpRequest({
    method: 'GET',
    url: 'http://bash.org.ru/quote/390892/rulez',
    onload: function(responseDetails) {
        // ... 
    }
  });
Он работает без ошибок, но рейтинг не увеличивается. Если ввести http://bash.org.ru/quote/390892/rulez в строке браузера и нажать [enter], то рейтинг тоже не увеличится. А если на странице http://bash.org.ru/quote/390892 нажать «+», то рейтинг увеличится. В чем дело? Почему GM_xmlhttpRequest не работает?

PS. XMLHttpRequest использовать не могу, т.к. greasemonkey-скрипт не для самого bash.org.ru, а для google.reader'а, т.е. cross-domain запрет работает здесь, как я понимаю.

Update: проблему удалось решить через sever-side скрипт, который подменяет Referer и обращается к башоргу по нужному адресу.
comments: 3 comments or Leave a comment Add to Memories Tell a Friend

Tags:,
Current Music:Lюк » Никотин
Subject:[опять шаблоны] Разделение html-шаблона и js-логики
Time:04:29 pm

Почитав thinking-about-markup, я озарился сделать аналогичную штуку для js и Jquery.

Пусть у нас будет такой html-шаблон:
<span id="ttt">AA</span>
Тогда, прикрутив такой js-шаблон:
at("#ttt").html("b");
Получим:
<span id="ttt">b</span>

Как же это работает?

Read more... )
comments: Leave a comment Add to Memories Tell a Friend

Tags:,
Current Music:Clint Mansell & Kronos Quartet - Summer: Coney Island Dreaming
Subject:outerHTML для Jquery
Time:02:12 pm
jQuery.fn.outer = function() {
  return $( $('<div></div>').html(this.clone()) ).html();
}
alert( $("#toolbar #save").outer() );
comments: Leave a comment Add to Memories Tell a Friend

Tags:
Subject:SXOOP.template
Time:01:42 pm

Еще один шаблонный движок для джаваскрипта. Отличается малым объемом кода и простотой (75 строк, вместе с комментариями). Простота, мало кода — это очень хорошо, надежно, в духе GR и XP. Шаблоны помещаются в скрытой <textarea>. В оригинале используются значки «[:» и «:]», но мне они не понравились, и я их изменил на «<%» и «%>».

Примеры шаблонов:
<ul>
  <% $_.map(function(el) { %>
    <%= include ("#li_tmpl", el) %>
  <% }) %>
</ul>
<li id="t<%= $_.id %>"><%= include ("#li-inside_tmpl", $_) %></li>
<span class='name'><%= $_.name %></span> <a href='javascript://' class='edit'>edit</a>
<% if ($_.notes) { %>
  <br /><span class='notes'><%= $_.notes %></span>
<% } %>
<% if ($_.tags) { %>
  <br /><span class='tags'>
    <% $_.tags.map(function(el, i, len) { %>
      <span class='tag'><%= db.tags.get(el) %></span><%= i+1<len? " ? " : "" %>
    <% }) %>
  </span><br />
<% } %>

javascript-templating-with-sxooptemplate

comments: Leave a comment Add to Memories Tell a Friend

Tags:
Subject:Beyond JS === ????
Time:02:10 pm

BeyondJS — это библиотека, которая… гм….

Приведу лучше пример кода. Простой такой примерчик. Звездочка двигается за курсором мышки особым образом.

Вот на обычном джаваскрипте:
if(!document.getElementById("doStar").checked) return;
var x = event.clientX;
var y = event.clientY;
setTimeout(function(){
  var angle = (new Date)/50;
  var star = document.getElementById("star");
  star.style.left = (30*Math.sin(angle))+x + "px";
  star.style.top  = (30*Math.cos(angle))+y + "px"; 
}, 1000);
А вот на Beyond JS:
Function.from("star", "moveTo").delay(1000).using(
    "+".using(
        Function.from(event, "x"), 
        "*".using(
            "radius",
            Function.from(Math, "sin", "angle")
        )
    ),
    "+".using(
        Function.from(event, "y"), 
        "*".using(
            "radius",
            Function.from(Math, "cos", "angle")
        )
    )
).curry({
    radius: 30,
    angle : function() {return (new Date)/50;}.asValue()
}).gate(
    Function.from("doStar".element(),"checked")
);

В библиотеку так же входит, например, beyondLazy — ленивые вычисления и ленивые списки.

В чем проблема? Не очень понятно что и как. Ну… я как-то не вижу документации. Кроме поста в la.ma.la ))) Но пост же на японском!! :)))

http://w3future.com/html/beyondJS/
http://la.ma.la/blog/diary_200508220821.htm

comments: 3 comments or Leave a comment Add to Memories Tell a Friend

Tags:
Current Music:Desimal - Fallen One
Subject:Dean Edwards / MiniWeb
Time:11:16 am
MiniWeb models an entire web site in a single HTML page. All of the site files are stored in a JSON object which you can navigate with a UNIX-like shell or the system browser. It has a built-in templating system and has an approximate separation of client and server
http://base2.googlecode.com/svn/trunk/src/apps/MiniWeb/MiniWeb.html

Я весьма впечатлен
comments: Leave a comment Add to Memories Tell a Friend

Tags:
Current Music:Serial Experiments Lain — Cloudy, with occasional rain
Subject:tmpl.js
Time:11:08 pm

Вдохновившись JKL.Hina, написал собственную шаблонную библиотечку. Они очень похожи, но есть и отличия. Теперь использую ее вместо jsonT. Под катом примеры работы.

Read more... )
comments: Leave a comment Add to Memories Tell a Friend

Tags:
Subject:DomQuery — A lightweight CSS Selector / Basic XPath implementation
Time:11:07 am
Нашел библиотеку DomQuery, которая, по результатам тестирования, в 3—10 раз быстрее Jquery. Более того, она легко расширяется. Круто! Вот бы еще поставлялась она независимо от extjs.
comments: 5 comments or Leave a comment Add to Memories Tell a Friend

Tags:
Current Music:Serial Experiments Lain — K I D s
Subject:JKL.Hina — template library for javascript
Time:09:43 pm

Нашел интересную библиотеку, JKL.Hina. Сразу буду на примерах кода показывать

var data = {
  title: "hello world",
  body: "Hina is yet another html template libraly for JavaScript."
};
В особом скрытом div'е у нас указан сам шаблон:
<h1>[/title]</h1>
<p>[/body]</p>
И преобразуется это, разумеется, в следующий код:
<h1>hello world</h1>
<p>Hina is yet another html template libraly for JavaScript.</p>
Можно использовать списки:
var data = {
  list1: [ 1, 2, 3 ]
};
<ul>
  <li title="@foreach i [/list1]">[/i]</li>
</ul>
И даже работать с объектами:
var data = {
  table1: [
    { name: "Ruby", author: "matz" },
    { name: "Perl", author: "Larry Wall" },
    { name: "Python", author: "Guido van Rossum" }
  ] 
};
<table border="1">
  <tr><th>name</th><th>author</th></tr>
  <tr title="@foreach line1 [/table1]">
    <td>[/line1/name]</td>
    <td>[/line1/author]</td>
  </tr>
</table>

Так же можно использовать условия (они, кстати, сделаны весьма интересно) и другие штуки.

В общем, довольно интересная библиотечка. Мне особенно понравился подход с аттрибутом title.

Вот только существует два затруднения: 1) она написана два года назад 2) она на японском %)

comments: 2 comments or Leave a comment Add to Memories Tell a Friend

Tags:
Subject:inline string format
Time:06:33 am
// 1
assertEqual("Hello, Pasha!",
    [{name: "Pasha", sign: "!", _: "Hello, {name}{sign}"}].map(function(el) {
        return el._.match(/\{.*?\}/ig).map(function(m) {
            el._ = el._.replace(eval('/'+m+'/ig'), el[m.replace(/^\{+|\}+$/g, "")]);
        }), el._;
    })
);
// 2
assertEqual("Hello, Pasha!",
    [{name: "Pasha", sign: "!", _: "Hello, {name}{sign}"}].map(function(el) {
        return el._.replace(/\{(.*?)\}/ig, function(w, g) {
            el._ = el._.replace(w, el[g]);
        }), el._;
    })
);
// 3
assertEqual("Hello, Pasha!",
    "Hello, {name}{sign}".replace(/\{(.*?)\}/ig, function(w, g) {
        return ({name: "Pasha", sign: "!"})[g];
    })
);

О реальной пользе такого подхода судить сложно, тем более, что принцип DRY никто не отменял. Но зато я сделал это без явных циклов и временных перменных))

upd: только что меня осенило третим вариантом. Он такой простой… Это просто смешно))

comments: Leave a comment Add to Memories Tell a Friend

Tags:,
Subject:Убиратель ненужного для jquery?
Time:07:46 pm
В mootools можно выбрать нужные компоненты, с ajs поставляется скрипт на питоне, который сканирует код и генерирует версию библиотеки…
Существует ли в природе нечто, позволяющее исключить из jquery неиспользуемые части?

Разумеется, это не вопрос первой необходимости. Все-таки jquery в упакованном виде весит 19 кб, но мне было бы приятно))
comments: Leave a comment Add to Memories Tell a Friend

Tags:,
Subject:The java vs k screencast in ruby… in javascript
Time:11:45 pm
Number.prototype.rand = function() {
  return Math.floor(Math.random()*this+1);
}
Number.prototype.to = function(to) {
    var array = [Number(this)];
    if (this < to) for (var i = this + 1; i <= to; ++i)    array.push(i);
    else for (var i = this - 1; i >= to; --i)    array.push(i);
    return array;
}
Number.prototype.times = function(callback) {
  if (typeof callback == 'string') callback = new Function('i', callback);
  for (var i = 0; i < this; i++) callback(i)
}

Array.prototype.map = Array.prototype.forEach = function(callback, thisObject) {
  if (typeof callback == 'string') callback = new Function('el', 'i', 'array', 'return ' + callback);
  var array = [];
  for (var i = 0, len = this.length; i < len; ++i)
    array.push(callback.call(thisObject, this[i], i, this));
  return array;
}
Array.prototype.filter = function(pred, thisObject) {
  if (typeof pred== 'string') pred= new Function('el', 'i', 'array', 'return ' + pred);
  var array = [];
  for (var i = 0, len = this.length, ret; i < len; ++i)
   if (pred.call(thisObject, this[i], i, this))
     array.push(this[i]);
  return array;
}
Array.prototype.foldRight = function(proc, seed) {
  for (var i = this.length - 1; i >= 0; --i) seed = proc.call(null, this[i], seed);
  return seed;
}
Array.prototype.deleteItem = function(item, eq, thisObject) {
  if (!eq) eq = function(x, y) { return x == y } 
    return this.remove(function(y) { return eq.call(null, item, y) }, thisObject);
}
Array.prototype.remove = function(pred, thisObject) {
  var array = [];
  for (var i = 0, len = this.length, ret; i < len; ++i)
    if (!pred.call(thisObject, this[i], i, this)) array.push(this[i]);
  return array;
}
Array.prototype.uniq = function(eq, thisObject) {
  return this.foldRight(function(item, array) { return [item].concat(array.deleteItem(item, eq, thisObject)) }, []);
}
people = 10;
days = 356;
bdays = 1 .to(people).map('days.rand()');
alert(bdays); // 151,264,286,135,17,34,266,108,135,274

collision = function(a) {
  return a.length != a.uniq().length;
}
alert(collision(bdays)); // true

collided = 0;

1000 .times("if ( collision(1 .to(people).map('days.rand()')) ) collided++");
alert(collided); // 112

alert(0 .to(1000).map("collision(1 .to(people).map('days.rand()'))")); 
// false, false, false, false, false, false, false, false, true, false, false, ...
alert(0 .to(1000).map("collision(1 .to(people).map('days.rand()'))").filter("!!el").length); // 110 alert(0 .to(1000).map("collision(1 .to(23).map('days.rand()'))").filter("!!el").length); // 499 alert(0 .to(1000).map("collision(1 .to(25).map('days.rand()'))").filter("!!el").length); // 570
Хотя в этом и нет смысла, но на javascript тоже можно так делать))
comments: 4 comments or Leave a comment Add to Memories Tell a Friend

Tags:,
Subject:[Javascript] Class-based & prototype-based
Time:08:52 pm
Class-based javascript (при помощи библиотеки AJS)
Animal = new AJS.Class({
  init: function(name) {
    this.name = name;
  }
});

amoeba = new Animal('Greenie');

Dog = Animal.extend({
  bark: function() {
    return this.name + " says woof!";
  }
});

lassie = new Dog('Lassie');
alert(lassie.bark()); // Lassie says woof!
Prototype-based javascript (при помощи своеобразной функции clone; один из способов)
Animal = clone({}, {}, {});
amoeba = clone(Animal, {name: 'Greenie'}, {});

Dog = clone(Animal, {}, {bark: 'this.name + " says woof!"'});
lassie = clone(Dog, {name: 'Lassie'}, {});
alert(lassie.bark()); // Lassie says woof!
function clone(myObj, members, gets){
  if(typeof(myObj) != 'object') return myObj;
  if(myObj == null) return myObj;
  var myNewObj = new Object();
  for(var i in myObj) myNewObj[i] = clone(myObj[i]);
  for(var i in members) myNewObj[i] = clone(members[i]);
  for(var i in gets) myNewObj[i] = new Function("return " + gets[i]);
  return myNewObj;
}
comments: Leave a comment Add to Memories Tell a Friend

Tags:,
Current Music:Bjцrk & Brodsky Quartet — Cowboy Lemmings
Subject:send("hello").to("Pasha");
Time:01:24 pm
send = function(msg)
{
  return {
    to: function(name){
      alert('"' + msg + '" to "' + name + '"');
    }
  }
}

send("hello").to("Pasha"); // "hello" to "Pasha"
PS. «Изобрел велосипед», блин)))

javascript 
functional 
comments: 6 comments or Leave a comment Add to Memories Tell a Friend

Tags:, ,
Time:10:25 pm
Итак, надо из двумерного массива с данными получить табличку.
var data = 
  [
    [null, 'name1', ['Р.', 'Бах']],
    [null, 'name2', ['В.', 'Бах']],
    [null, 'name3', ['Л.', 'Баг']],
    [null, 'name4', ['Р.', 'Бах']],  
  ]