introduced bower to manage js dependencies

also updated ic-ajax

closes CNVS-9979, CNVS-9981

Change-Id: I9cdfa997ea0df8de4b2900eac17c438369f92f2d
Reviewed-on: https://gerrit.instructure.com/27316
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jason Madsen <jmadsen@instructure.com>
Product-Review: Ryan Florence <ryanf@instructure.com>
QA-Review: Ryan Florence <ryanf@instructure.com>
This commit is contained in:
Ryan Florence 2013-12-11 15:47:17 -07:00
parent e9e7535789
commit 8350218104
77 changed files with 93687 additions and 9 deletions

3
.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "public/javascripts/bower"
}

View File

@ -12,5 +12,4 @@ define [
model: (params) ->
environment.setEnv(ENV)
id = environment.get('courseId')
ajax("/api/v1/courses/#{id}/quizzes").then (result) ->
result.response
ajax("/api/v1/courses/#{id}/quizzes")

View File

@ -6,7 +6,7 @@ define [
fetch = (url, records, data) ->
opts = $.extend({dataType: "json"}, {data: data})
ajax(url, opts).then (result) ->
ajax.raw(url, opts).then (result) ->
records.pushObjects result.response
meta = parseLinkHeader result.jqXHR
if meta.next

View File

@ -10,6 +10,7 @@
translate: <%= include_js_translations? %>,
baseUrl: '<%= js_base_url %>',
paths: <%= raw Canvas::RequireJs.paths(true) %>,
packages : <%= raw Canvas::RequireJs.packages %>,
use: <%= raw Canvas::RequireJs.shims %>
};
</script>

9
bower.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "canvas-lms",
"version": "0.0.0",
"private": true,
"dependencies": {
"ic-ajax": "~0.2.0",
"ic-menu": "~0.1.0"
}
}

View File

@ -19,6 +19,8 @@
paths: <%= paths %>,
packages: <%= packages %>,
// non-amd shims
use: <%= shims %>,

View File

