Showing preview only (794K chars total). Download the full file or copy to clipboard to get everything.
Repository: tart/tartJS
Branch: master
Commit: 3b677e6969af
Files: 144
Total size: 749.3 KB
Directory structure:
gitextract_2t11nxj1/
├── .gitignore
├── .gitmodules
├── .travis.yml
├── README.md
├── gulpfile.js
├── package.json
├── scripts/
│ ├── build.sh
│ ├── compileAllSpecRunners.sh
│ ├── compileForSpecRunner.sh
│ ├── deps.sh
│ ├── jsdoc-conf.json
│ └── runAllSpecRunners.sh
├── tart/
│ ├── Builder.js
│ ├── Carousel/
│ │ ├── Carousel.js
│ │ └── spec/
│ │ ├── CarouselSpec.js
│ │ └── SpecRunner.html
│ ├── CircularCarousel/
│ │ ├── CircularCarousel.js
│ │ └── spec/
│ │ ├── CircularCarouselSpec.js
│ │ └── SpecRunner.html
│ ├── Collection.js
│ ├── DropdownList/
│ │ ├── DropdownBuilder.js
│ │ └── DropdownList.js
│ ├── Err.js
│ ├── FormValidator/
│ │ ├── FormValidator.js
│ │ ├── README.md
│ │ └── spec/
│ │ ├── FormValidatorSpec.js
│ │ └── SpecRunner.html
│ ├── List.js
│ ├── Pagination/
│ │ ├── CircularPagination.js
│ │ ├── Pagination.js
│ │ └── spec/
│ │ ├── PaginationSpec.js
│ │ └── SpecRunner.html
│ ├── Registry.js
│ ├── StateMachine/
│ │ ├── State.js
│ │ └── StateMachine.js
│ ├── Tabs/
│ │ ├── TabPanel.js
│ │ └── Tabs.js
│ ├── Validation/
│ │ ├── README.md
│ │ ├── Validation.js
│ │ └── spec/
│ │ ├── SpecRunner.html
│ │ └── ValidationSpec.js
│ ├── XhrManager.js
│ ├── base/
│ │ ├── Model.js
│ │ └── plugin/
│ │ ├── BasePlugin.js
│ │ ├── Filter.js
│ │ ├── Pager.js
│ │ └── Sorter.js
│ ├── components/
│ │ ├── Carousel/
│ │ │ ├── Controller.js
│ │ │ ├── Model.js
│ │ │ ├── Template.js
│ │ │ ├── View.js
│ │ │ └── Widget.js
│ │ ├── Controller.js
│ │ ├── RemoteModel.js
│ │ ├── ThumbnailedCarousel/
│ │ │ ├── Model.js
│ │ │ ├── SpotController.js
│ │ │ ├── SpotTemplate.js
│ │ │ ├── SpotView.js
│ │ │ ├── ThumbnailsController.js
│ │ │ ├── ThumbnailsTemplate.js
│ │ │ ├── ThumbnailsView.js
│ │ │ └── Widget.js
│ │ ├── View.js
│ │ ├── Widget.js
│ │ └── spec/
│ │ ├── ComponentsSpec.js
│ │ └── SpecRunner.html
│ ├── dataProxy/
│ │ ├── Abstract.js
│ │ ├── CircularLocal.js
│ │ ├── Local.js
│ │ └── Xhr.js
│ ├── date/
│ │ ├── DateRange.js
│ │ └── date.js
│ ├── deps.js
│ ├── dom/
│ │ └── dom.js
│ ├── events/
│ │ ├── GestureHandler.js
│ │ └── HoverHandler.js
│ ├── events.js
│ ├── externs/
│ │ ├── jasmine.externs.js
│ │ ├── jquery-1.4.4.externs.js
│ │ └── tart.externs.js
│ ├── locale/
│ │ ├── en.js
│ │ ├── locale.js
│ │ └── tr.js
│ ├── mock/
│ │ ├── index.html
│ │ └── jQuery/
│ │ └── xhr.js
│ ├── money/
│ │ ├── Currency.js
│ │ ├── CurrencyTL.js
│ │ ├── CurrencyUSD.js
│ │ └── Money.js
│ ├── mvc/
│ │ ├── Action.js
│ │ ├── Application.js
│ │ ├── Controller.js
│ │ ├── IApplication.js
│ │ ├── Layout.js
│ │ ├── MobileAction.js
│ │ ├── MobileRenderer.js
│ │ ├── Model.js
│ │ ├── README.md
│ │ ├── Renderer.js
│ │ ├── View.js
│ │ ├── mvc.js
│ │ ├── spec/
│ │ │ ├── SpecRunner.html
│ │ │ └── mvcSpec.js
│ │ ├── test/
│ │ │ ├── Bootstrapper.js
│ │ │ ├── application/
│ │ │ │ ├── controllers/
│ │ │ │ │ ├── GamesController.js
│ │ │ │ │ └── IndexController.js
│ │ │ │ ├── mvcapp.js
│ │ │ │ └── views/
│ │ │ │ ├── layouts/
│ │ │ │ │ ├── common.js
│ │ │ │ │ └── rare.js
│ │ │ │ └── scripts/
│ │ │ │ ├── games/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── list.js
│ │ │ │ └── index/
│ │ │ │ └── list.js
│ │ │ └── index.html
│ │ └── uri/
│ │ ├── Redirection.js
│ │ ├── Request.js
│ │ ├── Route.js
│ │ └── Router.js
│ ├── storage/
│ │ └── Storage.js
│ ├── string/
│ │ └── string.js
│ ├── tart.js
│ └── ui/
│ ├── Component.js
│ ├── ComponentManager.js
│ ├── ComponentModel.js
│ ├── DlgComponent.js
│ ├── InfiniteScroll/
│ │ ├── InfiniteScrollComponent.js
│ │ ├── InfiniteScrollComponentModel.js
│ │ └── infinite-scroll.css
│ ├── NavBar/
│ │ ├── NavBarComponent.js
│ │ └── nav-bar.css
│ ├── PullToRefresh/
│ │ ├── P2RComponent.js
│ │ ├── P2RComponentModel.js
│ │ └── pull-to-refresh.css
│ ├── Sidebar/
│ │ ├── SidebarComponent.js
│ │ └── sidebar.css
│ ├── TabBar/
│ │ ├── TabBarView.js
│ │ └── tabbar.css
│ ├── View.js
│ ├── ViewManager.js
│ ├── ViewModel.js
│ ├── input/
│ │ ├── DateComponent.js
│ │ └── RevealingPassword.js
│ └── tooltip/
│ ├── TooltipComponent.js
│ └── TooltipComponentModel.js
└── third_party/
└── jquery/
└── jquery-1.5.2.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.swp
*.swo
.idea
*.DS_Store
*.pyc
compiled/*
/atlassian-ide-plugin.xml
compiled.js
SpecRunnerCompiled.html
node_modules
docs
================================================
FILE: .gitmodules
================================================
[submodule "tools"]
path = tools
url = https://github.com/tart/GUI-Tools.git
[submodule "third_party/jasmine"]
path = third_party/jasmine
url = https://github.com/pivotal/jasmine.git
[submodule "third_party/goog"]
path = third_party/goog
url = https://github.com/tart/closure-library.git
================================================
FILE: .travis.yml
================================================
sudo: false
language: node_js
node_js:
- '0.12'
install:
- npm -d install
- npm install -g gulp
before_script:
- git config --global user.email "travis@travis-ci.org"
- git config --global user.name "Travis-CI"
script:
- gulp travis
env:
global:
- secure: DeieQoup1BuwAfLvz+2oRNQKEf2mrO65MsgMoBpWZirhRZvoYnzuWFVonByA6EyNPAzgzZI5Kk64aZaogbg9CzZu+mhkAuJE7m4+KgouE517wjbba8IseEFdyZ951I/VdaFp0PC33Xff32SB8L5xlzY+GnIzIUqTwa2rlogD7RA=
================================================
FILE: README.md
================================================
tartJS
======
tartJS is a performance-focused JavaScript framework based on well-tested Google Closure Tools suite.
It provides rapid and responsive mobile app infrastructure.
Check out [the documentation](http://tart.js.org/docs) and join us on [](http://slack.tartjs.org) for anything about tartJS.
Track issues on [](https://huboard.com/tart/tartJS)
Closure Compiler optimizes, checks and cleans up your annotated JavaScript code with best minification rates while helping you to catch errors.
## Getting Started
### From scratch
Add tartJS to your project as a submodule:
```sh
git submodule add git@github.com:tart/tartJS.git js/lib/tartJS
```
### Boilerplates/Examples
* For TodoMVC implementation and generic boilerplate:
http://github.com/tart/tartjs-todomvc
* For working mobile project:
https://github.com/tart/tartjs-mobile-demo
* Generic boilerplate:
https://github.com/tart/BoilerPlate
## Documentation
(More coming soon)
### Annotation
With help of Closure Compiler, class based inheritance and type safety is widely used in tartJS.
See [Annotating JavaScript for the Closure Compiler](https://developers.google.com/closure/compiler/docs/js-for-compiler) how JSDoc annotation works.
### Directory structure
* [tart](https://github.com/tart/tartJS/tree/master/tart) : Contains core Tart libraries
* tools : Contains tools like Google Closure Compiler, Google Closure Linter etc (submodule to [tart/GUI-Tools](https://github.com/tart/GUI-Tools))
* [third_party](https://github.com/tart/tartJS/tree/master/third_party) : Contains third party libraries like Google Closure Library, Jasmine, jQuery etc.
## Examples
* Outstanding web audio processor for guitar players:
[Pedalboard.js](http://dashersw.github.io/pedalboard.js/)
* Example TodoMVC application (useful as a web application boilerplate):
[tartjs-todomvc](https://github.com/tart/tartjs-todomvc)
* Example TV show mobile app (useful as a mobile boilerplate):
[tartjs-mobile-demo](https://github.com/tart/tartjs-mobile-demo)
## Contributing
Want to contribute? Great! Fork it, create a branch, make your changes, push and [open pull request](https://github.com/tart/tartJS/pulls) to contribute.
Your pull request may not be merged immediately until necessary changes were made to match coding-style, pass tests.
We do follow [Google JavaScript Style Guide](https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).
## License
Copyright 2014 Startup Kitchen. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS-IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: gulpfile.js
================================================
var gulp = require('gulp');
var shell = require("gulp-shell");
var runSequence = require('run-sequence');
var GH_TOKEN = process.env.GH_TOKEN || '';
gulp.task('jsdoc', shell.task([
'rm -rf ./docs',
'jsdoc -c ./scripts/jsdoc-conf.json'
]));
gulp.task('gh-pages', ['jsdoc'], shell.task([
'mv docs docs_new',
'git remote add upstream https://' + GH_TOKEN + '@github.com/tart/tartJS.git/',
'git fetch upstream',
'git checkout -b gh-pages upstream/gh-pages',
'rm -rf docs',
'mv docs_new docs',
'git add docs',
'git commit -m "Update documentation"',
'git push upstream gh-pages',
'git checkout master'
]));
gulp.task('travis-master', ['gh-pages']);
gulp.task('travis-pull-request', []);
gulp.task('travis', function(callback) {
var task = process.env.TRAVIS_PULL_REQUEST != 'false' ? 'travis-pull-request' : 'travis-master';
runSequence(task, callback);
});
================================================
FILE: package.json
================================================
{
"name": "tartJS",
"description": "A performance-obsessed JavaScript framework for desktop, mobile and web applications.",
"repository": {
"type": "git",
"url": "https://github.com/tart/tartJS"
},
"dependencies": {},
"devDependencies": {
"gulp": "^3.9.0",
"gulp-shell": "^0.4.2",
"jaguarjs-jsdoc": "git://github.com/davidshimjs/jaguarjs-jsdoc",
"jsdoc": "^3.3.2",
"run-sequence": "^1.1.2"
}
}
================================================
FILE: scripts/build.sh
================================================
#!/bin/bash
#usage : scripts/build.sh ply.components.AnimatedCarouselExample.SpecRunner ply/components/AnimatedCarouselExample/spec/compiled.js
namespace=$1
outputFile=$2
third_party/goog/closure/bin/build/closurebuilder.py \
--root="third_party/goog/" \
--root="tart/" \
--namespace="${namespace}" \
--compiler_flags="--externs=tart/externs/tart.externs.js" \
--compiler_flags="--externs=tart/externs/jasmine.externs.js" \
--compiler_flags="--externs=tart/externs/jquery-1.4.4.externs.js" \
--output_mode="compiled" --compiler_jar=tools/compiler/compiler.jar \
--output_file=${outputFile} \
--compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS" \
--compiler_flags="--output_wrapper='(function(){%output%})()'" \
--compiler_flags="--create_source_map='compiled/source_map.js'" \
--compiler_flags="--property_renaming_report='compiled/properties.out'" \
--compiler_flags="--variable_renaming_report='compiled/variables.out'" \
--compiler_flags="--warning_level=VERBOSE" \
--compiler_flags="--formatting=PRETTY_PRINT" \
--compiler_flags="--formatting=PRINT_INPUT_DELIMITER" \
--compiler_flags="--jscomp_warning=accessControls" \
--compiler_flags="--jscomp_error=checkRegExp" \
--compiler_flags="--jscomp_error=checkTypes" \
--compiler_flags="--jscomp_error=nonStandardJsDocs" \
--compiler_flags="--jscomp_error=strictModuleDepCheck"
================================================
FILE: scripts/compileAllSpecRunners.sh
================================================
#!/bin/bash
for i in `find * -type f | grep -i spec | grep -i "SpecRunner.html$" | grep -v "third_party"`;
do
compiledJs=`echo $i | sed -e 's/SpecRunner.html/compiled.js/'`
echo -e "========= COMPILING $compiledJs =========" ;
scripts/compileForSpecRunner.sh $compiledJs 2> /dev/null;
echo -e "========= FINISHED $? =========\n";
done
================================================
FILE: scripts/compileForSpecRunner.sh
================================================
#!/bin/bash
#usage : scripts/compileForSpecRunner.sh ply/components/AnimatedCarouselExample/spec/compiled.js
outputFile=$1
if [[ $outputFile == *spec/compiled.js* ]]
then
namespace=`echo $outputFile | sed -e 's/\/spec\/compiled.js//g' | sed -e 's/\//\./g'`
namespace=${namespace}.SpecRunner
else
echo "ERROR : Path should containt spec/compiled.js";
exit 1;
fi
third_party/goog/closure/bin/build/closurebuilder.py --root="third_party/goog/" --root="tart/" --root="ply/" --namespace="${namespace}" --compiler_flags="--externs=tart/externs/tart.externs.js" --compiler_flags="--externs=tart/externs/jasmine.externs.js" \
--compiler_flags="--externs=tart/externs/jquery-1.4.4.externs.js" \
--output_mode="compiled" --compiler_jar=tools/compiler/compiler.jar \
--output_file=${outputFile} \
--compiler_flags="--compilation_level=ADVANCED_OPTIMIZATIONS" \
--compiler_flags="--output_wrapper='(function(){%output%})()'" \
--compiler_flags="--create_source_map='compiled/source_map.js'" \
--compiler_flags="--property_renaming_report='compiled/properties.out'" \
--compiler_flags="--variable_renaming_report='compiled/variables.out'" \
--compiler_flags="--warning_level=VERBOSE" \
--compiler_flags="--formatting=PRETTY_PRINT" \
--compiler_flags="--formatting=PRINT_INPUT_DELIMITER" \
--compiler_flags="--jscomp_warning=accessControls" \
--compiler_flags="--jscomp_error=checkRegExp" \
--compiler_flags="--jscomp_error=checkTypes" \
--compiler_flags="--jscomp_error=nonStandardJsDocs" \
--compiler_flags="--jscomp_error=strictModuleDepCheck"
================================================
FILE: scripts/deps.sh
================================================
#!/bin/bash
#usage : scripts/deps.sh
third_party/goog/closure/bin/build/depswriter.py --root_with_prefix='tart/ ../../../../tart/' --output_file='tart/deps.js'
================================================
FILE: scripts/jsdoc-conf.json
================================================
{
"tags": {
"allowUnknownTags": true,
"dictionaries": ["closure", "jsdoc"]
},
"source": {
"include": ["tart", "README.md"],
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"opts": {
"template": "node_modules/jaguarjs-jsdoc",
"encoding": "utf8",
"destination": "docs/",
"recurse": true
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": true,
"monospaceLinks": false,
"default": {
"outputSourceFiles": true
},
"applicationName": "TartJS",
"disqus": "",
"googleAnalytics": "",
"openGraph": {
"title": "",
"type": "",
"image": "",
"site_name": "",
"url": ""
},
"meta": {
"title": "tartJS",
"description": "",
"keyword": ""
},
"linenums": true
},
"markdown": {
"tags": []
}
}
================================================
FILE: scripts/runAllSpecRunners.sh
================================================
#!/bin/bash
#run all SpecRunner*html files using qasmine
for i in `find * -type f | grep -v third_party | grep -i SpecRunner | grep -i "\.html"`;
do
echo -e "========= RUNNUNG $i =========" ;
qasmine $i 2> /dev/null;
echo -e "========= FINISHED $? =========\n";
done
================================================
FILE: tart/Builder.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Generic builder class to build and modify DOM elements.
*/
goog.provide('tart.Builder');
goog.require('tart.Err');
/**
* Constructor method
*
* @constructor
* @param {string} id id for the builder. Can be used as the id of the DOM element this builder will build.
* @return {tart.Builder} A builder object.
*/
tart.Builder = function(id) {
this.id_ = id || '';
return this;
};
/**
* @type {jQueryObject}
* @protected
*/
tart.Builder.prototype.$dom = null;
/**
* @type {Object} Templates holder object.
*/
tart.Builder.templates = {};
/**
* Builds the DOM element.
* @param {*} owner Owner class for the builder.
*/
tart.Builder.prototype.buildDOM = goog.abstractMethod;
/**
* Returns built ready-to-use DOM part in jQuery object format.
*
* @return {?jQueryObject} the DOM object built by the builder.
*/
tart.Builder.prototype.getDOM = function() {
return this.$dom;
};
/**
* Removes the DOM part from document.
*/
tart.Builder.prototype.removeDOM = goog.abstractMethod;
================================================
FILE: tart/Carousel/Carousel.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.Carousel is an event driven Carousel/Image Slider class
* which handles next and previous events and gets visible items on viewport.
*
* Example usage:
*
* var items = [
* {name : 'one'},
* {name : 'two'},
* {name : 'three'},
* {name : 'four'},
* {name : 'five'},
* {name : 'six'},
* {name : 'seven'}
* ]; //seven items
*
* var carousel = new tart.Carousel(items);
*
* carousel.setItemPerViewport(2); //only 2 items is visibile
*
* goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function (e) {
* console.info('items moved next');
* console.log (e.itemsToBeRemoved);
* console.log (e.itemsToBeInserted);
* console.info(carousel.getVisibleItems());
* });
*
* goog.events.listen(carousel, tart.Carousel.EventTypes.PREV, function (e) {
* console.info('items moved prev');
* console.log (e.itemsToBeRemoved);
* console.log (e.itemsToBeInserted);
* console.info(carousel.getVisibleItems());
* });
*
* //items : 'one', 'two'
* carousel.next(1);
* //items : 'two', 'three'
* carousel.next(4);
* //items : 'six', 'seven'
* carousel.next(1);
* //items : 'six', 'seven' which is end of items, for circular navigation use tart.CircularCarousel instead
* carousel.prev(1);
* //items : 'five', 'six'
* carousel.prev(99999);
* //items : 'one', 'two'
*/
goog.provide('tart.Carousel');
goog.provide('tart.Carousel.EventTypes');
goog.require('goog.debug.ErrorHandler');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
/**
* Pagination class to handle all paging events
*
* @param {Array.<*>=} items array of items.
* @extends {goog.events.EventTarget}
* @constructor
*/
tart.Carousel = function(items) {
goog.events.EventTarget.call(this);
/** @protected */
this.items = items;
/** @protected */
this.itemCount = this.items.length;
/** @protected */
this.itemPerViewport = 1;
/**
* First visible item index in viewport
*
* @protected
* */
this.firstVisible = 0;
/**
* Last visible item index in viewport
*
* @protected
* */
this.lastVisible = this.firstVisible + this.itemPerViewport;
};
goog.inherits(tart.Carousel, goog.events.EventTarget);
/**
* Event types enumaration
*
* @enum {string}
*/
tart.Carousel.EventTypes = {
MOVED: 'moved',
PREV: 'prev',
NEXT: 'next'
};
/**
* Item per visible viewport
*
* @param {number} itemPerViewport number of visible items.
* @return {tart.Carousel} itself for chaining.
*/
tart.Carousel.prototype.setItemPerViewport = function(itemPerViewport) {
this.itemPerViewport = itemPerViewport;
this.lastVisible = this.firstVisible + itemPerViewport;
return this;
};
/**
* Get number of visible items in viewport
*
* @return {number} number of visible items.
*/
tart.Carousel.prototype.getItemPerViewport = function() {
return this.itemPerViewport;
};
/**
* Get visible items
*
* @return {Array.<*>} visible items array.
*/
tart.Carousel.prototype.getVisibleItems = function() {
return this.items.slice(this.firstVisible, this.lastVisible);
};
/**
* Get visible items indexes
*
* @return {Object} visible items array.
*/
tart.Carousel.prototype.getVisibleItemIndexes = function() {
var indexes = {
first: this.firstVisible,
last: this.lastVisible
};
return indexes;
};
/**
* Calculate max move count
*
* @param {string} direction 'next' or 'prev' direction.
* @param {number} moveCount number of movement.
* @return {number} max move count.
* @private
*/
tart.Carousel.prototype.getMaxMoveCount_ = function(direction, moveCount) {
var maxMoveCount;
if (direction == 'next') {
maxMoveCount = this.itemCount - this.lastVisible;
}
else {
maxMoveCount = this.firstVisible;
}
return maxMoveCount;
};
/**
* Find which items to be removed and inserted after move
*
* @param {number} moveCount item move count.
* @return {Object} object literal which has itemsToBeInserted and itemsToBeRemoved nodes.
*/
tart.Carousel.prototype.getItemsToBeInsertedAndRemoved = function(moveCount) {
var i,
previousItemsIndex = [],
nextItemsIndex = [];
for (i = this.firstVisible; i < this.lastVisible; i++) {
previousItemsIndex.push(i);
nextItemsIndex.push(i + moveCount);
}
var moveDiff = this.getMoveDiff(previousItemsIndex, nextItemsIndex, moveCount);
return moveDiff;
};
/**
* Get difference between visible items, after move and before move
*
* @param {Array.<number>} a1 first array.
* @param {Array.<number>} a2 second array.
* @param {number} moveCount item move count.
* @return {Object} generated diff.
* @protected
*/
tart.Carousel.prototype.getMoveDiff = function(a1, a2, moveCount) {
var direction = (moveCount > 0) ? 'next' : 'prev';
moveCount = Math.abs(moveCount);
var i = 0,
index = 0,
itemsToBeInserted = [],
itemsToBeRemoved = [],
itemCount = this.itemCount;
var tmpItems;
if (direction == 'prev') {
tmpItems = {
toBeInserted: a2.slice(0, moveCount),
toBeRemoved: a1.slice(-1 * moveCount, a1.length)
};
}
else {
tmpItems = {
toBeRemoved: a1.slice(0, moveCount),
toBeInserted: a2.slice(-1 * moveCount, a2.length)
};
}
for (i = 0; i < tmpItems.toBeInserted.length; i++) {
index = (tmpItems.toBeInserted[i] + itemCount) % itemCount;
itemsToBeInserted.push(this.items[index]);
}
for (i = 0; i < tmpItems.toBeRemoved.length; i++) {
index = (tmpItems.toBeRemoved[i] + itemCount) % itemCount;
itemsToBeRemoved.push(this.items[index]);
}
return {
itemsToBeInserted: itemsToBeInserted,
itemsToBeRemoved: itemsToBeRemoved
};
};
/**
* Move cursor to next or previous item
*
* @param {string} direction 'next' or 'prev' movement direction.
* @param {*} moveCount cursor move count.
* @protected
*/
tart.Carousel.prototype.move = function(direction, moveCount) {
moveCount = moveCount || 1;
moveCount = Math.abs(moveCount);
var maxMoveCount = this.getMaxMoveCount_(direction, moveCount);
moveCount = moveCount <= maxMoveCount ? moveCount : maxMoveCount;
var eventToDispatch = tart.Carousel.EventTypes.NEXT;
if (direction == 'prev') {
moveCount = moveCount * -1;
eventToDispatch = tart.Carousel.EventTypes.PREV;
}
var moveDiff = this.getItemsToBeInsertedAndRemoved(moveCount);
this.firstVisible = this.firstVisible + moveCount;
this.lastVisible = this.lastVisible + moveCount;
var eventObj = {type: eventToDispatch,
itemsToBeRemoved: moveDiff.itemsToBeRemoved,
itemsToBeInserted: moveDiff.itemsToBeInserted};
this.dispatchEvent(eventObj);
};
/**
* Move cursor to next
*
* @param {number|*} moveCount cursor move count.
*/
tart.Carousel.prototype.next = function(moveCount) {
this.move('next', moveCount);
};
/**
* Move cursor to previous
*
* @param {number|*} moveCount cursor move count.
*/
tart.Carousel.prototype.prev = function(moveCount) {
this.move('prev', moveCount);
};
================================================
FILE: tart/Carousel/spec/CarouselSpec.js
================================================
goog.require('tart.Carousel');
goog.provide('tart.Carousel.SpecRunner');
describe('Carousel', function() {
var carousel;
var items = [
{name: 'one'},
{name: 'two'},
{name: 'three'},
{name: 'four'},
{name: 'five'},
{name: 'six'},
{name: 'seven'}
];
beforeEach(function() {
carousel = new tart.Carousel(items);
});
describe('some parameters should be set and get', function() {
it('should set itemPerViewport', function() {
carousel.setItemPerViewport(10);
expect(carousel.getItemPerViewport()).toEqual(10);
});
it('should return visible items', function() {
carousel.setItemPerViewport(2);
var visibleItems = carousel.getVisibleItems();
expect(visibleItems[0].name == 'one' && visibleItems[1].name == 'two').toBeTruthy();
});
});
describe('will navigate through items', function() {
it('should move one item next', function() {
carousel.setItemPerViewport(3);
var previousItems = carousel.getVisibleItems(),
visibleItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function(e) {
visibleItems = carousel.getVisibleItems();
});
carousel.next(1);
expect(visibleItems[0].name == 'two' && visibleItems[1].name == 'three').toBeTruthy();
});
it('should move more than item next', function() {
carousel.setItemPerViewport(3);
var visibleItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function(e) {
visibleItems = carousel.getVisibleItems();
});
carousel.next(3);
expect(visibleItems[0].name == 'four' && visibleItems[1].name == 'five').toBeTruthy();
});
it('should not move more than item count', function() {
carousel.setItemPerViewport(2);
var visibleItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function(e) {
visibleItems = carousel.getVisibleItems();
});
carousel.next(99999);
expect(visibleItems[0].name == 'six' && visibleItems[1].name == 'seven').toBeTruthy();
});
});
});
/**
* Run jasmine spec
*/
tart.Carousel.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/Carousel/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript">
goog.require("goog.events.EventTarget");
</script>
<script type="text/javascript" src="../../Pagination.js"></script>
<script type="text/javascript" src="../Carousel.js"></script>
</head>
<body>
<!-- include spec files here... -->
<script type="text/javascript" src="CarouselSpec.js"></script>
</body>
</html>
================================================
FILE: tart/CircularCarousel/CircularCarousel.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.CircularCarousel is an event driven Carousel/Image Slider class which
* handles next and previous events and gets visible items on viewport.
*
* Example usage:
*
* var items = [
* {name : 'one'},
* {name : 'two'},
* {name : 'three'},
* {name : 'four'},
* {name : 'five'},
* {name : 'six'},
* {name : 'seven'}
* ]; //seven items
*
* var carousel = new tart.CircularCarousel(items);
*
* carousel.setItemPerViewport(2); //only 2 items is visibile
*
* goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function (e) {
* console.info('items moved next');
* console.log (e.itemsToBeRemoved);
* console.log (e.itemsToBeInserted);
* console.info(carousel.getVisibleItems());
* });
*
* goog.events.listen(carousel, tart.Carousel.EventTypes.PREV, function (e) {
* console.info('items moved prev');
* console.log (e.itemsToBeRemoved);
* console.log (e.itemsToBeInserted);
* console.info(carousel.getVisibleItems());
* });
*
* carousel.prev(3);
* carousel.next(1);
*/
goog.provide('tart.CircularCarousel');
goog.require('goog.events.EventTarget');
goog.require('tart.Carousel');
/**
* Pagination class to handle all paging events
*
* @param {Array.<*>=} items array of items.
* @extends {tart.Carousel}
* @constructor
*/
tart.CircularCarousel = function(items) {
goog.base(this, items);
};
goog.inherits(tart.CircularCarousel, tart.Carousel);
/**
* Find which items to be removed and inserted after move
*
* @param {number} moveCount item move count.
* @return {Object} object literal which has itemsToBeInserted and itemsToBeRemoved nodes.
*/
tart.CircularCarousel.prototype.getItemsToBeInsertedAndRemoved = function(moveCount) {
var i,
previousItemsIndex = [],
nextItemsIndex = [],
start = this.firstVisible + moveCount;
for (i = 0; i < this.lastVisible; i++) {
previousItemsIndex.push(i);
}
for (i = start; i < start + this.itemPerViewport; i++) {
nextItemsIndex.push(i);
}
var moveDiff = this.getMoveDiff(previousItemsIndex, nextItemsIndex, moveCount);
return moveDiff;
};
/**
* low level move which handles next and prev methods
*
* @param {string} direction 'next' or 'prev' direction of movement.
* @param {*} moveCount item move count.
* @override
* @protected
*/
tart.CircularCarousel.prototype.move = function(direction, moveCount) {
moveCount = moveCount || 1;
moveCount = Math.abs(moveCount);
moveCount = moveCount % this.itemCount;
var tmpCursor = 0;
//default event dispatched
var eventToDispatch = tart.Carousel.EventTypes.NEXT;
if (direction == 'prev') {
moveCount = moveCount * -1;
tmpCursor = this.itemCount;
eventToDispatch = tart.Carousel.EventTypes.PREV;
}
var tmp = [].concat(this.items).concat(this.items);
var moveDiff = this.getItemsToBeInsertedAndRemoved(moveCount);
this.firstVisible = this.firstVisible + tmpCursor + moveCount;
this.lastVisible = this.lastVisible + tmpCursor + moveCount;
this.items = tmp.slice(this.firstVisible, this.firstVisible + this.itemCount);
this.firstVisible = 0;
this.lastVisible = this.itemPerViewport;
var eventObj = {type: eventToDispatch,
itemsToBeRemoved: moveDiff.itemsToBeRemoved,
itemsToBeInserted: moveDiff.itemsToBeInserted};
this.dispatchEvent(eventObj);
};
================================================
FILE: tart/CircularCarousel/spec/CircularCarouselSpec.js
================================================
goog.require('tart.CircularCarousel');
goog.provide('tart.CircularCarousel.SpecRunner');
describe('CircularCarousel', function() {
var carousel;
var items = [
{name: 'one'},
{name: 'two'},
{name: 'three'},
{name: 'four'},
{name: 'five'},
{name: 'six'},
{name: 'seven'}
];
beforeEach(function() {
carousel = new tart.CircularCarousel(items);
});
describe('extends from tart.Carousel', function() {
it('is an isstance of tart.Carousel', function() {
expect(carousel instanceof tart.Carousel).toBeTruthy();
});
});
describe('has circular navigation', function() {
it('will navigate to seventh element after prev if current item is first item', function() {
carousel.setItemPerViewport(2);
var previousItems = carousel.getVisibleItems(),
nextItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.PREV, function(e) {
nextItems = carousel.getVisibleItems();
});
carousel.prev(1);
expect(previousItems[0].name == 'one' && nextItems[0].name == 'seven').toBeTruthy();
});
it('will navigate to second element after 6 previous steps', function() {
carousel.setItemPerViewport(2);
var previousItems = carousel.getVisibleItems(),
nextItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.PREV, function(e) {
nextItems = carousel.getVisibleItems();
});
carousel.prev(6);
expect(previousItems[0].name == 'one' && nextItems[0].name == 'two').toBeTruthy();
});
it('will navigate to seventh element after 8 previous steps which it means circular', function() {
carousel.setItemPerViewport(2);
var previousItems = carousel.getVisibleItems(),
nextItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.PREV, function(e) {
nextItems = carousel.getVisibleItems();
});
carousel.prev(8);
expect(previousItems[0].name == 'one' && nextItems[0].name == 'seven').toBeTruthy();
});
it('will navigate to second element after 8 next steps which it means circular', function() {
carousel.setItemPerViewport(2);
var previousItems = carousel.getVisibleItems(),
nextItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function(e) {
nextItems = carousel.getVisibleItems();
});
carousel.next(8);
expect(previousItems[0].name == 'one' && nextItems[0].name == 'two').toBeTruthy();
});
it('will navigate to third element after 2 next steps', function() {
carousel.setItemPerViewport(2);
var previousItems = carousel.getVisibleItems(),
nextItems;
goog.events.listen(carousel, tart.Carousel.EventTypes.NEXT, function(e) {
nextItems = carousel.getVisibleItems();
});
carousel.next(2);
expect(previousItems[0].name == 'one' && nextItems[0].name == 'three').toBeTruthy();
});
});
});
/**
* Run jasmine spec
*/
tart.CircularCarousel.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/CircularCarousel/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript">
goog.require("goog.events.EventTarget");
</script>
<script type="text/javascript" src="../../Carousel/Carousel.js"></script>
<script type="text/javascript" src="../CircularCarousel.js"></script>
</head>
<body>
<!-- include spec files here... -->
<script type="text/javascript" src="CircularCarouselSpec.js"></script>
</body>
</html>
================================================
FILE: tart/Collection.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.Collection is a useful data construct that also features an "active item". It is a key-value pair
* collection with easy to use methods. It is also event-driven, so observers are notified when the index of the
* active item changes.
*
* Example usage:
*
* var items = { foo : 'bar' };
* var list = new tart.Collection(items);
*
* OR
*
* var items = ['A','B', 'C', 'D'];
* var list = new tart.Collection(items);
*
* OR
*
* var items = { foo : 'bar', baz:'zoo' };
* var list = new tart.Collection(items, 1); // Set activeItemIndex to 1
*/
goog.provide('tart.Collection');
goog.require('goog.array');
goog.require('goog.pubsub.PubSub');
goog.require('tart.Err');
/**
* Constructor method
*
* @constructor
* @extends {goog.pubsub.PubSub}
* @param {tart.JSON=} initialList Default list items in JSON format.
* @param {number=} activeItem Default selected item index.
* @return {tart.Collection} A list object.
*/
tart.Collection = function(initialList, activeItem) {
// define privileged methods and properties here...
goog.base(this);
var initials = initialList || [];
this.activeItemIndex_ = (activeItem === undefined) ? -1 : activeItem;
this.values_ = []; // Values of all list elements.
this.keys_ = []; // Keys of all list elements.
this.items_ = []; // All key-val pairs in collection. Format [{a:1},{b:2},{c:x}]
// Initial values given like this: {a:b,c:d,e:f}
//@todo This loop should be coded in generic javascript instead of jQuery.
var _self = this;
$.each(initials, function(a, b) {
_self.addItem(a, b);
});
this.setActiveItemIndex(this.activeItemIndex_);
return this;
};
goog.inherits(tart.Collection, goog.pubsub.PubSub);
/**
* Adds a new key-value pair to the collection.
*
* @param {number|string} key Key for the pair.
* @param {*} value Value for the pair.
* @return {boolean} Returns true if the add operation was successful.
*/
tart.Collection.prototype.addItem = function(key, value) {
if (key === undefined || value === undefined) {
throw new tart.Err('Missing arguments (key: ' + key + ' value: ' + value + ')- you must give a key' +
'and a value to add a new item.');
} else if (this.getByKey(key)) {
// Deffensive check: key's must be unique
throw new tart.Err('Key "' + key + '" already in collection. Keys should be unique.');
} else {
var item = {};
item[key] = value;
this.keys_.push(key);
this.values_.push(value);
this.items_.push(item);
return true;
}
};
/**
* Returns active item as JSON object.
*
* @return {tart.JSON} returns the active key-value pair from the collection.
*/
tart.Collection.prototype.getActiveItem = function() {
return this.items_[this.getActiveItemIndex()];
};
/**
* Returns active item's key.
*
* @return {string|number} returns the active key from the collection.
*/
tart.Collection.prototype.getActiveItemKey = function() {
return this.keys_[this.getActiveItemIndex()];
};
/**
* Returns active item's value.
*
* @return {*} returns the active value from the collection.
*/
tart.Collection.prototype.getActiveItemValue = function() {
return this.values_[this.getActiveItemIndex()];
};
/**
* Returns active item's index.
* @return {number} returns the active index in the collection.
*/
tart.Collection.prototype.getActiveItemIndex = function() {
return this.activeItemIndex_;
};
/**
* Returns item by given key. If not found, returns boolean false.
*
* @param {string|number} key key to search for.
* @return {tart.JSON} returns the key-value pair given a specific key.
*/
tart.Collection.prototype.getByKey = function(key) {
return this.items_[goog.array.indexOf(this.keys_, key)];
};
/**
* Returns item by given value. If not found, returns boolean false.
*
* @param {string|number} val value to search for.
* @return {tart.JSON} returns the key-value pair given a specific value.
*/
tart.Collection.prototype.getByValue = function(val) {
return this.items_[goog.array.indexOf(this.values_, val)];
};
/**
* Returns item by given index.
*
* @param {number} index Index to search in the collection.
* @return {tart.JSON|boolean|undefined} returns the key-value pair given an index.
*/
tart.Collection.prototype.getByIndex = function(index) {
if (index >= this.keys_.length || index < 0 || index === undefined || isNaN(index)) {
return undefined;
} else {
return this.items_[index];
}
};
/**
* Dumps all items in an array.
* @return {Array} returns all pairs as an array.
*/
tart.Collection.prototype.getAll = function() {
return this.items_;
};
/** Returns all values in an array.
* @return {Array} returns all values in an array.
*/
tart.Collection.prototype.getValues = function() {
return this.values_;
};
/** Returns all keys in an array.
* @return {Array} returns all keys in an array.
*/
tart.Collection.prototype.getKeys = function() {
return this.keys_;
};
/**
* Returns all items in a kvp format.
* @return {tart.JSON} obj returns an object that contains keys as its keys and values as its values.
*/
tart.Collection.prototype.getItems = function() {
var obj = {};
for (var i = 0, l = this.items_.length; i < l; i++) {
var item = this.items_[i];
$.each(item, function(key, value) {
obj[key] = value;
});
}
return obj;
};
/**
* Removes an item from collection which given by index and rebuilds the item collection.
* Returns new activeItemIndex if item successfully removed or FALSE if not.
*
* @param {number} index Index to remove.
* @return {number|boolean|undefined} Condition of the operation or the active item index.
*/
tart.Collection.prototype.removeByIndex = function(index) {
if (index >= this.keys_.length || index < 0 || index === undefined || isNaN(index)) {
return undefined;
} else {
var oldActiveKey = this.getActiveItemKey();
this.items_.splice(index, 1);
this.keys_.splice(index, 1);
this.values_.splice(index, 1);
var oldActiveIndex = goog.array.indexOf(this.keys_, oldActiveKey);
if (oldActiveIndex > -1) {
this.setActiveItemIndex(oldActiveIndex);
} else {
this.setActiveItemIndex(-1);
}
return this.activeItemIndex_;
}
};
/**
* Removes items by key.
* @param {string} key Game items key.
*/
tart.Collection.prototype.removeByKey = function(key) {
var keys = this.getKeys();
var index = goog.array.indexOf(keys, key);
this.removeByIndex(index);
};
/**
* Sets active item index.
* @param {number} newIndex index to set as the new active item.
* @return {boolean} Whether the method was able to set the item.
*/
tart.Collection.prototype.setActiveItemIndex = function(newIndex) {
// Deffensive check; active item index should not greater than total items in collection.
if (newIndex > this.values_.length - 1 || newIndex === undefined || isNaN(newIndex) || newIndex == this.activeItemIndex_) {
return false;
} else {
var oldIndex = this.activeItemIndex_;
this.activeItemIndex_ = newIndex;
this.publish('indexChanged', this.activeItemIndex_, oldIndex);
return true;
}
};
================================================
FILE: tart/DropdownList/DropdownBuilder.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Builder class for dropdown lists.
*/
goog.require('tart.Builder');
goog.provide('tart.DropdownBuilder');
/**
* DropdownBuilder class builds the DOM for DropdownList class.
*
* @constructor
* @extends {tart.Builder}
* @param {string} id id for the builder. Can be used as the id of the DOM element this builder will build.
* @return {tart.DropdownBuilder} A builder object.
*/
tart.DropdownBuilder = function(id) {
goog.base(this, id);
this.owner = null;
return this;
};
goog.inherits(tart.DropdownBuilder, tart.Builder);
/**
* Main namespace of HTML templates for DOM structure.
*/
tart.DropdownBuilder.templates = {};
/**
* Select menu template.
* @param {string} id Id of the container.
* @param {string} optionListHTML HTML of the list of options.
* @return {string} the container HTML.
*/
tart.DropdownBuilder.templates.container = function(id, optionListHTML) {
return '<select id="' + id + '">' + optionListHTML + '</select>';
};
/**
* Generates a select menu element, converts it to a jQuery object and passes to this.$dom.
*
* @param {tart.Collection} owner Owner tart.Collection instance.
*/
tart.DropdownBuilder.prototype.buildDOM = function(owner) {
this.owner = owner;
var opts = [];
for (var k = 0, z = this.owner.keys_.length; k < z; k++) {
var option = tart.DropdownBuilder.templates.option(
this.owner.keys_[k], this.owner.values_[k], (k == this.owner.getActiveItemIndex()));
opts.push(option);
}
var finalDOM = tart.DropdownBuilder.templates.container(this.id_, opts.join(''));
this.$dom = $(finalDOM);
this.$dom.change(function() {
owner.switchIndex($(this).attr('selectedIndex'));
});
};
/**
* Generates a single option element which ready-to-use in a HTML select menu element.
*
* @param {string|number} key Option value.
* @param {string|number} value Option value.
* @param {boolean} selected Whether the option is selected.
* @return {string} the option HTML.
*/
tart.DropdownBuilder.templates.option = function(key, value, selected) {
var active = (selected) ? ' selected="selected"' : '';
return '<option value="' + key + '"' + active + '>' + value + '</option>';
};
/**
* Sets an select option's "selected" property to True.
*
* @param {number} newIndex the new index of the element to set the dropdown list to.
*/
tart.DropdownBuilder.prototype.changeActiveItem = function(newIndex) {
this.$dom.attr('selectedIndex', newIndex).change();
};
/**
* Removes a single select option from DOM by index which given as parameter.
*
* @param {number} index the index of the element to remove from the list.
*/
tart.DropdownBuilder.prototype.removeOption = function(index) {
this.$dom.children().eq(index).remove();
};
/**
* Creates a single select option and attachs it to the current DOM.
*
* @param {string|number} key value for the option.
* @param {string|number} value Text for the option.
* @return {jQueryObject} the jQuery object that holds the DOM object of the dropdown list.
*/
tart.DropdownBuilder.prototype.addOption = function(key, value) {
return this.$dom.append(tart.DropdownBuilder.templates.option(key, value, false));
};
/**
* @inheritDoc
*/
tart.DropdownBuilder.prototype.removeDOM = function() {
this.$dom.remove();
};
================================================
FILE: tart/DropdownList/DropdownList.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Dropdown list class is an example of an HTML select box.
*
* Example usage:
*
* var items = {key1:'val1',key2:'val2',key3:'val3'};
* var builder = new tart.DropdownBuilder('elementId');
* var selectedItem = 1;
* var list = new tart.DropdownList(items, builder, selectedItem);
* list.getAll(); // Outputs [{key1:'val1'},{key2:'val2'},{key3:'val3'}]
* list.getDOM(); // Returns a select (dropdown) menu in jquery format jQuery(select#elementId)
* list.setActiveItemIndex(2); // Sets key3:val3 option element selected property to TRUE;
* list.getActiveItemIndex(); // Returns an Object { key3="val3" }
*/
goog.provide('tart.DropdownList');
goog.require('tart.Collection');
goog.require('tart.DropdownBuilder');
/**
* Constructor method for DropdownList.
*
* @constructor
* @extends {tart.Collection}
* @param {Object|Array} initialList initial list of items.
* @param {tart.Builder=} opt_builder builder class.
* @param {number=} opt_activeItem index of the active item.
*/
tart.DropdownList = function(initialList, opt_builder, opt_activeItem) {
goog.base(this, initialList, opt_activeItem);
this.builder = opt_builder || new tart.DropdownBuilder('');
this.builder.buildDOM(this);
};
goog.inherits(tart.DropdownList, tart.Collection);
/**
* @inheritDoc
*/
tart.DropdownList.prototype.removeByIndex = function(index) {
var result = this.constructor.superClass_.removeByIndex.call(this, index);
if (result === false) {
return -1;
} else if (result === -1) {
this.setActiveItemIndex(0);
return 0;
} else {
if (this.builder) {
this.builder.removeOption(result);
}
return result;
}
};
/**
* Removes current DOM element of dropdownlist instance from window.document.
*/
tart.DropdownList.prototype.removeDOM = function() {
this.builder.removeDOM();
};
/**
* Returns current DOM element of dropdownlist instance.
*
* @return {jQueryObject} The jQuery object that wraps the DOM.
*/
tart.DropdownList.prototype.getDOM = function() {
return this.builder.getDOM();
};
/**
* @inheritDoc
*/
tart.DropdownList.prototype.setActiveItemIndex = function(newIndex) {
this.switchIndex(newIndex);
if (this.builder) {
this.builder.changeActiveItem(this.getActiveItemIndex());
return true;
}
return false;
};
/**
* Set active item belongs to value parameter.
* @param {(string|number)} value of an array.
*/
tart.DropdownList.prototype.setActiveItemByValue = function(value) {
var that = this;
var items = this.getValues();
var index = goog.array.findIndex(items, function(item) {
return value == item;
});
that.setActiveItemIndex(index);
};
/**
* Triggered by this.builder.dom_ element when user change the index by non-programatically way.
* Important: This method shouldn't be called in any implementation code. Developers should use
* this.setActiveItemIndex() method instead of this.
*
* @param {number} newIndex index of the item to set as active.
*/
tart.DropdownList.prototype.switchIndex = function(newIndex) {
this.constructor.superClass_.setActiveItemIndex.call(this, ((newIndex < 0) ? 0 : newIndex));
};
/**
* @inheritDoc
*/
tart.DropdownList.prototype.addItem = function(key, value) {
var added = this.constructor.superClass_.addItem.call(this, key, value);
if (this.builder && added === true) {
this.builder.addOption(key, value);
return true;
}
return false;
};
================================================
FILE: tart/Err.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tartJS error library and utility functions.
*/
goog.provide('tart.Err');
goog.require('tart');
/**
* Returns a new Error object which contains a custom error name and message.
*
* @param {string=} message Message to set as the error message.
* @param {string=} name Optional error name.
* @extends {Error}
* @constructor
*/
tart.Err = function(message, name) {
this.name = name || 'Error';
this.message = message || '';
};
goog.inherits(tart.Err, Error);
/**
* Returns a new Error object which contains a implementation error message.
*
* @param {string} methodName Name of the unimplemented method. This will be set as the error message.
* @throws {Error} Error object containing the details.
*/
tart.Err.unimplementedMethod = function(methodName) {
throw new tart.Err('Wrong implementation',
'You should implement your own ' + methodName + ' method in child class which you want to use.');
};
================================================
FILE: tart/FormValidator/FormValidator.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.FormValidator is a form validation library which uses tart.Validation instance as validator.
*
* Example usage:
*
* var form = $("form");
* var validationForSubmit = function (errors) {
* //do some stuff with 'errors' object
* };
* var validationForBlur = function (errors) {
* //do some stuff with 'errors' object
* };
* tart.FormValidator(form).validateOnSubmit(validationForSubmit);
* tart.FormValidator(form).validateOnBlur(validateOnBlur);
*
* More examples can be seen from spec/FormValidationSpec.js file
*/
goog.require('tart.Validation');
goog.provide('tart.FormValidator');
/**
* Attach validator to formEl
*
* @param {Object} formEl jQuery element for selected form.
* @constructor
* @return {tart.FormValidator} .
*/
tart.FormValidator = function(formEl) {
//TODO: this is tightly coupled to tart.Validation
/* @protected */
this.validator = tart.Validation;
/* @protected */
this.form = formEl;
/* @protected */
this.errors = [];
return this;
};
/**
* Set validation rules to attached form
*
* @param {Object} rules given rules in object literal notation.
* @return {tart.FormValidator} .
* @this {tart.FormValidator} .
*/
tart.FormValidator.prototype.setRules = function(rules) {
this.rules = rules;
return this;
};
/**
* Find element with elementName in given form object
*
* @param {string} elementName name of element which to be find in form.
* @return {Object} jQuery object for given element.
*/
tart.FormValidator.prototype.getFormElementByName = function(elementName) {
var el = this.form.find('input[name=' + elementName + ']');
return el;
};
/**
* Find related element attribute for given input type
*
* @param {Object} el jQuery object of element.
* @return {string} elements value for related input type.
*/
tart.FormValidator.prototype.getElementAttributeToCheck = function(el) {
//TODO: this can vary on elements type such has "attr"
return el.val();
};
/**
* Rule key for tart.Validation
*
* @param {string} ruleKey key of rule.
* @return {Function} elements value for related input type.
*/
tart.FormValidator.prototype.getValidationRuleByKey = function(ruleKey) {
var rule;
//TODO: this swich case should be looked up from an object literal
switch (ruleKey) {
case 'isEmail' : rule = this.validator.is.email; break;
case 'isNotOnlySpace' : rule = this.validator.is.notOnlySpace; break;
case 'isNumeric' : rule = this.validator.is.numeric; break;
case 'isDigitAndNonDigit' : rule = this.validator.is.digitAndNonDigit; break;
case 'hasMaxLength' : rule = this.validator.has.maxLength; break;
case 'hasMinLength' : rule = this.validator.has.minLength; break;
case 'hasMaxValue' : rule = this.validator.has.maxValue; break;
case 'hasMinValue' : rule = this.validator.has.minValue; break;
}
return rule;
};
/**
* Get rule key and rule options from rule object
*
* @param {Object} rule rule object whom key is ruleName and value is rule options.
* @return {Object} object which has .key and .options nodes.
*/
tart.FormValidator.prototype.getRuleKeyAndOptions = function(rule) {
var results = [];
//TODO: there should be a smarter way to do this
for (var i in rule) {
results.push({key: i, options: rule[i]});
}
return results;
};
/**
* Apply rule and generate result in object literal
*
* @param {Object} el jQuery object to rule rule object whom key is ruleName and value is rule options.
* @param {Object} rule rule to be applied to el.
* @return {Object} result object which has .success and .item nodes.
*/
tart.FormValidator.prototype.applyRule = function(el, rule) {
var value = this.getElementAttributeToCheck(el);
var keyAndOptionsArray = this.getRuleKeyAndOptions(rule);
var keyAndOptions,
key,
validationRule,
options,
result,
failed = false;
for (var i = 0; i < keyAndOptionsArray.length; i++) {
keyAndOptions = keyAndOptionsArray[i];
key = keyAndOptions.key;
options = keyAndOptions.options;
validationRule = this.getValidationRuleByKey(key);
result = validationRule(value, options.value);
//return on first error
if (!result) {
break;
}
}
return {success: result, item: {el: el, text: options.text}};
};
/**
* Validate given form object with given rules, if any errors occured this.errors array will be populated
*
* @return {tart.FormValidator} .
*/
tart.FormValidator.prototype.validate = function() {
this.errors = [];
var el,
rule,
result;
for (var i in this.rules) {
el = this.getFormElementByName(i);
rule = this.rules[i];
result = this.applyRule(el, rule);
if (!result.success) {
this.errors.push(result.item);
break;
}
}
return this;
};
/**
* Check if validation operation is successful or not by looking at this.errors array
*
* @return {boolean} validation is successful or not.
*/
tart.FormValidator.prototype.isValid = function() {
if (this.errors.length == 0) {
return true;
}
else {
return false;
}
};
/**
* Get generated errors array which contains element (el) and error text(text)
*
* @return {Array} errors array.
*/
tart.FormValidator.prototype.getErrors = function() {
return this.errors;
};
/**
* Validate form on submit
*
* @param {Function} callback callback function after submit.
*/
tart.FormValidator.prototype.validateOnSubmit = function(callback) {
callback = callback || function() {};
var that = this;
this.form.submit(function(e) {
that.validate();
if (!that.isValid()) { //if an error occured
e.preventDefault();
e.stopImmediatePropagation(); //stop other events propagation
callback(that.getErrors());
}
});
};
================================================
FILE: tart/FormValidator/README.md
================================================
# Tart FormValidator
A JavaScript validation library which validates form elements using tart.Validation
## Testing specs
You need [jasmine](http://pivotal.github.com/jasmine/) to run the specs
You better have [qasmine](https://github.com/tart/qasmine) to automatize the testing process
### How to run qasmine
Simlpy, run
qasmine spec/SpecRunner.html
## Validation checks
* Rules should be written in object literal like this
<pre>
var rules = {
testInput1 : {
isNumeric : {
text : "Input is not numeric"
},
hasMaxLength : {
text : "Input's length is more than 9",
value : 9
},
hasMinLength : {
text : "Input's length is less than 6",
value : 6
}
}
};
</pre>
<pre>
var form = $("form");
var rules = {
testInput1 : {
isNumeric : {
text : "Input is not numeric"
},
hasMaxLength : {
text : "Input's length is more than 9",
value : 9
},
hasMinLength : {
text : "Input's length is less than 6",
value : 6
}
}
};
var validator = new tart.FormValidator(form);
validator.setRules(rules).validate();
if(validator.isValid()) {
//its valid
}
else {
//its not valid, do some stuff with error object
var errors = validator.getErrors();
}
</pre>
### Form bindings
It can also binded before form submit and validation process can be done automatically and
results will be returned to a callback function
================================================
FILE: tart/FormValidator/spec/FormValidatorSpec.js
================================================
goog.require('tart.FormValidator');
goog.provide('tart.FormValidator.SpecRunner');
describe('Form Validator', function() {
var validator,
form,
formFields = [];
beforeEach(function() {
//create mock form object
form = $('<form>');
formFields[0] = $('<input>').attr('name', 'testInput1').appendTo(form);
formFields[1] = $('<input>').attr('name', 'testInput2').appendTo(form);
validator = new tart.FormValidator(form);
});
it('validator should be object', function() {
expect(typeof validator).toEqual('object');
});
describe('Form validator for email', function() {
var ruleErrorText = 'Not a valid email';
var rules = {
'testInput1': {
'isEmail': {
'text': ruleErrorText
}
}
};
it("should validate an input which has 'foo@bar.com' as valid email", function() {
formFields[0].val('foo@bar.com');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate in input which has 'foo@bar.xxxxx' as valid email", function() {
formFields[0].val('foo@bar.xxxxx');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate in input which has 'foo@bar.xxxxx' with text 'Not a valid email'", function() {
formFields[0].val('foo@bar.xxxxx');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
it("should not validate in input which has '' an errr text should be 'Not a valid email'", function() {
formFields[0].val(' ');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator for not only space', function() {
var ruleErrorText = 'You have ve to write at least one char or digit';
var rules = {
'testInput1': {
'isNotOnlySpace': {
'text': ruleErrorText
}
}
};
it("should validate an input which starts with space but has some chars like ' foo bar '", function() {
formFields[0].val(' foo bar ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input which has only spaces like ' '", function() {
formFields[0].val(' ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an empty string ''", function() {
formFields[0].val('');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should return error text 'You have ve to write at least one char or digit' on error", function() {
formFields[0].val('');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator for numeric control', function() {
var ruleErrorText = 'You can type only numbers between 0-9';
var rules = {
'testInput1': {
'isNumeric': {
'text': ruleErrorText
}
}
};
it("should validate an input which has only numbers like '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input which has numbers and space like ' 1234 5'", function() {
formFields[0].val(' 1234 5');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input which has numbers and chars like '12345foo'", function() {
formFields[0].val('12345foo');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate input with text 'You can type only numbers between 0-9' for 'foo12345bar'", function() {
formFields[0].val('foo12345foo');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator for input which contains both digit and non digit char', function() {
var ruleErrorText = 'Your input must contain both digit and non digit char';
var rules = {
'testInput1': {
'isDigitAndNonDigit': {
'text': ruleErrorText
}
}
};
it("should not validate an input which has only numbers like '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input which has only alpha chars 'foobar'", function() {
formFields[0].val('foobar');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input which has only spaces ' '", function() {
formFields[0].val(' ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should validate an input which has both digit and alpha chars 'foo12345bar'", function() {
formFields[0].val('foo12345foo');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should validate an input which has both digit, alpha chars,no nalpha chars 'foo12345bar-_`'", function() {
formFields[0].val('foo12345foo-_`');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should validate an input which has both digit and space chars like '12345 '", function() {
formFields[0].val('12345 ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input which has both alpha and space chars like 'foobar '", function() {
formFields[0].val('foobar ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input which has non alpha chars and space chars like '~-? '", function() {
formFields[0].val('~-? ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should return text 'Your input must contain both digit and non digit char' for invalid input", function() {
formFields[0].val('~-? ');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator to check inputs max length', function() {
var ruleErrorText = 'Your inputs lenght is more than 7';
var rules = {
'testInput1': {
'hasMaxLength': {
'text': ruleErrorText,
'value': 7
}
}
};
it("should validate an input like '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input like '12345 '", function() {
formFields[0].val('12345 ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input like ' '", function() {
formFields[0].val(' ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should validate an input like '123 5 7'", function() {
formFields[0].val('123 5 7');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should return 'Your inputs lenght is more than 7' text on error", function() {
formFields[0].val('123 5 7 foo bar');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator to check inputs min length', function() {
var ruleErrorText = 'Your inputs lenght is less than 3';
var rules = {
'testInput1': {
'hasMinLength': {
'text': ruleErrorText,
'value': 3
}
}
};
it("should validate an input like '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input like '12'", function() {
formFields[0].val('12');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input like ' '", function() {
formFields[0].val(' ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should validate an input like '1 '", function() {
formFields[0].val('1 ');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should return 'Your inputs lenght is less than 3' text on error", function() {
formFields[0].val('12');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe("Form validator to check input's numeric value", function() {
var ruleErrorText = 'Your inputs value is more than 10';
var rules = {
'testInput1': {
'hasMaxValue': {
'text': ruleErrorText,
'value': 10
}
}
};
it("should validate an input like '1'", function() {
formFields[0].val('1');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input like '12'", function() {
formFields[0].val('12');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should return 'Your inputs value is more than 10' text on error", function() {
formFields[0].val('12');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe("Form validator to check input's numeric value", function() {
var ruleErrorText = 'Your inputs value is less than 10';
var rules = {
'testInput1': {
'hasMinValue': {
'text': ruleErrorText,
'value': 10
}
}
};
it("should not validate an input like '1'", function() {
formFields[0].val('1');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should validate an input like '12'", function() {
formFields[0].val('12');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should return 'Your inputs value is less than 10' text on error", function() {
formFields[0].val('1');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual(ruleErrorText);
});
});
describe('Form validator for multiple rules', function() {
var rules = {
'testInput1': {
'isNumeric': {
'text': 'Input is not numeric'
},
'hasMaxLength': {
'text': "Input's length is more than 9",
'value': 9
},
'hasMinLength': {
'text': "Input's length is less than 6",
'value': 6
}
}
};
it("should not validate an input like 'fooobar'", function() {
formFields[0].val('fooobar');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should validate an input like '123456'", function() {
formFields[0].val('123456');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeTruthy();
});
it("should not validate an input like '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("should not validate an input like '12345678910'", function() {
formFields[0].val('12345678910');
validator.setRules(rules).validate();
expect(validator.isValid()).toBeFalsy();
});
it("error text should be 'Input is not numeric' for 'foobar'", function() {
formFields[0].val('foobar');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual('Input is not numeric');
});
it("error text should be 'Input\'s length is more than 9' for '1234567890'", function() {
formFields[0].val('1234567890');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual("Input's length is more than 9");
});
it("error text should be 'Input\'s length is less than 6' for '12345'", function() {
formFields[0].val('12345');
validator.setRules(rules).validate();
var errorText = validator.getErrors()[0].text;
expect(errorText).toEqual("Input's length is less than 6");
});
});
describe("Form validate validates form before form's submit", function() {
var rules = {
'testInput1': {
'isNumeric': {
'text': 'Input is not numeric'
},
'hasMaxLength': {
'text': "Input's length is more than 9",
'value': 9
},
'hasMinLength': {
'text': "Input's length is less than 6",
'value': 6
}
}
};
it('should validate form on submit and return generated errors in callback', function() {
formFields[0].val('foobar');
var errorObjects;
validator.setRules(rules).validateOnSubmit(function(errors) {
errorObjects = errors;
});
form.trigger('submit');
expect(errorObjects[0].el.get(0)).toEqual(formFields[0].get(0));
expect(errorObjects[0].text).toEqual('Input is not numeric');
});
});
});
/**
* Run jasmine spec
*/
tart.FormValidator.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/FormValidator/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript" src="../../Validation/Validation.js"></script>
<script type="text/javascript" src="../FormValidator.js"></script>
</head>
<body>
<script type="text/javascript" src="FormValidatorSpec.js"></script>
</body>
</html>
================================================
FILE: tart/List.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.List to handle List typed data structures extended from tart.Collection.
*/
goog.provide('tart.List');
goog.require('tart.Collection');
/**
* List data structure
*
* @extends {tart.Collection}
* @constructor
*/
tart.List = function() {
goog.base(this);
/** @private **/
this.keyCount_ = 0;
};
goog.inherits(tart.List, tart.Collection);
/**
* Adds a new item to list .
*
* @param {*} value Value for the pair.
* @return {boolean} .
*/
tart.List.prototype.addItem = function(value) {
return tart.Collection.prototype.addItem.call(this, this.keyCount_++, value);
};
================================================
FILE: tart/Pagination/CircularPagination.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.require('tart.Pagination');
goog.provide('tart.CircularPagination');
/**
* CircularPagination class to handle circular paging events
*
* @constructor
* @extends {tart.Pagination}
*/
tart.CircularPagination = function() {
goog.base(this);
};
goog.inherits(tart.CircularPagination, tart.Pagination);
/**
* Overriding tart.Pagination's hasPrev method, to return true for all conditions to make circular pages.
*
* @override
* @return {boolean} Whether previous page is available .
*/
tart.CircularPagination.prototype.hasPrev = function() {
return true;
};
/**
* Overriding tart.Pagination's hasNext method, to return true for all conditions to make circular pages.
*
* @override
* @return {boolean} Whether next page is available .
*/
tart.CircularPagination.prototype.hasNext = function() {
return true;
};
/**
* @override
*/
tart.CircularPagination.prototype.getNext = function() {
return this.currentPage == this.getTotalPage() ? 1 : this.currentPage + 1;
};
/**
* @override
*/
tart.CircularPagination.prototype.getPrev = function() {
return this.currentPage == 1 ? this.getTotalPage() : this.currentPage - 1;
};
/**
* @override
*/
tart.CircularPagination.prototype.setCurrentPage = function(page) {
if (this.getTotalItems() > this.getItemPerPage()) {
var oldValue = this.currentPage;
this.currentPage = page;
this.triggerPageChange_(oldValue, page);
}
return this;
};
================================================
FILE: tart/Pagination/Pagination.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.Pagination is an event driven Pagination object.
*
* Example usage:
*
* var paginator = new tart.Pagination();
*
* paginator.setTotalPage(5);
* paginator.setCurrentPage(2);
*
* goog.events.listen(paginator, tart.Pagination.EventTypes.PAGE_CHANGED, function (e) {
* console.log("page changed");
* console.log("old page : " + e.oldValue);
* console.log("new page : " + e.newValue);
* });
*
* paginator.setCurrentPage(4); // oldPage : 2, newPage : 4
* paginator.setCurrentPage(7); // oldPage : 4, newpage : 5 (totalPage)
* paginator.prev(); // oldPage : 5, newPage: 4
* paginator.setCurrentPage(0); // oldPage : 4, newpage : 1 (at least 1)
* paginator.next(); // oldPage : 1, newPage : 2
*
*/
goog.require('goog.debug.ErrorHandler');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
goog.provide('tart.Pagination');
/**
* Pagination class to handle all paging events
*
* @constructor
* @extends {goog.events.EventTarget}
*/
tart.Pagination = function() {
goog.events.EventTarget.call(this);
/** @private */
this.totalPage_ = 1;
/** @protected */
this.currentPage = 1;
/** @private */
this.itemPerPage_ = 1;
/** @private */
this.totalItems_ = 1;
};
goog.inherits(tart.Pagination, goog.events.EventTarget);
/**
* Event types enumaration
*
* @enum {string}
*/
tart.Pagination.EventTypes = {
PAGE_CHANGED: 'pageChanged'
};
/**
* Trigger page change event
*
* @param {string|number} oldValue old page value.
* @param {string|number} newValue new page value.
* @protected
*/
tart.Pagination.prototype.triggerPageChange_ = function(oldValue, newValue) {
if (oldValue != newValue)
this.dispatchEvent({type: tart.Pagination.EventTypes.PAGE_CHANGED, oldValue: oldValue, newValue: newValue});
};
/**
* Get total page count
*
* @return {number} page count.
*/
tart.Pagination.prototype.getTotalPage = function() {
return this.totalPage_;
};
/**
* Set total page count
*
* @param {number} page page count.
* @return {tart.Pagination} .
*/
tart.Pagination.prototype.setTotalPage = function(page) {
this.totalPage_ = page;
this.totalItems_ = page * this.itemPerPage_;
return this;
};
/**
* Get current page
*
* @return {number} current page.
*/
tart.Pagination.prototype.getCurrentPage = function() {
return this.currentPage;
};
/**
* Set current page
*
* @param {number} page current page.
* @return {tart.Pagination} .
*/
tart.Pagination.prototype.setCurrentPage = function(page) {
var oldValue = this.currentPage;
//if page > totalPage
page = (page > this.totalPage_) ? this.totalPage_ : page;
//if page < 1
page = (page < 1) ? 1 : page;
this.currentPage = page;
this.triggerPageChange_(oldValue, page);
return this;
};
/**
* Get total item count
*
* @return {number} number of items.
*/
tart.Pagination.prototype.getTotalItems = function() {
return this.totalItems_;
};
/**
* Set number of items
*
* @param {number} itemCount number of items.
* @return {tart.Pagination} .
*/
tart.Pagination.prototype.setTotalItems = function(itemCount) {
this.totalItems_ = itemCount;
this.totalPage_ = Math.ceil(itemCount / this.itemPerPage_);
return this;
};
/**
* Get number of items to be listed in a page
*
* @return {number} number of items in a page.
*/
tart.Pagination.prototype.getItemPerPage = function() {
return this.itemPerPage_;
};
/**
* set number of items to be listed in a page
*
* @param {number} itemPerPage number of items in a page.
* @return {tart.Pagination} .
*/
tart.Pagination.prototype.setItemPerPage = function(itemPerPage) {
this.itemPerPage_ = itemPerPage;
return this;
};
/**
* Determine if next page is available
*
* @return {boolean} is next page available.
*/
tart.Pagination.prototype.hasNext = function() {
return this.currentPage + 1 <= this.totalPage_;
};
/**
* Get next page
*
* @return {number} next page number.
*/
tart.Pagination.prototype.getNext = function() {
return this.hasNext() ? this.currentPage + 1 : this.currentPage;
};
/**
* Determine if previous page is available
*
* @return {boolean} is previous page available.
*/
tart.Pagination.prototype.hasPrev = function() {
return this.currentPage - 1 >= 1;
};
/**
* Get previous page
*
* @return {number} previous page number.
*/
tart.Pagination.prototype.getPrev = function() {
return this.hasPrev() ? this.currentPage - 1 : this.currentPage;
};
/**
* Change page to next page
*/
tart.Pagination.prototype.next = function() {
var oldValue = this.currentPage;
this.currentPage = this.getNext();
this.triggerPageChange_(oldValue, this.currentPage);
};
/**
* Change page to previous page
*/
tart.Pagination.prototype.prev = function() {
var oldValue = this.currentPage;
this.currentPage = this.getPrev();
this.triggerPageChange_(oldValue, this.currentPage);
};
================================================
FILE: tart/Pagination/spec/PaginationSpec.js
================================================
goog.require('tart.Pagination');
goog.provide('tart.Pagination.SpecRunner');
describe('Pagination', function() {
var paginator;
beforeEach(function() {
paginator = new tart.Pagination();
});
describe('should contain required parameters', function() {
it('should have totalPage', function() {
expect(paginator.getTotalPage()).toBeGreaterThan(0);
});
it('should have currentPage', function() {
expect(paginator.getCurrentPage()).toBeGreaterThan(0);
});
it('should have itemPerPage', function() {
expect(paginator.getItemPerPage()).toBeGreaterThan(0);
});
it('should have totalItems', function() {
expect(paginator.getTotalItems()).toBeGreaterThan(0);
});
it('should set totalPage', function() {
paginator.setTotalPage(5);
expect(paginator.getTotalPage()).toEqual(5);
});
it('should set currentPage', function() {
paginator.setTotalPage(5);
paginator.setCurrentPage(5);
expect(paginator.getCurrentPage()).toEqual(5);
});
it('should set itemPerPage', function() {
paginator.setItemPerPage(2);
expect(paginator.getItemPerPage()).toEqual(2);
});
it('should set totalItems', function() {
paginator.setTotalItems(2);
expect(paginator.getTotalItems()).toEqual(2);
});
it('should change page count when totalItem count set', function() {
paginator.setItemPerPage(2);
paginator.setTotalItems(5);
expect(paginator.getTotalPage()).toEqual(3);
});
it('should change item count when totalPage count set', function() {
paginator.setItemPerPage(2);
paginator.setTotalPage(4);
expect(paginator.getTotalItems()).toEqual(8);
});
it('should set page count to totalPageCount if page > totalPageCount', function() {
paginator.setTotalPage(5);
paginator.setCurrentPage(6);
expect(paginator.getCurrentPage()).toEqual(5);
});
it('should set page count to 1 if page < 1', function() {
paginator.setTotalPage(5);
paginator.setCurrentPage(0);
expect(paginator.getCurrentPage()).toEqual(1);
});
});
describe('controls navigation', function() {
it('should have a next element if currentPage < totalPage', function() {
paginator.setCurrentPage(3);
paginator.setTotalPage(4);
expect(paginator.hasNext()).toBeTruthy();
});
it('should not have a next element if currentPage >= totalPage', function() {
paginator.setTotalPage(4).setCurrentPage(4);
paginator.setTotalPage(4);
expect(paginator.hasNext()).toBeFalsy();
});
it('should have a previous element if currentPage > 1', function() {
paginator.setTotalPage(4).setCurrentPage(2);
expect(paginator.hasPrev()).toBeTruthy();
});
it('should not have a next element if currentPage <= 1', function() {
paginator.setCurrentPage(1);
paginator.setTotalPage(4);
expect(paginator.hasPrev()).toBeFalsy();
});
});
describe('triggers pageChanged event on some conditions', function() {
it('should trigger event on setCurrentPage', function() {
var triggeredObject = {};
goog.events.listen(paginator, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
triggeredObject = e;
});
paginator.setCurrentPage(10);
//check if newValue and oldValue exists
expect(triggeredObject.oldValue && triggeredObject.newValue).toBeTruthy();
});
it('should trigger event on next()', function() {
paginator.setTotalPage(12);
paginator.setCurrentPage(10);
var triggeredObject = {};
goog.events.listen(paginator, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
triggeredObject = e;
});
paginator.next();
//check if newValue and oldValue exists
expect(triggeredObject.oldValue && triggeredObject.newValue).toBeTruthy();
});
it('should trigger event on prev()', function() {
paginator.setTotalPage(12);
paginator.setCurrentPage(10);
var triggeredObject = {};
goog.events.listen(paginator, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
triggeredObject = e;
});
paginator.prev();
//check if newValue and oldValue exists
expect(triggeredObject.oldValue && triggeredObject.newValue).toBeTruthy();
});
});
});
/**
* Run jasmine spec
*/
tart.Pagination.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/Pagination/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript">
goog.require("goog.events.EventTarget");
</script>
<script type="text/javascript" src="../Pagination.js"></script>
</head>
<body>
<!-- include spec files here... -->
<script type="text/javascript" src="PaginationSpec.js"></script>
</body>
</html>
================================================
FILE: tart/Registry.js
================================================
// Copyright (c) 2009-2010 Techinox Information Technologies (http://www.techinox.com)
// Techinox Commercial License
//
// @author Armagan Amcalar <armagan@tart.com.tr>
/**
* @fileoverview tart.Registry is a convenience class that wraps goog.structs.Map and is intended to use as
* a global registry across a web application.
*/
goog.provide('tart.Registry');
goog.require('goog.structs.Map');
/**
* tart Registry class.
* @constructor
* @extends {goog.structs.Map}
*/
tart.Registry = function() {
goog.base(this);
};
goog.inherits(tart.Registry, goog.structs.Map);
================================================
FILE: tart/StateMachine/State.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview State class is used in conjunction with tart.StateMachine. It is a value object that holds two
* properties; a function that is executed when the state machine is in this state, and a transitions object for
* events that may happen in this state.
*/
goog.provide('tart.State');
/**
* Tart State class for state machines.
* @constructor
* @param {function()} fn The state function to be executed.
*/
tart.State = function(fn) {
this.fn = fn;
this.transitions = {};
};
================================================
FILE: tart/StateMachine/StateMachine.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview This class is an implementation of a Moore state machine that is common in digital electronics, etc.
*
* The state machine is by it's nature an event-driven system. Events that come at the right state will put the state
* machine in another expected state.
*
* To keep the implementation simple, many details are omitted. The state machine doesn't keep a record of its
* states, new states cannot be added after a state machine is started, etc. These rules do not prevent
* the functioning of the machine though.
*
* This class is a base class and not intended to be used on its own. To use a state machine, the developer has to
* subclass this base class and override the <code>createStates_</code> method. This method should hold the
* initialization of states in the state machine and should return the first state the machine should begin with.
*
* This implementation features lazy loading in the sense that the <code>createStates_</code> method is not called
* until the first call to <code>startMachine</code> method.
*
* Example usage:
*
* Foo.MooreMachine = function(){
* goog.base(this);
* }
* goog.inherits(Foo.MooreMachine, tart.StateMachine);
*
* // Having an enumerated type for events helps readability
* Foo.MooreMachine.Events = {
* CLICK: '0',
* DOUBLECLICK: '1'
* }
*
* Foo.MooreMachine.prototype.createStates_ = function(){
* var STATE1 = new tart.State(function(){
* console.log("state 1");
* });
*
* var STATE2 = new tart.State(function(){
* console.log("state 2");
* });
*
* STATE1.transitions[Foo.MooreMachine.Events.CLICK] = STATE2;
* STATE2.transitions[Foo.MooreMachine.Events.DOUBLECLICK] = STATE1;
*
* this.addState_(STATE1);
* this.addState_(STATE2);
*
* return STATE1;
* }
*
* var myMachine = new Foo.MooreMachine();
* myMachine.startMachine();
*
*/
goog.require('goog.array');
goog.require('goog.pubsub.PubSub');
goog.require('tart.State');
goog.provide('tart.StateMachine');
/**
* Tart State Machine Class
* @constructor
* @extends {goog.pubsub.PubSub}
*/
tart.StateMachine = function() {
goog.base(this);
/**
* @type {Array.<string>}
* @private
*/
this.events_ = [];
this.currentState = undefined;
};
goog.inherits(tart.StateMachine, goog.pubsub.PubSub);
/**
* Adds a state to the state machine.
* @param {tart.State} state State to be added.
* @protected
*/
tart.StateMachine.prototype.addState = function(state) {
for (var event in state.transitions) {
goog.array.insert(this.events_, event);
}
};
/**
* Sets the current state disregarding the previous one, and executes it's function.
* @param {tart.State} state State to be set as the current state.
* @param {Array.<*>=} opt_args Arguments to pass to the new state.
* @protected
*/
tart.StateMachine.prototype.setCurrentState = function(state, opt_args) {
opt_args = opt_args || [];
this.currentState = state;
this.currentState.fn.apply(this, opt_args);
};
/**
* Starts the state machine. If it's the first time this function is called, it also lazy loads the states via
* <code>createStates</code> method.
*/
tart.StateMachine.prototype.startMachine = function() {
if (this.currentState == undefined) {
this.firstState = this.createStates();
this.bindEvents_();
this.setCurrentState(this.firstState);
}
};
tart.StateMachine.prototype.reset = function() {
this.firstState && this.setCurrentState(this.firstState);
};
/**
* This should be overridden by child classes. It holds the initialization of states and is called when the
* <code>startMachine</code> method is called for the first time.
* @return {tart.State} The first state that the machine will start with.
*/
tart.StateMachine.prototype.createStates = goog.abstractMethod;
/**
* Subscribes its <code>handleEvent_</code> function to its every event
* @private
*/
tart.StateMachine.prototype.bindEvents_ = function() {
var self = this;
for (var i = 0, l = self.events_.length; i < l; i++) {
var eventName = self.events_[i];
self.subscribe(eventName, self.handleEvent_(self, eventName));
}
};
/**
* Handles incoming events. If any of the events are in the transitions list for the current state, that transition's
* target state becomes the current state.
* @param {tart.StateMachine} self The State Machine instance (due to the nature of goog.pubsub.PubSub.subscribe,
* this function loses its scope. This variable corrects it).
* @param {string} event The event to handle.
* @return {function()} Returns a closure to use as an eventHandler.
* @private
*/
tart.StateMachine.prototype.handleEvent_ = function(self, event) {
return function() {
var nextState = self.currentState.transitions[event];
if (nextState) {
self.setCurrentState(nextState, Array.prototype.slice.call(arguments));
}
}
};
================================================
FILE: tart/Tabs/TabPanel.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Creates an instance with a tab and panel for using with an existing tabpanel.
*
* Example Usage:
*
* var panel1 = new tart.TabPanel({
* title: 'Tab 1',
* html: 'This is a basic text'
* });
*
*/
goog.provide('tart.TabPanel');
goog.require('goog.pubsub.PubSub');
/**
* Returns an instance of tab and panel for using it in an tabpanel
* Options object should include a title as tab's title and html as panel's default html
* If Options object is ommited, an empty string will appended as tab title and panel html
* @constructor
* @extends {goog.pubsub.PubSub}
* @param {Object=} options Customized options for panel instance.
*/
tart.TabPanel = function(options) {
goog.base(this);
this.initOptions(options);
this.$tab = $(this.templates_tab());
this.$panel = $(this.templates_panel());
};
goog.inherits(tart.TabPanel, goog.pubsub.PubSub);
/**
* Merges custom options object with defaults
* @protected
* @param {Object=} options Custom config object.
*/
tart.TabPanel.prototype.initOptions = function(options) {
this.props = {};
options = options || {};
this.props.panelCssClass = options['panelCssClass'] || '';
this.props.tabCssClass = options['tabCssClass'] || '';
this.props.title = options.title || '';
this.props.html = options.html || '';
};
/**
* @return {string} Tab markup.
*/
tart.TabPanel.prototype.templates_tab = function() {
return '<div class="tartTab ' + this.props.tabCssClass + '">' + this.props.title + '</div>';
};
/**
* @return {string} Panel markup.
*/
tart.TabPanel.prototype.templates_panel = function() {
return '<div class="tartPanel ' + this.props.panelCssClass + '">' + this.props.html + '</div>';
};
/**
* Callback function that will be triggered before a TabPanel instance is shown.
* @type {Function|undefined}
*/
tart.TabPanel.prototype.onShow = undefined;
/**
* Callback function that will be triggered before a TabPanel instance is shown.
* @type {Function|undefined}
*/
tart.TabPanel.prototype.onClose = undefined;
================================================
FILE: tart/Tabs/Tabs.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Tabs is a fully working and customizable tab panel creator class.
*
* Example Usage:
*
*
* var tabPanel = new tart.Tabs({
* activeTab: 1
* });
*
* var panel1 = new tart.TabPanel({
* title: 'Tab 1',
* html: 'This is a basic text'
* });
* var panel2 = new tart.TabPanel({
* title: 'Tab 2',
* html: 'Lorem ipsum dolor sit amet'
* });
* var panel3 = new tart.TabPanel({
* title: 'Tab 3',
* html: 'Lorem ipsum dolor sit amet is a dummy text'
* });
*
* tabPanel.addTabPanel(panel1);
* tabPanel.addTabPanel(panel2);
* tabPanel.addTabPanel(panel3);
*
* var dom = tabPanel.buildDOM();
* $('body').append(dom);
*
*/
goog.provide('tart.Tabs');
goog.require('goog.pubsub.PubSub');
goog.require('tart.TabPanel');
/**
* Tabs is a fully working and customizable tab panel creator class
* @constructor
* @param {Object=} options Customized initial options for tabpanel.
* @extends {goog.pubsub.PubSub}
*/
tart.Tabs = function(options) {
goog.base(this);
options = options || {};
this.initOptions(options);
this.$tabContainer = $(this.templates_tabContainer());
this.$panelContainer = $(this.templates_panelContainer());
/**
* Holds TabPanel objects associated with the tabpanel
* @type {Array.<tart.TabPanel>}
* @protected
*/
this.tabPanels = [];
/**
* State of tab panel
* @protected
*/
this.rendered = false;
this.initialize(this.props.renderConfig);
};
goog.inherits(tart.Tabs, goog.pubsub.PubSub);
/**
* Initialize the tabpanel with calling buildDOM method
* @param {!string} renderCfg Where to container will be appended.
*/
tart.Tabs.prototype.initialize = function(renderCfg) {
var panelDOM = this.buildDOM();
if (renderCfg.insertAfter) {
panelDOM.insertAfter(renderCfg.insertAfter);
}
else if (renderCfg.insertBefore) {
panelDOM.insertBefore(renderCfg.insertBefore);
}
else if (renderCfg.append) {
renderCfg.append.append(panelDOM);
}
};
/**
* Adds new tab to existing tab panel
* @param {!(Array|tart.TabPanel)} tabPanels An array that holds instance of TabPanel Class to add new tab.
* Also tabPanels argument should be a tab panel instance instead of array.
*/
tart.Tabs.prototype.addTabPanel = function(tabPanels) {
var that = this;
if (goog.isArray(tabPanels)) {
for (var i = 0, len = tabPanels.length; i < len; i++) {
that.addTab(tabPanels[i]);
}
} else {
that.addTab(tabPanels);
}
this.setActiveTab(this.activeTab);
};
/**
* Adds a new tab to a Tabs instance.
* @param {tart.TabPanel} tabPanel instance that's going to be added to a Tabs instance.
*/
tart.Tabs.prototype.addTab = function(tabPanel) {
this.tabPanels.push(tabPanel);
this.$tabContainer.append(tabPanel.$tab);
this.$panelContainer.append(tabPanel.$panel);
this.bindTabPanelEvents(tabPanel);
};
/**
* Removes the tab with the given index.
* @param {!number} index Index number of the tab that you want to remove.
*/
tart.Tabs.prototype.removeTab = function(index) {
var tabsLength = this.getTabsLength();
if (index >= tabsLength || tabsLength === 0) {
return;
}
this.tabPanels[index].$tab.remove();
this.tabPanels[index].$panel.remove();
this.tabPanels.splice(index, 1);
try {
if (index <= this.activeTab) {
if (index === this.activeTab) {
this.setActiveTab(index - 1);
} else {
this.setActiveTab(this.activeTab - 1);
}
}
} catch (e) {}
};
/**
* Sets the tab as active with the given index.
* @param {!number} index Index number of the tab that you want to set as active.
*/
tart.Tabs.prototype.setActiveTab = function(index) {
if (index >= this.getTabsLength()) {
return false;
}
var deActivatedTab = this.getActiveTab();
for (var i = 0, len = this.tabPanels.length; i < len; i++) {
if (index != i) {
this.tabPanels[i].$tab.removeClass(this.props.activeTabCssClass);
this.tabPanels[i].$panel.removeClass(this.props.activePanelCssClass);
}
}
this.tabPanels[index].$tab.addClass(this.props.activeTabCssClass);
this.tabPanels[index].$panel.addClass(this.props.activePanelCssClass);
this.activeTab = index;
var newlyActivatedTab = this.getActiveTab();
if (deActivatedTab.onClose && deActivatedTab != newlyActivatedTab) /* prevent double fn call on initialize */
deActivatedTab.onClose(this);
newlyActivatedTab.onShow && newlyActivatedTab.onShow(this); // call newly activated tab's onShow function
this.publish('tabChange', this.getActiveTab(), this);
};
/**
* Returns the active tab object contains tab and panel elements and templates that used in tab and panel.
* @return {tart.TabPanel} The active tab.
*/
tart.Tabs.prototype.getActiveTab = function() {
return this.tabPanels[this.activeTab];
};
/**
* Binds required events of tabpanel.
* @param {!tart.TabPanel} tabPanel Tabpanel instance for binding events to it.
*/
tart.Tabs.prototype.bindTabPanelEvents = function(tabPanel) {
var that = this;
var setMeActive = function() {
var myIndex = goog.array.indexOf(that.tabPanels, tabPanel);
that.setActiveTab(myIndex);
};
tabPanel.$tab.click(setMeActive);
};
/**
* Builds DOM elements for tabpanel and returns DOM as ready to append to a container
* @return {jQueryObject} DOM element of the Tabs instance.
*/
tart.Tabs.prototype.buildDOM = function() {
this.$dom = $(this.templates_dom());
this.$dom.append(this.$tabContainer);
this.$dom.append(this.$panelContainer);
this.rendered = true;
return this.$dom;
};
/**
* @return {boolean} The status of tabpanel, rendered or not.
*/
tart.Tabs.prototype.isRendered = function() {
return this.rendered;
};
/**
* @return {number} number of tabs associated with the Tabs instance.
*/
tart.Tabs.prototype.getTabsLength = function() {
return this.tabPanels.length;
};
/**
* Merges custom options object with defaults
* @protected
* @param {Object=} options Customized options for Tabs instance.
*/
tart.Tabs.prototype.initOptions = function(options) {
var props = this.props = {};
props.axis = options.axis || 'x';
this.activeTab = options.activeTab || 0;
props.renderConfig = options.renderConfig || {};
props.tabPanelCssClass = options.tabPanelCssClass || '';
props.tabContainerCssClass = options.tabContainerCssClass || '';
props.panelContainerCssClass = options.panelContainerCssClass || '';
props.activeTabCssClass = options.activeTabCssClass || 'tartActiveTab';
props.activePanelCssClass = options.activePanelCssClass || 'tartActivePanel';
props.panelWrapperCssClass = options.panelWrapperCssClass || '';
};
/**
* @return {string} Main container markup.
*/
tart.Tabs.prototype.templates_dom = function() {
return '<div class="tartTabPanelContainer ' + this.props.tabPanelCssClass + '"></div>';
};
/**
* @return {string} Tab container markup.
*/
tart.Tabs.prototype.templates_tabContainer = function() {
return '<div class="tartTabContainer ' + this.props.tabContainerCssClass + '"></div>';
};
/**
* @return {string} Panel container markup.
*/
tart.Tabs.prototype.templates_panelContainer = function() {
return '<div class="tartPanelContainer ' + this.props.panelContainerCssClass + '"></div>';
};
================================================
FILE: tart/Validation/README.md
================================================
# Tart Validator
A JavaScript validation library
## Testing specs
You need [jasmine](http://pivotal.github.com/jasmine/) to run the specs
You better have [qasmine](https://github.com/tart/qasmine) to automatize the testing process
### How to run qasmine
Simlpy, run
qasmine spec/SpecRunner.html
## Validation checks
* is.email(string) : Checks string as a valid email
* is.notOnlySpace(string) : Checks string that it doesnt contains only from whitespaces
* is.numeric(string) : Checks string that only contains numeric values
* is.digitAndNonDigit(string) : Checks string which contains both digits and non-digit chars, can be useful to check passwords' strength
* has.maxLength(string, value) : Checks string for max length
* has.minlength(string, value) : Checks string for min length
* has.minValue(number, value) : Cheks number for its min value
* has.maxValue(number, value) : Cheks number for its max value
================================================
FILE: tart/Validation/Validation.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.Validation is a validation library which checks for variable's format (such as email, number) or
* attribute (such as char length).
*
* Example usage:
*
* var validator = tart.Validation;
* var isValidEmail = validator.is.email("foo@bar.com"); //returns boolean true
* var isNumeric = validator.is.numeric("123foo"); // returns boolean false
* var hasMaxLength10 = validator.has.maxLength("foobar", 10); //returns boolean true
*
*
* More examples can be seen from spec/ValidationSpec.js file
*/
goog.provide('tart.Validation');
goog.provide('tart.Validation.has');
goog.provide('tart.Validation.is');
/**
* Checks if given text is valid email
*
* @param {string} text email text to be validated.
* @return {boolean} true if its valid email.
*/
tart.Validation.is.email = function(text) {
var pattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
return pattern.test(text);
};
/**
* Checks if a value is true.
*
* @param {boolean} value value to check.
* @return {boolean} true if value evaluates to true.
*/
tart.Validation.is.truthy = function(value) {
return value == true;
};
/**
* Checks if given text doesnt contains only white spaces but some chars or numbers
*
* @param {string} text text to be validated.
* @return {boolean} true if text contains any char or number.
*/
tart.Validation.is.notOnlySpace = function(text) {
var result = text.replace(/^\s+|\s+$/g, '').length > 0;
return result;
};
/**
* Checks if given text contains only numeric chars
*
* @param {string} text text to be validated.
* @return {boolean} true if text contains only numbers.
*/
tart.Validation.is.numeric = function(text) {
var pattern = /^[0-9]+$/;
return pattern.test(text);
};
/**
* Checks if given text contains both digit and non-digit chars
*
* @param {string} text text to be validated.
* @return {boolean} true if text contains both digit and non-digit chars.
*/
tart.Validation.is.digitAndNonDigit = function(text) {
var pattern = /(\d\D)|(\D\d)/;
return pattern.test(text);
};
/**
* Checks if both given arguments are equal
*
* @param {*} arg1 item to be validated.
* @param {*} arg2 item to be validated.
* @return {boolean} true if both arguments are equal.
*/
tart.Validation.is.equal = function(arg1, arg2) {
return arg1 == arg2;
};
/**
* Checks for strings' min length
*
* @param {string} text string to check for char length.
* @param {number} value char length value.
* @return {boolean} true if string's length > value.
*/
tart.Validation.has.minLength = function(text, value) {
return (text.length >= value);
};
/**
* Checks for string's max length
*
* @param {string} text string to check for char length.
* @param {number} value char length value.
* @return {boolean} true if string's length < value.
*/
tart.Validation.has.maxLength = function(text, value) {
return (text.length <= value);
};
/**
* Checks for string or number's min numeric value
*
* @param {string|number} num number to check value for.
* @param {number} value value to check.
* @return {boolean} true if string's num < value.
*/
tart.Validation.has.minValue = function(num, value) {
return num >= value;
};
/**
* Checks for string or number's max numeric value
*
* @param {string|number} num number to check value for.
* @param {number} value value to check.
* @return {boolean} true if string's num > value.
*/
tart.Validation.has.maxValue = function(num, value) {
return num <= value;
};
================================================
FILE: tart/Validation/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript" src="../Validation.js"></script>
</head>
<body>
<script type="text/javascript" src="ValidationSpec.js"></script>
</body>
</html>
================================================
FILE: tart/Validation/spec/ValidationSpec.js
================================================
goog.require('tart.Validation');
goog.provide('tart.Validation.SpecRunner');
describe('Validation', function() {
var validator;
beforeEach(function() {
validator = tart.Validation;
});
it('validator should be object', function() {
expect(typeof validator).toEqual('object');
});
describe('Validation.is', function() {
describe('Validation.is.email', function() {
it('regular email like alnum1@alnum2.tld should pass', function() {
var result = validator.is.email('alnum1@alnum2.tld');
expect(result).toBeTruthy();
});
it('should not validate an email which has alnum1@alnum2.tldmorethan4chars', function() {
var result = validator.is.email('alnum1@alnum2.tldmorethan4chars');
expect(result).toBeFalsy();
});
it('should not validate an email which containts non@alhanümeric.çars ', function() {
var result = validator.is.email('non@alhanümeric.çars');
expect(result).toBeFalsy();
});
it('should validate an email which belongs@to.a.sub.dom.ain', function() {
var result = validator.is.email('belongs@to.a.sub.dom.ain');
expect(result).toBeTruthy();
});
it('should not validate email which contains@space.com', function() {
var result = validator.is.email('which contains@space.com');
expect(result).toBeFalsy();
});
});
describe('Validation.is.notOnlySpace', function() {
it('should not validate an input which has only white space', function() {
var result = validator.is.notOnlySpace(' ');
expect(result).toBeFalsy();
});
it('should validate an input which starts with whitespace but has other chars', function() {
var result = validator.is.notOnlySpace(' foobar');
expect(result).toBeTruthy();
});
it('should validate an input which starts and ends with whitespace but has other chars', function() {
var result = validator.is.notOnlySpace(' foobar ');
expect(result).toBeTruthy();
});
});
describe('Validation.is.numeric', function() {
it('should not validate text which has non numeric chars', function() {
var result = validator.is.numeric('foo123bar');
expect(result).toBeFalsy();
});
it('should not validate text which starts with numeric but has non numeric chars', function() {
var result = validator.is.numeric('123bar');
expect(result).toBeFalsy();
});
it('should not validate text which starts with space but has only numeric chars', function() {
var result = validator.is.numeric(' 123');
expect(result).toBeFalsy();
});
it('should validate text which has only numeric chars', function() {
var result = validator.is.numeric('123');
expect(result).toBeTruthy();
});
});
//TODO: add more tests
describe('Validation.is.equal', function() {
it('should validate same strings', function () {
var result = validator.is.equal("osman", "osman");
expect(result).toBeTruthy();
});
it('should validate same numbers', function () {
var result = validator.is.equal(1453, 1453);
expect(result).toBeTruthy();
});
it('should validate numeric strings', function () {
var result = validator.is.equal("1453", 1453);
expect(result).toBeTruthy();
});
it('should validate empty strings', function () {
var result = validator.is.equal("", "");
expect(result).toBeTruthy();
});
it('should validate falsy values', function () {
var result = validator.is.equal("", false);
expect(result).toBeTruthy();
});
it('should not validate falsy values with null', function () {
var result = validator.is.equal(null, false);
expect(result).toBeFalsy();
});
});
describe('Validation.is.digitAndNonDigit', function() {
it('should not validate text which has chars but numbers', function() {
var result = validator.is.digitAndNonDigit('foobar');
expect(result).toBeFalsy();
});
it('should not validate text which has chars only numbers', function() {
var result = validator.is.digitAndNonDigit('1234');
expect(result).toBeFalsy();
});
it('should not validate text which has only whitespaces', function() {
var result = validator.is.digitAndNonDigit(' ');
expect(result).toBeFalsy();
});
it('should validate text which contains both numbers and chars', function() {
var result = validator.is.digitAndNonDigit('foo123bar');
expect(result).toBeTruthy();
});
it('should validate text which contains both numbers, chars and whitespaces', function() {
var result = validator.is.digitAndNonDigit('foo 123 bar');
expect(result).toBeTruthy();
});
});
});
describe('Validation.has', function() {
describe('Validation.has.minLength', function() {
it("should validate 'abc' has minLength 3", function() {
var result = validator.has.minLength('abc', 3);
expect(result).toBeTruthy();
});
it("should validate 'abc' has minLength 2", function() {
var result = validator.has.minLength('abc', 2);
expect(result).toBeTruthy();
});
it("should not validate 'abc' has minLength 4", function() {
var result = validator.has.minLength('abc', 4);
expect(result).toBeFalsy();
});
it("should validate ' ' has minLength 1", function() {
var result = validator.has.minLength(' ', 1);
expect(result).toBeTruthy();
});
it("should not validate '' has minLength 1", function() {
var result = validator.has.minLength('', 1);
expect(result).toBeFalsy();
});
});
describe('Validation.has.maxLength', function() {
it("should not validate 'abc' has max length 2", function() {
var result = validator.has.maxLength('abc', 2);
expect(result).toBeFalsy();
});
it("should validate 'ab' has max length 2", function() {
var result = validator.has.maxLength('ab', 2);
expect(result).toBeTruthy();
});
it("should not validate ' ' has max length 2", function() {
var result = validator.has.maxLength(' ', 2);
expect(result).toBeFalsy();
});
it("should validate '' has max length 0", function() {
var result = validator.has.maxLength('', 0);
expect(result).toBeTruthy();
});
});
describe('Validation.has.minValue', function() {
it('should validate 3 has min value 1', function() {
var result = validator.has.minValue(3, 1);
expect(result).toBeTruthy();
});
it('should not validate 3 has min value 4', function() {
var result = validator.has.minValue(3, 4);
expect(result).toBeFalsy();
});
});
describe('Validation.has.maxValue', function() {
it('should validate 3 has max value 4', function() {
var result = validator.has.maxValue(3, 4);
expect(result).toBeTruthy();
});
it('should not validate 3 has max value 2', function() {
var result = validator.has.maxValue(3, 2);
expect(result).toBeFalsy();
});
});
});
});
/**
* Run jasmine spec
*/
tart.Validation.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/XhrManager.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.XhrManager static class to handle XHR requests.
*/
goog.provide('tart.XhrManager');
/**
* jQuery GET's wrapper
*
* @param {string} url url to send request.
* @param {Object} params POST/GET parameters.
* @param {?function(Object)} success success callback.
* @param {?function(Object)=} opt_fail fail callback.
* @param {string=} opt_dataType data type.
* @return {Object} .
*/
tart.XhrManager.get = function(url, params, success, opt_fail, opt_dataType) {
return tart.XhrManager.ajax('GET', url, params, success, opt_fail, opt_dataType);
};
/**
* jQuery POST's wrapper
*
* @param {string} url url to send request.
* @param {Object} params POST/GET parameters.
* @param {?function(Object)} success success callback.
* @param {?function(Object)=} opt_fail fail callback.
* @param {string=} opt_dataType data type.
* @return {Object} .
*/
tart.XhrManager.post = function(url, params, success, opt_fail, opt_dataType) {
return tart.XhrManager.ajax('POST', url, params, success, opt_fail, opt_dataType);
};
/**
* jQuery POST's wrapper
*
* @param {string} type request type.
* @param {string} url url to send request.
* @param {Object} params POST/GET parameters.
* @param {?function(Object)} success success callback.
* @param {?function(Object)=} opt_fail fail callback.
* @param {string=} opt_dataType data type.
* @return {Object} .
*/
tart.XhrManager.ajax = function(type, url, params, success, opt_fail, opt_dataType) {
return $.ajax({
'type': type,
'url': url,
'data': params,
'dataType': opt_dataType || 'json',
'xhrFields': {
'withCredentials': true
},
'success': function(response) {
success && success(response);
},
'error': function(response) {
opt_fail && opt_fail(response);
}
});
};
================================================
FILE: tart/base/Model.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.base.Model base model.
*/
goog.provide('tart.base.Model');
goog.require('goog.structs.Map');
goog.require('goog.debug.ErrorHandler');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
/**
* Base model
*
* @extends {goog.events.EventTarget}
* @constructor
*/
tart.base.Model = function() {
goog.events.EventTarget.call(this);
/** @private **/
this.items_ = null;
/** @private **/
this.totalItemCount_ = 0;
this.params = new goog.structs.Map();
};
goog.inherits(tart.base.Model, goog.events.EventTarget);
/**
* Abstract method to load data from any resource
* @param {Function=} opt_callback method after load.
*/
tart.base.Model.prototype.load = function (opt_callback) {
goog.abstractMethod();
};
/**
* getter for items
* @param {boolean=} dispatchEvent Whether this method should throw an event when its items are loaded. This may be used in classes that
* extend tart.base.Model.
* @return {Object} items all items.
*/
tart.base.Model.prototype.getItems = function(dispatchEvent) {
return this.items_;
};
/**
* Setter for items
* @param {Object} items items to be set.
*/
tart.base.Model.prototype.setItems = function(items) {
this.items_ = items;
};
/**
* Set total item count
* @param {number} itemCount total item count for this model.
*/
tart.base.Model.prototype.setTotalItemCount = function(itemCount) {
this.totalItemCount_ = itemCount;
};
/**
* Get total item count
* @return {number} total item count for this model.
*/
tart.base.Model.prototype.getTotalItemCount = function() {
return this.totalItemCount_;
};
/** @typedef {{type: string, oldValue, newValue}} */
tart.base.Model.Event;
/**
* Overriding goog.events.EventTarget's dispatchEvent method, to make this event consistent in application
*
* @param {Object|string} modelEvent event object which has type, oldValue and newValue fields.
* @return {boolean} .
* @override
*/
tart.base.Model.prototype.dispatchEvent = function(modelEvent) {
return goog.base(this, 'dispatchEvent', modelEvent);
};
================================================
FILE: tart/base/plugin/BasePlugin.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.base.plugin.BasePlugin to get common properties for a plugin in one class.
*/
goog.provide('tart.base.plugin.BasePlugin');
goog.require('goog.debug.ErrorHandler');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
goog.require('goog.structs.Map');
/**
* @param {tart.base.Model} model
* @extends {goog.events.EventTarget}
* @constructor
*/
tart.base.plugin.BasePlugin = function (model) {
goog.events.EventTarget.call(this);
/** @protected */
this.model = model;
/** @protected **/
this.map = new goog.structs.Map();
this.model.params.set(this.key, this.map);
};
goog.inherits(tart.base.plugin.BasePlugin, goog.events.EventTarget);
/**
* clear map for plugin
*/
tart.base.plugin.BasePlugin.prototype.clear = function () {
this.map.clear();
};
/**
* Getter for model
*/
tart.base.plugin.BasePlugin.prototype.getModel = function () {
return this.model;
};
/**
* models key
*/
tart.base.plugin.BasePlugin.prototype.key = undefined;
================================================
FILE: tart/base/plugin/Filter.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.base.plugin.Filter model filter plugin.
*/
goog.provide('tart.base.plugin.Filter');
goog.require('tart.base.plugin.BasePlugin');
/**
* @param {tart.base.Model} model
*
* @extends {tart.base.plugin.BasePlugin}
* @constructor
*/
tart.base.plugin.Filter = function (model) {
goog.base(this, model);
};
goog.inherits(tart.base.plugin.Filter, tart.base.plugin.BasePlugin);
/**
* Set plugins param key
*/
tart.base.plugin.Filter.prototype.key = "filterParams";
/**
* @param {string} field field to be filtereded.
* @param {string} condition condition operator.
* @param {string} value field value to filter field for.
*/
tart.base.plugin.Filter.prototype.addFilter = function (field, condition, value) {
/**
* There can be multiple condition-value pair for a field
*/
var fieldFilter = this.map.get(field);
//and if this field did not set before create a new object
if (!fieldFilter) {
fieldFilter = {};
}
fieldFilter[condition] = value;
this.map.set(field, fieldFilter);
};
================================================
FILE: tart/base/plugin/Pager.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.base.plugin.Pager model pager plugin to handle pagination.
*/
goog.provide('tart.base.plugin.Pager');
goog.require('tart.Pagination');
goog.require('tart.base.plugin.BasePlugin');
/**
* @param {tart.base.Model} model tart.base.Model instance to set pager params.
* @param {tart.Pagination=} pagination optional tart.Pagination instance to handle pagination.
*
* @extends {tart.base.plugin.BasePlugin}
* @constructor
*/
tart.base.plugin.Pager = function(model, pagination) {
goog.base(this, model);
var that = this;
/** @private */
that.pagination_ = pagination || new tart.Pagination();
that.pagination_.setParentEventTarget(this);
/**
* Change offset on page change events
*/
goog.events.listen(that.pagination_, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
var limit = parseInt(that.map.get('limit'), 10);
var newOffset = (e.newValue - 1) * limit;
that.map.set('offset', newOffset);
that.model.params.set(that.key, that.map);
});
};
goog.inherits(tart.base.plugin.Pager, tart.base.plugin.BasePlugin);
/**
* Plugin's parameter key which is inherited from BasePlugin and should be defined
*/
tart.base.plugin.Pager.prototype.key = 'paginationParams';
/**
* @param {number} pageCount number of pages.
*/
tart.base.plugin.Pager.prototype.setTotalPageCount = function(pageCount) {
this.map.set('pageCount', pageCount);
};
/**
* @param {number} offset cursor start point for paging.
*/
tart.base.plugin.Pager.prototype.setOffset = function(offset) {
this.map.set('offset', offset);
};
/**
*
* @param {number} limit item count to fetch.
*/
tart.base.plugin.Pager.prototype.setLimit = function(limit) {
this.map.set('limit', limit);
this.pagination_.setItemPerPage(limit);
};
/**
*
* @return {number} current limit.
*/
tart.base.plugin.Pager.prototype.getLimit = function() {
return this.pagination_.getItemPerPage();
};
/**
* @param {number} totalItemCount set total item count for paginator.
*/
tart.base.plugin.Pager.prototype.setTotalItems = function(totalItemCount) {
this.pagination_.setTotalItems(totalItemCount);
};
/**
* Next wrapper for paginator.
*/
tart.base.plugin.Pager.prototype.next = function() {
this.pagination_.next();
};
/**
* Prev wrapper for paginator.
*/
tart.base.plugin.Pager.prototype.prev = function() {
this.pagination_.prev();
};
/**
* setCurrentPage wrapper for paginator.
* @param {number} currentPageNum current page number.
*/
tart.base.plugin.Pager.prototype.setCurrentPage = function(currentPageNum) {
this.pagination_.setCurrentPage(currentPageNum);
};
/**
* @return {number} number of pages.
*/
tart.base.plugin.Pager.prototype.getTotalPage = function() {
return this.pagination_.getTotalPage();
};
/**
* @return {number} current page number.
*/
tart.base.plugin.Pager.prototype.getCurrentPage = function() {
return this.pagination_.getCurrentPage();
};
/**
* @return {boolean} Whether there is a previous page available.
*/
tart.base.plugin.Pager.prototype.hasPrev = function() {
return this.pagination_.hasPrev();
};
/**
* @return {boolean} Whether there is a next page available.
*/
tart.base.plugin.Pager.prototype.hasNext = function() {
return this.pagination_.hasNext();
};
================================================
FILE: tart/base/plugin/Sorter.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.base.plugin.Sorter model sorter plugin.
*/
goog.provide('tart.base.plugin.Sorter');
goog.require('tart.base.plugin.BasePlugin');
/**
* @param {tart.base.Model} model
*
* @extends {tart.base.plugin.BasePlugin}
* @constructor
*/
tart.base.plugin.Sorter = function (model) {
goog.events.EventTarget.call(this);
/** @protected */
this.model = model;
/** @protected **/
this.sorts = [];
this.model.params.set(this.key, this.sorts);
};
goog.inherits(tart.base.plugin.Sorter, tart.base.plugin.BasePlugin);
/**
* Set plugin's param
*/
tart.base.plugin.Sorter.prototype.key = "sortParams";
/**
* @param {string} field field to be sorted.
* @param {string} order order by directive, which is asc or desc.
*/
tart.base.plugin.Sorter.prototype.addSort = function (field, order) {
/**
* There can be multiple condition-value pair for a field
*/
var fieldSorter = goog.array.find(this.sorts, function(item){
return goog.object.getAnyKey(item) == field;
});
//and if this field did not set before create a new object
if (!fieldSorter) {
fieldSorter = {};
}
fieldSorter[field] = order;
this.model.params.get(this.key).push(fieldSorter);
};
/**
* clear map for plugin
*/
tart.base.plugin.Sorter.prototype.clear = function () {
this.sorts = [];
this.model.params.set(this.key, this.sorts);
};
================================================
FILE: tart/components/Carousel/Controller.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.Carousel.Controller is a base class for all carousel Controller's.
*/
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventTarget');
goog.require('tart.Pagination');
goog.require('tart.base.plugin.Pager');
goog.require('tart.components.Carousel.Model');
goog.require('tart.components.Carousel.Template');
goog.require('tart.components.Carousel.View');
goog.require('tart.components.Controller');
goog.provide('tart.components.Carousel.Controller');
/**
* Example controller class
*
* @extends {tart.components.Controller}
*
* @constructor
*/
tart.components.Carousel.Controller = function() {
this.model = this.model || new this.modelClass();
this.modelPager = new tart.base.plugin.Pager(this.model, new this.paginationClass());
this.modelPager.setOffset(0);
this.modelPager.setLimit(this.itemCount);
this.view = new this.viewClass();
this.buildDOM();
this.bindEvents();
};
goog.inherits(tart.components.Carousel.Controller, tart.components.Controller);
/**
* Carousel's View Class
*/
tart.components.Carousel.Controller.prototype.viewClass = tart.components.Carousel.View;
/**
* Carousel's Model Class
*/
tart.components.Carousel.Controller.prototype.modelClass = tart.components.Carousel.Model;
/**
* Carousel's Pagination Class
*/
tart.components.Carousel.Controller.prototype.paginationClass = tart.Pagination;
/**
* Number of carousel items
*/
tart.components.Carousel.Controller.prototype.itemCount = 5;
/**
* Build carousel after items' loaded
* @param {Object} visibleItems visible items.
* @param {number} totalItemCount total item count.
*/
tart.components.Carousel.Controller.prototype.buildCarouselAction = function(visibleItems, totalItemCount) {
if (visibleItems.length == 0)
this.view.noResults();
else {
//build carousel
this.view.buildCarouselItems(visibleItems);
//build pagination
this.modelPager.setTotalItems(totalItemCount);
if (totalItemCount > this.itemCount) {
this.view.buildPager(this.modelPager);
}
}
this.view.handleNavigationButtons(this.modelPager.hasNext(), this.modelPager.hasPrev());
};
/**
* Go to page in given direction
* @param {string} direction move direction.
* @param {Number} pageNumber page number to go.
*/
tart.components.Carousel.Controller.prototype.goToPageAction = function(direction, pageNumber) {
var items = this.model.getItems();
this.view.move(direction, items, this.modelPager.getLimit());
this.view.setPageSelected(pageNumber);
};
/**
* move next page
*/
tart.components.Carousel.Controller.prototype.nextAction = function() {
this.modelPager.next();
};
/**
* move previous page
*
*/
tart.components.Carousel.Controller.prototype.prevAction = function() {
this.modelPager.prev();
};
/**
* Bind controller events
* @protected
*/
tart.components.Carousel.Controller.prototype.bindEvents = function() {
var that = this;
//triggered when model.getItems() called
goog.events.listen(that.model, tart.components.Carousel.Model.EventTypes.ITEMS_LOADED, function(e) {
that.buildCarouselAction(e.visibleItems, e.totalItemCount);
if (e.visibleItems.length > 0) {
goog.style.setStyle(that.view.getDOM(), 'display', 'block');
}
});
//Triggered when page changed
goog.events.listen(that.modelPager, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
//dont do anything if page not changed
if (e.oldValue != e.newValue) {
var direction;
if (e.newValue > e.oldValue) {
direction = 'next';
}
else {
direction = 'prev';
}
that.goToPageAction(direction, e.newValue);
}
that.view.handleNavigationButtons(that.modelPager.hasNext(), that.modelPager.hasPrev());
});
goog.events.listen(that.view.get(that.view.domMappings.NEXT)[0], goog.events.EventType.CLICK,
this.nextAction, false, this);
goog.events.listen(that.view.get(that.view.domMappings.PREV)[0], goog.events.EventType.CLICK,
this.prevAction, false, this);
};
================================================
FILE: tart/components/Carousel/Model.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.Carousel.Model is a base class for all carousel Model's.
*/
goog.require('goog.events.EventTarget');
goog.require('tart.Carousel');
goog.require('tart.base.Model');
goog.require('tart.dataProxy.CircularLocal');
goog.provide('tart.components.Carousel.Model');
goog.provide('tart.components.Carousel.Model.EventTypes');
/**
* All component models should be inherited from goog.events.EventTarget
* to publish events to controllers
*
* @extends {tart.base.Model}
* @constructor
*/
tart.components.Carousel.Model = function() {
goog.base(this);
/** @protected */
this.proxy = new tart.dataProxy.CircularLocal();
};
goog.inherits(tart.components.Carousel.Model, tart.base.Model);
/**
* Model's default offset value.
*/
tart.components.Carousel.Model.prototype.offset = 0;
/**
* Model's default limit value.
*/
tart.components.Carousel.Model.prototype.limit = 0;
/**
* WidgetModel's remoteModelClass's default value is undefined.
*/
tart.components.Carousel.Model.prototype.remoteModelClass = undefined;
/**
* WidgetModel's RemoteModelClass's default value is undefined.
*/
tart.components.Carousel.Model.prototype.remoteModelClassParams = undefined;
/**
* event types enumaration
* @enum {string}
*/
tart.components.Carousel.Model.EventTypes = {
ITEMS_LOADED: 'loaded'
};
/**
* Get carousel items
* @param {boolean} dispatchEvent whether it dispatches an event.
* @return {Array} modelItems is count of items..
*/
tart.components.Carousel.Model.prototype.getItems = function(dispatchEvent) {
var that = this;
var modelItems;
this.load(function(items) {
if (dispatchEvent) {
var eventObject = {type: tart.components.Carousel.Model.EventTypes.ITEMS_LOADED,
visibleItems: items,
totalItemCount: that.getTotalItemCount()
};
that.dispatchEvent(eventObject);
}
modelItems = items;
});
return modelItems;
};
/**
* @param {Function} callback load callback function.
*/
tart.components.Carousel.Model.prototype.load = function(callback) {
var that = this;
var remoteModel;
var onProxyFetch = function(data) {
that.setItems(data);
callback.call(this, data);
};
var getremoteModelData = function() {
var data = remoteModel.getItems();
that.proxy.setData(data);
that.setTotalItemCount(data.length);
that.proxy.fetch(onProxyFetch);
};
that.proxy.setParams(this.params);
if (that.proxy.getData()) {
that.proxy.fetch(onProxyFetch);
}
else if (this.remoteModelClass) {
remoteModel = new this.remoteModelClass(this.remoteModelClassParams);
if (this.pagination) {
var remoteModelPager = new tart.base.plugin.Pager(remoteModel, this.pagination);
remoteModelPager.setOffset(this.offset);
remoteModelPager.setLimit(this.limit);
}
remoteModel.load(getremoteModelData);
}
};
================================================
FILE: tart/components/Carousel/Template.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.Carousel.Template is a base class for all carousel Template's.
*/
goog.provide('tart.components.Carousel.Template');
/**
* @constructor
*/
tart.components.Carousel.Template = function() {
this.properties = {
CAROUSEL_WIDTH: this.carouselWidth
};
this.domMappings = {
NAVIGATION: '.navigation',
PREV: '.navigation.prev',
NEXT: '.navigation.next',
ITEMS: '.contents',
PAGER: '.pager',
PAGER_ITEMS: '.pagerItems',
PAGER_ITEM: 'span'
};
};
/**
* Header
*
* @return {string} header markup.
*/
tart.components.Carousel.Template.prototype.header = function() {
return '';
};
tart.components.Carousel.Template.prototype.carouselWidth = 780;
/**
* Footer
*
* @return {string} footer markup.
*/
tart.components.Carousel.Template.prototype.footer = function() {
return '<div class="pager rounded">' +
'<div class="pagerItems"></div>' +
'</div>';
};
/**
* Base markup for carousel
*
* @return {string} base markup.
*/
tart.components.Carousel.Template.prototype.base = function() {
return '<div class="carousel loading">' +
this.header() +
'<span class="navigation next" title="next"></span>' +
'<span class="navigation prev" title="previous"></span>' +
'<div class="contentsWrapper">' +
'<div class="contents"></div>' +
'</div>' +
this.footer() +
'</div>';
};
/**
* Markup for carousel group
*
* @param {Array.<*>} itemArray carousel items.
* @return {(Node)} base markup.
*/
tart.components.Carousel.Template.prototype.carouselItems = goog.abstractMethod;
/**
*
* @param {number} pageNum is number of selected page.
* @param {boolean} selected class.
* @return {string} markup.
*/
tart.components.Carousel.Template.prototype.pagerItem = function(pageNum, selected) {
var selectedClass = selected ? 'selected' : '';
return '<span class="' + selectedClass + '" title="' + pageNum + ' "></span>';
};
/**
* @return {string}
*/
tart.components.Carousel.Template.prototype.noResults = function() {
return '';
};
================================================
FILE: tart/components/Carousel/View.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.Carousel.View is a base class for all carousel View's.
*/
goog.require('tart.components.View');
goog.provide('tart.components.Carousel.View');
/**
* @extends {tart.components.View}
* @constructor
*/
tart.components.Carousel.View = function() {
goog.base(this);
this.template = new this.templateClass();
this.domMappings = this.template.domMappings;
this.pagerItemsCache = {};
this.activeItems = null;
};
goog.inherits(tart.components.Carousel.View, tart.components.View);
/**
*
*/
tart.components.Carousel.View.prototype.templateClass = tart.components.Carousel.Template;
/**
* Build carousel items from item array
*
* @param {Array.<Object>} itemArray carousel data array.
*/
tart.components.Carousel.View.prototype.buildCarouselItems = function(itemArray) {
goog.dom.classlist.remove(this.getDOM(), 'loading');
var carouselItems = this.template.carouselItems(itemArray);
this.get(this.domMappings.ITEMS)[0].innerHTML = '';
goog.dom.appendChild(this.get(this.domMappings.ITEMS)[0], carouselItems);
this.itemsAppended(carouselItems);
this.activeItems = carouselItems;
};
/**
* Render method which has to be overriden
*
* @return {string} markup.
*/
tart.components.Carousel.View.prototype.render = function() {
return this.template.base();
};
/**
* get all carousel items' DOM reference
*
* @return {Object} DOM refernce.
* @protected
*/
tart.components.Carousel.View.prototype.getAllCarouselItemsDomReference = function() {
var carouselItems = this.get(this.domMappings.ITEMS)[0];
return goog.dom.getChildren(carouselItems);
};
/**
* Animate carousel with given rule
*
* @param {string} direction 'next' or 'previous' TODO: this should be enumarated.
* @param {Array.<Object>} diff items to be inserted.
* @param {number} moveCount count of move.
*/
tart.components.Carousel.View.prototype.move = function(direction, diff, moveCount) {
var that = this;
if (diff.length > 0) {
var carouselItems = $(that.get(that.domMappings.ITEMS));
//prevent glitch on rapid movements
carouselItems.stop(true, true);
var marginLeft;
var moveWidth = this.template.properties.CAROUSEL_WIDTH;
var allCarouselItems = $(that.getAllCarouselItemsDomReference());
var markup = $(this.template.carouselItems(diff));
this.activeItems = markup;
for (var i = 0; i < markup.length; i++) {
for (var j = 0; j < allCarouselItems.length; j++) {
if (markup[i] === allCarouselItems[j])
allCarouselItems = allCarouselItems.not(markup[i]);
}
}
if (direction == 'next') {
carouselItems.append(markup);
this.itemsAppended(markup);
marginLeft = '-=' + moveWidth + 'px';
} else {
carouselItems.prepend(markup);
this.itemsAppended(markup);
carouselItems.css('margin-left', (-1 * moveWidth) + 'px');
marginLeft = '+=' + moveWidth + 'px';
}
carouselItems.animate({ 'margin-left': marginLeft }, 500, '', function(){
allCarouselItems.detach();
carouselItems.css('margin-left', '0px');
});
}
};
tart.components.Carousel.View.prototype.itemsAppended = function(items) {
};
/**
* Method to hide previous button.
*/
tart.components.Carousel.View.prototype.hidePrev = function() {
goog.style.showElement(this.get(this.domMappings.PREV)[0], false);
};
/**
*
* @param {tart.base.plugin.Pager} pager to build pager.
*/
tart.components.Carousel.View.prototype.buildPager = function(pager) {
var that = this;
var pagerElement = that.get(that.domMappings.PAGER)[0];
var totalPage = pager.getTotalPage();
var navigation = that.get(that.domMappings.NAVIGATION)[0];
if (totalPage > 1) { //show pager if only totalPage > 1
if (pagerElement.length > 0) {
var pagerItems = pagerElement.querySelectorAll(that.domMappings.PAGER_ITEMS)[0];
//for each pager create pager button and attach event
for (var i = 1; i <= totalPage; i++) {
(function(i) {
var selected = (i == 1);
var pagerItem = tart.dom.createElement(that.template.pagerItem(i, selected))[0];
goog.events.listen(pagerItem, goog.events.EventType.CLICK, function(){
pager.setCurrentPage(i);
});
goog.dom.appendChild(pagerItems, pagerItem);
that.pagerItemsCache[i] = pagerItem;
})(i);
}
goog.style.showElement(pagerElement, true);
}
goog.style.showElement(navigation, true);
if (!pager.hasPrev()) that.hidePrev();
}
else {
//hide pager if totalPage < 2
pagerElement.hide();
navigation.hide();
}
};
/**
*
* @param {number} pageNum number of selected page.
*/
tart.components.Carousel.View.prototype.setPageSelected = function(pageNum) {
var that = this;
var pager = that.get(that.domMappings.PAGER)[0];
var pagerItems = pager.querySelector(that.domMappings.PAGER_ITEMS).querySelectorAll(that.domMappings.PAGER_ITEM);
goog.array.forEach(pagerItems, function(pagerItem) {
goog.dom.classlist.remove(pagerItem, 'selected');
});
that.pagerItemsCache[pageNum] && goog.dom.classlist.add(that.pagerItemsCache[pageNum], 'selected');
};
/**
*
* @param {boolean} hasNext Whether there is a previous page.
* @param {boolean} hasPrev Whether there is a next page.
*/
tart.components.Carousel.View.prototype.handleNavigationButtons = function(hasNext, hasPrev) {
var pagerNext = this.get(this.domMappings.NEXT)[0];
var pagerPrev = this.get(this.domMappings.PREV)[0];
goog.style.showElement(pagerNext, true);
goog.style.showElement(pagerPrev, true);
if (!hasNext) goog.style.showElement(pagerNext, false);
if (!hasPrev) goog.style.showElement(pagerPrev, false);
};
/**
* No results handler
*
*/
tart.components.Carousel.View.prototype.noResults = function() {
goog.dom.classlist.remove(this.getDOM(), 'loading');
var carouselText = this.template.noResults();
this.get(this.domMappings.ITEMS)[0].innerHTML = carouselText;
this.itemsAppended(carouselText);
this.activeItems = carouselText;
};
================================================
FILE: tart/components/Carousel/Widget.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.Carousel.Widget is a base for all carousel widgets.
*/
goog.provide('tart.components.Carousel.Widget');
goog.require('tart.components.Carousel.Controller');
goog.require('tart.components.Widget');
/**
* @constructor
* @extends {tart.components.Widget}
*/
tart.components.Carousel.Widget = function() {
this.controller = new this.controllerClass();
goog.base(this);
this.init();
};
goog.inherits(tart.components.Carousel.Widget, tart.components.Widget);
/**
*
*/
tart.components.Carousel.Widget.prototype.controllerClass = tart.components.Carousel.Controller;
tart.components.Carousel.Widget.prototype.init = function() {
this.controller.model.getItems(true);
};
================================================
FILE: tart/components/Controller.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.components.Controller is a base class for all components Controller's.
*
* Example usage:
*
* var ViewClass = function () {
* goog.base(this);
* };
* goog.inherits(ViewClass, tart.components.View);
*
* ViewClass.prototype.render = function () {
* return "<h1>Foo</h1>";
* };
* var view = new ViewClass();
*
* var ModelClass = function () {
* goog.base(this);
* };
* goog.inherits(ModelClass, tart.base.Model);
*
*
* var model = new ModelClass();
*
* var ControllerClass = function () {
* goog.base(this);
* };
* goog.inherits(ControllerClass, tart.components.Controller);
*
* var controller = new ControllerClass(model, view);
* var dom = controller.buildDOM();
*/
goog.require('tart.base.Model');
goog.require('tart.components.View');
goog.provide('tart.components.Controller');
/**
* Base controller
*
* @param {tart.base.Model=} opt_model Data model.
* @param {tart.components.View=} opt_view View object.
* @constructor
*/
tart.components.Controller = function(opt_model, opt_view) {
this.model = opt_model || new tart.base.Model();
this.view = opt_view || new tart.components.View();
};
/**
* Build DOM from view
*
* @return {Element} generated DOM of attached View object.
*/
tart.components.Controller.prototype.buildDOM = function() {
var dom = this.view.render();
// TODO : render should always be string so we should remove string check.
if(goog.isString(dom))
dom = /** @type {Element} */(tart.dom.createElement(dom));
this.view.setDOM(/** @type {Element} */(dom));
return /** @type {Element} */ (dom);
};
/**
* Get DOM generated by view and attached by controller
*
* @return {Element} DOM reference.
*/
tart.components.Controller.prototype.getDOM = function() {
return this.view.getDOM();
};
================================================
FILE: tart/components/RemoteModel.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
/**
* @fileoverview tart.components.RemoteModel RemoteModel which gets data from Xhr.
*/
goog.provide('tart.components.models.RemoteModel');
goog.require('tart.base.Model');
goog.require('tart.dataProxy.Xhr');
/**
* Remote Model
*
* @extends {tart.base.Model}
* @constructor
*/
tart.components.models.RemoteModel = function() {
goog.base(this);
this.params.set('method_', 'post');
this.params.set('url_', this.url);
this.totalCount = 0;
this.proxy = new this.proxyClass();
};
goog.inherits(tart.components.models.RemoteModel, tart.base.Model);
/**
* RemoteModel's entity class. Default value is undefined.
*/
tart.components.models.RemoteModel.prototype.entityClass = undefined;
tart.components.models.RemoteModel.prototype.proxyClass = tart.dataProxy.Xhr;
/**
* RemoteModel's request url. Default value is undefined.
*/
tart.components.models.RemoteModel.prototype.url = undefined;
/**
* Load data and map data to entity.
* @param {Function=} opt_callback method to call after load.
*/
tart.components.models.RemoteModel.prototype.load = function(opt_callback) {
var that = this;
that.proxy.setParams(this.params);
that.proxy.fetch(function(data) {
that.mapDataToEntities(data);
if (opt_callback) {
opt_callback.call(this, that.getItems());
}
});
};
/**
* map data to entity class.
* @param {Object} xhrData data returned from xhr request.
* @protected
*/
tart.components.models.RemoteModel.prototype.mapDataToEntities = function(xhrData) {
var items = [], collection = xhrData['data'];
for (var i = 0, l = collection.length; i < l; i++) {
items.push(new this.entityClass(collection[i]));
}
this.totalCount = items.length;
this.setItems(items);
};
================================================
FILE: tart/components/ThumbnailedCarousel/Model.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.components.Carousel.Model');
goog.provide('tart.components.ThumbnailedCarousel.Model');
/**
* @extends {tart.components.Carousel.Model}
* @constructor
*/
tart.components.ThumbnailedCarousel.Model = function() {
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.Model, tart.components.Carousel.Model);
/**
* @param {Array} activeItem Active carousel items.
*/
tart.components.ThumbnailedCarousel.Model.prototype.setActiveItem = function(activeItem) {
this.activeItem = activeItem;
this.dispatchEvent({
type: this.EventTypes.ACTIVE_ITEM,
activeItem: activeItem
});
};
tart.components.ThumbnailedCarousel.Model.prototype.EventTypes = {
ACTIVE_ITEM: 'activeItem'
};
================================================
FILE: tart/components/ThumbnailedCarousel/SpotController.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.CircularPagination');
goog.require('tart.components.Carousel.Controller');
goog.require('tart.components.ThumbnailedCarousel.Model');
goog.require('tart.components.ThumbnailedCarousel.ThumbnailsController');
goog.require('tart.components.ThumbnailedCarousel.ThumbnailsTemplate');
goog.require('tart.components.ThumbnailedCarousel.SpotView');
goog.provide('tart.components.ThumbnailedCarousel.SpotController');
/**
* @constructor
* @extends {tart.components.Carousel.Controller}
*/
tart.components.ThumbnailedCarousel.SpotController = function() {
this.pagination = new tart.CircularPagination();
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.SpotController, tart.components.Carousel.Controller);
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.paginationClass = tart.CircularPagination;
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.itemCount = 1;
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.viewClass = tart.components.ThumbnailedCarousel.SpotView;
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.modelClass = tart.components.ThumbnailedCarousel.Model;
/**
* Thumbnailed Carousel's thumbnails template class
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.thumbnailsTemplateClass =
tart.components.ThumbnailedCarousel.ThumbnailsTemplate;
/**
* Thumbnailed Carousel's thumbnails controller class
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.thumbnailsControllerClass =
tart.components.ThumbnailedCarousel.ThumbnailsController;
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.buildCarouselAction = function(visibleItems, totalItemCount) {
goog.base(this, 'buildCarouselAction', visibleItems, totalItemCount);
this.thumbnailsController = new this.thumbnailsControllerClass(this.model);
var $thumbnails = this.thumbnailsController.getDOM();
this.view.appendThumbnails($thumbnails);
};
/**
* @override
*/
tart.components.ThumbnailedCarousel.SpotController.prototype.bindEvents = function() {
goog.base(this, 'bindEvents');
var that = this;
goog.events.listen(this.modelPager, tart.Pagination.EventTypes.PAGE_CHANGED, function(e) {
that.model.setActiveItem(e.newValue);
});
goog.events.listen(this.model, this.model.EventTypes.ACTIVE_ITEM, function(e) {
that.modelPager.setCurrentPage(e.activeItem);
});
};
================================================
FILE: tart/components/ThumbnailedCarousel/SpotTemplate.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.components.Carousel.Template');
goog.provide('tart.components.ThumbnailedCarousel.SpotTemplate');
/**
* @extends {tart.components.Carousel.Template}
* @constructor
*/
tart.components.ThumbnailedCarousel.SpotTemplate = function() {
goog.base(this);
this.domMappings.THUMBNAILS_CONTAINER = '.thumbs';
};
goog.inherits(tart.components.ThumbnailedCarousel.SpotTemplate, tart.components.Carousel.Template);
/**
* Base function to create dom.
*
* @return {string} base markup of spot.
*/
tart.components.ThumbnailedCarousel.SpotTemplate.prototype.base = function() {
var markup = '<div class="carousel loading thumbnailedCarousel">' +
'<span class="navigation next" title="ileri"></span>' +
'<span class="navigation prev" title="geri"></span>' +
'<div class="contentsWrapper">' +
'<div class="contents"></div>' +
'</div>' +
'<div class="thumbs"></div>';
return markup;
};
================================================
FILE: tart/components/ThumbnailedCarousel/SpotView.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.trr>
goog.require('tart.components.Carousel.View');
goog.require('tart.components.ThumbnailedCarousel.SpotTemplate');
goog.provide('tart.components.ThumbnailedCarousel.SpotView');
/**
* @extends {tart.components.Carousel.View}
* @constructor
*/
tart.components.ThumbnailedCarousel.SpotView = function() {
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.SpotView, tart.components.Carousel.View);
tart.components.ThumbnailedCarousel.SpotView.prototype.templateClass = tart.components.ThumbnailedCarousel.SpotTemplate;
/**
* @param {string|jQueryObject} $dom for append thumbnails to carousel.
*/
tart.components.ThumbnailedCarousel.SpotView.prototype.appendThumbnails = function($dom) {
this.get(this.domMappings.THUMBNAILS_CONTAINER).append($dom);
};
================================================
FILE: tart/components/ThumbnailedCarousel/ThumbnailsController.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.CircularPagination');
goog.require('tart.components.Carousel.Controller');
goog.require('tart.components.ThumbnailedCarousel.ThumbnailsView');
goog.provide('tart.components.ThumbnailedCarousel.ThumbnailsController');
/**
* @constructor
* @extends {tart.components.Carousel.Controller}
*/
tart.components.ThumbnailedCarousel.ThumbnailsController = function(model) {
this.pagination = new this.paginationClass();
this.model = model || new this.modelClass();
this.modelPager = new tart.base.plugin.Pager(this.model, new this.paginationClass());
this.modelPager.setOffset(0);
this.modelPager.setLimit(this.itemCount);
this.view = new this.viewClass();
this.buildDOM();
this.bindEvents();
var items = this.model.getItems(); // true = trigger load event after items loaded
this.buildCarouselAction(items, this.model.getTotalItemCount());
};
goog.inherits(tart.components.ThumbnailedCarousel.ThumbnailsController, tart.components.Carousel.Controller);
/**
* @override
*/
tart.components.ThumbnailedCarousel.ThumbnailsController.prototype.viewClass = tart.components.ThumbnailedCarousel.ThumbnailsView;
/**
* @override
*/
tart.components.ThumbnailedCarousel.ThumbnailsController.prototype.bindEvents = function() {
goog.base(this, 'bindEvents');
var that = this;
goog.events.listen(that.model, this.model.EventTypes.ACTIVE_ITEM, function(e) {
that.modelPager.setCurrentPage(Math.ceil(e.activeItem / that.modelPager.pagination_.getItemPerPage()));
that.view.setActiveItem(e.activeItem);
});
};
/**
*
* @param visibleItems
* @param totalItemCount
*/
tart.components.ThumbnailedCarousel.ThumbnailsController.prototype.buildCarouselAction = function(visibleItems, totalItemCount) {
goog.base(this, 'buildCarouselAction', visibleItems, totalItemCount);
this.bindThumbnailEvents();
this.view.setActiveItem(1);
};
tart.components.ThumbnailedCarousel.ThumbnailsController.prototype.goToPageAction = function(p) {
goog.base(this, 'goToPageAction', p, null);
this.bindThumbnailEvents();
};
tart.components.ThumbnailedCarousel.ThumbnailsController.prototype.bindThumbnailEvents = function() {
var that = this;
var items = that.model.getItems();
goog.array.forEach(items, function(item, i) {
goog.events.removeAll(item.$thumbnail[0], goog.events.EventType.CLICK);
(function(item, i) {
goog.events.listen(item.$thumbnail[0], goog.events.EventType.CLICK, function(e) {
var offset = (that.modelPager.getCurrentPage() - 1) * that.modelPager.getLimit();
that.model.setActiveItem(offset + i);
});
})(item, i + 1);
});
};
================================================
FILE: tart/components/ThumbnailedCarousel/ThumbnailsTemplate.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.components.Carousel.Template');
goog.provide('tart.components.ThumbnailedCarousel.ThumbnailsTemplate');
/**
* @extends {tart.components.Carousel.Template}
* @constructor
*/
tart.components.ThumbnailedCarousel.ThumbnailsTemplate = function() {
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.ThumbnailsTemplate, tart.components.Carousel.Template);
/**
* @override
*/
tart.components.ThumbnailedCarousel.ThumbnailsTemplate.prototype.footer = function() {
return '';
}
================================================
FILE: tart/components/ThumbnailedCarousel/ThumbnailsView.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.trr>
goog.require('tart.components.Carousel.View');
goog.require('tart.components.ThumbnailedCarousel.ThumbnailsTemplate');
goog.provide('tart.components.ThumbnailedCarousel.ThumbnailsView');
/**
* @extends {tart.components.Carousel.View}
* @constructor
*/
tart.components.ThumbnailedCarousel.ThumbnailsView = function() {
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.ThumbnailsView, tart.components.Carousel.View);
tart.components.ThumbnailedCarousel.ThumbnailsView.prototype.templateClass = tart.components.ThumbnailedCarousel.ThumbnailsTemplate;
================================================
FILE: tart/components/ThumbnailedCarousel/Widget.js
================================================
// Copyright 2012 Tart. All Rights Reserved.
//
// @author Firat Yalavuz firat.yalavuz@tart.com.tr
goog.require('tart.components.Carousel.Widget');
goog.require('tart.components.ThumbnailedCarousel.SpotController');
goog.provide('tart.components.ThumbnailedCarousel.Widget');
/**
* @extends {tart.components.Carousel.Widget}
* @constructor
*/
tart.components.ThumbnailedCarousel.Widget = function() {
goog.base(this);
};
goog.inherits(tart.components.ThumbnailedCarousel.Widget, tart.components.Carousel.Widget);
tart.components.ThumbnailedCarousel.Widget.prototype.controllerClass = tart.components.ThumbnailedCarousel.SpotController;
================================================
FILE: tart/components/View.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.components.View is a base class for all components View's.
*
* Example usage:
*
* SubViewClass = function() {
* goog.base(this);
*
* this.domMappings = {
* HEADER: 'h1'
* };
* };
* goog.inherits(SubViewClass, tart.components.View);
*
* SubViewClass.prototype.templates_header = function(text) {
* text = text || '';
* return '<h1>' + text + '</h1>';
* };
*
* SubViewClass.prototype.render = function() {
* return this.templates_header();
* };
*
* var subView = new SubViewClass();
*
* var dummyDiv = tart.dom.createElement(subView.render());
*
* subView.setDOM(dummyDiv);
* subView.get(subView.domMappings.HEADER);
*
* Known issues:
* - Templates will be injected withing Templates object
*/
goog.provide('tart.components.View');
/**
* View class base
* @constructor
*/
tart.components.View = function() {
/** @protected */
this.domCache = {};
};
/** @type {Element} */
tart.components.View.prototype.dom;
/**
* Render abstract method, which all subclasses should implement
* @throws {Error}
* @return {string}
*/
tart.components.View.prototype.render = function() {
throw new Error('Not implemented yet');
};
/**
* Sets base DOM tree for component
* @param {Element} dom base DOM reference for component.
*/
tart.components.View.prototype.setDOM = function(dom) {
this.dom = dom;
};
/**
* get current DOM reference
*
* @return {Element}
*/
tart.components.View.prototype.getDOM = function() {
return this.dom;
};
/**
* Get item, which is indicated on domMappings node
* Cache them to domCache and return item
* Example of usage with an id as selector:
* this.get("[id='elementId']") or this.get("[id=elementId]")
*
* @param {string} key Object key from domMappings node.
* @return {{length: number}} found object after traverse.
*/
tart.components.View.prototype.get = function(key) {
if (!this.dom) {
throw new Error('DOM not set yet');
}
this.domCache[key] = this.domCache[key] || this.dom.querySelectorAll(key);
return this.domCache[key];
};
/**
* Clears the view's dom cache. This might come in handy where you find yourself with dangling HTMLElement's who are
* not in DOM anymore but bugs you because they are in cache. This also helps with memory leaks; you should often clear
* your cache. TODO: Make this default with a deconstructor for view
*/
tart.components.View.prototype.clearCache = function() {
this.domCache = {};
};
================================================
FILE: tart/components/Widget.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.components.Widget is a base class for all components Widget's.
*/
goog.require('tart');
goog.provide('tart.components.Widget');
/**
* Base widget
* @constructor
*/
tart.components.Widget = function() {
/** @private */
this.componentId_ = tart.getUid();
};
/**
* Renders the component in a given element or in its placeholder that should already be in the DOM.
*
* @param {Element=} rootEl If provided, the widget will render into this rootEl.
* Otherwise, it will look for its placeholder in DOM.
*/
tart.components.Widget.prototype.render = function (rootEl) {
rootEl = rootEl || goog.dom.getElement(this.componentId_);
rootEl.appendChild(this.controller.getDOM());
};
/**
* Get placeholder template
* @return {string} placeholder markup.
*/
tart.components.Widget.prototype.getPlaceholder = function () {
return this.templates_placeholder();
};
/**
* Component's placeholder template
* @return {string} placeholder markup.
*/
tart.components.Widget.prototype.templates_placeholder = function () {
return '<div class="widgetPlaceholder" id="' + this.componentId_ + '"></div>';
};
/**
* Get component id
* @return {Number} component id.
*/
tart.components.Widget.prototype.getId = function () {
return this.componentId_;
};
================================================
FILE: tart/components/spec/ComponentsSpec.js
================================================
goog.require('tart.components.Controller');
goog.require('tart.base.Model');
goog.require('tart.components.View');
goog.provide('tart.components.SpecRunner');
describe('Component', function() {
var opt_model = new tart.base.Model();
var opt_view = new tart.components.View();
describe('ComponentController', function() {
describe('has model and view objects in it', function() {
it('should have model object', function() {
var controller = new tart.components.Controller(opt_model, opt_view);
expect(controller.model instanceof tart.base.Model).toBeTruthy();
});
it('should have view object', function() {
var controller = new tart.components.Controller(opt_model, opt_view);
expect(controller.view instanceof tart.components.View).toBeTruthy();
});
});
describe('will get components DOM with buildDOM method', function() {
/**
* @constructor
* @extends {tart.components.View}
*/
var ViewClass = function() {
goog.base(this);
};
goog.inherits(ViewClass, tart.components.View);
/**
* @return {string} markup string .
*/
ViewClass.prototype.render = function() {
return '<h1>Foo</h1>';
};
var view = new ViewClass();
var controller = new tart.components.Controller(opt_model, view);
var dom = controller.buildDOM();
expect(dom).toBeTruthy();
});
});
describe('Component Model', function() {
describe('is event driven', function() {
it('should be inherited from goog.events.EventTarget', function() {
var model = new tart.base.Model();
expect(model instanceof goog.events.EventTarget).toBeTruthy();
});
it("should supply events to it's sub classes", function() {
/**
* @constructor
* @extends {tart.base.Model}
* */
var SubModelClass = function() {
goog.base(this);
};
goog.inherits(SubModelClass, tart.base.Model);
SubModelClass.EventTypes = {
SOMETHING_HAPPENED: 'foo'
};
var subModel = new SubModelClass();
var text;
goog.events.listen(subModel, SubModelClass.EventTypes.SOMETHING_HAPPENED, function(e) {
text = 'something triggered from model';
});
subModel.dispatchEvent({type: SubModelClass.EventTypes.SOMETHING_HAPPENED });
expect(text).toEqual('something triggered from model');
});
});
});
describe('ComponentView', function() {
describe('is an abstract class which sub classes should implement thier own "render" method', function() {
it('should throw en exception when "render" method called from own instance', function() {
var view = new tart.components.View();
var fn = function() {
view.render();
};
expect(fn).toThrow();
});
it('should render markup if sub class implemented its own "render" method', function() {
/**
* @constructor
* @extends {tart.components.View}
*/
var SubViewClass = function() {
goog.base(this);
};
goog.inherits(SubViewClass, tart.components.View);
/**
* @return {string} markup .
*/
SubViewClass.prototype.render = function() {
return '<b>this is rendered</b';
};
var subView = new SubViewClass();
expect(subView.render()).toBeTruthy();
});
});
describe('supplies dom traverse with "get" method', function() {
var SubViewClass;
beforeEach(function() {
/**
* @constructor
* @extends {tart.components.View}
*/
SubViewClass = function() {
goog.base(this);
this.domMappings = {
HEADER: 'h1'
};
};
goog.inherits(SubViewClass, tart.components.View);
SubViewClass.prototype.templates_header = function(text) {
text = text || '';
return '<h1>' + text + '</h1>';
};
SubViewClass.prototype.render = function() {
return this.templates_header();
};
});
it('should find related element on DOM', function() {
var subView = new SubViewClass();
//TODO: make it work with closure
var dummyDiv = $('<div>').append(subView.render());
subView.setDOM(dummyDiv);
expect(subView.get(subView.domMappings.HEADER)[0]).toBe(dummyDiv.find('h1')[0]);
});
it('should throw a "DOM not set yet" exception if DOM not set yet', function() {
var fn = function() {
var subView = new SubViewClass();
subView.get(subView.domMappings.HEADER);
};
expect(fn).toThrow('DOM not set yet');
});
});
});
});
/**
* Run jasmine specs
*/
tart.components.SpecRunner = function() {
jasmine.getEnv()['addReporter'](new jasmine.TrivialReporter());
jasmine.getEnv()['execute']();
}();
================================================
FILE: tart/components/spec/SpecRunner.html
================================================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="../../../third_party/jasmine/lib/jasmine.css">
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine.js"></script>
<script type="text/javascript" src="../../../third_party/jasmine/lib/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../../third_party/jquery/jquery-1.5.2.js"></script>
<script type="text/javascript" src="../../../third_party/goog/goog/base.js"></script>
<script type="text/javascript">
goog.require("goog.events.EventTarget");
</script>
<script type="text/javascript" src="../../base/Model.js"></script>
<script type="text/javascript" src="../View.js"></script>
<script type="text/javascript" src="../Controller.js"></script>
</head>
<body>
<script type="text/javascript" src="ComponentsSpec.js"></script>
</body>
</html>
================================================
FILE: tart/dataProxy/Abstract.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.dataProxy.Abstract base abstract class for local and xhr data proxies.
*/
goog.provide('tart.dataProxy.Abstract');
goog.require('goog.structs.Map');
/**
* Base model to handle xhr requests
*
* @constructor
*/
tart.dataProxy.Abstract = function() {
/** @protected **/
this.params = new goog.structs.Map();
};
/**
* Set params as hash map.
* @param {goog.structs.Map} params hash map to hold fetch params
*/
tart.dataProxy.Abstract.prototype.setParams = function (params) {
this.params = new goog.structs.Map(params);
};
/**
* Abstract method, which all inherited classes should implement
* @param {Function} callback callback method after fetch.
*/
tart.dataProxy.Abstract.prototype.fetch = function(callback) {
goog.abstractMethod();
};
================================================
FILE: tart/dataProxy/CircularLocal.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.dataProxy.CircularLocal XHR data proxy.
*/
goog.provide('tart.dataProxy.CircularLocal');
goog.require('tart.dataProxy.Local');
/**
*
* Base model to handle xhr requests
*
* @extends {tart.dataProxy.Local}
* @constructor
*/
tart.dataProxy.CircularLocal = function() {
goog.base(this);
};
goog.inherits(tart.dataProxy.CircularLocal, tart.dataProxy.Local);
/**
* Fetch data from xhr and call a function with returned data
* @param {Function=} callback function to call with returned data.
*/
tart.dataProxy.CircularLocal.prototype.fetch = function(callback) {
var fetchedData = this.getData();
var pagerParam = this.params.get('paginationParams');
if (!fetchedData || !pagerParam)
callback.call(this);
var offset = pagerParam.get('offset'),
limit = pagerParam.get('limit'),
length = fetchedData.length,
tmp = [],
pos;
if (limit > length) limit = length;
for (var i = offset, loopCount = offset + limit; i < loopCount; i++) {
pos = (i % length + length) % length;
tmp.push(fetchedData[pos]);
}
fetchedData = tmp;
callback.call(this, fetchedData);
};
================================================
FILE: tart/dataProxy/Local.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.dataProxy.Local XHR data proxy.
*/
goog.provide('tart.dataProxy.Local');
goog.require('tart.dataProxy.Abstract');
goog.require('goog.array');
/**
* Base model to handle xhr requests
*
* @extends {tart.dataProxy.Abstract}
* @constructor
*/
tart.dataProxy.Local = function() {
goog.base(this);
/** @private **/
this.data_ = undefined;
};
goog.inherits(tart.dataProxy.Local, tart.dataProxy.Abstract);
/**
* Fetch data from xhr and call a function with returned data
* @param {Function=} callback function to call with returned data.
*/
tart.dataProxy.Local.prototype.fetch = function(callback) {
var fetchedData = this.data_;
var pagerParam = this.params.get("paginationParams");
if (pagerParam) {
var offset = pagerParam.get("offset");
var limit = pagerParam.get("limit");
var tmp = [];
for(var i = offset; i < offset + limit; i++) {
if (fetchedData && fetchedData[i]) {
tmp.push(fetchedData[i]);
}
}
fetchedData = tmp;
}
callback.call(this, fetchedData);
};
tart.dataProxy.Local.prototype.setData = function(data) {
this.data_ = data;
};
tart.dataProxy.Local.prototype.getData = function() {
return this.data_;
};
================================================
FILE: tart/dataProxy/Xhr.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview tart.dataProxy.Xhr XHR data proxy.
*/
goog.provide('tart.dataProxy.Xhr');
goog.require('tart.XhrManager');
goog.require('tart.dataProxy.Abstract');
/**
* Base model to handle xhr requests
*
* @extends {tart.dataProxy.Abstract}
* @constructor
*/
tart.dataProxy.Xhr = function() {
goog.base(this);
};
goog.inherits(tart.dataProxy.Xhr, tart.dataProxy.Abstract);
/**
* Fetch data from xhr and call a function with returned data
* @param {?function(Object)} callback function to call with returned data.
* @param {function(Object)=} opt_fail function to call when request failed.
*/
tart.dataProxy.Xhr.prototype.fetch = function(callback, opt_fail) {
var url = this.params.get('url_');
this.params.remove('url_');
url = '' + url; //cast to string to make it type safe for XhrManager.get
var method = this.params.get('method_');
var methodFn;
this.params.remove('method_');
switch (method) {
case 'post' :
methodFn = tart.XhrManager.post;
break;
default:
methodFn = tart.XhrManager.get;
}
/**
* get plain objects from Maps from given plugins
*/
var pluginParams = this.params.getKeys();
for (var i = 0, ii = pluginParams.length; i < ii; i++) {
var param = this.params.get(pluginParams[i]);
if (param && param.constructor == goog.structs.Map) {
this.params.set(pluginParams[i], param.toObject());
}
else {
this.params.set(pluginParams[i], param);
}
}
methodFn(url, this.params.toObject(), callback, opt_fail);
};
================================================
FILE: tart/date/DateRange.js
================================================
// Copyright 2011 Tart. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview This file provides utility functions and classes for dateranges.
*/
gitextract_2t11nxj1/
├── .gitignore
├── .gitmodules
├── .travis.yml
├── README.md
├── gulpfile.js
├── package.json
├── scripts/
│ ├── build.sh
│ ├── compileAllSpecRunners.sh
│ ├── compileForSpecRunner.sh
│ ├── deps.sh
│ ├── jsdoc-conf.json
│ └── runAllSpecRunners.sh
├── tart/
│ ├── Builder.js
│ ├── Carousel/
│ │ ├── Carousel.js
│ │ └── spec/
│ │ ├── CarouselSpec.js
│ │ └── SpecRunner.html
│ ├── CircularCarousel/
│ │ ├── CircularCarousel.js
│ │ └── spec/
│ │ ├── CircularCarouselSpec.js
│ │ └── SpecRunner.html
│ ├── Collection.js
│ ├── DropdownList/
│ │ ├── DropdownBuilder.js
│ │ └── DropdownList.js
│ ├── Err.js
│ ├── FormValidator/
│ │ ├── FormValidator.js
│ │ ├── README.md
│ │ └── spec/
│ │ ├── FormValidatorSpec.js
│ │ └── SpecRunner.html
│ ├── List.js
│ ├── Pagination/
│ │ ├── CircularPagination.js
│ │ ├── Pagination.js
│ │ └── spec/
│ │ ├── PaginationSpec.js
│ │ └── SpecRunner.html
│ ├── Registry.js
│ ├── StateMachine/
│ │ ├── State.js
│ │ └── StateMachine.js
│ ├── Tabs/
│ │ ├── TabPanel.js
│ │ └── Tabs.js
│ ├── Validation/
│ │ ├── README.md
│ │ ├── Validation.js
│ │ └── spec/
│ │ ├── SpecRunner.html
│ │ └── ValidationSpec.js
│ ├── XhrManager.js
│ ├── base/
│ │ ├── Model.js
│ │ └── plugin/
│ │ ├── BasePlugin.js
│ │ ├── Filter.js
│ │ ├── Pager.js
│ │ └── Sorter.js
│ ├── components/
│ │ ├── Carousel/
│ │ │ ├── Controller.js
│ │ │ ├── Model.js
│ │ │ ├── Template.js
│ │ │ ├── View.js
│ │ │ └── Widget.js
│ │ ├── Controller.js
│ │ ├── RemoteModel.js
│ │ ├── ThumbnailedCarousel/
│ │ │ ├── Model.js
│ │ │ ├── SpotController.js
│ │ │ ├── SpotTemplate.js
│ │ │ ├── SpotView.js
│ │ │ ├── ThumbnailsController.js
│ │ │ ├── ThumbnailsTemplate.js
│ │ │ ├── ThumbnailsView.js
│ │ │ └── Widget.js
│ │ ├── View.js
│ │ ├── Widget.js
│ │ └── spec/
│ │ ├── ComponentsSpec.js
│ │ └── SpecRunner.html
│ ├── dataProxy/
│ │ ├── Abstract.js
│ │ ├── CircularLocal.js
│ │ ├── Local.js
│ │ └── Xhr.js
│ ├── date/
│ │ ├── DateRange.js
│ │ └── date.js
│ ├── deps.js
│ ├── dom/
│ │ └── dom.js
│ ├── events/
│ │ ├── GestureHandler.js
│ │ └── HoverHandler.js
│ ├── events.js
│ ├── externs/
│ │ ├── jasmine.externs.js
│ │ ├── jquery-1.4.4.externs.js
│ │ └── tart.externs.js
│ ├── locale/
│ │ ├── en.js
│ │ ├── locale.js
│ │ └── tr.js
│ ├── mock/
│ │ ├── index.html
│ │ └── jQuery/
│ │ └── xhr.js
│ ├── money/
│ │ ├── Currency.js
│ │ ├── CurrencyTL.js
│ │ ├── CurrencyUSD.js
│ │ └── Money.js
│ ├── mvc/
│ │ ├── Action.js
│ │ ├── Application.js
│ │ ├── Controller.js
│ │ ├── IApplication.js
│ │ ├── Layout.js
│ │ ├── MobileAction.js
│ │ ├── MobileRenderer.js
│ │ ├── Model.js
│ │ ├── README.md
│ │ ├── Renderer.js
│ │ ├── View.js
│ │ ├── mvc.js
│ │ ├── spec/
│ │ │ ├── SpecRunner.html
│ │ │ └── mvcSpec.js
│ │ ├── test/
│ │ │ ├── Bootstrapper.js
│ │ │ ├── application/
│ │ │ │ ├── controllers/
│ │ │ │ │ ├── GamesController.js
│ │ │ │ │ └── IndexController.js
│ │ │ │ ├── mvcapp.js
│ │ │ │ └── views/
│ │ │ │ ├── layouts/
│ │ │ │ │ ├── common.js
│ │ │ │ │ └── rare.js
│ │ │ │ └── scripts/
│ │ │ │ ├── games/
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── list.js
│ │ │ │ └── index/
│ │ │ │ └── list.js
│ │ │ └── index.html
│ │ └── uri/
│ │ ├── Redirection.js
│ │ ├── Request.js
│ │ ├── Route.js
│ │ └── Router.js
│ ├── storage/
│ │ └── Storage.js
│ ├── string/
│ │ └── string.js
│ ├── tart.js
│ └── ui/
│ ├── Component.js
│ ├── ComponentManager.js
│ ├── ComponentModel.js
│ ├── DlgComponent.js
│ ├── InfiniteScroll/
│ │ ├── InfiniteScrollComponent.js
│ │ ├── InfiniteScrollComponentModel.js
│ │ └── infinite-scroll.css
│ ├── NavBar/
│ │ ├── NavBarComponent.js
│ │ └── nav-bar.css
│ ├── PullToRefresh/
│ │ ├── P2RComponent.js
│ │ ├── P2RComponentModel.js
│ │ └── pull-to-refresh.css
│ ├── Sidebar/
│ │ ├── SidebarComponent.js
│ │ └── sidebar.css
│ ├── TabBar/
│ │ ├── TabBarView.js
│ │ └── tabbar.css
│ ├── View.js
│ ├── ViewManager.js
│ ├── ViewModel.js
│ ├── input/
│ │ ├── DateComponent.js
│ │ └── RevealingPassword.js
│ └── tooltip/
│ ├── TooltipComponent.js
│ └── TooltipComponentModel.js
└── third_party/
└── jquery/
└── jquery-1.5.2.js
SYMBOL INDEX (37 symbols across 2 files)
FILE: tart/externs/jquery-1.4.4.externs.js
function $ (line 53) | function $(arg1, arg2) {}
function jQuery (line 61) | function jQuery(arg1, arg2) {}
function jQueryObject (line 435) | function jQueryObject() { }
FILE: third_party/jquery/jquery-1.5.2.js
function jQuerySubclass (line 823) | function jQuerySubclass( selector, context ) {
function doScrollCheck (line 895) | function doScrollCheck() {
function resolveFunc (line 1059) | function resolveFunc( i ) {
function dataAttr (line 1602) | function dataAttr( elem, key, data ) {
function isEmptyDataObject (line 1632) | function isEmptyDataObject( obj ) {
function returnFalse (line 2732) | function returnFalse() {
function returnTrue (line 2735) | function returnTrue() {
function trigger (line 2983) | function trigger( type, elem, args ) {
function handler (line 3018) | function handler( donor ) {
function liveHandler (line 3208) | function liveHandler( event ) {
function liveConvert (line 3291) | function liveConvert( type, selector ) {
function dirNodeCheck (line 4592) | function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function dirCheck (line 4625) | function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function isDisconnected (line 4882) | function isDisconnected( node ) {
function winnow (line 5004) | function winnow( elements, qualifier, keep ) {
function root (line 5377) | function root( elem, cur ) {
function cloneCopyEvent (line 5384) | function cloneCopyEvent( src, dest ) {
function cloneFixAttributes (line 5413) | function cloneFixAttributes(src, dest) {
function getAll (line 5527) | function getAll( elem ) {
function evalScript (line 5724) | function evalScript( i, elem ) {
function getWH (line 6063) | function getWH( elem, name, extra ) {
function addToPrefiltersOrTransports (line 6167) | function addToPrefiltersOrTransports( structure ) {
function inspectPrefiltersOrTransports (line 6203) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
function done (line 6566) | function done( status, statusText, responses, headers ) {
function buildParams (line 6875) | function buildParams( prefix, obj, traditional, add ) {
function ajaxHandleResponses (line 6932) | function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert (line 6997) | function ajaxConvert( s, response ) {
function xhrOnUnloadAbort (line 7262) | function xhrOnUnloadAbort() {
function createStandardXHR (line 7272) | function createStandardXHR() {
function createActiveXHR (line 7278) | function createActiveXHR() {
function genFx (line 7723) | function genFx( type, num ) {
function t (line 7832) | function t( gotoEnd ) {
function defaultDisplay (line 7984) | function defaultDisplay( nodeName ) {
function getWindow (line 8297) | function getWindow( elem ) {
Condensed preview — 144 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (802K chars).
[
{
"path": ".gitignore",
"chars": 126,
"preview": "*.swp\n*.swo\n.idea\n*.DS_Store\n*.pyc\ncompiled/*\n/atlassian-ide-plugin.xml\ncompiled.js\nSpecRunnerCompiled.html\nnode_modules"
},
{
"path": ".gitmodules",
"chars": 294,
"preview": "[submodule \"tools\"]\n\tpath = tools\n\turl = https://github.com/tart/GUI-Tools.git\n[submodule \"third_party/jasmine\"]\n\tpath ="
},
{
"path": ".travis.yml",
"chars": 433,
"preview": "sudo: false\nlanguage: node_js\nnode_js:\n- '0.12'\ninstall:\n- npm -d install\n- npm install -g gulp\nbefore_script:\n- git con"
},
{
"path": "README.md",
"chars": 3204,
"preview": "tartJS\n======\n\ntartJS is a performance-focused JavaScript framework based on well-tested Google Closure Tools suite.\nIt "
},
{
"path": "gulpfile.js",
"chars": 917,
"preview": "var gulp = require('gulp');\nvar shell = require(\"gulp-shell\");\nvar runSequence = require('run-sequence');\n\nvar GH_TOKEN "
},
{
"path": "package.json",
"chars": 436,
"preview": "{\n \"name\": \"tartJS\",\n \"description\": \"A performance-obsessed JavaScript framework for desktop, mobile and web applicat"
},
{
"path": "scripts/build.sh",
"chars": 1346,
"preview": "#!/bin/bash\n\n#usage : scripts/build.sh ply.components.AnimatedCarouselExample.SpecRunner ply/components/AnimatedCarousel"
},
{
"path": "scripts/compileAllSpecRunners.sh",
"chars": 356,
"preview": "#!/bin/bash\n\nfor i in `find * -type f | grep -i spec | grep -i \"SpecRunner.html$\" | grep -v \"third_party\"`; \ndo\n comp"
},
{
"path": "scripts/compileForSpecRunner.sh",
"chars": 1562,
"preview": "#!/bin/bash\n\n#usage : scripts/compileForSpecRunner.sh ply/components/AnimatedCarouselExample/spec/compiled.js\n\noutputFil"
},
{
"path": "scripts/deps.sh",
"chars": 162,
"preview": "#!/bin/bash\n\n#usage : scripts/deps.sh\n\nthird_party/goog/closure/bin/build/depswriter.py --root_with_prefix='tart/ ../../"
},
{
"path": "scripts/jsdoc-conf.json",
"chars": 1004,
"preview": "{\n \"tags\": {\n \"allowUnknownTags\": true,\n \"dictionaries\": [\"closure\", \"jsdoc\"]\n },\n \"source\": {\n\t\""
},
{
"path": "scripts/runAllSpecRunners.sh",
"chars": 285,
"preview": "#!/bin/bash\n\n#run all SpecRunner*html files using qasmine\n\nfor i in `find * -type f | grep -v third_party | grep -i Spec"
},
{
"path": "tart/Builder.js",
"chars": 1645,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Carousel/Carousel.js",
"chars": 8049,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Carousel/spec/CarouselSpec.js",
"chars": 2557,
"preview": "goog.require('tart.Carousel');\n\ngoog.provide('tart.Carousel.SpecRunner');\n\ndescribe('Carousel', function() {\n var car"
},
{
"path": "tart/Carousel/spec/SpecRunner.html",
"chars": 1053,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/CircularCarousel/CircularCarousel.js",
"chars": 4170,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/CircularCarousel/spec/CircularCarouselSpec.js",
"chars": 3527,
"preview": "goog.require('tart.CircularCarousel');\n\ngoog.provide('tart.CircularCarousel.SpecRunner');\n\ndescribe('CircularCarousel', "
},
{
"path": "tart/CircularCarousel/spec/SpecRunner.html",
"chars": 1078,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/Collection.js",
"chars": 7992,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/DropdownList/DropdownBuilder.js",
"chars": 3953,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/DropdownList/DropdownList.js",
"chars": 4206,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Err.js",
"chars": 1560,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/FormValidator/FormValidator.js",
"chars": 6685,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/FormValidator/README.md",
"chars": 1563,
"preview": "# Tart FormValidator\n\nA JavaScript validation library which validates form elements using tart.Validation\n\n## Testing sp"
},
{
"path": "tart/FormValidator/spec/FormValidatorSpec.js",
"chars": 16681,
"preview": "goog.require('tart.FormValidator');\n\ngoog.provide('tart.FormValidator.SpecRunner');\n\ndescribe('Form Validator', function"
},
{
"path": "tart/FormValidator/spec/SpecRunner.html",
"chars": 934,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/List.js",
"chars": 1229,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Pagination/CircularPagination.js",
"chars": 2073,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Pagination/Pagination.js",
"chars": 5669,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Pagination/spec/PaginationSpec.js",
"chars": 5124,
"preview": "goog.require('tart.Pagination');\n\ngoog.provide('tart.Pagination.SpecRunner');\n\ndescribe('Pagination', function() {\n v"
},
{
"path": "tart/Pagination/spec/SpecRunner.html",
"chars": 987,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/Registry.js",
"chars": 583,
"preview": "// Copyright (c) 2009-2010 Techinox Information Technologies (http://www.techinox.com)\n// Techinox Commercial License\n//"
},
{
"path": "tart/StateMachine/State.js",
"chars": 1112,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/StateMachine/StateMachine.js",
"chars": 5723,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Tabs/TabPanel.js",
"chars": 2689,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Tabs/Tabs.js",
"chars": 8197,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Validation/README.md",
"chars": 931,
"preview": "# Tart Validator\n\nA JavaScript validation library\n\n## Testing specs\n\nYou need [jasmine](http://pivotal.github.com/jasmin"
},
{
"path": "tart/Validation/Validation.js",
"chars": 4179,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/Validation/spec/SpecRunner.html",
"chars": 854,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/Validation/spec/ValidationSpec.js",
"chars": 8722,
"preview": "goog.require('tart.Validation');\n\ngoog.provide('tart.Validation.SpecRunner');\n\ndescribe('Validation', function() {\n v"
},
{
"path": "tart/XhrManager.js",
"chars": 2495,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/base/Model.js",
"chars": 2723,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/base/plugin/BasePlugin.js",
"chars": 1652,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/base/plugin/Filter.js",
"chars": 1674,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/base/plugin/Pager.js",
"chars": 3940,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/base/plugin/Sorter.js",
"chars": 2023,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/components/Carousel/Controller.js",
"chars": 4296,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/Carousel/Model.js",
"chars": 3130,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/Carousel/Template.js",
"chars": 2280,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/Carousel/View.js",
"chars": 6568,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/Carousel/Widget.js",
"chars": 827,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/Controller.js",
"chars": 2539,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/components/RemoteModel.js",
"chars": 1882,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n/**\n * @fileoverview"
},
{
"path": "tart/components/ThumbnailedCarousel/Model.js",
"chars": 847,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n\ngoog.require('tart."
},
{
"path": "tart/components/ThumbnailedCarousel/SpotController.js",
"chars": 2654,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n\ngoog.require('tart."
},
{
"path": "tart/components/ThumbnailedCarousel/SpotTemplate.js",
"chars": 1060,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\ngoog.require('tart.c"
},
{
"path": "tart/components/ThumbnailedCarousel/SpotView.js",
"chars": 887,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.trr>\n\ngoog.require('tart"
},
{
"path": "tart/components/ThumbnailedCarousel/ThumbnailsController.js",
"chars": 2827,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n\ngoog.require('tart."
},
{
"path": "tart/components/ThumbnailedCarousel/ThumbnailsTemplate.js",
"chars": 623,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\ngoog.require('tart.c"
},
{
"path": "tart/components/ThumbnailedCarousel/ThumbnailsView.js",
"chars": 682,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.trr>\n\ngoog.require('tart"
},
{
"path": "tart/components/ThumbnailedCarousel/Widget.js",
"chars": 649,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// @author Firat Yalavuz firat.yalavuz@tart.com.tr\n\n\ngoog.require('tart."
},
{
"path": "tart/components/View.js",
"chars": 3195,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/components/Widget.js",
"chars": 1937,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/components/spec/ComponentsSpec.js",
"chars": 5940,
"preview": "goog.require('tart.components.Controller');\ngoog.require('tart.base.Model');\ngoog.require('tart.components.View');\n\ngoog"
},
{
"path": "tart/components/spec/SpecRunner.html",
"chars": 1080,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/dataProxy/Abstract.js",
"chars": 1401,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/dataProxy/CircularLocal.js",
"chars": 1800,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/dataProxy/Local.js",
"chars": 1894,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/dataProxy/Xhr.js",
"chars": 2236,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/date/DateRange.js",
"chars": 1519,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/date/date.js",
"chars": 3936,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/deps.js",
"chars": 15950,
"preview": "// This file was autogenerated by third_party/goog/closure/bin/build/depswriter.py.\n// Please do not edit.\ngoog.addDepen"
},
{
"path": "tart/dom/dom.js",
"chars": 1494,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/events/GestureHandler.js",
"chars": 5977,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/events/HoverHandler.js",
"chars": 2621,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/events.js",
"chars": 647,
"preview": "// Copyright (c) 2012 Tart New Media (http://www.tart.com.tr)\n// Tart Commercial License\n//\n// @author Sönmez Kartal <so"
},
{
"path": "tart/externs/jasmine.externs.js",
"chars": 3992,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/externs/jquery-1.4.4.externs.js",
"chars": 29746,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/externs/tart.externs.js",
"chars": 882,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/locale/en.js",
"chars": 699,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/locale/locale.js",
"chars": 2010,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/locale/tr.js",
"chars": 698,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/mock/index.html",
"chars": 745,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/mock/jQuery/xhr.js",
"chars": 1635,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/money/Currency.js",
"chars": 1745,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/money/CurrencyTL.js",
"chars": 1099,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/money/CurrencyUSD.js",
"chars": 1105,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/money/Money.js",
"chars": 3144,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/Action.js",
"chars": 2458,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/Application.js",
"chars": 5422,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/Controller.js",
"chars": 707,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/IApplication.js",
"chars": 1687,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/Layout.js",
"chars": 3152,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/MobileAction.js",
"chars": 1085,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/MobileRenderer.js",
"chars": 4150,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/Model.js",
"chars": 697,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/README.md",
"chars": 573,
"preview": "# tart.mvc\nTart MVC framework is a classical web MVC framework for Javascript. The framework is based upon Google Closur"
},
{
"path": "tart/mvc/Renderer.js",
"chars": 3671,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/View.js",
"chars": 1145,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/mvc.js",
"chars": 1139,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/spec/SpecRunner.html",
"chars": 1072,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n "
},
{
"path": "tart/mvc/spec/mvcSpec.js",
"chars": 3938,
"preview": "describe('MVC', function() {\n var app = new tart.mvc.Application(),\n basePath = '/',\n defaultRoute = ne"
},
{
"path": "tart/mvc/test/Bootstrapper.js",
"chars": 880,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/controllers/GamesController.js",
"chars": 2129,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/controllers/IndexController.js",
"chars": 1461,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/mvcapp.js",
"chars": 2508,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/views/layouts/common.js",
"chars": 903,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/views/layouts/rare.js",
"chars": 1093,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/views/scripts/games/index.js",
"chars": 1176,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/views/scripts/games/list.js",
"chars": 826,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/application/views/scripts/index/list.js",
"chars": 796,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/test/index.html",
"chars": 577,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <title></title>\n <script type=\"text/javascript\" src=\"../../../third_party/jquery/jq"
},
{
"path": "tart/mvc/uri/Redirection.js",
"chars": 1037,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/uri/Request.js",
"chars": 2309,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/uri/Route.js",
"chars": 2180,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/mvc/uri/Router.js",
"chars": 16057,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/storage/Storage.js",
"chars": 2755,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/string/string.js",
"chars": 5963,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/tart.js",
"chars": 2655,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/Component.js",
"chars": 4009,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/ComponentManager.js",
"chars": 5419,
"preview": "// Copyright (c) 2009-2012 Techinox Information Technologies (http://www.techinox.com)\n// Techinox Commercial License\n//"
},
{
"path": "tart/ui/ComponentModel.js",
"chars": 1208,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/DlgComponent.js",
"chars": 4020,
"preview": "// Copyright 2011 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/InfiniteScroll/InfiniteScrollComponent.js",
"chars": 4445,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/InfiniteScroll/InfiniteScrollComponentModel.js",
"chars": 2575,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/InfiniteScroll/infinite-scroll.css",
"chars": 10206,
"preview": ".inf-scroll {\n display: block;\n height: 140px;\n width: 100%;\n color: rgba(0, 0, 0, 0.48);\n text-shadow: 0"
},
{
"path": "tart/ui/NavBar/NavBarComponent.js",
"chars": 2954,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/NavBar/nav-bar.css",
"chars": 791,
"preview": "nav-bar, back-button, logo, share {\n display: block;\n position: absolute;\n}\n\nnav-bar {\n height: 90px;\n width"
},
{
"path": "tart/ui/PullToRefresh/P2RComponent.js",
"chars": 6010,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/PullToRefresh/P2RComponentModel.js",
"chars": 2514,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/PullToRefresh/pull-to-refresh.css",
"chars": 10287,
"preview": ".pull-to-refresh {\n position: absolute;\n top: 0px;\n display: block;\n height: 140px;\n width: 100%;\n fon"
},
{
"path": "tart/ui/Sidebar/SidebarComponent.js",
"chars": 2244,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/Sidebar/sidebar.css",
"chars": 678,
"preview": "sidebar-view {\n background: #eee;\n position: absolute;\n -webkit-transition-duration: 0s;\n display: block;\n "
},
{
"path": "tart/ui/TabBar/TabBarView.js",
"chars": 3324,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/TabBar/tabbar.css",
"chars": 564,
"preview": "tab-bar {\n position: absolute;\n bottom: 0;\n height: 120px;\n width: 100%;\n text-align: center;\n line-he"
},
{
"path": "tart/ui/View.js",
"chars": 4377,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/ViewManager.js",
"chars": 17184,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/ViewModel.js",
"chars": 920,
"preview": "// Copyright 2014 Startup Kitchen. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Licen"
},
{
"path": "tart/ui/input/DateComponent.js",
"chars": 4140,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/input/RevealingPassword.js",
"chars": 3563,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/tooltip/TooltipComponent.js",
"chars": 14889,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "tart/ui/tooltip/TooltipComponentModel.js",
"chars": 6223,
"preview": "// Copyright 2012 Tart. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// yo"
},
{
"path": "third_party/jquery/jquery-1.5.2.js",
"chars": 309316,
"preview": "/*!\n * jQuery JavaScript Library v1.5.2\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under th"
}
]
About this extraction
This page contains the full source code of the tart/tartJS GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 144 files (749.3 KB), approximately 178.3k tokens, and a symbol index with 37 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.