
Всем привет! Вторая часть про миниатюрный javascript фреймворк Atom (бывший Nano).
Теперь из Core убрано всё лишнее, вес — 1 кб.
Как и прежде — полный отказ от устаревших браузеров.
Dom, Class, Ajax и т.п. — подключаются как плагины.
Поменялся адрес репозитария: github.com/theshock/atomjs
Под катом — расскажу, что нового и опишу, как создавать плагины
Более подробный api есть на ГитХабе
Core
В Core осталось самая малость — средство для расширения фреймворка, кое-какие полезные методы и расширения прототипов для совместимости с JavaScript 1.8.5
atom.extend, atom.implement
atom.extend
позволяет расширять объекты и сам Атом.atom.implement
позволяет расширять прототипы элементов и АтомаИменно этим методы используются для написания плагинов.
На текущий момент есть плагин для работы с Dom а-ля JQuery, плагин для создания классов похожий на тот, что в MooTools и наборосок плагина Ajax
Плагин Dom мало изменился со времени предыдущего топика, потому описывать не буду, а Ajax-плагин будет описан ниже, в виде примера плагина
Atom.Plugins.Class
Плагин Class немного похож на тот, который идёт в MooTools
Простое создание класса и наследования — достаточно простое:
var Animal = atom.Class({
constructor : function (name) {
this.name = name;
this.log('Animal.constructor');
},
walk : function () {
this.log('Animal.walk');
},
// Вы можете использовать геттеры и сеттеры
_name : 'default',
set name (name) {
this._name = name || 'anonymous';
},
get name () {
return this._name;
}
});
var Dog = atom.Class(Animal, {
constructor : function (name, breed) {
this.parent(name);
this.breed = breed;
this.log('Dog.constructor');
},
bark : function () {
return this.log('Dog.bark');
}
});
Но можно создавать не класс, а фабрику класса, которая может расширять его статичными свойствами и примесями:
var AnimalFactory = atom.Factory({
constructor : function (name, breed) {
this.name = name;
alert(this.self.staticProperty)
}
}).extend({
staticProperty : 123
}).mixin(MixClass1, MixClass2);
var animal = AnimalFactory.produce(['name', 'breed']);
Фабрику можно получить из класса, а класс из фабрики:
var AnimalFactory = atom.Factory({});
var Animal = AnimalFactory.get();
Animal.factory == AnimalFactory;
В общем, обычное такие классы как в JavaScript
Создание плагина, расширяем прототипы
Итак, часто необходимо расширить прототип встроенных объектов. Давайте расширим прототип стандартного Array, добавив туда, если еще нету, forEach, map и toArray в статическое свойство:
// safe позволяет расширять прототип только если таких свойств в нём еще нету
atom.implement(Array, 'safe', {
forEach : function (fn) {
for (var i = 0, l = this.length; i < l; i++) if (i in this) {
fn(this[i], i);
}
return this;
},
map : function (fn) {
var arr = [];
for (var i = 0, l = this.length; i < l; i++) if (i in this) {
arr[i] = fn(this[i], i);
}
return arr;
},
// это просто пример того, что вы можете использовать геттеры и сеттеры
get isEmpty () {
return !this.length;
}
});
atom.extend(Array, 'safe', {
toArray : function () {
return Array.prototype.slice.call(elem);
}
});
Создание полноценного Атом-плагина
(function () {
// Следует добавить информацию в список плагинов.
// Вместо true может быть версия плагина
atom.plugins['ajax'] = true;
// это будет atom.ajax(config)
var ajax = function (userConfig) {
// Настройки по-умолчанию
var config = atom.extend({
interval : 0,
type : 'plain',
method : 'post',
url : location.href,
onLoad : function(){},
onError : function(){}
}, userConfig);
// Вы ведь помните, что мы отказались от устаревших браузеров?
var req = new XMLHttpRequest();
req.onreadystatechange = ajax.onready;
req.open(config.method.toUpperCase(), config.url, true);
req.send(null);
};
// Использование отдельных методов позволит
// каждому программисту менять любую мелкую часть плагина
ajax.onready = function (e) {
if (req.readyState == 4) {
if (req.status != 200) return config.onError(e);
var result = req.responseText;
if (config.type.toLowerCase() == 'json') {
result = JSON.parse(result);
}
if (config.interval > 0) setTimeout(function () {
atom.ajax(config);
}, config.interval * 1000);
config.onLoad(result);
};
};
// Добавляем метод в Atom
atom.extend({ ajax : ajax });
})();
Теперь, если подключён Dom-плагин, можно расширить его методом, который будет получать данные с помощью ajax и загружать в текущий элемент.
// Добавляем метод в Atom
atom.extend({ ajax : ajax });
// Только если есть плагин Dom
if (atom.plugins['dom']) {
// В этот раз расширяем прототип
atom.implement({
ajax : function (config) {
config = extend({}, config);
// Обратите внимание, что коллбеки, которые передаст пользователь,
// будут вызваны в контексте элемента atom()
atom.ajax(extend(config, {
// При загрузке использовать или колбек пользователя
// или просто обновить содержимое элемента
onLoad : (config.onLoad || function (res) {
this.get().innerHTML = res;
}).bind(this),
onError : (config.onError || function(){}).bind(this)
}));
return this;
}
});
}
Как видите, ничего сложного)
PS
Я открыт для предложений, идей, коммитов) Сам развитие этого фреймворка не потяну, но если сообщество поддержит, то буду рад.