@ -63,12 +63,18 @@ module Canvas
:jqueryui => 'vendor/jqueryui',
:use => 'vendor/use',
:uploadify => '../flash/uploadify/jquery.uploadify-3.1.min',
'ic-menu' => 'vendor/ic-menu/dist/main.amd',
'ic-dialog' => 'vendor/ic-dialog/dist/main.amd',
'ic-ajax' => 'vendor/ic-ajax/main',
}.update(cache_busting ? cache_busting_paths : {}).update(plugin_paths).update(Canvas::RequireJs::PluginExtension.paths).to_json.gsub(/([,{])/, "\\1\n ")
end
def packages
@packages ||= [
{'name' => 'ic-ajax', 'location' => 'bower/ic-ajax'},
{'name' => 'ic-styled', 'location' => 'bower/ic-styled'},
{'name' => 'ic-menu', 'location' => 'bower/ic-menu'},
].to_json
end
def plugin_paths
@plugin_paths ||= begin
Dir['public/javascripts/plugins/*'].inject({}) { |hash, plugin|

View File

@ -3,6 +3,5 @@ define ['ember', 'ic-ajax'], (Ember, ajax) ->
{{routeName}} = Ember.Route.extend
model: ->
ajax('/api/v1/users/self/activity_stream').then ({response}) ->
response
ajax '/api/v1/users/self/activity_stream'

View File

@ -0,0 +1,6 @@
currently just using this for `ic-<foo>` installs, not jquery, or ember, etc,
but we intend to eventually use bower for all of our third-party javascript.
we also check these deps in so we don't rely on github and others being up to
run our tests and deploy

View File

@ -0,0 +1,21 @@
{
"name": "ember",
"version": "1.2.0",
"main": [
"./ember.js"
],
"dependencies": {
"jquery": ">= 1.7",
"handlebars": ">= 1.0.0"
},
"homepage": "https://github.com/components/ember",
"_release": "1.2.0",
"_resolution": {
"type": "version",
"tag": "1.2.0",
"commit": "05c00c68fb5a2e7d153b4b5ef2611c1da45904be"
},
"_source": "git://github.com/components/ember.git",
"_target": "1.2.0",
"_originalSource": "ember"
}

View File

@ -0,0 +1,5 @@
vendor
composer.lock
components
node_modules
emberjs

View File

@ -0,0 +1,9 @@
VERSION=v1.2.0
default:
@curl -O http://builds.emberjs.com/tags/$(VERSION)/ember.js
@curl -O http://builds.emberjs.com/tags/$(VERSION)/ember.min.js
@curl -O http://builds.emberjs.com/tags/$(VERSION)/ember.prod.js
@curl -O http://builds.emberjs.com/tags/$(VERSION)/ember-template-compiler.js
.PHONY: default

View File

@ -0,0 +1,12 @@
Ember.js
========
Shim repository for [Ember Application Framework](http://emberjs.com/).
This package provides the core of the ember.js framework.
Package Managers
----------------
* [Bower](http://bower.io): `ember`
* [Composer](http://packagist.org/packages/components/ember): `components/ember`

View File

@ -0,0 +1,11 @@
{
"name": "ember",
"version": "1.2.0",
"main": [
"./ember.js"
],
"dependencies": {
"jquery": ">= 1.7",
"handlebars": ">= 1.0.0"
}
}

View File

@ -0,0 +1,13 @@
{
"name": "ember",
"repo": "components/ember",
"version": "1.2.0",
"main": "ember.js",
"scripts": [
"ember.js"
],
"dependencies": {
"component/jquery": ">= 1.7",
"components/handlebars.js": "1.0.0"
}
}

View File

@ -0,0 +1,27 @@
{
"name": "components/ember",
"description": "A framework for creating ambitious web applications.",
"type": "component",
"license": "MIT",
"require": {
"components/jquery": ">=1.7",
"components/handlebars.js": "1.*"
},
"extra": {
"component": {
"scripts": [
"ember.js"
],
"files": [
"ember.min.js"
],
"shim": {
"exports": "Ember",
"deps": [
"jquery",
"handlebars"
]
}
}
}
}

View File

@ -0,0 +1,325 @@
(function() {
var Ember = { assert: function() {}, FEATURES: { isEnabled: function() {} } };
// ==========================================================================
// Project: Ember - JavaScript Application Framework
// Copyright: Copyright 2011-2013 Tilde Inc. and contributors
// Portions Copyright 2006-2011 Strobe Inc.
// Portions Copyright 2008-2011 Apple Inc. All rights reserved.
// License: Licensed under MIT license
// See https://raw.github.com/emberjs/ember.js/master/LICENSE
// ==========================================================================
// Version: 1.2.0
(function() {
/**
@module ember
@submodule ember-handlebars-compiler
*/
// Eliminate dependency on any Ember to simplify precompilation workflow
var objectCreate = Object.create || function(parent) {
function F() {}
F.prototype = parent;
return new F();
};
var Handlebars = this.Handlebars || (Ember.imports && Ember.imports.Handlebars);
if (!Handlebars && typeof require === 'function') {
Handlebars = require('handlebars');
}
Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember.", Handlebars);
Ember.assert("Ember Handlebars requires Handlebars version 1.0 or 1.1, COMPILER_REVISION expected: 4, got: " + Handlebars.COMPILER_REVISION + " - Please note: Builds of master may have other COMPILER_REVISION values.", Handlebars.COMPILER_REVISION === 4);
/**
Prepares the Handlebars templating library for use inside Ember's view
system.
The `Ember.Handlebars` object is the standard Handlebars library, extended to
use Ember's `get()` method instead of direct property access, which allows
computed properties to be used inside templates.
To create an `Ember.Handlebars` template, call `Ember.Handlebars.compile()`.
This will return a function that can be used by `Ember.View` for rendering.
@class Handlebars
@namespace Ember
*/
Ember.Handlebars = objectCreate(Handlebars);
/**
Register a bound helper or custom view helper.
## Simple bound helper example
```javascript
Ember.Handlebars.helper('capitalize', function(value) {
return value.toUpperCase();
});
```
The above bound helper can be used inside of templates as follows:
```handlebars
{{capitalize name}}
```
In this case, when the `name` property of the template's context changes,
the rendered value of the helper will update to reflect this change.
For more examples of bound helpers, see documentation for
`Ember.Handlebars.registerBoundHelper`.
## Custom view helper example
Assuming a view subclass named `App.CalendarView` were defined, a helper
for rendering instances of this view could be registered as follows:
```javascript
Ember.Handlebars.helper('calendar', App.CalendarView):
```
The above bound helper can be used inside of templates as follows:
```handlebars
{{calendar}}
```
Which is functionally equivalent to:
```handlebars
{{view App.CalendarView}}
```
Options in the helper will be passed to the view in exactly the same
manner as with the `view` helper.
@method helper
@for Ember.Handlebars
@param {String} name
@param {Function|Ember.View} function or view class constructor
@param {String} dependentKeys*
*/
Ember.Handlebars.helper = function(name, value) {
Ember.assert("You tried to register a component named '" + name + "', but component names must include a '-'", !Ember.Component.detect(value) || name.match(/-/));
if (Ember.View.detect(value)) {
Ember.Handlebars.registerHelper(name, Ember.Handlebars.makeViewHelper(value));
} else {
Ember.Handlebars.registerBoundHelper.apply(null, arguments);
}
};
/**
@private
Returns a helper function that renders the provided ViewClass.
Used internally by Ember.Handlebars.helper and other methods
involving helper/component registration.
@method helper
@for Ember.Handlebars
@param {Function} ViewClass view class constructor
*/
Ember.Handlebars.makeViewHelper = function(ViewClass) {
return function(options) {
Ember.assert("You can only pass attributes (such as name=value) not bare values to a helper for a View", arguments.length < 2);
return Ember.Handlebars.helpers.view.call(this, ViewClass, options);
};
};
/**
@class helpers
@namespace Ember.Handlebars
*/
Ember.Handlebars.helpers = objectCreate(Handlebars.helpers);
/**
Override the the opcode compiler and JavaScript compiler for Handlebars.
@class Compiler
@namespace Ember.Handlebars
@private
@constructor
*/
Ember.Handlebars.Compiler = function() {};
// Handlebars.Compiler doesn't exist in runtime-only
if (Handlebars.Compiler) {
Ember.Handlebars.Compiler.prototype = objectCreate(Handlebars.Compiler.prototype);
}
Ember.Handlebars.Compiler.prototype.compiler = Ember.Handlebars.Compiler;
/**
@class JavaScriptCompiler
@namespace Ember.Handlebars
@private
@constructor
*/
Ember.Handlebars.JavaScriptCompiler = function() {};
// Handlebars.JavaScriptCompiler doesn't exist in runtime-only
if (Handlebars.JavaScriptCompiler) {
Ember.Handlebars.JavaScriptCompiler.prototype = objectCreate(Handlebars.JavaScriptCompiler.prototype);
Ember.Handlebars.JavaScriptCompiler.prototype.compiler = Ember.Handlebars.JavaScriptCompiler;
}
Ember.Handlebars.JavaScriptCompiler.prototype.namespace = "Ember.Handlebars";
Ember.Handlebars.JavaScriptCompiler.prototype.initializeBuffer = function() {
return "''";
};
/**
@private
Override the default buffer for Ember Handlebars. By default, Handlebars
creates an empty String at the beginning of each invocation and appends to
it. Ember's Handlebars overrides this to append to a single shared buffer.
@method appendToBuffer
@param string {String}
*/
Ember.Handlebars.JavaScriptCompiler.prototype.appendToBuffer = function(string) {
return "data.buffer.push("+string+");";
};
// Hacks ahead:
// Handlebars presently has a bug where the `blockHelperMissing` hook
// doesn't get passed the name of the missing helper name, but rather
// gets passed the value of that missing helper evaluated on the current
// context, which is most likely `undefined` and totally useless.
//
// So we alter the compiled template function to pass the name of the helper
// instead, as expected.
//
// This can go away once the following is closed:
// https://github.com/wycats/handlebars.js/issues/617
var DOT_LOOKUP_REGEX = /helpers\.(.*?)\)/,
BRACKET_STRING_LOOKUP_REGEX = /helpers\['(.*?)'/,
INVOCATION_SPLITTING_REGEX = /(.*blockHelperMissing\.call\(.*)(stack[0-9]+)(,.*)/;
Ember.Handlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation = function(source) {
var helperInvocation = source[source.length - 1],
helperName = (DOT_LOOKUP_REGEX.exec(helperInvocation) || BRACKET_STRING_LOOKUP_REGEX.exec(helperInvocation))[1],
matches = INVOCATION_SPLITTING_REGEX.exec(helperInvocation);
source[source.length - 1] = matches[1] + "'" + helperName + "'" + matches[3];
}
var stringifyBlockHelperMissing = Ember.Handlebars.JavaScriptCompiler.stringifyLastBlockHelperMissingInvocation;
var originalBlockValue = Ember.Handlebars.JavaScriptCompiler.prototype.blockValue;
Ember.Handlebars.JavaScriptCompiler.prototype.blockValue = function() {
originalBlockValue.apply(this, arguments);
stringifyBlockHelperMissing(this.source);
};
var originalAmbiguousBlockValue = Ember.Handlebars.JavaScriptCompiler.prototype.ambiguousBlockValue;
Ember.Handlebars.JavaScriptCompiler.prototype.ambiguousBlockValue = function() {
originalAmbiguousBlockValue.apply(this, arguments);
stringifyBlockHelperMissing(this.source);
};
var prefix = "ember" + (+new Date()), incr = 1;
/**
@private
Rewrite simple mustaches from `{{foo}}` to `{{bind "foo"}}`. This means that
all simple mustaches in Ember's Handlebars will also set up an observer to
keep the DOM up to date when the underlying property changes.
@method mustache
@for Ember.Handlebars.Compiler
@param mustache
*/
Ember.Handlebars.Compiler.prototype.mustache = function(mustache) {
if (mustache.isHelper && mustache.id.string === 'control') {
mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
mustache.hash.pairs.push(["controlID", new Handlebars.AST.StringNode(prefix + incr++)]);
} else if (mustache.params.length || mustache.hash) {
// no changes required
} else {
var id = new Handlebars.AST.IdNode([{ part: '_triageMustache' }]);
// Update the mustache node to include a hash value indicating whether the original node
// was escaped. This will allow us to properly escape values when the underlying value
// changes and we need to re-render the value.
if (!mustache.escaped) {
mustache.hash = mustache.hash || new Handlebars.AST.HashNode([]);
mustache.hash.pairs.push(["unescaped", new Handlebars.AST.StringNode("true")]);
}
mustache = new Handlebars.AST.MustacheNode([id].concat([mustache.id]), mustache.hash, !mustache.escaped);
}
return Handlebars.Compiler.prototype.mustache.call(this, mustache);
};
/**
Used for precompilation of Ember Handlebars templates. This will not be used
during normal app execution.
@method precompile
@for Ember.Handlebars
@static
@param {String} string The template to precompile
*/
Ember.Handlebars.precompile = function(string) {
var ast = Handlebars.parse(string);
var options = {
knownHelpers: {
action: true,
unbound: true,
bindAttr: true,
template: true,
view: true,
_triageMustache: true
},
data: true,
stringParams: true
};
var environment = new Ember.Handlebars.Compiler().compile(ast, options);
return new Ember.Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
};
// We don't support this for Handlebars runtime-only
if (Handlebars.compile) {
/**
The entry point for Ember Handlebars. This replaces the default
`Handlebars.compile` and turns on template-local data and String
parameters.
@method compile
@for Ember.Handlebars
@static
@param {String} string The template to compile
@return {Function}
*/
Ember.Handlebars.compile = function(string) {
var ast = Handlebars.parse(string);
var options = { data: true, stringParams: true };
var environment = new Ember.Handlebars.Compiler().compile(ast, options);
var templateSpec = new Ember.Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
var template = Ember.Handlebars.template(templateSpec);
template.isMethod = false; //Make sure we don't wrap templates with ._super
return template;
};
}
})();
exports.precompile = Ember.Handlebars.precompile;
exports.EmberHandlebars = Ember.Handlebars;
})();

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
{
"name": "components-ember",
"version": "1.2.0-beta.4",
"description": "Ember Application Framework",
"keywords": ["ember"],
"main": "./ember.js",
"dependencies": {
"jquery": "*",
"handlebars": "*"
}
}

View File

@ -0,0 +1,16 @@
{
"name": "handlebars",
"version": "1.1.2",
"main": "handlebars.js",
"dependencies": {},
"homepage": "https://github.com/components/handlebars.js",
"_release": "1.1.2",
"_resolution": {
"type": "version",
"tag": "v1.1.2",
"commit": "3ea87359ecb42a65a24bffc53e318352d55cb6b4"
},
"_source": "git://github.com/components/handlebars.js.git",
"_target": ">= 1.0.0",
"_originalSource": "handlebars"
}

View File

@ -0,0 +1,2 @@
vendor
composer.lock

View File

@ -0,0 +1,11 @@
Handlebars.js
=============
Shim repository for [Handlebars.js](http://handlebarsjs.com).
Package Managers
----------------
* [Bower](http://twitter.github.com/bower/): `handlebars`
* [Component](http://github.com/component/component): `components/handlebars.js`
* [Composer](http://packagist.org/packages/components/handlebars.js): `components/handlebars.js`

View File

@ -0,0 +1,6 @@
{
"name": "handlebars",
"version": "1.1.2",
"main": "handlebars.js",
"dependencies": {}
}

View File

@ -0,0 +1,9 @@
{
"name": "handlebars",
"repo": "components/handlebars.js",
"version": "1.0.0",
"main": "handlebars.js",
"scripts": [
"handlebars.js"
]
}

View File

@ -0,0 +1,35 @@
{
"name": "components/handlebars.js",
"description": "Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be.",
"homepage": "http://handlebarsjs.com",
"license": "MIT",
"type": "component",
"keywords": [
"handlebars",
"mustache",
"html"
],
"authors": [
{
"name": "Chris Wanstrath",
"homepage": "http://chriswanstrath.com"
}
],
"require": {
"robloach/component-installer": "*"
},
"extra": {
"component": {
"name": "handlebars",
"scripts": [
"handlebars.js"
],
"files": [
"handlebars.runtime.js"
],
"shim": {
"exports": "Handlebars"
}
}
}
}

View File

@ -0,0 +1,21 @@
# -*- encoding: utf-8 -*-
require 'json'
package = JSON.parse(File.read('bower.json'))
Gem::Specification.new do |gem|
gem.name = "handlebars-source"
gem.authors = ["Yehuda Katz"]
gem.email = ["wycats@gmail.com"]
gem.date = Time.now.strftime("%Y-%m-%d")
gem.description = %q{Handlebars.js source code wrapper for (pre)compilation gems.}
gem.summary = %q{Handlebars.js source code wrapper}
gem.homepage = "https://github.com/wycats/handlebars.js/"
gem.version = package["version"]
gem.files = [
'handlebars.js',
'handlebars.runtime.js',
'lib/handlebars/source.rb'
]
end

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<package>
<metadata>
<id>handlebars.js</id>
<version>1.1.2</version>
<authors>handlebars.js Authors</authors>
<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Extension of the Mustache logicless template language</description>
<releaseNotes></releaseNotes>
<tags>handlebars mustache template html</tags>
</metadata>
<files>
<file src="handlebars.js" target="Content\Scripts" />
</files>
</package>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,504 @@
/*!
handlebars v1.1.2
Copyright (C) 2011 by Yehuda Katz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@license
*/
define(
'handlebars/safe-string',["exports"],
function(__exports__) {
// Build out our basic SafeString type
function SafeString(string) {
this.string = string;
}
SafeString.prototype.toString = function() {
return "" + this.string;
};
__exports__["default"] = SafeString;
});
define(
'handlebars/utils',["./safe-string","exports"],
function(__dependency1__, __exports__) {
var SafeString = __dependency1__["default"];
var escape = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#x27;",
"`": "&#x60;"
};
var badChars = /[&<>"'`]/g;
var possible = /[&<>"'`]/;
function escapeChar(chr) {
return escape[chr] || "&amp;";
}
function extend(obj, value) {
for(var key in value) {
if(value.hasOwnProperty(key)) {
obj[key] = value[key];
}
}
}
__exports__.extend = extend;var toString = Object.prototype.toString;
__exports__.toString = toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
if (isFunction(/x/)) {
isFunction = function(value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
var isFunction;
__exports__.isFunction = isFunction;
var isArray = Array.isArray || function(value) {
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
};
__exports__.isArray = isArray;
function escapeExpression(string) {
// don't escape SafeStrings, since they're already safe
if (string instanceof SafeString) {
return string.toString();
} else if (!string && string !== 0) {
return "";
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = "" + string;
if(!possible.test(string)) { return string; }
return string.replace(badChars, escapeChar);
}
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
if (!value && value !== 0) {
return true;
} else if (isArray(value) && value.length === 0) {
return true;
} else {
return false;
}
}
__exports__.isEmpty = isEmpty;
});
define(
'handlebars/exception',["exports"],
function(__exports__) {
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
function Exception(/* message */) {
var tmp = Error.prototype.constructor.apply(this, arguments);
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
}
Exception.prototype = new Error();
__exports__["default"] = Exception;
});
define(
'handlebars/base',["./utils","./exception","exports"],
function(__dependency1__, __dependency2__, __exports__) {
/*globals Exception, Utils */
var Utils = __dependency1__;
var Exception = __dependency2__["default"];
var VERSION = "1.1.2";
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
__exports__.COMPILER_REVISION = COMPILER_REVISION;
var REVISION_CHANGES = {
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
2: '== 1.0.0-rc.3',
3: '== 1.0.0-rc.4',
4: '>= 1.0.0'
};
__exports__.REVISION_CHANGES = REVISION_CHANGES;
var isArray = Utils.isArray,
isFunction = Utils.isFunction,
toString = Utils.toString,
objectType = '[object Object]';
function HandlebarsEnvironment(helpers, partials) {
this.helpers = helpers || {};
this.partials = partials || {};
registerDefaultHelpers(this);
}
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
constructor: HandlebarsEnvironment,
logger: logger,
log: log,
registerHelper: function(name, fn, inverse) {
if (toString.call(name) === objectType) {
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
Utils.extend(this.helpers, name);
} else {
if (inverse) { fn.not = inverse; }
this.helpers[name] = fn;
}
},
registerPartial: function(name, str) {
if (toString.call(name) === objectType) {
Utils.extend(this.partials, name);
} else {
this.partials[name] = str;
}
}
};
function registerDefaultHelpers(instance) {
instance.registerHelper('helperMissing', function(arg) {
if(arguments.length === 2) {
return undefined;
} else {
throw new Error("Missing helper: '" + arg + "'");
}
});
instance.registerHelper('blockHelperMissing', function(context, options) {
var inverse = options.inverse || function() {}, fn = options.fn;
if (isFunction(context)) { context = context.call(this); }
if(context === true) {
return fn(this);
} else if(context === false || context == null) {
return inverse(this);
} else if (isArray(context)) {
if(context.length > 0) {
return instance.helpers.each(context, options);
} else {
return inverse(this);
}
} else {
return fn(context);
}
});
instance.registerHelper('each', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var i = 0, ret = "", data;
if (isFunction(context)) { context = context.call(this); }
if (options.data) {
data = createFrame(options.data);
}
if(context && typeof context === 'object') {
if (isArray(context)) {
for(var j = context.length; i<j; i++) {
if (data) {
data.index = i;
data.first = (i === 0)
data.last = (i === (context.length-1));
}
ret = ret + fn(context[i], { data: data });
}
} else {
for(var key in context) {
if(context.hasOwnProperty(key)) {
if(data) { data.key = key; }
ret = ret + fn(context[key], {data: data});
i++;
}
}
}
}
if(i === 0){
ret = inverse(this);
}
return ret;
});
instance.registerHelper('if', function(conditional, options) {
if (isFunction(conditional)) { conditional = conditional.call(this); }
// Default behavior is to render the positive path if the value is truthy and not empty.
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
instance.registerHelper('unless', function(conditional, options) {
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
});
instance.registerHelper('with', function(context, options) {
if (isFunction(context)) { context = context.call(this); }
if (!Utils.isEmpty(context)) return options.fn(context);
});
instance.registerHelper('log', function(context, options) {
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
instance.log(level, context);
});
}
var logger = {
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
// State enum
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
level: 3,
// can be overridden in the host environment
log: function(level, obj) {
if (logger.level <= level) {
var method = logger.methodMap[level];
if (typeof console !== 'undefined' && console[method]) {
console[method].call(console, obj);
}
}
}
};
__exports__.logger = logger;
function log(level, obj) { logger.log(level, obj); }
__exports__.log = log;var createFrame = function(object) {
var obj = {};
Utils.extend(obj, object);
return obj;
};
__exports__.createFrame = createFrame;
});
define(
'handlebars/runtime',["./utils","./exception","./base","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
/*global Utils */
var Utils = __dependency1__;
var Exception = __dependency2__["default"];
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
function checkRevision(compilerInfo) {
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
currentRevision = COMPILER_REVISION;
if (compilerRevision !== currentRevision) {
if (compilerRevision < currentRevision) {
var runtimeVersions = REVISION_CHANGES[currentRevision],
compilerVersions = REVISION_CHANGES[compilerRevision];
throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
} else {
// Use the embedded version info since the runtime doesn't know about this revision yet
throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
}
}
}
// TODO: Remove this line and break up compilePartial
function template(templateSpec, env) {
if (!env) {
throw new Error("No environment passed to template");
}
var invokePartialWrapper;
if (env.compile) {
invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
// TODO : Check this for all inputs and the options handling (partial flag, etc). This feels
// like there should be a common exec path
var result = invokePartial.apply(this, arguments);
if (result) { return result; }
var options = { helpers: helpers, partials: partials, data: data };
partials[name] = env.compile(partial, { data: data !== undefined }, env);
return partials[name](context, options);
};
} else {
invokePartialWrapper = function(partial, name /* , context, helpers, partials, data */) {
var result = invokePartial.apply(this, arguments);
if (result) { return result; }
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
};
}
// Just add water
var container = {
escapeExpression: Utils.escapeExpression,
invokePartial: invokePartialWrapper,
programs: [],
program: function(i, fn, data) {
var programWrapper = this.programs[i];
if(data) {
programWrapper = program(i, fn, data);
} else if (!programWrapper) {
programWrapper = this.programs[i] = program(i, fn);
}
return programWrapper;
},
merge: function(param, common) {
var ret = param || common;
if (param && common && (param !== common)) {
ret = {};
Utils.extend(ret, common);
Utils.extend(ret, param);
}
return ret;
},
programWithDepth: programWithDepth,
noop: noop,
compilerInfo: null
};
return function(context, options) {
options = options || {};
var namespace = options.partial ? options : env,
helpers,
partials;
if (!options.partial) {
helpers = options.helpers;
partials = options.partials;
}
var result = templateSpec.call(
container,
namespace, context,
helpers,
partials,
options.data);
if (!options.partial) {
checkRevision(container.compilerInfo);
}
return result;
};
}
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
var args = Array.prototype.slice.call(arguments, 3);
var prog = function(context, options) {
options = options || {};
return fn.apply(this, [context, options.data || data].concat(args));
};
prog.program = i;
prog.depth = args.length;
return prog;
}
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
var prog = function(context, options) {
options = options || {};
return fn(context, options.data || data);
};
prog.program = i;
prog.depth = 0;
return prog;
}
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
var options = { partial: true, helpers: helpers, partials: partials, data: data };
if(partial === undefined) {
throw new Exception("The partial " + name + " could not be found");
} else if(partial instanceof Function) {
return partial(context, options);
}
}
__exports__.invokePartial = invokePartial;function noop() { return ""; }
__exports__.noop = noop;
});
define(
'handlebars.runtime',["./handlebars/base","./handlebars/safe-string","./handlebars/exception","./handlebars/utils","./handlebars/runtime","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
var base = __dependency1__;
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var SafeString = __dependency2__["default"];
var Exception = __dependency3__["default"];
var Utils = __dependency4__;
var runtime = __dependency5__;
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function() {
var hb = new base.HandlebarsEnvironment();
Utils.extend(hb, base);
hb.SafeString = SafeString;
hb.Exception = Exception;
hb.Utils = Utils;
hb.VM = runtime;
hb.template = function(spec) {
return runtime.template(spec, hb);
};
return hb;
};
var Handlebars = create();
Handlebars.create = create;
__exports__["default"] = Handlebars;
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,518 @@
/*!
handlebars v1.1.2
Copyright (C) 2011 by Yehuda Katz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@license
*/
var Handlebars = (function() {
// handlebars/safe-string.js
var __module3__ = (function() {
"use strict";
var __exports__;
// Build out our basic SafeString type
function SafeString(string) {
this.string = string;
}
SafeString.prototype.toString = function() {
return "" + this.string;
};
__exports__ = SafeString;
return __exports__;
})();
// handlebars/utils.js
var __module2__ = (function(__dependency1__) {
"use strict";
var __exports__ = {};
var SafeString = __dependency1__;
var escape = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#x27;",
"`": "&#x60;"
};
var badChars = /[&<>"'`]/g;
var possible = /[&<>"'`]/;
function escapeChar(chr) {
return escape[chr] || "&amp;";
}
function extend(obj, value) {
for(var key in value) {
if(value.hasOwnProperty(key)) {
obj[key] = value[key];
}
}
}
__exports__.extend = extend;var toString = Object.prototype.toString;
__exports__.toString = toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
if (isFunction(/x/)) {
isFunction = function(value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
var isFunction;
__exports__.isFunction = isFunction;
var isArray = Array.isArray || function(value) {
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
};
__exports__.isArray = isArray;
function escapeExpression(string) {
// don't escape SafeStrings, since they're already safe
if (string instanceof SafeString) {
return string.toString();
} else if (!string && string !== 0) {
return "";
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = "" + string;
if(!possible.test(string)) { return string; }
return string.replace(badChars, escapeChar);
}
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
if (!value && value !== 0) {
return true;
} else if (isArray(value) && value.length === 0) {
return true;
} else {
return false;
}
}
__exports__.isEmpty = isEmpty;
return __exports__;
})(__module3__);
// handlebars/exception.js
var __module4__ = (function() {
"use strict";
var __exports__;
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
function Exception(/* message */) {
var tmp = Error.prototype.constructor.apply(this, arguments);
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
}
Exception.prototype = new Error();
__exports__ = Exception;
return __exports__;
})();
// handlebars/base.js
var __module1__ = (function(__dependency1__, __dependency2__) {
"use strict";
var __exports__ = {};
/*globals Exception, Utils */
var Utils = __dependency1__;
var Exception = __dependency2__;
var VERSION = "1.1.2";
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
__exports__.COMPILER_REVISION = COMPILER_REVISION;
var REVISION_CHANGES = {
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
2: '== 1.0.0-rc.3',
3: '== 1.0.0-rc.4',
4: '>= 1.0.0'
};
__exports__.REVISION_CHANGES = REVISION_CHANGES;
var isArray = Utils.isArray,
isFunction = Utils.isFunction,
toString = Utils.toString,
objectType = '[object Object]';
function HandlebarsEnvironment(helpers, partials) {
this.helpers = helpers || {};
this.partials = partials || {};
registerDefaultHelpers(this);
}
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
constructor: HandlebarsEnvironment,
logger: logger,
log: log,
registerHelper: function(name, fn, inverse) {
if (toString.call(name) === objectType) {
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
Utils.extend(this.helpers, name);
} else {
if (inverse) { fn.not = inverse; }
this.helpers[name] = fn;
}
},
registerPartial: function(name, str) {
if (toString.call(name) === objectType) {
Utils.extend(this.partials, name);
} else {
this.partials[name] = str;
}
}
};
function registerDefaultHelpers(instance) {
instance.registerHelper('helperMissing', function(arg) {
if(arguments.length === 2) {
return undefined;
} else {
throw new Error("Missing helper: '" + arg + "'");
}
});
instance.registerHelper('blockHelperMissing', function(context, options) {
var inverse = options.inverse || function() {}, fn = options.fn;
if (isFunction(context)) { context = context.call(this); }
if(context === true) {
return fn(this);
} else if(context === false || context == null) {
return inverse(this);
} else if (isArray(context)) {
if(context.length > 0) {
return instance.helpers.each(context, options);
} else {
return inverse(this);
}
} else {
return fn(context);
}
});
instance.registerHelper('each', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var i = 0, ret = "", data;
if (isFunction(context)) { context = context.call(this); }
if (options.data) {
data = createFrame(options.data);
}
if(context && typeof context === 'object') {
if (isArray(context)) {
for(var j = context.length; i<j; i++) {
if (data) {
data.index = i;
data.first = (i === 0)
data.last = (i === (context.length-1));
}
ret = ret + fn(context[i], { data: data });
}
} else {
for(var key in context) {
if(context.hasOwnProperty(key)) {
if(data) { data.key = key; }
ret = ret + fn(context[key], {data: data});
i++;
}
}
}
}
if(i === 0){
ret = inverse(this);
}
return ret;
});
instance.registerHelper('if', function(conditional, options) {
if (isFunction(conditional)) { conditional = conditional.call(this); }
// Default behavior is to render the positive path if the value is truthy and not empty.
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
return options.inverse(this);
} else {
return options.fn(this);
}
});
instance.registerHelper('unless', function(conditional, options) {
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
});
instance.registerHelper('with', function(context, options) {
if (isFunction(context)) { context = context.call(this); }
if (!Utils.isEmpty(context)) return options.fn(context);
});
instance.registerHelper('log', function(context, options) {
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
instance.log(level, context);
});
}
var logger = {
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
// State enum
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
level: 3,
// can be overridden in the host environment
log: function(level, obj) {
if (logger.level <= level) {
var method = logger.methodMap[level];
if (typeof console !== 'undefined' && console[method]) {
console[method].call(console, obj);
}
}
}
};
__exports__.logger = logger;
function log(level, obj) { logger.log(level, obj); }
__exports__.log = log;var createFrame = function(object) {
var obj = {};
Utils.extend(obj, object);
return obj;
};
__exports__.createFrame = createFrame;
return __exports__;
})(__module2__, __module4__);
// handlebars/runtime.js
var __module5__ = (function(__dependency1__, __dependency2__, __dependency3__) {
"use strict";
var __exports__ = {};
/*global Utils */
var Utils = __dependency1__;
var Exception = __dependency2__;
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
function checkRevision(compilerInfo) {
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
currentRevision = COMPILER_REVISION;
if (compilerRevision !== currentRevision) {
if (compilerRevision < currentRevision) {
var runtimeVersions = REVISION_CHANGES[currentRevision],
compilerVersions = REVISION_CHANGES[compilerRevision];
throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
} else {
// Use the embedded version info since the runtime doesn't know about this revision yet
throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
}
}
}
// TODO: Remove this line and break up compilePartial
function template(templateSpec, env) {
if (!env) {
throw new Error("No environment passed to template");
}
var invokePartialWrapper;
if (env.compile) {
invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
// TODO : Check this for all inputs and the options handling (partial flag, etc). This feels
// like there should be a common exec path
var result = invokePartial.apply(this, arguments);
if (result) { return result; }
var options = { helpers: helpers, partials: partials, data: data };
partials[name] = env.compile(partial, { data: data !== undefined }, env);
return partials[name](context, options);
};
} else {
invokePartialWrapper = function(partial, name /* , context, helpers, partials, data */) {
var result = invokePartial.apply(this, arguments);
if (result) { return result; }
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
};
}
// Just add water
var container = {
escapeExpression: Utils.escapeExpression,
invokePartial: invokePartialWrapper,
programs: [],
program: function(i, fn, data) {
var programWrapper = this.programs[i];
if(data) {
programWrapper = program(i, fn, data);
} else if (!programWrapper) {
programWrapper = this.programs[i] = program(i, fn);
}
return programWrapper;
},
merge: function(param, common) {
var ret = param || common;
if (param && common && (param !== common)) {
ret = {};
Utils.extend(ret, common);
Utils.extend(ret, param);
}
return ret;
},
programWithDepth: programWithDepth,
noop: noop,
compilerInfo: null
};
return function(context, options) {
options = options || {};
var namespace = options.partial ? options : env,
helpers,
partials;
if (!options.partial) {
helpers = options.helpers;
partials = options.partials;
}
var result = templateSpec.call(
container,
namespace, context,
helpers,
partials,
options.data);
if (!options.partial) {
checkRevision(container.compilerInfo);
}
return result;
};
}
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
var args = Array.prototype.slice.call(arguments, 3);
var prog = function(context, options) {
options = options || {};
return fn.apply(this, [context, options.data || data].concat(args));
};
prog.program = i;
prog.depth = args.length;
return prog;
}
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
var prog = function(context, options) {
options = options || {};
return fn(context, options.data || data);
};
prog.program = i;
prog.depth = 0;
return prog;
}
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
var options = { partial: true, helpers: helpers, partials: partials, data: data };
if(partial === undefined) {
throw new Exception("The partial " + name + " could not be found");
} else if(partial instanceof Function) {
return partial(context, options);
}
}
__exports__.invokePartial = invokePartial;function noop() { return ""; }
__exports__.noop = noop;
return __exports__;
})(__module2__, __module4__, __module1__);
// handlebars.runtime.js
var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
"use strict";
var __exports__;
var base = __dependency1__;
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
var SafeString = __dependency2__;
var Exception = __dependency3__;
var Utils = __dependency4__;
var runtime = __dependency5__;
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function() {
var hb = new base.HandlebarsEnvironment();
Utils.extend(hb, base);
hb.SafeString = SafeString;
hb.Exception = Exception;
hb.Utils = Utils;
hb.VM = runtime;
hb.template = function(spec) {
return runtime.template(spec, hb);
};
return hb;
};
var Handlebars = create();
Handlebars.create = create;
__exports__ = Handlebars;
return __exports__;
})(__module1__, __module3__, __module4__, __module2__, __module5__);
return __module0__;
})();

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,11 @@
module Handlebars
module Source
def self.bundled_path
File.expand_path("../../../handlebars.js", __FILE__)
end
def self.runtime_bundled_path
File.expand_path("../../../handlebars.runtime.js", __FILE__)
end
end
end

View File

@ -0,0 +1,39 @@
{
"name": "ic-ajax",
"version": "0.2.0",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"main": "main.js",
"moduleFormat": [
"amd",
"cjs",
"globals"
],
"license": "MIT",
"ignore": [
"bower_components",
"node_modules",
"package.json",
"testem.json",
"test.js",
"**/.*"
],
"dependencies": {
"ember": "~1.2.0"
},
"devDependencies": {
"sinon": "http://sinonjs.org/releases/sinon-1.7.3.js"
},
"homepage": "https://github.com/instructure/ic-ajax",
"_release": "0.2.0",
"_resolution": {
"type": "version",
"tag": "v0.2.0",
"commit": "4daa969eb5e3a6191afb6373ddeeec31c996e90a"
},
"_source": "git://github.com/instructure/ic-ajax.git",
"_target": "~0.2.0",
"_originalSource": "ic-ajax",
"_direct": true
}

View File

@ -0,0 +1,21 @@
Copyright (C) 2013 Instructure, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,111 @@
ic-ajax
=======
Ember-friendly `jQuery.ajax` wrapper.
- returns RSVP promises
- makes apps more testable (resolves promises with `Ember.run`)
- makes testing ajax simpler with fixture support
Installation
------------
`bower install ic-ajax`
`npm install ic-ajax`
... or download `main.js` and include it into your app however you want.
Module Support
--------------
- AMD
`define(['bower_components/ic-ajax'], function(ajax) {});`
- Node.JS (CJS)
`var ajax = require('ic-ajax')`
- Globals
`var ajax = ic.ajax;`
All instructure canvas stuff lives on the `ic` global.
API
---
Ajax simply wraps `jQuery.ajax` with two exceptions:
- success and error callbacks are not supported
- does not resolve three arguments like $.ajax (real promises only
resolve a single value). `ic.ajax` only resolves the response data
from the request, while ic.ajax.raw resolves an object with the three
"arguments" as keys if you need them.
Other than that, use it exactly like `$.ajax`.
```js
var ajax = ic.ajax;
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return ajax('/foo');
}
}
// if you need access to the jqXHR or textStatus, use raw
ajax.raw('/foo').then(function(result) {
// result.response
// result.textStatus
// result.jqXHR
});
```
Simplified Testing
------------------
Adding fixtures with `defineFixture` tells ic-ajax to resolve the promise
with the fixture matching a url instead of making a request. This allows
you to test your app without creating fake servers with sinon, etc.
Example:
```js
ic.ajax.defineFixture('api/v1/courses', {
response: [{name: 'basket weaving'}],
jqXHR: {},
textStatus: 'success'
});
ic.ajax('api/v1/courses').then(function(result) {
deepEqual(result, ic.ajax.lookupFixture('api/v1/courses').response);
});
```
Contributing
------------
Install dependencies and run tests with the following:
```sh
bower install
npm install
npm test
```
Special Thanks
--------------
Inspired by [discourse ajax][1].
License and Copyright
---------------------
MIT Style license
(c) 2013 Instructure, Inc.
[1]:https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/mixins/ajax.js#L19

View File

@ -0,0 +1,28 @@
{
"name": "ic-ajax",
"version": "0.2.0",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"main": "main.js",
"moduleFormat": [
"amd",
"cjs",
"globals"
],
"license": "MIT",
"ignore": [
"bower_components",
"node_modules",
"package.json",
"testem.json",
"test.js",
"**/.*"
],
"dependencies": {
"ember": "~1.2.0"
},
"devDependencies": {
"sinon": "http://sinonjs.org/releases/sinon-1.7.3.js"
}
}

View File

@ -0,0 +1,126 @@
/*!
* ic-ajax
*
* - (c) 2013 Instructure, Inc
* - please see license at https://github.com/instructure/ic-ajax/blob/master/LICENSE
* - inspired by discourse ajax: https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/mixins/ajax.js#L19
*/
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.ajax = factory(Ember);
}
}(this, function(Ember) {
/*
* jQuery.ajax wrapper, supports the same signature except providing
* `success` and `error` handlers will throw an error (use promises instead)
* and it resolves only the response (no access to jqXHR or textStatus).
*/
var ajax = function() {
return ajax.raw.apply(null, arguments).then(function(result) {
return result.response;
});
};
/*
* Same as `ajax` except it resolves an object with `{response, textStatus,
* jqXHR}`, useful if you need access to the jqXHR object for headers, etc.
*/
ajax.raw = function() {
return makePromise(parseArgs.apply(null, arguments));
};
/*
* Defines a fixture that will be used instead of an actual ajax
* request to a given url. This is useful for testing, allowing you to
* stub out responses your application will send without requiring
* libraries like sinon or mockjax, etc.
*
* For example:
*
* ajax.defineFixture('/self', {
* response: { firstName: 'Ryan', lastName: 'Florence' },
* textStatus: 'success'
* jqXHR: {}
* });
*
* @param {String} url
* @param {Object} fixture
*/
ajax.defineFixture = function(url, fixture) {
ajax.FIXTURES = ajax.FIXTURES || {};
ajax.FIXTURES[url] = fixture;
};
/*
* Looks up a fixture by url.
*
* @param {String} url
*/
ajax.lookupFixture = function(url) {
return ajax.FIXTURES && ajax.FIXTURES[url];
};
function makePromise(settings) {
return new Ember.RSVP.Promise(function(resolve, reject) {
var fixture = ajax.lookupFixture(settings.url);
if (fixture) {
return resolve(fixture);
}
settings.success = makeSuccess(resolve, reject);
settings.error = makeError(resolve, reject);
Ember.$.ajax(settings);
});
};
function parseArgs() {
var settings = {};
if (arguments.length === 1) {
if (typeof arguments[0] === "string") {
settings.url = arguments[0];
} else {
settings = arguments[0];
}
} else if (arguments.length === 2) {
settings = arguments[1];
settings.url = arguments[0];
}
if (settings.success || settings.error) {
throw new Error("ajax should use promises, received 'success' or 'error' callback");
}
return settings;
}
function makeSuccess(resolve, reject) {
return function(response, textStatus, jqXHR) {
Ember.run(null, resolve, {
response: response,
textStatus: textStatus,
jqXHR: jqXHR
});
}
}
function makeError(resolve, reject) {
return function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, {
jqXHR: jqXHR,
textStatus: textStatus,
errorThrown: errorThrown
});
};
}
return ajax;
}));

