Pull to refresh

AtomJS — миниатюрный JavaScript фреймворк

Reading time 3 min
Views 15K

Всем привет! Вторая часть про миниатюрный 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


Я открыт для предложений, идей, коммитов) Сам развитие этого фреймворка не потяну, но если сообщество поддержит, то буду рад.
Tags:
Hubs:
+52
Comments 75
Comments Comments 75

Articles