├── .project
├── README.md
├── build.xml
├── build
└── yuicompressor-2.4.2.jar
├── dist
├── tiquery.js
└── tiquery.min.js
├── src
├── core.js
├── events.js
├── http.js
├── intro.js
├── memory.js
├── outro.js
└── titanium.js
├── test
├── .fastdev.lock
├── .gitignore
├── .project
├── .settings
│ └── com.appcelerator.titanium.mobile.prefs
├── CHANGELOG.txt
├── LICENSE
├── LICENSE.txt
├── README
├── Resources
│ ├── KS_nav_ui.png
│ ├── KS_nav_views.png
│ ├── android
│ │ ├── appicon.png
│ │ ├── default.png
│ │ └── images
│ │ │ ├── res-long-land-hdpi
│ │ │ └── default.png
│ │ │ ├── res-long-land-ldpi
│ │ │ └── default.png
│ │ │ ├── res-long-port-hdpi
│ │ │ └── default.png
│ │ │ ├── res-long-port-ldpi
│ │ │ └── default.png
│ │ │ ├── res-notlong-land-hdpi
│ │ │ └── default.png
│ │ │ ├── res-notlong-land-ldpi
│ │ │ └── default.png
│ │ │ ├── res-notlong-land-mdpi
│ │ │ └── default.png
│ │ │ ├── res-notlong-port-hdpi
│ │ │ └── default.png
│ │ │ ├── res-notlong-port-ldpi
│ │ │ └── default.png
│ │ │ └── res-notlong-port-mdpi
│ │ │ └── default.png
│ ├── app.js
│ ├── iphone
│ │ ├── Default-Landscape.png
│ │ ├── Default-Portrait.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ └── appicon.png
│ ├── memory.js
│ ├── qunit-titanium
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── qunit
│ │ │ ├── qunit.js
│ │ │ ├── titanium_adaptor.js
│ │ │ └── titanium_adaptor_quiet.js
│ │ ├── runner.js
│ │ └── test
│ │ │ ├── events.js
│ │ │ ├── http.js
│ │ │ └── shortcuts.js
│ ├── tests.js
│ └── tiquery.js
├── manifest
└── tiapp.xml
└── version.txt
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TiQuery
4 |
5 |
6 |
7 |
8 |
9 |
10 | com.aptana.projects.webnature
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What is TiQuery?
2 |
3 | TiQuery is a javascript library that makes tasks within [Appcelerator Titanium](http://www.appcelerator.com/) easier and quicker. It is based on [jQuery](http://jquery.com).
4 |
5 | # Shortcuts
6 |
7 | TiQuery provides shortcuts to Titanium methods. Here are some:
8 |
9 | // Utilities
10 | $.info('My message');
11 | $.error('my error message');
12 | $.include('path/to/file.js');
13 | $.currentWindow;
14 |
15 | // create* methods
16 | var window = $.Window({
17 | src: 'path/to/file.js'
18 | });
19 |
20 | var view = $.View({
21 | width: 100,
22 | height: 100,
23 | backgroundColor: 'red'
24 | });
25 |
26 | window.add(view);
27 |
28 | # Events
29 |
30 | TiQuery makes adding and triggering events easy.
31 |
32 | $(view).click(function(event) {
33 | // do something
34 | });
35 |
36 | $(view).click(); // triggers the click event
37 |
38 | You can also register your own custom events.
39 |
40 | $.registerEvent('myEvent');
41 |
42 | $(window).myEvent(function() {
43 | // do something
44 | });
45 |
46 | # HTTP Client
47 |
48 | Getting data from HTTP is simple with TiQuery with its helper functions.
49 |
50 | $.get('http://www.google.com', function(data) {
51 | // do something with text data
52 | });
53 |
54 | $.post('http://www.example.com', {var1: 'value1', var2: 'value2'}, function(data) {
55 | // do something with text data
56 | });
57 |
58 | $.getJSON('http://www.example.com/file.json', function(data) {
59 | // do something with json object
60 | });
61 |
62 | $.getXML('http://www.example.com/file.xml', function(data) {
63 | // do something with xml dom object
64 | });
65 |
66 | # Documentation
67 |
68 | View the [wiki](https://github.com/naturalcodeproject/TiQuery/wiki) for more information.
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/build/yuicompressor-2.4.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/build/yuicompressor-2.4.2.jar
--------------------------------------------------------------------------------
/dist/tiquery.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * TiQuery Javascript Library for Titanium v0.0.1
3 | *
4 | * Copyright 2010 Eric Faerber, Natural Code Project
5 | * Released under GPL Version 2
6 | *
7 | * Includes large portions of jQuery
8 | * http://jquery.com
9 | * Copyright 2010, John Resig
10 | * Dual licensed under the MIT or GPL Version 2 licenses.
11 | */
12 |
13 | (function(global, Titanium, undefined) {
14 | var TiQuery = (function() {
15 | var TiQuery = function(selector) {
16 | return new TiQuery.fn.init(selector);
17 | },
18 |
19 | _TiQuery = global.TiQuery,
20 | _$ = global.$,
21 |
22 | /**
23 | * Check if a string has a non-whitespace character in it
24 | */
25 | rnotwhite = /\S/,
26 |
27 | /**
28 | * Used for trimming whitespace
29 | */
30 | rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
31 |
32 |
33 | // Save a reference to some core methods
34 | toString = Object.prototype.toString,
35 | hasOwnProperty = Object.prototype.hasOwnProperty,
36 | push = Array.prototype.push,
37 | slice = Array.prototype.slice,
38 | indexOf = Array.prototype.indexOf;
39 |
40 | TiQuery.fn = TiQuery.prototype = {
41 | init: function( selector, context ) {
42 | // Handle $(""), $(null), or $(undefined)
43 | if ( !selector ) {
44 | return this;
45 | }
46 |
47 | this.context = this[0] = selector;
48 | this.length = 1;
49 | return this;
50 | },
51 |
52 | /**
53 | * The number of elements contained in the matched element set
54 | */
55 | size: function() {
56 | return this.length;
57 | },
58 |
59 | toArray: function() {
60 | return slice.call( this, 0 );
61 | },
62 |
63 | /**
64 | * Get the Nth element in the matched element set OR
65 | * Get the whole matched element set as a clean array
66 | */
67 | get: function( num ) {
68 | return num == null ?
69 |
70 | // Return a 'clean' array
71 | this.toArray() :
72 |
73 | // Return just the object
74 | ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
75 | },
76 |
77 | /**
78 | * Take an array of elements and push it onto the stack
79 | * (returning the new matched element set)
80 | */
81 | pushStack: function( elems, name, selector ) {
82 | // Build a new TiQuery matched element set
83 | var ret = TiQuery();
84 |
85 | if ( TiQueryuery.isArray( elems ) ) {
86 | push.apply( ret, elems );
87 |
88 | } else {
89 | TiQuery.merge( ret, elems );
90 | }
91 |
92 | // Add the old object onto the stack (as a reference)
93 | ret.prevObject = this;
94 |
95 | ret.context = this.context;
96 |
97 | if ( name === "find" ) {
98 | ret.selector = this.selector + (this.selector ? " " : "") + selector;
99 | } else if ( name ) {
100 | ret.selector = this.selector + "." + name + "(" + selector + ")";
101 | }
102 |
103 | // Return the newly-formed element set
104 | return ret;
105 | },
106 |
107 | /**
108 | * Execute a callback for every element in the matched set.
109 | * (You can seed the arguments with an array of args, but this is
110 | * only used internally.)
111 | */
112 | each: function( callback, args ) {
113 | return TiQuery.each( this, callback, args );
114 | },
115 |
116 | ready: function( fn ) {
117 |
118 |
119 | return this;
120 | },
121 |
122 | eq: function( i ) {
123 | return i === -1 ?
124 | this.slice( i ) :
125 | this.slice( i, +i + 1 );
126 | },
127 |
128 | first: function() {
129 | return this.eq( 0 );
130 | },
131 |
132 | last: function() {
133 | return this.eq( -1 );
134 | },
135 |
136 | slice: function() {
137 | return this.pushStack( slice.apply( this, arguments ),
138 | "slice", slice.call(arguments).join(",") );
139 | },
140 |
141 | map: function( callback ) {
142 | return this.pushStack( TiQuery.map(this, function( elem, i ) {
143 | return callback.call( elem, i, elem );
144 | }));
145 | },
146 |
147 | end: function() {
148 | return this.prevObject || TiQuery(null);
149 | },
150 |
151 | // For internal use only.
152 | // Behaves like an Array's method, not like a TiQuery method.
153 | push: push,
154 | sort: [].sort,
155 | splice: [].splice
156 | };
157 |
158 | // Give the init function the TiQuery prototype for later instantiation
159 | TiQuery.fn.init.prototype = TiQuery.fn;
160 |
161 | TiQuery.fn.extend = TiQuery.extend = function() {
162 | // copy reference to target object
163 | var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
164 |
165 | // Handle a deep copy situation
166 | if ( typeof target === "boolean" ) {
167 | deep = target;
168 | target = arguments[1] || {};
169 | // skip the boolean and the target
170 | i = 2;
171 | }
172 |
173 | // Handle case when target is a string or something (possible in deep copy)
174 | if ( typeof target !== "object" && !TiQuery.isFunction(target) ) {
175 | target = {};
176 | }
177 |
178 | // extend TiQuery itself if only one argument is passed
179 | if ( length === i ) {
180 | target = this;
181 | --i;
182 | }
183 |
184 | for ( ; i < length; i++ ) {
185 | // Only deal with non-null/undefined values
186 | if ( (options = arguments[ i ]) != null ) {
187 | // Extend the base object
188 | for ( name in options ) {
189 | src = target[ name ];
190 | copy = options[ name ];
191 |
192 | // Prevent never-ending loop
193 | if ( target === copy ) {
194 | continue;
195 | }
196 |
197 | // Recurse if we're merging object literal values or arrays
198 | if ( deep && copy && ( TiQuery.isPlainObject(copy) || TiQuery.isArray(copy) ) ) {
199 | var clone = src && ( TiQuery.isPlainObject(src) || TiQuery.isArray(src) ) ? src
200 | : TiQuery.isArray(copy) ? [] : {};
201 |
202 | // Never move original objects, clone them
203 | target[ name ] = TiQuery.extend( deep, clone, copy );
204 |
205 | // Don't bring in undefined values
206 | } else if ( copy !== undefined ) {
207 | target[ name ] = copy;
208 | }
209 | }
210 | }
211 | }
212 |
213 | // Return the modified object
214 | return target;
215 |
216 | };
217 |
218 | TiQuery.extend({
219 | noConflict: function( deep ) {
220 | global.$ = _$;
221 |
222 | if ( deep ) {
223 | global.TiQuery = _TiQuery;
224 | }
225 |
226 | return TiQuery;
227 | },
228 |
229 | /**
230 | * See test/unit/core.js for details concerning isFunction.
231 | * Since version 1.3, DOM methods and functions like alert
232 | * aren't supported. They return false on IE (#2968).
233 | */
234 | isFunction: function( obj ) {
235 | return toString.call(obj) === "[object Function]";
236 | },
237 |
238 | isArray: function( obj ) {
239 | return toString.call(obj) === "[object Array]";
240 | },
241 |
242 | isPlainObject: function( obj ) {
243 | // Must be an Object.
244 | // Because of IE, we also have to check the presence of the constructor property.
245 | // Make sure that DOM nodes and window objects don't pass through, as well
246 | if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
247 | return false;
248 | }
249 |
250 | // Not own constructor property must be Object
251 | if ( obj.constructor
252 | && !hasOwnProperty.call(obj, "constructor")
253 | && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
254 | return false;
255 | }
256 |
257 | // Own properties are enumerated firstly, so to speed up,
258 | // if last one is own, then all properties are own.
259 |
260 | var key;
261 | for ( key in obj ) {}
262 |
263 | return key === undefined || hasOwnProperty.call( obj, key );
264 | },
265 |
266 | isEmptyObject: function( obj ) {
267 | for ( var name in obj ) {
268 | return false;
269 | }
270 | return true;
271 | },
272 |
273 | error: function( msg ) {
274 | throw msg;
275 | },
276 |
277 | parseJSON: function( data ) {
278 | if ( typeof data !== "string" || !data ) {
279 | return null;
280 | }
281 |
282 | // Make sure leading/trailing whitespace is removed (IE can't handle it)
283 | data = TiQuery.trim( data );
284 |
285 | // Make sure the incoming data is actual JSON
286 | // Logic borrowed from http://json.org/json2.js
287 | if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
288 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
289 | .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
290 | return JSON.parse(data);
291 |
292 | } else {
293 | TiQuery.error( "Invalid JSON: " + data );
294 | return false;
295 | }
296 | },
297 |
298 | noop: function() {},
299 |
300 | // args is for internal usage only
301 | each: function( object, callback, args ) {
302 | var name, i = 0,
303 | length = object.length,
304 | isObj = length === undefined || TiQuery.isFunction(object);
305 |
306 | if ( args ) {
307 | if ( isObj ) {
308 | for ( name in object ) {
309 | if ( callback.apply( object[ name ], args ) === false ) {
310 | break;
311 | }
312 | }
313 | } else {
314 | for ( ; i < length; ) {
315 | if ( callback.apply( object[ i++ ], args ) === false ) {
316 | break;
317 | }
318 | }
319 | }
320 |
321 | // A special, fast, case for the most common use of each
322 | } else {
323 | if ( isObj ) {
324 | for ( name in object ) {
325 | if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
326 | break;
327 | }
328 | }
329 | } else {
330 | for ( var value = object[0];
331 | i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
332 | }
333 | }
334 |
335 | return object;
336 | },
337 |
338 | trim: function( text ) {
339 | return (text || "").replace( rtrim, "" );
340 | },
341 |
342 | // results is for internal usage only
343 | makeArray: function( array, results ) {
344 | var ret = results || [];
345 |
346 | if ( array != null ) {
347 | // The window, strings (and functions) also have 'length'
348 | // The extra typeof function check is to prevent crashes
349 | // in Safari 2 (See: #3039)
350 | if ( array.length == null || typeof array === "string" || TiQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
351 | push.call( ret, array );
352 | } else {
353 | TiQuery.merge( ret, array );
354 | }
355 | }
356 |
357 | return ret;
358 | },
359 |
360 | inArray: function( elem, array ) {
361 | if ( array.indexOf ) {
362 | return array.indexOf( elem );
363 | }
364 |
365 | for ( var i = 0, length = array.length; i < length; i++ ) {
366 | if ( array[ i ] === elem ) {
367 | return i;
368 | }
369 | }
370 |
371 | return -1;
372 | },
373 |
374 | merge: function( first, second ) {
375 | var i = first.length, j = 0;
376 |
377 | if ( typeof second.length === "number" ) {
378 | for ( var l = second.length; j < l; j++ ) {
379 | first[ i++ ] = second[ j ];
380 | }
381 |
382 | } else {
383 | while ( second[j] !== undefined ) {
384 | first[ i++ ] = second[ j++ ];
385 | }
386 | }
387 |
388 | first.length = i;
389 |
390 | return first;
391 | },
392 |
393 | grep: function( elems, callback, inv ) {
394 | var ret = [];
395 |
396 | // Go through the array, only saving the items
397 | // that pass the validator function
398 | for ( var i = 0, length = elems.length; i < length; i++ ) {
399 | if ( !inv !== !callback( elems[ i ], i ) ) {
400 | ret.push( elems[ i ] );
401 | }
402 | }
403 |
404 | return ret;
405 | },
406 |
407 | /**
408 | * arg is for internal usage only
409 | */
410 | map: function( elems, callback, arg ) {
411 | var ret = [], value;
412 |
413 | // Go through the array, translating each of the items to their
414 | // new value (or values).
415 | for ( var i = 0, length = elems.length; i < length; i++ ) {
416 | value = callback( elems[ i ], i, arg );
417 |
418 | if ( value != null ) {
419 | ret[ ret.length ] = value;
420 | }
421 | }
422 |
423 | return ret.concat.apply( [], ret );
424 | },
425 |
426 | clone: function(obj, deep) {
427 | var newObj = {};
428 |
429 | if (deep == true) {
430 | newObj = TiQuery.extend(true, {}, obj);
431 | } else {
432 | newObj = TiQuery.extend({}, obj);
433 | }
434 |
435 | return newObj;
436 | },
437 |
438 | // A global GUID counter for objects
439 | guid: 1,
440 |
441 | proxy: function( fn, proxy, thisObject ) {
442 | if ( arguments.length === 2 ) {
443 | if ( typeof proxy === "string" ) {
444 | thisObject = fn;
445 | fn = thisObject[ proxy ];
446 | proxy = undefined;
447 |
448 | } else if ( proxy && !TiQuery.isFunction( proxy ) ) {
449 | thisObject = proxy;
450 | proxy = undefined;
451 | }
452 | }
453 |
454 | if ( !proxy && fn ) {
455 | proxy = function() {
456 | return fn.apply( thisObject || this, arguments );
457 | };
458 | }
459 |
460 | // Set the guid of unique handler to the same of original handler, so it can be removed
461 | if ( fn ) {
462 | proxy.guid = fn.guid = fn.guid || proxy.guid || TiQuery.guid++;
463 | }
464 |
465 | // So proxy can be declared as an argument
466 | return proxy;
467 | }
468 | });
469 |
470 | // expose TiQuery to the global object
471 | return (global.TiQuery = global.$ = TiQuery);
472 | })();
473 |
474 | function now() {
475 | return (new Date).getTime();
476 | }
477 | /**
478 | * events
479 | */
480 | (function(TiQuery) {
481 | TiQuery.extend({
482 | /**
483 | * registers an event shortcut
484 | */
485 | registerEvent: function(event) {
486 | TiQuery.fn[event] = function(fn) {
487 | if (fn == null) {
488 | return this.trigger(event);
489 | } else {
490 | return this.bind(event, fn);
491 | }
492 | }
493 | }
494 | });
495 |
496 | TiQuery.fn.extend({
497 | /**
498 | * binds an event to an object
499 | */
500 | bind: function(type, fn) {
501 | this[0].addEventListener(type, fn);
502 |
503 | return this;
504 | },
505 |
506 | /**
507 | * removes an event
508 | */
509 | unbind: function(type, fn) {
510 | this[0].removeEventListener(type, fn);
511 |
512 | return this;
513 | },
514 |
515 | /**
516 | * triggers an event on an object
517 | */
518 | trigger: function(type) {
519 | this[0].fireEvent(type);
520 |
521 | return this;
522 | }
523 | });
524 |
525 | var events = ['blur', 'cancel', 'click', 'dblclick', 'doubletap', 'focus', 'orientationchange', 'scroll', 'shake', 'singletap', 'swipe', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'twofingertap'];
526 |
527 | for(var i = 0, total = events.length; i < total; i++) {
528 | TiQuery.registerEvent(events[i]);
529 | }
530 |
531 | })(TiQuery);/**
532 | * http client
533 | */
534 | (function(TiQuery) {
535 | TiQuery.extend({
536 | httpSettings: {
537 | type: 'get',
538 | data: '',
539 | dataType: '',
540 | timeout: 3000, // milliseconds
541 | headers: {},
542 | onError: null,
543 | onLoad: null,
544 | onDataStream: null,
545 | onReadyStateChange: null,
546 | onSendStream: null
547 | },
548 |
549 | http: function(origSettings) {
550 | var s = TiQuery.extend(true, {}, TiQuery.httpSettings, origSettings);
551 |
552 | if (s.url == null) {
553 | return false;
554 | }
555 |
556 | s.type = s.type.toUpperCase();
557 | s.dataType = s.dataType.toUpperCase();
558 |
559 | // create the connection
560 | var http = Titanium.Network.createHTTPClient();
561 |
562 | // set callbacks
563 | http.ondatastream = s.onDataStream;
564 | http.onsendstream = s.onSendStream;
565 | http.onreadystatechange = s.onReadyStateChange;
566 |
567 | // set timeout
568 | http.setTimeout(s.timeout);
569 |
570 | // on load
571 | http.onload = function(event) {
572 | Titanium.API.debug('http complete');
573 |
574 | var results = false;
575 |
576 | if (s.dataType == 'XML') {
577 | // data is XML so parse it
578 | try {
579 | results = this.responseXML;
580 | }
581 | catch(E) {
582 | // not valid XML
583 | Titanium.API.error(E);
584 | results = false;
585 | }
586 | } else if (s.dataType == 'JSON') {
587 | // data is JSON so parse it
588 | results = TiQuery.parseJSON(this.responseText);
589 | } else {
590 | // no data type specified so don't do anything with it
591 | results = this.responseText;
592 | }
593 |
594 | if (TiQuery.isFunction(s.onLoad)) {
595 | s.onLoad(results, http, event);
596 | }
597 | }
598 |
599 | // on error
600 | http.onerror = function(event) {
601 | Titanium.API.error('http error: ' + event.error);
602 |
603 | if (TiQuery.isFunction(s.onError)) {
604 | s.onError(http, event);
605 | }
606 | }
607 |
608 | // open request
609 | http.open(s.type, s.url);
610 |
611 | // set headers
612 | if ($.isPlainObject(s.headers)) {
613 | for(var key in s.headers) {
614 | http.setRequestHeader(key, s.headers[key]);
615 | }
616 | }
617 |
618 | // send request
619 | http.send(s.data);
620 |
621 | // clear the object
622 | http = null;
623 |
624 | return true;
625 | }
626 | });
627 |
628 | var shortcuts = ['get', 'getJSON', 'getXML', 'post', 'postJSON', 'postXML'];
629 |
630 | for(var i = 0, total = shortcuts.length; i < total; i++) {
631 | (function(name) {
632 | var type = (name.indexOf('get') != -1) ? 'get' : 'post',
633 | dataType;
634 |
635 | if (name.indexOf('JSON') != -1) {
636 | dataType = 'JSON';
637 | } else if (name.indexOf('XML') != -1) {
638 | dataType = 'XML';
639 | }
640 |
641 | TiQuery[name] = function(url, data, fn, headers) {
642 | if (TiQuery.isFunction(data)) {
643 | headers = fn || {};
644 | fn = data;
645 | data = {};
646 | }
647 |
648 | this.http({
649 | type: type,
650 | url: url,
651 | data: data,
652 | dataType: dataType,
653 | headers: headers,
654 | onLoad: fn
655 | });
656 | }
657 | })(shortcuts[i]);
658 | }
659 | })(TiQuery);
660 | /**
661 | * Memory management
662 | *
663 | * see http://developer.appcelerator.com/question/116867/this-is-a-solution-to-your-memory-woes
664 | */
665 | (function(TiQuery) {
666 | TiQuery.extend({
667 | release: function(view, window) {
668 | if (!view) {
669 | return false;
670 | }
671 |
672 | if (!window) {
673 | window = Titanium.UI.currentWindow;
674 | }
675 |
676 | // create the hidden window
677 | memWindow = Titanium.UI.createWindow();
678 | memWindow.hide();
679 | memWindow.open();
680 |
681 | // remove the view from the window
682 | window.remove(view);
683 |
684 | // add the view to the hidden window
685 | if (TiQuery.isArray(view)) {
686 | for(var i = 0, total = view.length; i < total; i += 1) {
687 | memWindow.add(view[i]);
688 | }
689 | } else {
690 | memWindow.add(view);
691 | }
692 |
693 | // close the window releasing memory
694 | memWindow.close();
695 |
696 | memWindow = null;
697 | view = null;
698 | }
699 | });
700 | })(TiQuery);/**
701 | * Titanium shortcuts
702 | */
703 | (function(TiQuery) {
704 | TiQuery.extend({
705 | // shortcuts for Titanium.API.info, Titanium.API.error, etc
706 | info: function(message) { Titanium.API.info(message); },
707 | error: function(message) { Titanium.API.error(message); },
708 | warn: function(message) { Titanium.API.warn(message); },
709 | log: function(message) { Titanium.API.log(message); },
710 | include: function(file) { Titanium.include(file); },
711 | db: function(name) { return Titanium.Database.open(name); },
712 | currentWindow: function() { return Titanium.UI.currentWindow; },
713 | currenTab: function() { return Titanium.UI.currentTab; },
714 |
715 | // registers shortcuts
716 | registerShortcut: function(_namespace, _name, _shortcut, prefix) {
717 | if (_shortcut === undefined) {
718 | _shortcut = _name;
719 | }
720 |
721 | if (prefix === undefined) {
722 | prefix = 'create';
723 | }
724 |
725 | TiQuery[_shortcut] = function(args) {
726 | if (args === undefined) {
727 | args = {};
728 | }
729 | return Titanium[_namespace][prefix + _name](args);
730 | };
731 | }
732 | });
733 |
734 | /**
735 | * creates shortcuts to for create* methods within Titanium
736 | *
737 | * Idea/some code taken from Redux by Dawson Toth (https://github.com/dawsontoth/Appcelerator-Titanium-Redux)
738 | */
739 | var classes = {
740 | Android: ['BroadcastIntent', 'Intent', 'IntentChooser', 'Notification', 'PendingIntent', 'Service', 'ServiceIntent'],
741 | Contacts: ['Group', 'Person'],
742 | Facebook: ['LoginButton'],
743 | Filesystem: ['File', 'TempDirectory', 'TempFile'],
744 | Map: ['Annotation'],
745 | Media: ['AudioPlayer', 'AudioRecorder', 'Item', 'MusicPlayer', 'Sound', 'VideoPlayer'],
746 | Network: ['BonjourBrowser', 'BonjourService', 'HTTPClient', 'TCPSocket'],
747 | Platform: ['UUID'],
748 | Stream: ['Stream'],
749 | UI: ['2DMatrix', '3DMatrix', 'ActivityIndicator', 'AlertDialog', 'Animation', 'Button', 'ButtonBar', 'CoverFlowView', 'DashboardItem', 'DashboardView', 'EmailDialog', 'ImageView', 'Label', 'OptionDialog', 'Picker', 'PickerColumn', 'PickerRow', 'ProgressBar', 'ScrollView', 'ScrollableView', 'SearchBar', 'Slider', 'Switch', 'Tab', 'TabGroup', 'TabbedBar', 'TableView', 'TableViewRow', 'TableViewSection', 'TextArea', 'TextField', 'Toolbar', 'View', 'WebView', 'Window']
750 | }
751 |
752 | for(var namespace in classes) {
753 | for(var i = 0, total = classes[namespace].length; i < total; i++) {
754 | TiQuery.registerShortcut(namespace, classes[namespace][i])
755 | }
756 | }
757 |
758 | // A couple of methods don't follow the same pattern above so here they are
759 | TiQuery.registerShortcut('Map', 'View', 'MapView');
760 | })(TiQuery);})(this, Titanium);
--------------------------------------------------------------------------------
/dist/tiquery.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * TiQuery Javascript Library for Titanium v0.0.1
3 | *
4 | * Copyright 2010 Eric Faerber, Natural Code Project
5 | * Released under GPL Version 2
6 | *
7 | * Includes large portions of jQuery
8 | * http://jquery.com
9 | * Copyright 2010, John Resig
10 | * Dual licensed under the MIT or GPL Version 2 licenses.
11 | */
12 | (function(c,e,d){var b=(function(){var i=function(p){return new i.fn.init(p)},h=c.TiQuery,k=c.$,o=/\S/,j=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,f=Object.prototype.toString,g=Object.prototype.hasOwnProperty,l=Array.prototype.push,n=Array.prototype.slice,m=Array.prototype.indexOf;i.fn=i.prototype={init:function(p,q){if(!p){return this}this.context=this[0]=p;this.length=1;return this},size:function(){return this.length},toArray:function(){return n.call(this,0)},get:function(p){return p==null?this.toArray():(p<0?this.slice(p)[0]:this[p])},pushStack:function(q,s,p){var r=i();if(TiQueryuery.isArray(q)){l.apply(r,q)}else{i.merge(r,q)}r.prevObject=this;r.context=this.context;if(s==="find"){r.selector=this.selector+(this.selector?" ":"")+p}else{if(s){r.selector=this.selector+"."+s+"("+p+")"}}return r},each:function(q,p){return i.each(this,q,p)},ready:function(p){return this},eq:function(p){return p===-1?this.slice(p):this.slice(p,+p+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(n.apply(this,arguments),"slice",n.call(arguments).join(","))},map:function(p){return this.pushStack(i.map(this,function(r,q){return p.call(r,q,r)}))},end:function(){return this.prevObject||i(null)},push:l,sort:[].sort,splice:[].splice};i.fn.init.prototype=i.fn;i.fn.extend=i.extend=function(){var u=arguments[0]||{},t=1,s=arguments.length,w=false,x,r,p,q;if(typeof u==="boolean"){w=u;u=arguments[1]||{};t=2}if(typeof u!=="object"&&!i.isFunction(u)){u={}}if(s===t){u=this;--t}for(;t
2 |
3 | Tests2
4 |
5 |
6 |
7 |
8 |
9 | com.appcelerator.titanium.core.builder
10 |
11 |
12 |
13 |
14 | com.aptana.ide.core.unifiedBuilder
15 |
16 |
17 |
18 |
19 |
20 | com.appcelerator.titanium.mobile.nature
21 | com.aptana.projects.webnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/.settings/com.appcelerator.titanium.mobile.prefs:
--------------------------------------------------------------------------------
1 | #Fri Sep 30 13:59:24 MDT 2011
2 | MOBILE_PROJECT_SDK_VERSION=1.7.2
3 | eclipse.preferences.version=1
4 |
--------------------------------------------------------------------------------
/test/CHANGELOG.txt:
--------------------------------------------------------------------------------
1 | Place your change log text here. This file will be incorporated with your app at package time.
--------------------------------------------------------------------------------
/test/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2009 Appcelerator, Inc.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | (or the full text of the license is below)
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 |
18 |
19 | Apache License
20 | Version 2.0, January 2004
21 | http://www.apache.org/licenses/
22 |
23 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
24 |
25 | 1. Definitions.
26 |
27 | "License" shall mean the terms and conditions for use, reproduction,
28 | and distribution as defined by Sections 1 through 9 of this document.
29 |
30 | "Licensor" shall mean the copyright owner or entity authorized by
31 | the copyright owner that is granting the License.
32 |
33 | "Legal Entity" shall mean the union of the acting entity and all
34 | other entities that control, are controlled by, or are under common
35 | control with that entity. For the purposes of this definition,
36 | "control" means (i) the power, direct or indirect, to cause the
37 | direction or management of such entity, whether by contract or
38 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
39 | outstanding shares, or (iii) beneficial ownership of such entity.
40 |
41 | "You" (or "Your") shall mean an individual or Legal Entity
42 | exercising permissions granted by this License.
43 |
44 | "Source" form shall mean the preferred form for making modifications,
45 | including but not limited to software source code, documentation
46 | source, and configuration files.
47 |
48 | "Object" form shall mean any form resulting from mechanical
49 | transformation or translation of a Source form, including but
50 | not limited to compiled object code, generated documentation,
51 | and conversions to other media types.
52 |
53 | "Work" shall mean the work of authorship, whether in Source or
54 | Object form, made available under the License, as indicated by a
55 | copyright notice that is included in or attached to the work
56 | (an example is provided in the Appendix below).
57 |
58 | "Derivative Works" shall mean any work, whether in Source or Object
59 | form, that is based on (or derived from) the Work and for which the
60 | editorial revisions, annotations, elaborations, or other modifications
61 | represent, as a whole, an original work of authorship. For the purposes
62 | of this License, Derivative Works shall not include works that remain
63 | separable from, or merely link (or bind by name) to the interfaces of,
64 | the Work and Derivative Works thereof.
65 |
66 | "Contribution" shall mean any work of authorship, including
67 | the original version of the Work and any modifications or additions
68 | to that Work or Derivative Works thereof, that is intentionally
69 | submitted to Licensor for inclusion in the Work by the copyright owner
70 | or by an individual or Legal Entity authorized to submit on behalf of
71 | the copyright owner. For the purposes of this definition, "submitted"
72 | means any form of electronic, verbal, or written communication sent
73 | to the Licensor or its representatives, including but not limited to
74 | communication on electronic mailing lists, source code control systems,
75 | and issue tracking systems that are managed by, or on behalf of, the
76 | Licensor for the purpose of discussing and improving the Work, but
77 | excluding communication that is conspicuously marked or otherwise
78 | designated in writing by the copyright owner as "Not a Contribution."
79 |
80 | "Contributor" shall mean Licensor and any individual or Legal Entity
81 | on behalf of whom a Contribution has been received by Licensor and
82 | subsequently incorporated within the Work.
83 |
84 | 2. Grant of Copyright License. Subject to the terms and conditions of
85 | this License, each Contributor hereby grants to You a perpetual,
86 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
87 | copyright license to reproduce, prepare Derivative Works of,
88 | publicly display, publicly perform, sublicense, and distribute the
89 | Work and such Derivative Works in Source or Object form.
90 |
91 | 3. Grant of Patent License. Subject to the terms and conditions of
92 | this License, each Contributor hereby grants to You a perpetual,
93 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
94 | (except as stated in this section) patent license to make, have made,
95 | use, offer to sell, sell, import, and otherwise transfer the Work,
96 | where such license applies only to those patent claims licensable
97 | by such Contributor that are necessarily infringed by their
98 | Contribution(s) alone or by combination of their Contribution(s)
99 | with the Work to which such Contribution(s) was submitted. If You
100 | institute patent litigation against any entity (including a
101 | cross-claim or counterclaim in a lawsuit) alleging that the Work
102 | or a Contribution incorporated within the Work constitutes direct
103 | or contributory patent infringement, then any patent licenses
104 | granted to You under this License for that Work shall terminate
105 | as of the date such litigation is filed.
106 |
107 | 4. Redistribution. You may reproduce and distribute copies of the
108 | Work or Derivative Works thereof in any medium, with or without
109 | modifications, and in Source or Object form, provided that You
110 | meet the following conditions:
111 |
112 | (a) You must give any other recipients of the Work or
113 | Derivative Works a copy of this License; and
114 |
115 | (b) You must cause any modified files to carry prominent notices
116 | stating that You changed the files; and
117 |
118 | (c) You must retain, in the Source form of any Derivative Works
119 | that You distribute, all copyright, patent, trademark, and
120 | attribution notices from the Source form of the Work,
121 | excluding those notices that do not pertain to any part of
122 | the Derivative Works; and
123 |
124 | (d) If the Work includes a "NOTICE" text file as part of its
125 | distribution, then any Derivative Works that You distribute must
126 | include a readable copy of the attribution notices contained
127 | within such NOTICE file, excluding those notices that do not
128 | pertain to any part of the Derivative Works, in at least one
129 | of the following places: within a NOTICE text file distributed
130 | as part of the Derivative Works; within the Source form or
131 | documentation, if provided along with the Derivative Works; or,
132 | within a display generated by the Derivative Works, if and
133 | wherever such third-party notices normally appear. The contents
134 | of the NOTICE file are for informational purposes only and
135 | do not modify the License. You may add Your own attribution
136 | notices within Derivative Works that You distribute, alongside
137 | or as an addendum to the NOTICE text from the Work, provided
138 | that such additional attribution notices cannot be construed
139 | as modifying the License.
140 |
141 | You may add Your own copyright statement to Your modifications and
142 | may provide additional or different license terms and conditions
143 | for use, reproduction, or distribution of Your modifications, or
144 | for any such Derivative Works as a whole, provided Your use,
145 | reproduction, and distribution of the Work otherwise complies with
146 | the conditions stated in this License.
147 |
148 | 5. Submission of Contributions. Unless You explicitly state otherwise,
149 | any Contribution intentionally submitted for inclusion in the Work
150 | by You to the Licensor shall be under the terms and conditions of
151 | this License, without any additional terms or conditions.
152 | Notwithstanding the above, nothing herein shall supersede or modify
153 | the terms of any separate license agreement you may have executed
154 | with Licensor regarding such Contributions.
155 |
156 | 6. Trademarks. This License does not grant permission to use the trade
157 | names, trademarks, service marks, or product names of the Licensor,
158 | except as required for reasonable and customary use in describing the
159 | origin of the Work and reproducing the content of the NOTICE file.
160 |
161 | 7. Disclaimer of Warranty. Unless required by applicable law or
162 | agreed to in writing, Licensor provides the Work (and each
163 | Contributor provides its Contributions) on an "AS IS" BASIS,
164 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
165 | implied, including, without limitation, any warranties or conditions
166 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
167 | PARTICULAR PURPOSE. You are solely responsible for determining the
168 | appropriateness of using or redistributing the Work and assume any
169 | risks associated with Your exercise of permissions under this License.
170 |
171 | 8. Limitation of Liability. In no event and under no legal theory,
172 | whether in tort (including negligence), contract, or otherwise,
173 | unless required by applicable law (such as deliberate and grossly
174 | negligent acts) or agreed to in writing, shall any Contributor be
175 | liable to You for damages, including any direct, indirect, special,
176 | incidental, or consequential damages of any character arising as a
177 | result of this License or out of the use or inability to use the
178 | Work (including but not limited to damages for loss of goodwill,
179 | work stoppage, computer failure or malfunction, or any and all
180 | other commercial damages or losses), even if such Contributor
181 | has been advised of the possibility of such damages.
182 |
183 | 9. Accepting Warranty or Additional Liability. While redistributing
184 | the Work or Derivative Works thereof, You may choose to offer,
185 | and charge a fee for, acceptance of support, warranty, indemnity,
186 | or other liability obligations and/or rights consistent with this
187 | License. However, in accepting such obligations, You may act only
188 | on Your own behalf and on Your sole responsibility, not on behalf
189 | of any other Contributor, and only if You agree to indemnify,
190 | defend, and hold each Contributor harmless for any liability
191 | incurred by, or claims asserted against, such Contributor by reason
192 | of your accepting any such warranty or additional liability.
193 |
194 | END OF TERMS AND CONDITIONS
195 |
196 | APPENDIX: How to apply the Apache License to your work.
197 |
198 | To apply the Apache License to your work, attach the following
199 | boilerplate notice, with the fields enclosed by brackets "[]"
200 | replaced with your own identifying information. (Don't include
201 | the brackets!) The text should be enclosed in the appropriate
202 | comment syntax for the file format. We also recommend that a
203 | file or class name and description of purpose be included on the
204 | same "printed page" as the copyright notice for easier
205 | identification within third-party archives.
206 |
207 | Copyright [yyyy] [name of copyright owner]
208 |
209 | Licensed under the Apache License, Version 2.0 (the "License");
210 | you may not use this file except in compliance with the License.
211 | You may obtain a copy of the License at
212 |
213 | http://www.apache.org/licenses/LICENSE-2.0
214 |
215 | Unless required by applicable law or agreed to in writing, software
216 | distributed under the License is distributed on an "AS IS" BASIS,
217 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
218 | See the License for the specific language governing permissions and
219 | limitations under the License.
--------------------------------------------------------------------------------
/test/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Place your license text here. This file will be incorporated with your app at package time.
--------------------------------------------------------------------------------
/test/README:
--------------------------------------------------------------------------------
1 | Welcome to your Appcelerator Titanium Mobile Project
2 |
3 | This is a blank project. Start by editing your application's app.js to
4 | make your first mobile project using Titanium.
5 |
6 |
7 |
8 | ----------------------------------
9 | Stuff our legal folk make us say:
10 |
11 | Appcelerator, Appcelerator Titanium and associated marks and logos are
12 | trademarks of Appcelerator, Inc.
13 |
14 | Titanium is Copyright (c) 2009-2010 by Appcelerator, Inc. All Rights Reserved.
15 |
16 | Titanium is licensed under the Apache Public License (Version 2). Please
17 | see the LICENSE file for the full license.
18 |
19 |
--------------------------------------------------------------------------------
/test/Resources/KS_nav_ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/KS_nav_ui.png
--------------------------------------------------------------------------------
/test/Resources/KS_nav_views.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/KS_nav_views.png
--------------------------------------------------------------------------------
/test/Resources/android/appicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/appicon.png
--------------------------------------------------------------------------------
/test/Resources/android/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-long-land-hdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-long-land-hdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-long-land-ldpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-long-land-ldpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-long-port-hdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-long-port-hdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-long-port-ldpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-long-port-ldpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-land-hdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-land-hdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-land-ldpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-land-ldpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-land-mdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-land-mdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-port-hdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-port-hdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-port-ldpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-port-ldpi/default.png
--------------------------------------------------------------------------------
/test/Resources/android/images/res-notlong-port-mdpi/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/android/images/res-notlong-port-mdpi/default.png
--------------------------------------------------------------------------------
/test/Resources/app.js:
--------------------------------------------------------------------------------
1 | var tabGroup = Titanium.UI.createTabGroup();
2 |
3 | var testsWindow = Titanium.UI.createWindow({
4 | url: "tests.js",
5 | title: "Unit Tests",
6 | backgroundColor: "#000000"
7 | });
8 |
9 | var testsTab = Titanium.UI.createTab({
10 | window: testsWindow,
11 | title: testsWindow.title
12 | });
13 |
14 | tabGroup.addTab(testsTab);
15 |
16 | var memoryWindow = Titanium.UI.createWindow({
17 | url: "memory.js",
18 | title: "Memory Tests",
19 | backgroundColor: "#000000"
20 | });
21 |
22 | var memoryTab = Titanium.UI.createTab({
23 | window: memoryWindow,
24 | title: memoryWindow.title
25 | });
26 |
27 | tabGroup.addTab(memoryTab);
28 |
29 | tabGroup.open();
--------------------------------------------------------------------------------
/test/Resources/iphone/Default-Landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/iphone/Default-Landscape.png
--------------------------------------------------------------------------------
/test/Resources/iphone/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/iphone/Default-Portrait.png
--------------------------------------------------------------------------------
/test/Resources/iphone/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/iphone/Default.png
--------------------------------------------------------------------------------
/test/Resources/iphone/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/iphone/Default@2x.png
--------------------------------------------------------------------------------
/test/Resources/iphone/appicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/iphone/appicon.png
--------------------------------------------------------------------------------
/test/Resources/memory.js:
--------------------------------------------------------------------------------
1 | Titanium.include('tiquery.js');
2 |
3 | var win = $.currentWindow();
4 |
5 | var view = $.View({
6 | width: "100%",
7 | height: "100%"
8 | });
9 |
10 | win.add(view);
11 |
12 | // memory display
13 | var memory = $.Label({
14 | width: 'auto',
15 | height: 'auto',
16 | bottom: 0,
17 | left: 0,
18 | font:{fontSize:20,fontFamily:'Helvetica Neue'},
19 | color: '#FFFFFF',
20 | zIndex: 1000
21 | });
22 |
23 | win.add(memory);
24 |
25 | function updateMemory() {
26 | memory.text = Titanium.Platform.availableMemory;
27 |
28 | setTimeout(updateMemory, 500);
29 | }
30 |
31 | updateMemory();
32 |
33 | // shapes button
34 | var addShapesBttn = $.Button({
35 | width: 200,
36 | height: 30,
37 | title: "Add Shapes",
38 | bottom: 0,
39 | right: 0,
40 | zIndex: 1000
41 | });
42 |
43 | win.add(addShapesBttn);
44 |
45 | var colors = [
46 | "red",
47 | "green",
48 | "yellow",
49 | "orange",
50 | "purple",
51 | "blue",
52 | "white"
53 | ];
54 |
55 | var adding = false;
56 | $(addShapesBttn).click(function() {
57 | if (adding == true) {
58 | return;
59 | }
60 |
61 | adding = true;
62 |
63 | for(var i = 0; i < 10; i += 1) {
64 | (function() {
65 | var shape = $.View({
66 | width: randomNumber(500),
67 | height: randomNumber(500),
68 | top: randomNumber(500),
69 | left: randomNumber(500),
70 | borderRadius: randomNumber(25),
71 | backgroundColor: colors[randomNumber(colors.length)]
72 | });
73 |
74 | view.add(shape);
75 | })()
76 | }
77 |
78 | adding = false;
79 | });
80 |
81 | var addImagesBttn = $.Button({
82 | width: 200,
83 | height: 30,
84 | title: "Add Images",
85 | bottom: 0,
86 | right: 220,
87 | zIndex: 1000
88 | });
89 | win.add(addImagesBttn);
90 |
91 | $(addImagesBttn).click(function() {
92 | for(var i = 0; i < 10; i += 1) {
93 | (function() {
94 | var now = new Date();
95 | var image = $.ImageView({
96 | width: randomNumber(500),
97 | height: randomNumber(500),
98 | top: randomNumber(500),
99 | left: randomNumber(500),
100 | image: 'http://www.cornify.com/getacorn.php?r=' + now.getTime() + '&url=https://github.com/wGEric/TiQuery',
101 | })
102 |
103 | view.add(image);
104 | })();
105 | }
106 | });
107 |
108 | var releaseBttn = $.Button({
109 | width: 200,
110 | height: 30,
111 | title: "Release Memory",
112 | bottom: 0,
113 | right: 440,
114 | zIndex: 1000
115 | });
116 | win.add(releaseBttn);
117 |
118 | $(releaseBttn).click(function() {
119 | $.release(view);
120 |
121 | view = $.View({
122 | width: "100%",
123 | height: "100%"
124 | });
125 | win.add(view);
126 | });
127 |
128 | function randomNumber(max) {
129 | return Math.floor(Math.random() * (max + 1));
130 | }
131 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .swp
3 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/README.md:
--------------------------------------------------------------------------------
1 | This is the very first stab at getting qunit to work in Titanium.
2 |
3 | The qunit.js file has been patched so most tests run. However, one test is failing even though there does not seem to be a problem.
4 |
5 | The great thing is that this supports asynch tests, though I haven't done too much yet with it.
6 |
7 | Install
8 | =======
9 | Via git submodule:
10 | (from the top of your titanium app:)
11 | git submodule add git://github.com/mindreframer/qunit-titanium.git Resources/vendor/qunit-titanium
12 | cp vendor/qunit-titanium/runner.js runner.js
13 | mkdir -p test
14 | cp vendor/qunit-titanium/test/*.js test/
15 |
16 |
17 | Modify tests_to_run.js to include your tests.
18 |
19 | Add the app.js_snippet to your app.js (assuming you are using tabGroups, otherwise you will have to find another way).
20 |
21 | For mocking, I've tested jsMockito support. Follow the instructions to install jsMockito (http://chrisleishman.github.com/jsmockito/) and uncomment the lines in titanium_adaptor.js (correcting the subdirectories, etc. on the way).
22 |
23 | Disclaimer
24 | ==========
25 | This is a work in progress. Please comment with any issues you are having.
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "qunit",
3 | "author": {
4 | "name": "John Resig",
5 | "email": "jeresig@gmail.com",
6 | "url": "http://ejohn.org/"
7 | },
8 | "maintainer": {
9 | "name": "Jörn Zaefferer",
10 | "email": "joern.zaefferer@googlemail.com",
11 | "url": "http://bassistance.de/"
12 | },
13 | "url": "http://docs.jquery.com/QUnit",
14 | "license": {
15 | "name": "MIT",
16 | "url": "http://www.opensource.org/licenses/mit-license.php"
17 | },
18 | "description": "An easy-to-use JavaScript Unit Testing framework.",
19 | "keywords": [ "testing", "unit", "jquery" ],
20 | "lib": "qunit"
21 | }
22 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/qunit/qunit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * QUnit - A JavaScript Unit Testing Framework
3 | *
4 | * http://docs.jquery.com/QUnit
5 | *
6 | * Copyright (c) 2009 John Resig, Jörn Zaefferer
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | */
10 |
11 | (function(window) {
12 |
13 | var QUnit = {
14 |
15 | // call on start of module test to prepend name to all tests
16 | module: function(name, testEnvironment) {
17 | config.currentModule = name;
18 |
19 | synchronize(function() {
20 | if ( config.currentModule ) {
21 | QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
22 | }
23 |
24 | config.currentModule = name;
25 | config.moduleTestEnvironment = testEnvironment;
26 | config.moduleStats = { all: 0, bad: 0 };
27 |
28 | QUnit.moduleStart( name, testEnvironment );
29 | });
30 | },
31 |
32 | asyncTest: function(testName, expected, callback) {
33 | if ( arguments.length === 2 ) {
34 | callback = expected;
35 | expected = 0;
36 | }
37 |
38 | QUnit.test(testName, expected, callback, true);
39 | },
40 |
41 | test: function(testName, expected, callback, async) {
42 | var name = '' + testName + '', testEnvironment, testEnvironmentArg;
43 |
44 | if ( arguments.length === 2 ) {
45 | callback = expected;
46 | expected = null;
47 | }
48 | // is 2nd argument a testEnvironment?
49 | if ( expected && typeof expected === 'object') {
50 | testEnvironmentArg = expected;
51 | expected = null;
52 | }
53 |
54 | if ( config.currentModule ) {
55 | name = '' + config.currentModule + ": " + name;
56 | }
57 |
58 | if ( !validTest(config.currentModule + ": " + testName) ) {
59 | return;
60 | }
61 |
62 | synchronize(function() {
63 |
64 | testEnvironment = extend({
65 | setup: function() {},
66 | teardown: function() {}
67 | }, config.moduleTestEnvironment);
68 | if (testEnvironmentArg) {
69 | extend(testEnvironment,testEnvironmentArg);
70 | }
71 |
72 | QUnit.testStart( testName, testEnvironment );
73 |
74 | // allow utility functions to access the current test environment
75 | QUnit.current_testEnvironment = testEnvironment;
76 |
77 | config.assertions = [];
78 | config.expected = expected;
79 |
80 | var tests = id("qunit-tests");
81 | if (tests) {
82 | var b = document.createElement("strong");
83 | b.innerHTML = "Running " + name;
84 | var li = document.createElement("li");
85 | li.appendChild( b );
86 | li.id = "current-test-output";
87 | tests.appendChild( li )
88 | }
89 |
90 | try {
91 | if ( !config.pollution ) {
92 | saveGlobal();
93 | }
94 |
95 | testEnvironment.setup.call(testEnvironment);
96 | } catch(e) {
97 | QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
98 | }
99 | });
100 |
101 | synchronize(function() {
102 | if ( async ) {
103 | QUnit.stop();
104 | }
105 |
106 | try {
107 | callback.call(testEnvironment);
108 | } catch(e) {
109 | fail("Test " + name + " died, exception and test follows", e, callback);
110 | var message;
111 | if (e.message) {
112 | message = e.message;
113 | } else {
114 | message = JSON.stringify(e);
115 | }
116 | QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + message );
117 | // else next test will carry the responsibility
118 | saveGlobal();
119 |
120 | // Restart the tests if they're blocking
121 | if ( config.blocking ) {
122 | start();
123 | }
124 | }
125 | });
126 |
127 | synchronize(function() {
128 | try {
129 | checkPollution();
130 | testEnvironment.teardown.call(testEnvironment);
131 | } catch(e) {
132 | QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
133 | }
134 | });
135 |
136 | synchronize(function() {
137 | try {
138 | QUnit.reset();
139 | } catch(e) {
140 | fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
141 | }
142 |
143 | if ( config.expected && config.expected != config.assertions.length ) {
144 | QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
145 | }
146 |
147 | var good = 0, bad = 0,
148 | tests = id("qunit-tests");
149 |
150 | config.stats.all += config.assertions.length;
151 | config.moduleStats.all += config.assertions.length;
152 |
153 | if ( tests ) {
154 | var ol = document.createElement("ol");
155 |
156 | for ( var i = 0; i < config.assertions.length; i++ ) {
157 | var assertion = config.assertions[i];
158 |
159 | var li = document.createElement("li");
160 | li.className = assertion.result ? "pass" : "fail";
161 | li.innerHTML = assertion.message || "(no message)";
162 | ol.appendChild( li );
163 |
164 | if ( assertion.result ) {
165 | good++;
166 | } else {
167 | bad++;
168 | config.stats.bad++;
169 | config.moduleStats.bad++;
170 | }
171 | }
172 | if (bad == 0) {
173 | ol.style.display = "none";
174 | }
175 |
176 | var b = document.createElement("strong");
177 | b.innerHTML = name + " (" + bad + ", " + good + ", " + config.assertions.length + ")";
178 |
179 | addEvent(b, "click", function() {
180 | var next = b.nextSibling, display = next.style.display;
181 | next.style.display = display === "none" ? "block" : "none";
182 | });
183 |
184 | addEvent(b, "dblclick", function(e) {
185 | var target = e && e.target ? e.target : window.event.srcElement;
186 | if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
187 | target = target.parentNode;
188 | }
189 | if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
190 | window.location.search = "?" + encodeURIComponent(getText([target]).replace(/\(.+\)$/, "").replace(/(^\s*|\s*$)/g, ""));
191 | }
192 | });
193 |
194 | var li = id("current-test-output");
195 | li.id = "";
196 | li.className = bad ? "fail" : "pass";
197 | li.removeChild( li.firstChild );
198 | li.appendChild( b );
199 | li.appendChild( ol );
200 |
201 | if ( bad ) {
202 | var toolbar = id("qunit-testrunner-toolbar");
203 | if ( toolbar ) {
204 | toolbar.style.display = "block";
205 | id("qunit-filter-pass").disabled = null;
206 | id("qunit-filter-missing").disabled = null;
207 | }
208 | }
209 |
210 | } else {
211 | for ( var i = 0; i < config.assertions.length; i++ ) {
212 | if ( !config.assertions[i].result ) {
213 | bad++;
214 | config.stats.bad++;
215 | config.moduleStats.bad++;
216 | }
217 | }
218 | }
219 |
220 | QUnit.testDone( testName, bad, config.assertions.length );
221 |
222 | if ( !window.setTimeout && !config.queue.length ) {
223 | done();
224 | }
225 | });
226 |
227 | if ( window.setTimeout && !config.doneTimer ) {
228 | config.doneTimer = window.setTimeout(function(){
229 | if ( !config.queue.length ) {
230 | done();
231 | } else {
232 | synchronize( done );
233 | }
234 | }, 13);
235 | }
236 | },
237 |
238 | /**
239 | * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
240 | */
241 | expect: function(asserts) {
242 | config.expected = asserts;
243 | },
244 |
245 | /**
246 | * Asserts true.
247 | * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
248 | */
249 | ok: function(a, msg) {
250 | msg = escapeHtml(msg);
251 | if(!a){QUnit.log(a, msg);}
252 |
253 | config.assertions.push({
254 | result: !!a,
255 | message: msg
256 | });
257 | },
258 |
259 | /**
260 | * Checks that the first two arguments are equal, with an optional message.
261 | * Prints out both actual and expected values.
262 | *
263 | * Prefered to ok( actual == expected, message )
264 | *
265 | * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
266 | *
267 | * @param Object actual
268 | * @param Object expected
269 | * @param String message (optional)
270 | */
271 | equal: function(actual, expected, message) {
272 | push(expected == actual, actual, expected, message);
273 | },
274 |
275 | notEqual: function(actual, expected, message) {
276 | push(expected != actual, actual, expected, message);
277 | },
278 |
279 | deepEqual: function(actual, expected, message) {
280 | push(QUnit.equiv(actual, expected), actual, expected, message);
281 | },
282 |
283 | notDeepEqual: function(actual, expected, message) {
284 | push(!QUnit.equiv(actual, expected), actual, expected, message);
285 | },
286 |
287 | strictEqual: function(actual, expected, message) {
288 | push(expected === actual, actual, expected, message);
289 | },
290 |
291 | notStrictEqual: function(actual, expected, message) {
292 | push(expected !== actual, actual, expected, message);
293 | },
294 |
295 | raises: function(fn, message) {
296 | try {
297 | fn();
298 | ok( false, message );
299 | }
300 | catch (e) {
301 | ok( true, message );
302 | }
303 | },
304 |
305 | start: function(run_sync) {
306 | // A slight delay, to avoid any current callbacks
307 | if ( window.setTimeout && !run_sync) {
308 | window.setTimeout(function() {
309 | if ( config.timeout ) {
310 | clearTimeout(config.timeout);
311 | }
312 |
313 | config.blocking = false;
314 | process();
315 | }, 13);
316 | } else {
317 | config.blocking = false;
318 | process();
319 | }
320 | },
321 |
322 | stop: function(timeout) {
323 | config.blocking = true;
324 |
325 | if ( timeout && window.setTimeout ) {
326 | config.timeout = window.setTimeout(function() {
327 | QUnit.ok( false, "Test timed out" );
328 | QUnit.start();
329 | }, timeout);
330 | }
331 | }
332 |
333 | };
334 |
335 | // Backwards compatibility, deprecated
336 | QUnit.equals = QUnit.equal;
337 | QUnit.same = QUnit.deepEqual;
338 |
339 | // Maintain internal state
340 | var config = {
341 | // The queue of tests to run
342 | queue: [],
343 |
344 | // block until document ready
345 | blocking: true
346 | };
347 |
348 | // Load paramaters
349 | (function() {
350 | var location = window.location || { search: "", protocol: "file:" },
351 | GETParams = location.search.slice(1).split('&');
352 |
353 | for ( var i = 0; i < GETParams.length; i++ ) {
354 | GETParams[i] = decodeURIComponent( GETParams[i] );
355 | if ( GETParams[i] === "noglobals" ) {
356 | GETParams.splice( i, 1 );
357 | i--;
358 | config.noglobals = true;
359 | } else if ( GETParams[i].search('=') > -1 ) {
360 | GETParams.splice( i, 1 );
361 | i--;
362 | }
363 | }
364 |
365 | // restrict modules/tests by get parameters
366 | config.filters = GETParams;
367 |
368 | // Figure out if we're running the tests from a server or not
369 | QUnit.isLocal = !!(location.protocol === 'file:');
370 | })();
371 |
372 | // Expose the API as global variables, unless an 'exports'
373 | // object exists, in that case we assume we're in CommonJS
374 | if ( typeof exports === "undefined" || typeof require === "undefined" ) {
375 | extend(window, QUnit);
376 | window.QUnit = QUnit;
377 | } else {
378 | extend(exports, QUnit);
379 | exports.QUnit = QUnit;
380 | }
381 |
382 | // define these after exposing globals to keep them in these QUnit namespace only
383 | extend(QUnit, {
384 | config: config,
385 |
386 | // Initialize the configuration options
387 | init: function() {
388 | extend(config, {
389 | stats: { all: 0, bad: 0 },
390 | moduleStats: { all: 0, bad: 0 },
391 | started: +new Date,
392 | updateRate: 1000,
393 | blocking: false,
394 | autostart: true,
395 | autorun: false,
396 | assertions: [],
397 | filters: [],
398 | queue: []
399 | });
400 |
401 | var tests = id("qunit-tests"),
402 | banner = id("qunit-banner"),
403 | result = id("qunit-testresult");
404 |
405 | if ( tests ) {
406 | tests.innerHTML = "";
407 | }
408 |
409 | if ( banner ) {
410 | banner.className = "";
411 | }
412 |
413 | if ( result ) {
414 | result.parentNode.removeChild( result );
415 | }
416 | },
417 |
418 | /**
419 | * Resets the test setup. Useful for tests that modify the DOM.
420 | */
421 | reset: function() {
422 | if ( window.jQuery ) {
423 | jQuery("#main, #qunit-fixture").html( config.fixture );
424 | }
425 | },
426 |
427 | /**
428 | * Trigger an event on an element.
429 | *
430 | * @example triggerEvent( document.body, "click" );
431 | *
432 | * @param DOMElement elem
433 | * @param String type
434 | */
435 | triggerEvent: function( elem, type, event ) {
436 | if ( document.createEvent ) {
437 | event = document.createEvent("MouseEvents");
438 | event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
439 | 0, 0, 0, 0, 0, false, false, false, false, 0, null);
440 | elem.dispatchEvent( event );
441 |
442 | } else if ( elem.fireEvent ) {
443 | elem.fireEvent("on"+type);
444 | }
445 | },
446 |
447 | // Safe object type checking
448 | is: function( type, obj ) {
449 | return QUnit.objectType( obj ) == type;
450 | },
451 |
452 | objectType: function( obj ) {
453 | if (typeof obj === "undefined") {
454 | return "undefined";
455 |
456 | // consider: typeof null === object
457 | }
458 | if (obj === null) {
459 | return "null";
460 | }
461 |
462 | var type = Object.prototype.toString.call( obj )
463 | .match(/^\[object\s(.*)\]$/)[1] || '';
464 |
465 | switch (type) {
466 | case 'Number':
467 | if (isNaN(obj)) {
468 | return "nan";
469 | } else {
470 | return "number";
471 | }
472 | case 'String':
473 | case 'Boolean':
474 | case 'Array':
475 | case 'Date':
476 | case 'RegExp':
477 | case 'Function':
478 | return type.toLowerCase();
479 | }
480 | if (typeof obj === "object") {
481 | return "object";
482 | }
483 | return undefined;
484 | },
485 |
486 | // Logging callbacks
487 | begin: function() {},
488 | done: function(failures, total) {},
489 | log: function(result, message) {},
490 | testStart: function(name, testEnvironment) {},
491 | testDone: function(name, failures, total) {},
492 | moduleStart: function(name, testEnvironment) {},
493 | moduleDone: function(name, failures, total) {}
494 | });
495 |
496 | if ( typeof document === "undefined" || document.readyState === "complete" ) {
497 | config.autorun = true;
498 | }
499 |
500 | addEvent(window, "load", function() {
501 | QUnit.begin();
502 |
503 | // Initialize the config, saving the execution queue
504 | var oldconfig = extend({}, config);
505 | QUnit.init();
506 | extend(config, oldconfig);
507 |
508 | config.blocking = false;
509 |
510 | var userAgent = id("qunit-userAgent");
511 | if ( userAgent ) {
512 | userAgent.innerHTML = navigator.userAgent;
513 | }
514 |
515 | var toolbar = id("qunit-testrunner-toolbar");
516 | if ( toolbar ) {
517 | toolbar.style.display = "none";
518 |
519 | var filter = document.createElement("input");
520 | filter.type = "checkbox";
521 | filter.id = "qunit-filter-pass";
522 | filter.disabled = true;
523 | addEvent( filter, "click", function() {
524 | var li = document.getElementsByTagName("li");
525 | for ( var i = 0; i < li.length; i++ ) {
526 | if ( li[i].className.indexOf("pass") > -1 ) {
527 | li[i].style.display = filter.checked ? "none" : "";
528 | }
529 | }
530 | });
531 | toolbar.appendChild( filter );
532 |
533 | var label = document.createElement("label");
534 | label.setAttribute("for", "qunit-filter-pass");
535 | label.innerHTML = "Hide passed tests";
536 | toolbar.appendChild( label );
537 |
538 | var missing = document.createElement("input");
539 | missing.type = "checkbox";
540 | missing.id = "qunit-filter-missing";
541 | missing.disabled = true;
542 | addEvent( missing, "click", function() {
543 | var li = document.getElementsByTagName("li");
544 | for ( var i = 0; i < li.length; i++ ) {
545 | if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
546 | li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
547 | }
548 | }
549 | });
550 | toolbar.appendChild( missing );
551 |
552 | label = document.createElement("label");
553 | label.setAttribute("for", "qunit-filter-missing");
554 | label.innerHTML = "Hide missing tests (untested code is broken code)";
555 | toolbar.appendChild( label );
556 | }
557 |
558 | var main = id('main') || id('qunit-fixture');
559 | if ( main ) {
560 | config.fixture = main.innerHTML;
561 | }
562 |
563 | if (config.autostart) {
564 | QUnit.start(true);
565 | }
566 | });
567 |
568 | function done() {
569 | if ( config.doneTimer && window.clearTimeout ) {
570 | window.clearTimeout( config.doneTimer );
571 | config.doneTimer = null;
572 | }
573 |
574 | if ( config.queue.length ) {
575 | config.doneTimer = window.setTimeout(function(){
576 | if ( !config.queue.length ) {
577 | done();
578 | } else {
579 | synchronize( done );
580 | }
581 | }, 13);
582 |
583 | return;
584 | }
585 |
586 | config.autorun = true;
587 |
588 | // Log the last module results
589 | if ( config.currentModule ) {
590 | QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
591 | }
592 |
593 | var banner = id("qunit-banner"),
594 | tests = id("qunit-tests"),
595 | html = ['Tests completed in ',
596 | +new Date - config.started, ' milliseconds.
',
597 | '', config.stats.all - config.stats.bad, ' tests of ', config.stats.all, ' passed, ', config.stats.bad,' failed.'].join('');
598 |
599 | if ( banner ) {
600 | banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
601 | }
602 |
603 | if ( tests ) {
604 | var result = id("qunit-testresult");
605 |
606 | if ( !result ) {
607 | result = document.createElement("p");
608 | result.id = "qunit-testresult";
609 | result.className = "result";
610 | tests.parentNode.insertBefore( result, tests.nextSibling );
611 | }
612 |
613 | result.innerHTML = html;
614 | }
615 |
616 | QUnit.done( config.stats.bad, config.stats.all );
617 | }
618 |
619 | function validTest( name ) {
620 | var i = config.filters.length,
621 | run = false;
622 |
623 | if ( !i ) {
624 | return true;
625 | }
626 |
627 | while ( i-- ) {
628 | var filter = config.filters[i],
629 | not = filter.charAt(0) == '!';
630 |
631 | if ( not ) {
632 | filter = filter.slice(1);
633 | }
634 |
635 | if ( name.indexOf(filter) !== -1 ) {
636 | return !not;
637 | }
638 |
639 | if ( not ) {
640 | run = true;
641 | }
642 | }
643 |
644 | return run;
645 | }
646 |
647 | function escapeHtml(s) {
648 | s = s === null ? "" : s + "";
649 | return s.replace(/[\&"<>\\]/g, function(s) {
650 | switch(s) {
651 | case "&": return "&";
652 | case "\\": return "\\\\";
653 | case '"': return '\"';
654 | case "<": return "<";
655 | case ">": return ">";
656 | default: return s;
657 | }
658 | });
659 | }
660 |
661 | function push(result, actual, expected, message) {
662 | message = escapeHtml(message) || (result ? "okay" : "failed");
663 | message = '' + message + "";
664 | expected = escapeHtml(QUnit.jsDump.parse(expected));
665 | actual = escapeHtml(QUnit.jsDump.parse(actual));
666 | var output = message + ', expected: ' + expected + '';
667 | if (actual != expected) {
668 | output += ' result: ' + actual + ', diff: ' + QUnit.diff(expected, actual);
669 | }
670 |
671 | // can't use ok, as that would double-escape messages
672 | if(!result){QUnit.log(result, output);}
673 | config.assertions.push({
674 | result: !!result,
675 | message: output
676 | });
677 | }
678 |
679 | function synchronize( callback ) {
680 | config.queue.push( callback );
681 |
682 | if ( config.autorun && !config.blocking ) {
683 | process();
684 | }
685 | }
686 |
687 | function process() {
688 | var start = (new Date()).getTime();
689 |
690 | while ( config.queue.length && !config.blocking ) {
691 | if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
692 | config.queue.shift()();
693 |
694 | } else {
695 | setTimeout( process, 13 );
696 | break;
697 | }
698 | }
699 | }
700 |
701 | function saveGlobal() {
702 | config.pollution = [];
703 |
704 | if ( config.noglobals ) {
705 | for ( var key in window ) {
706 | config.pollution.push( key );
707 | }
708 | }
709 | }
710 |
711 | function checkPollution( name ) {
712 | var old = config.pollution;
713 | saveGlobal();
714 |
715 | var newGlobals = diff( old, config.pollution );
716 | if ( newGlobals.length > 0 ) {
717 | ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
718 | config.expected++;
719 | }
720 |
721 | var deletedGlobals = diff( config.pollution, old );
722 | if ( deletedGlobals.length > 0 ) {
723 | ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
724 | config.expected++;
725 | }
726 | }
727 |
728 | // returns a new Array with the elements that are in a but not in b
729 | function diff( a, b ) {
730 | var result = a.slice();
731 | for ( var i = 0; i < result.length; i++ ) {
732 | for ( var j = 0; j < b.length; j++ ) {
733 | if ( result[i] === b[j] ) {
734 | result.splice(i, 1);
735 | i--;
736 | break;
737 | }
738 | }
739 | }
740 | return result;
741 | }
742 |
743 | function fail(message, exception, callback) {
744 | if ( typeof console !== "undefined" && console.error && console.warn ) {
745 | console.error(message);
746 | console.error(exception);
747 | console.warn(callback.toString());
748 |
749 | } else if ( window.opera && opera.postError ) {
750 | opera.postError(message, exception, callback.toString);
751 | }
752 | }
753 |
754 | function extend(a, b) {
755 | for ( var prop in b ) {
756 | a[prop] = b[prop];
757 | }
758 |
759 | return a;
760 | }
761 |
762 | function addEvent(elem, type, fn) {
763 | if ( elem.addEventListener ) {
764 | elem.addEventListener( type, fn, false );
765 | } else if ( elem.attachEvent ) {
766 | elem.attachEvent( "on" + type, fn );
767 | } else {
768 | fn();
769 | }
770 | }
771 |
772 | function id(name) {
773 | return !!(typeof document !== "undefined" && document && document.getElementById) &&
774 | document.getElementById( name );
775 | }
776 |
777 | // Test for equality any JavaScript type.
778 | // Discussions and reference: http://philrathe.com/articles/equiv
779 | // Test suites: http://philrathe.com/tests/equiv
780 | // Author: Philippe Rathé
781 | QUnit.equiv = function () {
782 |
783 | var innerEquiv; // the real equiv function
784 | var callers = []; // stack to decide between skip/abort functions
785 | var parents = []; // stack to avoiding loops from circular referencing
786 |
787 | // Call the o related callback with the given arguments.
788 | function bindCallbacks(o, callbacks, args) {
789 | var prop = QUnit.objectType(o);
790 | if (prop) {
791 | if (QUnit.objectType(callbacks[prop]) === "function") {
792 | return callbacks[prop].apply(callbacks, args);
793 | } else {
794 | return callbacks[prop]; // or undefined
795 | }
796 | }
797 | }
798 |
799 | var callbacks = function () {
800 |
801 | // for string, boolean, number and null
802 | function useStrictEquality(b, a) {
803 | if (b instanceof a.constructor || a instanceof b.constructor) {
804 | // to catch short annotaion VS 'new' annotation of a declaration
805 | // e.g. var i = 1;
806 | // var j = new Number(1);
807 | return a == b;
808 | } else {
809 | return a === b;
810 | }
811 | }
812 |
813 | return {
814 | "string": useStrictEquality,
815 | "boolean": useStrictEquality,
816 | "number": useStrictEquality,
817 | "null": useStrictEquality,
818 | "undefined": useStrictEquality,
819 |
820 | "nan": function (b) {
821 | return isNaN(b);
822 | },
823 |
824 | "date": function (b, a) {
825 | return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();
826 | },
827 |
828 | "regexp": function (b, a) {
829 | return QUnit.objectType(b) === "regexp" &&
830 | a.source === b.source && // the regex itself
831 | a.global === b.global && // and its modifers (gmi) ...
832 | a.ignoreCase === b.ignoreCase &&
833 | a.multiline === b.multiline;
834 | },
835 |
836 | // - skip when the property is a method of an instance (OOP)
837 | // - abort otherwise,
838 | // initial === would have catch identical references anyway
839 | "function": function () {
840 | var caller = callers[callers.length - 1];
841 | return caller !== Object &&
842 | typeof caller !== "undefined";
843 | },
844 |
845 | "array": function (b, a) {
846 | var i, j, loop;
847 | var len;
848 |
849 | // b could be an object literal here
850 | if ( ! (QUnit.objectType(b) === "array")) {
851 | return false;
852 | }
853 |
854 | len = a.length;
855 | if (len !== b.length) { // safe and faster
856 | return false;
857 | }
858 |
859 | //track reference to avoid circular references
860 | parents.push(a);
861 | for (i = 0; i < len; i++) {
862 | loop = false;
863 | for(j=0;j= 0) {
1008 | type = "array";
1009 | } else {
1010 | type = typeof obj;
1011 | }
1012 | return type;
1013 | },
1014 | separator:function() {
1015 | return this.multiline ? this.HTML ? '
' : '\n' : this.HTML ? ' ' : ' ';
1016 | },
1017 | indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
1018 | if ( !this.multiline )
1019 | return '';
1020 | var chr = this.indentChar;
1021 | if ( this.HTML )
1022 | chr = chr.replace(/\t/g,' ').replace(/ /g,' ');
1023 | return Array( this._depth_ + (extra||0) ).join(chr);
1024 | },
1025 | up:function( a ) {
1026 | this._depth_ += a || 1;
1027 | },
1028 | down:function( a ) {
1029 | this._depth_ -= a || 1;
1030 | },
1031 | setParser:function( name, parser ) {
1032 | this.parsers[name] = parser;
1033 | },
1034 | // The next 3 are exposed so you can use them
1035 | quote:quote,
1036 | literal:literal,
1037 | join:join,
1038 | //
1039 | _depth_: 1,
1040 | // This is the list of parsers, to modify them, use jsDump.setParser
1041 | parsers:{
1042 | window: '[Window]',
1043 | document: '[Document]',
1044 | error:'[ERROR]', //when no parser is found, shouldn't happen
1045 | unknown: '[Unknown]',
1046 | 'null':'null',
1047 | undefined:'undefined',
1048 | 'function':function( fn ) {
1049 | var ret = 'function',
1050 | name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
1051 | if ( name )
1052 | ret += ' ' + name;
1053 | ret += '(';
1054 |
1055 | ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
1056 | return join( ret, this.parse(fn,'functionCode'), '}' );
1057 | },
1058 | array: array,
1059 | nodelist: array,
1060 | arguments: array,
1061 | object:function( map ) {
1062 | var ret = [ ];
1063 | this.up();
1064 | for ( var key in map )
1065 | ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
1066 | this.down();
1067 | return join( '{', ret, '}' );
1068 | },
1069 | node:function( node ) {
1070 | var open = this.HTML ? '<' : '<',
1071 | close = this.HTML ? '>' : '>';
1072 |
1073 | var tag = node.nodeName.toLowerCase(),
1074 | ret = open + tag;
1075 |
1076 | for ( var a in this.DOMAttrs ) {
1077 | var val = node[this.DOMAttrs[a]];
1078 | if ( val )
1079 | ret += ' ' + a + '=' + this.parse( val, 'attribute' );
1080 | }
1081 | return ret + close + open + '/' + tag + close;
1082 | },
1083 | functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
1084 | var l = fn.length;
1085 | if ( !l ) return '';
1086 |
1087 | var args = Array(l);
1088 | while ( l-- )
1089 | args[l] = String.fromCharCode(97+l);//97 is 'a'
1090 | return ' ' + args.join(', ') + ' ';
1091 | },
1092 | key:quote, //object calls it internally, the key part of an item in a map
1093 | functionCode:'[code]', //function calls it internally, it's the content of the function
1094 | attribute:quote, //node calls it internally, it's an html attribute value
1095 | string:quote,
1096 | date:quote,
1097 | regexp:literal, //regex
1098 | number:literal,
1099 | 'boolean':literal
1100 | },
1101 | DOMAttrs:{//attributes to dump from nodes, name=>realName
1102 | id:'id',
1103 | name:'name',
1104 | 'class':'className'
1105 | },
1106 | HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
1107 | indentChar:' ',//indentation unit
1108 | multiline:false //if true, items in a collection, are separated by a \n, else just a space.
1109 | };
1110 |
1111 | return jsDump;
1112 | })();
1113 |
1114 | // from Sizzle.js
1115 | function getText( elems ) {
1116 | var ret = "", elem;
1117 |
1118 | for ( var i = 0; elems[i]; i++ ) {
1119 | elem = elems[i];
1120 |
1121 | // Get the text from text nodes and CDATA nodes
1122 | if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
1123 | ret += elem.nodeValue;
1124 |
1125 | // Traverse everything else, except comment nodes
1126 | } else if ( elem.nodeType !== 8 ) {
1127 | ret += getText( elem.childNodes );
1128 | }
1129 | }
1130 |
1131 | return ret;
1132 | };
1133 |
1134 | /*
1135 | * Javascript Diff Algorithm
1136 | * By John Resig (http://ejohn.org/)
1137 | * Modified by Chu Alan "sprite"
1138 | *
1139 | * Released under the MIT license.
1140 | *
1141 | * More Info:
1142 | * http://ejohn.org/projects/javascript-diff-algorithm/
1143 | *
1144 | * Usage: QUnit.diff(expected, actual)
1145 | *
1146 | * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over"
1147 | */
1148 | QUnit.diff = (function() {
1149 | function diff(o, n){
1150 | var ns = new Object();
1151 | var os = new Object();
1152 |
1153 | for (var i = 0; i < n.length; i++) {
1154 | if (ns[n[i]] == null)
1155 | ns[n[i]] = {
1156 | rows: new Array(),
1157 | o: null
1158 | };
1159 | ns[n[i]].rows.push(i);
1160 | }
1161 |
1162 | for (var i = 0; i < o.length; i++) {
1163 | if (os[o[i]] == null)
1164 | os[o[i]] = {
1165 | rows: new Array(),
1166 | n: null
1167 | };
1168 | os[o[i]].rows.push(i);
1169 | }
1170 |
1171 | for (var i in ns) {
1172 | if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
1173 | n[ns[i].rows[0]] = {
1174 | text: n[ns[i].rows[0]],
1175 | row: os[i].rows[0]
1176 | };
1177 | o[os[i].rows[0]] = {
1178 | text: o[os[i].rows[0]],
1179 | row: ns[i].rows[0]
1180 | };
1181 | }
1182 | }
1183 |
1184 | for (var i = 0; i < n.length - 1; i++) {
1185 | if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&
1186 | n[i + 1] == o[n[i].row + 1]) {
1187 | n[i + 1] = {
1188 | text: n[i + 1],
1189 | row: n[i].row + 1
1190 | };
1191 | o[n[i].row + 1] = {
1192 | text: o[n[i].row + 1],
1193 | row: i + 1
1194 | };
1195 | }
1196 | }
1197 |
1198 | for (var i = n.length - 1; i > 0; i--) {
1199 | if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
1200 | n[i - 1] == o[n[i].row - 1]) {
1201 | n[i - 1] = {
1202 | text: n[i - 1],
1203 | row: n[i].row - 1
1204 | };
1205 | o[n[i].row - 1] = {
1206 | text: o[n[i].row - 1],
1207 | row: i - 1
1208 | };
1209 | }
1210 | }
1211 |
1212 | return {
1213 | o: o,
1214 | n: n
1215 | };
1216 | }
1217 |
1218 | return function(o, n){
1219 | o = o.replace(/\s+$/, '');
1220 | n = n.replace(/\s+$/, '');
1221 | var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));
1222 |
1223 | var str = "";
1224 |
1225 | var oSpace = o.match(/\s+/g);
1226 | if (oSpace == null) {
1227 | oSpace = [" "];
1228 | }
1229 | else {
1230 | oSpace.push(" ");
1231 | }
1232 | var nSpace = n.match(/\s+/g);
1233 | if (nSpace == null) {
1234 | nSpace = [" "];
1235 | }
1236 | else {
1237 | nSpace.push(" ");
1238 | }
1239 |
1240 | if (out.n.length == 0) {
1241 | for (var i = 0; i < out.o.length; i++) {
1242 | str += '' + out.o[i] + oSpace[i] + "";
1243 | }
1244 | }
1245 | else {
1246 | if (out.n[0].text == null) {
1247 | for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
1248 | str += '' + out.o[n] + oSpace[n] + "";
1249 | }
1250 | }
1251 |
1252 | for (var i = 0; i < out.n.length; i++) {
1253 | if (out.n[i].text == null) {
1254 | str += '' + out.n[i] + nSpace[i] + "";
1255 | }
1256 | else {
1257 | var pre = "";
1258 |
1259 | for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
1260 | pre += '' + out.o[n] + oSpace[n] + "";
1261 | }
1262 | str += " " + out.n[i].text + nSpace[i] + pre;
1263 | }
1264 | }
1265 | }
1266 |
1267 | return str;
1268 | }
1269 | })();
1270 |
1271 | })(this);
1272 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/qunit/titanium_adaptor.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wGEric/TiQuery/381b6a3a7b550e2f78510e38849ef5f1ebfaf572/test/Resources/qunit-titanium/qunit/titanium_adaptor.js
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/qunit/titanium_adaptor_quiet.js:
--------------------------------------------------------------------------------
1 | Titanium.include('qunit.js');
2 |
3 | // =============================================================================
4 | // Uncomment the following lines in order to get jsMockito support for mocking
5 | // (after following jsMockito install instructions)
6 | // =============================================================================
7 |
8 | // Titanium.include('qunit/jshamcrest.js');
9 | // Titanium.include('qunit/jsmockito-1.0.2.js');
10 | // JsHamcrest.Integration.QUnit();
11 | // JsMockito.Integration.importTo(this);
12 |
13 | var logger = function(failures, message) {
14 | if (failures) {
15 | Titanium.API.error(message);
16 | } else {
17 | Titanium.API.info(message);
18 | }
19 | };
20 |
21 | var logSummary = function(name, failures, total){
22 | return "*********** " + name + ": (" + (total-failures) + '/' + total + ')'
23 | }
24 | // QUnit.testStart(name) is called whenever a new test batch of assertions starts running. name is the string name of the test batch.
25 | QUnit.testStart = function(name) {
26 | //logger(false, '.');
27 | };
28 | // QUnit.testDone(name, failures, total) is called whenever a batch of assertions finishes running. name is the string name of the test batch. failures is the number of test failures that occurred. total is the total number of test assertions that occurred.
29 | QUnit.testDone = function(name, failures, total) {
30 | if(failures){
31 | logger(failures, logSummary(name, failures, total));
32 | }
33 | };
34 | // QUnit.moduleStart(name) is called whenever a new module of tests starts running. name is the string name of the module.
35 | QUnit.moduleStart = function(name) {
36 | //logger(false, '>>>> MODULE START: '+name);
37 | };
38 | // QUnit.moduleDone(name, failures, total) is called whenever a module finishes running. name is the string name of the module. failures is the number of module failures that occurred. total is the total number of module assertions that occurred.
39 | QUnit.moduleDone = function(name, failures, total) {
40 | if(failures){
41 | logger(failures, logSummary('MODULE ' + name, failures, total));
42 | }
43 | };
44 | // QUnit.begin() is called once before running any tests. It should have been called QUnit.start, but thats already in use elsewhere and can't be changed.
45 | QUnit.begin = function() {
46 | //logger(false, 'BEGIN');
47 | };
48 | // QUnit.done(failures, total) is called whenever all the tests have finished running. failures is the number of failures that occurred. total is the total number of assertions that occurred.
49 | QUnit.done = function(failures, total) {
50 | var msg = logSummary("TEST SUMMARY: ", failures, total)
51 | logger(failures, msg);
52 | };
53 |
54 | // QUnit.log(result, message) is called whenever an assertion is completed. result is a boolean (true for passing, false for failing) and message is a string description provided by the assertion.
55 |
56 | QUnit.log = function(result, message) {
57 | if (!result) {
58 | logger(true, message);
59 | } else {
60 | Titanium.API.info(message);
61 | }
62 | };
63 |
64 | // Tests to run
65 | Titanium.include('../test/tests_to_run.js');
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/runner.js:
--------------------------------------------------------------------------------
1 | // This file needs to sit in the Resources directory so that when
2 | // it is used as a URL to a window, the include structure doesn't change.
3 | Titanium.include('vendor/qunit-titanium/qunit/titanium_adaptor_quiet.js');
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/test/events.js:
--------------------------------------------------------------------------------
1 | module("Events");
2 |
3 | test("Event Shortcuts Exists", function() {
4 | expect(32);
5 |
6 | var events = ['blur', 'cancel', 'click', 'dblclick', 'doubletap', 'focus', 'orientationchange', 'scroll', 'shake', 'singletap', 'swipe', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'twofingertap'];
7 |
8 | for(var i = 0, total = events.length; i < total; i++) {
9 | ok($.fn[events[i]] != undefined, events[i] + " defined");
10 | ok($.isFunction($.fn[events[i]]), events[i] + " function");
11 | }
12 | });
13 |
14 | test("Custom Events", function() {
15 | expect(2);
16 |
17 | $.registerEvent('customEvent');
18 |
19 | ok($.fn.customEvent != undefined, "customEvent defined");
20 | ok($.isFunction($.fn.customEvent), "customEvent function");
21 | });
22 |
23 | // only testing click since if it works the other ones will since they are all setup the same
24 | test("Click", function() {
25 | expect(1);
26 |
27 | stop();
28 |
29 | var clickEvent = function() {
30 | ok(true);
31 | start();
32 |
33 | $(label).unbind('click', clickEvent);
34 | };
35 |
36 | $(label).click(clickEvent);
37 |
38 | $(label).click();
39 | });
40 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/test/http.js:
--------------------------------------------------------------------------------
1 | module("HTTP");
2 |
3 | test("HTTP Exists", function() {
4 | expect(14);
5 |
6 | var shortcuts = ['http', 'get', 'getJSON', 'getXML', 'post', 'postJSON', 'postXML'];
7 |
8 | for(var i = 0, total = shortcuts.length; i < total; i++) {
9 | ok($[shortcuts[i]] != undefined, shortcuts[i] + " defined");
10 | ok($.isFunction($[shortcuts[i]]), shortcuts[i] + " function");
11 | }
12 | });
13 |
14 | test("URL Required", function() {
15 | ok($.http() === false);
16 | });
17 |
18 | test("Callbacks", function() {
19 | expect((Titanium.Platform.osname == 'android') ? 3 : 4);
20 |
21 | stop();
22 |
23 | var dataStream = false;
24 |
25 | $.http({
26 | url: 'http://www.google.com',
27 | data: 'test=test',
28 | onLoad: function() {
29 | ok(true, "onLoad");
30 | start();
31 | },
32 | onDataStream: function() {
33 | // this fires multiple times. We only want it once.
34 | if (dataStream == false) {
35 | ok(true, "onDataStream")
36 | dataStream = true;
37 | }
38 | },
39 | onReadyStateChange: function(event) {
40 | if (event.source.readyState == 1) {
41 | ok(true, "onReadyStateChange");
42 | }
43 | },
44 | onSendStream: function() {
45 | ok(true, "onSendStream");
46 | }
47 | });
48 | });
49 |
50 | test("Error Callback", function() {
51 | expect(1);
52 |
53 | stop();
54 |
55 | $.http({
56 | url: 'http://thisisabogusurladlfjfo.com',
57 | onError: function() {
58 | ok(true, "onError");
59 |
60 | start();
61 | }
62 | });
63 | });
64 |
65 | /*test("POST", function() {
66 | expect(1);
67 |
68 | stop();
69 |
70 | $.post("http://www.google.com", {foo: "bar"}, function(data) {
71 | $.info(data);
72 |
73 | ok(data, "post returns data");
74 |
75 | start();
76 | });
77 | });*/
78 |
79 | test("GET txt file", function() {
80 | expect(1);
81 |
82 | stop();
83 |
84 | $.get("http://www.tiquery.com/tests/tests.txt", function(data) {
85 | equals(data, "test text file");
86 | start();
87 | });
88 | });
89 |
90 | test("GET xml file", function() {
91 | expect(3);
92 |
93 | stop();
94 |
95 | $.getXML("http://www.tiquery.com/tests/tests.xml", function(data) {
96 | var items = data.getElementsByTagName("item");
97 |
98 | equals(items.length, 2, "number of - s");
99 | equals(items.item(0).text, "one", "first
- text");
100 | equals(items.item(1).text, "two", "second
- text");
101 |
102 | start();
103 | });
104 | });
105 |
106 | test("GET json file", function() {
107 | expect(3);
108 |
109 | stop();
110 |
111 | $.getJSON("http://www.tiquery.com/tests/tests.json", function(data) {
112 | equals(data.length, 2, "number of items in array");
113 | equals(data[0].foo, "bar", "value of foo");
114 | equals(data[1].green, "yellow", "value of green");
115 |
116 | start();
117 | });
118 | });
119 |
--------------------------------------------------------------------------------
/test/Resources/qunit-titanium/test/shortcuts.js:
--------------------------------------------------------------------------------
1 | module("Titanium Shortcuts");
2 |
3 | if (Titanium.Platform.osname == 'android') {
4 | test("Android Functions", function() {
5 | expect(5);
6 |
7 | //equal($.BroadcastIntent().toString(), Titanium.Android.createBroadcastIntent().toString(), 'BroadcastIntent'); possible bug in Titanium
8 | equal($.Intent().toString(), Titanium.Android.createIntent().toString(), 'Intent');
9 | // equal($.IntentChooser().toString(), Titanium.Android.createIntentChooser().toString(), 'IntentChooser'); possible bug in Titanium
10 | equal($.Notification().toString(), Titanium.Android.createNotification().toString(), 'Notification');
11 | equal($.PendingIntent({intent: $.Intent()}).toString(), Titanium.Android.createPendingIntent({intent: $.Intent()}).toString(), 'PendingIntent');
12 | equal($.Service($.Intent()).toString(), Titanium.Android.createService($.Intent()).toString(), 'Service');
13 | equal($.ServiceIntent($.Intent()).toString(), Titanium.Android.createServiceIntent().toString($.Intent()), 'ServiceIntent');
14 | });
15 | }
16 |
17 | if (Titanium.Platform.osname != 'android') {
18 | test("Contact Functions", function() {
19 | expect(2);
20 |
21 | equal($.Group().toString(), Titanium.Contacts.createGroup().toString(), 'Group');
22 | equal($.Person().toString(), Titanium.Contacts.createPerson().toString(), 'Person');
23 | });
24 | }
25 |
26 | test("Facebook Functions", function() {
27 | expect(1);
28 |
29 | equal($.LoginButton().toString(), Titanium.Facebook.createLoginButton().toString(), 'LoginButton');
30 | });
31 |
32 | test("Filesystem Functions", function() {
33 | expect(2);
34 |
35 | if (Titanium.Platform.osname != 'android') {
36 | expect(3);
37 | equal($.File().toString(), Titanium.Filesystem.createFile().toString(), 'File');
38 | }
39 |
40 | equal($.TempDirectory().toString(), Titanium.Filesystem.createTempDirectory().toString(), 'TempDirectory');
41 | equal($.TempFile().toString(), Titanium.Filesystem.createTempFile().toString(), 'TempFile');
42 | });
43 |
44 | test("Map Functions", function() {
45 | expect(2);
46 |
47 | equal($.Annotation().toString(), Titanium.Map.createAnnotation().toString(), 'Annotation');
48 | equal($.MapView().toString(), Titanium.Map.createView().toString(), 'MapView');
49 | });
50 |
51 | if (Titanium.Platform.osname != 'android') {
52 | test("Media Functions", function() {
53 | expect(4);
54 |
55 | equal($.AudioPlayer().toString(), Titanium.Media.createAudioPlayer().toString(), 'AudioPlayer');
56 | equal($.AudioRecorder().toString(), Titanium.Media.createAudioRecorder().toString(), 'AudioRecorder');
57 |
58 | // commented out because of Titanium (doc?) bugs
59 | //equal($.Item().toString(), Titanium.Media.createItem().toString(), 'Item');
60 | //equal($.MusicPlayer().toString(), Titanium.Media.createMusicPlayer().toString(), 'MusicPlayer');
61 | equal($.Sound().toString(), Titanium.Media.createSound().toString(), 'Sound');
62 | equal($.VideoPlayer().toString(), Titanium.Media.createVideoPlayer().toString(), 'VideoPlayer');
63 | });
64 | }
65 |
66 | test("Network Functions", function() {
67 | expect(1);
68 |
69 | if (Titanium.Platform.osname != 'android') {
70 | expect(4);
71 | equal($.BonjourBrowser().toString(), Titanium.Network.createBonjourBrowser().toString(), 'BonjourBrowser');
72 | equal($.BonjourService().toString(), Titanium.Network.createBonjourService().toString(), 'BonjourService');
73 | equal($.TCPSocket().toString(), Titanium.Network.createTCPSocket().toString(), 'TCPSocket');
74 | }
75 |
76 | equal($.HTTPClient().toString(), Titanium.Network.createHTTPClient().toString(), 'HTTPClient');
77 | });
78 |
79 | test("Platform Functions", function() {
80 | expect(1);
81 | ok($.UUID().toString().match(/[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}/i), 'UUID isn\'t valid');
82 | });
83 |
84 | test("Stream Functions", function() {
85 | expect(0);
86 |
87 | //equal(Titanium.Stream.createStream().toString(), $.Stream().toString());
88 | });
89 |
90 | test("UI Functions", function() {
91 | expect(31);
92 |
93 | equal($['2DMatrix']().toString(), Titanium.UI.create2DMatrix().toString(), '2DMatrix');
94 | equal($['3DMatrix']().toString(), Titanium.UI.create3DMatrix().toString(), '3DMatrix');
95 | equal($.ActivityIndicator().toString(), Titanium.UI.createActivityIndicator().toString(), 'ActivityIndicator');
96 | equal($.AlertDialog().toString(), Titanium.UI.createAlertDialog().toString(), 'AlertDialog');
97 | equal($.Animation().toString(), Titanium.UI.createAnimation().toString(), 'Animation');
98 | equal($.Button().toString(), Titanium.UI.createButton().toString(), 'Button');
99 | equal($.ButtonBar().toString(), Titanium.UI.createButtonBar().toString(), 'ButtonBar');
100 | equal($.EmailDialog().toString(), Titanium.UI.createEmailDialog().toString(), 'EmailDialog');
101 | equal($.ImageView().toString(), Titanium.UI.createImageView().toString(), 'ImageView');
102 | equal($.Label().toString(), Titanium.UI.createLabel().toString(), 'Label');
103 | equal($.OptionDialog().toString(), Titanium.UI.createOptionDialog().toString(), 'OptionDialog');
104 | equal($.Picker().toString(), Titanium.UI.createPicker().toString(), 'Picker');
105 | equal($.PickerColumn().toString(), Titanium.UI.createPickerColumn().toString(), 'PickerColumn');
106 | equal($.PickerRow().toString(), Titanium.UI.createPickerRow().toString(), 'PickerRow');
107 | equal($.ProgressBar().toString(), Titanium.UI.createProgressBar().toString(), 'ProgressBar');
108 | equal($.ScrollView().toString(), Titanium.UI.createScrollView().toString(), 'ScrollView');
109 | equal($.ScrollableView().toString(), Titanium.UI.createScrollableView().toString(), 'ScrollableView');
110 | equal($.SearchBar().toString(), Titanium.UI.createSearchBar().toString(), 'SearchBar');
111 | equal($.Slider().toString(), Titanium.UI.createSlider().toString(), 'Slider');
112 | equal($.Switch().toString(), Titanium.UI.createSwitch().toString(), 'Switch');
113 | equal($.Tab().toString(), Titanium.UI.createTab().toString(), 'Tab');
114 | equal($.TabGroup().toString(), Titanium.UI.createTabGroup().toString(), 'TabGroup');
115 | equal($.TableView().toString(), Titanium.UI.createTableView().toString(), 'TableView');
116 | equal($.TableViewRow().toString(), Titanium.UI.createTableViewRow().toString(), 'TableViewRow');
117 | equal($.TableViewSection().toString(), Titanium.UI.createTableViewSection().toString(), 'TableViewSection');
118 | equal($.TextArea().toString(), Titanium.UI.createTextArea().toString(), 'TextArea');
119 | equal($.TextField().toString(), Titanium.UI.createTextField().toString(), 'TextField');
120 | equal($.Toolbar().toString(), Titanium.UI.createToolbar().toString(), 'Toolbar');
121 | equal($.View().toString(), Titanium.UI.createView().toString(), 'View');
122 | equal($.WebView().toString(), Titanium.UI.createWebView().toString(), 'WebView');
123 | equal($.Window().toString(), Titanium.UI.createWindow().toString(), 'Window');
124 |
125 | if (Titanium.Platform.osname != 'android') {
126 | expect(35);
127 | equal($.CoverFlowView().toString(), Titanium.UI.createCoverFlowView().toString(), 'CoverFowView');
128 | equal($.DashboardItem().toString(), Titanium.UI.createDashboardItem().toString(), 'DashboardItem');
129 | equal($.DashboardView().toString(), Titanium.UI.createDashboardView().toString(), 'DashboardView');
130 | equal($.TabbedBar().toString(), Titanium.UI.createTabbedBar().toString(), 'TabbedBar');
131 | }
132 | });
133 |
--------------------------------------------------------------------------------
/test/Resources/tests.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Unit Tests
3 | */
4 | Titanium.include('tiquery.js');
5 | Titanium.include('qunit-titanium/qunit/qunit.js');
6 |
7 | // =============================================================================
8 | // Uncomment the following lines in order to get jsMockito support for mocking
9 | // (after following jsMockito install instructions)
10 | // =============================================================================
11 |
12 | // Titanium.include('qunit/jshamcrest.js');
13 | // Titanium.include('qunit/jsmockito-1.0.2.js');
14 | // JsHamcrest.Integration.QUnit();
15 | // JsMockito.Integration.importTo(this);
16 |
17 | var html = '';
18 |
19 | var win = Titanium.UI.currentWindow;
20 |
21 | var scrollView = Titanium.UI.createScrollView({
22 | width: '100%',
23 | height: '100%',
24 | contentWidth:'auto',
25 | contentHeight:'auto'
26 | })
27 |
28 | win.add(scrollView);
29 |
30 | var label = Titanium.UI.createLabel({
31 | color:'#999',
32 | text: "Running tests...",
33 | font: {
34 | fontSize:16,
35 | fontFamily:'Helvetica Neue'
36 | },
37 | textAlign:'left',
38 | width:'100%',
39 | height: 'auto'
40 | });
41 |
42 | scrollView.add(label);
43 | win.open();
44 |
45 | var logger = function(failures, message) {
46 | if (failures) {
47 | Titanium.API.error(message);
48 | } else {
49 | Titanium.API.info(message);
50 | }
51 |
52 | html += message + "\n";
53 | };
54 | // QUnit.testStart(name) is called whenever a new test batch of assertions starts running. name is the string name of the test batch.
55 | QUnit.testStart = function(name) {
56 | logger(false, '> TEST START: '+name);
57 | };
58 | // QUnit.testDone(name, failures, total) is called whenever a batch of assertions finishes running. name is the string name of the test batch. failures is the number of test failures that occurred. total is the total number of test assertions that occurred.
59 | QUnit.testDone = function(name, failures, total) {
60 | logger(failures, '< TEST DONE : '+name+"\n<< FAILURES: "+failures+"\n<< TOTAL: "+total);
61 | };
62 | // QUnit.moduleStart(name) is called whenever a new module of tests starts running. name is the string name of the module.
63 | QUnit.moduleStart = function(name) {
64 | logger(false, 'MODULE START: '+name);
65 | };
66 | // QUnit.moduleDone(name, failures, total) is called whenever a module finishes running. name is the string name of the module. failures is the number of module failures that occurred. total is the total number of module assertions that occurred.
67 | QUnit.moduleDone = function(name, failures, total) {
68 | logger(failures, 'MODULE DONE : '+name+"\n< FAILURES: "+failures+"\n< TOTAL: "+total+"\n");
69 | };
70 | // QUnit.begin() is called once before running any tests. It should have been called QUnit.start, but thats already in use elsewhere and can't be changed.
71 | QUnit.begin = function() {
72 | logger(false, 'BEGIN');
73 | };
74 | // QUnit.done(failures, total) is called whenever all the tests have finished running. failures is the number of failures that occurred. total is the total number of assertions that occurred.
75 | QUnit.done = function(failures, total) {
76 | logger(failures, "DONE\n< FAILURES: "+failures+"\n< TOTAL: "+total);
77 | label.text = html;
78 |
79 | alert("Failures: " + failures + "\nTotal: " + total);
80 | };
81 |
82 | // QUnit.log(result, message) is called whenever an assertion is completed. result is a boolean (true for passing, false for failing) and message is a string description provided by the assertion.
83 |
84 | QUnit.log = function(result, message) {
85 | if (!result) {
86 | logger(true, message);
87 | } else {
88 | Titanium.API.log(message);
89 | }
90 | };
91 |
92 | // Tests to run
93 | Titanium.include('qunit-titanium/test/shortcuts.js');
94 | Titanium.include('qunit-titanium/test/events.js');
95 | Titanium.include('qunit-titanium/test/http.js');
--------------------------------------------------------------------------------
/test/Resources/tiquery.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * TiQuery Javascript Library for Titanium v0.0.1
3 | *
4 | * Copyright 2010 Eric Faerber, Natural Code Project
5 | * Released under GPL Version 2
6 | *
7 | * Includes large portions of jQuery
8 | * http://jquery.com
9 | * Copyright 2010, John Resig
10 | * Dual licensed under the MIT or GPL Version 2 licenses.
11 | */
12 |
13 | (function(global, Titanium, undefined) {
14 | var TiQuery = (function() {
15 | var TiQuery = function(selector) {
16 | return new TiQuery.fn.init(selector);
17 | },
18 |
19 | _TiQuery = global.TiQuery,
20 | _$ = global.$,
21 |
22 | /**
23 | * Check if a string has a non-whitespace character in it
24 | */
25 | rnotwhite = /\S/,
26 |
27 | /**
28 | * Used for trimming whitespace
29 | */
30 | rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
31 |
32 |
33 | // Save a reference to some core methods
34 | toString = Object.prototype.toString,
35 | hasOwnProperty = Object.prototype.hasOwnProperty,
36 | push = Array.prototype.push,
37 | slice = Array.prototype.slice,
38 | indexOf = Array.prototype.indexOf;
39 |
40 | TiQuery.fn = TiQuery.prototype = {
41 | init: function( selector, context ) {
42 | // Handle $(""), $(null), or $(undefined)
43 | if ( !selector ) {
44 | return this;
45 | }
46 |
47 | this.context = this[0] = selector;
48 | this.length = 1;
49 | return this;
50 | },
51 |
52 | /**
53 | * The number of elements contained in the matched element set
54 | */
55 | size: function() {
56 | return this.length;
57 | },
58 |
59 | toArray: function() {
60 | return slice.call( this, 0 );
61 | },
62 |
63 | /**
64 | * Get the Nth element in the matched element set OR
65 | * Get the whole matched element set as a clean array
66 | */
67 | get: function( num ) {
68 | return num == null ?
69 |
70 | // Return a 'clean' array
71 | this.toArray() :
72 |
73 | // Return just the object
74 | ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
75 | },
76 |
77 | /**
78 | * Take an array of elements and push it onto the stack
79 | * (returning the new matched element set)
80 | */
81 | pushStack: function( elems, name, selector ) {
82 | // Build a new TiQuery matched element set
83 | var ret = TiQuery();
84 |
85 | if ( TiQueryuery.isArray( elems ) ) {
86 | push.apply( ret, elems );
87 |
88 | } else {
89 | TiQuery.merge( ret, elems );
90 | }
91 |
92 | // Add the old object onto the stack (as a reference)
93 | ret.prevObject = this;
94 |
95 | ret.context = this.context;
96 |
97 | if ( name === "find" ) {
98 | ret.selector = this.selector + (this.selector ? " " : "") + selector;
99 | } else if ( name ) {
100 | ret.selector = this.selector + "." + name + "(" + selector + ")";
101 | }
102 |
103 | // Return the newly-formed element set
104 | return ret;
105 | },
106 |
107 | /**
108 | * Execute a callback for every element in the matched set.
109 | * (You can seed the arguments with an array of args, but this is
110 | * only used internally.)
111 | */
112 | each: function( callback, args ) {
113 | return TiQuery.each( this, callback, args );
114 | },
115 |
116 | ready: function( fn ) {
117 |
118 |
119 | return this;
120 | },
121 |
122 | eq: function( i ) {
123 | return i === -1 ?
124 | this.slice( i ) :
125 | this.slice( i, +i + 1 );
126 | },
127 |
128 | first: function() {
129 | return this.eq( 0 );
130 | },
131 |
132 | last: function() {
133 | return this.eq( -1 );
134 | },
135 |
136 | slice: function() {
137 | return this.pushStack( slice.apply( this, arguments ),
138 | "slice", slice.call(arguments).join(",") );
139 | },
140 |
141 | map: function( callback ) {
142 | return this.pushStack( TiQuery.map(this, function( elem, i ) {
143 | return callback.call( elem, i, elem );
144 | }));
145 | },
146 |
147 | end: function() {
148 | return this.prevObject || TiQuery(null);
149 | },
150 |
151 | // For internal use only.
152 | // Behaves like an Array's method, not like a TiQuery method.
153 | push: push,
154 | sort: [].sort,
155 | splice: [].splice
156 | };
157 |
158 | // Give the init function the TiQuery prototype for later instantiation
159 | TiQuery.fn.init.prototype = TiQuery.fn;
160 |
161 | TiQuery.fn.extend = TiQuery.extend = function() {
162 | // copy reference to target object
163 | var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
164 |
165 | // Handle a deep copy situation
166 | if ( typeof target === "boolean" ) {
167 | deep = target;
168 | target = arguments[1] || {};
169 | // skip the boolean and the target
170 | i = 2;
171 | }
172 |
173 | // Handle case when target is a string or something (possible in deep copy)
174 | if ( typeof target !== "object" && !TiQuery.isFunction(target) ) {
175 | target = {};
176 | }
177 |
178 | // extend TiQuery itself if only one argument is passed
179 | if ( length === i ) {
180 | target = this;
181 | --i;
182 | }
183 |
184 | for ( ; i < length; i++ ) {
185 | // Only deal with non-null/undefined values
186 | if ( (options = arguments[ i ]) != null ) {
187 | // Extend the base object
188 | for ( name in options ) {
189 | src = target[ name ];
190 | copy = options[ name ];
191 |
192 | // Prevent never-ending loop
193 | if ( target === copy ) {
194 | continue;
195 | }
196 |
197 | // Recurse if we're merging object literal values or arrays
198 | if ( deep && copy && ( TiQuery.isPlainObject(copy) || TiQuery.isArray(copy) ) ) {
199 | var clone = src && ( TiQuery.isPlainObject(src) || TiQuery.isArray(src) ) ? src
200 | : TiQuery.isArray(copy) ? [] : {};
201 |
202 | // Never move original objects, clone them
203 | target[ name ] = TiQuery.extend( deep, clone, copy );
204 |
205 | // Don't bring in undefined values
206 | } else if ( copy !== undefined ) {
207 | target[ name ] = copy;
208 | }
209 | }
210 | }
211 | }
212 |
213 | // Return the modified object
214 | return target;
215 |
216 | };
217 |
218 | TiQuery.extend({
219 | noConflict: function( deep ) {
220 | global.$ = _$;
221 |
222 | if ( deep ) {
223 | global.TiQuery = _TiQuery;
224 | }
225 |
226 | return TiQuery;
227 | },
228 |
229 | /**
230 | * See test/unit/core.js for details concerning isFunction.
231 | * Since version 1.3, DOM methods and functions like alert
232 | * aren't supported. They return false on IE (#2968).
233 | */
234 | isFunction: function( obj ) {
235 | return toString.call(obj) === "[object Function]";
236 | },
237 |
238 | isArray: function( obj ) {
239 | return toString.call(obj) === "[object Array]";
240 | },
241 |
242 | isPlainObject: function( obj ) {
243 | // Must be an Object.
244 | // Because of IE, we also have to check the presence of the constructor property.
245 | // Make sure that DOM nodes and window objects don't pass through, as well
246 | if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
247 | return false;
248 | }
249 |
250 | // Not own constructor property must be Object
251 | if ( obj.constructor
252 | && !hasOwnProperty.call(obj, "constructor")
253 | && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
254 | return false;
255 | }
256 |
257 | // Own properties are enumerated firstly, so to speed up,
258 | // if last one is own, then all properties are own.
259 |
260 | var key;
261 | for ( key in obj ) {}
262 |
263 | return key === undefined || hasOwnProperty.call( obj, key );
264 | },
265 |
266 | isEmptyObject: function( obj ) {
267 | for ( var name in obj ) {
268 | return false;
269 | }
270 | return true;
271 | },
272 |
273 | error: function( msg ) {
274 | throw msg;
275 | },
276 |
277 | parseJSON: function( data ) {
278 | if ( typeof data !== "string" || !data ) {
279 | return null;
280 | }
281 |
282 | // Make sure leading/trailing whitespace is removed (IE can't handle it)
283 | data = TiQuery.trim( data );
284 |
285 | // Make sure the incoming data is actual JSON
286 | // Logic borrowed from http://json.org/json2.js
287 | if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
288 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
289 | .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
290 | return JSON.parse(data);
291 |
292 | } else {
293 | TiQuery.error( "Invalid JSON: " + data );
294 | return false;
295 | }
296 | },
297 |
298 | noop: function() {},
299 |
300 | // args is for internal usage only
301 | each: function( object, callback, args ) {
302 | var name, i = 0,
303 | length = object.length,
304 | isObj = length === undefined || TiQuery.isFunction(object);
305 |
306 | if ( args ) {
307 | if ( isObj ) {
308 | for ( name in object ) {
309 | if ( callback.apply( object[ name ], args ) === false ) {
310 | break;
311 | }
312 | }
313 | } else {
314 | for ( ; i < length; ) {
315 | if ( callback.apply( object[ i++ ], args ) === false ) {
316 | break;
317 | }
318 | }
319 | }
320 |
321 | // A special, fast, case for the most common use of each
322 | } else {
323 | if ( isObj ) {
324 | for ( name in object ) {
325 | if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
326 | break;
327 | }
328 | }
329 | } else {
330 | for ( var value = object[0];
331 | i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
332 | }
333 | }
334 |
335 | return object;
336 | },
337 |
338 | trim: function( text ) {
339 | return (text || "").replace( rtrim, "" );
340 | },
341 |
342 | // results is for internal usage only
343 | makeArray: function( array, results ) {
344 | var ret = results || [];
345 |
346 | if ( array != null ) {
347 | // The window, strings (and functions) also have 'length'
348 | // The extra typeof function check is to prevent crashes
349 | // in Safari 2 (See: #3039)
350 | if ( array.length == null || typeof array === "string" || TiQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
351 | push.call( ret, array );
352 | } else {
353 | TiQuery.merge( ret, array );
354 | }
355 | }
356 |
357 | return ret;
358 | },
359 |
360 | inArray: function( elem, array ) {
361 | if ( array.indexOf ) {
362 | return array.indexOf( elem );
363 | }
364 |
365 | for ( var i = 0, length = array.length; i < length; i++ ) {
366 | if ( array[ i ] === elem ) {
367 | return i;
368 | }
369 | }
370 |
371 | return -1;
372 | },
373 |
374 | merge: function( first, second ) {
375 | var i = first.length, j = 0;
376 |
377 | if ( typeof second.length === "number" ) {
378 | for ( var l = second.length; j < l; j++ ) {
379 | first[ i++ ] = second[ j ];
380 | }
381 |
382 | } else {
383 | while ( second[j] !== undefined ) {
384 | first[ i++ ] = second[ j++ ];
385 | }
386 | }
387 |
388 | first.length = i;
389 |
390 | return first;
391 | },
392 |
393 | grep: function( elems, callback, inv ) {
394 | var ret = [];
395 |
396 | // Go through the array, only saving the items
397 | // that pass the validator function
398 | for ( var i = 0, length = elems.length; i < length; i++ ) {
399 | if ( !inv !== !callback( elems[ i ], i ) ) {
400 | ret.push( elems[ i ] );
401 | }
402 | }
403 |
404 | return ret;
405 | },
406 |
407 | /**
408 | * arg is for internal usage only
409 | */
410 | map: function( elems, callback, arg ) {
411 | var ret = [], value;
412 |
413 | // Go through the array, translating each of the items to their
414 | // new value (or values).
415 | for ( var i = 0, length = elems.length; i < length; i++ ) {
416 | value = callback( elems[ i ], i, arg );
417 |
418 | if ( value != null ) {
419 | ret[ ret.length ] = value;
420 | }
421 | }
422 |
423 | return ret.concat.apply( [], ret );
424 | },
425 |
426 | clone: function(obj, deep) {
427 | var newObj = {};
428 |
429 | if (deep == true) {
430 | newObj = TiQuery.extend(true, {}, obj);
431 | } else {
432 | newObj = TiQuery.extend({}, obj);
433 | }
434 |
435 | return newObj;
436 | },
437 |
438 | // A global GUID counter for objects
439 | guid: 1,
440 |
441 | proxy: function( fn, proxy, thisObject ) {
442 | if ( arguments.length === 2 ) {
443 | if ( typeof proxy === "string" ) {
444 | thisObject = fn;
445 | fn = thisObject[ proxy ];
446 | proxy = undefined;
447 |
448 | } else if ( proxy && !TiQuery.isFunction( proxy ) ) {
449 | thisObject = proxy;
450 | proxy = undefined;
451 | }
452 | }
453 |
454 | if ( !proxy && fn ) {
455 | proxy = function() {
456 | return fn.apply( thisObject || this, arguments );
457 | };
458 | }
459 |
460 | // Set the guid of unique handler to the same of original handler, so it can be removed
461 | if ( fn ) {
462 | proxy.guid = fn.guid = fn.guid || proxy.guid || TiQuery.guid++;
463 | }
464 |
465 | // So proxy can be declared as an argument
466 | return proxy;
467 | }
468 | });
469 |
470 | // expose TiQuery to the global object
471 | return (global.TiQuery = global.$ = TiQuery);
472 | })();
473 |
474 | function now() {
475 | return (new Date).getTime();
476 | }
477 | /**
478 | * events
479 | */
480 | (function(TiQuery) {
481 | TiQuery.extend({
482 | /**
483 | * registers an event shortcut
484 | */
485 | registerEvent: function(event) {
486 | TiQuery.fn[event] = function(fn) {
487 | if (fn == null) {
488 | return this.trigger(event);
489 | } else {
490 | return this.bind(event, fn);
491 | }
492 | }
493 | }
494 | });
495 |
496 | TiQuery.fn.extend({
497 | /**
498 | * binds an event to an object
499 | */
500 | bind: function(type, fn) {
501 | this[0].addEventListener(type, fn);
502 |
503 | return this;
504 | },
505 |
506 | /**
507 | * removes an event
508 | */
509 | unbind: function(type, fn) {
510 | this[0].removeEventListener(type, fn);
511 |
512 | return this;
513 | },
514 |
515 | /**
516 | * triggers an event on an object
517 | */
518 | trigger: function(type) {
519 | this[0].fireEvent(type);
520 |
521 | return this;
522 | }
523 | });
524 |
525 | var events = ['blur', 'cancel', 'click', 'dblclick', 'doubletap', 'focus', 'orientationchange', 'scroll', 'shake', 'singletap', 'swipe', 'touchcancel', 'touchend', 'touchmove', 'touchstart', 'twofingertap'];
526 |
527 | for(var i = 0, total = events.length; i < total; i++) {
528 | TiQuery.registerEvent(events[i]);
529 | }
530 |
531 | })(TiQuery);/**
532 | * http client
533 | */
534 | (function(TiQuery) {
535 | TiQuery.extend({
536 | httpSettings: {
537 | type: 'get',
538 | data: '',
539 | dataType: '',
540 | timeout: 3000, // milliseconds
541 | headers: {},
542 | onError: null,
543 | onLoad: null,
544 | onDataStream: null,
545 | onReadyStateChange: null,
546 | onSendStream: null
547 | },
548 |
549 | http: function(origSettings) {
550 | var s = TiQuery.extend(true, {}, TiQuery.httpSettings, origSettings);
551 |
552 | if (s.url == null) {
553 | return false;
554 | }
555 |
556 | s.type = s.type.toUpperCase();
557 | s.dataType = s.dataType.toUpperCase();
558 |
559 | // create the connection
560 | var http = Titanium.Network.createHTTPClient();
561 |
562 | // set callbacks
563 | http.ondatastream = s.onDataStream;
564 | http.onsendstream = s.onSendStream;
565 | http.onreadystatechange = s.onReadyStateChange;
566 |
567 | // set timeout
568 | http.setTimeout(s.timeout);
569 |
570 | // on load
571 | http.onload = function(event) {
572 | Titanium.API.debug('http complete');
573 |
574 | var results = false;
575 |
576 | if (s.dataType == 'XML') {
577 | // data is XML so parse it
578 | try {
579 | results = this.responseXML;
580 | }
581 | catch(E) {
582 | // not valid XML
583 | Titanium.API.error(E);
584 | results = false;
585 | }
586 | } else if (s.dataType == 'JSON') {
587 | // data is JSON so parse it
588 | results = TiQuery.parseJSON(this.responseText);
589 | } else {
590 | // no data type specified so don't do anything with it
591 | results = this.responseText;
592 | }
593 |
594 | if (TiQuery.isFunction(s.onLoad)) {
595 | s.onLoad(results, http, event);
596 | }
597 | }
598 |
599 | // on error
600 | http.onerror = function(event) {
601 | Titanium.API.error('http error: ' + event.error);
602 |
603 | if (TiQuery.isFunction(s.onError)) {
604 | s.onError(http, event);
605 | }
606 | }
607 |
608 | // open request
609 | http.open(s.type, s.url);
610 |
611 | // set headers
612 | if ($.isPlainObject(s.headers)) {
613 | for(var key in s.headers) {
614 | http.setRequestHeader(key, s.headers[key]);
615 | }
616 | }
617 |
618 | // send request
619 | http.send(s.data);
620 |
621 | // clear the object
622 | http = null;
623 |
624 | return true;
625 | }
626 | });
627 |
628 | var shortcuts = ['get', 'getJSON', 'getXML', 'post', 'postJSON', 'postXML'];
629 |
630 | for(var i = 0, total = shortcuts.length; i < total; i++) {
631 | (function(name) {
632 | var type = (name.indexOf('get') != -1) ? 'get' : 'post',
633 | dataType;
634 |
635 | if (name.indexOf('JSON') != -1) {
636 | dataType = 'JSON';
637 | } else if (name.indexOf('XML') != -1) {
638 | dataType = 'XML';
639 | }
640 |
641 | TiQuery[name] = function(url, data, fn, headers) {
642 | if (TiQuery.isFunction(data)) {
643 | headers = fn || {};
644 | fn = data;
645 | data = {};
646 | }
647 |
648 | this.http({
649 | type: type,
650 | url: url,
651 | data: data,
652 | dataType: dataType,
653 | headers: headers,
654 | onLoad: fn
655 | });
656 | }
657 | })(shortcuts[i]);
658 | }
659 | })(TiQuery);
660 | /**
661 | * Memory management
662 | *
663 | * see http://developer.appcelerator.com/question/116867/this-is-a-solution-to-your-memory-woes
664 | */
665 | (function(TiQuery) {
666 | TiQuery.extend({
667 | release: function(view, window) {
668 | if (!view) {
669 | return false;
670 | }
671 |
672 | if (!window) {
673 | window = Titanium.UI.currentWindow;
674 | }
675 |
676 | // create the hidden window
677 | memWindow = Titanium.UI.createWindow();
678 | memWindow.hide();
679 | memWindow.open();
680 |
681 | // remove the view from the window
682 | window.remove(view);
683 |
684 | // add the view to the hidden window
685 | if (TiQuery.isArray(view)) {
686 | for(var i = 0, total = view.length; i < total; i += 1) {
687 | memWindow.add(view[i]);
688 | }
689 | } else {
690 | memWindow.add(view);
691 | }
692 |
693 | // close the window releasing memory
694 | memWindow.close();
695 |
696 | memWindow = null;
697 | view = null;
698 | }
699 | });
700 | })(TiQuery);/**
701 | * Titanium shortcuts
702 | */
703 | (function(TiQuery) {
704 | TiQuery.extend({
705 | // shortcuts for Titanium.API.info, Titanium.API.error, etc
706 | info: function(message) { Titanium.API.info(message); },
707 | error: function(message) { Titanium.API.error(message); },
708 | warn: function(message) { Titanium.API.warn(message); },
709 | log: function(message) { Titanium.API.log(message); },
710 | include: function(file) { Titanium.include(file); },
711 | db: function(name) { return Titanium.Database.open(name); },
712 | currentWindow: function() { return Titanium.UI.currentWindow; },
713 | currenTab: function() { return Titanium.UI.currentTab; },
714 |
715 | // registers shortcuts
716 | registerShortcut: function(_namespace, _name, _shortcut, prefix) {
717 | if (_shortcut === undefined) {
718 | _shortcut = _name;
719 | }
720 |
721 | if (prefix === undefined) {
722 | prefix = 'create';
723 | }
724 |
725 | TiQuery[_shortcut] = function(args) {
726 | if (args === undefined) {
727 | args = {};
728 | }
729 | return Titanium[_namespace][prefix + _name](args);
730 | };
731 | }
732 | });
733 |
734 | /**
735 | * creates shortcuts to for create* methods within Titanium
736 | *
737 | * Idea/some code taken from Redux by Dawson Toth (https://github.com/dawsontoth/Appcelerator-Titanium-Redux)
738 | */
739 | var classes = {
740 | Android: ['BroadcastIntent', 'Intent', 'IntentChooser', 'Notification', 'PendingIntent', 'Service', 'ServiceIntent'],
741 | Contacts: ['Group', 'Person'],
742 | Facebook: ['LoginButton'],
743 | Filesystem: ['File', 'TempDirectory', 'TempFile'],
744 | Map: ['Annotation'],
745 | Media: ['AudioPlayer', 'AudioRecorder', 'Item', 'MusicPlayer', 'Sound', 'VideoPlayer'],
746 | Network: ['BonjourBrowser', 'BonjourService', 'HTTPClient', 'TCPSocket'],
747 | Platform: ['UUID'],
748 | Stream: ['Stream'],
749 | UI: ['2DMatrix', '3DMatrix', 'ActivityIndicator', 'AlertDialog', 'Animation', 'Button', 'ButtonBar', 'CoverFlowView', 'DashboardItem', 'DashboardView', 'EmailDialog', 'ImageView', 'Label', 'OptionDialog', 'Picker', 'PickerColumn', 'PickerRow', 'ProgressBar', 'ScrollView', 'ScrollableView', 'SearchBar', 'Slider', 'Switch', 'Tab', 'TabGroup', 'TabbedBar', 'TableView', 'TableViewRow', 'TableViewSection', 'TextArea', 'TextField', 'Toolbar', 'View', 'WebView', 'Window']
750 | }
751 |
752 | for(var namespace in classes) {
753 | for(var i = 0, total = classes[namespace].length; i < total; i++) {
754 | TiQuery.registerShortcut(namespace, classes[namespace][i])
755 | }
756 | }
757 |
758 | // A couple of methods don't follow the same pattern above so here they are
759 | TiQuery.registerShortcut('Map', 'View', 'MapView');
760 | })(TiQuery);})(this, Titanium);
--------------------------------------------------------------------------------
/test/manifest:
--------------------------------------------------------------------------------
1 | #appname: Tests2
2 | #publisher: efaerber
3 | #url: https://github.com/naturalcodeproject/TiQuery
4 | #image: appicon.png
5 | #appid: com.tiquery.tests
6 | #desc: undefined
7 | #type: ipad
8 | #guid: dd51047d-9885-429c-80e9-a57616c400af
9 |
--------------------------------------------------------------------------------
/test/tiapp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | true
6 | true
7 | true
8 | false
9 |
10 | com.tiquery.tests
11 | Tests2
12 | 1.0
13 | efaerber
14 | https://github.com/naturalcodeproject/TiQuery
15 | not specified
16 | 2011 by efaerber
17 | appicon.png
18 | false
19 | false
20 | default
21 | false
22 | false
23 | false
24 | true
25 | dd51047d-9885-429c-80e9-a57616c400af
26 |
27 |
28 | Ti.UI.PORTRAIT
29 |
30 |
31 | Ti.UI.PORTRAIT
32 | Ti.UI.UPSIDE_PORTRAIT
33 | Ti.UI.LANDSCAPE_LEFT
34 | Ti.UI.LANDSCAPE_RIGHT
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/version.txt:
--------------------------------------------------------------------------------
1 | 0.0.1
--------------------------------------------------------------------------------