View File

@ -0,0 +1,80 @@
#!/usr/bin/env node
var prompt = require('prompt');
var fs = require('fs');
var exec = require('child_process').exec;
var schema = {
properties: {
version: {
description: 'version? (old is '+version()+')',
pattern: /^[0-9]\.[0-9]+\.[0-9](-.+)?/,
message: 'Must be a valid semver string i.e. 1.0.2, 2.3.0-beta.1',
required: true
}
}
};
prompt.start();
prompt.get(schema, function(err, result) {
var rawVersion = result.version;
var version = 'v'+rawVersion;
updateJSON('package', rawVersion);
updateJSON('bower', rawVersion);
commit(version, function() {
tag(version, function() {
publish(version);
})
});
});
function commit(version, cb) {
exec('git commit -am "release '+version+'"', execHandler(cb));
}
function tag(version, cb) {
exec('git tag '+version, execHandler(cb));
}
function publish(version) {
exec('git push origin master', execHandler());
exec('git push origin '+version, execHandler());
exec('npm publish', execHandler());
}
function execHandler(cb) {
return function(err, stdout, stderr) {
if (err) throw new Error(err);
console.log(stdout);
console.log(stderr);
if (cb) cb();
}
}
function updateJSON(pkg, version) {
var path = './'+pkg+'.json';
var json = readJSON(path);
json.version = version;
writeJSON(path, json);
}
function version() {
try {
return readJSON('./package.json').version;
} catch(e) {
console.log('Could not read package.json version');
}
}
function readJSON(path) {
try {
return JSON.parse(fs.readFileSync(path).toString());
} catch(e) {
console.log('Could not read package.json version');
}
}
function writeJSON(path, data) {
fs.writeFileSync(path, JSON.stringify(data, null, 2));
}

