├── .gitignore
├── .gitmodules
├── Docs
└── En
│ ├── Accessors.md
│ ├── Ajax.md
│ ├── Class
│ ├── Class.md
│ ├── Events.md
│ ├── Mutators
│ │ └── Generators.md
│ └── Options.md
│ ├── Cookie.md
│ ├── Core.md
│ ├── CoreExtended.md
│ ├── Declare
│ ├── Animatable.md
│ ├── Color.md
│ ├── Declare.md
│ ├── Events.md
│ ├── ImagePreloader.md
│ ├── Keyboard.md
│ ├── Settings.md
│ ├── Trace.md
│ ├── Transition.md
│ └── transition-graph.png
│ ├── Dom.md
│ ├── Frame.md
│ ├── PointerLock.md
│ ├── Prototypes
│ ├── Array.md
│ ├── Function.md
│ ├── Number.md
│ ├── Object.md
│ └── String.md
│ ├── Types
│ ├── Array.md
│ ├── Function.md
│ ├── Math.md
│ ├── Number.md
│ ├── Object.md
│ └── String.md
│ └── Uri.md
├── README.md
├── Source
├── Accessors.js
├── Ajax.Dom.js
├── Ajax.js
├── Class
│ ├── BindAll.js
│ ├── Class.js
│ ├── Events.js
│ ├── Generators.js
│ └── Options.js
├── Cookie.js
├── Core.js
├── CoreExtended.js
├── Declare
│ ├── Animatable.js
│ ├── ClassCompat.js
│ ├── Color.js
│ ├── Declare.js
│ ├── Events.js
│ ├── ImagePreloader.js
│ ├── Keyboard.js
│ ├── Registry.js
│ ├── Settings.js
│ ├── Trace.js
│ └── Transition.js
├── Dom.js
├── Frame.js
├── Js185.js
├── PointerLock.js
├── Prototypes
│ ├── Abstract.js
│ ├── Array.js
│ ├── Function.js
│ ├── Number.js
│ ├── Object.js
│ └── String.js
├── Types
│ ├── Array.js
│ ├── Function.js
│ ├── Math.js
│ ├── Number.js
│ ├── Object.js
│ └── String.js
├── Uri.js
├── atom.css
├── overall.js
└── package.yml
├── Tests
├── cells.png
├── index.html
├── lib
│ ├── jquery.js
│ ├── qunit.css
│ └── qunit.js
├── tests
│ ├── class.js
│ ├── color.js
│ ├── core.js
│ ├── declare.js
│ ├── dom.js
│ ├── mootools.js
│ ├── prototypes.js
│ └── uri.js
└── visual-tests.html
├── atom-full-compiled.js
└── build
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | *.iml
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Packager"]
2 | path = Packager
3 | url = git@github.com:theshock/packager.git
4 |
--------------------------------------------------------------------------------
/Docs/En/Accessors.md:
--------------------------------------------------------------------------------
1 | Atom Accessors
2 | ==============
3 |
4 | ## atom.accessors.has(object, prop)
5 |
6 | Checks if `object` has getter or setter for property `prop` as own property, or in prototype chain
7 |
8 | #### Example:
9 | var object = {
10 | set foo () {}
11 | };
12 |
13 | atom.accessors.has(object, 'foo'); // true
14 | atom.accessors.has(object, 'bar'); // false
15 |
16 | ## atom.accessors.define(object, prop, value)
17 |
18 | Defines setter or getter of `object` with name `prop`
19 |
20 | #### Example:
21 | var object = {};
22 |
23 | atom.accessors.define(object, 'foo', {
24 | set: function (value) { console.log('object.foo Setter'); )
25 | get: function () { console.log('object.foo Getter'); )
26 | });
27 |
28 | object.foo = 123; // object.foo Setter
29 | object.foo + 123; // object.foo Getter
30 |
31 | ## atom.accessors.lookup(object, prop)
32 |
33 | Get accessors from `object` with name `prop`
34 |
35 | #### Examples:
36 | var object = {
37 | set foo(value) { console.log('object.foo Setter'); ),
38 | get foo() { console.log('object.foo Getter'); ),
39 |
40 | bar: 123
41 | };
42 |
43 | console.log(atom.accessors.lookup(object, 'bar')); // null
44 |
45 | var accessors = atom.accessors.lookup(object, 'foo');
46 | /* accessors equals to object:
47 | * {
48 | * set: function (value) { console.log('object.foo Setter'); )
49 | * get: function () { console.log('object.foo Getter'); )
50 | * }
51 | */
52 |
53 | ## atom.accessors.inherit(from, to, prop)
54 | Inherit accessors from `from` to `to` with name `prop` and return `true`, or return `false`
55 |
56 | var Parent = {
57 | get foo() { return 'Parent.foo'; },
58 | bar: 'Parent.bar'
59 | };
60 |
61 | var Child = {};
62 |
63 | atom.accessors.inherit(Parent, Child, 'foo'); // true
64 | atom.accessors.inherit(Parent, Child, 'bar'); // false
65 |
66 | /* accessors equals to:
67 | * {
68 | * get foo() { return 'Parent.foo'; }
69 | * }
70 | */
--------------------------------------------------------------------------------
/Docs/En/Ajax.md:
--------------------------------------------------------------------------------
1 | Atom AJAX
2 | =========
3 |
4 | atom.ajax(config);
5 |
6 | #### Config parameters:
7 |
8 | * `interval`: 0. Repeat every `interval` seconds if it's greater than 0
9 | * `type`: `'plain'`. One of `'plain'` or `'json'` (response automatically parsed as JSON)
10 | * `method`: `'post'`. One of `'post'`, `'get'`, `'put'`, `'delete'`
11 | * `data`: `{}`.
12 | * `cache`: `false`. Disabling blowser cache: `cache:false`
13 | * `url`: `location.href`. Request url
14 | * `onLoad`: callback
15 | * `onError`: callback
16 |
17 | #### Example:
18 |
19 | atom.ajax({
20 | type : 'json',
21 | method : 'get',
22 | url : 'test.php',
23 | data : { 'hello': 'world' },
24 | cache : true,
25 | onLoad : function (json) {
26 | atom.log(json);
27 | },
28 | onError: function () {
29 | atom.log('error');
30 | }
31 | });
32 |
33 | **Note:** if you're declare `onLoad()` function, then you function will be override default `onLoad()` and response text will not be added, like he did it default.
34 |
35 | # Atom.Plugins.Ajax + Atom.Plugins.Dom
36 |
37 | atom.dom('#newMsgs').ajax({ // update html of #newMsgs
38 | interval : 15, // every 15 seconds
39 | url : 'newMsgs.php'
40 | });
41 |
--------------------------------------------------------------------------------
/Docs/En/Class/Class.md:
--------------------------------------------------------------------------------
1 | # atom.Class
2 |
3 | Wrapper for native prototype-based OOP
4 |
5 | ### Base class creating
6 | var NameLogger = atom.Class({
7 | log : function (msg) {
8 | atom.log(this.name, msg);
9 | return this;
10 | }
11 | });
12 |
13 | ### Class creating with constuctor, static variable
14 | var Animal = atom.Class({
15 | Extends: NameLogger,
16 | Static: {
17 | staticProperty: 'animal'
18 | },
19 | initialize : function (name) {
20 | this.name = name;
21 | this.log('Animal.initialize');
22 | },
23 | walk : function () {
24 | this.log('Animal.walk');
25 | }
26 | });
27 |
28 | ### Extending classes
29 | var Dog = atom.Class({
30 | Extends: Animal,
31 | initialize : function (name, breed) {
32 | this.parent(name);
33 | this.breed = breed;
34 | this.log('Dog.initialize');
35 | },
36 | bark : function () {
37 | return this.log('Dog.bark');
38 | },
39 | logStatic : function () {
40 | this.log(this.self.staticProperty);
41 | },
42 | isSelf : function () {
43 | return this instanceof this.self; // always true
44 | }
45 | });
46 |
47 | ### using
48 | var dog = new Dog('Box', 'shepherd');
49 | dog.bark();
50 | dog.walk();
51 | atom.log(dog instanceof Animal); // true
52 | atom.log(dog instanceof Dog); // true
53 |
54 | ### Factory method:
55 | var cat = Animal.factory(['Tom']);
56 | var dog = Dog.factory(['Max', 'dalmatian']);
57 |
58 | ### Invoking Class
59 | You can invoke your Class without `new`. As default it just creates new instance:
60 |
61 | var MyClass = atom.Class({});
62 |
63 | new MyClass(5, 42);
64 | // similar to
65 | MyClass(5, 42);
66 |
67 | But you can change this behaviour, changing Static method `invoke`:
68 |
69 | var MyClass = atom.Class({
70 | Static: {
71 | invoke: function (first, second) {
72 | alert( first + second );
73 | return this.factory( arguments );
74 | }
75 | }
76 | });
77 |
78 | // Just creates new instance:
79 | var mc = new MyClass(5, 42);
80 |
81 | // Alerts 47, than create instance
82 | var mc = MyClass(5, 42);
83 |
84 | You even can create width this way instances of another class:
85 |
86 | var Foo = atom.Class({});
87 |
88 | var Bar = atom.Class({
89 | Static: {
90 | invoke: function () {
91 | return Foo.factory( arguments );
92 | }
93 | }
94 | });
95 |
96 | var bar = new Bar();
97 | var foo = Bar();
98 |
99 | console.log(
100 | bar instanceof Bar, // true
101 | bar instanceof Foo, // false
102 | foo instanceof Bar, // false
103 | foo instanceof Foo // true
104 | );
105 |
106 | ### Properties
107 | `self` You can use property "self" to get the link to the class as in methods `logStatic` and `isSelf`
108 |
109 | `parent` You can use method `parent` to call method with the same name of the parent
110 |
111 | `factory` You can use static factory property to create instance of object with array of arguments
112 |
113 | new Point(3, 8);
114 | // equals to
115 | Point.factory([3, 8]);
116 |
117 | *note*: `self`, `parent` & `factory` are reserved properties and you can't override them
118 |
119 | ### Methods
120 | Available some methods helpers:
121 |
122 | `abstractMethod`, which thrown mistake if is not overriden
123 |
124 | `protectedMethod`, which can be called only with parents
125 |
126 | `hiddenMethod`, which not implemented in children (not equals to private)
127 |
128 | var MyClass = atom.Class({
129 | abstr: atom.Class.abstractMethod,
130 |
131 | initialize: atom.Class.hiddenMethod(function () {
132 | atom.log('initilize will not be implemented by children (hidden)');
133 | }),
134 |
135 | prot: atom.Class.protectedMethod(function() {
136 | atom.log('this is protected method');
137 | })
138 | });
139 |
140 | ### Accessors
141 | You can use accessors!
142 |
143 | var Foo = atom.Class({
144 | _bar: 0,
145 | set bar (value) {
146 | this._bar = value * 2;
147 | },
148 | get bar () {
149 | return 'Foo.bar: ' + this._bar;
150 | }
151 | });
152 |
153 | var foo = new Foo;
154 | foo.bar = 21;
155 | log(foo.bar); // 'Foo.bar: 42'
156 |
157 | ### Expanding prototype, no reset
158 | Unlike the MooTools we dont reset each object. So the objects are links in prototype:
159 |
160 | var MyClass = atom.Class({
161 | settings: {},
162 | initialize: function (width, height) {
163 | this.settings.width = width;
164 | this.settings.height = height;
165 | }
166 | });
167 |
168 | var small = new MyClass(100, 100);
169 | var big = new MyClass(555, 555);
170 |
171 | atom.log(small.settings. == big.settings); // true
172 | atom.log(small.settings.width, small.settings.height); // (555, 555)
173 |
174 | So, use constructor object creating instead:
175 |
176 | var MyClass = atom.Class({
177 | initialize: function (width, height) {
178 | this.settings = {};
179 | this.settings.width = width;
180 | this.settings.height = height;
181 | }
182 | });
183 |
184 | var small = new MyClass(100, 100);
185 | var big = new MyClass(555, 555);
186 |
187 | atom.log(small.settings. == big.settings); // false
188 | atom.log(small.settings.width, small.settings.height); // (100, 100), as expected
189 |
190 | # Default Mutators
191 |
192 | ### Static
193 | Let you to add static properties:
194 |
195 | MyClass = atom.Class({
196 | Static: {
197 | staticProperty: 15,
198 | staticMethod : function () { return 88; }
199 | }
200 | });
201 |
202 | atom.log(MyClass.staticProperty); // 15
203 | atom.log(MyClass.staticMethod()); // 88
204 |
205 | ### Extends
206 | Let you to extends one class from another. You can call `parent` to access method with same name of parent class.
207 | Unlimited nesting is available. Accessors are implemented, but you can't call `parent` from them
208 |
209 | var Foo = atom.Class({
210 | initialize: function () {
211 | log('Foo.initialize');
212 | },
213 | fooMethod: function () {
214 | log('Foo.fooMethod');
215 | },
216 | genMethod: function (arg) {
217 | log('genMethod: ' + arg);
218 | },
219 | get accessor () {
220 | return 100;
221 | }
222 | });
223 |
224 | var Bar = atom.Class({
225 | Extends: Foo,
226 | initialize: function () {
227 | this.parent(); // 'Foo.initialize'
228 | log('Bar.initialize');
229 | this.fooMethod(); // 'Foo.fooMethod'
230 | },
231 | genMethod: function () {
232 | this.parent(42); // 'genMethod: 42'
233 | alert(this.accessor); // 100
234 | }
235 | });
236 |
237 | var Qux = atom.Class({
238 | Extends: Bar,
239 | initialize: function () {
240 | this.parent(); // 'Foo.initialize', 'Bar.initialize'
241 | log('Qux.initialize');
242 | },
243 | get accessor () {
244 | return this.parent() + 1; // Error
245 | }
246 | });
247 |
248 | var foo = new Foo();
249 | var qux = new Qux();
250 |
251 | foo instanceof Foo; // true
252 | foo instanceof Qux; // false
253 |
254 | qux instanceof Foo; // true
255 | qux instanceof Qux; // true
256 |
257 | ### Implements
258 | Let you mixin properties from some classes. You can't access mixin properties using "parent"
259 |
260 | Bar = atom.Class({
261 | barMethod: function () {
262 | log('Bar.barMethod');
263 | }
264 | });
265 | Qux = atom.Class({
266 | quxMethod: function () {
267 | log('Qux.quxMethod');
268 | }
269 | });
270 |
271 | Foo = atom.Class({
272 | Implements: [ Bar, Qux ],
273 | fooMethod: function () {
274 | log('Foo.fooMethod');
275 | this.quxMethod(); // 'Qux.quxMethod'
276 | },
277 | barMethod: function () {
278 | this.parent(); // Error('The method «barMethod» has no parent.');
279 | }
280 | });
281 |
282 | var foo = new Foo;
283 | foo instanceof Foo; // true
284 | foo instanceof Bar; // false
285 | foo instanceof Qux; // false
286 |
287 |
--------------------------------------------------------------------------------
/Docs/En/Class/Events.md:
--------------------------------------------------------------------------------
1 | # atom.Class.Events
2 |
3 | Let you add and fire event, linked with current object
4 |
5 | #### method addEvent
6 | addEvent(string name, function fn)
7 |
8 | Using this method you can add events to eventable object
9 |
10 | #### method removeEvent
11 | removeEvent(string name, function fn)
12 |
13 | Using this method you can remove events from eventable object
14 |
15 | #### method fireEvent
16 | fireEvent(string name, array arguments)
17 |
18 | Using this method you can fire events in eventable object
19 |
20 | #### method readyEvent
21 | readyEvent(string name, array arguments)
22 |
23 | Using this method you can fire event in eventable object and automaticaly fire it on during all next "addEvent" (as image.onload)
24 |
25 | ### Base examples
26 |
27 | MyClass = atom.Class({
28 | Implements: [ atom.Class.Events ]
29 | });
30 |
31 | var my = new MyClass;
32 |
33 |
34 | // We listen 2 events:
35 | my.addEvent('foo', function ( firstArg ) {
36 | alert(firstArg);
37 | });
38 | my.addEvent('bar', atom.log);
39 |
40 | // event `foo` fired
41 | my.fireEvent('foo');
42 | // event `bar` fired
43 | my.fireEvent('bar');
44 |
45 | // we don't listen `bar` event now
46 | me.removeEvent('bar', atom.log);
47 |
48 | ### readyEvent examples
49 | readyEvent used for once runable events. E.g. it can be application initialize or image loaded
50 |
51 | Application = atom.Class({
52 | Implements: [ atom.Class.Events ],
53 | initialize: function (src) {
54 | this.image = new Image;
55 | this.image.onload = function () {
56 | this.readyEvent('ready');
57 | }.bind(this);
58 | this.image.src = src;
59 | }
60 | });
61 |
62 | var app = new Application('test');
63 | app.addEvent('ready', function () {
64 | alert('image loaded and application is ready');
65 | });
66 |
67 |
--------------------------------------------------------------------------------
/Docs/En/Class/Mutators/Generators.md:
--------------------------------------------------------------------------------
1 | # atom.Class.Mutators.Generators
2 |
3 | Used to DRY such pattern:
4 |
5 | MyClass = atom.Class({
6 | _property: null,
7 | get property () {
8 | if (this._property == null) {
9 | this._property = countValue();
10 | }
11 | return this._property;
12 | }
13 | });
14 |
15 | You can use Generators mutators instead (it will be counted only once):
16 |
17 | MyClass = atom.Class({
18 | Generators: {
19 | property: function () {
20 | return countValue();
21 | }
22 | }
23 | });
--------------------------------------------------------------------------------
/Docs/En/Class/Options.md:
--------------------------------------------------------------------------------
1 | # atom.Class.Options
2 |
3 | Let you add options property to your class
4 |
5 | MyClass = atom.Class({
6 | Implements: [ atom.Class.Options ],
7 | options : { // default options
8 | foo: 15,
9 | bar: 42
10 | }
11 | });
12 |
13 | var my = new MyClass();
14 |
15 | my.setOptions({
16 | foo: 3,
17 | qux: 100
18 | });
19 |
20 | atom.log(my.options); // {foo: 3, bar: 42, qux: 100}
21 |
22 | *note* never set options property, or one of the option directly. Always use `setOptions` for it.
23 |
24 | You can add several arguments to `setOptions`, which will be apply one-by-one
25 |
26 | MyClass = atom.Class({
27 | Implements: [ atom.Class.Options ]
28 | });
29 |
30 | var my = MyClass.factory();
31 | my.setOptions({ a: 15 }, { b: 33 });
32 | atom.log(my.options); // { a: 15, b: 33 };
33 |
34 | ### With events
35 |
36 | When class also implement `atom.Class.Events` - you can set events using `on*`
37 |
38 | MyClass = atom.Class({
39 | Implements: [
40 | atom.Class.Options,
41 | atom.Class.Events
42 | ]
43 | });
44 |
45 | var my = new MyClass;
46 |
47 | my.setOptions({
48 | onClick: atom.log
49 | });
50 |
51 | // equals to
52 |
53 | my.addEvent('click', atom.log);
--------------------------------------------------------------------------------
/Docs/En/Cookie.md:
--------------------------------------------------------------------------------
1 | Atom Cookie
2 | ===================
3 |
4 |
5 | ### atom.cookie.get(name)
6 | Returns value of cookie `name` or `null` if not exists
7 |
8 | var testCookie = atom.cookie.get('test');
9 |
10 | ### atom.cookie.set(name, value, options)
11 |
12 | Sets value of cookie, returns link to `atom.cookie`
13 |
14 | * `name` (*string*) cookie title
15 |
16 | * `value` (*string*) cookie value
17 |
18 | * `options` (*mixed*) additional options for cookie:
19 |
20 | * `expires` (*number|date*) Cookie expires, can be time in seconds, left to expire, or Date object
21 | * `path` (*string*) cookie path
22 | * `domain` (*string*) cookie domain
23 | * `secure` (*boolean*) secure connection
24 |
25 | #### example:
26 |
27 | atom.cookie
28 | .set('first' , 1)
29 | .set('second', 2);
30 |
31 |
32 | ### atom.cookie.del(name)
33 | Delete cookie with name `name` and returns `atom.cookie`
34 |
35 | atom.cookie
36 | .del('first')
37 | .del('second');
--------------------------------------------------------------------------------
/Docs/En/Core.md:
--------------------------------------------------------------------------------
1 | Atom Core
2 | =========
3 |
4 | * title: ore
5 | * group: core
6 |
7 |
8 | ## atom.core.isFunction(fn)
9 |
10 | Checks if `fn` is function
11 |
12 | if (atom.core.isFunction(object.method)) {
13 | object.method();
14 | }
15 |
16 | ## atom.core.objectize(key, value)
17 |
18 | If `key` is not object - returns object, where `key` is single key & `value` is value of this key.
19 | Else - returns `key`
20 |
21 | atom.core.objectize( 'test', 'foo' ); // { test: 'foo' )
22 | atom.core.objectize({ test: 'foo' }); // { test: 'foo' )
23 |
24 | Can be used, when you what to be sure, you works with object:
25 |
26 | method: function (callback, nameOrHash, value) {
27 | var hash = atom.core.objectize(nameOrHash, value);
28 | for (var i in hash) {
29 | // do
30 | }
31 | }
32 |
33 | ## atom.core.contains(array, value)
34 |
35 | Checks is array contains value. Is similar to `array.indexOf(value) != -1`
36 |
37 | if (atom.core.contains(['first', 'second'], value)) {
38 | // do smth
39 | }
40 |
41 | ## atom.core.includeUnique(array, value)
42 |
43 | Push `value` to `array` if it doesn't contains it;
44 |
45 | atom.core.includeUnique( [1,2,3], 1 ); // [1,2,3 ]
46 | atom.core.includeUnique( [1,2,3], 4 ); // [1,2,3,4]
47 |
48 | ## atom.core.eraseOne(array, value)
49 |
50 | Erase first `value` from `array`
51 |
52 | atom.core.eraseOne( [1,2,3,2,1], 2 ); // [1,3,2,1]
53 |
54 | ## atom.core.eraseAll(array, value)
55 |
56 | Erase all `value` from `array`
57 |
58 | atom.core.eraseAll( [1,2,3,2,1], 2 ); // [1,3,1]
59 |
60 | ## atom.core.toArray(arrayLikeObject)
61 |
62 | Cast `arrayLikeObject` (array, DomCollection, arguments) to `Array`
63 |
64 | var args = atom.core.toArray(arguments);
65 |
66 | ## atom.core.isArrayLike(object)
67 |
68 | Checks if `object` is arrayLike
69 |
70 | if (atom.core.isArrayLike(object)) {
71 | for (var i = 0; i < object.length; i++) {
72 | // do
73 | }
74 | }
75 |
76 | ## atom.core.append(target, source)
77 |
78 | Append all properties from sourceto target
79 |
80 | var target = { a: 1 };
81 | var source = { b: 2 };
82 | atom.core.append( target, source );
83 | console.log(target); // { a: 1, b: 2 }
84 |
85 |
86 |
87 |
88 | JavaScript 1.8.5 Compatiblity
89 | =============================
90 |
91 | Browsers, which do not have JavaScript 1.8.5 compatibility, will get those methods implemented:
92 |
93 | * [Function.prototype.bind](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind)
94 | * [Object.keys](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys)
95 | * [Array.isArray](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray)
96 |
--------------------------------------------------------------------------------
/Docs/En/CoreExtended.md:
--------------------------------------------------------------------------------
1 | Atom Extended Core
2 | ==================
3 |
4 | ## atom.extend(object = atom, from)
5 |
6 | Extend `object` with `from` properties.
7 |
8 | #### Example: config
9 | config = atom.core.extend({
10 | // default values for config
11 | a : 15,
12 | b : 20
13 | }, config);
14 |
15 | #### Example: extending atom
16 | atom.core.extend({
17 | value: 123
18 | });
19 | alert(atom.value); // 123
20 |
21 |
22 | ## atom.core.implement(object = atom, from)
23 |
24 | Extend `object.prototype` with `from` properties.
25 |
26 | #### Example: class extends
27 | atom.core.implement(child, parent);
28 |
29 | #### Example: expanding atom
30 | atom.core.implement({
31 | test: function () {
32 | alert(123);
33 | }
34 | });
35 | var a = atom();
36 | a.test(); // 123
37 |
38 | ## atom.clone(object)
39 | Returns clone of object
40 |
41 | var cloneArray = atom.core.clone(oldArray);
42 |
43 | ## atom.typeOf(object)
44 | Returns type of object:
45 |
46 | atom.core.typeOf( document.body ) == 'element'
47 | atom.core.typeOf( function(){} ) == 'function'
48 | atom.core.typeOf( new Date() ) == 'date'
49 | atom.core.typeOf( null ) == 'null'
50 | atom.core.typeOf( arguments ) == 'arguments'
51 | atom.core.typeOf( /abc/i ) == 'regexp'
52 | atom.core.typeOf( [] ) == 'array'
53 | atom.core.typeOf( {} ) == 'object'
54 | atom.core.typeOf( 15 ) == 'number'
55 | atom.core.typeOf( true ) == 'boolean'
56 |
57 | var MyClass = atom.Class({});
58 | atom.core.typeOf( new MyClass() ) == 'class'
--------------------------------------------------------------------------------
/Docs/En/Declare/Animatable.md:
--------------------------------------------------------------------------------
1 | atom.Animatable
2 | ===============
3 |
4 | `atom.Animatable` provides you the way to change properies of objects during time.
5 |
6 | var animatable = new atom.Animatable( targetObject );
7 |
8 | ### get current
9 |
10 | Contains current animation
11 |
12 | var currentAnimation = animatable.current;
13 |
14 | ### animate
15 |
16 | atom.Animatable.Animation animate( object config )
17 |
18 | Push new animation to stack & starts it when all previous animations will finish
19 |
20 | `Config` properies:
21 | * `props` - properies on object, you want to animate
22 | * `time` - time in seconds animation should continue
23 | * `fn` - `atom.Transition` method (`linear` is default)
24 | * `onTick` - callback, should be runned each property change
25 | * `onComplete` - callback, should be runned, when animation successfully complete
26 | * `onDestroy` - callback, should be runned, when animation complete
27 |
28 | First argument in callback is always `animation`
29 |
30 | ### stop
31 |
32 | atom.Animatable stop( boolean all )
33 |
34 | Stops current animation if `all=false` & all animations if `all=true`
35 |
36 | animatable.stop( true );
37 |
38 | atom.Animatable.Animation
39 | =========================
40 |
41 | Private class, which represents animation. It returns by `atom.Animatable#animate` & shouldn't be created manual
42 |
43 | var animation = animatable.animate(animateConfig);
44 |
45 | ### Properties:
46 |
47 | * `transition` - animation transition function
48 | * `initial` - values of properties, object contains on animation start
49 | * `target` - animation target values of properties
50 | * `delta` - difference between source & target values
51 | * `allTime` - time, which animation should continue
52 | * `timeLeft` - time, animation left to continue
53 |
54 | atom.dom.animate
55 | ================
56 |
57 | ### atom.dom().animate()
58 |
59 | Provides the way to animate dom properties
60 |
61 | atom.dom('div').animate({ width: 150 });
62 |
63 | ### atom.dom().stopAnimation(all)
64 |
65 | Stops current animation
66 |
67 | atom.dom('div').stopAnimation(true);
68 |
69 | atom.Color
70 | ==========
71 |
72 | You can animate colors if `atom.Color` class used.
73 |
74 | var object = { color: 'red' };
75 |
76 | new atom.Animatable( object ).animate({ color: 'blue' });
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Color.md:
--------------------------------------------------------------------------------
1 | atom.Color
2 | ==========
3 |
4 | `atom.Color` allows you to manipulate with colors.
5 |
6 | ## Own:
7 |
8 | ### colorNames
9 | Set of color names & hex values
10 |
11 | * `#ffffff` - white
12 | * `#c0c0c0` - silver
13 | * `#808080` - gray
14 | * `#000000` - black
15 | * `#ff0000` - red
16 | * `#800000` - maroon
17 | * `#ffff00` - yellow
18 | * `#808000` - olive
19 | * `#00ff00` - lime
20 | * `#008000` - green
21 | * `#00ffff` - aqua
22 | * `#008080` - teal
23 | * `#0000ff` - blue
24 | * `#000080` - navy
25 | * `#ff00ff` - fuchsia
26 | * `#800080` - purple
27 | * `#ffa500` - orange
28 |
29 | ### atom.Color.isColorString( string string );
30 | Checks if `string` is hex/rgba or color name
31 |
32 | atom.Color.isColorString( [42,0,13] ) // false
33 | atom.Color.isColorString( 'foobar' ) // false
34 | atom.Color.isColorString( '#dec0de' ) // true
35 | atom.Color.isColorString( 'red' ) // true
36 |
37 | ### random( bool html )
38 |
39 | Returns `atom.Color` instance with random color value.
40 | If `html` is `true` - gets value only from `colorNames`
41 |
42 | atom.Color.random().toString('hex'); // #61f405
43 |
44 | ## Prototype
45 |
46 | ### constructing
47 |
48 | var color = new atom.Color( value );
49 |
50 | Value can be array, object, string or number according to `from*` methods.
51 |
52 | ### from* methods
53 |
54 | #### fromArray( Array color )
55 | Sets values , parsing array as `[ red, green, blue, alpha=1 ]`, where `alpha` is optional
56 |
57 | color.fromArray([ 41, 55, 231, 0.5 ]);
58 |
59 |
60 | #### fromObject( Object color )
61 | Sets values from object keys `red, green, blue, alpha`
62 |
63 | color.fromObject({
64 | red : 14,
65 | green: 63,
66 | blue : 151,
67 | alpha: 0.5
68 | });
69 |
70 | #### fromString( String color )
71 | Parse valid (`true` in `atom.Color.isColorString`) string as color:
72 |
73 | color.fromString( '#dead13' );
74 | color.fromString( 'cyan' );
75 |
76 | #### fromNumber( Number number )
77 | Parse number as color string. Format is `0xRRGGBBAA`
78 |
79 | color.fromNumber( 0xDECODEFF );
80 |
81 | Note that color `0xFFFF00` is not yellow, because it equals to `0x00FFFF00` - cyan color with zero alpha. Correct yellow color is `0xFFFF00FF`
82 |
83 | ### to* methods
84 |
85 | #### toArray()
86 | Returns array `[red, green, blue, alpha]` of color. E.G.:
87 |
88 | console.log( new atom.Color('orange').toArray() ); // [255, 165, 0, 1]
89 |
90 | #### toObject(abbreviationNames)
91 | Returns object `{red, green, blue, alpha}` of color. E.G.:
92 |
93 | console.log( new atom.Color('orange').toObject() ); // {red:255, green:165, blue:0, alpha:1}
94 | console.log( new atom.Color('orange').toObject(true) ); // {r:255, g:165, b:0, a:1}
95 |
96 | #### toString(type)
97 | Returns string '#RRGGBB' is `type=='hex'` &t 'rgba(red, green, blue, alpha)' if hex otherwise
98 |
99 | console.log( new atom.Color('orange').toString() ); // 'rgba(255,165,0,1)'
100 | console.log( new atom.Color('orange').toString('hex') ); // '#ffa500'
101 |
102 | #### toNumber()
103 | Returns number
104 |
105 | console.log( new atom.Color('orange').toNumber() ); // 4289003775
106 | console.log( new atom.Color('orange').toNumber() == 0xffa500ff ); // true
107 |
108 |
109 | ### properties
110 |
111 | This properties can get or set values of color with checking limits
112 |
113 | * `red`
114 | * `green`
115 | * `blue`
116 | * `alpha`
117 |
118 | var color = new atom.Color('orange');
119 | color.red = -1000;
120 | color.blue = 1000;
121 | color.toArray(); // [0, 165, 255, 1]
122 |
123 | ### manipulations
124 |
125 | #### equals()
126 | Checks, if colors are similar.
127 |
128 | var a = new atom.Color('red');
129 | var b = new atom.Color('#ff0000');
130 |
131 | console.log( a == b ); // false
132 | console.log( a.equals(b) ); // true
133 |
134 | #### clone()
135 | Clones color
136 |
137 | var a = new atom.Color('red');
138 | var b = a.clone();
139 |
140 | console.log( a == b ); // false
141 | console.log( a.equals(b) ); // true
142 |
143 | b.green = 150;
144 |
145 | console.log( a.equals(b) ); // false
146 |
147 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Declare.md:
--------------------------------------------------------------------------------
1 | atom.declare
2 | ============
3 |
4 | Light and fast wrapper for native prototype-based OOP.
5 |
6 | Function atom.declare( String declareName = null, Function parent = null, Object params = null )
7 | Function atom.declare( Object params )
8 |
9 | Each argument is optional. Returns constructor that can be called with "new".
10 |
11 | #### Example:
12 |
13 | var Foo = atom.declare({
14 | fooMethod: function () {}
15 | });
16 |
17 | var Bar = atom.declare( Foo );
18 |
19 | ### params
20 |
21 | `params` object without `prototype` property is recognized as `prototype`, otherwise it is parsed with the following rules:
22 |
23 | * `name` - name of the resulting constructor and instances. Can be used for debugging, and is returned by `toString` method
24 |
25 | var C = atom.declare({
26 | name: 'FooQux',
27 | prototype: {}
28 | });
29 | console.log( new C().toString() ); // '[object FooQux]'
30 |
31 | * `declareName` - property created by library. Can be used for easy namespace creation. It will automaticaly create all nessesary objects
32 |
33 | atom.declare({
34 | declareName: 'Foo.Qux.Bar',
35 | name: 'FQB',
36 | prototype: {}
37 | });
38 | console.log( new Foo.Qux.Bar().toString() ); // '[object FQB]'
39 |
40 | * `prototype` - with object will be mixed to constructor prototype
41 |
42 | var Foo = atom.declare({
43 | prototype: {
44 | fooMethod: function () {
45 | return 'Foo#fooMethod';
46 | }
47 | }
48 | });
49 |
50 | console.log( new Foo().fooMethod() ); // 'Foo#fooMethod'
51 |
52 | * `parent` - this constructor will be parent of result constructor
53 |
54 | var Foo = atom.declare({
55 | prototype: {
56 | fooMethod: function () {
57 | return 'Foo#fooMethod';
58 | }
59 | }
60 | });
61 | var Bar = atom.declare({
62 | parent: Foo,
63 |
64 | prototype: {
65 | barMethod: function () {
66 | return 'Bar#barMethod';
67 | }
68 | }
69 | });
70 |
71 | var foo = new Foo();
72 | var bar = new Bar();
73 |
74 | console.log( foo instanceof Foo ); // true
75 | console.log( foo instanceof Bar ); // false
76 | console.log( bar instanceof Foo ); // true
77 | console.log( bar instanceof Bar ); // true
78 |
79 | console.log( foo.fooMethod() ); // 'Foo#fooMethod'
80 | console.log( bar.fooMethod() ); // 'Foo#fooMethod'
81 | console.log( bar.barMethod() ); // 'Bar#barMethod'
82 |
83 | * `own` - this properties will be mixed to constructor as static:
84 |
85 | var Foo = atom.declare({
86 |
87 | own: { fooProp: 'foo-static-prop' },
88 | prototype: {}
89 | });
90 |
91 | var Bar = atom.declare({
92 | parent: Foo,
93 | own: { barProp: 'bar-static-prop' },
94 | prototype: { }
95 | });
96 |
97 | console.log( Foo.fooProp ); // 'foo-static-prop'
98 | console.log( Bar.fooProp ); // 'foo-static-prop'
99 | console.log( Bar.barProp ); // 'bar-static-prop'
100 |
101 | ### alternate constructor params
102 |
103 | You can use alternate optional constructor params.
104 |
105 | Function atom.declare( String declareName = null, Function parent = null, Object params = null )
106 |
107 | * `declareName` - will set `name` & `declareName` of original params, so:
108 |
109 | atom.declare( 'Foo.Bar', {
110 | prototype: { test: 1241 }
111 | });
112 |
113 | // equals to:
114 |
115 | atom.declare({
116 | declareName: 'Foo.Bar',
117 | name: 'Foo.Bar',
118 | prototype: { test: 1241 }
119 | });
120 |
121 | * `parent` - will set `parent` of original params, so:
122 |
123 | atom.declare( Foo );
124 |
125 | // equals to:
126 |
127 | atom.declare({
128 | parent: Foo,
129 | prototype: {}
130 | });
131 |
132 | Also, you can skip `prototype` property in `params` if you want `params` to be `prototype`:
133 |
134 | atom.declare({
135 | prototype: {
136 | foo: 123,
137 | bar: function () {
138 | return this.foo;
139 | }
140 | }
141 | });
142 |
143 | // equals to:
144 |
145 | atom.declare({
146 | foo: 123,
147 | bar: function () {
148 | return this.foo;
149 | }
150 | });
151 |
152 | That's why if you want empty `prototype` - you should set it manualy:
153 |
154 | // wrong way:
155 | atom.declare({
156 | own: {/* static methods here */}
157 | });
158 | // it equals to:
159 | atom.declare({
160 | prototype: {
161 | own: {/* static methods here */}
162 | }
163 | });
164 | // right way:
165 | atom.declare({
166 | own: {/* static methods here */},
167 | prototype: {}
168 | });
169 |
170 | ### static methods of result constructor:
171 |
172 | * `own` - will mixin properties as static to constructor:
173 |
174 | var Foo = atom.declare({});
175 | Foo.own({ a: 123 });
176 | console.log( Foo.a ); // 123
177 |
178 | * `factory` - will produce object from array of params. It can be used, if you want to construct object from array (as `.apply` method of function):
179 |
180 | Foo.factory( [42, 'string', {test: null}] )
181 | // equals to:
182 | new Foo(42, 'string', {test: null});
183 |
184 | ### initialize
185 |
186 | `initialize` method in prototype will be called on instance construction:
187 |
188 | var Foo = atom.declare({
189 | initialize: function (id) {
190 | console.log( 'Foo#initialize', id );
191 | this.id = id;
192 | }
193 | });
194 |
195 | var foo = new Foo(42); // Foo#initialize 42
196 | console.log( foo.id ); // 42
197 |
198 | ### extended methods
199 |
200 | Library mixin two properties to your methods - `path` & `previous` (if exists). You can access to them by named function:
201 |
202 | atom.declare( 'Foo', {
203 | method: function YOUR_NAME_HERE () {
204 | // use YOUR_NAME_HERE.%property%
205 | }
206 | });
207 |
208 | Such way is fast & easy for debug.
209 |
210 | `path` property shows full path to method & can be used for logging:
211 |
212 | atom.declare( 'Foo.Bar', {
213 | testPathProperty: function method () {
214 | console.log( 'Invoke: ', method.path, arguments );
215 | }
216 | });
217 |
218 | new Foo.Bar().testPathProperty(); // Invoke: Foo.Bar#testPathProperty [13, 42]
219 |
220 | `previous` can be used for calling parent method. It contains link to method, that way previous with that name or null. You should call it with manual context set using `.call` or `.apply`
221 |
222 | atom.declare( 'Foo', {
223 | testPrevious: function method (arg) {
224 | console.log( method.path, arg );
225 | }
226 | });
227 |
228 | atom.declare( 'Bar', Foo, {
229 | testPrevious: function method (arg) {
230 | method.previous.call(this, arg);
231 | console.log( method.path, arg );
232 | method.previous.call(this, 95612);
233 | }
234 | });
235 |
236 | new Bar().testPrevious(42);
237 | /* Foo#testPrevious 42
238 | * Bar#testPrevious 42
239 | * Foo#testPrevious 95612
240 | */
241 |
242 | Use `previous` property carefull - calling without `.call(this)` will provide wrong context & calling `null` property will throw an error:
243 |
244 |
245 | atom.declare( 'Fail', {
246 | testPrevious: function method () {
247 | method.previous.call(this);
248 | }
249 | });
250 |
251 | new Fail().testPrevious(); // TypeError: Cannot call method 'call' of undefined
252 |
253 |
254 |
255 |
256 |
257 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Events.md:
--------------------------------------------------------------------------------
1 | atom.Events
2 | ===========
3 |
4 | `atom.Events` is class, which provides easy events manipulations
5 |
6 | var events = new atom.Events();
7 |
8 | ### add
9 |
10 | `add` - add callback for event.
11 |
12 | atom.Events add( string name, function callback );
13 |
14 | #### example:
15 |
16 | events.add( 'activate', function () {
17 | console.log( 'activate event fired' );
18 | });
19 |
20 | #### returns `this`
21 |
22 | ### remove
23 |
24 | `remove` - remove callback, binded for event.
25 |
26 | atom.Events remove( string name, function callback );
27 |
28 | #### example:
29 |
30 | function listenActivate () {
31 | console.log( 'activate event fired' );
32 | }
33 |
34 | events.add( 'activate', listenActivate );
35 |
36 | // event now
37 | events.remove( 'activate', listenActivate );
38 |
39 | #### returns `this`
40 |
41 | ### add/remove alternate:
42 |
43 | `add` & `remove` callbacks can be called with different arguments. `name` argument can be array, so we can bind or unbind for several events with one callback
44 |
45 | events.add( [ 'rotate', 'move' ], function () {
46 | console.log( 'position changed' );
47 | });
48 |
49 | instead of two arguments we can send object of arguments, where key will be name & value will be callback:
50 |
51 | events.add({
52 | rotate: function () { console.log('rotated') },
53 | move : function () { console.log('moved') },
54 | });
55 |
56 | ### exists
57 |
58 | `exists` checks if someone binded for event.
59 |
60 | events.add( 'complete', onComplete );
61 | console.log(
62 | events.exists('comlete'), // true
63 | events.exists('error') // false
64 | );
65 |
66 | ### fire
67 |
68 | atom.Events fire( string name, Array arguments );
69 |
70 | `fire` invokes all callback, that was binded for that name.
71 |
72 | events.add( 'foo', function (arg) { console.log(13, arg) });
73 | events.add( 'foo', function (arg) { console.log(42, arg) });
74 | events.add( 'bar', function (arg) { console.log(99, arg) });
75 |
76 | events.fire( 'foo', 5 );
77 | // 13, 5
78 | // 42, 5
79 |
80 | ### ready
81 |
82 | atom.Events ready( string name, Array arguments );
83 |
84 | `ready` fires events once & fire all callbacks immedeatly, when they are binded. Can be used for some kind of "ready" events such as `image.onload` and so on, which fires only once.
85 |
86 | events.add( 'complete', function () { console.log(13) }); // wait event
87 |
88 | events.ready('complete'); // log 13
89 |
90 | events.add( 'complete', function () { console.log(42) }); // immedeatly log 42
91 |
92 | ### changing context
93 |
94 | You can change context(value of `this`) in fired callbacks by setting in in constructor:
95 |
96 | atom.declare( 'Foo', {
97 | property: 42,
98 |
99 | initialize: function () {
100 | this.events = new atom.Events(this);
101 | },
102 |
103 | run: function () {
104 | this.events.fire('run');
105 | }
106 | });
107 |
108 | var foo = new Foo();
109 |
110 | foo.events.add( 'run', function () {
111 | console.log( this.property ); // 42
112 | });
113 |
114 | foo.run();
--------------------------------------------------------------------------------
/Docs/En/Declare/ImagePreloader.md:
--------------------------------------------------------------------------------
1 | atom.ImagePreloader
2 | ===================
3 |
4 | Class, which provides the easy way to preload images.
5 |
6 | ## Properties
7 |
8 | * `events` - `atom.Events` object
9 |
10 | * `settings` - `atom.Settings` object
11 |
12 | * `count` - object, state of images preloading, subproperties:
13 |
14 | * * `load` - number of images, loaded successful
15 | * * `abort` - number of images, which loading was aborted
16 | * * `error` - number of images, loaded with errors
17 |
18 | * `isReady` - `bool`, true, if all images are loaded
19 |
20 | * `info` - returns debug info about images loading state
21 |
22 | * `progress` - float value between 0 and 1 - percent of images, loaded already
23 |
24 | ## Methods
25 |
26 | ### initialize
27 |
28 | void initialize( Settings settings )
29 |
30 | ##### Settings:
31 |
32 | * `images` - hash of images should be preloaded
33 | * `prefix` - string, all images should be prefixed by. Can be used, if all images begins with similar path
34 | * `suffix` - string, all images should be suffixed by. Can be used to avoid images caching
35 |
36 | ##### Events:
37 |
38 | * `ready` - fires when all images are successfully loaded
39 |
40 | ##### Example:
41 |
42 | new atom.ImagePrealoader({
43 | prefix: 'http://static.example.com/images/',
44 | suffix: '?_avoid_cache=' + Date.now(),
45 | images: {
46 | 'unit-tractor' : 'units/tractor.png',
47 | 'unit-tank' : 'units/tank.png',
48 | 'unit-fighter' : 'units/fighter.png',
49 | 'unit-destroyer': 'units/destroyer.png',
50 |
51 | 'building-factory' : 'building/factory.jpg',
52 | 'building-oilrig' : 'building/oilrig.jpg',
53 | 'building-warehouse': 'building/warehouse.jpg'
54 | },
55 | onReady: function (imagePreloader) {
56 | new Game(imagePreloader);
57 | }
58 | });
59 |
60 | ### exists
61 |
62 | bool exists( string name )
63 |
64 | Checks, if image with name `name` was loaded.
65 |
66 | imagePreloader.exists( 'unit-traktor' ); // true
67 | imagePreloader.exists( 'unit-diablo' ); // false
68 |
69 | ### get
70 |
71 | Image get( string name )
72 |
73 | Returns image with name `name`, if exists, or throws `Error` otherwise
74 |
75 | imagePreloader.exists( 'unit-traktor' ); // returns image
76 | imagePreloader.exists( 'unit-diablo' ); // throws Error
77 |
78 | ## atom.ImagePreloader.run
79 |
80 | imagePreloader ImagePreloader.run( Object images, Function onReady, mixed context = null )
81 |
82 | Short way to create image preloader.
83 |
84 | ImagePrealoader.run({ unit: 'unit.png' }, function (preloader) {
85 | new Game(preloader);
86 | });
87 |
88 | // equals to:
89 |
90 | new ImagePrealoader({
91 | images: { unit: 'unit.png' },
92 | onReady: function (preloader) {
93 | new Game(preloader);
94 | }
95 | });
96 |
97 | ## images syntax
98 |
99 | Preloader can dynamically crop images (sprites). Just add `[x:y:w:h]` part in the end of image path:
100 |
101 | ImagePrealoader.run({
102 | 'unit-tractor' : 'units.png [0:0:50:50]',
103 | 'unit-tank' : 'units.png [50:0:50:50]',
104 | 'unit-fighter' : 'units.png [100:0:50:50]',
105 | 'unit-destroyer': 'units.png [150:0:50:50]',
106 |
107 | 'building-factory' : 'building.jpg [0:0:200:100]',
108 | 'building-oilrig' : 'building.jpg [0:100:200:100]',
109 | 'building-warehouse': 'building.jpg [0:200:200:100]'
110 | });
111 |
112 | Another way is `tile cropping`. Syntax is `[w:h]{x:y}` where `w` is width of tile, `h` is height of tile, `x` is horisontal index of tile at image and `y` is vertical index of tile in image. Next code is indetial to previous:
113 |
114 | ImagePrealoader.run({
115 | 'unit-tractor' : 'units.png [50:50]{0:0}',
116 | 'unit-tank' : 'units.png [50:50]{1:0}',
117 | 'unit-fighter' : 'units.png [50:50]{2:0}',
118 | 'unit-destroyer': 'units.png [50:50]{3:0}',
119 |
120 | 'building-factory' : 'building.jpg [200:100]{0:0}',
121 | 'building-oilrig' : 'building.jpg [200:100]{0:1}',
122 | 'building-warehouse': 'building.jpg [200:100]{0:2}'
123 | });
124 |
125 | You can begins image with `http://` or `https://` if you dont want to prefix them:
126 |
127 | new ImagePrealoader({
128 | prefix: 'http://s1.example.com/images',
129 | images: {
130 | unit1: 'unit1.png',
131 | unit2: 'unit2.png',
132 | unit3: 'https://s2.example.com/images/secret-unit.png',
133 | },
134 | });
135 |
136 |
137 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Keyboard.md:
--------------------------------------------------------------------------------
1 | atom.Keyboard
2 | =============
3 |
4 | Provides the way to easy manipulate the keyboard
5 |
6 | ### own
7 |
8 | * `keyCodes` - object, where key is key name & value is key code.
9 | * `codeNames` - object, where key is key code & value is key name.
10 |
11 | #### keyName
12 |
13 | Returns name of key. First argument can be event or number
14 |
15 | window.onclick = function (e) {
16 | atom.trace( atom.Keyboard.keyName(e) );
17 | }
18 |
19 | ### prototype
20 |
21 | #### initialize
22 |
23 | new atom.Keyboard( DOMElement element );
24 |
25 | First argument can be null - that used `document` as default.
26 |
27 | var keyboard = new atom.Keyboard();
28 |
29 | #### key
30 |
31 | boolean key( string keyName )
32 |
33 | Checks if current key is pressed now
34 |
35 | if (keyboard.key('aleft')) {
36 | turnLeft();
37 | } else if (keyboard.key('aright')) {
38 | turnRight();
39 | }
40 |
41 | #### events
42 |
43 | Contains `atom.Events` instance. You can bind keys here. `:up` & `:press` prefixes can be used to specialize events:
44 |
45 | keyboard.events.add( 'space', function () {
46 | unit.jump();
47 | });
48 |
49 | keyboard.events.add( 'tab:up', function () {
50 | console.log( 'tab up' );
51 | });
52 |
53 |
54 | Key Codes
55 | =========
56 |
57 | ### Latin symbols
58 |
59 | Name | Code | Name | Code | Name | Code
60 | -------- | ---- | -------- | ---- | -------- | ----
61 | a | 65 | b | 66 | c | 67
62 | d | 68 | e | 69 | f | 70
63 | g | 71 | h | 72 | i | 73
64 | j | 74 | k | 75 | l | 76
65 | m | 77 | n | 78 | o | 79
66 | p | 80 | q | 81 | r | 82
67 | s | 83 | t | 84 | u | 85
68 | v | 86 | w | 87 | x | 88
69 | y | 89 | z | 90 | |
70 |
71 |
72 | ### Numbers & F*
73 |
74 | Name | Code | Name | Code | Name | Code
75 | -------- | ---- | -------- | ---- | -------- | ----
76 | n0 | 48 | n1 | 49 | n2 | 50
77 | n3 | 51 | n4 | 52 | n5 | 53
78 | n6 | 54 | n7 | 55 | n8 | 56
79 | n9 | 57 | | | |
80 | f1 | 112 | f2 | 113 | f3 | 114
81 | f4 | 115 | f5 | 116 | f6 | 117
82 | f7 | 118 | f8 | 119 | f9 | 120
83 | f10 | 121 | f11 | 122 | f12 | 123
84 |
85 | ### Controls
86 |
87 | Name | Code | Name | Code | Name | Code
88 | -------- | ---- | -------- | ---- | ---------- | ----
89 | capslock | 20 | numlock | 144 | scrolllock | 145
90 | enter | 13 | shift | 16 | backspace | 6
91 | tab | 9 | ctrl | 17 | alt | 18
92 | menu | 93 | pause | 19 | esc | 27
93 | insert | 45 | home | 36 | pageup | 33
94 | delete | 46 | end | 35 | pagedown | 34
95 | | | aup | 38 | |
96 | aleft | 37 | adown | 40 | aright | 39
97 |
98 | ### Symbols
99 |
100 | Name | Code | Name | Code | Name | Code
101 | -------- | ---- | -------- | ---- | ---------- | ----
102 | equals | 61 | hyphen | 109 | semicolon | 59
103 | dot | 190 | sbopen | 219 | sbclose | 221
104 | slash | 191 | gravis | 192 | backslash | 220
105 | | | coma | 188 | apostrophe | 222
106 |
107 | ### Numpad
108 |
109 | Name | Code | Name | Code | Name | Code
110 | -------- | ---- | -------- | ---- | ---------- | ----
111 | np0 | 96 | np1 | 97 | npslash | 11
112 | np2 | 98 | np3 | 99 | npstar | 106
113 | np4 | 100 | np5 | 101 | nphyphen | 109
114 | np6 | 102 | np7 | 103 | npplus | 107
115 | np8 | 104 | np9 | 105 | npdot | 110
--------------------------------------------------------------------------------
/Docs/En/Declare/Settings.md:
--------------------------------------------------------------------------------
1 | atom.Settings
2 | =============
3 |
4 | `atom.Settings` is class, which provides easy settings changing
5 |
6 | var settings = new atom.Settings();
7 |
8 | ### set
9 |
10 | `set` - sets values
11 |
12 | atom.Settings set( string name, mixed value );
13 | atom.Settings set( object values );
14 |
15 | #### example:
16 |
17 | settings.set( 'test', 123 );
18 | settings.set({ a: 1, b: 2 });
19 |
20 | #### returns `this`
21 |
22 | ### get
23 |
24 | `get` - returns value of key, or all values
25 |
26 | mixed get( string key, mixed defaultValue = undefined );
27 |
28 | #### example:
29 |
30 | settings.get( 'test' ); // 123
31 | settings.get( 'wrong', 'default' ); // 'default'
32 |
33 | ### properties
34 |
35 | `properties` - such properties will be set automatically to target object.
36 | If no names set - all properties will be set.
37 |
38 | atom.Settings properties( string target, string[] names = null );
39 |
40 | #### example:
41 |
42 | var object = {};
43 |
44 | settings.properties( object, [ 'foo' ] );
45 | settings.set({ foo: 1, bar: 2 });
46 |
47 | console.log( object.foo ); // 1
48 | console.log( object.bar ); // undefined
49 |
50 | ### initial values
51 |
52 | You can set initial values of Settings using first argument while constructing:
53 |
54 | var settings = new atom.Settings({ initial: 42 });
55 | settings.get('initial'); // 42
56 |
57 | ### addEvents
58 |
59 | atom.Settings addEvents( atom.Events events );
60 |
61 | When events are added all settings, which begins with 'on' are recognized as events
62 |
63 | var events = new atom.Events();
64 | var settings = new atom.Settings();
65 | settings.addEvents( events );
66 |
67 | settings.set({ onClick: onClickCallback });
68 | //equals to:
69 | events.add( 'click', onClickCallback );
70 |
71 | This can be used for easy events+settings class construction:
72 |
73 | atom.declare( 'Button', {
74 | initialize: function (settings) {
75 | this.events = new atom.Events(this);
76 | this.settings = new atom.Settings(settings);
77 |
78 | this.settings.addEvents( this.events );
79 | }
80 | });
81 |
82 | new Button({
83 | title: 'My Test Button',
84 | onClick: function () {
85 | // button onClick event
86 | }
87 | });
88 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Trace.md:
--------------------------------------------------------------------------------
1 | atom.trace
2 | ==========
3 |
4 | This class used in browsers for easy online debug without using browser console. Please, use `atom.css` from repo core.
5 |
6 | It recurcively dumps (map depth is 5) object according inner rules & object 'dump' method & show result at screen.
7 |
8 | ### atom.trace.dumpPlain( object )
9 |
10 | Returns plain dump (string) of object, that can be logged e.g. in console or another place.
11 |
12 | #### example:
13 |
14 | atom.trace.dumpPlain({
15 | foo: 123,
16 | bar: null,
17 | arr: [ 1, 2, 3 ],
18 | sub: { test: 'string' },
19 | dumpable: {
20 | dump: function () { return '[My Dumpable Object]' }
21 | }
22 | });
23 |
24 | #### result:
25 |
26 | {
27 | foo: 123
28 | bar: null
29 | arr: [
30 | 0: 1
31 | 1: 2
32 | 2: 3
33 | ]
34 | sub: {
35 | test: "string"
36 | }
37 | dumpable: [My Dumpable Object]
38 | }
39 |
40 | ### Instance
41 |
42 | var trace = new atom.Trace( value );
43 |
44 | Shows result of dump on page. Can be dynamicaly changed. It can be used for showing current fps number, mouse coord or another debug info, which can be change so fast, that we can't just log it into console.
45 |
46 | You can use `destroy` method to remove it from screen, or just click on it.
47 |
48 | You can change current its content by setting value property:
49 |
50 | var trace = atom.trace();
51 | var value = 0;
52 |
53 | setInterval(function () {
54 | trace.value = value++;
55 | }, 100);
56 |
57 | You can set as value any object, you can see.
58 |
59 | // Some class:
60 | atom.declare( 'Changer', {
61 | value: 0,
62 | max : 0,
63 |
64 | initialize: function (initial, max) {
65 | this.value = initial;
66 | this.max = max;
67 | this.events = new atom.Events(this);
68 | this.runNext();
69 | },
70 |
71 | change: function () {
72 | this.value += Number.random(-5, 10);
73 |
74 | if (this.value > this.max) {
75 | this.events.fire('stop');
76 | } else {
77 | this.events.fire('change');
78 | this.runNext();
79 | }
80 | },
81 |
82 | runNext: function () {
83 | this.change.delay(100, this);
84 | },
85 |
86 | dump: function () {
87 | return '[Changer ' + this.value + ']';
88 | }
89 | });
90 |
91 | // listen code:
92 | var myChanger = new Changer(1000, 1200);
93 |
94 | var changerTrace = atom.trace(myChanger);
95 | myChanger.events.add({
96 | change: function () {
97 | changerTrace.value = myChanger;
98 | },
99 | stop: function (){
100 | changerTrace.destroy();
101 | }
102 | });
103 |
104 |
105 |
--------------------------------------------------------------------------------
/Docs/En/Declare/Transition.md:
--------------------------------------------------------------------------------
1 | atom.Transition
2 | ===============
3 |
4 | `atom.Transition` specifies the speed curves of the transition effects.
5 |
6 | ### atom.Transition.set
7 |
8 | atom.Transition.set( id, fn );
9 |
10 | Sets new transition function:
11 |
12 | atom.Transition.set( 'Special', function(p){
13 | return Math.sqrt( Math.atan(p*Math.PI/2) );
14 | });
15 |
16 | ### atom.Transition.get
17 |
18 | atom.Transition.get( id );
19 |
20 | Returns transition function. Returns 'ease-in-out' as default, 'ease-in' if `-in` prefix contains & 'ease-out' if `out` prefix contains;
21 |
22 | var transitionInOut = atom.Transition.get( 'special' );
23 | var transitionIn = atom.Transition.get( 'special-in' );
24 | var transitionOut = atom.Transition.get( 'special-out' );
25 |
26 | console.log( transitionInOut(0.5) ); // 0.5
27 |
28 | ### Build-in timing functions
29 |
30 | * linear
31 | * sine
32 | * asine
33 | * back
34 | * bounce
35 | * elastic
36 | * expo
37 | * circ
38 | * quad
39 | * cubic
40 | * quart
41 | * quint
42 |
43 | 
--------------------------------------------------------------------------------
/Docs/En/Declare/transition-graph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/theshock/atomjs/8fcc3209e9b49727fd30c1b15194f895054ad6dc/Docs/En/Declare/transition-graph.png
--------------------------------------------------------------------------------
/Docs/En/Dom.md:
--------------------------------------------------------------------------------
1 | Atom DOM
2 | ========
3 |
4 | #### Constructor:
5 |
6 | atom.dom();
7 | atom.dom('tag .class');
8 | atom.dom(document.getElementsByTagName('tag'));
9 | atom.dom(selector, context);
10 |
11 | #### onready
12 |
13 | atom.dom(function () {
14 | // DOMContentLoaded
15 | });
16 |
17 | #### atom.dom.create(tagName, attrs = null)
18 |
19 | Creates and returns (*atom.dom*) tag with name `tagName`
20 |
21 | Example:
22 |
23 | // creating Canvas with properties
24 | var atomCanvas = atom.dom.create('canvas', {
25 | width : 400,
26 | height : 100
27 | });
28 |
29 | #### atom.dom().body
30 |
31 | var body = atom.dom().body;
32 |
33 | #### atom.dom().get(index = 0)
34 |
35 | Returns html-element from current collection
36 |
37 | atom.dom('img').first; // first image on a page
38 | atom.dom('img').get(); // first image on a page
39 | atom.dom('img').get(5); // fifth image on a page
40 |
41 | #### atom.dom().create(tagName, index = 0, attrs = null)
42 |
43 | Creates element, adds it to node and returns node
44 |
45 | Optional arguments:
46 |
47 | * `index` - index of node in current collection
48 | * `attrs` - properties to set on new element
49 |
50 | Example:
51 |
52 | // creating Canvas in fifth div:
53 | atom.dom('div').create('canvas', 5);
54 |
55 | // creating Canvas with properties
56 | atom.dom('div').create('canvas', {
57 | width : 400,
58 | height : 100
59 | });
60 |
61 | // creating few elements in div
62 | var divNode = atom.dom('div')
63 | .create('canvas')
64 | .create('canvas')
65 | .create('footer')
66 |
67 | console.log(divNode) //
...
68 |
69 | and now div looks like:
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | #### atom.dom().each(fn)
78 |
79 | Apply function on each element of collection (analogue of `Array.forEach`):
80 |
81 | atom.dom('div').each(function (div, index) {
82 | div.className = 'active';
83 | // this == atom.dom('div')
84 | });
85 |
86 | #### atom.dom().parent(step = 1)
87 |
88 | Returns parent element for choosed step.
89 |
90 | Example:
91 |
92 |
93 |
98 |
99 |
100 | atom.dom('#id3').parent().id; //id2
101 | atom.dom('#id3').parent(2).id; //id1
102 |
103 | #### atom.dom().css(properties)
104 |
105 | Apply CSS to every element:
106 |
107 | // let's paint every div in red
108 | atom.dom('div').css('background', 'red');
109 | atom.dom('div').css({background: 'red'});
110 |
111 | #### atom.dom().addEvent(events)
112 |
113 | Attach event handler to every element in current collection
114 |
115 | atom.dom('div').addEvent({click: function () {
116 | alert('div clicked')
117 | }});
118 |
119 | Prevent default actions for events
120 |
121 | atom.dom("a").addEvent("click", false);
122 |
123 | #### atom.dom().bind(events)
124 |
125 | Deprecated, use *addEvent*
126 |
127 | #### atom.dom().removeEvent(events)
128 |
129 | Detach event handler from evety element in current collection
130 |
131 | atom.dom("div").addEvent("click", function listener (event) {
132 | alert('div clicked')
133 | this.removeEvent("click", listener);
134 | });
135 |
136 | #### atom.dom().unbind(events)
137 |
138 | Deprecated, use *removeEvent*
139 |
140 | #### atom.dom().delegate(selector, event, fn)
141 |
142 | Attach event handler to every matching element in current collection now and in
143 | future.
144 |
145 | atom.dom('div').delegate('img', 'click', function () {
146 | alert('img in div clicked')
147 | }});
148 |
149 | #### atom.dom().find(selector)
150 |
151 | Find element inside current collection. Equivalent to atom(selector, context);
152 |
153 | atom.dom('div').find('p') == atom.dom('div p');
154 |
155 | #### atom.dom().appendTo(elem)
156 |
157 | Append collection to another element
158 |
159 | atom.dom('img').appendTo('div'); // append every image to div
160 |
161 | #### atom.dom().attr(values)
162 |
163 | Set attribute for every element in current collection
164 |
165 | atom.dom('canvas').attr({
166 | width : 50,
167 | height : 50
168 | });
169 |
170 | #### atom.dom().destroy()
171 |
172 | Destroy current collection
173 |
174 | atom.dom('div').destroy();
175 |
176 | #### atom.dom().filter(selector)
177 |
178 | Filter elements according to selector
179 |
180 | // returns only divs with class "className"
181 | atom.dom('div').filter('.className');
182 |
183 |
184 | #### atom.dom().is(selector)
185 |
186 | Checks if elems is matched to selector
187 |
188 | // returns true is there are divs with class "className"
189 | atom.dom('div').is('.className');
190 |
191 | #### atom.dom().html(value = undefined)
192 |
193 | get or set html of first element in set
194 |
195 | atom.dom('div').html('abc ');
196 | atom.dom('div').html(); // 'abc '
197 |
198 | #### atom.dom().text(value = undefined)
199 |
200 | get or set text of first element in set
201 |
202 | atom.dom('div').text('abc');
203 | atom.dom('div').text(); // 'abc';
204 |
205 | atom.dom('div').html('abc ');
206 | atom.dom('div').text(); // 'abc';
207 |
208 | #### atom.dom().wrap(wrapper)
209 |
210 | Wrap first element of set with wrapper
211 |
212 | atom.dom('span').wrap( atom.dom.create('div') );
213 |
214 | #### atom.dom().replaceWith(newElement)
215 |
216 | Replace first element of the set with newElement
217 |
218 | atom.dom('span').replaceWith( atom.dom.create('div') );
219 |
220 | #### atom.dom().addClass(className)
221 |
222 | Adds new class "className" to all elements of set
223 |
224 | atom.dom('span').addClass('foo');
225 |
226 |
227 | #### atom.dom().removeClass(className)
228 |
229 | Removes class "className" from all elements of set
230 |
231 | atom.dom('span').removeClass('foo');
232 |
233 |
234 | #### atom.dom().toggleClass(className)
235 |
236 | Toggles class "className" for all elements of set
237 |
238 | atom.dom('span').toggleClass('foo');
239 |
240 |
241 | #### atom.dom().hasClass(className)
242 |
243 | Returns true if set contains one or more elements
244 | having class "className"
245 |
246 | atom.dom('span').hasClass('foo');
247 |
--------------------------------------------------------------------------------
/Docs/En/Frame.md:
--------------------------------------------------------------------------------
1 | Atom Frame
2 | ==========
3 |
4 | Provides interface to perform animation. It calls you function up to 60 times per second.
5 | Alternative (and wrapper in future) for `requestAnimationFrame`
6 |
7 |
8 | ### atom.frame.add(function callback)
9 | Adds callback for animation
10 |
11 | ### atom.frame.remove(function callback)
12 | Remove callback from animation
13 |
14 | #### Example
15 | atom.frame.add(function animate() {
16 | element.left += 5;
17 | if (element.left > 100) {
18 | atom.frame.remove(animate);
19 | }
20 | });
--------------------------------------------------------------------------------
/Docs/En/PointerLock.md:
--------------------------------------------------------------------------------
1 | Pointer Lock
2 | ============
3 |
4 | Provides interface for cross browser pointer locking
5 |
6 |
7 | ### atom.pointerLock.supports
8 | Equals `true` if `PointerLock` supports:
9 |
10 | ```js
11 | if (atom.pointerLock.supports) {
12 | console.log('PointerLock supports');
13 | }
14 | ```
15 |
16 | ### atom.pointerLock.locked(DOMElement element)
17 | Returns `true` if element is locked now:
18 |
19 | ```js
20 | if (atom.pointerLock.locked(myCanvas)) {
21 | console.log('myCanvas locked');
22 | }
23 | ```
24 |
25 | ### atom.pointerLock.request(DOMElement element, function callback)
26 | Try to pointer lock `element` & then calls `callback` on mouse move:
27 |
28 | ```js
29 | atom.pointerLock.request( myCanvas, function (e) {
30 | console.log( 'Locked mouse move: ', e.movementX, e.movementY );
31 | });
32 | ```
33 |
34 | ### atom.pointerLock.exit()
35 | Unlock pointer if locked
36 |
37 | ```js
38 | atom.pointerLock.exit()
39 | ```
--------------------------------------------------------------------------------
/Docs/En/Prototypes/Array.md:
--------------------------------------------------------------------------------
1 | Array extending
2 | ===============
3 |
4 | Generally build-in type extending use `atom.%type%.*` methods, so here you will only see links to manual and examples
5 |
6 | ### See: [atom.array](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/Math.md)
7 |
8 | ### Own properties
9 |
10 | Next list of properties mixin to Array:
11 |
12 | * range
13 | * from
14 | * pickFrom
15 | * fill
16 | * fillMatrix
17 | * collect
18 | * create
19 | * toHash
20 |
21 | ##### example
22 |
23 | Array.range( from, to );
24 | // equals to:
25 | atom.array.range( from, to );
26 |
27 | ### prototype extending
28 |
29 | Next properties mixed in to prototype, where first property is `this` array:
30 |
31 | * randomIndex
32 | * property
33 | * contains
34 | * include
35 | * append
36 | * erase
37 | * combine
38 | * pick
39 | * invoke
40 | * shuffle
41 | * sortBy
42 | * min
43 | * max
44 | * mul
45 | * add
46 | * sum
47 | * product
48 | * average
49 | * unique
50 | * associate
51 | * clean
52 | * empty
53 | * clone
54 | * hexToRgb
55 | * rgbToHex
56 |
57 | ##### example
58 | var myArray = [1,2,3];
59 |
60 | myArray.include( 4 );
61 | // equals to:
62 | atom.array.include( myArray, 4 );
63 |
64 | // and
65 |
66 | myArray.sum()
67 | // equals to:
68 | atom.array.sum( myArray );
69 |
70 | ### Own properties
71 |
72 | * `last` - returns last element in array
73 |
74 | var myArray = ['foo','bar','qux'];
75 | console.log( myArray.last ); // 'qux'
76 |
77 | * `random` - returns random property of array:
78 |
79 | var myArray = ['foo','bar','qux'];
80 | console.log( myArray.random ); // 'foo' or 'bar' or 'qux'
81 |
82 |
83 |
--------------------------------------------------------------------------------
/Docs/En/Prototypes/Function.md:
--------------------------------------------------------------------------------
1 | Function extending
2 | ==================
3 |
4 | Generally build-in type extending use `atom.%type%.*` methods, so here you will only see links to manual and examples
5 |
6 | ### See: [atom.fn](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/Function.md)
7 |
8 | ### Own properties
9 |
10 | * `after` - Equals to `atom.fn.after`
11 | * `lambda` - Equals to `atom.fn.lambda`
12 |
13 | ### Prototype extending
14 |
15 | #### delay
16 |
17 | Function delay( Number time, mixed context = null, Array arguments = [] );
18 |
19 | equivalent to `setTimeout`, easy wat to launch function `time` later.
20 |
21 | object.method.delay( 500, object, [ 1, 'foo' ] );
22 | // equals to:
23 | setTimeout( object.method.bind( object, 1, 'foo' ), 500 );
24 |
25 | #### periodical
26 |
27 | Function periodical( Number time, mixed context = null, Array arguments = [] );
28 |
29 | equivalent to `setInterval`, easy wat to launch function `time` later.
30 |
31 | object.method.periodical( 500, object, [ 1, 'foo' ] );
32 | // equals to:
33 | setInterval( object.method.bind( object, 1, 'foo' ), 500 );
34 |
--------------------------------------------------------------------------------
/Docs/En/Prototypes/Number.md:
--------------------------------------------------------------------------------
1 | Number extending
2 | ================
3 |
4 | Generally build-in type extending use `atom.%type%.*` methods, so here you will only see links to manual and examples
5 |
6 | ### See: [atom.number](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/Number.md), [atom.math](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/Math.md)
7 |
8 | ### Own properties
9 |
10 | * Number.random
11 |
12 | Equivalent to `atom.number.random`:
13 |
14 | Number.random(5, 100);
15 | // equals to
16 | atom.number.random(5, 100);
17 |
18 | * Number.randomFloat
19 |
20 | Equivalent to `atom.number.randomFloat`:
21 |
22 | Number.randomFloat(5, 100);
23 | // equals to
24 | atom.number.randomFloat(5, 100);
25 |
26 | ### prototype extending
27 |
28 | Next properties mixed into prototype from `atom.number`, where first property is `this` array:
29 |
30 | * between
31 | * equals
32 | * limit
33 | * round
34 | * stop
35 |
36 |
37 | Next properties mixed into prototype from `atom.math`, where first property is `this` array:
38 |
39 | * degree
40 | * getDegree
41 | * normalizeAngle
42 |
43 |
44 | ##### example
45 | var myNumber = 10;
46 |
47 | myNumber.between( 5, 15 );
48 | // equals to:
49 | atom.number.between( myNumber, 5, 15 );
50 |
51 | // and
52 |
53 | myNumber.degree()
54 | // equals to:
55 | atom.math.degree( myNumber );
56 |
57 |
58 | Next properties mixed into prototype from javascript build-in `Math`, where first property is `this` array:
59 |
60 | * abs
61 | * acos
62 | * asin
63 | * atan
64 | * atan2
65 | * ceil
66 | * cos
67 | * exp
68 | * floor
69 | * log
70 | * max
71 | * min
72 | * pow
73 | * sin
74 | * sqrt
75 | * tan
76 |
77 |
78 | ##### example
79 |
80 | var myNumber = -5.123;
81 |
82 | myNumber.abs();
83 | // equals to
84 | Math.abs( myNumber );
85 |
86 | // and
87 |
88 | myNumber.pow(3);
89 | // equals to:
90 | Math.pow( myNumber, 3 );
91 |
92 |
--------------------------------------------------------------------------------
/Docs/En/Prototypes/Object.md:
--------------------------------------------------------------------------------
1 | Object extending
2 | ================
3 |
4 | Generally build-in type extending use `atom.%type%.*` methods, so here you will only see links to manual and examples
5 |
6 | ### See: [atom.object](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/Object.md)
7 |
8 | ### Own properties
9 |
10 | All properties of `atom.object` mixed to `Object`:
11 |
12 | * invert
13 | * collect
14 | * values
15 | * map
16 | * max
17 | * min
18 | * isEmpty
19 | * path
20 |
21 | ##### example
22 |
23 | Object.invert( myObject );
24 | // equals to:
25 | atom.object.invert( myObject );
26 |
27 | // and
28 |
29 | Object.map( myObject, callback );
30 | // equals to:
31 | atom.object.map( myObject, callback );
--------------------------------------------------------------------------------
/Docs/En/Prototypes/String.md:
--------------------------------------------------------------------------------
1 | String extending
2 | ================
3 |
4 | Generally build-in type extending use `atom.%type%.*` methods, so here you will only see links to manual and examples
5 |
6 | ### See: [atom.string](https://github.com/theshock/atomjs/blob/master/Docs/En/Types/String.md)
7 |
8 | ### prototype extending
9 |
10 | Next properties mixed in to prototype, where first property is `this` array:
11 |
12 | * safeHtml
13 | * repeat
14 | * substitute
15 | * replaceAll
16 | * contains
17 | * begins
18 | * ends
19 | * ucfirst
20 | * lcfirst
21 |
22 | ##### example
23 |
24 | var myString = 'test {string} is here';
25 |
26 | myString.begins( 'test' );
27 | // equals to:
28 | atom.string.begins( myString, 'test' );
29 |
30 | // and
31 |
32 | myString.substitute({ 'string': 'substring' });
33 | // equals to:
34 | atom.string.substitute( myString, { 'string': 'substring' });
35 |
--------------------------------------------------------------------------------
/Docs/En/Types/Function.md:
--------------------------------------------------------------------------------
1 | atom.fn
2 | =======
3 |
4 | Provides method to operate with functions:
5 |
6 | ### atom.fn.lambda(value)
7 |
8 | Returns function, which returns value.
9 |
10 | window.onclick = atom.fn.lambda(false);
11 |
12 | ### atom.fn.after(onReady, fnName)
13 |
14 | Returns hash of functions, which should be invoked before onReady will be invoked. Can be used for parallel invoking of several async callbacks.
15 |
16 | var callbacks = atom.fn.after(function (args) {
17 | console.log(
18 | args.fileReaded, // data from file
19 | args.dbQuery, // data from database
20 | args.userInput // data from user
21 | );
22 | }, 'fileReaded', 'dbQuery', 'userInput' );
23 |
24 | // here we subscribe to async events:
25 |
26 | new My.File.Read.Async( 'filename.txt', callbacks.fileReaded );
27 | new My.Db.Query.Async( 'SELECT * from `db`', callbacks.dbQuery );
28 | document.onclick = callbacks.userInput;
--------------------------------------------------------------------------------
/Docs/En/Types/Math.md:
--------------------------------------------------------------------------------
1 | atom.math
2 | =========
3 |
4 | ### atom.math.degree( degrees )
5 |
6 | Cast degrees to radians
7 |
8 | atom.math.degree(90) == Math.PI/2
9 |
10 | ### atom.math.getDegree( radians )
11 |
12 | Cast radians to degrees. If second argument is `true` - result will be rounded
13 |
14 | atom.math.getDegree(Math.PI/2) == 90
15 |
16 | ### atom.math.normalizeAngle( radians )
17 |
18 | Ensure, angle is between 0 & 360 degrees:
19 |
20 | var angle = atom.math.degree( 1000 );
21 | var normal = atom.math.normalizeAngle( angle );
22 | console.log( atom.math.getDegree( normal, true ) ); // 280
23 |
24 | ### atom.math.hypotenuse( cathetus1, cathetus2 )
25 |
26 | Returns hypotenuse of right triangle from two cathetus
27 |
28 | atom.math.hypotenuse( 5, 12 ); // 13
29 |
30 | ### atom.math.cathetus( hypotenuse, cathetus2 )
31 |
32 | Returns cathetus of right triangle from hypotenuse & cathetus
33 |
34 | atom.math.cathetus( 13, 12 ); // 5
--------------------------------------------------------------------------------
/Docs/En/Types/Number.md:
--------------------------------------------------------------------------------
1 | atom.number
2 | ===========
3 |
4 | Provides methods to operate with numbers
5 |
6 | ### random(min, max) {
7 | Returns random number between `min` & `max` inclusive
8 |
9 | atom.number.random(1, 3); // returns 1 or 2 or 3
10 |
11 | ### randomFloat(min, max) {
12 | Returns random float number between `min` & `max`
13 |
14 | atom.number.randomFloat(1, 3.5); // returns 1.4152 or 3.672, or smth else
15 |
16 | ### between(number, left, right, equals) {
17 |
18 | Checks if `number` is greater than `left` & less than `right`.
19 | `Equals` can be used if `number` can be equals to one or both of sides
20 |
21 | `Equals` can be:
22 | * false or '' - not equals to anyone `number => (left, right)`
23 | * 'L' - can be equals to left side, but not equals right `number => [left, right)`
24 | * 'R' - can be equals to right side, but not equals left `number => (left, right]`
25 | * true or 'LR' - can be equals to both side `number => [left, right]`
26 |
27 | ##### Examples
28 |
29 | atom.number.between( 5, 3, 7 ); // true
30 | atom.number.between( 5, 3, 7, 'L' ); // true
31 | atom.number.between( 5, 3, 7, 'R' ); // true
32 | atom.number.between( 5, 3, 7, true ); // true
33 |
34 | atom.number.between( 7, 3, 7 ); // false
35 | atom.number.between( 7, 3, 7, 'L' ); // false
36 | atom.number.between( 7, 3, 7, 'R' ); // true
37 | atom.number.between( 7, 3, 7, true ); // true
38 |
39 | atom.number.between( 3, 3, 7 ); // false
40 | atom.number.between( 3, 3, 7, 'L' ); // true
41 | atom.number.between( 3, 3, 7, 'R' ); // false
42 | atom.number.between( 3, 3, 7, true ); // true
43 |
44 | atom.number.between( 0, 3, 7 ); // false
45 | atom.number.between( 0, 3, 7, 'L' ); // false
46 | atom.number.between( 0, 3, 7, 'R' ); // false
47 | atom.number.between( 0, 3, 7, true ); // false
48 |
49 | ### equals(left, right, accuracy = 8)
50 |
51 | Allows to compare two float numbers (which can't be done with ==) with `accuracy` digits after dot
52 |
53 |
54 | (0.7 + 0.1) * 10 == 8; // false
55 | atom.number.equals((0.7 + 0.1) * 10, 8); // true
56 |
57 | atom.number.equals(1.15177354, 1.1517, 2); // true (1.152 == 1.152)
58 |
59 | ### limit(number, min, max)
60 |
61 | Returns `number` limited by `min` & `max` values. `max` can be null & only `min` will be used
62 |
63 | atom.number.limit( 42, 0, 100 ); // 42
64 | atom.number.limit( 666, 0, 100 ); // 100
65 | atom.number.limit( -13, 0, 100 ); // 0
66 |
67 | atom.number.limit( -13, 0 ); // 0
68 | atom.number.limit( 183, 0 ); // 183
69 |
70 |
71 | ### round(number, precision = 0)
72 |
73 | Rounds number to `precision` digits after dots if `precision > 0`
74 | Rounds number to `precision` digits before dots if `precision < 0`
75 |
76 |
77 | atom.number.round( 84139.234567 ); // 84139
78 |
79 | atom.number.round( 84139.234567, 1 ); // 84139.2
80 | atom.number.round( 84139.234567, 3 ); // 84139.235
81 | atom.number.round( 84139.234567, 9 ); // 84139.234567
82 |
83 | atom.number.round( 84139.234567, -1 ); // 84140
84 | atom.number.round( 84139.234567, -3 ); // 84000
85 | atom.number.round( 84139.234567, -9 ); // 0
86 |
--------------------------------------------------------------------------------
/Docs/En/Types/Object.md:
--------------------------------------------------------------------------------
1 | atom.object
2 | ===========
3 |
4 | Provides methods to operate with object
5 |
6 | #### append(target, source1, source2, ... )
7 |
8 | Appends source objects content to target
9 |
10 | var source = { a: 1, b: 2, c: 3 };
11 |
12 | atom.object.append( source, {d:4}, {e:5} );
13 |
14 | console.log( source ); // { a: 1, b: 2, c: 3, d: 4, e: 5 };
15 |
16 | #### invert(object)
17 |
18 | Returns inverted object - where keys is values & values is keys.
19 |
20 | var source = { a: 1, b: 2, c: 3 };
21 | var result = atom.object.invert( source );
22 |
23 | console.log( result ); // { 1: 'a', 2: 'b', 3: 'c' };
24 |
25 |
26 | #### collect(object, Array properties, mixed default = undefined)
27 |
28 | Returns subset with only `properties` as keys
29 |
30 | var source = { a: 1, b: 2, c: 3 };
31 | var result = atom.object.collect( source, [ 'a', 'b', 'e', 'x' ], 42 );
32 |
33 | console.log( result ); // { a: 1, b: 2, e: 42, x: 42 };
34 |
35 | #### values(object)
36 |
37 | Returns array of object values
38 |
39 | var source = { a: 1, b: 2, c: 3 };
40 | var result = atom.object.values( source );
41 | console.log( result ); // [1,2,3]
42 |
43 | #### map(object, callback)
44 |
45 | Returns new object, which has mapped with `callback` values:
46 |
47 |
48 | var source = { a: 1, b: 2, c: 3 };
49 | var result = atom.object.map( source, function (value, key) {
50 | return value * value;
51 | });
52 |
53 | console.log( result ); // { a: 1, b: 4, c: 9};
54 |
55 | #### max(object)
56 |
57 | Returns key, where max value contains
58 |
59 | var source = { x: 42, a: 1, b: 2, c: 3 };
60 | console.log( atom.object.max(source) ); // 'x'
61 |
62 | #### min(object)
63 |
64 | Returns key, where min value contains
65 |
66 | var source = { x: 42, a: 1, b: 2, c: 3 };
67 | console.log( atom.object.max(source) ); // 'a'
68 |
69 | #### isEmpty(object)
70 |
71 | Checks if object is empty
72 |
73 | console.log( atom.object.isEmpty({ }) ); // true
74 | console.log( atom.object.isEmpty({a:1}) ); // false
75 |
76 | #### path.get(object, path)
77 |
78 | Returns value by the path.
79 |
80 | var source = {
81 | foo: {
82 | bar: {
83 | qux: 123
84 | }
85 | }
86 | };
87 |
88 | console.log( atom.object.path.get(source, 'foo.bar.qux') ); // 123
89 | console.log( atom.object.path.get(source, 'nil.bar.qux') ); // undefined
90 |
91 | #### path.set(object, path)
92 |
93 | Sets value by the path.
94 |
95 | var source = {
96 | foo: {
97 | bar: {
98 | qux: 123
99 | }
100 | }
101 | };
102 |
103 | atom.object.path.set(source, 'foo.bar.qux', 42 );
104 | atom.object.path.set(source, 'nil.bar.qux', 13 );
105 | atom.object.path.set(source, 'foo.bar.qwe', 99 );
106 | atom.object.path.set(source, 'foo.sub' , 9126 );
107 |
108 | console.log( source ); /* {
109 | foo: {
110 | bar: {
111 | qux: 42,
112 | qwe: 99
113 | },
114 | sub: 9126
115 | },
116 | nil: {
117 | bar: { qux: 13 }
118 | }
119 | } */
120 |
121 | Can be used to safely create namespaces:
122 |
123 | atom.object.path.set( window, 'My.Namespace.Foo', function () {
124 | // My.Namespace.Foo function
125 | });
126 |
127 | atom.object.path.set( window, 'My.Namespace.Bar', function () {
128 | // My.Namespace.Bar function
129 | });
--------------------------------------------------------------------------------
/Docs/En/Types/String.md:
--------------------------------------------------------------------------------
1 | atom.string
2 | ===========
3 |
4 | #### uniqueID
5 | Returns unique for sessiong string id
6 |
7 | atom.string.uniqueID() // "h3biq3tz"
8 | atom.string.uniqueID() // "h3biq3u0"
9 |
10 | #### safeHtml
11 | Returns escaped string, safe to insert as html
12 |
13 | atom.string.safeHtml( 'Hello "World" ' );
14 | // "<b>Hello "World"</b>"
15 |
16 | #### repeat
17 | Repeat string `times` times
18 |
19 | atom.string.repeat( 'bar*', 3 ); // bar*bar*bar*
20 |
21 | #### substitute
22 | Append values to string from object
23 |
24 |
25 | atom.string.substitute(
26 | 'Hello, {name}! How are you? Are you {type}? "{name}" is your real name?',
27 | {
28 | name: 't800', type: 'destroyer'
29 | });
30 | // "Hello, t800! How are you? Are you destroyer? "t800" is your real name?"
31 |
32 |
33 | #### replaceAll
34 | Replace all source substrings with target
35 |
36 | atom.string.replaceAll('Hi--my--dear--friend!', { '--': '+', '!': '?' })
37 | // "Hi+my+dear+friend?"
38 |
39 | #### contains
40 | Checks if string contains substring
41 |
42 | atom.string.contains( 'Hello, World!', 'World' ); // true
43 | atom.string.contains( 'Hello, World!', 'Heaven' ); // false
44 |
45 | #### begins
46 | Checks if string begins with substring
47 |
48 | atom.string.begins( 'Hello, World!', 'Hello' ); // true
49 | atom.string.begins( 'Hello, World!', 'World' ); // false
50 |
51 | #### begins
52 | Checks if string begins with substring
53 |
54 | atom.string.begins( 'Hello, World!', 'Hello' ); // true
55 | atom.string.begins( 'Hello, World!', 'World' ); // false
56 |
57 | #### ends
58 | Checks if string ends with substring
59 |
60 | atom.string.ends( 'Hello, World!', 'Hello' ); // false
61 | atom.string.ends( 'Hello, World!', 'World!' ); // true
62 |
63 | #### ucfirst
64 | Uppercase first character
65 |
66 | atom.string.ucfirst( 'hello, world!' ); // 'Hello, world!'
67 |
68 | #### lcfirst
69 | Lowercase first character
70 |
71 | atom.string.lcfirst( 'Hello, world!' ); // 'hello, world!'
72 |
--------------------------------------------------------------------------------
/Docs/En/Uri.md:
--------------------------------------------------------------------------------
1 | Atom Uri
2 | ========
3 |
4 | ## atom.accessors.uri(str = location.href)
5 |
6 | Parse and returns object - parts of uri `str`
7 |
8 | Available such properties:
9 |
10 | * anchor
11 | * query
12 | * file
13 | * directory
14 | * path
15 | * relative
16 | * port
17 | * host
18 | * password
19 | * user
20 | * userInfo
21 | * authority
22 | * protocol
23 | * source
24 | * queryKey
25 |
26 | #### Result, absolute path `http://usr:pwd@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value#top`:
27 |
28 | anchor: 'top',
29 | query: 'q1=0&&test1&test2=value',
30 | file: 'index.htm',
31 | directory: '/dir/dir.2/',
32 | path: '/dir/dir.2/index.htm',
33 | relative: '/dir/dir.2/index.htm?q1=0&&test1&test2=value#top',
34 | port: '81',
35 | host: 'www.example.com',
36 | password: 'pwd',
37 | user: 'usr',
38 | userInfo: 'usr:pwd',
39 | authority: 'usr:pwd@www.example.com:81',
40 | protocol: 'http',
41 | source: uri,
42 | queryKey: {
43 | q1: '0',
44 | test1: '',
45 | test2: 'value'
46 | }
47 |
48 | #### Result, relative path `/dir/dir.2/index.htm?q1=0&&test1&test2=value#top`:
49 |
50 | anchor: 'top',
51 | query: 'q1=0&&test1&test2=value',
52 | file: 'index.htm',
53 | directory: '/dir/dir.2/',
54 | path: '/dir/dir.2/index.htm',
55 | relative: '/dir/dir.2/index.htm?q1=0&&test1&test2=value#top',
56 | port: '',
57 | host: '',
58 | password: '',
59 | user: '',
60 | userInfo: '',
61 | authority: '',
62 | protocol: '',
63 | source: uri,
64 | queryKey: {
65 | q1: '0',
66 | test1: '',
67 | test2: 'value'
68 | }
69 |
70 | #### Example:
71 |
72 | var uri = atom.uri('http://example.com?debug=1');
73 |
74 | if (uri.queryKey.debug) initDebug();
75 |
76 | #### Default parameter:
77 |
78 | var uri = atom.uri();
79 | // equals to:
80 | var url = atom.uri(location.href);
81 |
82 | alert(uri.anchor);
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Atom
2 | ====
3 |
4 | Atom is compact JavaScript framework oriented on modern browsers, which allows
5 | to support quite broad list of features without keeping a lot of cruft necessary
6 | to implement them in old browsers.
7 |
8 | Supported browsers:
9 |
10 | * Firefox 3.5+
11 | * Google Chrome
12 | * Safari 4+
13 | * Opera 10+
14 | * Internet Explorer 9+
15 | * Mobile Safari
16 | * Android Browser
17 | * Opera Mobile
18 |
19 | Distributed under terms of MIT or LGPL.
20 |
21 | Documentation: see [Docs folder](/master/Docs/En) for description of Atom core and bundled plugins.
22 |
23 |
24 | ## Integration
25 |
26 | * [Ruby on Rails gem](https://github.com/tanraya/atomjs-rails)
27 |
28 |
--------------------------------------------------------------------------------
/Source/Accessors.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Accessors"
5 |
6 | description: "Implementing accessors"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: accessors
16 |
17 | ...
18 | */
19 |
20 | (function (Object) {
21 | var standard = !!Object.getOwnPropertyDescriptor, nonStandard = !!{}.__defineGetter__;
22 |
23 | if (!standard && !nonStandard) throw new Error('Accessors are not supported');
24 |
25 | var lookup = nonStandard ?
26 | function (from, key, bool) {
27 | var g = from.__lookupGetter__(key), s = from.__lookupSetter__(key), has = !!(g || s);
28 |
29 | if (bool) return has;
30 |
31 | return has ? { get: g, set: s } : null;
32 | } :
33 | function (from, key, bool) {
34 | var descriptor = Object.getOwnPropertyDescriptor(from, key);
35 | if (!descriptor) {
36 | // try to find accessors according to chain of prototypes
37 | var proto = Object.getPrototypeOf(from);
38 | if (proto) return atom.accessors.lookup(proto, key, bool);
39 | } else if ( descriptor.set || descriptor.get ) {
40 | if (bool) return true;
41 |
42 | return {
43 | set: descriptor.set,
44 | get: descriptor.get
45 | };
46 | }
47 | return bool ? false : null;
48 | }; /* lookup */
49 |
50 | var define = nonStandard ?
51 | function (object, prop, descriptor) {
52 | if (descriptor) {
53 | if (descriptor.get) object.__defineGetter__(prop, descriptor.get);
54 | if (descriptor.set) object.__defineSetter__(prop, descriptor.set);
55 | }
56 | return object;
57 | } :
58 | function (object, prop, descriptor) {
59 | if (descriptor) {
60 | var desc = {
61 | get: descriptor.get,
62 | set: descriptor.set,
63 | configurable: true,
64 | enumerable: true
65 | };
66 | Object.defineProperty(object, prop, desc);
67 | }
68 | return object;
69 | };
70 |
71 | atom.accessors = {
72 | lookup: lookup,
73 | define: function (object, prop, descriptor) {
74 | if (typeof prop == 'object') {
75 | for (var i in prop) define(object, i, prop[i]);
76 | } else {
77 | define(object, prop, descriptor);
78 | }
79 | return object;
80 | },
81 | has: function (object, key) {
82 | return atom.accessors.lookup(object, key, true);
83 | },
84 | inherit: function (from, to, key) {
85 | var a = atom.accessors.lookup(from, key);
86 |
87 | if ( a ) {
88 | atom.accessors.define(to, key, a);
89 | return true;
90 | }
91 | return false;
92 | }
93 | };
94 | })(Object);
--------------------------------------------------------------------------------
/Source/Ajax.Dom.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Ajax.Dom"
5 |
6 | description: todo
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - dom
15 | - ajax
16 |
17 | provides: ajax.dom
18 |
19 | ...
20 | */
21 |
22 | atom.dom.prototype.ajax = function (config) {
23 | config = coreAppend({}, config);
24 |
25 | var $dom = this;
26 |
27 | if (config.onLoad ) {
28 | config.onLoad = config.onLoad.bind($dom);
29 | } else {
30 | config.onLoad = function (r) { $dom.first.innerHTML = r };
31 | }
32 | if (config.onError) config.onError = config.onError.bind($dom);
33 |
34 | atom.ajax(config);
35 | return $dom;
36 | };
37 |
--------------------------------------------------------------------------------
/Source/Ajax.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Ajax"
5 |
6 | description: "todo"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - CoreExtended
15 |
16 | provides: ajax
17 |
18 | ...
19 | */
20 |
21 | (function () {
22 | var extend = atom.core.extend, emptyFn = function () {};
23 |
24 | var ajax = function (userConfig) {
25 | var data, config, method, req, url;
26 | config = {};
27 | extend(config, ajax.defaultProps);
28 | extend(config, userConfig);
29 | config.headers = {};
30 | extend(config.headers, ajax.defaultHeaders);
31 | extend(config.headers, userConfig.headers);
32 |
33 | data = ajax.stringify( config.data );
34 | req = new XMLHttpRequest();
35 | url = config.url;
36 | method = config.method.toUpperCase();
37 | if (method == 'GET' && data) {
38 | url += (url.indexOf( '?' ) == -1 ? '?' : '&') + data;
39 | }
40 | if (!config.cache) {
41 | url += (url.indexOf( '?' ) == -1 ? '?' : '&') + '_no_cache=' + Date.now();
42 | }
43 | req.onreadystatechange = ajax.onready(req, config);
44 | req.open(method, url, true);
45 | for (var i in config.headers) {
46 | req.setRequestHeader(i, config.headers[i]);
47 | }
48 | req.send( method == 'POST' && data ? data : null );
49 | };
50 |
51 | ajax.stringify = function (object) {
52 | if (!object) return '';
53 | if (typeof object == 'string' || typeof object == 'number') return String( object );
54 |
55 | var array = [], e = encodeURIComponent;
56 | for (var i in object) if (object.hasOwnProperty(i)) {
57 | array.push( e(i) + '=' + e(object[i]) );
58 | }
59 | return array.join('&');
60 | };
61 |
62 | ajax.defaultProps = {
63 | interval: 0,
64 | type : 'plain',
65 | method : 'post',
66 | data : {},
67 | headers : {},
68 | cache : false,
69 | url : location.href,
70 | onLoad : emptyFn,
71 | onError : emptyFn
72 | };
73 |
74 | ajax.defaultHeaders = {
75 | 'X-Requested-With': 'XMLHttpRequest',
76 | 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
77 | };
78 | /** @type {function} */
79 | ajax.onready = function (req, config) {
80 | return function (e) {
81 | if (req.readyState == 4) {
82 | if (req.status != 200) return config.onError(e);
83 |
84 | var result = req.responseText;
85 | if (config.type.toLowerCase() == 'json') {
86 | result = JSON.parse(result);
87 | }
88 | if (config.interval > 0) setTimeout(function () {
89 | atom.ajax(config);
90 | }, config.interval * 1000);
91 | config.onLoad(result);
92 | }
93 | };
94 | };
95 |
96 | atom.ajax = ajax;
97 | })();
98 |
--------------------------------------------------------------------------------
/Source/Class/BindAll.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Class.BindAll"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Class
15 |
16 | inspiration:
17 | - "[MooTools](http://mootools.net)"
18 |
19 | provides: Class.BindAll
20 |
21 | ...
22 | */
23 |
24 | atom.Class.bindAll = function (object, methods) {
25 | if (typeof methods == 'string') {
26 | if (
27 | methods != '$caller' &&
28 | !atom.accessors.has(object, methods) &&
29 | coreIsFunction(object[methods])
30 | ) {
31 | object[methods] = object[methods].bind( object );
32 | }
33 | } else if (methods) {
34 | for (var i = methods.length; i--;) atom.Class.bindAll( object, methods[i] );
35 | } else {
36 | for (var i in object) atom.Class.bindAll( object, i );
37 | }
38 | return object;
39 | };
40 |
--------------------------------------------------------------------------------
/Source/Class/Class.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Class"
5 |
6 | description: "Contains the Class Function for easily creating, extending, and implementing reusable Classes."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - CoreExtended
15 | - accessors
16 | - Array
17 |
18 | inspiration:
19 | - "[MooTools](http://mootools.net)"
20 |
21 | provides: Class
22 |
23 | deprecated: "Use declare instead"
24 |
25 | ...
26 | */
27 |
28 |
29 | (function(atom){
30 |
31 | var typeOf = atom.core.typeOf,
32 | extend = atom.core.extend,
33 | accessors = atom.accessors.inherit,
34 | prototype = 'prototype',
35 | lambda = function (value) { return function () { return value; }},
36 | prototyping = false;
37 |
38 | var Class = function (params) {
39 | if (prototyping) return this;
40 |
41 | if (typeof params == 'function' && typeOf(params) == 'function') params = { initialize: params };
42 |
43 | var Constructor = function(){
44 | if (this instanceof Constructor) {
45 | if (prototyping) return this;
46 | return this.initialize ? this.initialize.apply(this, arguments) : this;
47 | } else {
48 | return Constructor.invoke.apply(Constructor, arguments);
49 | }
50 | };
51 | extend(Constructor, Class);
52 | Constructor.prototype = getInstance(Class);
53 |
54 | Constructor
55 | .implement(params, false)
56 | .reserved(true, {
57 | parent: parent,
58 | self : Constructor
59 | })
60 | .reserved({
61 | factory : function() {
62 | function Factory(args) { return Constructor.apply(this, args); }
63 | Factory.prototype = Constructor.prototype;
64 | return function(args) { return new Factory(args || []); }
65 | }()
66 | });
67 |
68 | Constructor.prototype.constructor = Constructor;
69 |
70 | return Constructor;
71 | };
72 |
73 | var parent = function(){
74 | if (!this.$caller) throw new Error('The method «parent» cannot be called.');
75 | var name = this.$caller.$name,
76 | parent = this.$caller.$owner.parent,
77 | previous = parent && parent.prototype[name];
78 | if (!previous) throw new Error('The method «' + name + '» has no parent.');
79 | return previous.apply(this, arguments);
80 | };
81 |
82 | var wrap = function(self, key, method){
83 | // if method is already wrapped
84 | if (method.$origin) method = method.$origin;
85 |
86 | var wrapper = function() {
87 | if (!this || this == atom.global) throw new TypeError('Context lost');
88 | if (method.$protected && !this.$caller) throw new Error('The method «' + key + '» is protected.');
89 | var current = this.$caller;
90 | this.$caller = wrapper;
91 | var result = method.apply(this, arguments);
92 | this.$caller = current;
93 | return result;
94 | };
95 | wrapper.$owner = self;
96 | wrapper.$origin = method;
97 | wrapper.$name = key;
98 |
99 | return wrapper;
100 | };
101 |
102 | var getInstance = function(Class){
103 | if (atom.declare && Class instanceof atom.declare) {
104 | return atom.declare.config.methods.proto(Class);
105 | }
106 |
107 | prototyping = true;
108 | var proto = new Class;
109 | prototyping = false;
110 | return proto;
111 | };
112 |
113 | Class.extend = function (name, fn) {
114 | if (typeof name == 'string') {
115 | var object = {};
116 | object[name] = fn;
117 | } else {
118 | object = name;
119 | }
120 |
121 | for (var i in object) if (!accessors(object, this, i)) {
122 | this[i] = object[i];
123 | }
124 | return this;
125 | };
126 |
127 | Class.extend({
128 | implement: function(name, fn, retain){
129 | if (typeof name == 'string') {
130 | var params = {};
131 | params[name] = fn;
132 | } else {
133 | params = name;
134 | retain = fn;
135 | }
136 |
137 | for (var key in params) {
138 | if (!accessors(params, this.prototype, key)) {
139 | var value = params[key];
140 |
141 | if (Class.Mutators.hasOwnProperty(key)){
142 | value = Class.Mutators[key].call(this, value);
143 | if (value == null) continue;
144 | }
145 |
146 | if (typeof value == 'function' && typeOf(value) == 'function'){
147 | if (value.$origin) value = value.$origin;
148 | if (value.$hidden == 'next') {
149 | value.$hidden = true
150 | } else if (value.$hidden) {
151 | continue;
152 | }
153 | this.prototype[key] = (retain) ? value : wrap(this, key, value);
154 | } else {
155 | this.prototype[key] = atom.clone(value);
156 | }
157 | }
158 | }
159 | return this;
160 | },
161 | mixin: function () {
162 | Array.from(arguments).forEach(function (item) {
163 | this.implement(getInstance(item));
164 | }.bind(this));
165 | return this;
166 | },
167 | reserved: function (toProto, props) { // use careful !!
168 | if (arguments.length == 1) {
169 | props = toProto;
170 | toProto = false;
171 | }
172 | var target = toProto ? this.prototype : this;
173 | for (var name in props) {
174 | atom.accessors.define(target, name, { get: lambda(props[name]) });
175 | }
176 | return this;
177 | },
178 | isInstance: function (object) {
179 | return object instanceof this;
180 | },
181 | invoke: function () {
182 | return this.factory( arguments );
183 | },
184 | Mutators: {
185 | Extends: function(parent){
186 | if (parent == null) throw new TypeError('Cant extends from null');
187 | this.extend(parent).reserved({ parent: parent });
188 | this.prototype = getInstance(parent);
189 | },
190 |
191 | Implements: function(items){
192 | this.mixin.apply(this, Array.from(items));
193 | },
194 |
195 | Static: function(properties) {
196 | this.extend(properties);
197 | }
198 | },
199 | abstractMethod: function () {
200 | throw new Error('Abstract Method «' + this.$caller.$name + '» called');
201 | },
202 | protectedMethod: function (fn) {
203 | return extend(fn, { $protected: true });
204 | },
205 | hiddenMethod: function (fn) {
206 | return extend(fn, { $hidden: 'next' });
207 | }
208 | });
209 |
210 | Class.abstractMethod.$abstract = true;
211 | atom.Class = Class;
212 |
213 | })(atom);
--------------------------------------------------------------------------------
/Source/Class/Events.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Class.Events"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Class
15 |
16 | inspiration:
17 | - "[MooTools](http://mootools.net)"
18 |
19 | provides: Class.Events
20 |
21 | ...
22 | */
23 |
24 | new function () {
25 |
26 | var Class = atom.Class;
27 |
28 | var fire = function (name, fn, args) {
29 | var result = fn.apply(this, Array.from(args || []));
30 | if (typeof result == 'string' && result.toLowerCase() == 'removeevent') {
31 | this.removeEvent(name, fn);
32 | }
33 | };
34 |
35 | var removeOn = function(string){
36 | return (string || '').replace(/^on([A-Z])/, function(full, first){
37 | return first.toLowerCase();
38 | });
39 | };
40 |
41 | var initEvents = function (object, reset) {
42 | if (reset || !object._events) object._events = { $ready: {} };
43 | };
44 |
45 | var nextTick = function (fn) {
46 | nextTick.fn.push(fn);
47 | if (!nextTick.id) {
48 | nextTick.id = function () {
49 | nextTick.reset().invoke();
50 | }.delay(1);
51 | }
52 | };
53 | nextTick.reset = function () {
54 | var fn = nextTick.fn;
55 | nextTick.fn = [];
56 | nextTick.id = 0;
57 | return fn;
58 | };
59 | nextTick.reset();
60 |
61 | coreAppend(Class, {
62 | Events: Class({
63 | addEvent: function(name, fn) {
64 | initEvents(this);
65 |
66 | var i, l, onfinish = [];
67 | if (arguments.length == 1 && typeof name != 'string') {
68 | for (i in name) {
69 | this.addEvent(i, name[i]);
70 | }
71 | } else if (Array.isArray(name)) {
72 | for (i = 0, l = name.length; i < l; i++) {
73 | this.addEvent(name[i], fn);
74 | }
75 | } else {
76 | name = removeOn(name);
77 | if (name == '$ready') {
78 | throw new TypeError('Event name «$ready» is reserved');
79 | } else if (!fn) {
80 | throw new TypeError('Function is empty');
81 | } else {
82 | Object.ifEmpty(this._events, name, []);
83 |
84 | this._events[name].include(fn);
85 |
86 | var ready = this._events.$ready[name];
87 | if (ready) fire.apply(this, [name, fn, ready, onfinish]);
88 | onfinish.invoke();
89 | }
90 | }
91 | return this;
92 | },
93 | removeEvent: function (name, fn) {
94 | if (!arguments.length) {
95 | initEvents( this, true );
96 | return this;
97 | }
98 |
99 | initEvents(this);
100 |
101 | if (Array.isArray(name)) {
102 | for (var i = name.length; i--;) {
103 | this.removeEvent(name[i], fn);
104 | }
105 | } else if (arguments.length == 1 && typeof name != 'string') {
106 | for (i in name) {
107 | this.removeEvent(i, name[i]);
108 | }
109 | } else {
110 | name = removeOn(name);
111 | if (name == '$ready') {
112 | throw new TypeError('Event name «$ready» is reserved');
113 | } else if (arguments.length == 1) {
114 | this._events[name] = [];
115 | } else if (name in this._events) {
116 | this._events[name].erase(fn);
117 | }
118 | }
119 | return this;
120 | },
121 | isEventAdded: function (name) {
122 | initEvents(this);
123 |
124 | var e = this._events[name];
125 | return !!(e && e.length);
126 | },
127 | fireEvent: function (name, args) {
128 | initEvents(this);
129 |
130 | name = removeOn(name);
131 | // we should prevent skipping next event on removing this in different fireEvents
132 | var funcs = atom.clone(this._events[name]);
133 | if (funcs) {
134 | var l = funcs.length,
135 | i = 0;
136 | for (;i < l; i++) fire.call(this, name, funcs[i], args || []);
137 | }
138 | return this;
139 | },
140 | readyEvent: function (name, args) {
141 | initEvents(this);
142 |
143 | nextTick(function () {
144 | name = removeOn(name);
145 | this._events.$ready[name] = args || [];
146 | this.fireEvent(name, args || []);
147 | }.bind(this));
148 | return this;
149 | }
150 | })
151 | });
152 |
153 | };
--------------------------------------------------------------------------------
/Source/Class/Generators.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Class.Mutators.Generators"
5 |
6 | description: "Provides Generators mutator"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | authors:
13 | - "Shock "
14 |
15 | requires:
16 | - Core
17 | - accessors
18 | - Class
19 |
20 | provides: Class.Mutators.Generators
21 |
22 | ...
23 | */
24 |
25 | new function () {
26 |
27 | var getter = function (key, fn) {
28 | return function() {
29 | var pr = '_' + key, obj = this;
30 | return pr in obj ? obj[pr] : (obj[pr] = fn.call(obj));
31 | };
32 | };
33 |
34 | atom.Class.Mutators.Generators = function(properties) {
35 | atom.Class.Mutators.Generators.init(this, properties);
36 | };
37 |
38 | atom.Class.Mutators.Generators.init = function (Class, properties) {
39 | for (var i in properties) atom.accessors.define(Class.prototype, i, { get: getter(i, properties[i]) });
40 | };
41 |
42 | };
--------------------------------------------------------------------------------
/Source/Class/Options.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Class.Options"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Class
15 |
16 | inspiration:
17 | - "[MooTools](http://mootools.net)"
18 |
19 | provides: Class.Options
20 |
21 | ...
22 | */
23 |
24 | atom.Class.Options = atom.Class({
25 | options: {},
26 | fastSetOptions: false,
27 | setOptions: function(){
28 | if (!this.options) {
29 | this.options = {};
30 | } else if (this.options == this.self.prototype.options) {
31 | // it shouldn't be link to static options
32 | if (this.fastSetOptions) {
33 | this.options = coreAppend({}, this.options);
34 | } else {
35 | this.options = atom.clone(this.options);
36 | }
37 | }
38 | var options = this.options;
39 |
40 | for (var a = arguments, i = 0, l = a.length; i < l; i++) {
41 | if (typeof a[i] == 'object') {
42 | if (this.fastSetOptions) {
43 | coreAppend(options, a[i]);
44 | } else {
45 | atom.extend(options, a[i]);
46 | }
47 | }
48 | }
49 |
50 | if (this.addEvent) for (var option in options){
51 | if (atom.typeOf(options[option]) == 'function' && (/^on[A-Z]/).test(option)) {
52 | this.addEvent(option, options[option]);
53 | delete options[option];
54 | }
55 | }
56 | return this;
57 | }
58 | });
--------------------------------------------------------------------------------
/Source/Cookie.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Cookie"
5 |
6 | description: "todo"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: cookie
16 |
17 | ...
18 | */
19 |
20 | atom.cookie = {
21 | get: function (name) {
22 | var matches = document.cookie.match(new RegExp(
23 | "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
24 | ));
25 | return matches ? decodeURIComponent(matches[1]) : null;
26 | },
27 | set: function (name, value, options) {
28 | options = options || {};
29 | var exp = options.expires;
30 | if (exp) {
31 | if (typeof exp == 'number') {
32 | exp = new Date(exp * 1000 + Date.now());
33 | }
34 | if (exp.toUTCString) {
35 | exp = exp.toUTCString();
36 | }
37 | options.expires = exp;
38 | }
39 |
40 | var cookie = [name + "=" + encodeURIComponent(value)];
41 | for (var o in options) cookie.push(
42 | options[o] === true ? o : o + "=" + options[o]
43 | );
44 | document.cookie = cookie.join('; ');
45 |
46 | return atom.cookie;
47 | },
48 | del: function (name) {
49 | return atom.cookie.set(name, '', { expires: -1 });
50 | }
51 | };
--------------------------------------------------------------------------------
/Source/Core.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Core"
5 |
6 | description: "The core of AtomJS."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | inspiration:
13 | - "[JQuery](http://jquery.com)"
14 | - "[MooTools](http://mootools.net)"
15 |
16 | provides: Core
17 |
18 | requires:
19 | - js185
20 |
21 | ...
22 | */
23 |
24 | function coreIsFunction (item) {
25 | return item && toString.call(item) == '[object Function]';
26 | }
27 |
28 | function coreObjectize (properties, value) {
29 | if (typeof properties != 'object') {
30 | var key = properties;
31 | properties = {};
32 | if (key != null) {
33 | properties[key] = value;
34 | }
35 | }
36 | return properties;
37 | }
38 |
39 | function coreContains (array, element) {
40 | return array.indexOf(element) >= 0;
41 | }
42 |
43 | function includeUnique(array, element) {
44 | if (!coreContains(array, element)) {
45 | array.push(element);
46 | }
47 | return array;
48 | }
49 |
50 | function coreEraseOne(array, element) {
51 | element = array.indexOf(element);
52 | if (element != -1) {
53 | array.splice( element, 1 );
54 | }
55 | return array;
56 | }
57 |
58 | function coreEraseAll(array, element) {
59 | for (var i = array.length; i--;) {
60 | if (array[i] == element) {
61 | array.splice( i, 1 );
62 | }
63 | }
64 | return array;
65 | }
66 | function coreToArray (elem) { return slice.call(elem) }
67 | function coreIsArrayLike (item) {
68 | return item && (Array.isArray(item) || (
69 | typeof item != 'string' &&
70 | !coreIsFunction(item) &&
71 | typeof item.nodeName != 'string' &&
72 | typeof item.length == 'number'
73 | ));
74 | }
75 | function coreAppend(target, source) {
76 | if (source) for (var key in source) if (hasOwn.call(source, key)) {
77 | target[key] = source[key];
78 | }
79 | return target;
80 | }
81 |
82 | new function () {
83 |
84 | function ensureObjectSetter (fn) {
85 | return function (properties, value) {
86 | return fn.call(this, coreObjectize(properties, value))
87 | }
88 | }
89 | function overloadSetter (fn) {
90 | return function (properties, value) {
91 | properties = coreObjectize(properties, value);
92 | for (var i in properties) fn.call( this, i, properties[i] );
93 | return this;
94 | };
95 | }
96 | function overloadGetter (fn, ignoreEmpty) {
97 | return function (properties) {
98 | if (Array.isArray(properties)) {
99 | var result = {}, name, value;
100 | for (var i = properties.length; i--;) {
101 | name = properties[i];
102 | value = fn.call(this, name);
103 | if (!ignoreEmpty || typeof value !== 'undefined') {
104 | result[name] = value;
105 | }
106 | }
107 | return result;
108 | }
109 | return fn.call(this, properties);
110 | };
111 | }
112 | /**
113 | * Returns function that calls callbacks.get
114 | * if first parameter is primitive & second parameter is undefined
115 | * object.attr('name') - get
116 | * object.attr('name', 'value') - set
117 | * object.attr({name: 'value'}) - set
118 | * @param {Object} callbacks
119 | * @param {Function} callbacks.get
120 | * @param {Function} callbacks.set
121 | */
122 | function slickAccessor (callbacks) {
123 | var setter = atom.core.overloadSetter(callbacks.set);
124 |
125 | return function (properties, value) {
126 | if (typeof value === 'undefined' && typeof properties !== 'object') {
127 | return callbacks.get.call(this, properties);
128 | } else {
129 | return setter.call(this, properties, value);
130 | }
131 | };
132 | }
133 |
134 | atom.core = {
135 | isFunction: coreIsFunction,
136 | objectize : coreObjectize,
137 | contains : coreContains,
138 | eraseOne : coreEraseOne,
139 | eraseAll : coreEraseAll,
140 | toArray : coreToArray,
141 | append : coreAppend,
142 | isArrayLike : coreIsArrayLike,
143 | includeUnique : includeUnique,
144 | slickAccessor : slickAccessor,
145 | overloadSetter: overloadSetter,
146 | overloadGetter: overloadGetter,
147 | ensureObjectSetter: ensureObjectSetter
148 | };
149 |
150 | /** @deprecated - use atom.core.toArray instead */
151 | atom.toArray = coreToArray;
152 | /** @deprecated - use console-cap instead: https://github.com/theshock/console-cap/ */
153 | atom.log = function () { throw new Error('deprecated') };
154 | /** @deprecated - use atom.core.isArrayLike instead */
155 | atom.isArrayLike = coreIsArrayLike;
156 | /** @deprecated - use atom.core.append instead */
157 | atom.append = coreAppend;
158 |
159 | };
--------------------------------------------------------------------------------
/Source/CoreExtended.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "CoreExtended"
5 |
6 | description: "Extended core of AtomJS - extend, implements, clone, typeOf"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | inspiration:
13 | - "[JQuery](http://jquery.com)"
14 | - "[MooTools](http://mootools.net)"
15 |
16 | provides: CoreExtended
17 |
18 | requires:
19 | - js185
20 | - Core
21 |
22 | ...
23 | */
24 |
25 | new function () {
26 |
27 | function innerExtend (proto) {
28 | return function (elem, from) {
29 | if (from == null) {
30 | from = elem;
31 | elem = atom;
32 | }
33 |
34 | var ext = proto ? elem.prototype : elem,
35 | accessors = atom.accessors && atom.accessors.inherit;
36 |
37 | for (var i in from) if (i != 'constructor') {
38 | if ( accessors && accessors(from, ext, i) ) continue;
39 |
40 | ext[i] = clone(from[i]);
41 | }
42 | return elem;
43 | };
44 | }
45 |
46 | function typeOf (item) {
47 | if (item == null) return 'null';
48 |
49 | var string = toString.call(item);
50 | for (var i in typeOf.types) if (i == string) return typeOf.types[i];
51 |
52 | if (item.nodeName){
53 | if (item.nodeType == 1) return 'element';
54 | if (item.nodeType == 3) return /\S/.test(item.nodeValue) ? 'textnode' : 'whitespace';
55 | }
56 |
57 | var type = typeof item;
58 |
59 | if (item && type == 'object') {
60 | if (atom.Class && item instanceof atom.Class) return 'class';
61 | if (coreIsArrayLike(item)) return 'arguments';
62 | }
63 |
64 | return type;
65 | }
66 |
67 | typeOf.types = {};
68 | ['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Class'].forEach(function(name) {
69 | typeOf.types['[object ' + name + ']'] = name.toLowerCase();
70 | });
71 |
72 |
73 | function clone (object) {
74 | var type = typeOf(object);
75 | return type in clone.types ? clone.types[type](object) : object;
76 | }
77 | clone.types = {
78 | 'array': function (array) {
79 | var i = array.length, c = new Array(i);
80 | while (i--) c[i] = clone(array[i]);
81 | return c;
82 | },
83 | 'class':function (object) {
84 | return typeof object.clone == 'function' ?
85 | object.clone() : object;
86 | },
87 | 'object': function (object) {
88 | if (typeof object.clone == 'function') return object.clone();
89 |
90 | var c = {}, accessors = atom.accessors && atom.accessors.inherit;
91 | for (var key in object) {
92 | if (accessors && accessors(object, c, key)) continue;
93 | c[key] = clone(object[key]);
94 | }
95 | return c;
96 | }
97 | };
98 |
99 | atom.core.extend = innerExtend(false);
100 | atom.core.implement = innerExtend(true);
101 | atom.core.typeOf = typeOf;
102 | atom.core.clone = clone;
103 |
104 | atom.extend = atom.core.extend;
105 | atom.implement = atom.core.implement;
106 | atom.typeOf = atom.core.typeOf;
107 | atom.clone = atom.core.clone;
108 |
109 | };
--------------------------------------------------------------------------------
/Source/Declare/Animatable.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Animatable"
5 |
6 | description: "Provides Color class"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - declare
15 | - frame
16 | - Transition
17 | - Events
18 | - Settings
19 | - Types.Object
20 |
21 | provides: Animatable
22 |
23 | ...
24 | */
25 |
26 | /** @class atom.Animatable */
27 | declare( 'atom.Animatable', {
28 |
29 | element: null,
30 |
31 | initialize: function (callbacks, context) {
32 | this.bindMethods('animate');
33 | this.context = context || null;
34 |
35 | if (!callbacks) throw new TypeError( 'callbacks cant be null' );
36 |
37 | this.animations = [];
38 | if (this.isValidCallbacks(callbacks)) {
39 | this.callbacks = callbacks;
40 | } else {
41 | this.callbacks = this.getDefaultCallbacks(callbacks);
42 | }
43 | },
44 |
45 | get current () {
46 | return this.animations[0];
47 | },
48 |
49 | /**
50 | * Binded to `Animatable`
51 | * @returns {atom.Animatable.Animation}
52 | */
53 | animate: atom.core.ensureObjectSetter(function (properties) {
54 | return this.next(new atom.Animatable.Animation(this, properties));
55 | }),
56 |
57 | stop: function (all) {
58 | var current = this.current;
59 | if (current) {
60 | if (all) this.animations.length = 0;
61 | current.destroy('stop');
62 | }
63 | return this;
64 | },
65 |
66 | /** @private */
67 | getDefaultCallbacks: function (element) {
68 | return {
69 | get: function (property) {
70 | return atom.object.path.get(element, property);
71 | },
72 | set: atom.core.overloadSetter(function (property, value) {
73 | return atom.object.path.set(element, property, value);
74 | })
75 | };
76 | },
77 | /** @private */
78 | isValidCallbacks: function (callbacks) {
79 | return typeof callbacks == 'object' &&
80 | Object.keys(callbacks).length == 2 &&
81 | coreIsFunction(callbacks.set) &&
82 | coreIsFunction(callbacks.get);
83 | },
84 |
85 | /** @private */
86 | animations: null,
87 |
88 | /** @private */
89 | next: function (animation) {
90 | var queue = this.animations;
91 | if (animation) {
92 | queue.push(animation);
93 | if (queue.length == 1) {
94 | this.launch(animation);
95 | }
96 | } else if (queue.length) {
97 | this.launch(this.current);
98 | }
99 | return animation;
100 | },
101 | /** @private */
102 | launch: function (animation) {
103 | var queue = this.animations, animatable = this;
104 | animation.events.add('destroy', function remove () {
105 | queue.splice(queue.indexOf(animation), 1);
106 | animation.events.remove('destroy', remove);
107 | animatable.next();
108 | });
109 | animation.start();
110 | },
111 | /** @private */
112 | get: function (name) {
113 | return this.callbacks.get.apply(this.context, arguments);
114 | },
115 | /** @private */
116 | set: function (name, value) {
117 | return this.callbacks.set.apply(this.context, arguments);
118 | }
119 | });
120 |
121 | /** @class atom.Animatable.Animation */
122 | declare( 'atom.Animatable.Animation', {
123 | /** @property {atom.Animatable} */
124 | animatable: null,
125 |
126 | /**
127 | * initial values of properties
128 | * @property {Object}
129 | */
130 | initial: null,
131 |
132 | /**
133 | * target values of properties
134 | * @property {Object}
135 | */
136 | target: null,
137 |
138 | initialize: function (animatable, settings) {
139 | this.bindMethods([ 'tick', 'start' ]);
140 |
141 | if (!settings.props) settings = {props: settings};
142 | this.events = new atom.Events(animatable);
143 | this.settings = new atom.Settings({
144 | fn : 'linear',
145 | time: 500
146 | })
147 | .set(settings)
148 | .addEvents(this.events);
149 | this.animatable = animatable;
150 | this.transition = atom.Transition.get(this.settings.get('fn'));
151 | this.allTime = this.settings.get('time');
152 | this.target = this.settings.get('props');
153 | },
154 |
155 | start: function () {
156 | this.initial = this.fetchInitialValues();
157 | this.delta = this.countValuesDelta();
158 | this.timeLeft = this.allTime;
159 | this.events.fire( 'start', [ this ]);
160 | atom.frame.add(this.tick);
161 | return this;
162 | },
163 |
164 | /** @private */
165 | countValuesDelta: function () {
166 | var initial = this.initial;
167 | return atom.object.map(this.target, function (value, key) {
168 | var start = initial[key];
169 | if (atom.Color && start instanceof atom.Color) {
170 | return start.diff( new atom.Color(value) );
171 | } else {
172 | return value - start;
173 | }
174 | });
175 | },
176 |
177 | /** @private */
178 | fetchInitialValues: function () {
179 | var animatable = this.animatable;
180 | return atom.object.map(this.target, function (value, key) {
181 | var v = animatable.get(key);
182 | if (atom.Color && atom.Color.isColorString(value) || value instanceof atom.Color) {
183 | if (!v) {
184 | v = new atom.Color(value);
185 | v.alpha = 0;
186 | return v;
187 | }
188 | return new atom.Color(v);
189 | } else if (isNaN(v)) {
190 | throw new Error('value is not animatable: ' + v);
191 | } else {
192 | return v;
193 | }
194 | });
195 | },
196 |
197 | /** @private */
198 | changeValues: function (progress) {
199 | var delta = this.delta, animatable = this.animatable, initial, target;
200 | for (var i in delta) if (delta.hasOwnProperty(i)) {
201 | if (progress == null) {
202 | target = this.target[i];
203 | animatable.set( i,
204 | atom.Color && target instanceof atom.Color
205 | ? target.toString() : target
206 | );
207 | } else {
208 | initial = this.initial[i];
209 | animatable.set( i,
210 | atom.Color && initial instanceof atom.Color ?
211 | initial.clone().move(delta[i].clone().mul(progress)).toString() :
212 | initial + delta[i] * progress
213 | );
214 | }
215 | }
216 | },
217 |
218 | /** @private */
219 | tick: function (time) {
220 | var lastTick = time >= this.timeLeft;
221 | this.timeLeft = lastTick ? 0 : this.timeLeft - time;
222 |
223 | this.changeValues(this.transition(
224 | lastTick ? 1 : (this.allTime - this.timeLeft) / this.allTime
225 | ));
226 | this.events.fire( 'tick', [ this ]);
227 |
228 | if (lastTick) this.destroy('complete');
229 | },
230 |
231 | destroy: function (type) {
232 | if (!type) type = 'error';
233 | this.events.fire( type, [ this ]);
234 | this.events.fire( 'destroy', [ this ]);
235 | atom.frame.remove(this.tick);
236 | return this;
237 | }
238 | });
239 |
240 | if (atom.dom) (function (animatable) {
241 | var accessors = {
242 | get: function (name) {
243 | var value = this.css(name);
244 | return atom.Color && atom.Color.isColorString(value) ? value : parseFloat(value);
245 | },
246 | set: function (name, value) {
247 | this.css(name, value);
248 | }
249 | };
250 |
251 | atom.dom.prototype.animate = atom.core.ensureObjectSetter(function (params) {
252 | this.each(function (elem) {
253 | if (!elem[animatable]) {
254 | elem[animatable] = new atom.Animatable(accessors, atom.dom(elem));
255 | }
256 | elem[animatable].animate(params);
257 | });
258 | return this
259 | });
260 |
261 | atom.dom.prototype.stopAnimation = function (force) {
262 | this.each(function (elem) {
263 | if (elem[animatable]) {
264 | elem[animatable].stop(force);
265 | }
266 | });
267 | return this;
268 | };
269 | })('atom.animatable');
--------------------------------------------------------------------------------
/Source/Declare/ClassCompat.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "ClassCompat"
5 |
6 | description: "Contains the Class Function for easily creating, extending, and implementing reusable Classes."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - CoreExtended
15 | - declare
16 |
17 | provides: ClassCompat
18 | ...
19 | */
20 |
21 | declare( 'atom.Settings.Mixin',
22 | /** @deprecated */
23 | {
24 | /**
25 | * @private
26 | * @property atom.Settings
27 | */
28 | settings: null,
29 | options : {},
30 |
31 | setOptions: function (options) {
32 | if (!this.settings) {
33 | this.settings = new atom.Settings(
34 | atom.clone(this.options || {})
35 | );
36 | this.options = this.settings.values;
37 | }
38 |
39 | for (var i = 0; i < arguments.length; i++) {
40 | this.settings.set(arguments[i]);
41 | }
42 |
43 | return this;
44 | }
45 | });
46 |
47 | declare( 'atom.Events.Mixin', new function () {
48 | var init = function () {
49 | var events = this.__events;
50 | if (!events) events = this.__events = new atom.Events(this);
51 | if (this._events) {
52 | for (var name in this._events) if (name != '$ready') {
53 | this._events[name].forEach(function (fn) {
54 | events.add(name, fn);
55 | });
56 | }
57 | }
58 | return events;
59 | };
60 |
61 | var method = function (method, useReturn) {
62 | return function () {
63 | var result, events = init.call(this);
64 |
65 | result = events[method].apply( events, arguments );
66 | return useReturn ? result : this;
67 | }
68 | };
69 |
70 | return {
71 | get events ( ) { return init.call(this); },
72 | set events (e) { this.__events = e; },
73 | isEventAdded: method( 'exists', true ),
74 | addEvent : method( 'add' , false ),
75 | removeEvent : method( 'remove', false ),
76 | fireEvent : method( 'fire' , false ),
77 | readyEvent : method( 'ready' , false )
78 | };
79 | });
--------------------------------------------------------------------------------
/Source/Declare/Color.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Color"
5 |
6 | description: "Provides Color class"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - declare
15 |
16 | provides: Color
17 |
18 | ...
19 | */
20 | /** @class atom.Color */
21 | declare( 'atom.Color', {
22 | initialize: function (value) {
23 | var a = arguments, type;
24 | if (a.length == 4 || a.length == 3) {
25 | value = slice.call(a);
26 | } else if (value && value.length == 1) {
27 | value = value[0];
28 | }
29 |
30 | type = typeof value;
31 | if (Array.isArray(value)) {
32 | this.fromArray(value);
33 | } else if (type == 'number') {
34 | this.fromNumber(value);
35 | } else if (type == 'string') {
36 | this.fromString(value);
37 | } else if (type == 'object') {
38 | this.fromObject(value);
39 | } else {
40 | throw new TypeError('Unknown type in atom.Color: ' + typeof value + ';\n' + value);
41 | }
42 | },
43 |
44 | /** @private */
45 | r: 0,
46 | /** @private */
47 | g: 0,
48 | /** @private */
49 | b: 0,
50 | /** @private */
51 | a: 1,
52 |
53 | /**
54 | * We are array-like object (looks at accessors at bottom of class)
55 | * @constant
56 | */
57 | length: 4,
58 |
59 | noLimits: false,
60 |
61 | get red () { return this.r; },
62 | get green () { return this.g; },
63 | get blue () { return this.b; },
64 | get alpha () { return this.a; },
65 |
66 | set red (v) { this.setValue('r', v) },
67 | set green (v) { this.setValue('g', v) },
68 | set blue (v) { this.setValue('b', v) },
69 | set alpha (v) { this.setValue('a', v, true) },
70 |
71 | /** @private */
72 | safeAlphaSet: function (v) {
73 | if (v != null) {
74 | this.alpha = Math.round(v*1000)/1000;
75 | }
76 | },
77 |
78 | /** @private */
79 | setValue: function (prop, value, isFloat) {
80 | value = Number(value);
81 | if (value != value) { // isNaN
82 | throw new TypeError('Value is NaN (' + prop + '): ' + value);
83 | }
84 |
85 | if (!isFloat) value = Math.round(value);
86 | // We don't want application down, if user script (e.g. animation)
87 | // generates such wrong array: [150, 125, -1]
88 | // `noLimits` switch off this check
89 | this[prop] = this.noLimits ? value :
90 | atom.number.limit( value, 0, isFloat ? 1 : 255 );
91 | },
92 |
93 | // Parsing
94 |
95 | /**
96 | * @param {int[]} array
97 | * @returns {atom.Color}
98 | */
99 | fromArray: function (array) {
100 | if (!array || array.length < 3 || array.length > 4) {
101 | throw new TypeError('Wrong array in atom.Color: ' + array);
102 | }
103 | this.red = array[0];
104 | this.green = array[1];
105 | this.blue = array[2];
106 | this.safeAlphaSet(array[3]);
107 | return this;
108 | },
109 | /**
110 | * @param {Object} object
111 | * @param {number} object.red
112 | * @param {number} object.green
113 | * @param {number} object.blue
114 | * @returns {atom.Color}
115 | */
116 | fromObject: function (object) {
117 | if (typeof object != 'object') {
118 | throw new TypeError( 'Not object in "fromObject": ' + typeof object );
119 | }
120 |
121 | function fetch (p1, p2) {
122 | return object[p1] != null ? object[p1] : object[p2]
123 | }
124 |
125 | this.red = fetch('r', 'red' );
126 | this.green = fetch('g', 'green');
127 | this.blue = fetch('b', 'blue' );
128 | this.safeAlphaSet(fetch('a', 'alpha'));
129 | return this;
130 | },
131 | /**
132 | * @param {string} string
133 | * @returns {atom.Color}
134 | */
135 | fromString: function (string) {
136 | if (!this.constructor.isColorString(string)) {
137 | throw new TypeError( 'Not color string in "fromString": ' + string );
138 | }
139 |
140 | var hex, array;
141 |
142 | string = string.toLowerCase();
143 | string = this.constructor.colorNames[string] || string;
144 |
145 | if (hex = string.match(/^#(\w{1,2})(\w{1,2})(\w{1,2})(\w{1,2})?$/)) {
146 | array = atom.array.clean(hex.slice(1));
147 | array = array.map(function (part) {
148 | if (part.length == 1) part += part;
149 | return parseInt(part, 16);
150 | });
151 | if (array.length == 4) array[3] /= 255;
152 | } else {
153 | array = string.match(/([\.\d]{1,})/g).map( Number );
154 | }
155 | return this.fromArray(array);
156 | },
157 | /**
158 | * @param {number} number
159 | * @returns {atom.Color}
160 | */
161 | fromNumber: function (number) {
162 | if (typeof number != 'number' || number < 0 || number > 0xffffffff) {
163 | throw new TypeError( 'Not color number in "fromNumber": ' + (number.toString(16)) );
164 | }
165 |
166 | return this.fromArray([
167 | (number>>24) & 0xff,
168 | (number>>16) & 0xff,
169 | (number>> 8) & 0xff,
170 | (number & 0xff) / 255
171 | ]);
172 | },
173 |
174 | // Casting
175 |
176 | /** @returns {int[]} */
177 | toArray: function () {
178 | return [this.r, this.g, this.b, this.a];
179 | },
180 | /** @returns {string} */
181 | toString: function (type) {
182 | var arr = this.toArray();
183 | if (type == 'hex' || type == 'hexA') {
184 | return '#' + arr.map(function (color, i) {
185 | if (i == 3) { // alpha
186 | if (type == 'hex') return '';
187 | color = Math.round(color * 255);
188 | }
189 | var bit = color.toString(16);
190 | return bit.length == 1 ? '0' + bit : bit;
191 | }).join('');
192 | } else {
193 | return 'rgba(' + arr + ')';
194 | }
195 | },
196 | /** @returns {number} */
197 | toNumber: function () {
198 | // maybe needs optimizations
199 | return parseInt( this.toString('hexA').substr(1) , 16)
200 | },
201 | /** @returns {object} */
202 | toObject: function (abbreviationNames) {
203 | return abbreviationNames ?
204 | { r : this.r, g : this.g, b : this.b, a : this.a } :
205 | { red: this.r, green: this.g, blue: this.b, alpha: this.a };
206 | },
207 |
208 | // manipulations
209 |
210 | /**
211 | * @param {atom.Color} color
212 | * @returns {atom.Color}
213 | */
214 | diff: function (color) {
215 | // we can't use this.constructor, because context exists in such way
216 | // && invoke is not called
217 | color = atom.Color( color );
218 | return new atom.Color.Shift([
219 | color.red - this.red ,
220 | color.green - this.green,
221 | color.blue - this.blue ,
222 | color.alpha - this.alpha
223 | ]);
224 | },
225 | /**
226 | * @param {atom.Color} color
227 | * @returns {atom.Color}
228 | */
229 | move: function (color) {
230 | color = atom.Color.Shift(color);
231 | this.red += color.red ;
232 | this.green += color.green;
233 | this.blue += color.blue ;
234 | this.alpha += color.alpha;
235 | return this;
236 | },
237 | /** @deprecated - use `clone`+`move` instead */
238 | shift: function (color) {
239 | return this.clone().move(color);
240 | },
241 | map: function (fn) {
242 | var color = this;
243 | ['red', 'green', 'blue', 'alpha'].forEach(function (component) {
244 | color[component] = fn.call( color, color[component], component, color );
245 | });
246 | return color;
247 | },
248 | add: function (factor) {
249 | return this.map(function (value) {
250 | return value + factor;
251 | });
252 | },
253 | mul: function (factor) {
254 | return this.map(function (value) {
255 | return value * factor;
256 | });
257 | },
258 | /**
259 | * @param {atom.Color} color
260 | * @returns {boolean}
261 | */
262 | equals: function (color) {
263 | return color &&
264 | color instanceof this.constructor &&
265 | color.red == this.red &&
266 | color.green == this.green &&
267 | color.blue == this.blue &&
268 | color.alpha == this.alpha;
269 | },
270 |
271 | /** @private */
272 | dump: function () {
273 | return '[atom.Color(' + this.toString('hexA') + ')]';
274 | },
275 |
276 | /**
277 | * @returns {atom.Color}
278 | */
279 | clone: function () {
280 | return new this.constructor(this);
281 | }
282 | }).own({
283 | invoke: declare.castArguments,
284 |
285 | /**
286 | * Checks if string is color description
287 | * @param {string} string
288 | * @returns {boolean}
289 | */
290 | isColorString : function (string) {
291 | if (typeof string != 'string') return false;
292 | return Boolean(
293 | string in this.colorNames ||
294 | string.match(/^#\w{3,6}$/) ||
295 | string.match(/^rgba?\([\d\., ]+\)$/)
296 | );
297 | },
298 |
299 | colorNames: {
300 | white: '#ffffff',
301 | silver: '#c0c0c0',
302 | gray: '#808080',
303 | black: '#000000',
304 | red: '#ff0000',
305 | maroon: '#800000',
306 | yellow: '#ffff00',
307 | olive: '#808000',
308 | lime: '#00ff00',
309 | green: '#008000',
310 | aqua: '#00ffff',
311 | teal: '#008080',
312 | blue: '#0000ff',
313 | navy: '#000080',
314 | fuchsia:'#ff00ff',
315 | purple: '#800080',
316 | orange: '#ffa500'
317 | },
318 |
319 | /**
320 | * @param {boolean} [html=false] - only html color names
321 | * @returns {atom.Color}
322 | */
323 | random: function (html) {
324 | var source, random = atom.number.random;
325 |
326 | if (html) {
327 | source = atom.array.random( this.colorNamesList );
328 | } else {
329 | source = [ random(0, 255), random(0, 255), random(0, 255) ];
330 | }
331 |
332 | return new this(source);
333 | }
334 | });
335 |
336 | atom.Color.colorNamesList = Object.keys(atom.Color.colorNames);
337 |
338 | /** @class atom.Color.Shift */
339 | declare( 'atom.Color.Shift', atom.Color, { noLimits: true });
--------------------------------------------------------------------------------
/Source/Declare/Declare.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Declare"
5 |
6 | description: "Contains the Class Function for easily creating, extending, and implementing reusable Classes."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - accessors
15 |
16 | provides: declare
17 |
18 | ...
19 | */
20 |
21 | var declare = (function(atom){
22 |
23 | var
24 | declare, methods,
25 | accessors = atom.accessors.inherit,
26 | factory = false,
27 | prototyping = false,
28 | mutators = [];
29 |
30 | declare = function (declareName, Parent, params) {
31 | if (prototyping) return this;
32 |
33 | params = methods.prepareParams(declareName, Parent, params);
34 |
35 | // line break for more user-friendly debug string
36 | var Constructor = function ()
37 | { return methods.construct.call(this, Constructor, arguments) };
38 |
39 | // - should be removed on production
40 | if (params.name) {
41 | Constructor = new Function('con', 'return {"' + params.name + '": ' +
42 | function(){ return con.apply(this, arguments) }
43 | + '}["' + params.name + '"];')(Constructor);
44 | }
45 | //
46 |
47 | for (var i = 0, l = mutators.length; i < l; i++) {
48 | mutators[i].fn( Constructor, params[mutators[i].name] );
49 | }
50 |
51 | Constructor.prototype.constructor = Constructor;
52 |
53 | if (params.declareName) methods.define( params.declareName, Constructor );
54 |
55 | return Constructor;
56 | };
57 |
58 | declare.prototype.bindMethods = function (methods) {
59 | var i;
60 |
61 | if (typeof methods == 'string') {
62 | if (typeof this[methods] == 'function') {
63 | this[methods] = this[methods].bind(this);
64 | }
65 | return this;
66 | }
67 |
68 | if (!methods) {
69 | for (i in this) this.bindMethods(i);
70 | return this;
71 | }
72 |
73 | for (i = methods.length; i--;) this.bindMethods( methods[i] );
74 | return this;
75 | };
76 |
77 | declare.prototype.toString = function () {
78 | return '[object ' + (this.constructor.NAME || 'Declare') + ']';
79 | };
80 |
81 | declare.NAME = 'atom.declare';
82 |
83 | declare.invoke = function () {
84 | return this.factory( arguments );
85 | };
86 |
87 | declare.own = function (properties) {
88 | methods.addTo(this, properties, this.NAME + '.');
89 | return this;
90 | };
91 |
92 | declare.factory = function (args) {
93 | factory = true;
94 | return new this(args);
95 | };
96 |
97 | declare.castArguments = function (args) {
98 | if (args == null) return null;
99 |
100 | var constructor = this;
101 |
102 | return (args != null && args[0] && args[0] instanceof constructor) ?
103 | args[0] : args instanceof constructor ? args : new constructor( args );
104 | };
105 |
106 | methods = {
107 | define: function (path, value) {
108 | var key, part, target = atom.global;
109 |
110 | path = path.split('.');
111 | key = path.pop();
112 |
113 | while (path.length) {
114 | part = path.shift();
115 | if (!target[part]) {
116 | target = target[part] = {};
117 | } else {
118 | target = target[part];
119 | }
120 | }
121 |
122 | target[key] = value;
123 | },
124 | mixin: function (target, items) {
125 | if (!Array.isArray(items)) items = [ items ];
126 | for (var i = 0, l = items.length; i < l; i++) {
127 | methods.addTo( target.prototype, methods.proto(items[i]) );
128 | }
129 | return this;
130 | },
131 | addTo: function (target, source, name) {
132 | var i, property;
133 | if (source) for (i in source) if (source.hasOwnProperty(i)) {
134 | if (!accessors(source, target, i) && source[i] != declare.config) {
135 | property = source[i];
136 | if (coreIsFunction(property)) {
137 | if (name) property.path = name + i;
138 | if (!property.previous && coreIsFunction(target[i])) {
139 | property.previous = target[i];
140 | }
141 | }
142 | target[i] = property;
143 | }
144 | }
145 | return target;
146 | },
147 | prepareParams: function (declareName, Parent, params) {
148 | if (typeof declareName != 'string') {
149 | params = Parent;
150 | Parent = declareName;
151 | declareName = null;
152 | }
153 |
154 | if (params == null && typeof Parent != 'function') {
155 | params = Parent;
156 | Parent = null;
157 | }
158 |
159 | if (!params ) params = {};
160 | if (!params.prototype ) params = { prototype: params };
161 | if (!params.name ) params.name = declareName;
162 | if (!params.declareName ) params.declareName = declareName;
163 | if (!params.parent && Parent) params.parent = Parent;
164 |
165 | if (!params.prototype.initialize) {
166 | params.prototype.initialize = function () {
167 | if (!params.parent) return;
168 | return params.parent.prototype.initialize.apply(this, arguments);
169 | };
170 | }
171 | return params;
172 | },
173 | proto: function (Fn) {
174 | prototyping = true;
175 | var result = new Fn;
176 | prototyping = false;
177 | return result;
178 | },
179 | construct: function (Constructor, args) {
180 | if (factory) {
181 | args = args[0];
182 | factory = false;
183 | }
184 |
185 | if (prototyping) return this;
186 |
187 | if (this instanceof Constructor) {
188 | if (Constructor.NAME) this.Constructor = Constructor.NAME;
189 | return this.initialize.apply(this, args);
190 | } else {
191 | return Constructor.invoke.apply(Constructor, args);
192 | }
193 | }
194 | };
195 |
196 | declare.config = {
197 | methods: methods,
198 | mutator: atom.core.overloadSetter(function (name, fn) {
199 | mutators.push({ name: name, fn: fn });
200 | return this;
201 | })
202 | };
203 |
204 | declare.config
205 | .mutator( 'parent', function (Constructor, parent) {
206 | parent = parent || declare;
207 | methods.addTo( Constructor, parent );
208 | Constructor.prototype = methods.proto( parent );
209 | Constructor.Parent = parent;
210 | })
211 | .mutator( 'mixin', function (Constructor, mixins) {
212 | if (mixins) methods.mixin( Constructor, mixins );
213 | })
214 | .mutator( 'name', function (Constructor, name) {
215 | if (!name) return;
216 | Constructor.NAME = name;
217 | })
218 | .mutator( 'own', function (Constructor, properties) {
219 | Constructor.own(properties);
220 | })
221 | .mutator( 'prototype', function (Constructor, properties) {
222 | methods.addTo(Constructor.prototype, properties, Constructor.NAME + '#');
223 | });
224 |
225 | return atom.declare = declare;
226 |
227 | })(atom);
--------------------------------------------------------------------------------
/Source/Declare/Events.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Events"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - declare
15 |
16 | inspiration:
17 | - "[MooTools](http://mootools.net)"
18 |
19 | provides: Events
20 |
21 | ...
22 | */
23 |
24 | /** @class atom.Events */
25 | declare( 'atom.Events', {
26 |
27 | /** @constructs */
28 | initialize: function (context) {
29 | this.context = context || this;
30 | this.locked = [];
31 | this.events = {};
32 | this.actions = {};
33 | this.readyList = {};
34 | },
35 |
36 | /**
37 | * @param {String} name
38 | * @return Boolean
39 | */
40 | exists: function (name) {
41 | var array = this.events[this.removeOn( name )];
42 | return !!(array && array.length);
43 | },
44 |
45 | /**
46 | * @param {String} name
47 | * @param {Function} callback
48 | * @return Boolean
49 | */
50 | add: function (name, callback) {
51 | this.run( 'addOne', name, callback );
52 | return this;
53 | },
54 |
55 | /**
56 | * @param {String} name
57 | * @param {Function} [callback]
58 | * @return Boolean
59 | */
60 | remove: function (name, callback) {
61 | if (typeof name == 'string' && !callback) {
62 | this.removeAll( name );
63 | } else {
64 | this.run( 'removeOne', name, callback );
65 | }
66 | return this;
67 | },
68 |
69 | /**
70 | * @param {String} name
71 | * @param {Array} args
72 | * @return atom.Events
73 | */
74 | fire: function (name, args) {
75 | args = args ? slice.call( args ) : [];
76 | name = this.removeOn( name );
77 |
78 | this.locked.push(name);
79 | var i = 0, l, events = this.events[name];
80 | if (events) for (l = events.length; i < l; i++) {
81 | events[i].apply( this.context, args );
82 | }
83 | this.unlock( name );
84 | return this;
85 | },
86 |
87 | /**
88 | * @param {String} name
89 | * @param {Array} [args=null]
90 | * @return atom.Events
91 | */
92 | ready: function (name, args) {
93 | name = this.removeOn( name );
94 | this.locked.push(name);
95 | if (name in this.readyList) {
96 | throw new Error( 'Event «'+name+'» is ready' );
97 | }
98 | this.readyList[name] = args;
99 | this.fire(name, args);
100 | this.removeAll(name);
101 | this.unlock( name );
102 | return this;
103 | },
104 |
105 | /**
106 | * @param {String} name
107 | * @param {Array} [args=null]
108 | * @return atom.Events
109 | */
110 | ensureReady: function (name, args) {
111 | if (!(name in this.readyList)) {
112 | this.ready(name, args);
113 | }
114 | return this;
115 | },
116 |
117 |
118 | // only private are below
119 |
120 | /** @private */
121 | context: null,
122 | /** @private */
123 | events: {},
124 | /** @private */
125 | readyList: {},
126 | /** @private */
127 | locked: [],
128 | /** @private */
129 | actions: {},
130 |
131 | /** @private */
132 | removeOn: function (name) {
133 | return (name || '').replace(/^on([A-Z])/, function(full, first){
134 | return first.toLowerCase();
135 | });
136 | },
137 | /** @private */
138 | removeAll: function (name) {
139 | var events = this.events[name];
140 | if (events) for (var i = events.length; i--;) {
141 | this.removeOne( name, events[i] );
142 | }
143 | },
144 | /** @private */
145 | unlock: function (name) {
146 | var action,
147 | all = this.actions[name],
148 | index = this.locked.indexOf( name );
149 |
150 | this.locked.splice(index, 1);
151 |
152 | if (all) for (index = 0; index < all.length; index++) {
153 | action = all[index];
154 |
155 | this[action.method]( name, action.callback );
156 | }
157 | },
158 | /** @private */
159 | run: function (method, name, callback) {
160 | var i = 0, l = 0;
161 |
162 | if (Array.isArray(name)) {
163 | for (i = 0, l = name.length; i < l; i++) {
164 | this[method](name[i], callback);
165 | }
166 | } else if (typeof name == 'object') {
167 | for (i in name) {
168 | this[method](i, name[i]);
169 | }
170 | } else if (typeof name == 'string') {
171 | this[method](name, callback);
172 | } else {
173 | throw new TypeError( 'Wrong arguments in Events.' + method );
174 | }
175 | },
176 | /** @private */
177 | register: function (name, method, callback) {
178 | var actions = this.actions;
179 | if (!actions[name]) {
180 | actions[name] = [];
181 | }
182 | actions[name].push({ method: method, callback: callback })
183 | },
184 | /** @private */
185 | addOne: function (name, callback) {
186 | var events, ready, context;
187 |
188 | name = this.removeOn( name );
189 |
190 | if (this.locked.indexOf(name) == -1) {
191 | ready = this.readyList[name];
192 | if (ready) {
193 | context = this.context;
194 | setTimeout(function () {
195 | callback.apply(context, ready);
196 | }, 0);
197 | return this;
198 | } else {
199 | events = this.events;
200 | if (!events[name]) {
201 | events[name] = [callback];
202 | } else {
203 | events[name].push(callback);
204 | }
205 | }
206 | } else {
207 | this.register(name, 'addOne', callback);
208 | }
209 | },
210 | /** @private */
211 | removeOne: function (name, callback) {
212 | name = this.removeOn( name );
213 |
214 | if (this.locked.indexOf(name) == -1) {
215 | var events = this.events[name], i = events.length;
216 | while (i--) if (events[i] == callback) {
217 | events.splice(i, 1);
218 | }
219 | } else {
220 | this.register(name, 'removeOne', callback);
221 | }
222 | }
223 | });
224 |
225 | // local alias
226 | var Events = atom.Events;
--------------------------------------------------------------------------------
/Source/Declare/ImagePreloader.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "ImagePreloader"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - declare
14 | - Events
15 | - Settings
16 |
17 | provides: ImagePreloader
18 |
19 | ...
20 | */
21 |
22 | atom.declare( 'atom.ImagePreloader', {
23 | processed : 0,
24 | number : 0,
25 |
26 | initialize: function (settings) {
27 | this.events = new Events(this);
28 | this.settings = new Settings(settings).addEvents(this.events);
29 |
30 | this.count = {
31 | error: 0,
32 | abort: 0,
33 | load : 0
34 | };
35 |
36 | this.suffix = this.settings.get('suffix') || '';
37 | this.usrImages = this.prefixImages(this.settings.get('images'));
38 | this.imageUrls = this.fetchUrls();
39 | this.domImages = {};
40 | //this.domImages = this.createDomImages();
41 | this.images = {};
42 | this.createNext();
43 | },
44 | get isReady () {
45 | return this.number == this.processed;
46 | },
47 | get info () {
48 | var stat = atom.string.substitute(
49 | "Images loaded: {load}; Errors: {error}; Aborts: {abort}",
50 | this.count
51 | );
52 | if (this.isReady) stat = "Image preloading has completed;\n" + stat;
53 | return stat;
54 | },
55 | get progress () {
56 | return this.isReady ? 1 : atom.number.round(this.processed / this.number, 4);
57 | },
58 | append: function (preloader) {
59 | for (var i in preloader.images) {
60 | this.images[i] = preloader.images[i];
61 | }
62 | return this;
63 | },
64 | exists: function (name) {
65 | return !!this.images[name];
66 | },
67 | get: function (name) {
68 | var image = this.images[name];
69 | if (image) {
70 | return image;
71 | } else {
72 | throw new Error('No image «' + name + '»');
73 | }
74 | },
75 |
76 | /** @private */
77 | cropImage: function (img, c) {
78 | if (!c) return img;
79 |
80 | var canvas = document.createElement('canvas');
81 | canvas.width = c[2];
82 | canvas.height = c[3];
83 | canvas.getContext('2d').drawImage( img,
84 | c[0], c[1], c[2], c[3], 0, 0, c[2], c[3]
85 | );
86 | return canvas;
87 | },
88 | /** @private */
89 | withoutPrefix: function (src) {
90 | return src.indexOf('http://') === 0 || src.indexOf('https://') === 0;
91 | },
92 | /** @private */
93 | prefixImages: function (images) {
94 | var prefix = this.settings.get('prefix');
95 | if (!prefix) return images;
96 |
97 | return atom.object.map(images, function (src) {
98 | return this.withoutPrefix(src) ? src : prefix + src;
99 | }.bind(this));
100 | },
101 | /** @private */
102 | cutImages: function () {
103 | var i, parts, img;
104 | for (i in this.usrImages) if (this.usrImages.hasOwnProperty(i)) {
105 | parts = this.splitUrl( this.usrImages[i] );
106 | img = this.domImages[ parts.url ];
107 | this.images[i] = this.cropImage(img, parts.coords);
108 | }
109 | return this;
110 | },
111 | /** @private */
112 | splitUrl: function (str) {
113 | var url = str, size, cell, match, coords = null;
114 |
115 | // searching for pattern 'url [x:y:w:y]'
116 | if (match = str.match(/ \[(\d+):(\d+):(\d+):(\d+)\]$/)) {
117 | coords = match.slice( 1 );
118 | // searching for pattern 'url [w:y]{x:y}'
119 | } else if (match = str.match(/ \[(\d+):(\d+)\]\{(\d+):(\d+)\}$/)) {
120 | coords = match.slice( 1 ).map( Number );
121 | size = coords.slice( 0, 2 );
122 | cell = coords.slice( 2, 4 );
123 | coords = [ cell[0] * size[0], cell[1] * size[1], size[0], size[1] ];
124 | }
125 | if (match) {
126 | url = str.substr(0, str.lastIndexOf(match[0]));
127 | coords = coords.map( Number );
128 | }
129 | if (this.suffix) {
130 | if (typeof this.suffix == 'function') {
131 | url = this.suffix( url );
132 | } else {
133 | url += this.suffix;
134 | }
135 | }
136 |
137 | return { url: url, coords: coords };
138 | },
139 | /** @private */
140 | fetchUrls: function () {
141 | var i, result = [], hash = {}, url, images = this.usrImages;
142 | for (i in images) if (images.hasOwnProperty(i)) {
143 | url = this.splitUrl( images[i] ).url;
144 | if (!hash[url]) {
145 | result.push(url);
146 | hash[url] = true;
147 | this.number++;
148 | }
149 | }
150 | return result;
151 | },
152 | /** @private */
153 | createDomImage : function (src) {
154 | var img = new Image();
155 | img.src = src;
156 | if (window.opera && img.complete) {
157 | setTimeout(this.onProcessed.bind(this, 'load', img), 10);
158 | } else {
159 | ['load', 'error', 'abort'].forEach(function (event) {
160 | img.addEventListener( event, this.onProcessed.bind(this, event, img), false );
161 | }.bind(this));
162 | }
163 | return img;
164 | },
165 | createNext: function () {
166 | if (this.imageUrls.length) {
167 | var url = this.imageUrls.shift();
168 | this.domImages[url] = this.createDomImage(url);
169 | }
170 | },
171 | resetImage: function (img) {
172 | // opera fullscreen bug workaround
173 | img.width = img.width;
174 | img.height = img.height;
175 | img.naturalWidth = img.naturalWidth;
176 | img.naturalHeight = img.naturalHeight;
177 | },
178 | /** @private */
179 | onProcessed : function (type, img) {
180 | if (type == 'load' && window.opera) {
181 | this.resetImage(img);
182 | }
183 | this.count[type]++;
184 | this.processed++;
185 | this.events.fire('progress', [this, img]);
186 |
187 | if (this.isReady) {
188 | this.cutImages();
189 | this.events.ensureReady('ready', [this]);
190 | } else {
191 | this.createNext();
192 | }
193 | return this;
194 | }
195 | }).own({
196 | run: function (images, callback, context) {
197 | var preloader = new this({ images: images });
198 |
199 | preloader.events.add( 'ready', context ? callback.bind(context) : callback );
200 |
201 | return preloader;
202 | }
203 | });
--------------------------------------------------------------------------------
/Source/Declare/Keyboard.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Keyboard"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - declare
14 | - Events
15 |
16 | provides: Keyboard
17 |
18 | ...
19 | */
20 |
21 | var Keyboard = function () {
22 |
23 | var
24 | keyName,
25 | codeNames = {},
26 | keyCodes = {
27 | // Alphabet
28 | a:65, b:66, c:67, d:68, e:69,
29 | f:70, g:71, h:72, i:73, j:74,
30 | k:75, l:76, m:77, n:78, o:79,
31 | p:80, q:81, r:82, s:83, t:84,
32 | u:85, v:86, w:87, x:88, y:89, z:90,
33 | // Numbers
34 | n0:48, n1:49, n2:50, n3:51, n4:52,
35 | n5:53, n6:54, n7:55, n8:56, n9:57,
36 | // Controls
37 | tab: 9, enter:13, shift:16, backspace:8,
38 | ctrl:17, alt :18, esc :27, space :32,
39 | menu:93, pause:19, cmd :91,
40 | insert :45, home:36, pageup :33,
41 | 'delete':46, end :35, pagedown:34,
42 | // F*
43 | f1:112, f2:113, f3:114, f4 :115, f5 :116, f6 :117,
44 | f7:118, f8:119, f9:120, f10:121, f11:122, f12:123,
45 | // numpad
46 | np0: 96, np1: 97, np2: 98, np3: 99, np4:100,
47 | np5:101, np6:102, np7:103, np8:104, np9:105,
48 | npslash:11,npstar:106,nphyphen:109,npplus:107,npdot:110,
49 | // Lock
50 | capslock:20, numlock:144, scrolllock:145,
51 |
52 | // Symbols
53 | equals: 61, hyphen :109, coma :188, dot:190,
54 | gravis:192, backslash:220, sbopen:219, sbclose:221,
55 | slash :191, semicolon: 59, apostrophe: 222,
56 |
57 | // Arrows
58 | aleft:37, aup:38, aright:39, adown:40
59 | };
60 |
61 | for (keyName in keyCodes) if (keyCodes.hasOwnProperty(keyName)) {
62 | codeNames[ keyCodes[keyName] ] = keyName;
63 | }
64 |
65 | /** @class atom.Keyboard */
66 | return declare( 'atom.Keyboard', {
67 | initialize : function (element, preventDefault) {
68 | if (Array.isArray(element)) {
69 | preventDefault = element;
70 | element = null;
71 | }
72 | if (element == null) element = document;
73 |
74 | if (element == document) {
75 | if (this.constructor.instance) {
76 | return this.constructor.instance;
77 | }
78 | this.constructor.instance = this;
79 | }
80 |
81 | this.events = new Events(this);
82 | this.keyStates = {};
83 | this.preventDefault = preventDefault;
84 |
85 | atom.dom(element).bind({
86 | keyup: this.keyEvent('up'),
87 | keydown: this.keyEvent('down'),
88 | keypress: this.keyEvent('press')
89 | });
90 | },
91 | /** @private */
92 | keyEvent: function (event) {
93 | return this.onKeyEvent.bind(this, event);
94 | },
95 | /** @private */
96 | onKeyEvent: function (event, e) {
97 | var key = this.constructor.keyName(e),
98 | prevent = this.prevent(key);
99 |
100 | e.keyName = key;
101 |
102 | if (prevent) e.preventDefault();
103 | this.events.fire( event, [e] );
104 |
105 | if (event == 'down') {
106 | this.events.fire(key, [e]);
107 | this.keyStates[key] = true;
108 | } else if (event == 'up') {
109 | this.events.fire(key + ':up', [e]);
110 | delete this.keyStates[key];
111 | } else if (event == 'press') {
112 | this.events.fire(key + ':press', [e]);
113 | }
114 |
115 | return !prevent;
116 | },
117 | /** @private */
118 | prevent : function (key) {
119 | var pD = this.preventDefault;
120 | return pD && (pD === true || pD.indexOf(key) >= 0);
121 | },
122 | key: function (keyName) {
123 | return !!this.keyStates[ this.constructor.keyName(keyName) ];
124 | }
125 | }).own({
126 | keyCodes : keyCodes,
127 | codeNames: codeNames,
128 | keyName: function (code) {
129 | if (code && code.keyCode != null) {
130 | code = code.keyCode;
131 | }
132 |
133 | var type = typeof code;
134 |
135 | if (type == 'number') {
136 | return this.codeNames[code];
137 | } else if (type == 'string' && code in this.keyCodes) {
138 | return code;
139 | }
140 |
141 | return null;
142 | }
143 | });
144 |
145 | }();
146 |
--------------------------------------------------------------------------------
/Source/Declare/Registry.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Registry"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - declare
14 |
15 | provides: Registry
16 |
17 | ...
18 | */
19 |
20 | /** @class atom.Registry */
21 | declare( 'atom.Registry', {
22 | items: {},
23 | initialize: function (initial) {
24 | this.items = {};
25 | if (initial) this.set(initial);
26 | },
27 | set: atom.core.overloadSetter(function (name, value) {
28 | this.items[name] = value;
29 | }),
30 | get: atom.core.overloadGetter(function (name) {
31 | return this.items[name];
32 | })
33 | });
34 |
35 | var Registry = atom.Registry;
--------------------------------------------------------------------------------
/Source/Declare/Settings.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Settings"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - declare
14 |
15 | provides: Settings
16 |
17 | ...
18 | */
19 |
20 | /** @class atom.Settings */
21 | declare( 'atom.Settings', {
22 | /** @private */
23 | recursive: false,
24 |
25 | /** @private */
26 | values: {},
27 |
28 | /**
29 | * @constructs
30 | * @param {Object} [initialValues]
31 | */
32 | initialize: function (initialValues) {
33 | this.values = {};
34 |
35 | if (initialValues) this.set(initialValues);
36 | },
37 |
38 | /**
39 | * @param {atom.Events} events
40 | * @return atom.Options
41 | */
42 | addEvents: function (events) {
43 | this.events = events;
44 | return this.invokeEvents();
45 | },
46 |
47 | /**
48 | * @param {string|Array} name
49 | */
50 | get: function (name, defaultValue) {
51 | if (Array.isArray(name)) return this.subset(name, defaultValue);
52 |
53 | return name in this.values ? this.values[name] : defaultValue;
54 | },
55 |
56 | /**
57 | * @param {object} target
58 | * @param {string[]} [names=undefined]
59 | * @return {atom.Settings}
60 | */
61 | properties: function (target, names) {
62 | var originalNames = this.propertiesNames;
63 |
64 | if (typeof names == 'string') {
65 | names = names.split(' ');
66 | }
67 |
68 | if (names == null || names === true) {
69 | this.propertiesNames = true;
70 | } else if (originalNames == null) {
71 | this.propertiesNames = names;
72 | } else if (originalNames !== true) {
73 | atom.array.append(originalNames, names);
74 | }
75 |
76 | this.propertiesTarget = target;
77 |
78 | for (var i in this.values) {
79 | this.exportProperty(i, this.values);
80 | }
81 |
82 | return this;
83 | },
84 |
85 | subset: function (names, defaultValue) {
86 | var i, values = {};
87 |
88 | for (i = names.length; i--;) {
89 | values[names[i]] = this.get( names[i], defaultValue );
90 | }
91 |
92 | return values;
93 | },
94 |
95 | /** @private */
96 | propertiesNames : null,
97 | /** @private */
98 | propertiesTarget: null,
99 |
100 | /**
101 | * @param {Object} options
102 | * @return atom.Options
103 | */
104 | set: function (options, value) {
105 | var i, values = this.values;
106 |
107 | options = this.prepareOptions(options, value);
108 |
109 | for (i in options) {
110 | value = options[i];
111 | if (values[i] != value) {
112 | values[i] = value;
113 | this.exportProperty(i, values);
114 | }
115 | }
116 |
117 | this.invokeEvents();
118 |
119 | return this;
120 | },
121 |
122 | /** @private */
123 | exportProperty: function (i, values) {
124 | var
125 | target = this.propertiesTarget,
126 | names = this.propertiesNames;
127 |
128 | if (target && (names === true || names.indexOf(i) >= 0)) {
129 | target[i] = values[i];
130 | }
131 | },
132 |
133 | /** @private */
134 | prepareOptions: function (options, value) {
135 | if (typeof options == 'string') {
136 | var i = options;
137 | options = {};
138 | options[i] = value;
139 | } else if (options instanceof this.constructor) {
140 | options = options.values;
141 | }
142 | return options;
143 | },
144 |
145 | /**
146 | * @param {String} name
147 | * @return atom.Options
148 | */
149 | unset: function (name) {
150 | delete this.values[name];
151 | return this;
152 | },
153 |
154 | /** @private */
155 | invokeEvents: function () {
156 | if (!this.events) return this;
157 |
158 | var values = this.values, name, option;
159 | for (name in values) if (values.hasOwnProperty(name)) {
160 | option = values[name];
161 | if (this.isInvokable(name, option)) {
162 | this.events.add(name, option);
163 | this.unset(name);
164 | }
165 | }
166 | return this;
167 | },
168 |
169 | /** @private */
170 | isInvokable: function (name, option) {
171 | return name &&
172 | option &&
173 | coreIsFunction(option) &&
174 | (/^on[A-Z]/).test(name);
175 | }
176 | });
177 |
178 | var Settings = atom.Settings;
--------------------------------------------------------------------------------
/Source/Declare/Trace.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "trace"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - declare
14 | - dom
15 | - CoreExtended
16 |
17 | provides: trace
18 |
19 | ...
20 | */
21 |
22 | atom.trace = declare( 'atom.trace', {
23 | initialize : function (object) {
24 | this.value = object;
25 | this.stopped = false;
26 | },
27 | set value (value) {
28 | if (!this.stopped) {
29 | var html = atom.string.replaceAll( this.constructor.dump(value), {
30 | '\t': ' '.repeat(3),
31 | '\n': ' '
32 | });
33 | this.createNode().html(html);
34 | }
35 | },
36 | destroy : function (force) {
37 | var trace = this;
38 | if (force) this.stop();
39 | if (trace.node) {
40 | trace.node.addClass('atom-trace-node-destroy');
41 | trace.timeout = setTimeout(function () {
42 | if (trace.node) {
43 | trace.node.destroy();
44 | trace.node = null;
45 | }
46 | }, 500);
47 | }
48 | return trace;
49 | },
50 | /** @private */
51 | stop : function () {
52 | this.stopped = true;
53 | return this;
54 | },
55 | /** @private */
56 | getContainer : function () {
57 | var cont = atom.dom('#atom-trace-container');
58 | return cont.length ? cont :
59 | atom.dom.create('div', { 'id' : 'atom-trace-container'})
60 | .appendTo('body');
61 | },
62 | /** @deprecated */
63 | trace : function (value) {
64 | this.value = value;
65 | return this;
66 | },
67 | /** @private */
68 | createNode : function () {
69 | var trace = this, node = trace.node;
70 |
71 | if (node) {
72 | if (trace.timeout) {
73 | clearTimeout(trace.timeout);
74 | node.removeClass('atom-trace-node-destroy');
75 | }
76 | return node;
77 | }
78 |
79 | return trace.node = atom.dom
80 | .create('div')
81 | .addClass('atom-trace-node')
82 | .appendTo(trace.getContainer())
83 | .bind({
84 | click : function () { trace.destroy(0) },
85 | dblclick : function () { trace.destroy(1) }
86 | });
87 | }
88 | }).own({
89 | dumpRec : function dumpRec (obj, level, plain) {
90 | var html = '', type, tabs;
91 |
92 | level = parseInt(level) || 0;
93 |
94 | if (level > 5) return '*TOO_DEEP*';
95 |
96 | if (obj && typeof obj == 'object' && coreIsFunction(obj.dump)) return obj.dump();
97 |
98 | function escape (v) {
99 | return plain ? v : atom.string.safeHtml(v);
100 | }
101 |
102 | function subDump (elem, index) {
103 | return tabs + '\t' + index + ': ' + dumpRec(elem, level+1, plain) + '\n';
104 | }
105 |
106 | type = atom.typeOf(obj);
107 | tabs = '\t'.repeat(level);
108 |
109 | switch (type) {
110 | case 'object':
111 | for (var index in obj) if (obj.hasOwnProperty(index)) {
112 | html += subDump(obj[index], index);
113 | }
114 | return '{\n' + html + tabs + '}';
115 |
116 | case 'element':
117 | var prop = (obj.width && obj.height) ? '('+obj.width+'×'+obj.height+')' : '';
118 | return '[DOM ' + obj.tagName.toLowerCase() + prop + ']';
119 |
120 | case 'textnode':
121 | case 'whitespace':
122 | return '[DOM ' + type + ']';
123 |
124 | case 'array' : return '[\n' + obj.map(subDump).join('') + tabs + ']';
125 | case 'null' : return 'null';
126 | case 'boolean': return obj ? 'true' : 'false';
127 | case 'string' : return escape('"' + obj + '"');
128 | default : return escape('' + obj);
129 | }
130 | },
131 | dumpPlain: function (object) {
132 | return (this.dumpRec(object, 0, true));
133 | },
134 | dump : function (object) {
135 | return (this.dumpRec(object, 0));
136 | }
137 | });
--------------------------------------------------------------------------------
/Source/Declare/Transition.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Transition"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - declare
15 |
16 | inspiration:
17 | - "[MooTools](http://mootools.net)"
18 |
19 | provides: Transition
20 |
21 | ...
22 | */
23 |
24 | atom.Transition = function (method, noEase) {
25 | var easeIn = function (progress) {
26 | return method(progress);
27 | };
28 |
29 | if (noEase) {
30 | return coreAppend( easeIn, {
31 | easeIn : easeIn,
32 | easeOut : easeIn,
33 | easeInOut: easeIn
34 | });
35 | }
36 |
37 | return coreAppend( easeIn, {
38 | easeIn: easeIn,
39 | easeOut: function(progress){
40 | return 1 - method(1 - progress);
41 | },
42 | easeInOut: function(progress){
43 | if (progress > 0.5) {
44 | return ( 2 - method(2 * (1 - progress)) ) /2
45 | } else {
46 | return method(2 * progress)/2;
47 | }
48 | }
49 | });
50 | };
51 |
52 | atom.Transition.set = atom.core.overloadSetter(function (id, fn) {
53 | atom.Transition[id] = atom.Transition(fn);
54 | });
55 |
56 | atom.Transition.get = function (fn) {
57 | if (typeof fn != 'string') return fn;
58 | var method = fn.split('-')[0], ease = 'easeInOut', In, Out;
59 | if (method != fn) {
60 | In = fn.indexOf('-in' ) > 0;
61 | Out = fn.indexOf('-out') > 0;
62 | if (In ^ Out) {
63 | if (In ) ease = 'easeIn';
64 | if (Out) ease = 'easeOut';
65 | }
66 | }
67 | method = method[0].toUpperCase() + method.substr(1);
68 | if (!atom.Transition[method]) {
69 | throw new Error('No Transition method: ' + method);
70 | }
71 | return atom.Transition[method][ease];
72 | };
73 |
74 | atom.Transition.Linear = atom.Transition(function(p) { return p }, true);
75 |
76 | atom.Transition.set({
77 | Expo: function(p){
78 | return Math.pow(2, 8 * (p - 1));
79 | },
80 |
81 | Circ: function(p){
82 | return 1 - Math.sin(Math.acos(p));
83 | },
84 |
85 | Sine: function(p){
86 | return 1 - Math.cos(p * Math.PI / 2);
87 | },
88 |
89 | Back: function(p){
90 | var x = 1.618;
91 | return Math.pow(p, 2) * ((x + 1) * p - x);
92 | },
93 |
94 | Bounce: function(p){
95 | var value, a = 0, b = 1;
96 | for (;;){
97 | if (p >= (7 - 4 * a) / 11){
98 | value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
99 | break;
100 | }
101 | a += b, b /= 2
102 | }
103 | return value;
104 | },
105 |
106 | Elastic: function(p){
107 | return Math.pow(2, 10 * --p) * Math.cos(12 * p);
108 | }
109 |
110 | });
111 |
112 | ['Quad', 'Cubic', 'Quart', 'Quint'].forEach(function(transition, i){
113 | atom.Transition.set(transition, function(p){
114 | return Math.pow(p, i + 2);
115 | });
116 | });
--------------------------------------------------------------------------------
/Source/Frame.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Frame"
5 |
6 | description: "Provides cross-browser interface for requestAnimationFrame"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: frame
16 |
17 | ...
18 | */
19 | (function () {
20 |
21 | var previous,
22 | started = false,
23 | callbacks = [],
24 | remove = [],
25 | frameTime = 16, // 62 fps
26 | // we'll switch to real `requestAnimationFrame` here
27 | // when all browsers will be ready
28 | requestAnimationFrame = function (callback) {
29 | window.setTimeout(callback, frameTime);
30 | };
31 |
32 | function startAnimation () {
33 | if (!started) {
34 | previous = Date.now();
35 | requestAnimationFrame(frame);
36 | started = true;
37 | }
38 | }
39 |
40 | function invokeFrame () {
41 | var fn, i, l,
42 | now = Date.now(),
43 | // 1 sec is max time for frame to avoid some bugs with too large time
44 | delta = Math.min(now - previous, 1000);
45 |
46 | for (i = 0, l = remove.length; i < l; i++) {
47 | coreEraseOne(callbacks, remove[i]);
48 | }
49 | remove.length = 0;
50 |
51 | for (i = 0, l = callbacks.length; i < l; i++) {
52 | fn = callbacks[i];
53 | // one of previous calls can remove our fn
54 | if (remove.indexOf(fn) == -1) {
55 | fn.call(null, delta);
56 | }
57 | }
58 |
59 | previous = now;
60 | }
61 |
62 | function frame() {
63 | requestAnimationFrame(frame);
64 |
65 | if (callbacks.length == 0) {
66 | remove.length = 0;
67 | previous = Date.now();
68 | } else invokeFrame();
69 | }
70 |
71 | atom.frame = {
72 | add: function (fn) {
73 | startAnimation();
74 | includeUnique(callbacks, fn);
75 | },
76 | // we dont want to fragmentate callbacks, so remove only before frame started
77 | remove: function (fn) {
78 | if (started) includeUnique(remove, fn);
79 | }
80 | };
81 |
82 | }());
--------------------------------------------------------------------------------
/Source/Js185.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "JavaScript 1.8.5"
5 |
6 | description: "JavaScript 1.8.5 Compatiblity."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | inspiration:
13 | - "[JQuery](http://jquery.com)"
14 | - "[MooTools](http://mootools.net)"
15 |
16 | provides: js185
17 |
18 | ...
19 | */
20 |
21 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
22 | if (!Function.prototype.bind) {
23 | Function.prototype.bind = function(context /*, arg1, arg2... */) {
24 | if (typeof this !== "function") throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
25 |
26 | var args = slice.call(arguments, 1),
27 | toBind = this,
28 | Nop = function () {},
29 | Bound = function () {
30 | var isInstance;
31 | // Opera & Safari bug fixed. I must fix it in right way
32 | // TypeError: Second argument to 'instanceof' does not implement [[HasInstance]]
33 | try {
34 | isInstance = this instanceof Nop;
35 | } catch (ignored) {
36 | // console.log( 'bind error', Nop.prototype );
37 | isInstance = false;
38 | }
39 | return toBind.apply(
40 | isInstance ? this : ( context || {} ),
41 | args.concat( slice.call(arguments) )
42 | );
43 | };
44 | Nop.prototype = toBind.prototype;
45 | Bound.prototype = new Nop();
46 | return Bound;
47 | };
48 | }
49 |
50 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
51 | if (!Object.keys) (function (has) {
52 |
53 | Object.keys = function(obj) {
54 | if (obj !== Object(obj)) throw new TypeError('Object.keys called on non-object');
55 |
56 | var keys = [], i;
57 | for (i in obj) if (has.call(obj, i)) keys.push(i);
58 | return keys;
59 | };
60 | })({}.hasOwnProperty);
61 |
62 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
63 | if (!Array.isArray) {
64 | Array.isArray = function(o) {
65 | return o && toString.call(o) === '[object Array]';
66 | };
67 | }
68 |
69 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create
70 | if (!Object.create) {
71 | Object.create = function (o) {
72 | if (arguments.length > 1) {
73 | throw new Error('Object.create implementation only accepts the first parameter.');
74 | }
75 | function F() {}
76 | F.prototype = o;
77 | return new F();
78 | };
79 | }
80 |
81 | if (!String.prototype.trim) {
82 | String.prototype.trim = function () {
83 | return this.replace(/^\s+|\s+$/g, '');
84 | }
85 | }
86 |
87 | if (!String.prototype.trimLeft) {
88 | String.prototype.trimLeft = function () {
89 | return this.replace(/^\s+/, '');
90 | }
91 | }
92 |
93 | if (!String.prototype.trimRight) {
94 | String.prototype.trimRight = function () {
95 | return this.replace(/\s+$/g, '');
96 | }
97 | }
--------------------------------------------------------------------------------
/Source/PointerLock.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "PointerLock"
5 |
6 | description: "Provides cross-browser interface for locking pointer"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: PointerLock
16 |
17 | ...
18 | */
19 | (function (document) {
20 | var prefix =
21 | 'pointerLockElement' in document ? '':
22 | 'mozPointerLockElement' in document ? 'moz':
23 | 'webkitPointerLockElement' in document ? 'webkit': null;
24 |
25 | function PointerLock (supports) {
26 | this.supports = supports;
27 | }
28 |
29 | function p (string) {
30 | return prefix ? prefix + string :
31 | string[0].toLowerCase() + string.substr(1);
32 | }
33 |
34 | function isLocked (element) {
35 | return document[p('PointerLockElement')] === element;
36 | }
37 |
38 | if (prefix == null) {
39 | PointerLock.prototype = {
40 | locked : function () { return false },
41 | request : function () {},
42 | exit : function () {}
43 | };
44 | } else {
45 |
46 | document.addEventListener("mousemove", function onMove (e) {
47 | if (lockedElement && isLocked(lockedElement)) {
48 | e.movementX = e[p('MovementX')] || 0;
49 | e.movementY = e[p('MovementY')] || 0;
50 |
51 | callback && callback(e);
52 | }
53 | }, false);
54 |
55 |
56 | var lockedElement = false, callback = null;
57 |
58 | PointerLock.prototype = {
59 | locked: function (element) {
60 | return isLocked(element || lockedElement);
61 | },
62 | request: function (element, fn) {
63 | lockedElement = element;
64 | callback = fn;
65 | element[p('RequestPointerLock')]();
66 | },
67 | exit: function () {
68 | lockedElement = null;
69 | callback = null;
70 | document[p('ExitPointerLock')]();
71 | }
72 | };
73 | }
74 |
75 | atom.pointerLock = new PointerLock(prefix != null);
76 |
77 | }(document));
--------------------------------------------------------------------------------
/Source/Prototypes/Abstract.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.Abstract"
5 |
6 | description: "Contains office methods for prototypes extension."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Types.Array
15 | - Types.Object
16 |
17 | provides: Prototypes.Abstract
18 |
19 | ...
20 | */
21 |
22 | var prototypize = {
23 | callbacks: [],
24 | fn: function (source) {
25 | return function (methodName) {
26 | return function () {
27 | var args = slice.call(arguments);
28 | args.unshift(this);
29 | return source[methodName].apply(source, args);
30 | };
31 | };
32 | },
33 | proto: function (object, proto, methodsString) {
34 | coreAppend(object.prototype, atom.array.associate(
35 | methodsString.split(' '), proto
36 | ));
37 | return prototypize;
38 | },
39 | own: function (object, source, methodsString) {
40 | coreAppend(object, atom.object.collect( source, methodsString.split(' ') ));
41 | return prototypize;
42 | },
43 | add: function (callback) {
44 | this.callbacks.push(callback);
45 | }
46 | };
47 |
48 | atom.patching = function (globalObject) {
49 | prototypize.callbacks.forEach(function (callback) {
50 | callback(globalObject);
51 | });
52 | };
--------------------------------------------------------------------------------
/Source/Prototypes/Array.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.Array"
5 |
6 | description: "Contains Array Prototypes like include, contains, and erase."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Types.Array
14 | - Prototypes.Abstract
15 |
16 | provides: Prototypes.Array
17 |
18 | ...
19 | */
20 |
21 | prototypize.add(function (globalObject) {
22 |
23 | var Array = globalObject.Array;
24 |
25 | var proto = prototypize.fn(atom.array);
26 |
27 | prototypize
28 | .own(Array, atom.array, 'range from pickFrom fill fillMatrix collect create toHash')
29 | .proto(Array, proto, 'randomIndex property contains include append erase combine pick invoke shuffle sortBy min max mul add sum product average unique associate clean empty clone hexToRgb rgbToHex' );
30 |
31 | atom.accessors.define(Array.prototype, {
32 | last : { get: function () {
33 | return atom.array.last(this);
34 | }},
35 | random: { get: function () {
36 | return atom.array.random(this, false);
37 | }}
38 | });
39 |
40 | coreAppend(Array.prototype, {
41 | popRandom: function () {
42 | return atom.array.random(this, true);
43 | },
44 | /** @deprecated */
45 | toKeys: function () {
46 | console.log( '[].toKeys is deprecated. Use forEach instead' );
47 | return atom.array.toKeys(this);
48 | },
49 | /** @deprecated */
50 | fullMap: function (callback, context) {
51 | console.log( '[].fullMap is deprecated. Use atom.array.create instead' );
52 | return atom.array.create(this.length, callback, context);
53 | }
54 | });
55 |
56 | if (!Array.prototype.reduce ) Array.prototype.reduce = proto('reduce');
57 | if (!Array.prototype.reduceRight) Array.prototype.reduceRight = proto('reduceRight');
58 |
59 | });
--------------------------------------------------------------------------------
/Source/Prototypes/Function.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.Function"
5 |
6 | description: "Contains Function Prototypes like after, periodical and delay."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Types.Function
15 | - Prototypes.Abstract
16 |
17 | provides: Prototypes.Function
18 |
19 | ...
20 | */
21 |
22 | prototypize.add(function (globalObject) {
23 |
24 | var Function = globalObject.Function;
25 |
26 | Function.lambda = atom.fn.lambda;
27 |
28 | function timer (periodical) {
29 | var set = periodical ? setInterval : setTimeout;
30 |
31 | return function (time, bind, args) {
32 | var fn = this;
33 | return set(function () {
34 | fn.apply( bind, args || [] );
35 | }, time);
36 | };
37 | }
38 |
39 | coreAppend(Function.prototype, {
40 | after: prototypize.fn(atom.fn)('after'),
41 | delay : timer(false),
42 | periodical: timer(true )
43 | });
44 |
45 | });
46 |
--------------------------------------------------------------------------------
/Source/Prototypes/Number.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.Number"
5 |
6 | description: "Contains Number Prototypes like limit, round, times, and ceil."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Types.Number
14 | - Types.Math
15 | - Prototypes.Abstract
16 |
17 | provides: Prototypes.Number
18 |
19 | ...
20 | */
21 |
22 | prototypize.add(function (globalObject) {
23 |
24 | var Number = globalObject.Number;
25 |
26 | prototypize
27 | .own(Number, atom.number, 'random randomFloat')
28 | .proto(Number, prototypize.fn(atom.number), 'between equals limit round stop' )
29 | .proto(Number, prototypize.fn(atom.math ), 'degree getDegree normalizeAngle' );
30 |
31 | coreAppend(Number.prototype, {
32 | toFloat: function(){
33 | return parseFloat(this);
34 | },
35 | toInt: function(base){
36 | return parseInt(this, base || 10);
37 | }
38 | });
39 |
40 | 'abs acos asin atan atan2 ceil cos exp floor log max min pow sin sqrt tan'
41 | .split(' ')
42 | .forEach(function(method) {
43 | if (Number[method]) return;
44 |
45 | Number.prototype[method] = function() {
46 | return Math[method].apply(null, [this].append(arguments));
47 | };
48 | });
49 | });
--------------------------------------------------------------------------------
/Source/Prototypes/Object.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.Object"
5 |
6 | description: "Object generic methods"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Types.Object
14 |
15 | provides: Prototypes.Object
16 |
17 | ...
18 | */
19 |
20 | prototypize.add(function (globalObject) {
21 | coreAppend(globalObject.Object, atom.object);
22 | });
--------------------------------------------------------------------------------
/Source/Prototypes/String.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Prototypes.String"
5 |
6 | description: "Contains String Prototypes like repeat, substitute, replaceAll and begins."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Types.String
14 | - Prototypes.Abstract
15 |
16 | provides: Prototypes.String
17 |
18 | ...
19 | */
20 |
21 | prototypize.add(function (globalObject) {
22 | prototypize.proto(globalObject.String, prototypize.fn(atom.string),
23 | 'safeHtml repeat substitute replaceAll contains begins ends ucfirst lcfirst'
24 | );
25 | });
--------------------------------------------------------------------------------
/Source/Types/Function.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Types.Function"
5 |
6 | description: "Contains function manipulation methods."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 | - Types.Array
15 |
16 | provides: Types.Function
17 |
18 | ...
19 | */
20 |
21 | atom.fn = {
22 | lambda: function (value) {
23 | var returnThis = (arguments.length == 0);
24 | return function () { return returnThis ? this : value; };
25 | },
26 |
27 | after: function (onReady, fnName) {
28 | var after = {}, ready = {};
29 | function checkReady (){
30 | for (var i in after) if (!ready[i]) return;
31 | onReady(ready);
32 | }
33 | slice.call(arguments, 1).forEach(function (key) {
34 | after[key] = function () {
35 | ready[key] = slice.call(arguments);
36 | ready[key].context = this;
37 | checkReady();
38 | };
39 | });
40 | return after;
41 | }
42 | };
43 |
--------------------------------------------------------------------------------
/Source/Types/Math.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Types.Math"
5 |
6 | description: ""
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: Types.Math
16 |
17 | ...
18 | */
19 |
20 | (function () {
21 |
22 | var
23 | degree = Math.PI / 180,
24 | deg360 = Math.PI * 2;
25 |
26 | atom.math = {
27 |
28 | DEGREE360: deg360,
29 |
30 | /**
31 | * Cast degrees to radians
32 | * atom.math.degree(90) == Math.PI/2
33 | */
34 | degree: function (degrees) {
35 | return degrees * degree;
36 | },
37 |
38 | /**
39 | * Cast radians to degrees
40 | * atom.math.getDegree(Math.PI/2) == 90
41 | */
42 | getDegree: function (radians, round) {
43 | radians /= degree;
44 |
45 | return round ? Math.round(radians) : radians;
46 | },
47 | normalizeAngle : function (radians) {
48 | radians %= deg360;
49 |
50 | return radians + ( radians < 0 ? deg360 : 0 );
51 | },
52 |
53 | hypotenuse: function (cathetus1, cathetus2) {
54 | return Math.sqrt(cathetus1*cathetus1 + cathetus2*cathetus2);
55 | },
56 | cathetus: function (hypotenuse, cathetus2) {
57 | return Math.sqrt(hypotenuse*hypotenuse - cathetus2*cathetus2);
58 | }
59 | };
60 |
61 | })();
62 |
--------------------------------------------------------------------------------
/Source/Types/Number.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Types.Number"
5 |
6 | description: "Contains number-manipulation methods like limit, round, times, and ceil."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: Types.Number
16 |
17 | ...
18 | */
19 |
20 | atom.number = {
21 | randomFloat: function (max, min) {
22 | return Math.random() * (max - min) + min;
23 | },
24 | random : function (min, max) {
25 | return Math.floor(Math.random() * (max - min + 1) + min);
26 | },
27 | between: function (number, n1, n2, equals) {
28 | number = Number(number);
29 | n1 = Number(n1);
30 | n2 = Number(n2);
31 | return (n1 <= n2) && (
32 | (equals == 'L' && number == n1) ||
33 | (equals == 'R' && number == n2) ||
34 | (number > n1 && number < n2) ||
35 | ([true,'LR','RL'].indexOf(equals) != -1 && (n1 == number || n2 == number))
36 | );
37 | },
38 | equals : function (number, to, accuracy) {
39 | if (accuracy == null) accuracy = 8;
40 | return number.toFixed(accuracy) == to.toFixed(accuracy);
41 | },
42 | limit: function(number, min, max){
43 | var bottom = Math.max(min, Number(number));
44 | return max != null ? Math.min(max, bottom) : bottom;
45 | },
46 | round: function(number, precision){
47 | if (!precision) return Math.round(number);
48 |
49 | if (precision < 0) {
50 | precision = Number( Math.pow(10, precision).toFixed( -precision ) );
51 | } else {
52 | precision = Math.pow(10, precision);
53 | }
54 | return Math.round(number * precision) / precision;
55 | },
56 | stop: function(num) {
57 | num = Number(num);
58 | if (num) {
59 | clearInterval(num);
60 | clearTimeout (num);
61 | }
62 | return this;
63 | }
64 | };
--------------------------------------------------------------------------------
/Source/Types/Object.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Types.Object"
5 |
6 | description: "Object generic methods"
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: Types.Object
16 |
17 | ...
18 | */
19 |
20 | atom.object = {
21 | append: function (target, source1, source2) {
22 | for (var i = 1, l = arguments.length; i < l; i++) {
23 | atom.core.append(target, arguments[i]);
24 | }
25 | return target;
26 | },
27 | invert: function (object) {
28 | var newObj = {};
29 | for (var i in object) newObj[object[i]] = i;
30 | return newObj;
31 | },
32 | collect: function (obj, props, Default) {
33 | var newObj = {};
34 | props.forEach(function (i){
35 | newObj[i] = i in obj ? obj[i] : Default;
36 | });
37 | return newObj;
38 | },
39 | values: function (obj) {
40 | var values = [];
41 | for (var i in obj) values.push(obj[i]);
42 | return values;
43 | },
44 | /** @deprecated */
45 | isDefined: function (obj) {
46 | return typeof obj !== 'undefined';
47 | },
48 | /** @deprecated */
49 | isReal: function (obj) {
50 | return obj != null;
51 | },
52 | map: function (obj, fn) {
53 | var mapped = {};
54 | for (var i in obj) if (obj.hasOwnProperty(i)) {
55 | mapped[i] = fn( obj[i], i, obj );
56 | }
57 | return mapped;
58 | },
59 | max: function (obj) {
60 | var max = null, key = null;
61 | for (var i in obj) if (max == null || obj[i] > max) {
62 | key = i;
63 | max = obj[i];
64 | }
65 | return key;
66 | },
67 | min: function (obj) {
68 | var min = null, key = null;
69 | for (var i in obj) if (min == null || obj[i] < min) {
70 | key = i;
71 | min = obj[i];
72 | }
73 | return key;
74 | },
75 | deepEquals: function (first, second) {
76 | if (!first || (typeof first) !== (typeof second)) return false;
77 |
78 | for (var i in first) {
79 | var f = first[i], s = second[i];
80 | if (typeof f === 'object') {
81 | if (!s || !Object.deepEquals(f, s)) return false;
82 | } else if (f !== s) {
83 | return false;
84 | }
85 | }
86 |
87 | for (i in second) if (!(i in first)) return false;
88 |
89 | return true;
90 | },
91 | isEmpty: function (object) {
92 | for (var i in object) if (object.hasOwnProperty(i)) {
93 | return false;
94 | }
95 | return true;
96 | },
97 | ifEmpty: function (object, key, defaultValue) {
98 | if (!(key in object)) {
99 | object[key] = defaultValue;
100 | }
101 | return object;
102 | },
103 | path: {
104 | parts: function (path, delimiter) {
105 | return Array.isArray(path) ? path : String(path).split( delimiter || '.' );
106 | },
107 | get: function (object, path, delimiter) {
108 | if (!path) return object;
109 |
110 | path = atom.object.path.parts( path, delimiter );
111 |
112 | for (var i = 0; i < path.length; i++) {
113 | if (object != null && path[i] in object) {
114 | object = object[path[i]];
115 | } else {
116 | return;
117 | }
118 | }
119 |
120 | return object;
121 | },
122 | set: function (object, path, value, delimiter) {
123 | path = atom.object.path.parts( path, delimiter );
124 |
125 | var key = path.pop();
126 |
127 | while (path.length) {
128 | var current = path.shift();
129 | if (object[current]) {
130 | object = object[current];
131 | } else {
132 | object = object[current] = {};
133 | }
134 | }
135 |
136 | object[key] = value;
137 | }
138 | }
139 | };
--------------------------------------------------------------------------------
/Source/Types/String.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Types.String"
5 |
6 | description: "Contains string-manipulation methods like repeat, substitute, replaceAll and begins."
7 |
8 | license:
9 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
10 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
11 |
12 | requires:
13 | - Core
14 |
15 | provides: Types.String
16 |
17 | ...
18 | */
19 |
20 | new function () {
21 |
22 | var UID = Date.now();
23 |
24 | atom.string = {
25 | /**
26 | * @returns {string} - unique for session value in 36-radix
27 | */
28 | uniqueID: function () {
29 | return (UID++).toString(36);
30 | },
31 | /**
32 | * escape all html unsafe characters - & ' " < >
33 | * @param {string} string
34 | * @returns {string}
35 | */
36 | safeHtml: function (string) {
37 | return this.replaceAll(string, /[<'&">]/g, {
38 | '&' : '&',
39 | '\'' : ''',
40 | '\"' : '"',
41 | '<' : '<',
42 | '>' : '>'
43 | });
44 | },
45 | /**
46 | * repeat string `times` times
47 | * @param {string} string
48 | * @param {int} times
49 | * @returns {string}
50 | */
51 | repeat: function(string, times) {
52 | return new Array(times + 1).join(string);
53 | },
54 | /**
55 | * @param {string} string
56 | * @param {Object} object
57 | * @param {RegExp} [regexp=null]
58 | * @returns {string}
59 | */
60 | substitute: function(string, object, regexp){
61 | return string.replace(regexp || /\\?\{([^{}]+)\}/g, function(match, name){
62 | return (match[0] == '\\') ? match.slice(1) : (object[name] == null ? '' : object[name]);
63 | });
64 | },
65 | /**
66 | * @param {string} string
67 | * @param {Object|RegExp|string} find
68 | * @param {Object|string} [replace=null]
69 | * @returns {String}
70 | */
71 | replaceAll: function (string, find, replace) {
72 | if (toString.call(find) == '[object RegExp]') {
73 | return string.replace(find, function (symb) { return replace[symb]; });
74 | } else if (typeof find == 'object') {
75 | for (var i in find) string = this.replaceAll(string, i, find[i]);
76 | return string;
77 | }
78 | return string.split(find).join(replace);
79 | },
80 | /**
81 | * Checks if string contains such substring
82 | * @param {string} string
83 | * @param {string} substr
84 | */
85 | contains: function (string, substr) {
86 | return string ? string.indexOf( substr ) >= 0 : false;
87 | },
88 | /**
89 | * Checks if string begins with such substring
90 | * @param {string} string
91 | * @param {string} substring
92 | * @param {boolean} [caseInsensitive=false]
93 | * @returns {boolean}
94 | */
95 | begins: function (string, substring, caseInsensitive) {
96 | if (!string) return false;
97 | return (!caseInsensitive) ? substring == string.substr(0, substring.length) :
98 | substring.toLowerCase() == string.substr(0, substring.length).toLowerCase();
99 | },
100 | /**
101 | * Checks if string ends with such substring
102 | * @param {string} string
103 | * @param {string} substring
104 | * @param {boolean} [caseInsensitive=false]
105 | * @returns {boolean}
106 | */
107 | ends: function (string, substring, caseInsensitive) {
108 | if (!string) return false;
109 | return (!caseInsensitive) ? substring == string.substr(string.length - substring.length) :
110 | substring.toLowerCase() == string.substr(string.length - substring.length).toLowerCase();
111 | },
112 | /**
113 | * Uppercase first character
114 | * @param {string} string
115 | * @returns {string}
116 | */
117 | ucfirst : function (string) {
118 | return string ? string[0].toUpperCase() + string.substr(1) : '';
119 | },
120 | /**
121 | * Lowercase first character
122 | * @param {string} string
123 | * @returns {string}
124 | */
125 | lcfirst : function (string) {
126 | return string ? string[0].toLowerCase() + string.substr(1) : '';
127 | }
128 | };
129 |
130 | }();
--------------------------------------------------------------------------------
/Source/Uri.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "Uri"
5 |
6 | description: "Port of parseUri function"
7 |
8 | license: "MIT License"
9 |
10 | author: "Steven Levithan "
11 |
12 | requires:
13 | - Core
14 |
15 | provides: uri
16 |
17 | ...
18 | */
19 | new function () {
20 |
21 | var uri = function (str) {
22 | var o = atom.uri.options,
23 | m = o.parser.exec(str || window.location.href),
24 | uri = {},
25 | i = 14;
26 |
27 | while (i--) uri[o.key[i]] = m[i] || "";
28 |
29 | uri[o.q.name] = {};
30 | uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
31 | if ($1) uri[o.q.name][$1] = $2;
32 | });
33 |
34 | return uri;
35 | };
36 | uri.options = {
37 | key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
38 | q: {
39 | name: "queryKey",
40 | parser: /(?:^|&)([^&=]*)=?([^&]*)/g
41 | },
42 | parser: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
43 | };
44 |
45 | atom.uri = uri;
46 |
47 | };
--------------------------------------------------------------------------------
/Source/atom.css:
--------------------------------------------------------------------------------
1 | #atom-trace-container {
2 | z-index : 87223;
3 | position : fixed;
4 | top : 3px;
5 | right : 6px;
6 | max-width : 70%;
7 | max-height: 100%;
8 | overflow-y: auto;
9 | background: rgba(0,192,0,0.2);
10 | }
11 |
12 | .atom-trace-node {
13 | background : #000;
14 | border : 1px dashed #0c0;
15 | color : #0c0;
16 | cursor : pointer;
17 | font-family: monospace;
18 | margin : 1px;
19 | min-width : 200px;
20 | overflow : auto;
21 | padding : 3px 12px;
22 | white-space: pre;
23 | }
24 |
25 | .atom-trace-node-destroy {
26 | background : #300;
27 | }
--------------------------------------------------------------------------------
/Source/overall.js:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 |
4 | name: "AtomJS"
5 |
6 | license:
7 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
8 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
9 |
10 | authors:
11 | - Pavel Ponomarenko aka Shock
12 |
13 | inspiration:
14 | - "[JQuery](http://jquery.com)"
15 | - "[MooTools](http://mootools.net)"
16 |
17 | ...
18 | */
19 |
20 | (function (Object, Array, undefined) { // AtomJS
21 | // Safari 5 bug:
22 | // 'use strict';
23 |
24 | var
25 | toString = Object.prototype.toString,
26 | hasOwn = Object.prototype.hasOwnProperty,
27 | slice = Array .prototype.slice,
28 | atom = this.atom = function () {
29 | if (atom.initialize) return atom.initialize.apply(this, arguments);
30 | };
31 |
32 | atom.global = this;
33 |
34 | /*** [Code] ***/
35 |
36 | }.call(typeof exports == 'undefined' ? window : exports, Object, Array));
--------------------------------------------------------------------------------
/Source/package.yml:
--------------------------------------------------------------------------------
1 | name: "AtomJS"
2 |
3 | exports: "atom.js"
4 |
5 | web: "[atomjs.com](http://atomjs.com/)"
6 |
7 | description: "Atom, The JavaScript framework"
8 |
9 | license:
10 | - "[GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)"
11 | - "[MIT License](http://opensource.org/licenses/mit-license.php)"
12 |
13 | copyright: "© [AtomJS](http://atomjs.com)"
14 |
15 | authors: "[AtomJS Development Team](http://atomjs.com)"
16 |
17 | sources: "*.js"
18 |
19 | overall: "overall.js"
--------------------------------------------------------------------------------
/Tests/cells.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/theshock/atomjs/8fcc3209e9b49727fd30c1b15194f895054ad6dc/Tests/cells.png
--------------------------------------------------------------------------------
/Tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
ccc
20 |
The standard Lorem Ipsum passage, used since the 1500s
21 |
"Lorem ipsum dolor sit amet , consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
22 |
Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
23 |
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"
24 |
1914 translation by H. Rackham
25 |
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
26 |
Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
27 |
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
28 |
29 |
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Tests/lib/qunit.css:
--------------------------------------------------------------------------------
1 | /** Font Family and Sizes */
2 |
3 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
4 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
5 | }
6 |
7 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
8 | #qunit-tests { font-size: smaller; }
9 |
10 |
11 | /** Resets */
12 |
13 | #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 |
19 | /** Header */
20 |
21 | #qunit-header {
22 | padding: 0.5em 0 0.5em 1em;
23 |
24 | color: #8699a4;
25 | background-color: #0d3349;
26 |
27 | font-size: 1.5em;
28 | line-height: 1em;
29 | font-weight: normal;
30 |
31 | border-radius: 15px 15px 0 0;
32 | -moz-border-radius: 15px 15px 0 0;
33 | -webkit-border-top-right-radius: 15px;
34 | -webkit-border-top-left-radius: 15px;
35 | }
36 |
37 | #qunit-header a {
38 | text-decoration: none;
39 | color: #c2ccd1;
40 | }
41 |
42 | #qunit-header a:hover,
43 | #qunit-header a:focus {
44 | color: #fff;
45 | }
46 |
47 | #qunit-banner {
48 | height: 5px;
49 | }
50 |
51 | #qunit-testrunner-toolbar {
52 | padding: 0em 0 0.5em 2em;
53 | }
54 |
55 | #qunit-userAgent {
56 | padding: 0.5em 0 0.5em 2.5em;
57 | background-color: #2b81af;
58 | color: #fff;
59 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
60 | }
61 |
62 |
63 | /** Tests: Pass/Fail */
64 |
65 | #qunit-tests {
66 | list-style-position: inside;
67 | }
68 |
69 | #qunit-tests li {
70 | padding: 0.4em 0.5em 0.4em 2.5em;
71 | border-bottom: 1px solid #fff;
72 | list-style-position: inside;
73 | }
74 |
75 | #qunit-tests li strong {
76 | cursor: pointer;
77 | }
78 |
79 | #qunit-tests ol {
80 | margin-top: 0.5em;
81 | padding: 0.5em;
82 |
83 | background-color: #fff;
84 |
85 | border-radius: 15px;
86 | -moz-border-radius: 15px;
87 | -webkit-border-radius: 15px;
88 |
89 | box-shadow: inset 0px 2px 13px #999;
90 | -moz-box-shadow: inset 0px 2px 13px #999;
91 | -webkit-box-shadow: inset 0px 2px 13px #999;
92 | }
93 |
94 | #qunit-tests table {
95 | border-collapse: collapse;
96 | margin-top: .2em;
97 | }
98 |
99 | #qunit-tests th {
100 | text-align: right;
101 | vertical-align: top;
102 | padding: 0 .5em 0 0;
103 | }
104 |
105 | #qunit-tests td {
106 | vertical-align: top;
107 | }
108 |
109 | #qunit-tests pre {
110 | margin: 0;
111 | white-space: pre-wrap;
112 | word-wrap: break-word;
113 | }
114 |
115 | #qunit-tests del {
116 | background-color: #e0f2be;
117 | color: #374e0c;
118 | text-decoration: none;
119 | }
120 |
121 | #qunit-tests ins {
122 | background-color: #ffcaca;
123 | color: #500;
124 | text-decoration: none;
125 | }
126 |
127 | /*** Test Counts */
128 |
129 | #qunit-tests b.counts { color: black; }
130 | #qunit-tests b.passed { color: #5E740B; }
131 | #qunit-tests b.failed { color: #710909; }
132 |
133 | #qunit-tests li li {
134 | margin: 0.5em;
135 | padding: 0.4em 0.5em 0.4em 0.5em;
136 | background-color: #fff;
137 | border-bottom: none;
138 | list-style-position: inside;
139 | }
140 |
141 | /*** Passing Styles */
142 |
143 | #qunit-tests li li.pass {
144 | color: #5E740B;
145 | background-color: #fff;
146 | border-left: 26px solid #C6E746;
147 | }
148 |
149 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
150 | #qunit-tests .pass .test-name { color: #366097; }
151 |
152 | #qunit-tests .pass .test-actual,
153 | #qunit-tests .pass .test-expected { color: #999999; }
154 |
155 | #qunit-banner.qunit-pass { background-color: #C6E746; }
156 |
157 | /*** Failing Styles */
158 |
159 | #qunit-tests li li.fail {
160 | color: #710909;
161 | background-color: #fff;
162 | border-left: 26px solid #EE5757;
163 | }
164 |
165 | #qunit-tests .fail { color: #000000; background-color: #EE5757; }
166 | #qunit-tests .fail .test-name,
167 | #qunit-tests .fail .module-name { color: #000000; }
168 |
169 | #qunit-tests .fail .test-actual { color: #EE5757; }
170 | #qunit-tests .fail .test-expected { color: green; }
171 |
172 | #qunit-banner.qunit-fail,
173 | #qunit-testrunner-toolbar { background-color: #EE5757; }
174 |
175 |
176 | /** Footer */
177 |
178 | #qunit-testresult {
179 | padding: 0.5em 0.5em 0.5em 2.5em;
180 |
181 | color: #2b81af;
182 | background-color: #D2E0E6;
183 |
184 | border-radius: 0 0 15px 15px;
185 | -moz-border-radius: 0 0 15px 15px;
186 | -webkit-border-bottom-right-radius: 15px;
187 | -webkit-border-bottom-left-radius: 15px;
188 | }
189 |
190 | /** Fixture */
191 |
192 | #qunit-fixture {
193 | position: absolute;
194 | top: -10000px;
195 | left: -10000px;
196 | }
--------------------------------------------------------------------------------
/Tests/tests/color.js:
--------------------------------------------------------------------------------
1 |
2 | module('[Atom Plugins] Color');
3 |
4 | test('Color Constructing', function(){
5 | var color;
6 |
7 | color = new atom.Color('#ac45de');
8 |
9 | equal(color.r, 172, 'Hex: red is correct');
10 | equal(color.g, 69, 'Hex: green is correct');
11 | equal(color.b, 222, 'Hex: blue is correct');
12 | equal(color.a, 1, 'Hex: alpha is default');
13 |
14 | color = new atom.Color(24, 56, 12, 0.7);
15 |
16 | equal(color.r, 24, 'Arguments: red is correct');
17 | equal(color.g, 56, 'Arguments: green is correct');
18 | equal(color.b, 12, 'Arguments: blue is correct');
19 | equal(color.a, 0.7, 'Arguments: alpha is correct');
20 |
21 | color = new atom.Color.Shift(-24, 56, -12, 0.7);
22 |
23 | equal(color.r, -24, 'No limits: red is correct');
24 | equal(color.g, 56, 'No limits: green is correct');
25 | equal(color.b, -12, 'No limits: blue is correct');
26 | equal(color.a, 0.7, 'No limits: alpha is correct');
27 |
28 | color = new atom.Color([174, 41, 62, 0.4]);
29 |
30 | equal(color.r, 174, 'Array: red is correct');
31 | equal(color.g, 41, 'Array: green is correct');
32 | equal(color.b, 62, 'Array: blue is correct');
33 | equal(color.a, 0.4, 'Array: alpha is correct');
34 |
35 | color = new atom.Color({ r: 46, g: 72, b: 0, a: 0.6 });
36 |
37 | equal(color.r, 46, 'Object short: red is correct');
38 | equal(color.g, 72, 'Object short: green is correct');
39 | equal(color.b, 0, 'Object short: blue is correct');
40 | equal(color.a, 0.6, 'Object short: alpha is correct');
41 |
42 | color = new atom.Color({ red: 12, green: 34, blue: 50 });
43 |
44 | equal(color.r, 12, 'Object long: red is correct');
45 | equal(color.g, 34, 'Object long: green is correct');
46 | equal(color.b, 50, 'Object long: blue is correct');
47 | equal(color.a, 1, 'Object long: alpha is default');
48 |
49 | color = new atom.Color(0x2246dd66);
50 |
51 | equal(color.r, 34, 'Number: red is correct');
52 | equal(color.g, 70, 'Number: green is correct');
53 | equal(color.b, 221, 'Number: blue is correct');
54 | equal(color.a, 0.4, 'Number: alpha is correct');
55 |
56 | color = new atom.Color(0xff000000);
57 |
58 | equal(color.r, 255, 'Big Int: red is correct');
59 | });
60 |
61 | test('Color Casting', function(){
62 | var color = new atom.Color(0x2246dd66);
63 |
64 | deepEqual( color.toArray(), [34, 70, 221, 0.4], 'color.toArray()');
65 | deepEqual( color.toString(), 'rgba(34,70,221,0.4)', 'color.toString()');
66 | deepEqual( color.toString('hex'), '#2246dd', 'color.toString("hex")');
67 | deepEqual( color.toString('hexA'), '#2246dd66', 'color.toString("hexA")');
68 | deepEqual( color.toObject(), {red:34, green:70, blue:221, alpha:0.4}, 'color.toObject()');
69 | deepEqual( color.toObject(true), {r:34, g:70, b:221, a:0.4}, 'color.toObject(true)');
70 | deepEqual( color.toNumber(), 0x2246dd66, 'color.toNumber()');
71 | });
72 |
73 | test('Color Equals', function(){
74 | var foo = new atom.Color(0x2246dd66);
75 | var bar = new atom.Color(0x2246dd66);
76 | var red = new atom.Color(0xff0000ff);
77 |
78 | notEqual(foo, bar, 'foo & bar are different objects');
79 | ok( foo.equals(bar), 'foo equals bar');
80 | ok(!foo.equals(red), 'foo not equals red');
81 | ok(!foo.equals(null),'foo not equals null');
82 | });
83 |
84 | test('Color maniplations', function () {
85 | var foo, bar;
86 |
87 | foo = 0x12345678, bar = new atom.Color(foo);
88 |
89 | ok( atom.Color(foo).equals(bar), 'Color.invoke' );
90 |
91 | foo = new atom.Color(foo);
92 |
93 | ok( atom.Color(foo).equals(bar), 'Color.invoke empty' );
94 |
95 | foo = new atom.Color([ 255, 240, 225, 0.8 ]);
96 | bar = new atom.Color([ 220, 240, 250, 0.4 ]);
97 | var diff = new atom.Color.Shift([ -35, 0, 25, -0.4 ]);
98 |
99 | ok( foo.diff(bar).equals(diff), 'foo.diff(bar) is correct' );
100 | ok( foo.move(diff).equals(bar), 'foo.move(bar) is correct' );
101 | });
--------------------------------------------------------------------------------
/Tests/tests/core.js:
--------------------------------------------------------------------------------
1 |
2 | new function(undefined) {
3 |
4 | module('[Atom Core]');
5 |
6 | test('Initialize', function(){
7 | ok( atom, 'atom' );
8 | });
9 | test('JavaScript 1.8.5 Compatiblity', function(){
10 | equal( typeof (function(){}.bind) , 'function', 'typeof function(){}.bind' );
11 | equal( typeof Object.keys , 'function', 'typeof Object.keys' );
12 | equal( typeof Array.isArray, 'function', 'typeof Array.isArray' );
13 |
14 | ok( Array.isArray([]), ' Array.isArray([])' );
15 | ok( !Array.isArray({}), '!Array.isArray({})' );
16 |
17 | deepEqual( Object.keys({3:3,a:1,b:2}), ['3','a','b'], 'Object.keys({a:1,b:2,3:3})' );
18 | });
19 | test('atom.typeOf', function(){
20 | equal( atom.typeOf(document.body), 'element' , 'atom.typeOf(document.body)');
21 | equal( atom.typeOf(function(){}) , 'function' , 'atom.typeOf(function(){})');
22 | equal( atom.typeOf(new Date()) , 'date' , 'atom.typeOf(new Date())');
23 | equal( atom.typeOf(null) , 'null' , 'atom.typeOf(null)');
24 | equal( atom.typeOf(arguments), 'arguments', 'atom.typeOf(arguments)');
25 | equal( atom.typeOf(/abc/i) , 'regexp' , 'atom.typeOf(/abc/i)');
26 | equal( atom.typeOf([]) , 'array' , 'atom.typeOf([])');
27 | equal( atom.typeOf({}) , 'object' , 'atom.typeOf({})');
28 | equal( atom.typeOf(15) , 'number' , 'atom.typeOf(15)');
29 | equal( atom.typeOf(true) , 'boolean' , 'atom.typeOf(true)');
30 | });
31 | test('atom.clone', function(){
32 | // array cloning
33 | var mixed, object, array, clone;
34 | array = [1,2,3,[4,5]];
35 | clone = atom.clone(array);
36 | notStrictEqual(clone, array, 'array !== clone');
37 | deepEqual(clone, array, 'clone is same to array');
38 | clone[4] = 'changed';
39 | notDeepEqual(clone, array, 'clone is changed');
40 |
41 | // hash cloning
42 | object = {a:'2', b:'3', array: [1,2,3], object: {foo:'bar'}};
43 | clone = atom.clone(object);
44 | notStrictEqual(clone, object, 'object !== clone');
45 | deepEqual(clone, object, 'clone is same to object');
46 | clone['prop'] = 'changed';
47 | notDeepEqual(clone, object, 'clone is changed');
48 |
49 | // object cloning
50 | var Foo = function (name) { this.name = name; };
51 | var Bar = function (name) {
52 | this.name = name;
53 | this.clone = function () {
54 | return new Bar('clone of ' + this.name);
55 | };
56 | };
57 |
58 | object = {foo: new Foo('fooName'), bar: new Bar('barName')};
59 | clone = atom.clone(object);
60 | notStrictEqual(object.bar, clone.bar, 'Objects with "clone" - cloning');
61 | equal(clone.bar.name, 'clone of barName', 'Objects with "clone" - cloning');
62 |
63 | // todo: [qtest] accessors
64 | });
65 |
66 |
67 | // todo: [qtest] atom.merge
68 | test('atom.extend', function(){
69 | atom.extend({
70 | get testProp() { return 'testPropValue:static'; },
71 | testMethod: function () { return 'testMethodValue:static'; }
72 | });
73 | equal(atom.testProp, 'testPropValue:static' , 'atom.extend getter');
74 | equal(atom.testMethod(), 'testMethodValue:static', 'atom.extend method');
75 |
76 | var testObject = {};
77 | atom.extend(testObject, { prop : 'Yes' });
78 | equal(testObject.prop, 'Yes', 'atom object extend');
79 | });
80 |
81 |
82 | };
--------------------------------------------------------------------------------
/Tests/tests/mootools.js:
--------------------------------------------------------------------------------
1 |
2 | module('[MooTools]');
3 |
4 | test('Prototypes.Array', function () {
5 | ok([1,2,3,0,0,0].contains(0), 'contains: element found');
6 | ok(![0,1,2].contains('not found'), 'contains: element not found');
7 | deepEqual([1,2,3,4].include(1).include(5), [1,2,3,4,5], 'include');
8 |
9 | new function () {
10 | var a = [1,2,4];
11 | var b = [2,3,4,5];
12 | a.append(b);
13 | deepEqual(a, [1,2,4,2,3,4,5], 'append');
14 | deepEqual(b, [2,3,4,5], 'append (original element left the same)');
15 | };
16 |
17 | deepEqual([1,2,3,0,0,0].erase(0), [1,2,3], 'erase');
18 | deepEqual([1,2,3,4].combine([3,1,4,5,6,7]), [1,2,3,4,5,6,7], 'combine');
19 |
20 | strictEqual([null, undefined, true, 1].pick(), true, 'pick: true');
21 | strictEqual([].pick(), null, 'pick: null');
22 |
23 | deepEqual([1,2,3,0,0,0].associate(['a', 'b', 'c', 'd']), {a:1, b:2, c:3, d:0}, 'associate');
24 | deepEqual([null, 1, 0, true, false, "foo", undefined].clean(), [1, 0, true, false, "foo"], 'clean');
25 | deepEqual([1,2,3,4].empty(), [], 'empty');
26 |
27 | new function () { // Array.hexToRgb
28 | strictEqual([].hexToRgb(), null, 'hexToRgb: null');
29 | strictEqual(['0','0','0'].hexToRgb(), 'rgb(0,0,0)', 'hexToRgb: string, digits');
30 | strictEqual(['c','c','c'].hexToRgb(), 'rgb(204,204,204)', 'hexToRgb: string, alpha');
31 | deepEqual(['ff','ff','ff'].hexToRgb(true), [255,255,255], 'hexToRgb: array');
32 | };
33 |
34 | new function () {
35 | strictEqual([0,1].rgbToHex(), null, 'rgbToHex: null');
36 | strictEqual(['255', '0', '0'].rgbToHex(), '#ff0000', 'rgbToHex: strings');
37 | strictEqual([0,0,255].rgbToHex(), '#0000ff', 'rgbToHex: numbers');
38 | deepEqual([0,255,0].rgbToHex(true), ['00', 'ff', '00'], 'rgbToHex: array');
39 | };
40 | });
--------------------------------------------------------------------------------
/Tests/tests/prototypes.js:
--------------------------------------------------------------------------------
1 |
2 | new function () {
3 |
4 | /******************************************
5 | * [Atom Plugins] Prototypes
6 | ******************************************/
7 |
8 | module('[Atom Plugins] Prototypes');
9 |
10 | test('Function', function() {
11 |
12 | equal(Function.lambda('Foo')(), 'Foo', 'Function.lambda');
13 |
14 | // todo: [qtest] function.delay
15 | // todo: [qtest] function.periodical
16 | });
17 |
18 | test('Number', function(){
19 | ok(Number.random(150, 200).between(150, 200, true), 'Number.random in right range');
20 |
21 | // between
22 | ok( (50).between(20, 80), ' (50).between(20, 80)');
23 | ok(!(20).between(20, 80), '!(20).between(20, 80)');
24 | ok(!( 0).between(20, 80), '!( 0).between(20, 80)');
25 | ok( (20).between(20, 80, true), ' (20).between(20, 80, true)');
26 | ok(!(20).between(20, 80, 'R'), '!(20).between(20, 80, "R")');
27 | ok( (20).between(20, 80, 'L'), ' (20).between(20, 80, "L")');
28 | ok( (20).between(20, 80, 'LR'), ' (20).between(20, 80, "LR")');
29 | ok( (80).between(20, 80, true), ' (80).between(20, 80, true)');
30 | ok( (80).between(20, 80, 'R'), ' (80).between(20, 80, "R")');
31 | ok(!(80).between(20, 80, 'L'), '!(80).between(20, 80, "L")');
32 | ok( (80).between(20, 80, 'LR'), ' (80).between(20, 80, "LR")');
33 |
34 | // equals
35 | ok( (5).equals(5), '(5).equals(5)' );
36 | ok(!(7).equals(5), '(7).equals(5)' );
37 | notEqual( (0.7+0.1)*10, 8, '(0.7+0.1)*10 != 8' );
38 | ok( ((0.7+0.1)*10).equals(8), '(0.7+0.1)*10.equals(8)' );
39 | ok( (0.123456).equals(0.123456), ' (0.123456).equals(0.123456)' );
40 | ok(!(0.123456).equals(0.123457), '!(0.123456).equals(0.123457)' );
41 | ok( (0.123456).equals(0.123457, 4), ' (0.123456).equals(0.123457, 4)' );
42 |
43 | // limit
44 | equal((50).limit(20, 80), 50, '(50).limit(20, 80) == 50');
45 | equal((10).limit(20, 80), 20, '(10).limit(20, 80) == 20');
46 | equal((90).limit(20, 80), 80, '(90).limit(20, 80) == 80');
47 |
48 | // todo: [qtest] number.round(value)
49 | equal((15.234).round(), 15, '(15.234).round() == 15');
50 |
51 | // todo: [qtest] number.toFloat
52 | // todo: [qtest] number.toInt
53 | // todo: [qtest] number.stop
54 |
55 | // todo: [qtest] number.Math
56 | });
57 |
58 | test('String', function(){
59 | // todo: [qtest] string.safehtml
60 |
61 | ok( 'abc def ghi'.contains('abc'), 'Search with index=0' );
62 | ok( 'abc def ghi'.contains('def'), 'Search with index=average' );
63 | ok( 'abc def ghi'.contains('ghi'), 'Search with index=max' );
64 | ok( !'abc def ghi'.contains('xyz'), 'Fail search' );
65 |
66 | // repeat
67 | equal('ab-'.repeat(3), 'ab-ab-ab-', 'String.repeat');
68 |
69 | // repeat
70 | equal('result is {here}!'.substitute({ here: 123 }), 'result is 123!', 'String.substitute');
71 |
72 | // replaceAll
73 | equal('Repl/ace /all "/a"'.replaceAll('/a', '0'), 'Repl0ce 0ll "0"', 'String.replaceAll(from, to)');
74 | equal('Repl/ace /all "/a"'.replaceAll({ '/a': '0' }), 'Repl0ce 0ll "0"', 'String.replaceAll(object)');
75 |
76 | // begins
77 | ok( 'String'.begins('Str'), 'String.begins("Str")');
78 | ok(!'String'.begins('ing'), 'String.begins("ing")');
79 |
80 |
81 | ok(!'String'.ends('Str'), 'String.ends("Str")');
82 | ok( 'String'.ends('ing'), 'String.ends("ing")');
83 |
84 | // [ul]cfirst
85 | equal( 'string'.ucfirst(), 'String', 'String.ucfirst');
86 | equal( 'STRING'.lcfirst(), 'sTRING', 'String.lcfirst');
87 | });
88 |
89 | test('Array', function(){
90 | /** Static **/
91 |
92 | // todo: [qtest] Array.pickFrom
93 | deepEqual(Array.range(5, 9), [5,6,7,8,9], 'Array.range(5, 9)');
94 | deepEqual(Array.range(5, 9, 2), [5, 7, 9], 'Array.range(5, 9, 2)');
95 | deepEqual(Array.fill(5, 8), [8,8,8,8,8], 'Array.fill(5,8)');
96 | deepEqual(Array.collect({a:1, b:2, c:3}, ['a','b','z'], 9), [1,2,9], 'Array.collect');
97 |
98 | /** Dynamic **/
99 | // Contains
100 | ok( [1,2,3,4].contains(3), ' [1,2,3,4].contains(3)' );
101 | ok(![1,2,3,4].contains(0), '![1,2,3,4].contains(0)' );
102 |
103 | // include
104 | deepEqual([1,2,3].include(4), [1,2,3,4], '[1,2,3].include(4)');
105 | deepEqual([1,2,3].include(3), [1,2,3 ], '[1,2,3].include(3)');
106 |
107 | deepEqual([1,2,3].append([2,3,4]), [1,2,3,2,3,4], '[1,2,3].append([2,3,4])');
108 | deepEqual([1,2,3].append([2,3,4], [5,6,7]), [1,2,3,2,3,4,5,6,7], '[1,2,3].append([2,3,4],[5,6,7])');
109 |
110 | // erase
111 | deepEqual([1,2,3,1,2,3].erase(2), [1,3,1,3], 'array.erase');
112 |
113 | // combine
114 | deepEqual([1,2,3].combine([2,3,4]), [1,2,3,4], 'array.combine');
115 |
116 | // last
117 | equal([6,7,8,9].last, 9, 'array.last');
118 |
119 | // random
120 | ok([6,7,8,9].random.between(6, 9, true), 'array.random');
121 |
122 | strictEqual([undefined, null, 1, undefined].pick(), 1, 'array.pick, 1');
123 | strictEqual([undefined, null, 0, undefined].pick(), 0, 'array.pick, 0');
124 | strictEqual([undefined, null, '', undefined].pick(), '', 'array.pick, ""');
125 | strictEqual([undefined, null, undefined].pick(), null, 'array.pick, null');
126 |
127 | deepEqual([
128 | function (x) { return x * this.i * 0; },
129 | function (x) { return x * this.i * 1; },
130 | function (x) { return x * this.i * 2; },
131 | function (x) { return x * this.i * 3; }
132 | ].invoke({i : 2}, 5), [0, 10, 20, 30], 'array.invoke');
133 | // todo: [qtest] array.shuffle
134 | // todo: [qtest] array.sortBy
135 | equal([4, 1, 8, 13, 8].min(), 1, 'array.min');
136 | equal([4, 1, 8, 13, 8].max(), 13, 'array.max');
137 | equal([1, 2, 3, 4, 5].sum(), 15, 'array.sum');
138 | equal([1, 2, 3, 4, 5].average(), 3, 'array.average');
139 | deepEqual([1, 2, 1, 2, 1, 2].unique(), [1,2], 'array.unique');
140 | // todo: [qtest] array.associate
141 | deepEqual([1,2,0,null,'string'].clean(), [1,2,0,'string'], 'array.clean');
142 | deepEqual([1,2,3].empty(), [], 'array.empty');
143 | deepEqual([1,2,3].clone(), [1,2,3], 'array.clone() result is similar to array');
144 | notStrictEqual([1,2,3].clone(), [1,2,3], 'array.clone() result not equals to array');
145 |
146 | // todo: [qtest] array.hexToRgb
147 | // todo: [qtest] array.rgbToHex
148 | });
149 |
150 | test('Object', function(){
151 |
152 | deepEqual(Object.invert({ a:'x', b:'y', c:'z' }), { x:'a', y: 'b', z: 'c'}, 'Object.invert');
153 | deepEqual(Object.collect({ a:'x', b:'y', c:'z' }, ['a','b','k'], 5), { a:'x', b:'y', k:5}, 'Object.collect');
154 |
155 | deepEqual( Object.map({a: 5, b: 6}, function (x) { return x * x }), { a: 25, b: 36 }, 'Object.map');
156 | // todo: [qtest] Object.deepEquals
157 |
158 | var undefined, test = { foo: 2, bar: { qux: 3, zog: { asd: 4 } } };
159 |
160 | equal( Object.path.get(test, 'foo'), 2, 'Object.path.get: First level');
161 | equal( Object.path.get(test, 'bar.zog.asd'), 4, 'Object.path.get: Third level');
162 | strictEqual( Object.path.get(test, 'no.value'), undefined, 'Object.path.get: no such value');
163 |
164 | Object.path.set(test, 'rex', 15);
165 | Object.path.set(test, 'bar.zog.max', 42);
166 |
167 | equal( test.rex, 15, 'First level Object.path.set');
168 | equal( test.bar.zog.max, 42, 'Third level Object.path.set');
169 |
170 | deepEqual(test, { foo: 2, rex: 15, bar: { qux: 3, zog: { max: 42, asd: 4 } } });
171 | });
172 |
173 | };
--------------------------------------------------------------------------------
/Tests/tests/uri.js:
--------------------------------------------------------------------------------
1 |
2 | new function () {
3 |
4 | module('[Atom Plugins] Uri');
5 |
6 | var testUri = function (uri, tests) {
7 | // based on http://stevenlevithan.com/demo/parseuri/js/
8 |
9 | var parse = atom.uri(uri);
10 |
11 | for (prop in tests) if (prop != 'queryKey') {
12 | equal(parse[prop], tests[prop], prop);
13 | }
14 |
15 |
16 | if ('queryKey' in tests) deepEqual(parse.queryKey, tests.queryKey, 'queryKey');
17 | };
18 |
19 | test('Full path', function(){
20 | var uri = 'http://usr:pwd@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value#top';
21 | testUri( uri, {
22 | anchor: 'top',
23 | query: 'q1=0&&test1&test2=value',
24 | file: 'index.htm',
25 | directory: '/dir/dir.2/',
26 | path: '/dir/dir.2/index.htm',
27 | relative: '/dir/dir.2/index.htm?q1=0&&test1&test2=value#top',
28 | port: '81',
29 | host: 'www.example.com',
30 | password: 'pwd',
31 | user: 'usr',
32 | userInfo: 'usr:pwd',
33 | authority: 'usr:pwd@www.example.com:81',
34 | protocol: 'http',
35 | source: uri,
36 | queryKey: {
37 | q1: '0',
38 | test1: '',
39 | test2: 'value'
40 | }
41 | });
42 | });
43 |
44 | test('Relative path', function(){
45 | var uri = '/dir/dir.2/index.htm?q1=0&&test1&test2=value#top';
46 | testUri( uri, {
47 | anchor: 'top',
48 | query: 'q1=0&&test1&test2=value',
49 | file: 'index.htm',
50 | directory: '/dir/dir.2/',
51 | path: '/dir/dir.2/index.htm',
52 | relative: '/dir/dir.2/index.htm?q1=0&&test1&test2=value#top',
53 | port: '',
54 | host: '',
55 | password: '',
56 | user: '',
57 | userInfo: '',
58 | authority: '',
59 | protocol: '',
60 | source: uri,
61 | queryKey: {
62 | q1: '0',
63 | test1: '',
64 | test2: 'value'
65 | }
66 | });
67 | });
68 |
69 | };
--------------------------------------------------------------------------------
/Tests/visual-tests.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
94 |
--------------------------------------------------------------------------------
/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/php
2 |
3 | get_all_files() : $pkg->components_to_files($argv);
16 |
17 | $files = $pkg->complete_files($files);
18 |
19 | fwrite($stderr, "/**\n");
20 | fwrite($stderr, " * AtomJS\n * \n");
21 | fwrite($stderr, " * Included Components:\n");
22 | foreach ($files as $file){
23 | fwrite($stderr, " * - $file\n");
24 | }
25 | fwrite($stderr, " */\n\n");
26 |
27 | $output = $pkg->build($files, array(), array(), array());
28 |
29 | echo $output;
30 |
31 | fclose($stderr);
32 |
33 | ?>
34 |
--------------------------------------------------------------------------------