View File

@ -0,0 +1,33 @@
{
"name": "ic-menu",
"version": "0.1.0",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"dependencies": {
"ember": "1.2.0",
"ic-styled": "~1.1.0"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"devDependencies": {
"ember-template-compiler": "http://builds.emberjs.com/release/ember-template-compiler.js"
},
"homepage": "https://github.com/instructure/ic-menu",
"_release": "0.1.0",
"_resolution": {
"type": "version",
"tag": "v0.1.0",
"commit": "c7530d414b891c3a15ce8d0cc52543ad82710043"
},
"_source": "git://github.com/instructure/ic-menu.git",
"_target": "~0.1.0",
"_originalSource": "ic-menu",
"_direct": true
}

View File

@ -0,0 +1,45 @@
fs = require 'fs'
module.exports = (grunt) ->
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)
grunt.initConfig
watch:
testTemplates:
files: ['test/**/*.hbs']
tasks: ['emberTemplates:test']
build:
files: ['lib/**/*.{js,hbs}', 'lib/main.js']
tasks: ['build']
emberTemplates:
options:
templateCompilerPath: 'bower_components/ember-template-compiler/index.js'
handlebarsPath: 'bower_components/handlebars/handlebars.js'
lib:
options:
templateBasePath: 'lib/templates/'
files:
'lib/templates.js': 'lib/templates/{,*/}*.hbs'
test:
options:
templateBasePath: 'test/support/'
files:
'test/support/templates.js': 'test/support/{,*/}*.hbs'
concat:
build:
src: [
'lib/*/**/*.js'
'lib/templates.js'
'lib/main.js'
]
dest: 'dist/main.js'
clean:
build: ['build']
grunt.registerTask 'build', ['clean:build', 'emberTemplates', 'concat']
grunt.registerTask 'default', ['build', 'watch']

View File

@ -0,0 +1,52 @@
ic-menu
=======
An accessible menu component for ember applications.
Installation
------------
`bower install ic-menu`
Usage
-----
__application.hbs__
```handlebars
{{#ic-menu}}
{{#ic-menu-trigger}}Actions{{/ic-menu-trigger}}
{{#ic-menu-list}}
{{#ic-menu-item on-select="remove"}}Remove{{/ic-menu-item}}
{{#ic-menu-item on-select="save"}}Save{{/ic-menu-item}}
{{/ic-menu-list}}
{{/ic-menu}}
```
__application_controller.js__
```js
App.ApplicationController = Ember.Controller.extend({
actions: {
remove: function(icMenuItem) {
// do stuff with the icMenuItem instance
},
save: function(icMenuItem) {
// do stuff with the icMenuItem instance
}
}
});
```
Development
-----------
1. Fork the repo
2. `npm install && bower install`
3. Create a new branch for your feature/bug fix
4. `grunt` to build and watch files.
5. `testem` in a new tab to run tests.
6. Send a pull request.

View File

@ -0,0 +1,22 @@
{
"name": "ic-menu",
"version": "0.1.0",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"dependencies": {
"ember": "1.2.0",
"ic-styled": "~1.1.0"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"devDependencies": {
"ember-template-compiler": "http://builds.emberjs.com/release/ember-template-compiler.js"
}
}

View File

@ -0,0 +1,440 @@
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuItemComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuItemComponent = Ember.Component.extend({
tagName: 'ic-menu-item',
attributeBindings: [
'tabindex',
'role'
],
role: 'menuitem',
tabindex: -1,
focused: false,
click: function(event) {
var wasKeyboard = !event.clientX && !event.clientY;
this.get('parentView').close();
Ember.run.next(this, function() {
if (wasKeyboard) { this.get('parentView').focusTrigger(); }
this.sendAction('on-select', this);
});
},
keyDown: function(event) {
if (event.keyCode == 13 || event.keyCode == 32) {
this.click(event);
}
},
register: function() {
this.get('parentView').registerItem(this);
}.on('didInsertElement'),
deregister: function() {
this.get('parentView').deregisterItem(this);
}.on('willDestroyElement'),
focus: function() {
this.set('focused', true);
this.$().focus();
},
mouseEnter: function() {
this.get('parentView').focusItem(this);
},
blur: function() {
this.set('focused', false);
}
});
return MenuItemComponent;
});
// See http://www.w3.org/WAI/GL/wiki/Using_ARIA_menus
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuListComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuListComponent = Ember.Component.extend({
role: 'menu',
tagName: 'ic-menu-list',
attributeBindings: [
'ariaExpanded:aria-expanded',
'tabindex',
'role'
],
// so we can focus the menu manually and get "focusOut" to trigger without
// putting the menu in the tab-o-sphere
tabindex: -1,
isOpen: false,
ariaExpanded: function() {
return this.get('isOpen')+''; // aria wants "true" and "false" as strings
}.property('isOpen'),
focusedItem: null,
createItems: function() {
this.set('items', Ember.ArrayProxy.create({content: []}));
}.on('init'),
keyDown: function(event) {
keysDict = {
40: this.focusNext, /*down*/
38: this.focusPrevious, /*up*/
27: this.focusTrigger /*escape*/
};
if (keysDict.hasOwnProperty(event.keyCode)) {
event.preventDefault();
keysDict[event.keyCode].call(this)
}
},
focusTrigger: function() {
this.get('parentView.listTrigger').focus();
},
focusNext: function() {
var index = 0;
var items = this.get('items');
var focusedItem = this.get('focusedItem');
if (focusedItem) {
index = items.indexOf(focusedItem) + 1;
}
if (index === items.get('length')) {
index = 0; // loop it
}
this.focusItemAtIndex(index);
},
focusPrevious: function() {
var items = this.get('items');
var index = items.get('length') - 1;
var focusedItem = this.get('focusedItem');
if (focusedItem) {
index = items.indexOf(focusedItem) - 1;
}
if (index == -1) {
index = items.get('length') - 1; // loop it
}
this.focusItemAtIndex(index);
},
focusItemAtIndex: function(index) {
var item = this.get('items').objectAt(index);
this.focusItem(item);
},
focusItem: function(item) {
var focusedItem = this.get('focusedItem');
if (focusedItem) focusedItem.blur();
this.set('focusedItem', item);
item.focus();
},
registerItem: function(item) {
this.get('items').addObject(item);
},
deregisterItem: function(item) {
this.get('items').removeObject(item);
},
open: function() {
this.set('isOpen', true);
},
close: function() {
this.set('isOpen', false);
this.set('focusedItem', null);
},
focusFirstItemOnOpen: function() {
if (!this.get('isOpen')) return;
// wait for dom repaint so we can actually focus items
Ember.run.next(this, function() {
if (this.get('parentView.listTrigger.lastClickEventWasMouse')) {
// focus the list then keyboard navigation still works, but the first
// item isn't strangely selected
this.$().focus();
} else {
// select first item for keyboard navigation
this.focusItemAtIndex(0);
}
});
}.observes('isOpen'),
registerWithParent: function() {
this.get('parentView').registerList(this);
}.on('didInsertElement'),
focusOut: function(event) {
// wait for activeElement to get set (I think?)
Ember.run.next(this, function(){
// gaurd against case where this.$() is undefinded.
// otherwise get random failures
if (this.$()) {
if (!this.$().has(document.activeElement).length) {
this.close();
}
}
});
}
});
return MenuListComponent;
});
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuTriggerComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuTriggerComponent = Ember.Component.extend({
tagName: 'ic-menu-trigger',
role: 'button',
attributeBindings: [
'ariaOwns:aria-owns',
'ariaHaspopup:aria-haspopup',
'role',
'tabindex'
],
tabindex: 0,
ariaHaspopup: 'true',
ariaOwns: function() {
return this.get('parentView.list.elementId');
}.property('parentView.list'),
mouseDown: function() {
if (!this.get('parentView.list.isOpen')) return;
// MenuList::focusOut handles outerclick/outerfocus, mousedown on the
// trigger will close an already open list, then the click finishes after
// and would reopen the list, so we have this temporary property to deal
// with it.
this.closingClickStarted = true;
},
click: Ember.aliasMethod('openList'),
keyDown: function(event) {
switch (event.keyCode) {
case 13 /*enter*/:
case 32 /*space*/:
case 40 /*down*/:
case 38 /*up*/: this.openList(event); break;
}
},
openList: function(event) {
event.preventDefault();
// I have no idea how reliable this is, but it seems good enough
this.set('lastClickEventWasMouse', event.clientX > 0 && event.clientY > 0);
if (this.closingClickStarted) {
return this.closingClickStarted = false;
}
this.get('parentView').openList();
},
click: Ember.aliasMethod('openList'),
registerWithParent: function() {
this.get('parentView').registerTrigger(this);
}.on('didInsertElement'),
focus: function() {
this.$().focus();
}
});
return MenuTriggerComponent;
});
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuComponent = Ember.Component.extend({
tagName: 'ic-menu',
classNameBindings: ['isOpen:is-open:is-closed'],
list: null,
listTrigger: null,
isOpen: function() {
return this.get('list.isOpen');
}.property('list.isOpen'),
registerList: function(list) {
this.set('list', list);
},
registerTrigger: function(trigger) {
this.set('listTrigger', trigger);
},
openList: function() {
this.get('list').open();
}
});
return MenuComponent;
});
Ember.TEMPLATES["components/ic-menu-css"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
data.buffer.push("<style>\nic-menu {\n display: inline-block;\n}\n\nic-menu-list {\n position: absolute;\n display: none;\n}\n\nic-menu-list[aria-expanded=\"true\"] {\n display: block;\n}\n\nic-menu-list {\n outline: none;\n background: #fff;\n border: 1px solid #aaa;\n border-radius: 3px;\n box-shadow: 2px 2px 20px rgba(0, 0, 0, 0.25);\n list-style-type: none;\n padding: 2px 0px;\n font-family: \"Lucida Grande\", \"Arial\", sans-serif;\n font-size: 12px;\n}\n\nic-menu-item {\n display: block;\n padding: 4px 20px;\n cursor: default;\n white-space: nowrap;\n}\n\nic-menu-item:focus {\n background: #3879D9;\n color: #fff;\n outline: none;\n}\n</style>\n\n");
});
Ember.TEMPLATES["components/ic-menu-list"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
var buffer = '', hashTypes, hashContexts, escapeExpression=this.escapeExpression;
hashTypes = {};
hashContexts = {};
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "yield", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
data.buffer.push("\n");
return buffer;
});
Ember.TEMPLATES["components/ic-menu"] = Ember.Handlebars.template(function anonymous(Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
var buffer = '', hashTypes, hashContexts, escapeExpression=this.escapeExpression;
hashTypes = {};
hashContexts = {};
data.buffer.push(escapeExpression(helpers._triageMustache.call(depth0, "yield", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
data.buffer.push("\n");
return buffer;
});
// <look-the-other-way>
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([
'ember',
'./components/ic-menu-item',
'./components/ic-menu-list',
'./components/ic-menu-trigger',
'./components/ic-menu',
'ic-styled'
], function(Ember, Item, List, Trigger) {
return factory(Ember, Item, List, Trigger, Menu);
});
} else if (typeof exports === 'object') {
module.exports = factory(
require('ember'),
require('./components/ic-menu-item'),
require('./components/ic-menu-list'),
require('./components/ic-menu-trigger'),
require('./components/ic-menu'),
require('ic-styled')
);
} else {
factory(
Ember,
root.ic.MenuItemComponent,
root.ic.MenuListComponent,
root.ic.MenuTriggerComponent,
root.ic.MenuComponent
);
}
}(this, function(Ember, Item, List, Trigger, Menu) {
// </look-the-other-way>
Ember.Application.initializer({
name: 'ic-menu',
initialize: function(container, application) {
//application.IcMenuItemComponent = Item;
//application.IcMenuListComponent = List;
//application.IcMenuTriggerComponent = Trigger;
//application.IcMenuComponent = Menu;
container.register('component:ic-menu-item', Item);
container.register('component:ic-menu-list', List);
container.register('component:ic-menu-trigger', Trigger);
container.register('component:ic-menu', Menu);
}
});
return {
MenuItemComponent: Item,
MenuListComponent: List,
MenuTriggerComponent: Trigger,
MenuComponent: Menu
}
});

View File

@ -0,0 +1,67 @@
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuItemComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuItemComponent = Ember.Component.extend({
tagName: 'ic-menu-item',
attributeBindings: [
'tabindex',
'role'
],
role: 'menuitem',
tabindex: -1,
focused: false,
click: function(event) {
var wasKeyboard = !event.clientX && !event.clientY;
this.get('parentView').close();
Ember.run.next(this, function() {
if (wasKeyboard) { this.get('parentView').focusTrigger(); }
this.sendAction('on-select', this);
});
},
keyDown: function(event) {
if (event.keyCode == 13 || event.keyCode == 32) {
this.click(event);
}
},
register: function() {
this.get('parentView').registerItem(this);
}.on('didInsertElement'),
deregister: function() {
this.get('parentView').deregisterItem(this);
}.on('willDestroyElement'),
focus: function() {
this.set('focused', true);
this.$().focus();
},
mouseEnter: function() {
this.get('parentView').focusItem(this);
},
blur: function() {
this.set('focused', false);
}
});
return MenuItemComponent;
});

View File

@ -0,0 +1,151 @@
// See http://www.w3.org/WAI/GL/wiki/Using_ARIA_menus
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuListComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuListComponent = Ember.Component.extend({
role: 'menu',
tagName: 'ic-menu-list',
attributeBindings: [
'ariaExpanded:aria-expanded',
'tabindex',
'role'
],
// so we can focus the menu manually and get "focusOut" to trigger without
// putting the menu in the tab-o-sphere
tabindex: -1,
isOpen: false,
ariaExpanded: function() {
return this.get('isOpen')+''; // aria wants "true" and "false" as strings
}.property('isOpen'),
focusedItem: null,
createItems: function() {
this.set('items', Ember.ArrayProxy.create({content: []}));
}.on('init'),
keyDown: function(event) {
keysDict = {
40: this.focusNext, /*down*/
38: this.focusPrevious, /*up*/
27: this.focusTrigger /*escape*/
};
if (keysDict.hasOwnProperty(event.keyCode)) {
event.preventDefault();
keysDict[event.keyCode].call(this)
}
},
focusTrigger: function() {
this.get('parentView.listTrigger').focus();
},
focusNext: function() {
var index = 0;
var items = this.get('items');
var focusedItem = this.get('focusedItem');
if (focusedItem) {
index = items.indexOf(focusedItem) + 1;
}
if (index === items.get('length')) {
index = 0; // loop it
}
this.focusItemAtIndex(index);
},
focusPrevious: function() {
var items = this.get('items');
var index = items.get('length') - 1;
var focusedItem = this.get('focusedItem');
if (focusedItem) {
index = items.indexOf(focusedItem) - 1;
}
if (index == -1) {
index = items.get('length') - 1; // loop it
}
this.focusItemAtIndex(index);
},
focusItemAtIndex: function(index) {
var item = this.get('items').objectAt(index);
this.focusItem(item);
},
focusItem: function(item) {
var focusedItem = this.get('focusedItem');
if (focusedItem) focusedItem.blur();
this.set('focusedItem', item);
item.focus();
},
registerItem: function(item) {
this.get('items').addObject(item);
},
deregisterItem: function(item) {
this.get('items').removeObject(item);
},
open: function() {
this.set('isOpen', true);
},
close: function() {
this.set('isOpen', false);
this.set('focusedItem', null);
},
focusFirstItemOnOpen: function() {
if (!this.get('isOpen')) return;
// wait for dom repaint so we can actually focus items
Ember.run.next(this, function() {
if (this.get('parentView.listTrigger.lastClickEventWasMouse')) {
// focus the list then keyboard navigation still works, but the first
// item isn't strangely selected
this.$().focus();
} else {
// select first item for keyboard navigation
this.focusItemAtIndex(0);
}
});
}.observes('isOpen'),
registerWithParent: function() {
this.get('parentView').registerList(this);
}.on('didInsertElement'),
focusOut: function(event) {
// wait for activeElement to get set (I think?)
Ember.run.next(this, function(){
// gaurd against case where this.$() is undefinded.
// otherwise get random failures
if (this.$()) {
if (!this.$().has(document.activeElement).length) {
this.close();
}
}
});
}
});
return MenuListComponent;
});

View File

@ -0,0 +1,78 @@
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuTriggerComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuTriggerComponent = Ember.Component.extend({
tagName: 'ic-menu-trigger',
role: 'button',
attributeBindings: [
'ariaOwns:aria-owns',
'ariaHaspopup:aria-haspopup',
'role',
'tabindex'
],
tabindex: 0,
ariaHaspopup: 'true',
ariaOwns: function() {
return this.get('parentView.list.elementId');
}.property('parentView.list'),
mouseDown: function() {
if (!this.get('parentView.list.isOpen')) return;
// MenuList::focusOut handles outerclick/outerfocus, mousedown on the
// trigger will close an already open list, then the click finishes after
// and would reopen the list, so we have this temporary property to deal
// with it.
this.closingClickStarted = true;
},
click: Ember.aliasMethod('openList'),
keyDown: function(event) {
switch (event.keyCode) {
case 13 /*enter*/:
case 32 /*space*/:
case 40 /*down*/:
case 38 /*up*/: this.openList(event); break;
}
},
openList: function(event) {
event.preventDefault();
// I have no idea how reliable this is, but it seems good enough
this.set('lastClickEventWasMouse', event.clientX > 0 && event.clientY > 0);
if (this.closingClickStarted) {
return this.closingClickStarted = false;
}
this.get('parentView').openList();
},
click: Ember.aliasMethod('openList'),
registerWithParent: function() {
this.get('parentView').registerTrigger(this);
}.on('didInsertElement'),
focus: function() {
this.$().focus();
}
});
return MenuTriggerComponent;
});

View File

@ -0,0 +1,43 @@
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.MenuComponent = factory(Ember);
}
}(this, function(Ember) {
var MenuComponent = Ember.Component.extend({
tagName: 'ic-menu',
classNameBindings: ['isOpen:is-open:is-closed'],
list: null,
listTrigger: null,
isOpen: function() {
return this.get('list.isOpen');
}.property('list.isOpen'),
registerList: function(list) {
this.set('list', list);
},
registerTrigger: function(trigger) {
this.set('listTrigger', trigger);
},
openList: function() {
this.get('list').open();
}
});
return MenuComponent;
});

View File

@ -0,0 +1,60 @@
// <look-the-other-way>
+function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([
'ember',
'./components/ic-menu-item',
'./components/ic-menu-list',
'./components/ic-menu-trigger',
'./components/ic-menu',
'ic-styled'
], function(Ember, Item, List, Trigger) {
return factory(Ember, Item, List, Trigger, Menu);
});
} else if (typeof exports === 'object') {
module.exports = factory(
require('ember'),
require('./components/ic-menu-item'),
require('./components/ic-menu-list'),
require('./components/ic-menu-trigger'),
require('./components/ic-menu'),
require('ic-styled')
);
} else {
factory(
Ember,
root.ic.MenuItemComponent,
root.ic.MenuListComponent,
root.ic.MenuTriggerComponent,
root.ic.MenuComponent
);
}
}(this, function(Ember, Item, List, Trigger, Menu) {
// </look-the-other-way>
Ember.Application.initializer({
name: 'ic-menu',
initialize: function(container, application) {
//application.IcMenuItemComponent = Item;
//application.IcMenuListComponent = List;
//application.IcMenuTriggerComponent = Trigger;
//application.IcMenuComponent = Menu;
container.register('component:ic-menu-item', Item);
container.register('component:ic-menu-list', List);
container.register('component:ic-menu-trigger', Trigger);
container.register('component:ic-menu', Menu);
}
});
return {
MenuItemComponent: Item,
MenuListComponent: List,
MenuTriggerComponent: Trigger,
MenuComponent: Menu
}
});

View File

@ -0,0 +1,40 @@
<style>
ic-menu {
display: inline-block;
}
ic-menu-list {
position: absolute;
display: none;
}
ic-menu-list[aria-expanded="true"] {
display: block;
}
ic-menu-list {
outline: none;
background: #fff;
border: 1px solid #aaa;
border-radius: 3px;
box-shadow: 2px 2px 20px rgba(0, 0, 0, 0.25);
list-style-type: none;
padding: 2px 0px;
font-family: "Lucida Grande", "Arial", sans-serif;
font-size: 12px;
}
ic-menu-item {
display: block;
padding: 4px 20px;
cursor: default;
white-space: nowrap;
}
ic-menu-item:focus {
background: #3879D9;
color: #fff;
outline: none;
}
</style>

View File

@ -0,0 +1 @@
{{yield}}

View File

@ -0,0 +1 @@
{{yield}}

View File

@ -0,0 +1,24 @@
{
"name": "ic-menu",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "testem ci"
},
"author": "Ryan Florence <rpflorence@gmail.com>",
"license": "MIT",
"dependencies": {
"ember": "1.2.0",
"ic-styled": "~1.1.0"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-ember-templates": "~0.4.17",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-clean": "~0.5.0",
"testem": "~0.5.12",
"matchdep": "~0.3.0"
}
}

View File

@ -0,0 +1,13 @@
{
"framework": "qunit",
"src_files": [
"bower_components/jquery/jquery.js",
"bower_components/handlebars/handlebars.js",
"bower_components/ember/ember.js",
"bower_components/ic-styled/main.js",
"dist/main.js",
"test/support/**/*.js",
"test/**/*.spec.js"
]
}

View File

@ -0,0 +1,35 @@
{
"name": "ic-styled",
"version": "1.1.3",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"main": "main.js",
"moduleFormat": [
"amd",
"cjs",
"globals"
],
"license": "MIT",
"ignore": [
"bower_components",
"node_modules",
"package.json",
"testem.json",
"test.js",
"**/.*"
],
"dependencies": {
"ember": "~1.2.0"
},
"homepage": "https://github.com/instructure/ic-styled",
"_release": "1.1.3",
"_resolution": {
"type": "version",
"tag": "v1.1.3",
"commit": "ab42a6228fa04e5330af5066f75809467b8459dd"
},
"_source": "git://github.com/instructure/ic-styled.git",
"_target": "~1.1.0",
"_originalSource": "ic-styled"
}

View File

@ -0,0 +1,21 @@
Copyright (C) 2013 Instructure, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,88 @@
ic-styled
=========
Automatically style components with css templates.
Installation
------------
`bower install ic-styled`
`npm install ic-styled`
... or download `main.js` and include it into your app however you want.
Module Support
--------------
ic-styled doesn't export anything, it just adds functionality to
`Ember.Component`. If using a module system, require it somewhere in the
root of your application somewhere (like `application.js`).
- AMD
`define(['ic-styled'], function() {});`
- CJS
`require('ic-styled')`
Usage
-----
Given a component named `x-foo`, create an additional component template
at `components/x-foo-css`, treat it like a css file. The css will be
imported into your app automatically on the first instance of `x-foo`.
Sounds tricky but its not; here's a sample app:
```html
<script type="text/x-handlebars">
<h1>Application Template using x-foo</h1>
{{x-foo}}
</script>
<script type="text/x-handlebars" id="components/x-foo">
I am x-foo, the main component.
</script>
<script type="text/x-handlebars" id="components/x-foo-css">
/* I am x-foo-css, the styles that go with x-foo */
x-foo { color: red; font-weight: bold; }
</script>
<script>
var App = Ember.Application.create();
App.XFooComponent = Ember.Component.extend({
tagName: 'x-foo'
});
</script>
```
At the first render of `{{x-foo}}` the `{{x-foo-css}}` template is
imported into the app to style `x-foo` elements.
Overriding Component Styles
---------------------------
`Styled` injects the css template to the top of the `<head>` element so
its the first-ish css to be applied. This means that you can override
the CSS of styled components the same as any native element since your
app's CSS will be applied after.
Contributing
------------
```sh
bower install
npm install
npm test
```
License and Copyright
---------------------
MIT Style license
(c) 2013 Instructure, Inc.

View File

@ -0,0 +1,25 @@
{
"name": "ic-styled",
"version": "1.1.3",
"authors": [
"Ryan Florence <rpflorence@gmail.com>"
],
"main": "main.js",
"moduleFormat": [
"amd",
"cjs",
"globals"
],
"license": "MIT",
"ignore": [
"bower_components",
"node_modules",
"package.json",
"testem.json",
"test.js",
"**/.*"
],
"dependencies": {
"ember": "~1.2.0"
}
}

View File

@ -0,0 +1,54 @@
/*!
* ic-styled
* please see license at https://github.com/instructure/ic-styled
*/
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['ember'], function(Ember) { return factory(Ember); });
} else if (typeof exports === 'object') {
module.exports = factory(require('ember'));
} else {
root.ic = root.ic || {};
root.ic.Styled = factory(Ember);
}
}(this, function(Ember) {
/*
* Auto-injects a sister component containing the styles for this component.
* Given a component `x-foo` create a template at `components/x-foo-css`,
* treat it like a `css` file, it becomes a `<style>` tag.
*/
Ember.Component.reopen({
injectStyles: function() {
var klass = this.constructor;
var Style = lookupStyleComponent(this);
if (!Style || Style._injected) { return; }
Style._injected = true;
var style = Style.create();
style.reopen({tagName: 'style', classNames: 'ic-styled'});
style.appendTo(document.body);
Ember.run.scheduleOnce('afterRender', this, function() {
style.$().prependTo('head');
});
}.on('willInsertElement')
});
function getStyleComponentName(component) {
var tagName = component.get('tagName');
if (!tagName || tagName.indexOf('-') == -1) {
// do not use _debugContainerKey without permission from Stefan Penner
tagName = component._debugContainerKey.split(':')[1];
}
return tagName+'-css';
}
function lookupStyleComponent(component) {
var noIdea = component.container.lookup('component-lookup:main');
var name = getStyleComponentName(component);
return noIdea.lookupFactory(name, component.container);
}
}));

View File

@ -0,0 +1,21 @@
{
"name": "jquery",
"version": "2.0.3",
"description": "jQuery component",
"keywords": [
"jquery",
"component"
],
"main": "jquery.js",
"license": "MIT",
"homepage": "https://github.com/components/jquery",
"_release": "2.0.3",
"_resolution": {
"type": "version",
"tag": "2.0.3",
"commit": "452a56b52b8f4a032256cdb8b6838f25f0bdb3d2"
},
"_source": "git://github.com/components/jquery.git",
"_target": ">= 1.7",
"_originalSource": "jquery"
}

View File

@ -0,0 +1 @@
build

View File

@ -0,0 +1,11 @@
jQuery Component
================
Shim repository for the [jQuery](http://jquery.com).
Package Managers
----------------
* [Bower](http://bower.io/): `jquery`
* [Component](https://github.com/component/component): `components/jquery`
* [Composer](http://packagist.org/packages/components/jquery): `components/jquery`

View File

@ -0,0 +1,11 @@
{
"name": "jquery",
"version": "2.0.3",
"description": "jQuery component",
"keywords": [
"jquery",
"component"
],
"main": "jquery.js",
"license": "MIT"
}

View File

@ -0,0 +1,15 @@
{
"name": "jquery",
"repo": "components/jquery",
"version": "2.0.3",
"description": "jQuery component",
"keywords": [
"jquery",
"component"
],
"main": "jquery.js",
"scripts": [
"jquery.js"
],
"license": "MIT"
}

View File

@ -0,0 +1,35 @@
{
"name": "components/jquery",
"description": "jQuery JavaScript Library",
"type": "component",
"homepage": "http://jquery.com",
"license": "MIT",
"support": {
"irc": "irc://irc.freenode.org/jquery",
"issues": "http://bugs.jquery.com",
"forum": "http://forum.jquery.com",
"wiki": "http://docs.jquery.com/",
"source": "https://github.com/jquery/jquery"
},
"authors": [
{
"name": "John Resig",
"email": "jeresig@gmail.com"
}
],
"require": {
"robloach/component-installer": "*"
},
"extra": {
"component": {
"scripts": [
"jquery.js"
],
"files": [
"jquery.min.js",
"jquery-migrate.js",
"jquery-migrate.min.js"
]
}
}
}

View File

@ -0,0 +1,511 @@
/*!
* jQuery Migrate - v1.1.1 - 2013-02-16
* https://github.com/jquery/jquery-migrate
* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
*/
(function( jQuery, window, undefined ) {
// See http://bugs.jquery.com/ticket/13335
// "use strict";
var warnedAbout = {};
// List of warnings already given; public read only
jQuery.migrateWarnings = [];
// Set to true to prevent console output; migrateWarnings still maintained
// jQuery.migrateMute = false;
// Show a message on the console so devs know we're active
if ( !jQuery.migrateMute && window.console && console.log ) {
console.log("JQMIGRATE: Logging is active");
}
// Set to false to disable traces that appear with warnings
if ( jQuery.migrateTrace === undefined ) {
jQuery.migrateTrace = true;
}
// Forget any warnings we've already given; public
jQuery.migrateReset = function() {
warnedAbout = {};
jQuery.migrateWarnings.length = 0;
};
function migrateWarn( msg) {
if ( !warnedAbout[ msg ] ) {
warnedAbout[ msg ] = true;
jQuery.migrateWarnings.push( msg );
if ( window.console && console.warn && !jQuery.migrateMute ) {
console.warn( "JQMIGRATE: " + msg );
if ( jQuery.migrateTrace && console.trace ) {
console.trace();
}
}
}
}
function migrateWarnProp( obj, prop, value, msg ) {
if ( Object.defineProperty ) {
// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
// allow property to be overwritten in case some other plugin wants it
try {
Object.defineProperty( obj, prop, {
configurable: true,
enumerable: true,
get: function() {
migrateWarn( msg );
return value;
},
set: function( newValue ) {
migrateWarn( msg );
value = newValue;
}
});
return;
} catch( err ) {
// IE8 is a dope about Object.defineProperty, can't warn there
}
}
// Non-ES5 (or broken) browser; just set the property
jQuery._definePropertyBroken = true;
obj[ prop ] = value;
}
if ( document.compatMode === "BackCompat" ) {
// jQuery has never supported or tested Quirks Mode
migrateWarn( "jQuery is not compatible with Quirks Mode" );
}
var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
oldAttr = jQuery.attr,
valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
function() { return null; },
valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
function() { return undefined; },
rnoType = /^(?:input|button)$/i,
rnoAttrNodeType = /^[238]$/,
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
ruseDefault = /^(?:checked|selected)$/i;
// jQuery.attrFn
migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
jQuery.attr = function( elem, name, value, pass ) {
var lowerName = name.toLowerCase(),
nType = elem && elem.nodeType;
if ( pass ) {
// Since pass is used internally, we only warn for new jQuery
// versions where there isn't a pass arg in the formal params
if ( oldAttr.length < 4 ) {
migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
}
if ( elem && !rnoAttrNodeType.test( nType ) &&
(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
return jQuery( elem )[ name ]( value );
}
}
// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
}
// Restore boolHook for boolean property/attribute synchronization
if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
jQuery.attrHooks[ lowerName ] = {
get: function( elem, name ) {
// Align boolean attributes with corresponding properties
// Fall back to attribute presence where some booleans are not supported
var attrNode,
property = jQuery.prop( elem, name );
return property === true || typeof property !== "boolean" &&
( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
name.toLowerCase() :
undefined;
},
set: function( elem, value, name ) {
var propName;
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else {
// value is true since we know at this point it's type boolean and not false
// Set boolean attributes to the same name and set the DOM property
propName = jQuery.propFix[ name ] || name;
if ( propName in elem ) {
// Only set the IDL specifically if it already exists on the element
elem[ propName ] = true;
}
elem.setAttribute( name, name.toLowerCase() );
}
return name;
}
};
// Warn only for attributes that can remain distinct from their properties post-1.9
if ( ruseDefault.test( lowerName ) ) {
migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
}
}
return oldAttr.call( jQuery, elem, name, value );
};
// attrHooks: value
jQuery.attrHooks.value = {
get: function( elem, name ) {
var nodeName = ( elem.nodeName || "" ).toLowerCase();
if ( nodeName === "button" ) {
return valueAttrGet.apply( this, arguments );
}
if ( nodeName !== "input" && nodeName !== "option" ) {
migrateWarn("jQuery.fn.attr('value') no longer gets properties");
}
return name in elem ?
elem.value :
null;
},
set: function( elem, value ) {
var nodeName = ( elem.nodeName || "" ).toLowerCase();
if ( nodeName === "button" ) {
return valueAttrSet.apply( this, arguments );
}
if ( nodeName !== "input" && nodeName !== "option" ) {
migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
}
// Does not return so that setAttribute is also used
elem.value = value;
}
};
var matched, browser,
oldInit = jQuery.fn.init,
oldParseJSON = jQuery.parseJSON,
// Note this does NOT include the #9521 XSS fix from 1.7!
rquickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*|#([\w\-]*))$/;
// $(html) "looks like html" rule change
jQuery.fn.init = function( selector, context, rootjQuery ) {
var match;
if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
(match = rquickExpr.exec( selector )) && match[1] ) {
// This is an HTML string according to the "old" rules; is it still?
if ( selector.charAt( 0 ) !== "<" ) {
migrateWarn("$(html) HTML strings must start with '<' character");
}
// Now process using loose rules; let pre-1.8 play too
if ( context && context.context ) {
// jQuery object as context; parseHTML expects a DOM object
context = context.context;
}
if ( jQuery.parseHTML ) {
return oldInit.call( this, jQuery.parseHTML( jQuery.trim(selector), context, true ),
context, rootjQuery );
}
}
return oldInit.apply( this, arguments );
};
jQuery.fn.init.prototype = jQuery.fn;
// Let $.parseJSON(falsy_value) return null
jQuery.parseJSON = function( json ) {
if ( !json && json !== null ) {
migrateWarn("jQuery.parseJSON requires a valid JSON string");
return null;
}
return oldParseJSON.apply( this, arguments );
};
jQuery.uaMatch = function( ua ) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
// Don't clobber any existing jQuery.browser in case it's different
if ( !jQuery.browser ) {
matched = jQuery.uaMatch( navigator.userAgent );
browser = {};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
}
// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
browser.webkit = true;
} else if ( browser.webkit ) {
browser.safari = true;
}
jQuery.browser = browser;
}
// Warn if the code tries to get jQuery.browser
migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
jQuery.sub = function() {
function jQuerySub( selector, context ) {
return new jQuerySub.fn.init( selector, context );
}
jQuery.extend( true, jQuerySub, this );
jQuerySub.superclass = this;
jQuerySub.fn = jQuerySub.prototype = this();
jQuerySub.fn.constructor = jQuerySub;
jQuerySub.sub = this.sub;
jQuerySub.fn.init = function init( selector, context ) {
if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
context = jQuerySub( context );
}
return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
};
jQuerySub.fn.init.prototype = jQuerySub.fn;
var rootjQuerySub = jQuerySub(document);
migrateWarn( "jQuery.sub() is deprecated" );
return jQuerySub;
};
// Ensure that $.ajax gets the new parseJSON defined in core.js
jQuery.ajaxSetup({
converters: {
"text json": jQuery.parseJSON
}
});
var oldFnData = jQuery.fn.data;
jQuery.fn.data = function( name ) {
var ret, evt,
elem = this[0];
// Handles 1.7 which has this behavior and 1.8 which doesn't
if ( elem && name === "events" && arguments.length === 1 ) {
ret = jQuery.data( elem, name );
evt = jQuery._data( elem, name );
if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
migrateWarn("Use of jQuery.fn.data('events') is deprecated");
return evt;
}
}
return oldFnData.apply( this, arguments );
};
var rscriptType = /\/(java|ecma)script/i,
oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
jQuery.fn.andSelf = function() {
migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
return oldSelf.apply( this, arguments );
};
// Since jQuery.clean is used internally on older versions, we only shim if it's missing
if ( !jQuery.clean ) {
jQuery.clean = function( elems, context, fragment, scripts ) {
// Set context per 1.8 logic
context = context || document;
context = !context.nodeType && context[0] || context;
context = context.ownerDocument || context;
migrateWarn("jQuery.clean() is deprecated");
var i, elem, handleScript, jsTags,
ret = [];
jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
// Complex logic lifted directly from jQuery 1.8
if ( fragment ) {
// Special handling of each script element
handleScript = function( elem ) {
// Check if we consider it executable
if ( !elem.type || rscriptType.test( elem.type ) ) {
// Detach the script and store it in the scripts array (if provided) or the fragment
// Return truthy to indicate that it has been handled
return scripts ?
scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
fragment.appendChild( elem );
}
};
for ( i = 0; (elem = ret[i]) != null; i++ ) {
// Check if we're done after handling an executable script
if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
// Append to fragment and handle embedded scripts
fragment.appendChild( elem );
if ( typeof elem.getElementsByTagName !== "undefined" ) {
// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
// Splice the scripts into ret after their former ancestor and advance our index beyond them
ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
i += jsTags.length;
}
}
}
}
return ret;
};
}
var eventAdd = jQuery.event.add,
eventRemove = jQuery.event.remove,
eventTrigger = jQuery.event.trigger,
oldToggle = jQuery.fn.toggle,
oldLive = jQuery.fn.live,
oldDie = jQuery.fn.die,
ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
hoverHack = function( events ) {
if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
return events;
}
if ( rhoverHack.test( events ) ) {
migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
}
return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
};
// Event props removed in 1.9, put them back if needed; no practical way to warn them
if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
}
// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
if ( jQuery.event.dispatch ) {
migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
}
// Support for 'hover' pseudo-event and ajax event warnings
jQuery.event.add = function( elem, types, handler, data, selector ){
if ( elem !== document && rajaxEvent.test( types ) ) {
migrateWarn( "AJAX events should be attached to document: " + types );
}
eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
};
jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
};
jQuery.fn.error = function() {
var args = Array.prototype.slice.call( arguments, 0);
migrateWarn("jQuery.fn.error() is deprecated");
args.splice( 0, 0, "error" );
if ( arguments.length ) {
return this.bind.apply( this, args );
}
// error event should not bubble to window, although it does pre-1.7
this.triggerHandler.apply( this, args );
return this;
};
jQuery.fn.toggle = function( fn, fn2 ) {
// Don't mess with animation or css toggles
if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
return oldToggle.apply( this, arguments );
}
migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
// Save reference to arguments for access in closure
var args = arguments,
guid = fn.guid || jQuery.guid++,
i = 0,
toggler = function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
// and execute the function
return args[ lastToggle ].apply( this, arguments ) || false;
};
// link all the functions, so any of them can unbind this click handler
toggler.guid = guid;
while ( i < args.length ) {
args[ i++ ].guid = guid;
}
return this.click( toggler );
};
jQuery.fn.live = function( types, data, fn ) {
migrateWarn("jQuery.fn.live() is deprecated");
if ( oldLive ) {
return oldLive.apply( this, arguments );
}
jQuery( this.context ).on( types, this.selector, data, fn );
return this;
};
jQuery.fn.die = function( types, fn ) {
migrateWarn("jQuery.fn.die() is deprecated");
if ( oldDie ) {
return oldDie.apply( this, arguments );
}
jQuery( this.context ).off( types, this.selector || "**", fn );
return this;
};
// Turn global events into document-triggered events
jQuery.event.trigger = function( event, data, elem, onlyHandlers ){
if ( !elem && !rajaxEvent.test( event ) ) {
migrateWarn( "Global events are undocumented and deprecated" );
}
return eventTrigger.call( this, event, data, elem || document, onlyHandlers );
};
jQuery.each( ajaxEvents.split("|"),
function( _, name ) {
jQuery.event.special[ name ] = {
setup: function() {
var elem = this;
// The document needs no shimming; must be !== for oldIE
if ( elem !== document ) {
jQuery.event.add( document, name + "." + jQuery.guid, function() {
jQuery.event.trigger( name, null, elem, true );
});
jQuery._data( this, name, jQuery.guid++ );
}
return false;
},
teardown: function() {
if ( this !== document ) {
jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
}
return false;
}
};
}
);
})( jQuery, window );

File diff suppressed because one or more lines are too long

8829
public/javascripts/bower/jquery/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
{
"name": "components-jquery",
"version": "2.0.3",
"description": "jQuery component",
"keywords": ["jquery"],
"main": "./jquery.js"
}

View File

@ -73,7 +73,7 @@
name: 'spec',
location: '../../spec'
},
]
].concat(<%= packages %>)
};
</script>
<script src="../../public/javascripts/vendor/require.js"></script>