Add third party js on which converse.js depends
This commit is contained in:
parent
5fdb4d1f29
commit
d4d4979a39
20
Libraries/app.build.js
Normal file
20
Libraries/app.build.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
({
|
||||
appDir: "../",
|
||||
baseUrl: "scripts/",
|
||||
dir: "../../webapp-build",
|
||||
//Comment out the optimize line if you want
|
||||
//the code minified by UglifyJS
|
||||
optimize: "none",
|
||||
|
||||
paths: {
|
||||
"jquery": "empty:"
|
||||
},
|
||||
|
||||
modules: [
|
||||
//Optimize the application files. jQuery is not
|
||||
//included since it is already in require-jquery.js
|
||||
{
|
||||
name: "main"
|
||||
}
|
||||
]
|
||||
})
|
1431
Libraries/backbone.js
Normal file
1431
Libraries/backbone.js
Normal file
File diff suppressed because it is too large
Load Diff
23
Libraries/burry.js/LICENSE
Normal file
23
Libraries/burry.js/LICENSE
Normal file
|
@ -0,0 +1,23 @@
|
|||
Copyright (c) 2012 Yiorgis Gozadinos, Riot AS
|
||||
Postboks 2236, 3103 Tønsberg, Norway
|
||||
|
||||
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.
|
80
Libraries/burry.js/README.md
Normal file
80
Libraries/burry.js/README.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
# burry.js
|
||||
|
||||
A simple caching layer on the browser's localStorage
|
||||
|
||||
## Usage
|
||||
|
||||
### Creation
|
||||
|
||||
Create a Burry `Store`, optionally passing a namespace. A default store is always available with no namespace:
|
||||
|
||||
```javascript
|
||||
var burry = new Burry.Store('mystuff');
|
||||
```
|
||||
|
||||
If you want to also set a default time-to-live on a namespaced store, pass the time-to-live as a second parameter. For instance,
|
||||
|
||||
```javascript
|
||||
var burrywithttl = new Burry.Store('mystuff', 10);
|
||||
```
|
||||
|
||||
will create a store where the default time-to-live when you set items is 10 minutes.
|
||||
|
||||
You can obtain all available stores, by invoking `stores()`:
|
||||
|
||||
```javascript
|
||||
var stores = Burry.stores(); // stores is ['', 'mystuff']
|
||||
```
|
||||
|
||||
### Getting/Setting
|
||||
|
||||
`set` and `get` JSON-serializable javascript objects easily to and from the cache.
|
||||
|
||||
```javascript
|
||||
burry.set('foo', {bar: 'burry'});
|
||||
var foo = burry.get('foo'); // foo is {bar: 'burry'}
|
||||
foo = burry.get('unknown'); // foo is undefined
|
||||
```
|
||||
|
||||
You can specify a time-to-live per key/value. This is expressed in minutes:
|
||||
|
||||
```javascript
|
||||
burry.set('foo', {bar: 'burry'}, 10);
|
||||
var foo = burry.get('foo'); // foo is {bar: 'burry'}
|
||||
...
|
||||
// Ten minutes later...
|
||||
foo = burry.get('foo'); // foo is undefined and also removed from localStorage
|
||||
```
|
||||
|
||||
Attempting to `set` when the `localStorage` is full, will try again after flushing expired key/values from the cache. If this does not succeed either, your `set` will be ignored.
|
||||
|
||||
### Counters
|
||||
|
||||
You can increment/decrement persistent counters. If the counter does not exist, it is initialized with the value 0.
|
||||
|
||||
```javascript
|
||||
burry.incr('counter');
|
||||
burry.incr('counter');
|
||||
var counter = burry.get('counter'); // counter === 2
|
||||
burry.decr('counter');
|
||||
counter = burry.get('counter'); // counter === 1
|
||||
```
|
||||
|
||||
### Helpers
|
||||
|
||||
The following more esoteric functions are also exposed:
|
||||
|
||||
* `burry.add(key, value, ttl)`, same as `set` except it will only add the key if it does not already exist, or it has already expired.
|
||||
* `burry.replace(key, value, ttl)`, same as `set` except it will only add the key if it does already exist and has not expired.
|
||||
* `burry.flush()`, removes from `localStorage` all Burry items.
|
||||
* `burry.flushExpired()`, removes from `localStorage` all expired Burry items of the store.
|
||||
* `Burry.flushExpired()`, removes from `localStorage` all expired Burry items of all stores.
|
||||
* `burry.keys()`, returns all stored keys.
|
||||
* `burry.expirableKeys()` return an dictionary of key/values where the values are the TTL of the keys from Epoch.
|
||||
* `burry.hasExpired(key)`, returns whether a key has expired.
|
||||
* `Burry.isSupported()`, returns whether `localStorage` and `JSON` serialization are supported on the browser.
|
||||
|
||||
## License
|
||||
|
||||
Backbone.xmpp.storage is Copyright (C) 2012 Yiorgis Gozadinos, Riot AS.
|
||||
It is distributed under the MIT license.
|
292
Libraries/burry.js/burry.js
Normal file
292
Libraries/burry.js/burry.js
Normal file
|
@ -0,0 +1,292 @@
|
|||
// Burry.js Storage v0.1
|
||||
|
||||
// (c) 2012 Yiorgis Gozadinos, Riot AS.
|
||||
// Burry.js is distributed under the MIT license.
|
||||
// http://github.com/ggozad/burry.js
|
||||
|
||||
// AMD/global registrations
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define([], function () {
|
||||
return factory();
|
||||
});
|
||||
} else {
|
||||
// Browser globals
|
||||
root.Burry = factory();
|
||||
}
|
||||
}(this, function () {
|
||||
|
||||
// Construct a new Burry store with an optional `namespace` and an optional default `ttl`.
|
||||
var Burry = {
|
||||
|
||||
Store: function (ns, default_ttl) {
|
||||
var stores = Burry.stores();
|
||||
if (ns) {
|
||||
this._CACHE_SUFFIX = this._CACHE_SUFFIX + ns;
|
||||
this._EXPIRY_KEY = this._EXPIRY_KEY + ns;
|
||||
if (stores.indexOf(ns) === -1)
|
||||
stores.push(ns);
|
||||
}
|
||||
localStorage.setItem('_burry_stores_', JSON.stringify(stores));
|
||||
this.default_ttl = default_ttl;
|
||||
},
|
||||
|
||||
// Time resolution in minutes
|
||||
_EXPIRY_UNITS: 60 * 1000,
|
||||
|
||||
// Calculate the time since Epoch in minutes
|
||||
_mEpoch: function () {
|
||||
return Math.floor((new Date().getTime())/Burry._EXPIRY_UNITS);
|
||||
},
|
||||
|
||||
stores: function () {
|
||||
var stores = localStorage.getItem('_burry_stores_');
|
||||
if (stores) {
|
||||
stores = JSON.parse(stores);
|
||||
} else {
|
||||
stores = [''];
|
||||
}
|
||||
return stores;
|
||||
},
|
||||
|
||||
// Checks for localStorage & JSON support.
|
||||
isSupported: function () {
|
||||
// If this has been called before we already know.
|
||||
if (Burry._isSupported) return Burry._isSupported;
|
||||
|
||||
try {
|
||||
localStorage.setItem('_burry_', '_burry_');
|
||||
localStorage.removeItem('_burry_');
|
||||
} catch (e) {
|
||||
return Burry._isSupported = false;
|
||||
}
|
||||
if (!JSON) {
|
||||
return Burry._isSupported = false;
|
||||
}
|
||||
return Burry._isSupported = true;
|
||||
},
|
||||
|
||||
flushExpired: function () {
|
||||
var i, match, key, val, ns,
|
||||
remove = [],
|
||||
now = Burry._mEpoch();
|
||||
|
||||
for (i=0; i< localStorage.length; i++) {
|
||||
key = localStorage.key(i);
|
||||
match = key.match(/(.+)-_burry_exp_(.*)/);
|
||||
if (match) {
|
||||
val = localStorage.getItem(key);
|
||||
if (val < now) {
|
||||
key = match[1]; ns = match[2];
|
||||
remove.push(key + Burry.Store.prototype._CACHE_SUFFIX + ns);
|
||||
remove.push(key + Burry.Store.prototype._EXPIRY_KEY + ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i< remove.length; i++) {
|
||||
localStorage.removeItem(remove[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Instance methods
|
||||
|
||||
Burry.Store.prototype = {
|
||||
|
||||
// Suffix to all keys in the cache
|
||||
_CACHE_SUFFIX: '-_burry_',
|
||||
|
||||
// Key used to store expiration data
|
||||
_EXPIRY_KEY: '-_burry_exp_',
|
||||
|
||||
// Return the internally used suffixed key.
|
||||
_internalKey: function (key) {
|
||||
return key + this._CACHE_SUFFIX;
|
||||
},
|
||||
|
||||
// Return the internally used suffixed expiration key.
|
||||
_expirationKey: function (key) {
|
||||
return key + this._EXPIRY_KEY;
|
||||
},
|
||||
|
||||
// Check if a key is a valid internal key
|
||||
_isInternalKey: function (key) {
|
||||
if (key.slice(-this._CACHE_SUFFIX.length) === this._CACHE_SUFFIX)
|
||||
return key.slice(0, -this._CACHE_SUFFIX.length);
|
||||
return false;
|
||||
},
|
||||
|
||||
// Check if a key is a valid expiration key
|
||||
_isExpirationKey: function (key) {
|
||||
if (key.slice(-this._EXPIRY_KEY.length) === this._EXPIRY_KEY)
|
||||
return key.slice(0, -this._EXPIRY_KEY.length);
|
||||
return false;
|
||||
},
|
||||
|
||||
// Returns in how many minutes after Epoch the key expires,
|
||||
// or `undefined` if it does not expire.
|
||||
_expiresOn: function (key) {
|
||||
var expires = localStorage.getItem(this._expirationKey(key));
|
||||
if (expires) {
|
||||
return parseInt(expires, 10);
|
||||
}
|
||||
},
|
||||
|
||||
// Parse the value of a key as an integer.
|
||||
_getCounter: function (bkey) {
|
||||
var value = localStorage.getItem(bkey);
|
||||
if (value === null) return 0;
|
||||
|
||||
return parseInt(value, 10);
|
||||
},
|
||||
|
||||
// Returns the value of `key` from the cache, `undefined` if the `key` has
|
||||
// expired or is not stored.
|
||||
get: function (key) {
|
||||
var value = localStorage.getItem(this._internalKey(key));
|
||||
if (value === null) {
|
||||
return undefined;
|
||||
}
|
||||
if (this.hasExpired(key)) {
|
||||
this.remove(key);
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
// Sets a `key`/`value` on the cache. Optionally, sets the expiration in `ttl` minutes.
|
||||
set: function (key, value, ttl) {
|
||||
var i, bkey, expires = {};
|
||||
ttl = ttl || this.default_ttl;
|
||||
if (ttl) ttl = parseInt(ttl, 10);
|
||||
if (typeof key === undefined || typeof value === undefined) return;
|
||||
value = JSON.stringify(value);
|
||||
try {
|
||||
localStorage.setItem(this._internalKey(key), value);
|
||||
if (ttl) {
|
||||
localStorage.setItem(this._expirationKey(key), Burry._mEpoch() + ttl);
|
||||
} else {
|
||||
localStorage.removeItem(this._expirationKey(key));
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
|
||||
// No space left on localStorage, let's flush expired items and try agagin.
|
||||
Burry.flushExpired();
|
||||
try {
|
||||
localStorage.setItem(this._internalKey(key), value);
|
||||
if (ttl) {
|
||||
localStorage.setItem(this._expirationKey(key), Burry._mEpoch() + ttl);
|
||||
} else {
|
||||
localStorage.removeItem(this._expirationKey(key));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// Oh well. Let's forget about it.
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Sets a `key`/`value` on the cache as does **set** but only if the key does not already exist or has expired.
|
||||
add: function (key, value, ttl) {
|
||||
if (localStorage.getItem(this._internalKey(key)) === null || this.hasExpired(key)) {
|
||||
this.set(key, value, ttl);
|
||||
}
|
||||
},
|
||||
|
||||
// Sets a `key`/`value` on the cache as does **set** but only if the key already exist and has not expired.
|
||||
replace: function (key, value, ttl) {
|
||||
if (localStorage.getItem(this._internalKey(key)) !== null && !this.hasExpired(key)) {
|
||||
this.set(key, value, ttl);
|
||||
}
|
||||
},
|
||||
|
||||
// Removes an item from the cache.
|
||||
remove: function (key) {
|
||||
localStorage.removeItem(this._internalKey(key));
|
||||
localStorage.removeItem(this._expirationKey(key));
|
||||
},
|
||||
|
||||
// Increments the integer value of `key` by 1
|
||||
incr: function (key) {
|
||||
var bkey = this._internalKey(key),
|
||||
value = this._getCounter(bkey);
|
||||
value++;
|
||||
localStorage.setItem(bkey, value);
|
||||
},
|
||||
|
||||
// Decrements the integer value of `key` by 1
|
||||
decr: function (key) {
|
||||
var bkey = this._internalKey(key),
|
||||
value = this._getCounter(bkey);
|
||||
value--;
|
||||
localStorage.setItem(bkey, value);
|
||||
},
|
||||
|
||||
// Returns whether `key` has expired.
|
||||
hasExpired: function (key) {
|
||||
var expireson = this._expiresOn(key);
|
||||
if (expireson && (expireson < Burry._mEpoch())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Returns a list of all the cached keys
|
||||
keys: function () {
|
||||
var i, bkey, key, results = [];
|
||||
for (i=0; i < localStorage.length ; i++) {
|
||||
bkey = localStorage.key(i);
|
||||
key = this._isInternalKey(bkey);
|
||||
if (key) {
|
||||
results.push(key);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
// Returns an object with all the expirable keys. The values are the ttl
|
||||
// in minutes since Epoch.
|
||||
expirableKeys: function () {
|
||||
var i, bkey, key, results = {};
|
||||
for (i=0; i < localStorage.length ; i++) {
|
||||
bkey = localStorage.key(i);
|
||||
key = this._isExpirationKey(bkey);
|
||||
if (key) {
|
||||
results[key] = parseInt(localStorage.getItem(bkey), 10);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
// Removes all Burry items from `localStorage`.
|
||||
flush: function () {
|
||||
var i, key, remove = [];
|
||||
for (i=0; i < localStorage.length ; i++) {
|
||||
key = localStorage.key(i);
|
||||
if (this._isInternalKey(key) || this._isExpirationKey(key)) {
|
||||
remove.push(key);
|
||||
}
|
||||
}
|
||||
for (i=0; i<remove.length; i++)
|
||||
localStorage.removeItem(remove[i]);
|
||||
},
|
||||
|
||||
// Removes all expired items.
|
||||
flushExpired: function () {
|
||||
var expirable = this.expirableKeys(), now = Burry._mEpoch(), key, val;
|
||||
for (key in expirable) {
|
||||
val = expirable[key];
|
||||
if (val < now) this.remove(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Burry;
|
||||
}));
|
601
Libraries/burry.js/docs/burry.html
Normal file
601
Libraries/burry.js/docs/burry.html
Normal file
|
@ -0,0 +1,601 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
<title>burry.js</title>
|
||||
<link rel="stylesheet" href="pycco.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="background"></div>
|
||||
<div id='container'>
|
||||
<div class='section'>
|
||||
<div class='docs'><h1>burry.js</h1></div>
|
||||
</div>
|
||||
<div class='clearall'>
|
||||
<div class='section' id='section-0'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-0'>#</a>
|
||||
</div>
|
||||
<p>Burry.js Storage v0.1</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-1'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-1'>#</a>
|
||||
</div>
|
||||
<p>(c) 2012 Yiorgis Gozadinos, Riot AS.
|
||||
Burry.js is distributed under the MIT license.
|
||||
http://github.com/ggozad/burry.js</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-2'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-2'>#</a>
|
||||
</div>
|
||||
<p>AMD/global registrations</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">root</span><span class="p">,</span> <span class="nx">factory</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">define</span> <span class="o">===</span> <span class="s1">'function'</span> <span class="o">&&</span> <span class="nx">define</span><span class="p">.</span><span class="nx">amd</span><span class="p">)</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-3'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-3'>#</a>
|
||||
</div>
|
||||
<p>AMD. Register as an anonymous module.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">define</span><span class="p">([],</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">factory</span><span class="p">();</span>
|
||||
<span class="p">});</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-4'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-4'>#</a>
|
||||
</div>
|
||||
<p>Browser globals</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">root</span><span class="p">.</span><span class="nx">Burry</span> <span class="o">=</span> <span class="nx">factory</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}(</span><span class="k">this</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-5'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-5'>#</a>
|
||||
</div>
|
||||
<p>Construct a new Burry store with an optional <code>namespace</code> and an optional default <code>ttl</code>.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="kd">var</span> <span class="nx">Burry</span> <span class="o">=</span> <span class="p">{</span>
|
||||
|
||||
<span class="nx">Store</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">ns</span><span class="p">,</span> <span class="nx">default_ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">stores</span> <span class="o">=</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">stores</span><span class="p">();</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">ns</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span> <span class="o">+</span> <span class="nx">ns</span><span class="p">;</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span> <span class="o">+</span> <span class="nx">ns</span><span class="p">;</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">stores</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">ns</span><span class="p">)</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="nx">stores</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">ns</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">'_burry_stores_'</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">stores</span><span class="p">));</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">default_ttl</span> <span class="o">=</span> <span class="nx">default_ttl</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-6'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-6'>#</a>
|
||||
</div>
|
||||
<p>Time resolution in minutes</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_EXPIRY_UNITS</span><span class="o">:</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">,</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-7'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-7'>#</a>
|
||||
</div>
|
||||
<p>Calculate the time since Epoch in minutes</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_mEpoch</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">((</span><span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">())</span><span class="o">/</span><span class="nx">Burry</span><span class="p">.</span><span class="nx">_EXPIRY_UNITS</span><span class="p">);</span>
|
||||
<span class="p">},</span>
|
||||
|
||||
<span class="nx">stores</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">stores</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">'_burry_stores_'</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">stores</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">stores</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">stores</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">stores</span> <span class="o">=</span> <span class="p">[</span><span class="s1">''</span><span class="p">];</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="nx">stores</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-8'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-8'>#</a>
|
||||
</div>
|
||||
<p>Checks for localStorage & JSON support.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">isSupported</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">'_burry_'</span><span class="p">,</span> <span class="s1">'_burry_'</span><span class="p">);</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="s1">'_burry_'</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">JSON</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
||||
<span class="p">},</span>
|
||||
|
||||
<span class="nx">flushExpired</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">match</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span><span class="p">,</span> <span class="nx">ns</span><span class="p">,</span>
|
||||
<span class="nx">remove</span> <span class="o">=</span> <span class="p">[],</span>
|
||||
<span class="nx">now</span> <span class="o">=</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">_mEpoch</span><span class="p">();</span>
|
||||
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o"><</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">key</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">key</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
|
||||
<span class="nx">match</span> <span class="o">=</span> <span class="nx">key</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/(.+)-_burry_exp_(.*)/</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">match</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">val</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o"><</span> <span class="nx">now</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">key</span> <span class="o">=</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="nx">ns</span> <span class="o">=</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
|
||||
<span class="nx">remove</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span> <span class="o">+</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">Store</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span> <span class="o">+</span> <span class="nx">ns</span><span class="p">);</span>
|
||||
<span class="nx">remove</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span> <span class="o">+</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">Store</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span> <span class="o">+</span> <span class="nx">ns</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o"><</span> <span class="nx">remove</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="nx">remove</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-9'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-9'>#</a>
|
||||
</div>
|
||||
<p>Instance methods</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">Burry</span><span class="p">.</span><span class="nx">Store</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-10'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-10'>#</a>
|
||||
</div>
|
||||
<p>Suffix to all keys in the cache</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_CACHE_SUFFIX</span><span class="o">:</span> <span class="s1">'-_burry_'</span><span class="p">,</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-11'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-11'>#</a>
|
||||
</div>
|
||||
<p>Key used to store expiration data</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_EXPIRY_KEY</span><span class="o">:</span> <span class="s1">'-_burry_exp_'</span><span class="p">,</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-12'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-12'>#</a>
|
||||
</div>
|
||||
<p>Return the internally used suffixed key.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_internalKey</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">key</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-13'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-13'>#</a>
|
||||
</div>
|
||||
<p>Return the internally used suffixed expiration key.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_expirationKey</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nx">key</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-14'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-14'>#</a>
|
||||
</div>
|
||||
<p>Check if a key is a valid internal key</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_isInternalKey</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="o">-</span><span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">===</span> <span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nx">key</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="k">this</span><span class="p">.</span><span class="nx">_CACHE_SUFFIX</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-15'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-15'>#</a>
|
||||
</div>
|
||||
<p>Check if a key is a valid expiration key</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_isExpirationKey</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="o">-</span><span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">===</span> <span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nx">key</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="k">this</span><span class="p">.</span><span class="nx">_EXPIRY_KEY</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-16'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-16'>#</a>
|
||||
</div>
|
||||
<p>Returns in how many minutes after Epoch the key expires,
|
||||
or <code>undefined</code> if it does not expire.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_expiresOn</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">expires</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">expires</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">expires</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-17'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-17'>#</a>
|
||||
</div>
|
||||
<p>Parse the value of a key as an integer.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">_getCounter</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">bkey</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="nx">bkey</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">value</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-18'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-18'>#</a>
|
||||
</div>
|
||||
<p>Returns the value of <code>key</code> from the cache, <code>undefined</code> if the <code>key</code> has
|
||||
expired or is not stored.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">get</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">value</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">hasExpired</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">value</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">undefined</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="nx">value</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-19'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-19'>#</a>
|
||||
</div>
|
||||
<p>Sets a <code>key</code>/<code>value</code> on the cache. Optionally, sets the expiration in <code>ttl</code> minutes.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">set</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">bkey</span><span class="p">,</span> <span class="nx">expires</span> <span class="o">=</span> <span class="p">{};</span>
|
||||
<span class="nx">ttl</span> <span class="o">=</span> <span class="nx">ttl</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">default_ttl</span><span class="p">;</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">ttl</span><span class="p">)</span> <span class="nx">ttl</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">ttl</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">key</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">value</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
|
||||
<span class="nx">value</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span> <span class="nx">value</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">_mEpoch</span><span class="p">()</span> <span class="o">+</span> <span class="nx">ttl</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s1">'QUOTA_EXCEEDED_ERR'</span> <span class="o">||</span> <span class="nx">e</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s1">'NS_ERROR_DOM_QUOTA_REACHED'</span><span class="p">)</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-20'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-20'>#</a>
|
||||
</div>
|
||||
<p>No space left on localStorage, let's flush expired items and try agagin.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">Burry</span><span class="p">.</span><span class="nx">flushExpired</span><span class="p">();</span>
|
||||
<span class="k">try</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span> <span class="nx">value</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">_mEpoch</span><span class="p">()</span> <span class="o">+</span> <span class="nx">ttl</span><span class="p">);</span>
|
||||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-21'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-21'>#</a>
|
||||
</div>
|
||||
<p>Oh well. Let's forget about it.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-22'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-22'>#</a>
|
||||
</div>
|
||||
<p>Sets a <code>key</code>/<code>value</code> on the cache as does <strong>set</strong> but only if the key does not already exist or has expired.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">add</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">hasExpired</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">ttl</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-23'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-23'>#</a>
|
||||
</div>
|
||||
<p>Sets a <code>key</code>/<code>value</code> on the cache as does <strong>set</strong> but only if the key already exist and has not expired.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">replace</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">ttl</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="o">!==</span> <span class="kc">null</span> <span class="o">&&</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">hasExpired</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">ttl</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-24'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-24'>#</a>
|
||||
</div>
|
||||
<p>Removes an item from the cache.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">remove</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_expirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">));</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-25'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-25'>#</a>
|
||||
</div>
|
||||
<p>Increments the integer value of <code>key</code> by 1</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">incr</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">bkey</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span>
|
||||
<span class="nx">value</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_getCounter</span><span class="p">(</span><span class="nx">bkey</span><span class="p">);</span>
|
||||
<span class="nx">value</span><span class="o">++</span><span class="p">;</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="nx">bkey</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-26'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-26'>#</a>
|
||||
</div>
|
||||
<p>Decrements the integer value of <code>key</code> by 1</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">decr</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">bkey</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_internalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">),</span>
|
||||
<span class="nx">value</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_getCounter</span><span class="p">(</span><span class="nx">bkey</span><span class="p">);</span>
|
||||
<span class="nx">value</span><span class="o">--</span><span class="p">;</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="nx">bkey</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-27'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-27'>#</a>
|
||||
</div>
|
||||
<p>Returns whether <code>key</code> has expired.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">hasExpired</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">expireson</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_expiresOn</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">expireson</span> <span class="o">&&</span> <span class="p">(</span><span class="nx">expireson</span> <span class="o"><</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">_mEpoch</span><span class="p">()))</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-28'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-28'>#</a>
|
||||
</div>
|
||||
<p>Returns a list of all the cached keys</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">keys</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">bkey</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">[];</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span> <span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">bkey</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">key</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
|
||||
<span class="nx">key</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_isInternalKey</span><span class="p">(</span><span class="nx">bkey</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">results</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-29'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-29'>#</a>
|
||||
</div>
|
||||
<p>Returns an object with all the expirable keys. The values are the ttl
|
||||
in minutes since Epoch.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">expirableKeys</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">bkey</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">results</span> <span class="o">=</span> <span class="p">{};</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span> <span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">bkey</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">key</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
|
||||
<span class="nx">key</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">_isExpirationKey</span><span class="p">(</span><span class="nx">bkey</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">results</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="nx">bkey</span><span class="p">),</span> <span class="mi">10</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="nx">results</span><span class="p">;</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-30'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-30'>#</a>
|
||||
</div>
|
||||
<p>Removes all Burry items from <code>localStorage</code>.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">flush</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">remove</span> <span class="o">=</span> <span class="p">[];</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">length</span> <span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">key</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">key</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_isInternalKey</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">_isExpirationKey</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="nx">remove</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o"><</span><span class="nx">remove</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span>
|
||||
<span class="nx">localStorage</span><span class="p">.</span><span class="nx">removeItem</span><span class="p">(</span><span class="nx">remove</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
|
||||
<span class="p">},</span></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
<div class='section' id='section-31'>
|
||||
<div class='docs'>
|
||||
<div class='octowrap'>
|
||||
<a class='octothorpe' href='#section-31'>#</a>
|
||||
</div>
|
||||
<p>Removes all expired items.</p>
|
||||
</div>
|
||||
<div class='code'>
|
||||
<div class="highlight"><pre> <span class="nx">flushExpired</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
|
||||
<span class="kd">var</span> <span class="nx">expirable</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">expirableKeys</span><span class="p">(),</span> <span class="nx">now</span> <span class="o">=</span> <span class="nx">Burry</span><span class="p">.</span><span class="nx">_mEpoch</span><span class="p">(),</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span><span class="p">;</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">expirable</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nx">val</span> <span class="o">=</span> <span class="nx">expirable</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o"><</span> <span class="nx">now</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="k">return</span> <span class="nx">Burry</span><span class="p">;</span>
|
||||
<span class="p">}));</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearall'></div>
|
||||
</div>
|
||||
</body>
|
186
Libraries/burry.js/docs/pycco.css
Normal file
186
Libraries/burry.js/docs/pycco.css
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*--------------------- Layout and Typography ----------------------------*/
|
||||
body {
|
||||
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #252519;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
a {
|
||||
color: #261a3b;
|
||||
}
|
||||
a:visited {
|
||||
color: #261a3b;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 40px 0 15px 0;
|
||||
}
|
||||
h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
}
|
||||
#container, div.section {
|
||||
position: relative;
|
||||
}
|
||||
#background {
|
||||
position: fixed;
|
||||
top: 0; left: 580px; right: 0; bottom: 0;
|
||||
background: #f5f5ff;
|
||||
border-left: 1px solid #e5e5ee;
|
||||
z-index: -1;
|
||||
}
|
||||
#jump_to, #jump_page {
|
||||
background: white;
|
||||
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
|
||||
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
|
||||
font: 10px Arial;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
}
|
||||
#jump_to, #jump_wrapper {
|
||||
position: fixed;
|
||||
right: 0; top: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#jump_wrapper {
|
||||
padding: 0;
|
||||
display: none;
|
||||
}
|
||||
#jump_to:hover #jump_wrapper {
|
||||
display: block;
|
||||
}
|
||||
#jump_page {
|
||||
padding: 5px 0 3px;
|
||||
margin: 0 0 25px 25px;
|
||||
}
|
||||
#jump_page .source {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
text-decoration: none;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
#jump_page .source:hover {
|
||||
background: #f5f5ff;
|
||||
}
|
||||
#jump_page .source:first-child {
|
||||
}
|
||||
div.docs {
|
||||
float: left;
|
||||
max-width: 500px;
|
||||
min-width: 500px;
|
||||
min-height: 5px;
|
||||
padding: 10px 25px 1px 50px;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
.docs pre {
|
||||
margin: 15px 0 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
.docs p tt, .docs p code {
|
||||
background: #f8f8ff;
|
||||
border: 1px solid #dedede;
|
||||
font-size: 12px;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
.octowrap {
|
||||
position: relative;
|
||||
}
|
||||
.octothorpe {
|
||||
font: 12px Arial;
|
||||
text-decoration: none;
|
||||
color: #454545;
|
||||
position: absolute;
|
||||
top: 3px; left: -20px;
|
||||
padding: 1px 2px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
}
|
||||
div.docs:hover .octothorpe {
|
||||
opacity: 1;
|
||||
}
|
||||
div.code {
|
||||
margin-left: 580px;
|
||||
padding: 14px 15px 16px 50px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.code pre, .docs p code {
|
||||
font-size: 12px;
|
||||
}
|
||||
pre, tt, code {
|
||||
line-height: 18px;
|
||||
font-family: Monaco, Consolas, "Lucida Console", monospace;
|
||||
margin: 0; padding: 0;
|
||||
}
|
||||
div.clearall {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------- Syntax Highlighting -----------------------------*/
|
||||
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
|
||||
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
|
||||
body .hll { background-color: #ffffcc }
|
||||
body .c { color: #408080; font-style: italic } /* Comment */
|
||||
body .err { border: 1px solid #FF0000 } /* Error */
|
||||
body .k { color: #954121 } /* Keyword */
|
||||
body .o { color: #666666 } /* Operator */
|
||||
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
body .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
body .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
body .gd { color: #A00000 } /* Generic.Deleted */
|
||||
body .ge { font-style: italic } /* Generic.Emph */
|
||||
body .gr { color: #FF0000 } /* Generic.Error */
|
||||
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
body .gi { color: #00A000 } /* Generic.Inserted */
|
||||
body .go { color: #808080 } /* Generic.Output */
|
||||
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
body .gs { font-weight: bold } /* Generic.Strong */
|
||||
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
body .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
body .kc { color: #954121 } /* Keyword.Constant */
|
||||
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
|
||||
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
|
||||
body .kp { color: #954121 } /* Keyword.Pseudo */
|
||||
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
|
||||
body .kt { color: #B00040 } /* Keyword.Type */
|
||||
body .m { color: #666666 } /* Literal.Number */
|
||||
body .s { color: #219161 } /* Literal.String */
|
||||
body .na { color: #7D9029 } /* Name.Attribute */
|
||||
body .nb { color: #954121 } /* Name.Builtin */
|
||||
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
body .no { color: #880000 } /* Name.Constant */
|
||||
body .nd { color: #AA22FF } /* Name.Decorator */
|
||||
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
body .nf { color: #0000FF } /* Name.Function */
|
||||
body .nl { color: #A0A000 } /* Name.Label */
|
||||
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
|
||||
body .nv { color: #19469D } /* Name.Variable */
|
||||
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
body .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
body .mf { color: #666666 } /* Literal.Number.Float */
|
||||
body .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
body .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
body .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
body .sb { color: #219161 } /* Literal.String.Backtick */
|
||||
body .sc { color: #219161 } /* Literal.String.Char */
|
||||
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
|
||||
body .s2 { color: #219161 } /* Literal.String.Double */
|
||||
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
body .sh { color: #219161 } /* Literal.String.Heredoc */
|
||||
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
body .sx { color: #954121 } /* Literal.String.Other */
|
||||
body .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
body .s1 { color: #219161 } /* Literal.String.Single */
|
||||
body .ss { color: #19469D } /* Literal.String.Symbol */
|
||||
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
|
||||
body .vc { color: #19469D } /* Name.Variable.Class */
|
||||
body .vg { color: #19469D } /* Name.Variable.Global */
|
||||
body .vi { color: #19469D } /* Name.Variable.Instance */
|
||||
body .il { color: #666666 } /* Literal.Number.Integer.Long */
|
17
Libraries/burry.js/tests/index.html
Normal file
17
Libraries/burry.js/tests/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal">
|
||||
<head>
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="./vendor/jasmine/jasmine.css"/>
|
||||
<script src="./vendor/jquery.js"></script>
|
||||
<script src="../burry.js"></script>
|
||||
<script src="./vendor/jasmine/jasmine.js"></script>
|
||||
<script src="./vendor/jasmine/jasmine-html.js"></script>
|
||||
<script src="./specs/burry_spec.js"></script>
|
||||
<script type="text/javascript" src="./index.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
14
Libraries/burry.js/tests/index.js
Normal file
14
Libraries/burry.js/tests/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*globals jasmine:false */
|
||||
|
||||
(function ($) {
|
||||
$(function () {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
jasmineEnv.execute();
|
||||
});
|
||||
})(this.jQuery);
|
244
Libraries/burry.js/tests/specs/burry_spec.js
Normal file
244
Libraries/burry.js/tests/specs/burry_spec.js
Normal file
|
@ -0,0 +1,244 @@
|
|||
(function (Burry) {
|
||||
|
||||
describe('burry.js Storage', function () {
|
||||
|
||||
afterEach(function () {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
describe('Static methods', function () {
|
||||
|
||||
it('returns the stores that have been created', function () {
|
||||
var burryfoo, burrybar;
|
||||
burryfoo = new Burry.Store('foo');
|
||||
burrybar = new Burry.Store('bar');
|
||||
burrybar2 = new Burry.Store('bar');
|
||||
expect(Burry.stores()).toEqual(['', 'foo', 'bar']);
|
||||
});
|
||||
|
||||
it('calculates time elapsed since epoch in minutues', function () {
|
||||
var datea = new Date(10 * 60 * 1000);
|
||||
spyOn(window, 'Date').andReturn(datea);
|
||||
expect(Burry._mEpoch()).toEqual(10);
|
||||
});
|
||||
|
||||
it('supports localStorage', function () {
|
||||
expect(Burry.isSupported()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('flushes expired key/values from all stores', function () {
|
||||
burryfoo = new Burry.Store('foo');
|
||||
burrybar = new Burry.Store('bar');
|
||||
burryfoo.set('expired1', {foo: 'bar'}, -1);
|
||||
burryfoo.set('expired2', {foo: 'bar'}, -2);
|
||||
burryfoo.set('not-expired', {foo: 'bar'}, 10);
|
||||
burrybar.set('expired1', {foo: 'bar'}, -1);
|
||||
burrybar.set('expired2', {foo: 'bar'}, -2);
|
||||
burrybar.set('not-expired', {foo: 'bar'}, 10);
|
||||
Burry.flushExpired();
|
||||
expect(localStorage.getItem(burryfoo._internalKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burryfoo._expirationKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burryfoo._internalKey('expired2'))).toBeNull();
|
||||
expect(localStorage.getItem(burryfoo._expirationKey('expired2'))).toBeNull();
|
||||
expect(burryfoo.get('not-expired')).toBeDefined();
|
||||
expect(localStorage.getItem(burrybar._internalKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burrybar._expirationKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burrybar._internalKey('expired2'))).toBeNull();
|
||||
expect(localStorage.getItem(burrybar._expirationKey('expired2'))).toBeNull();
|
||||
expect(burrybar.get('not-expired')).toBeDefined();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Instance methods', function () {
|
||||
|
||||
var burry;
|
||||
|
||||
beforeEach(function () {
|
||||
burry = new Burry.Store('');
|
||||
});
|
||||
|
||||
it('allows to set a default ttl', function () {
|
||||
burry = new Burry.Store('', 10);
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
expect(localStorage.getItem('akey-_burry_')).toEqual('{"foo":"bar"}');
|
||||
expect(parseInt(localStorage.getItem('akey-_burry_exp_'), 10)).toEqual(Burry._mEpoch() + 10);
|
||||
});
|
||||
|
||||
it('calculates the key used internally', function () {
|
||||
expect(burry._internalKey('akey')).toEqual('akey-_burry_');
|
||||
});
|
||||
|
||||
it('calculates the expiration key used internally', function () {
|
||||
expect(burry._expirationKey(12345)).toEqual('12345-_burry_exp_');
|
||||
});
|
||||
|
||||
it('decides whether a key is a "burry" key', function () {
|
||||
expect(burry._isInternalKey('foo-_burry_')).toEqual('foo');
|
||||
expect(burry._isInternalKey('foo-_burry_bar')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('decides whether a key is a "burry" expiration key', function () {
|
||||
expect(burry._isExpirationKey('foo-_burry_exp_')).toEqual('foo');
|
||||
expect(burry._isExpirationKey('foo-_burry_exp_bar')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('applies correctly the namespace on the keys on construction', function () {
|
||||
var nsburry = new Burry.Store('testing');
|
||||
expect(nsburry._isInternalKey('foo-_burry_testing')).toEqual('foo');
|
||||
expect(nsburry._isInternalKey('foo-_burry_')).toBeFalsy();
|
||||
expect(nsburry._isExpirationKey('foo-_burry_exp_testing')).toEqual('foo');
|
||||
expect(nsburry._isExpirationKey('foo-_burry_exp_')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('stores a key/value to localStorage', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
expect(localStorage.getItem('akey-_burry_')).toEqual('{"foo":"bar"}');
|
||||
});
|
||||
|
||||
it('stores a key/value to localStorage with an expiration time', function () {
|
||||
burry.set('akey', {foo: 'bar'}, 10);
|
||||
expect(localStorage.getItem('akey-_burry_')).toEqual('{"foo":"bar"}');
|
||||
expect(parseInt(localStorage.getItem('akey-_burry_exp_'), 10)).toEqual(Burry._mEpoch() + 10);
|
||||
});
|
||||
|
||||
it('returns the value from a stored key', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
expect(burry.get('akey')).toEqual({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('returns undefined for a non-existing key', function () {
|
||||
expect(burry.get('akey')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns undefined for an expired key, and removes it from localStorage', function () {
|
||||
burry.set('akey', {foo: 'bar'}, -1);
|
||||
expect(localStorage.getItem('akey-_burry_')).toEqual('{"foo":"bar"}');
|
||||
expect(parseInt(localStorage.getItem('akey-_burry_exp_'), 10)).toEqual(Burry._mEpoch() - 1);
|
||||
expect(burry.get('akey')).toBeUndefined();
|
||||
expect(localStorage.getItem('akey-_burry_')).toBeNull();
|
||||
expect(localStorage.getItem('akey-_burry_exp_')).toBeNull();
|
||||
expect(burry.get('akey')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('adds a key/value when the key does not already exist or has expired', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
burry.add('akey', {bar: 'foo'});
|
||||
expect(burry.get('akey')).toEqual({foo: 'bar'});
|
||||
burry.add('otherkey', {foo: 'bar'});
|
||||
expect(burry.get('otherkey')).toEqual({foo: 'bar'});
|
||||
burry.set('akey', {foo: 'bar'}, -10);
|
||||
burry.add('akey', {bar: 'foo'});
|
||||
expect(burry.get('akey')).toEqual({bar: 'foo'});
|
||||
});
|
||||
|
||||
it('replaces a key/value only when the key already exists and has not expired', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
burry.replace('akey', {bar: 'foo'});
|
||||
expect(burry.get('akey')).toEqual({bar: 'foo'});
|
||||
burry.replace('otherkey', {foo: 'bar'});
|
||||
expect(burry.get('otherkey')).not.toBeDefined();
|
||||
burry.set('akey', {foo: 'bar'}, -10);
|
||||
burry.replace('akey', {bar: 'foo'});
|
||||
expect(burry.get('akey')).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('removes a key/value', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
burry.remove('akey');
|
||||
expect(burry.get('akey')).toBeUndefined();
|
||||
expect(localStorage.getItem('akey-_burry_')).toBeNull();
|
||||
expect(localStorage.getItem('akey-_burry_exp_')).toBeNull();
|
||||
});
|
||||
|
||||
it('increments a counter', function () {
|
||||
burry.incr('counter');
|
||||
expect(burry.get('counter')).toEqual(1);
|
||||
burry.set('counter', 0);
|
||||
burry.incr('counter');
|
||||
burry.incr('counter');
|
||||
expect(burry.get('counter')).toEqual(2);
|
||||
});
|
||||
|
||||
it('decrements a counter', function () {
|
||||
burry.decr('counter');
|
||||
expect(burry.get('counter')).toEqual(-1);
|
||||
burry.set('counter', 0);
|
||||
burry.decr('counter');
|
||||
burry.decr('counter');
|
||||
expect(burry.get('counter')).toEqual(-2);
|
||||
});
|
||||
|
||||
it('determines if an item has expired', function () {
|
||||
burry.set('akey', {foo: 'bar'});
|
||||
expect(burry.hasExpired('akey')).toBeFalsy();
|
||||
burry.set('akey', {foo: 'bar'}, 10);
|
||||
expect(burry.hasExpired('akey')).toBeFalsy();
|
||||
burry.set('akey', {foo: 'bar'}, -10);
|
||||
expect(burry.hasExpired('akey')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns all cache keys', function () {
|
||||
var keys;
|
||||
burry.set('expirable1', {foo: 'bar'}, 10);
|
||||
burry.set('expirable2', {foo: 'bar'}, -20);
|
||||
burry.set('non-expirable', {foo: 'bar'});
|
||||
expect(burry.keys().indexOf('expirable1')).not.toEqual(-1);
|
||||
expect(burry.keys().indexOf('expirable2')).not.toEqual(-1);
|
||||
expect(burry.keys().indexOf('non-expirable')).not.toEqual(-1);
|
||||
|
||||
});
|
||||
|
||||
it('returns all expirable keys', function () {
|
||||
var expirable, fakedate = new Date(0);
|
||||
spyOn(window, 'Date').andReturn(fakedate);
|
||||
burry.set('expirable1', {foo: 'bar'}, 10);
|
||||
burry.set('expirable2', {foo: 'bar'}, 20);
|
||||
burry.set('non-expirable', {foo: 'bar'});
|
||||
expect(burry.expirableKeys()).toEqual({expirable1: 10, expirable2: 20});
|
||||
});
|
||||
|
||||
it('flushes all Burry items', function () {
|
||||
burry.set('expirable2', {foo: 'bar'}, 20);
|
||||
burry.set('non-expirable', {foo: 'bar'});
|
||||
localStorage.setItem('foo', 'bar');
|
||||
burry.flush();
|
||||
expect(localStorage.length).toEqual(2);
|
||||
expect(localStorage.key(0)).toEqual('_burry_stores_');
|
||||
expect(localStorage.key(1)).toEqual('foo');
|
||||
});
|
||||
|
||||
it('flushes expired key/values', function () {
|
||||
burry.set('expired1', {foo: 'bar'}, -1);
|
||||
burry.set('expired2', {foo: 'bar'}, -2);
|
||||
burry.set('not-expired', {foo: 'bar'}, 10);
|
||||
burry.flushExpired();
|
||||
expect(localStorage.getItem(burry._internalKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burry._expirationKey('expired1'))).toBeNull();
|
||||
expect(localStorage.getItem(burry._internalKey('expired2'))).toBeNull();
|
||||
expect(localStorage.getItem(burry._expirationKey('expired2'))).toBeNull();
|
||||
expect(burry.get('not-expired')).toBeDefined();
|
||||
});
|
||||
|
||||
it('removes expired objects when setting a value that does not fit in localStorage', function () {
|
||||
var biggie = Array(1024*1024 + 1).join('0'),
|
||||
key = '';
|
||||
while (true) {
|
||||
try {
|
||||
key += 'key';
|
||||
localStorage.setItem(burry._internalKey(key), JSON.stringify(biggie));
|
||||
localStorage.setItem(burry._expirationKey(key), '0');
|
||||
} catch (e) {
|
||||
// The storage is now full.
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(localStorage.length > 0).toBeTruthy();
|
||||
burry.set('biggie', biggie);
|
||||
expect(localStorage.length).toEqual(2);
|
||||
expect(burry.get('biggie')).toEqual(biggie);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})(this.Burry);
|
20
Libraries/burry.js/tests/vendor/jasmine/MIT.LICENSE
vendored
Normal file
20
Libraries/burry.js/tests/vendor/jasmine/MIT.LICENSE
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2008-2011 Pivotal Labs
|
||||
|
||||
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.
|
616
Libraries/burry.js/tests/vendor/jasmine/jasmine-html.js
vendored
Normal file
616
Libraries/burry.js/tests/vendor/jasmine/jasmine-html.js
vendored
Normal file
|
@ -0,0 +1,616 @@
|
|||
jasmine.HtmlReporterHelpers = {};
|
||||
|
||||
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
|
||||
var results = child.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
|
||||
var parentDiv = this.dom.summary;
|
||||
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
|
||||
var parent = child[parentSuite];
|
||||
|
||||
if (parent) {
|
||||
if (typeof this.views.suites[parent.id] == 'undefined') {
|
||||
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
|
||||
}
|
||||
parentDiv = this.views.suites[parent.id].element;
|
||||
}
|
||||
|
||||
parentDiv.appendChild(childElement);
|
||||
};
|
||||
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
|
||||
for(var fn in jasmine.HtmlReporterHelpers) {
|
||||
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter = function(_doc) {
|
||||
var self = this;
|
||||
var doc = _doc || window.document;
|
||||
|
||||
var reporterView;
|
||||
|
||||
var dom = {};
|
||||
|
||||
// Jasmine Reporter Public Interface
|
||||
self.logRunningSpecs = false;
|
||||
|
||||
self.reportRunnerStarting = function(runner) {
|
||||
var specs = runner.specs() || [];
|
||||
|
||||
if (specs.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReporterDom(runner.env.versionString());
|
||||
doc.body.appendChild(dom.reporter);
|
||||
|
||||
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
|
||||
reporterView.addSpecs(specs, self.specFilter);
|
||||
};
|
||||
|
||||
self.reportRunnerResults = function(runner) {
|
||||
reporterView && reporterView.complete();
|
||||
};
|
||||
|
||||
self.reportSuiteResults = function(suite) {
|
||||
reporterView.suiteComplete(suite);
|
||||
};
|
||||
|
||||
self.reportSpecStarting = function(spec) {
|
||||
if (self.logRunningSpecs) {
|
||||
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
self.reportSpecResults = function(spec) {
|
||||
reporterView.specComplete(spec);
|
||||
};
|
||||
|
||||
self.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.specFilter = function(spec) {
|
||||
if (!focusedSpecName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return spec.getFullName().indexOf(focusedSpecName()) === 0;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function focusedSpecName() {
|
||||
var specName;
|
||||
|
||||
(function memoizeFocusedSpec() {
|
||||
if (specName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var paramMap = [];
|
||||
var params = doc.location.search.substring(1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
specName = paramMap.spec;
|
||||
})();
|
||||
|
||||
return specName;
|
||||
}
|
||||
|
||||
function createReporterDom(version) {
|
||||
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
|
||||
dom.banner = self.createDom('div', { className: 'banner' },
|
||||
self.createDom('span', { className: 'title' }, "Jasmine "),
|
||||
self.createDom('span', { className: 'version' }, version)),
|
||||
|
||||
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
|
||||
dom.alert = self.createDom('div', {className: 'alert'}),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
};
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) {
|
||||
this.startedAt = new Date();
|
||||
this.runningSpecCount = 0;
|
||||
this.completeSpecCount = 0;
|
||||
this.passedCount = 0;
|
||||
this.failedCount = 0;
|
||||
this.skippedCount = 0;
|
||||
|
||||
this.createResultsMenu = function() {
|
||||
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
|
||||
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
|
||||
' | ',
|
||||
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
|
||||
|
||||
this.summaryMenuItem.onclick = function() {
|
||||
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
|
||||
};
|
||||
|
||||
this.detailsMenuItem.onclick = function() {
|
||||
showDetails();
|
||||
};
|
||||
};
|
||||
|
||||
this.addSpecs = function(specs, specFilter) {
|
||||
this.totalSpecCount = specs.length;
|
||||
|
||||
this.views = {
|
||||
specs: {},
|
||||
suites: {}
|
||||
};
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var spec = specs[i];
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
|
||||
if (specFilter(spec)) {
|
||||
this.runningSpecCount++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.specComplete = function(spec) {
|
||||
this.completeSpecCount++;
|
||||
|
||||
if (isUndefined(this.views.specs[spec.id])) {
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
|
||||
}
|
||||
|
||||
var specView = this.views.specs[spec.id];
|
||||
|
||||
switch (specView.status()) {
|
||||
case 'passed':
|
||||
this.passedCount++;
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.failedCount++;
|
||||
break;
|
||||
|
||||
case 'skipped':
|
||||
this.skippedCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
specView.refresh();
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
this.suiteComplete = function(suite) {
|
||||
var suiteView = this.views.suites[suite.id];
|
||||
if (isUndefined(suiteView)) {
|
||||
return;
|
||||
}
|
||||
suiteView.refresh();
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
|
||||
if (isUndefined(this.resultsMenu)) {
|
||||
this.createResultsMenu();
|
||||
}
|
||||
|
||||
// currently running UI
|
||||
if (isUndefined(this.runningAlert)) {
|
||||
this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
|
||||
dom.alert.appendChild(this.runningAlert);
|
||||
}
|
||||
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
|
||||
|
||||
// skipped specs UI
|
||||
if (isUndefined(this.skippedAlert)) {
|
||||
this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
|
||||
}
|
||||
|
||||
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.skippedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.skippedAlert);
|
||||
}
|
||||
|
||||
// passing specs UI
|
||||
if (isUndefined(this.passedAlert)) {
|
||||
this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
|
||||
}
|
||||
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
|
||||
|
||||
// failing specs UI
|
||||
if (isUndefined(this.failedAlert)) {
|
||||
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
|
||||
}
|
||||
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
|
||||
|
||||
if (this.failedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.failedAlert);
|
||||
dom.alert.appendChild(this.resultsMenu);
|
||||
}
|
||||
|
||||
// summary info
|
||||
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
|
||||
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
|
||||
};
|
||||
|
||||
this.complete = function() {
|
||||
dom.alert.removeChild(this.runningAlert);
|
||||
|
||||
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.failedCount === 0) {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
|
||||
} else {
|
||||
showDetails();
|
||||
}
|
||||
|
||||
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function showDetails() {
|
||||
if (dom.reporter.className.search(/showDetails/) === -1) {
|
||||
dom.reporter.className += " showDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefined(obj) {
|
||||
return typeof obj === 'undefined';
|
||||
}
|
||||
|
||||
function isDefined(obj) {
|
||||
return !isUndefined(obj);
|
||||
}
|
||||
|
||||
function specPluralizedFor(count) {
|
||||
var str = count + " spec";
|
||||
if (count > 1) {
|
||||
str += "s"
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
|
||||
|
||||
|
||||
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
|
||||
this.spec = spec;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.symbol = this.createDom('li', { className: 'pending' });
|
||||
this.dom.symbolSummary.appendChild(this.symbol);
|
||||
|
||||
this.summary = this.createDom('div', { className: 'specSummary' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.description)
|
||||
);
|
||||
|
||||
this.detail = this.createDom('div', { className: 'specDetail' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.getFullName())
|
||||
);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.spec);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
|
||||
this.symbol.className = this.status();
|
||||
|
||||
switch (this.status()) {
|
||||
case 'skipped':
|
||||
break;
|
||||
|
||||
case 'passed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
this.appendFailureDetail();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
|
||||
this.summary.className += ' ' + this.status();
|
||||
this.appendToSummary(this.spec, this.summary);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
|
||||
this.detail.className += ' ' + this.status();
|
||||
|
||||
var resultItems = this.spec.results().getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
this.detail.appendChild(messagesDiv);
|
||||
this.dom.details.appendChild(this.detail);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
|
||||
this.suite = suite;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.element = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
|
||||
);
|
||||
|
||||
this.appendToSummary(this.suite, this.element);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.suite);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
|
||||
this.element.className += " " + this.status();
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
|
||||
|
||||
/* @deprecated Use jasmine.HtmlReporter instead
|
||||
*/
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
81
Libraries/burry.js/tests/vendor/jasmine/jasmine.css
vendored
Normal file
81
Libraries/burry.js/tests/vendor/jasmine/jasmine.css
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
|
||||
|
||||
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
#HTMLReporter a { text-decoration: none; }
|
||||
#HTMLReporter a:hover { text-decoration: underline; }
|
||||
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
|
||||
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
|
||||
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#HTMLReporter .version { color: #aaaaaa; }
|
||||
#HTMLReporter .banner { margin-top: 14px; }
|
||||
#HTMLReporter .duration { color: #aaaaaa; float: right; }
|
||||
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
|
||||
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
|
||||
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
|
||||
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
#HTMLReporter .runningAlert { background-color: #666666; }
|
||||
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
|
||||
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
|
||||
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
|
||||
#HTMLReporter .passingAlert { background-color: #a6b779; }
|
||||
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
|
||||
#HTMLReporter .failingAlert { background-color: #cf867e; }
|
||||
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
|
||||
#HTMLReporter .results { margin-top: 14px; }
|
||||
#HTMLReporter #details { display: none; }
|
||||
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .summary { display: none; }
|
||||
#HTMLReporter.showDetails #details { display: block; }
|
||||
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter .summary { margin-top: 14px; }
|
||||
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
|
||||
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
|
||||
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
|
||||
#HTMLReporter .description + .suite { margin-top: 0; }
|
||||
#HTMLReporter .suite { margin-top: 14px; }
|
||||
#HTMLReporter .suite a { color: #333333; }
|
||||
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
|
||||
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
|
||||
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
|
||||
#HTMLReporter .resultMessage span.result { display: block; }
|
||||
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
|
||||
|
||||
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
|
||||
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
|
||||
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
|
||||
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
|
||||
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
|
||||
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
|
||||
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
|
||||
#TrivialReporter .runner.running { background-color: yellow; }
|
||||
#TrivialReporter .options { text-align: right; font-size: .8em; }
|
||||
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
|
||||
#TrivialReporter .suite .suite { margin: 5px; }
|
||||
#TrivialReporter .suite.passed { background-color: #dfd; }
|
||||
#TrivialReporter .suite.failed { background-color: #fdd; }
|
||||
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
|
||||
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
|
||||
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
|
||||
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
|
||||
#TrivialReporter .spec.skipped { background-color: #bbb; }
|
||||
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
|
||||
#TrivialReporter .passed { background-color: #cfc; display: none; }
|
||||
#TrivialReporter .failed { background-color: #fbb; }
|
||||
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
|
||||
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
|
||||
#TrivialReporter .resultMessage .mismatch { color: black; }
|
||||
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
|
||||
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
|
||||
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
|
||||
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
|
2529
Libraries/burry.js/tests/vendor/jasmine/jasmine.js
vendored
Normal file
2529
Libraries/burry.js/tests/vendor/jasmine/jasmine.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Libraries/burry.js/tests/vendor/jasmine/jasmine_favicon.png
vendored
Normal file
BIN
Libraries/burry.js/tests/vendor/jasmine/jasmine_favicon.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 905 B |
9404
Libraries/burry.js/tests/vendor/jquery.js
vendored
Normal file
9404
Libraries/burry.js/tests/vendor/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
251
Libraries/jarnxmpp.core.handlers.js
Normal file
251
Libraries/jarnxmpp.core.handlers.js
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*global $:false, document:false, window:false, portal_url:false,
|
||||
$msg:false, Strophe:false, setTimeout:false, navigator:false, jarn:false, google:false, jarnxmpp:false, jQuery:false, sessionStorage:false, $iq:false, $pres:false, Image:false, */
|
||||
|
||||
(function (jarnxmpp, $, portal_url) {
|
||||
|
||||
portal_url = portal_url || '';
|
||||
|
||||
jarnxmpp.Storage = {
|
||||
storage: null,
|
||||
init: function () {
|
||||
try {
|
||||
if ('sessionStorage' in window && window.sessionStorage !== null && JSON in window && window.JSON !== null) {
|
||||
jarnxmpp.Storage.storage = sessionStorage;
|
||||
if (!('_user_info' in jarnxmpp.Storage.storage)) {
|
||||
jarnxmpp.Storage.set('_user_info', {});
|
||||
}
|
||||
if (!('_vCards' in jarnxmpp.Storage.storage)) {
|
||||
jarnxmpp.Storage.set('_vCards', {});
|
||||
}
|
||||
if (!('_subscriptions' in jarnxmpp.Storage.storage)) {
|
||||
jarnxmpp.Storage.set('_subscriptions', null);
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
|
||||
get: function (key) {
|
||||
if (key in sessionStorage) {
|
||||
return JSON.parse(sessionStorage[key]);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
set: function (key, value) {
|
||||
sessionStorage[key] = JSON.stringify(value);
|
||||
},
|
||||
|
||||
xmppGet: function (key, callback) {
|
||||
var stanza = $iq({type: 'get'})
|
||||
.c('query', {xmlns: 'jabber:iq:private'})
|
||||
.c('jarnxmpp', {xmlns: 'http://jarn.com/ns/jarnxmpp:prefs:' + key})
|
||||
.tree();
|
||||
jarnxmpp.connection.sendIQ(stanza, function success(result) {
|
||||
callback($('jarnxmpp ' + 'value', result).first().text());
|
||||
});
|
||||
},
|
||||
|
||||
xmppSet: function (key, value) {
|
||||
var stanza = $iq({type: 'set'})
|
||||
.c('query', {xmlns: 'jabber:iq:private'})
|
||||
.c('jarnxmpp', {xmlns: 'http://jarn.com/ns/jarnxmpp:prefs:' + key})
|
||||
.c('value', value)
|
||||
.tree();
|
||||
jarnxmpp.connection.sendIQ(stanza);
|
||||
}
|
||||
};
|
||||
|
||||
jarnxmpp.Storage.init();
|
||||
|
||||
jarnxmpp.Presence = {
|
||||
online: {},
|
||||
_user_info: {},
|
||||
|
||||
onlineCount: function () {
|
||||
var me = Strophe.getNodeFromJid(jarnxmpp.connection.jid),
|
||||
counter = 0,
|
||||
user;
|
||||
for (user in jarnxmpp.Presence.online) {
|
||||
if ((jarnxmpp.Presence.online.hasOwnProperty(user)) && user !== me) {
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
},
|
||||
|
||||
getUserInfo: function (user_id, callback) {
|
||||
// User info on browsers without storage
|
||||
if (jarnxmpp.Storage.storage === null) {
|
||||
if (user_id in jarnxmpp.Presence._user_info) {
|
||||
callback(jarnxmpp.Presence._user_info[user_id]);
|
||||
} else {
|
||||
$.getJSON(portal_url + "/xmpp-userinfo?user_id=" + user_id, function (data) {
|
||||
jarnxmpp.Presence._user_info[user_id] = data;
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
var _user_info = jarnxmpp.Storage.get('_user_info');
|
||||
if (user_id in _user_info) {
|
||||
callback(_user_info[user_id]);
|
||||
} else {
|
||||
$.getJSON(portal_url + "/xmpp-userinfo?user_id=" + user_id, function (data) {
|
||||
_user_info[user_id] = data;
|
||||
jarnxmpp.Storage.set('_user_info', _user_info);
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jarnxmpp.vCard = {
|
||||
|
||||
_vCards: {},
|
||||
|
||||
_getVCard: function (jid, callback) {
|
||||
var stanza =
|
||||
$iq({type: 'get', to: jid})
|
||||
.c('vCard', {xmlns: 'vcard-temp'}).tree();
|
||||
jarnxmpp.connection.sendIQ(stanza, function (data) {
|
||||
var result = {};
|
||||
$('vCard[xmlns="vcard-temp"]', data).children().each(function (idx, element) {
|
||||
result[element.nodeName] = element.textContent;
|
||||
});
|
||||
if (typeof (callback) !== 'undefined') {
|
||||
callback(result);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getVCard: function (jid, callback) {
|
||||
jid = Strophe.getBareJidFromJid(jid);
|
||||
if (jarnxmpp.Storage.storage === null) {
|
||||
if (jid in jarnxmpp.vCard._vCards) {
|
||||
callback(jarnxmpp.vCard._vCards[jid]);
|
||||
} else {
|
||||
jarnxmpp.vCard._getVCard(jid, function (result) {
|
||||
jarnxmpp.vCard._vCards[jid] = result;
|
||||
callback(result);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
var _vCards = jarnxmpp.Storage.get('_vCards');
|
||||
if (jid in _vCards) {
|
||||
callback(_vCards[jid]);
|
||||
} else {
|
||||
jarnxmpp.vCard._getVCard(jid, function (result) {
|
||||
_vCards[jid] = result;
|
||||
jarnxmpp.Storage.set('_vCards', _vCards);
|
||||
callback(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setVCard: function (params, photoUrl) {
|
||||
var key,
|
||||
vCard = Strophe.xmlElement('vCard', [['xmlns', 'vcard-temp'], ['version', '2.0']]);
|
||||
for (key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
vCard.appendChild(Strophe.xmlElement(key, [], params[key]));
|
||||
}
|
||||
}
|
||||
var send = function () {
|
||||
var stanza = $iq({type: 'set'}).cnode(vCard).tree();
|
||||
jarnxmpp.connection.sendIQ(stanza);
|
||||
};
|
||||
if (typeof (photoUrl) === 'undefined') {
|
||||
send();
|
||||
} else {
|
||||
jarnxmpp.vCard.getBase64Image(photoUrl, function (base64img) {
|
||||
base64img = base64img.replace(/^data:image\/png;base64,/, "");
|
||||
var photo = Strophe.xmlElement('PHOTO');
|
||||
photo.appendChild(Strophe.xmlElement('TYPE', [], 'image/png'));
|
||||
photo.appendChild(Strophe.xmlElement('BINVAL', [], base64img));
|
||||
vCard.appendChild(photo);
|
||||
send();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getBase64Image: function (url, callback) {
|
||||
// Create the element, then draw it on a canvas to get the base64 data.
|
||||
var img = new Image();
|
||||
$(img).load(function () {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
callback(canvas.toDataURL('image/png'));
|
||||
}).attr('src', url);
|
||||
}
|
||||
};
|
||||
|
||||
jarnxmpp.onConnect = function (status) {
|
||||
if ((status === Strophe.Status.ATTACHED) || (status === Strophe.Status.CONNECTED)) {
|
||||
$(window).bind('beforeunload', function () {
|
||||
$(document).trigger('jarnxmpp.disconnecting');
|
||||
var presence = $pres({type: 'unavailable'});
|
||||
jarnxmpp.connection.send(presence);
|
||||
jarnxmpp.connection.disconnect();
|
||||
jarnxmpp.connection.flush();
|
||||
});
|
||||
$(document).trigger('jarnxmpp.connected');
|
||||
} else if (status === Strophe.Status.DISCONNECTED) {
|
||||
$(document).trigger('jarnxmpp.disconnected');
|
||||
}
|
||||
};
|
||||
|
||||
jarnxmpp.rawInput = function (data) {
|
||||
var event = jQuery.Event('jarnxmpp.dataReceived');
|
||||
event.text = data;
|
||||
$(document).trigger(event);
|
||||
};
|
||||
|
||||
jarnxmpp.rawOutput = function (data) {
|
||||
var event = jQuery.Event('jarnxmpp.dataSent');
|
||||
event.text = data;
|
||||
$(document).trigger(event);
|
||||
};
|
||||
|
||||
$(document).bind('jarnxmpp.connected', function () {
|
||||
// Logging
|
||||
jarnxmpp.connection.rawInput = jarnxmpp.rawInput;
|
||||
jarnxmpp.connection.rawOutput = jarnxmpp.rawOutput;
|
||||
});
|
||||
|
||||
$(document).bind('jarnxmpp.disconnecting', function () {
|
||||
if (jarnxmpp.Storage.storage !== null) {
|
||||
jarnxmpp.Storage.set('online-count', jarnxmpp.Presence.onlineCount());
|
||||
}
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
var resource = jarnxmpp.Storage.get('xmppresource');
|
||||
if (resource) {
|
||||
data = {'resource': resource};
|
||||
} else {
|
||||
data = {};
|
||||
}
|
||||
$.ajax({
|
||||
'url':portal_url + '/@@xmpp-loader',
|
||||
'dataType': 'json',
|
||||
'data': data,
|
||||
'success': function (data) {
|
||||
if (!(('rid' in data) && ('sid' in data) && ('BOSH_SERVICE' in data))) {
|
||||
return;
|
||||
}
|
||||
if (!resource) {
|
||||
jarnxmpp.Storage.set('xmppresource', Strophe.getResourceFromJid(data.jid));
|
||||
}
|
||||
jarnxmpp.BOSH_SERVICE = data.BOSH_SERVICE;
|
||||
jarnxmpp.jid = data.jid;
|
||||
jarnxmpp.connection = new Strophe.Connection(jarnxmpp.BOSH_SERVICE);
|
||||
jarnxmpp.connection.attach(jarnxmpp.jid, data.sid, data.rid, jarnxmpp.onConnect);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(window.jarnxmpp = window.jarnxmpp || {}, jQuery, portal_url);
|
278
Libraries/jquery-GPL-LICENSE.txt
Normal file
278
Libraries/jquery-GPL-LICENSE.txt
Normal file
|
@ -0,0 +1,278 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
20
Libraries/jquery-MIT-LICENSE.txt
Normal file
20
Libraries/jquery-MIT-LICENSE.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2009 John Resig, http://jquery.com/
|
||||
|
||||
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.
|
11421
Libraries/require-jquery.js
Normal file
11421
Libraries/require-jquery.js
Normal file
File diff suppressed because it is too large
Load Diff
42
Libraries/sjcl.js
Normal file
42
Libraries/sjcl.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
|
||||
if(typeof module!="undefined"&&module.exports)module.exports=sjcl;
|
||||
sjcl.cipher.aes=function(a){this.h[0][0][0]||this.z();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
|
||||
g[3][f[c&255]]}};
|
||||
sjcl.cipher.aes.prototype={encrypt:function(a){return this.I(a,0)},decrypt:function(a){return this.I(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],z:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e=
|
||||
0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},I:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16&
|
||||
255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}};
|
||||
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;
|
||||
if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=
|
||||
a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
|
||||
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
|
||||
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
|
||||
sjcl.codec.base64={F:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,f=sjcl.codec.base64.F,g=0,h=sjcl.bitArray.bitLength(a);if(c)f=f.substr(0,62)+"-_";for(c=0;d.length*6<h;){d+=f.charAt((g^a[c]>>>e)>>>26);if(e<6){g=a[c]<<6-e;e+=26;c++}else{g<<=6;e-=6}}for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d=0,e=sjcl.codec.base64.F,f=0,g;if(b)e=e.substr(0,62)+"-_";for(b=0;b<a.length;b++){g=e.indexOf(a.charAt(b));
|
||||
if(g<0)throw new sjcl.exception.invalid("this isn't base64!");if(d>26){d-=26;c.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&c.push(sjcl.bitArray.partial(d&56,f,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.a[0]||this.z();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
|
||||
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.D(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/
|
||||
4294967296));for(b.push(this.e|0);b.length;)this.D(b.splice(0,16));this.reset();return c},N:[],a:[],z:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},D:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
|
||||
b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}};
|
||||
sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.H(a,b,c,d,e,f);g=sjcl.mode.ccm.J(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b,
|
||||
h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.J(a,i,c,k,e,b);a=sjcl.mode.ccm.H(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},H:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
|
||||
f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4).concat([0,0,0])))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4).concat([0,0,0])));return h.clamp(f,e*8)},J:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,
|
||||
f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}};
|
||||
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.B,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l.concat([0,0,0]),g),b);j=k(j,k(l.concat([0,0,0]),g));j=a.encrypt(k(j,k(c,h(c))));
|
||||
if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a,d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.B,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),
|
||||
m).concat([0,0,0]));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k=i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.B,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0,0,
|
||||
0,0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},B:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};
|
||||
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()};
|
||||
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k};
|
||||
sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notReady("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.w();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady(),i=0;d=this.G[c];if(d===undefined)d=this.G[c]=this.R++;if(g===undefined)g=this.q[c]=
|
||||
0;this.q[c]=(this.q[c]+1)%this.b.length;switch(typeof a){case "number":if(b===undefined)b=1;this.b[g].update([d,this.u++,1,b,f,1,a|0]);break;case "object":c=Object.prototype.toString.call(a);if(c==="[object Uint32Array]"){e=[];for(c=0;c<a.length;c++)e.push(a[c]);a=e}else{if(c!=="[object Array]")i=1;for(c=0;c<a.length&&!i;c++)if(typeof a[c]!="number")i=1}if(!i){if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.u++,2,b,f,a.length].concat(a))}break;case "string":if(b===
|
||||
undefined)b=a.length;this.b[g].update([d,this.u++,3,b,f,a.length]);this.b[g].update(a);break;default:i=1}if(i)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.C[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=
|
||||
this.C[a?a:this.t];return this.g>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload",this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",
|
||||
this.o,false);window.removeEventListener("mousemove",this.p,false)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;a=this.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],A:0,q:{},u:0,G:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,
|
||||
t:6,m:false,r:{progress:{},seeded:{}},Q:0,C:[0,48,64,96,128,192,0x100,384,512,768,1024],w:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.w().concat(this.w());this.s=new sjcl.cipher.aes(this.a)},T:function(a){this.a=sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=
|
||||
0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.A&1<<d)break}if(this.A>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.A++;this.T(b)},p:function(a){sjcl.random.addEntropy([a.x||a.clientX||a.offsetX||0,a.y||a.clientY||a.offsetY||0],2,"mouse")},o:function(){sjcl.random.addEntropy((new Date).valueOf(),2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];
|
||||
var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};try{var s=new Uint32Array(32);crypto.getRandomValues(s);sjcl.random.addEntropy(s,1024,"crypto['getRandomValues']")}catch(t){}
|
||||
sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.c(f,c);c=f.adata;if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<
|
||||
2||f.iv.length>4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){g=sjcl.misc.cachedPbkdf2(a,f);a=g.key.slice(0,f.ks/32);f.salt=g.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);if(typeof c==="string")c=sjcl.codec.utf8String.toBits(c);g=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(g,b,f.iv,c,f.ts);return e.encode(f)},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),e.decode(b)),
|
||||
c,true);var f;c=b.adata;if(typeof b.salt==="string")b.salt=sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){f=sjcl.misc.cachedPbkdf2(a,b);a=f.key.slice(0,b.ks/32);b.salt=f.salt}if(typeof c===
|
||||
"string")c=sjcl.codec.utf8String.toBits(c);f=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(f,b.ct,b.iv,c,b.ts);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+'"'+b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+
|
||||
sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[2]]=
|
||||
d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4])}return b},c:function(a,b,c){if(a===undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},W:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},V:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=
|
||||
a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};
|
4201
Libraries/strophe.js
Normal file
4201
Libraries/strophe.js
Normal file
File diff suppressed because it is too large
Load Diff
955
Libraries/strophe.muc.js
Normal file
955
Libraries/strophe.muc.js
Normal file
|
@ -0,0 +1,955 @@
|
|||
|
||||
/*
|
||||
*Plugin to implement the MUC extension.
|
||||
http://xmpp.org/extensions/xep-0045.html
|
||||
*Previous Author:
|
||||
Nathan Zorn <nathan.zorn@gmail.com>
|
||||
*Complete CoffeeScript rewrite:
|
||||
Andreas Guth <guth@dbis.rwth-aachen.de>
|
||||
*/
|
||||
// AMD/global registrations
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([
|
||||
"Libraries/strophe"
|
||||
], function () {
|
||||
return factory(jQuery, console);
|
||||
}
|
||||
);
|
||||
}
|
||||
}(this, function ($, console) {
|
||||
|
||||
(function() {
|
||||
var Occupant, RoomConfig, XmppRoom,
|
||||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
|
||||
Strophe.addConnectionPlugin('muc', {
|
||||
_connection: null,
|
||||
rooms: [],
|
||||
/*Function
|
||||
Initialize the MUC plugin. Sets the correct connection object and
|
||||
extends the namesace.
|
||||
*/
|
||||
init: function(conn) {
|
||||
this._connection = conn;
|
||||
this._muc_handler = null;
|
||||
Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC + "#owner");
|
||||
Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
|
||||
Strophe.addNamespace('MUC_USER', Strophe.NS.MUC + "#user");
|
||||
return Strophe.addNamespace('MUC_ROOMCONF', Strophe.NS.MUC + "#roomconfig");
|
||||
},
|
||||
/*Function
|
||||
Join a multi-user chat room
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room to join.
|
||||
(String) nick - The nickname to use in the chat room. Optional
|
||||
(Function) msg_handler_cb - The function call to handle messages from the
|
||||
specified chat room.
|
||||
(Function) pres_handler_cb - The function call back to handle presence
|
||||
in the chat room.
|
||||
(String) password - The optional password to use. (password protected
|
||||
rooms only)
|
||||
*/
|
||||
join: function(room, nick, msg_handler_cb, pres_handler_cb, roster_cb, password) {
|
||||
var msg, room_nick, _base,
|
||||
_this = this;
|
||||
room_nick = this.test_append_nick(room, nick);
|
||||
msg = $pres({
|
||||
from: this._connection.jid,
|
||||
to: room_nick
|
||||
}).c("x", {
|
||||
xmlns: Strophe.NS.MUC
|
||||
});
|
||||
if (password != null) {
|
||||
msg.cnode(Strophe.xmlElement("password", [], password));
|
||||
}
|
||||
if (this._muc_handler == null) {
|
||||
this._muc_handler = this._connection.addHandler(function(stanza) {
|
||||
var from, handler, handlers, id, roomname, x, xmlns, xquery, _i, _len;
|
||||
from = stanza.getAttribute('from');
|
||||
roomname = from.split("/")[0];
|
||||
if (!_this.rooms[roomname]) return true;
|
||||
room = _this.rooms[roomname];
|
||||
handlers = {};
|
||||
if (stanza.nodeName === "message") {
|
||||
handlers = room._message_handlers;
|
||||
} else if (stanza.nodeName === "presence") {
|
||||
xquery = stanza.getElementsByTagName("x");
|
||||
if (xquery.length > 0) {
|
||||
for (_i = 0, _len = xquery.length; _i < _len; _i++) {
|
||||
x = xquery[_i];
|
||||
xmlns = x.getAttribute("xmlns");
|
||||
if (xmlns && xmlns.match(Strophe.NS.MUC)) {
|
||||
handlers = room._presence_handlers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (id in handlers) {
|
||||
handler = handlers[id];
|
||||
if (!handler(stanza, room)) delete handlers[id];
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
if ((_base = this.rooms)[room] == null) {
|
||||
_base[room] = new XmppRoom(this, room, nick, password);
|
||||
}
|
||||
if (pres_handler_cb) {
|
||||
this.rooms[room].addHandler('presence', pres_handler_cb);
|
||||
}
|
||||
if (msg_handler_cb) this.rooms[room].addHandler('message', msg_handler_cb);
|
||||
if (roster_cb) this.rooms[room].addHandler('roster', roster_cb);
|
||||
return this._connection.send(msg);
|
||||
},
|
||||
/*Function
|
||||
Leave a multi-user chat room
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room to leave.
|
||||
(String) nick - The nick name used in the room.
|
||||
(Function) handler_cb - Optional function to handle the successful leave.
|
||||
(String) exit_msg - optional exit message.
|
||||
Returns:
|
||||
iqid - The unique id for the room leave.
|
||||
*/
|
||||
leave: function(room, nick, handler_cb, exit_msg) {
|
||||
var presence, presenceid, room_nick;
|
||||
delete this.rooms[room];
|
||||
if (this.rooms.length === 0) {
|
||||
this._connection.deleteHandler(this._muc_handler);
|
||||
this._muc_handler = null;
|
||||
}
|
||||
room_nick = this.test_append_nick(room, nick);
|
||||
presenceid = this._connection.getUniqueId();
|
||||
presence = $pres({
|
||||
type: "unavailable",
|
||||
id: presenceid,
|
||||
from: this._connection.jid,
|
||||
to: room_nick
|
||||
});
|
||||
if (exit_msg != null) presence.c("status", exit_msg);
|
||||
if (handler_cb != null) {
|
||||
this._connection.addHandler(handler_cb, null, "presence", null, presenceid);
|
||||
}
|
||||
this._connection.send(presence);
|
||||
return presenceid;
|
||||
},
|
||||
/*Function
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) nick - The nick name used in the chat room.
|
||||
(String) message - The plaintext message to send to the room.
|
||||
(String) html_message - The message to send to the room with html markup.
|
||||
(String) type - "groupchat" for group chat messages o
|
||||
"chat" for private chat messages
|
||||
Returns:
|
||||
msgiq - the unique id used to send the message
|
||||
*/
|
||||
message: function(room, nick, message, html_message, type) {
|
||||
var msg, msgid, parent, room_nick;
|
||||
room_nick = this.test_append_nick(room, nick);
|
||||
type = type || (nick != null ? "chat" : "groupchat");
|
||||
msgid = this._connection.getUniqueId();
|
||||
msg = $msg({
|
||||
to: room_nick,
|
||||
from: this._connection.jid,
|
||||
type: type,
|
||||
id: msgid
|
||||
}).c("body", {
|
||||
xmlns: Strophe.NS.CLIENT
|
||||
}).t(message);
|
||||
msg.up();
|
||||
if (html_message != null) {
|
||||
msg.c("html", {
|
||||
xmlns: Strophe.NS.XHTML_IM
|
||||
}).c("body", {
|
||||
xmlns: Strophe.NS.XHTML
|
||||
}).h(html_message);
|
||||
if (msg.node.childNodes.length === 0) {
|
||||
parent = msg.node.parentNode;
|
||||
msg.up().up();
|
||||
msg.node.removeChild(parent);
|
||||
} else {
|
||||
msg.up().up();
|
||||
}
|
||||
}
|
||||
msg.c("x", {
|
||||
xmlns: "jabber:x:event"
|
||||
}).c("composing");
|
||||
this._connection.send(msg);
|
||||
return msgid;
|
||||
},
|
||||
/*Function
|
||||
Convenience Function to send a Message to all Occupants
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) message - The plaintext message to send to the room.
|
||||
(String) html_message - The message to send to the room with html markup.
|
||||
Returns:
|
||||
msgiq - the unique id used to send the message
|
||||
*/
|
||||
groupchat: function(room, message, html_message) {
|
||||
return this.message(room, null, message, html_message);
|
||||
},
|
||||
/*Function
|
||||
Send a mediated invitation.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) receiver - The invitation's receiver.
|
||||
(String) reason - Optional reason for joining the room.
|
||||
Returns:
|
||||
msgiq - the unique id used to send the invitation
|
||||
*/
|
||||
invite: function(room, receiver, reason) {
|
||||
var invitation, msgid;
|
||||
msgid = this._connection.getUniqueId();
|
||||
invitation = $msg({
|
||||
from: this._connection.jid,
|
||||
to: room,
|
||||
id: msgid
|
||||
}).c('x', {
|
||||
xmlns: Strophe.NS.MUC_USER
|
||||
}).c('invite', {
|
||||
to: receiver
|
||||
});
|
||||
if (reason != null) invitation.c('reason', reason);
|
||||
this._connection.send(invitation);
|
||||
return msgid;
|
||||
},
|
||||
/*Function
|
||||
Send a direct invitation.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) receiver - The invitation's receiver.
|
||||
(String) reason - Optional reason for joining the room.
|
||||
(String) password - Optional password for the room.
|
||||
Returns:
|
||||
msgiq - the unique id used to send the invitation
|
||||
*/
|
||||
directInvite: function(room, receiver, reason, password) {
|
||||
var attrs, invitation, msgid;
|
||||
msgid = this._connection.getUniqueId();
|
||||
attrs = {
|
||||
xmlns: 'jabber:x:conference',
|
||||
jid: room
|
||||
};
|
||||
if (reason != null) attrs.reason = reason;
|
||||
if (password != null) attrs.password = password;
|
||||
invitation = $msg({
|
||||
from: this._connection.jid,
|
||||
to: receiver,
|
||||
id: msgid
|
||||
}).c('x', attrs);
|
||||
this._connection.send(invitation);
|
||||
return msgid;
|
||||
},
|
||||
/*Function
|
||||
Queries a room for a list of occupants
|
||||
(String) room - The multi-user chat room name.
|
||||
(Function) success_cb - Optional function to handle the info.
|
||||
(Function) error_cb - Optional function to handle an error.
|
||||
Returns:
|
||||
id - the unique id used to send the info request
|
||||
*/
|
||||
queryOccupants: function(room, success_cb, error_cb) {
|
||||
var attrs, info;
|
||||
attrs = {
|
||||
xmlns: Strophe.NS.DISCO_ITEMS
|
||||
};
|
||||
info = $iq({
|
||||
from: this._connection.jid,
|
||||
to: room,
|
||||
type: 'get'
|
||||
}).c('query', attrs);
|
||||
return this._connection.sendIQ(info, success_cb, error_cb);
|
||||
},
|
||||
/*Function
|
||||
Start a room configuration.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(Function) handler_cb - Optional function to handle the config form.
|
||||
Returns:
|
||||
id - the unique id used to send the configuration request
|
||||
*/
|
||||
configure: function(room, handler_cb) {
|
||||
var config, id, stanza;
|
||||
config = $iq({
|
||||
to: room,
|
||||
type: "get"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_OWNER
|
||||
});
|
||||
stanza = config.tree();
|
||||
id = this._connection.sendIQ(stanza);
|
||||
if (handler_cb != null) {
|
||||
this._connection.addHandler(function(stanza) {
|
||||
handler_cb(stanza);
|
||||
return false;
|
||||
}, Strophe.NS.MUC_OWNER, "iq", null, id);
|
||||
}
|
||||
return id;
|
||||
},
|
||||
/*Function
|
||||
Cancel the room configuration
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
Returns:
|
||||
id - the unique id used to cancel the configuration.
|
||||
*/
|
||||
cancelConfigure: function(room) {
|
||||
var config, stanza;
|
||||
config = $iq({
|
||||
to: room,
|
||||
type: "set"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_OWNER
|
||||
}).c("x", {
|
||||
xmlns: "jabber:x:data",
|
||||
type: "cancel"
|
||||
});
|
||||
stanza = config.tree();
|
||||
return this._connection.sendIQ(stanza);
|
||||
},
|
||||
/*Function
|
||||
Save a room configuration.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(Array) configarray - an array of form elements used to configure the room.
|
||||
Returns:
|
||||
id - the unique id used to save the configuration.
|
||||
*/
|
||||
saveConfiguration: function(room, configarray) {
|
||||
var conf, config, stanza, _i, _len;
|
||||
config = $iq({
|
||||
to: room,
|
||||
type: "set"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_OWNER
|
||||
}).c("x", {
|
||||
xmlns: "jabber:x:data",
|
||||
type: "submit"
|
||||
});
|
||||
for (_i = 0, _len = configarray.length; _i < _len; _i++) {
|
||||
conf = configarray[_i];
|
||||
config.cnode(conf).up();
|
||||
}
|
||||
stanza = config.tree();
|
||||
return this._connection.sendIQ(stanza);
|
||||
},
|
||||
/*Function
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
Returns:
|
||||
id - the unique id used to create the chat room.
|
||||
*/
|
||||
createInstantRoom: function(room) {
|
||||
var roomiq;
|
||||
roomiq = $iq({
|
||||
to: room,
|
||||
type: "set"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_OWNER
|
||||
}).c("x", {
|
||||
xmlns: "jabber:x:data",
|
||||
type: "submit"
|
||||
});
|
||||
return this._connection.sendIQ(roomiq.tree());
|
||||
},
|
||||
/*Function
|
||||
Set the topic of the chat room.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) topic - Topic message.
|
||||
*/
|
||||
setTopic: function(room, topic) {
|
||||
var msg;
|
||||
msg = $msg({
|
||||
to: room,
|
||||
from: this._connection.jid,
|
||||
type: "groupchat"
|
||||
}).c("subject", {
|
||||
xmlns: "jabber:client"
|
||||
}).t(topic);
|
||||
return this._connection.send(msg.tree());
|
||||
},
|
||||
/*Function
|
||||
Internal Function that Changes the role or affiliation of a member
|
||||
of a MUC room. This function is used by modifyRole and modifyAffiliation.
|
||||
The modification can only be done by a room moderator. An error will be
|
||||
returned if the user doesn't have permission.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(Object) item - Object with nick and role or jid and affiliation attribute
|
||||
(String) reason - Optional reason for the change.
|
||||
(Function) handler_cb - Optional callback for success
|
||||
(Function) errer_cb - Optional callback for error
|
||||
Returns:
|
||||
iq - the id of the mode change request.
|
||||
*/
|
||||
_modifyPrivilege: function(room, item, reason, handler_cb, error_cb) {
|
||||
var iq;
|
||||
iq = $iq({
|
||||
to: room,
|
||||
type: "set"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_ADMIN
|
||||
}).cnode(item.node);
|
||||
if (reason != null) iq.c("reason", reason);
|
||||
return this._connection.sendIQ(iq.tree(), handler_cb, error_cb);
|
||||
},
|
||||
/*Function
|
||||
Changes the role of a member of a MUC room.
|
||||
The modification can only be done by a room moderator. An error will be
|
||||
returned if the user doesn't have permission.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) nick - The nick name of the user to modify.
|
||||
(String) role - The new role of the user.
|
||||
(String) affiliation - The new affiliation of the user.
|
||||
(String) reason - Optional reason for the change.
|
||||
(Function) handler_cb - Optional callback for success
|
||||
(Function) errer_cb - Optional callback for error
|
||||
Returns:
|
||||
iq - the id of the mode change request.
|
||||
*/
|
||||
modifyRole: function(room, nick, role, reason, handler_cb, error_cb) {
|
||||
var item;
|
||||
item = $build("item", {
|
||||
nick: nick,
|
||||
role: role
|
||||
});
|
||||
return this._modifyPrivilege(room, item, reason, handler_cb, error_cb);
|
||||
},
|
||||
kick: function(room, nick, reason, handler_cb, error_cb) {
|
||||
return this.modifyRole(room, nick, 'none', reason, handler_cb, error_cb);
|
||||
},
|
||||
voice: function(room, nick, reason, handler_cb, error_cb) {
|
||||
return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb);
|
||||
},
|
||||
mute: function(room, nick, reason, handler_cb, error_cb) {
|
||||
return this.modifyRole(room, nick, 'visitor', reason, handler_cb, error_cb);
|
||||
},
|
||||
op: function(room, nick, reason, handler_cb, error_cb) {
|
||||
return this.modifyRole(room, nick, 'moderator', reason, handler_cb, error_cb);
|
||||
},
|
||||
deop: function(room, nick, reason, handler_cb, error_cb) {
|
||||
return this.modifyRole(room, nick, 'participant', reason, handler_cb, error_cb);
|
||||
},
|
||||
/*Function
|
||||
Changes the affiliation of a member of a MUC room.
|
||||
The modification can only be done by a room moderator. An error will be
|
||||
returned if the user doesn't have permission.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) jid - The jid of the user to modify.
|
||||
(String) affiliation - The new affiliation of the user.
|
||||
(String) reason - Optional reason for the change.
|
||||
(Function) handler_cb - Optional callback for success
|
||||
(Function) errer_cb - Optional callback for error
|
||||
Returns:
|
||||
iq - the id of the mode change request.
|
||||
*/
|
||||
modifyAffiliation: function(room, jid, affiliation, reason, handler_cb, error_cb) {
|
||||
var item;
|
||||
item = $build("item", {
|
||||
jid: jid,
|
||||
affiliation: affiliation
|
||||
});
|
||||
return this._modifyPrivilege(room, item, reason, handler_cb, error_cb);
|
||||
},
|
||||
ban: function(room, jid, reason, handler_cb, error_cb) {
|
||||
return this.modifyAffiliation(room, jid, 'outcast', reason, handler_cb, error_cb);
|
||||
},
|
||||
member: function(room, jid, reason, handler_cb, error_cb) {
|
||||
return this.modifyAffiliation(room, jid, 'member', reason, handler_cb, error_cb);
|
||||
},
|
||||
revoke: function(room, jid, reason, handler_cb, error_cb) {
|
||||
return this.modifyAffiliation(room, jid, 'none', reason, handler_cb, error_cb);
|
||||
},
|
||||
owner: function(room, jid, reason, handler_cb, error_cb) {
|
||||
return this.modifyAffiliation(room, jid, 'owner', reason, handler_cb, error_cb);
|
||||
},
|
||||
admin: function(room, jid, reason, handler_cb, error_cb) {
|
||||
return this.modifyAffiliation(room, jid, 'admin', reason, handler_cb, error_cb);
|
||||
},
|
||||
/*Function
|
||||
Change the current users nick name.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) user - The new nick name.
|
||||
*/
|
||||
changeNick: function(room, user) {
|
||||
var presence, room_nick;
|
||||
room_nick = this.test_append_nick(room, user);
|
||||
presence = $pres({
|
||||
from: this._connection.jid,
|
||||
to: room_nick,
|
||||
id: this._connection.getUniqueId()
|
||||
});
|
||||
return this._connection.send(presence.tree());
|
||||
},
|
||||
/*Function
|
||||
Change the current users status.
|
||||
Parameters:
|
||||
(String) room - The multi-user chat room name.
|
||||
(String) user - The current nick.
|
||||
(String) show - The new show-text.
|
||||
(String) status - The new status-text.
|
||||
*/
|
||||
setStatus: function(room, user, show, status) {
|
||||
var presence, room_nick;
|
||||
room_nick = this.test_append_nick(room, user);
|
||||
presence = $pres({
|
||||
from: this._connection.jid,
|
||||
to: room_nick
|
||||
});
|
||||
if (show != null) presence.c('show', show).up();
|
||||
if (status != null) presence.c('status', status);
|
||||
return this._connection.send(presence.tree());
|
||||
},
|
||||
/*Function
|
||||
List all chat room available on a server.
|
||||
Parameters:
|
||||
(String) server - name of chat server.
|
||||
(String) handle_cb - Function to call for room list return.
|
||||
*/
|
||||
listRooms: function(server, handle_cb) {
|
||||
var iq;
|
||||
iq = $iq({
|
||||
to: server,
|
||||
from: this._connection.jid,
|
||||
type: "get"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.DISCO_ITEMS
|
||||
});
|
||||
return this._connection.sendIQ(iq, handle_cb);
|
||||
},
|
||||
test_append_nick: function(room, nick) {
|
||||
return room + (nick != null ? "/" + (Strophe.escapeNode(nick)) : "");
|
||||
}
|
||||
});
|
||||
|
||||
XmppRoom = (function() {
|
||||
|
||||
XmppRoom.prototype.roster = {};
|
||||
|
||||
XmppRoom.prototype._message_handlers = {};
|
||||
|
||||
XmppRoom.prototype._presence_handlers = {};
|
||||
|
||||
XmppRoom.prototype._roster_handlers = {};
|
||||
|
||||
XmppRoom.prototype._handler_ids = 0;
|
||||
|
||||
function XmppRoom(client, name, nick, password) {
|
||||
this.client = client;
|
||||
this.name = name;
|
||||
this.nick = nick;
|
||||
this.password = password;
|
||||
this._roomRosterHandler = __bind(this._roomRosterHandler, this);
|
||||
this._addOccupant = __bind(this._addOccupant, this);
|
||||
if (client.muc) this.client = client.muc;
|
||||
this.name = Strophe.getBareJidFromJid(name);
|
||||
this.client.rooms[this.name] = this;
|
||||
this.addHandler('presence', this._roomRosterHandler);
|
||||
}
|
||||
|
||||
XmppRoom.prototype.join = function(msg_handler_cb, pres_handler_cb) {
|
||||
if (!this.client.rooms[this.name]) {
|
||||
return this.client.join(this.name, this.nick, msg_handler_cb, pres_handler_cb, this.password);
|
||||
}
|
||||
};
|
||||
|
||||
XmppRoom.prototype.leave = function(handler_cb, message) {
|
||||
this.client.leave(this.name, this.nick, handler_cb, message);
|
||||
return delete this.client.rooms[this.name];
|
||||
};
|
||||
|
||||
XmppRoom.prototype.message = function(nick, message, html_message, type) {
|
||||
return this.client.message(this.name, nick, message, html_message, type);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.groupchat = function(message, html_message) {
|
||||
return this.client.groupchat(this.name, message, html_message);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.invite = function(receiver, reason) {
|
||||
return this.client.invite(this.name, receiver, reason);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.directInvite = function(receiver, reason) {
|
||||
return this.client.directInvite(this.name, receiver, reason, this.password);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.configure = function(handler_cb) {
|
||||
return this.client.configure(this.name, handler_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.cancelConfigure = function() {
|
||||
return this.client.cancelConfigure(this.name);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.saveConfiguration = function(configarray) {
|
||||
return this.client.saveConfiguration(this.name, configarray);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.queryOccupants = function(success_cb, error_cb) {
|
||||
return this.client.queryOccupants(this.name, success_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.setTopic = function(topic) {
|
||||
return this.client.setTopic(this.name, topic);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.modifyRole = function(nick, role, reason, success_cb, error_cb) {
|
||||
return this.client.modifyRole(this.name, nick, role, reason, success_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.kick = function(nick, reason, handler_cb, error_cb) {
|
||||
return this.client.kick(this.name, nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.voice = function(nick, reason, handler_cb, error_cb) {
|
||||
return this.client.voice(this.name, nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.mute = function(nick, reason, handler_cb, error_cb) {
|
||||
return this.client.mute(this.name, nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.op = function(nick, reason, handler_cb, error_cb) {
|
||||
return this.client.op(this.name, nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.deop = function(nick, reason, handler_cb, error_cb) {
|
||||
return this.client.deop(this.name, nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.modifyAffiliation = function(jid, affiliation, reason, success_cb, error_cb) {
|
||||
return this.client.modifyAffiliation(this.name, jid, affiliation, reason, success_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.ban = function(jid, reason, handler_cb, error_cb) {
|
||||
return this.client.ban(this.name, jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.member = function(jid, reason, handler_cb, error_cb) {
|
||||
return this.client.member(this.name, jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.revoke = function(jid, reason, handler_cb, error_cb) {
|
||||
return this.client.revoke(this.name, jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.owner = function(jid, reason, handler_cb, error_cb) {
|
||||
return this.client.owner(this.name, jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.admin = function(jid, reason, handler_cb, error_cb) {
|
||||
return this.client.admin(this.name, jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.changeNick = function(nick) {
|
||||
this.nick = nick;
|
||||
return this.client.changeNick(this.name, nick);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.setStatus = function(show, status) {
|
||||
return this.client.setStatus(this.name, this.nick, show, status);
|
||||
};
|
||||
|
||||
/*Function
|
||||
Adds a handler to the MUC room.
|
||||
Parameters:
|
||||
(String) handler_type - 'message', 'presence' or 'roster'.
|
||||
(Function) handler - The handler function.
|
||||
Returns:
|
||||
id - the id of handler.
|
||||
*/
|
||||
|
||||
XmppRoom.prototype.addHandler = function(handler_type, handler) {
|
||||
var id;
|
||||
id = this._handler_ids++;
|
||||
switch (handler_type) {
|
||||
case 'presence':
|
||||
this._presence_handlers[id] = handler;
|
||||
break;
|
||||
case 'message':
|
||||
this._message_handlers[id] = handler;
|
||||
break;
|
||||
case 'roster':
|
||||
this._roster_handlers[id] = handler;
|
||||
break;
|
||||
default:
|
||||
this._handler_ids--;
|
||||
return null;
|
||||
}
|
||||
return id;
|
||||
};
|
||||
|
||||
/*Function
|
||||
Removes a handler from the MUC room.
|
||||
This function takes ONLY ids returned by the addHandler function
|
||||
of this room. passing handler ids returned by connection.addHandler
|
||||
may brake things!
|
||||
Parameters:
|
||||
(number) id - the id of the handler
|
||||
*/
|
||||
|
||||
XmppRoom.prototype.removeHandler = function(id) {
|
||||
delete this._presence_handlers[id];
|
||||
delete this._message_handlers[id];
|
||||
return delete this._roster_handlers[id];
|
||||
};
|
||||
|
||||
/*Function
|
||||
Creates and adds an Occupant to the Room Roster.
|
||||
Parameters:
|
||||
(Object) data - the data the Occupant is filled with
|
||||
Returns:
|
||||
occ - the created Occupant.
|
||||
*/
|
||||
|
||||
XmppRoom.prototype._addOccupant = function(data) {
|
||||
var occ;
|
||||
occ = new Occupant(data, this);
|
||||
this.roster[occ.nick] = occ;
|
||||
return occ;
|
||||
};
|
||||
|
||||
/*Function
|
||||
The standard handler that managed the Room Roster.
|
||||
Parameters:
|
||||
(Object) pres - the presence stanza containing user information
|
||||
*/
|
||||
|
||||
XmppRoom.prototype._roomRosterHandler = function(pres) {
|
||||
var data, handler, id, newnick, nick, _ref;
|
||||
data = XmppRoom._parsePresence(pres);
|
||||
nick = data.nick;
|
||||
newnick = data.newnick || null;
|
||||
switch (data.type) {
|
||||
case 'error':
|
||||
return;
|
||||
case 'unavailable':
|
||||
if (newnick) {
|
||||
data.nick = newnick;
|
||||
if (this.roster[nick] && this.roster[newnick]) {
|
||||
this.roster[nick].update(this.roster[newnick]);
|
||||
this.roster[newnick] = this.roster[nick];
|
||||
}
|
||||
if (this.roster[nick] && !this.roster[newnick]) {
|
||||
this.roster[newnick] = this.roster[nick].update(data);
|
||||
}
|
||||
}
|
||||
delete this.roster[nick];
|
||||
break;
|
||||
default:
|
||||
if (this.roster[nick]) {
|
||||
this.roster[nick].update(data);
|
||||
} else {
|
||||
this._addOccupant(data);
|
||||
}
|
||||
}
|
||||
_ref = this._roster_handlers;
|
||||
for (id in _ref) {
|
||||
handler = _ref[id];
|
||||
if (!handler(this.roster, this)) delete this._roster_handlers[id];
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/*Function
|
||||
Parses a presence stanza
|
||||
Parameters:
|
||||
(Object) data - the data extracted from the presence stanza
|
||||
*/
|
||||
|
||||
XmppRoom._parsePresence = function(pres) {
|
||||
var a, c, c2, data, _i, _j, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
|
||||
data = {};
|
||||
a = pres.attributes;
|
||||
data.nick = Strophe.getResourceFromJid(a.from.textContent);
|
||||
data.type = ((_ref = a.type) != null ? _ref.textContent : void 0) || null;
|
||||
data.states = [];
|
||||
_ref2 = pres.childNodes;
|
||||
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
||||
c = _ref2[_i];
|
||||
switch (c.nodeName) {
|
||||
case "status":
|
||||
data.status = c.textContent || null;
|
||||
break;
|
||||
case "show":
|
||||
data.show = c.textContent || null;
|
||||
break;
|
||||
case "x":
|
||||
a = c.attributes;
|
||||
if (((_ref3 = a.xmlns) != null ? _ref3.textContent : void 0) === Strophe.NS.MUC_USER) {
|
||||
_ref4 = c.childNodes;
|
||||
for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) {
|
||||
c2 = _ref4[_j];
|
||||
switch (c2.nodeName) {
|
||||
case "item":
|
||||
a = c2.attributes;
|
||||
data.affiliation = ((_ref5 = a.affiliation) != null ? _ref5.textContent : void 0) || null;
|
||||
data.role = ((_ref6 = a.role) != null ? _ref6.textContent : void 0) || null;
|
||||
data.jid = ((_ref7 = a.jid) != null ? _ref7.textContent : void 0) || null;
|
||||
data.newnick = ((_ref8 = a.nick) != null ? _ref8.textContent : void 0) || null;
|
||||
break;
|
||||
case "status":
|
||||
if (c2.attributes.code) {
|
||||
data.states.push(c2.attributes.code.textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
return XmppRoom;
|
||||
|
||||
})();
|
||||
|
||||
RoomConfig = (function() {
|
||||
|
||||
function RoomConfig(info) {
|
||||
this.parse = __bind(this.parse, this); if (info != null) this.parse(info);
|
||||
}
|
||||
|
||||
RoomConfig.prototype.parse = function(result) {
|
||||
var attr, attrs, child, field, identity, query, _i, _j, _k, _len, _len2, _len3, _ref;
|
||||
query = result.getElementsByTagName("query")[0].childNodes;
|
||||
this.identities = [];
|
||||
this.features = [];
|
||||
this.x = [];
|
||||
for (_i = 0, _len = query.length; _i < _len; _i++) {
|
||||
child = query[_i];
|
||||
attrs = child.attributes;
|
||||
switch (child.nodeName) {
|
||||
case "identity":
|
||||
identity = {};
|
||||
for (_j = 0, _len2 = attrs.length; _j < _len2; _j++) {
|
||||
attr = attrs[_j];
|
||||
identity[attr.name] = attr.textContent;
|
||||
}
|
||||
this.identities.push(identity);
|
||||
break;
|
||||
case "feature":
|
||||
this.features.push(attrs["var"].textContent);
|
||||
break;
|
||||
case "x":
|
||||
attrs = child.childNodes[0].attributes;
|
||||
if ((!attrs["var"].textContent === 'FORM_TYPE') || (!attrs.type.textContent === 'hidden')) {
|
||||
break;
|
||||
}
|
||||
_ref = child.childNodes;
|
||||
for (_k = 0, _len3 = _ref.length; _k < _len3; _k++) {
|
||||
field = _ref[_k];
|
||||
if (!(!field.attributes.type)) continue;
|
||||
attrs = field.attributes;
|
||||
this.x.push({
|
||||
"var": attrs["var"].textContent,
|
||||
label: attrs.label.textContent || "",
|
||||
value: field.firstChild.textContent || ""
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
"identities": this.identities,
|
||||
"features": this.features,
|
||||
"x": this.x
|
||||
};
|
||||
};
|
||||
|
||||
return RoomConfig;
|
||||
|
||||
})();
|
||||
|
||||
Occupant = (function() {
|
||||
|
||||
function Occupant(data, room) {
|
||||
this.room = room;
|
||||
this.update = __bind(this.update, this);
|
||||
this.admin = __bind(this.admin, this);
|
||||
this.owner = __bind(this.owner, this);
|
||||
this.revoke = __bind(this.revoke, this);
|
||||
this.member = __bind(this.member, this);
|
||||
this.ban = __bind(this.ban, this);
|
||||
this.modifyAffiliation = __bind(this.modifyAffiliation, this);
|
||||
this.deop = __bind(this.deop, this);
|
||||
this.op = __bind(this.op, this);
|
||||
this.mute = __bind(this.mute, this);
|
||||
this.voice = __bind(this.voice, this);
|
||||
this.kick = __bind(this.kick, this);
|
||||
this.modifyRole = __bind(this.modifyRole, this);
|
||||
this.update(data);
|
||||
}
|
||||
|
||||
Occupant.prototype.modifyRole = function(role, reason, success_cb, error_cb) {
|
||||
return this.room.modifyRole(this.nick, role, reason, success_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.kick = function(reason, handler_cb, error_cb) {
|
||||
return this.room.kick(this.nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.voice = function(reason, handler_cb, error_cb) {
|
||||
return this.room.voice(this.nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.mute = function(reason, handler_cb, error_cb) {
|
||||
return this.room.mute(this.nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.op = function(reason, handler_cb, error_cb) {
|
||||
return this.room.op(this.nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.deop = function(reason, handler_cb, error_cb) {
|
||||
return this.room.deop(this.nick, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.modifyAffiliation = function(affiliation, reason, success_cb, error_cb) {
|
||||
return this.room.modifyAffiliation(this.jid, affiliation, reason, success_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.ban = function(reason, handler_cb, error_cb) {
|
||||
return this.room.ban(this.jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.member = function(reason, handler_cb, error_cb) {
|
||||
return this.room.member(this.jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.revoke = function(reason, handler_cb, error_cb) {
|
||||
return this.room.revoke(this.jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.owner = function(reason, handler_cb, error_cb) {
|
||||
return this.room.owner(this.jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.admin = function(reason, handler_cb, error_cb) {
|
||||
return this.room.admin(this.jid, reason, handler_cb, error_cb);
|
||||
};
|
||||
|
||||
Occupant.prototype.update = function(data) {
|
||||
this.nick = data.nick || null;
|
||||
this.affiliation = data.affiliation || null;
|
||||
this.role = data.role || null;
|
||||
this.jid = data.jid || null;
|
||||
this.status = data.status || null;
|
||||
this.show = data.show || null;
|
||||
return this;
|
||||
};
|
||||
|
||||
return Occupant;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
}));
|
452
Libraries/strophe.roster.js
Normal file
452
Libraries/strophe.roster.js
Normal file
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
Copyright 2010, François de Metz <francois@2metz.fr>
|
||||
*/
|
||||
/**
|
||||
* Roster Plugin
|
||||
* Allow easily roster management
|
||||
*
|
||||
* Features
|
||||
* * Get roster from server
|
||||
* * handle presence
|
||||
* * handle roster iq
|
||||
* * subscribe/unsubscribe
|
||||
* * authorize/unauthorize
|
||||
* * roster versioning (xep 237)
|
||||
*/
|
||||
|
||||
|
||||
// AMD/global registrations
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([
|
||||
"Libraries/strophe"
|
||||
], function () {
|
||||
return factory(jQuery, console);
|
||||
}
|
||||
);
|
||||
}
|
||||
}(this, function ($, console) {
|
||||
Strophe.addConnectionPlugin('roster',
|
||||
{
|
||||
_connection: null,
|
||||
|
||||
_callbacks : [],
|
||||
/** Property: items
|
||||
* Roster items
|
||||
* [
|
||||
* {
|
||||
* name : "",
|
||||
* jid : "",
|
||||
* subscription : "",
|
||||
* ask : "",
|
||||
* groups : ["", ""],
|
||||
* resources : {
|
||||
* myresource : {
|
||||
* show : "",
|
||||
* status : "",
|
||||
* priority : ""
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
items : [],
|
||||
/** Property: ver
|
||||
* current roster revision
|
||||
* always null if server doesn't support xep 237
|
||||
*/
|
||||
ver : null,
|
||||
/** Function: init
|
||||
* Plugin init
|
||||
*
|
||||
* Parameters:
|
||||
* (Strophe.Connection) conn - Strophe connection
|
||||
*/
|
||||
init: function(conn)
|
||||
{
|
||||
this._connection = conn;
|
||||
this.items = [];
|
||||
// Override the connect and attach methods to always add presence and roster handlers.
|
||||
// They are removed when the connection disconnects, so must be added on connection.
|
||||
var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
|
||||
var newCallback = function(status)
|
||||
{
|
||||
if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Presence subscription
|
||||
conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null);
|
||||
conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
Strophe.error(e);
|
||||
}
|
||||
}
|
||||
if (oldCallback !== null)
|
||||
oldCallback.apply(this, arguments);
|
||||
};
|
||||
conn.connect = function(jid, pass, callback, wait, hold)
|
||||
{
|
||||
oldCallback = callback;
|
||||
if (typeof arguments[0] == "undefined")
|
||||
arguments[0] = null;
|
||||
if (typeof arguments[1] == "undefined")
|
||||
arguments[1] = null;
|
||||
arguments[2] = newCallback;
|
||||
_connect.apply(conn, arguments);
|
||||
};
|
||||
conn.attach = function(jid, sid, rid, callback, wait, hold, wind)
|
||||
{
|
||||
oldCallback = callback;
|
||||
if (typeof arguments[0] == "undefined")
|
||||
arguments[0] = null;
|
||||
if (typeof arguments[1] == "undefined")
|
||||
arguments[1] = null;
|
||||
if (typeof arguments[2] == "undefined")
|
||||
arguments[2] = null;
|
||||
arguments[3] = newCallback;
|
||||
_attach.apply(conn, arguments);
|
||||
};
|
||||
|
||||
Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver');
|
||||
},
|
||||
/** Function: supportVersioning
|
||||
* return true if roster versioning is enabled on server
|
||||
*/
|
||||
supportVersioning: function()
|
||||
{
|
||||
return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0);
|
||||
},
|
||||
/** Function: get
|
||||
* Get Roster on server
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) userCallback - callback on roster result
|
||||
* (String) ver - current rev of roster
|
||||
* (only used if roster versioning is enabled)
|
||||
* (Array) items - initial items of ver
|
||||
* (only used if roster versioning is enabled)
|
||||
* In browser context you can use sessionStorage
|
||||
* to store your roster in json (JSON.stringify())
|
||||
*/
|
||||
get: function(userCallback, ver, items)
|
||||
{
|
||||
var attrs = {xmlns: Strophe.NS.ROSTER};
|
||||
this.items = [];
|
||||
if (this.supportVersioning())
|
||||
{
|
||||
// empty rev because i want an rev attribute in the result
|
||||
attrs.ver = ver || '';
|
||||
this.items = items || [];
|
||||
}
|
||||
var iq = $iq({type: 'get', 'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
|
||||
this._connection.sendIQ(iq,
|
||||
this._onReceiveRosterSuccess.bind(this, userCallback),
|
||||
this._onReceiveRosterError.bind(this, userCallback));
|
||||
},
|
||||
/** Function: registerCallback
|
||||
* register callback on roster (presence and iq)
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) call_back
|
||||
*/
|
||||
registerCallback: function(call_back)
|
||||
{
|
||||
this._callbacks.push(call_back);
|
||||
},
|
||||
/** Function: findItem
|
||||
* Find item by JID
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
*/
|
||||
findItem : function(jid)
|
||||
{
|
||||
for (var i = 0; i < this.items.length; i++)
|
||||
{
|
||||
if (this.items[i] && this.items[i].jid == jid)
|
||||
{
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/** Function: removeItem
|
||||
* Remove item by JID
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
*/
|
||||
removeItem : function(jid)
|
||||
{
|
||||
for (var i = 0; i < this.items.length; i++)
|
||||
{
|
||||
if (this.items[i] && this.items[i].jid == jid)
|
||||
{
|
||||
this.items.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/** Function: subscribe
|
||||
* Subscribe presence
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
* (String) message
|
||||
*/
|
||||
subscribe: function(jid, message)
|
||||
{
|
||||
var pres = $pres({to: jid, type: "subscribe"});
|
||||
if (message && message != "")
|
||||
pres.c("status").t(message);
|
||||
this._connection.send(pres);
|
||||
},
|
||||
/** Function: unsubscribe
|
||||
* Unsubscribe presence
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
* (String) message
|
||||
*/
|
||||
unsubscribe: function(jid, message)
|
||||
{
|
||||
var pres = $pres({to: jid, type: "unsubscribe"});
|
||||
if (message && message != "")
|
||||
pres.c("status").t(message);
|
||||
this._connection.send(pres);
|
||||
},
|
||||
/** Function: authorize
|
||||
* Authorize presence subscription
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
* (String) message
|
||||
*/
|
||||
authorize: function(jid, message)
|
||||
{
|
||||
var pres = $pres({to: jid, type: "subscribed"});
|
||||
if (message && message != "")
|
||||
pres.c("status").t(message);
|
||||
this._connection.send(pres);
|
||||
},
|
||||
/** Function: unauthorize
|
||||
* Unauthorize presence subscription
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
* (String) message
|
||||
*/
|
||||
unauthorize: function(jid, message)
|
||||
{
|
||||
var pres = $pres({to: jid, type: "unsubscribed"});
|
||||
if (message && message != "")
|
||||
pres.c("status").t(message);
|
||||
this._connection.send(pres);
|
||||
},
|
||||
/** Function: add
|
||||
* Add roster item
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid - item jid
|
||||
* (String) name - name
|
||||
* (Array) groups
|
||||
* (Function) call_back
|
||||
*/
|
||||
add: function(jid, name, groups, call_back)
|
||||
{
|
||||
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
|
||||
name: name});
|
||||
for (var i = 0; i < groups.length; i++)
|
||||
{
|
||||
iq.c('group').t(groups[i]).up();
|
||||
}
|
||||
this._connection.sendIQ(iq, call_back, call_back);
|
||||
},
|
||||
/** Function: update
|
||||
* Update roster item
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid - item jid
|
||||
* (String) name - name
|
||||
* (Array) groups
|
||||
* (Function) call_back
|
||||
*/
|
||||
update: function(jid, name, groups, call_back)
|
||||
{
|
||||
var item = this.findItem(jid);
|
||||
if (!item)
|
||||
{
|
||||
throw "item not found";
|
||||
}
|
||||
var newName = name || item.name;
|
||||
var newGroups = groups || item.groups;
|
||||
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
|
||||
name: newName});
|
||||
for (var i = 0; i < newGroups.length; i++)
|
||||
{
|
||||
iq.c('group').t(newGroups[i]).up();
|
||||
}
|
||||
this._connection.sendIQ(iq, call_back, call_back);
|
||||
},
|
||||
/** Function: remove
|
||||
* Remove roster item
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid - item jid
|
||||
* (Function) call_back
|
||||
*/
|
||||
remove: function(jid, call_back)
|
||||
{
|
||||
var item = this.findItem(jid);
|
||||
if (!item)
|
||||
{
|
||||
throw "item not found";
|
||||
}
|
||||
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
|
||||
subscription: "remove"});
|
||||
this._connection.sendIQ(iq, call_back, call_back);
|
||||
},
|
||||
/** PrivateFunction: _onReceiveRosterSuccess
|
||||
*
|
||||
*/
|
||||
_onReceiveRosterSuccess: function(userCallback, stanza)
|
||||
{
|
||||
this._updateItems(stanza);
|
||||
userCallback(this.items);
|
||||
},
|
||||
/** PrivateFunction: _onReceiveRosterError
|
||||
*
|
||||
*/
|
||||
_onReceiveRosterError: function(userCallback, stanza)
|
||||
{
|
||||
userCallback(this.items);
|
||||
},
|
||||
/** PrivateFunction: _onReceivePresence
|
||||
* Handle presence
|
||||
*/
|
||||
_onReceivePresence : function(presence)
|
||||
{
|
||||
// TODO: from is optional
|
||||
var jid = presence.getAttribute('from');
|
||||
var from = Strophe.getBareJidFromJid(jid);
|
||||
var item = this.findItem(from);
|
||||
// not in roster
|
||||
if (!item)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var type = presence.getAttribute('type');
|
||||
if (type == 'unavailable')
|
||||
{
|
||||
delete item.resources[Strophe.getResourceFromJid(jid)];
|
||||
}
|
||||
else if (!type)
|
||||
{
|
||||
// TODO: add timestamp
|
||||
item.resources[Strophe.getResourceFromJid(jid)] = {
|
||||
show : (presence.getElementsByTagName('show').length != 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "",
|
||||
status : (presence.getElementsByTagName('status').length != 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "",
|
||||
priority : (presence.getElementsByTagName('priority').length != 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : ""
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stanza is not a presence notification. (It's probably a subscription type stanza.)
|
||||
return true;
|
||||
}
|
||||
this._call_backs(this.items, item);
|
||||
return true;
|
||||
},
|
||||
/** PrivateFunction: _call_backs
|
||||
*
|
||||
*/
|
||||
_call_backs : function(items, item)
|
||||
{
|
||||
for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
|
||||
{
|
||||
this._callbacks[i](items, item);
|
||||
}
|
||||
},
|
||||
/** PrivateFunction: _onReceiveIQ
|
||||
* Handle roster push.
|
||||
*/
|
||||
_onReceiveIQ : function(iq)
|
||||
{
|
||||
var id = iq.getAttribute('id');
|
||||
var from = iq.getAttribute('from');
|
||||
// Receiving client MUST ignore stanza unless it has no from or from = user's JID.
|
||||
if (from && from != "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid))
|
||||
return true;
|
||||
var iqresult = $iq({type: 'result', id: id, from: this._connection.jid});
|
||||
this._connection.send(iqresult);
|
||||
this._updateItems(iq);
|
||||
return true;
|
||||
},
|
||||
/** PrivateFunction: _updateItems
|
||||
* Update items from iq
|
||||
*/
|
||||
_updateItems : function(iq)
|
||||
{
|
||||
var query = iq.getElementsByTagName('query');
|
||||
if (query.length != 0)
|
||||
{
|
||||
this.ver = query.item(0).getAttribute('ver');
|
||||
var self = this;
|
||||
Strophe.forEachChild(query.item(0), 'item',
|
||||
function (item)
|
||||
{
|
||||
self._updateItem(item);
|
||||
}
|
||||
);
|
||||
}
|
||||
this._call_backs(this.items);
|
||||
},
|
||||
/** PrivateFunction: _updateItem
|
||||
* Update internal representation of roster item
|
||||
*/
|
||||
_updateItem : function(item)
|
||||
{
|
||||
var jid = item.getAttribute("jid");
|
||||
var name = item.getAttribute("name");
|
||||
var subscription = item.getAttribute("subscription");
|
||||
var ask = item.getAttribute("ask");
|
||||
var groups = [];
|
||||
Strophe.forEachChild(item, 'group',
|
||||
function(group)
|
||||
{
|
||||
groups.push(Strophe.getText(group));
|
||||
}
|
||||
);
|
||||
|
||||
if (subscription == "remove")
|
||||
{
|
||||
this.removeItem(jid);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = this.findItem(jid);
|
||||
if (!item)
|
||||
{
|
||||
this.items.push({
|
||||
name : name,
|
||||
jid : jid,
|
||||
subscription : subscription,
|
||||
ask : ask,
|
||||
groups : groups,
|
||||
resources : {}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
item.name = name;
|
||||
item.subscription = subscription;
|
||||
item.ask = ask;
|
||||
item.groups = groups;
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
1059
Libraries/underscore.js
Normal file
1059
Libraries/underscore.js
Normal file
File diff suppressed because it is too large
Load Diff
600
Libraries/underscore.string.js
Normal file
600
Libraries/underscore.string.js
Normal file
|
@ -0,0 +1,600 @@
|
|||
// Underscore.string
|
||||
// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
|
||||
// Underscore.string is freely distributable under the terms of the MIT license.
|
||||
// Documentation: https://github.com/epeli/underscore.string
|
||||
// Some code is borrowed from MooTools and Alexandru Marasteanu.
|
||||
// Version '2.2.0rc'
|
||||
|
||||
!function(root, String){
|
||||
'use strict';
|
||||
|
||||
// Defining helper functions.
|
||||
|
||||
var nativeTrim = String.prototype.trim;
|
||||
var nativeTrimRight = String.prototype.trimRight;
|
||||
var nativeTrimLeft = String.prototype.trimLeft;
|
||||
|
||||
var parseNumber = function(source) { return source * 1 || 0; };
|
||||
|
||||
var strRepeat = function(str, qty){
|
||||
if (qty < 1) return '';
|
||||
var result = '';
|
||||
while (qty > 0) {
|
||||
if (qty & 1) result += str;
|
||||
qty >>= 1, str += str;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
var slice = [].slice;
|
||||
|
||||
var defaultToWhiteSpace = function(characters) {
|
||||
if (characters == null)
|
||||
return '\\s';
|
||||
else if (characters.source)
|
||||
return characters.source;
|
||||
else
|
||||
return '[' + _s.escapeRegExp(characters) + ']';
|
||||
};
|
||||
|
||||
var escapeChars = {
|
||||
lt: '<',
|
||||
gt: '>',
|
||||
quot: '"',
|
||||
apos: "'",
|
||||
amp: '&'
|
||||
};
|
||||
|
||||
var reversedEscapeChars = {};
|
||||
for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; }
|
||||
|
||||
// sprintf() for JavaScript 0.7-beta1
|
||||
// http://www.diveintojavascript.com/projects/javascript-sprintf
|
||||
//
|
||||
// Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
|
||||
// All rights reserved.
|
||||
|
||||
var sprintf = (function() {
|
||||
function get_type(variable) {
|
||||
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
|
||||
}
|
||||
|
||||
var str_repeat = strRepeat;
|
||||
|
||||
var str_format = function() {
|
||||
if (!str_format.cache.hasOwnProperty(arguments[0])) {
|
||||
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
|
||||
}
|
||||
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
|
||||
};
|
||||
|
||||
str_format.format = function(parse_tree, argv) {
|
||||
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
|
||||
for (i = 0; i < tree_length; i++) {
|
||||
node_type = get_type(parse_tree[i]);
|
||||
if (node_type === 'string') {
|
||||
output.push(parse_tree[i]);
|
||||
}
|
||||
else if (node_type === 'array') {
|
||||
match = parse_tree[i]; // convenience purposes only
|
||||
if (match[2]) { // keyword argument
|
||||
arg = argv[cursor];
|
||||
for (k = 0; k < match[2].length; k++) {
|
||||
if (!arg.hasOwnProperty(match[2][k])) {
|
||||
throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
|
||||
}
|
||||
arg = arg[match[2][k]];
|
||||
}
|
||||
} else if (match[1]) { // positional argument (explicit)
|
||||
arg = argv[match[1]];
|
||||
}
|
||||
else { // positional argument (implicit)
|
||||
arg = argv[cursor++];
|
||||
}
|
||||
|
||||
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
|
||||
throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
|
||||
}
|
||||
switch (match[8]) {
|
||||
case 'b': arg = arg.toString(2); break;
|
||||
case 'c': arg = String.fromCharCode(arg); break;
|
||||
case 'd': arg = parseInt(arg, 10); break;
|
||||
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
|
||||
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
|
||||
case 'o': arg = arg.toString(8); break;
|
||||
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
|
||||
case 'u': arg = Math.abs(arg); break;
|
||||
case 'x': arg = arg.toString(16); break;
|
||||
case 'X': arg = arg.toString(16).toUpperCase(); break;
|
||||
}
|
||||
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
|
||||
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
|
||||
pad_length = match[6] - String(arg).length;
|
||||
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
|
||||
output.push(match[5] ? arg + pad : pad + arg);
|
||||
}
|
||||
}
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
str_format.cache = {};
|
||||
|
||||
str_format.parse = function(fmt) {
|
||||
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
|
||||
while (_fmt) {
|
||||
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
|
||||
parse_tree.push(match[0]);
|
||||
}
|
||||
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
|
||||
parse_tree.push('%');
|
||||
}
|
||||
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
|
||||
if (match[2]) {
|
||||
arg_names |= 1;
|
||||
var field_list = [], replacement_field = match[2], field_match = [];
|
||||
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
|
||||
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
}
|
||||
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
|
||||
field_list.push(field_match[1]);
|
||||
}
|
||||
else {
|
||||
throw new Error('[_.sprintf] huh?');
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error('[_.sprintf] huh?');
|
||||
}
|
||||
match[2] = field_list;
|
||||
}
|
||||
else {
|
||||
arg_names |= 2;
|
||||
}
|
||||
if (arg_names === 3) {
|
||||
throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
|
||||
}
|
||||
parse_tree.push(match);
|
||||
}
|
||||
else {
|
||||
throw new Error('[_.sprintf] huh?');
|
||||
}
|
||||
_fmt = _fmt.substring(match[0].length);
|
||||
}
|
||||
return parse_tree;
|
||||
};
|
||||
|
||||
return str_format;
|
||||
})();
|
||||
|
||||
|
||||
|
||||
// Defining underscore.string
|
||||
|
||||
var _s = {
|
||||
|
||||
VERSION: '2.2.0rc',
|
||||
|
||||
isBlank: function(str){
|
||||
if (str == null) str = '';
|
||||
return (/^\s*$/).test(str);
|
||||
},
|
||||
|
||||
stripTags: function(str){
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/<\/?[^>]+>/g, '');
|
||||
},
|
||||
|
||||
capitalize : function(str){
|
||||
str = str == null ? '' : String(str);
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
},
|
||||
|
||||
chop: function(str, step){
|
||||
if (str == null) return [];
|
||||
str = String(str);
|
||||
step = ~~step;
|
||||
return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
|
||||
},
|
||||
|
||||
clean: function(str){
|
||||
return _s.strip(str).replace(/\s+/g, ' ');
|
||||
},
|
||||
|
||||
count: function(str, substr){
|
||||
if (str == null || substr == null) return 0;
|
||||
return String(str).split(substr).length - 1;
|
||||
},
|
||||
|
||||
chars: function(str) {
|
||||
if (str == null) return [];
|
||||
return String(str).split('');
|
||||
},
|
||||
|
||||
swapCase: function(str) {
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/\S/g, function(c){
|
||||
return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
|
||||
});
|
||||
},
|
||||
|
||||
escapeHTML: function(str) {
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; });
|
||||
},
|
||||
|
||||
unescapeHTML: function(str) {
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/\&([^;]+);/g, function(entity, entityCode){
|
||||
var match;
|
||||
|
||||
if (entityCode in escapeChars) {
|
||||
return escapeChars[entityCode];
|
||||
} else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
|
||||
return String.fromCharCode(parseInt(match[1], 16));
|
||||
} else if (match = entityCode.match(/^#(\d+)$/)) {
|
||||
return String.fromCharCode(~~match[1]);
|
||||
} else {
|
||||
return entity;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
escapeRegExp: function(str){
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
|
||||
},
|
||||
|
||||
splice: function(str, i, howmany, substr){
|
||||
var arr = _s.chars(str);
|
||||
arr.splice(~~i, ~~howmany, substr);
|
||||
return arr.join('');
|
||||
},
|
||||
|
||||
insert: function(str, i, substr){
|
||||
return _s.splice(str, i, 0, substr);
|
||||
},
|
||||
|
||||
include: function(str, needle){
|
||||
if (needle === '') return true;
|
||||
if (str == null) return false;
|
||||
return String(str).indexOf(needle) !== -1;
|
||||
},
|
||||
|
||||
join: function() {
|
||||
var args = slice.call(arguments),
|
||||
separator = args.shift();
|
||||
|
||||
if (separator == null) separator = '';
|
||||
|
||||
return args.join(separator);
|
||||
},
|
||||
|
||||
lines: function(str) {
|
||||
if (str == null) return [];
|
||||
return String(str).split("\n");
|
||||
},
|
||||
|
||||
reverse: function(str){
|
||||
return _s.chars(str).reverse().join('');
|
||||
},
|
||||
|
||||
startsWith: function(str, starts){
|
||||
if (starts === '') return true;
|
||||
if (str == null || starts == null) return false;
|
||||
str = String(str); starts = String(starts);
|
||||
return str.length >= starts.length && str.slice(0, starts.length) === starts;
|
||||
},
|
||||
|
||||
endsWith: function(str, ends){
|
||||
if (ends === '') return true;
|
||||
if (str == null || ends == null) return false;
|
||||
str = String(str); ends = String(ends);
|
||||
return str.length >= ends.length && str.slice(str.length - ends.length) === ends;
|
||||
},
|
||||
|
||||
succ: function(str){
|
||||
if (str == null) return '';
|
||||
str = String(str);
|
||||
return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length-1) + 1);
|
||||
},
|
||||
|
||||
titleize: function(str){
|
||||
if (str == null) return '';
|
||||
return String(str).replace(/(?:^|\s)\S/g, function(c){ return c.toUpperCase(); });
|
||||
},
|
||||
|
||||
camelize: function(str){
|
||||
return _s.trim(str).replace(/[-_\s]+(.)?/g, function(match, c){ return c.toUpperCase(); });
|
||||
},
|
||||
|
||||
underscored: function(str){
|
||||
return _s.trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
|
||||
},
|
||||
|
||||
dasherize: function(str){
|
||||
return _s.trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
|
||||
},
|
||||
|
||||
classify: function(str){
|
||||
return _s.titleize(String(str).replace(/_/g, ' ')).replace(/\s/g, '');
|
||||
},
|
||||
|
||||
humanize: function(str){
|
||||
return _s.capitalize(_s.underscored(str).replace(/_id$/,'').replace(/_/g, ' '));
|
||||
},
|
||||
|
||||
trim: function(str, characters){
|
||||
if (str == null) return '';
|
||||
if (!characters && nativeTrim) return nativeTrim.call(str);
|
||||
characters = defaultToWhiteSpace(characters);
|
||||
return String(str).replace(new RegExp('\^' + characters + '+|' + characters + '+$', 'g'), '');
|
||||
},
|
||||
|
||||
ltrim: function(str, characters){
|
||||
if (str == null) return '';
|
||||
if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
|
||||
characters = defaultToWhiteSpace(characters);
|
||||
return String(str).replace(new RegExp('^' + characters + '+'), '');
|
||||
},
|
||||
|
||||
rtrim: function(str, characters){
|
||||
if (str == null) return '';
|
||||
if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
|
||||
characters = defaultToWhiteSpace(characters);
|
||||
return String(str).replace(new RegExp(characters + '+$'), '');
|
||||
},
|
||||
|
||||
truncate: function(str, length, truncateStr){
|
||||
if (str == null) return '';
|
||||
str = String(str); truncateStr = truncateStr || '...';
|
||||
length = ~~length;
|
||||
return str.length > length ? str.slice(0, length) + truncateStr : str;
|
||||
},
|
||||
|
||||
/**
|
||||
* _s.prune: a more elegant version of truncate
|
||||
* prune extra chars, never leaving a half-chopped word.
|
||||
* @author github.com/rwz
|
||||
*/
|
||||
prune: function(str, length, pruneStr){
|
||||
if (str == null) return '';
|
||||
|
||||
str = String(str); length = ~~length;
|
||||
pruneStr = pruneStr != null ? String(pruneStr) : '...';
|
||||
|
||||
if (str.length <= length) return str;
|
||||
|
||||
var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; },
|
||||
template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
|
||||
|
||||
if (template.slice(template.length-2).match(/\w\w/))
|
||||
template = template.replace(/\s*\S+$/, '');
|
||||
else
|
||||
template = _s.rtrim(template.slice(0, template.length-1));
|
||||
|
||||
return (template+pruneStr).length > str.length ? str : str.slice(0, template.length)+pruneStr;
|
||||
},
|
||||
|
||||
words: function(str, delimiter) {
|
||||
if (_s.isBlank(str)) return [];
|
||||
return _s.trim(str, delimiter).split(delimiter || /\s+/);
|
||||
},
|
||||
|
||||
pad: function(str, length, padStr, type) {
|
||||
str = str == null ? '' : String(str);
|
||||
length = ~~length;
|
||||
|
||||
var padlen = 0;
|
||||
|
||||
if (!padStr)
|
||||
padStr = ' ';
|
||||
else if (padStr.length > 1)
|
||||
padStr = padStr.charAt(0);
|
||||
|
||||
switch(type) {
|
||||
case 'right':
|
||||
padlen = length - str.length;
|
||||
return str + strRepeat(padStr, padlen);
|
||||
case 'both':
|
||||
padlen = length - str.length;
|
||||
return strRepeat(padStr, Math.ceil(padlen/2)) + str
|
||||
+ strRepeat(padStr, Math.floor(padlen/2));
|
||||
default: // 'left'
|
||||
padlen = length - str.length;
|
||||
return strRepeat(padStr, padlen) + str;
|
||||
}
|
||||
},
|
||||
|
||||
lpad: function(str, length, padStr) {
|
||||
return _s.pad(str, length, padStr);
|
||||
},
|
||||
|
||||
rpad: function(str, length, padStr) {
|
||||
return _s.pad(str, length, padStr, 'right');
|
||||
},
|
||||
|
||||
lrpad: function(str, length, padStr) {
|
||||
return _s.pad(str, length, padStr, 'both');
|
||||
},
|
||||
|
||||
sprintf: sprintf,
|
||||
|
||||
vsprintf: function(fmt, argv){
|
||||
argv.unshift(fmt);
|
||||
return sprintf.apply(null, argv);
|
||||
},
|
||||
|
||||
toNumber: function(str, decimals) {
|
||||
if (str == null || str == '') return 0;
|
||||
str = String(str);
|
||||
var num = parseNumber(parseNumber(str).toFixed(~~decimals));
|
||||
return num === 0 && !str.match(/^0+$/) ? Number.NaN : num;
|
||||
},
|
||||
|
||||
numberFormat : function(number, dec, dsep, tsep) {
|
||||
if (isNaN(number) || number == null) return '';
|
||||
|
||||
number = number.toFixed(~~dec);
|
||||
tsep = tsep || ',';
|
||||
|
||||
var parts = number.split('.'), fnums = parts[0],
|
||||
decimals = parts[1] ? (dsep || '.') + parts[1] : '';
|
||||
|
||||
return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
|
||||
},
|
||||
|
||||
strRight: function(str, sep){
|
||||
if (str == null) return '';
|
||||
str = String(str); sep = sep != null ? String(sep) : sep;
|
||||
var pos = !sep ? -1 : str.indexOf(sep);
|
||||
return ~pos ? str.slice(pos+sep.length, str.length) : str;
|
||||
},
|
||||
|
||||
strRightBack: function(str, sep){
|
||||
if (str == null) return '';
|
||||
str = String(str); sep = sep != null ? String(sep) : sep;
|
||||
var pos = !sep ? -1 : str.lastIndexOf(sep);
|
||||
return ~pos ? str.slice(pos+sep.length, str.length) : str;
|
||||
},
|
||||
|
||||
strLeft: function(str, sep){
|
||||
if (str == null) return '';
|
||||
str = String(str); sep = sep != null ? String(sep) : sep;
|
||||
var pos = !sep ? -1 : str.indexOf(sep);
|
||||
return ~pos ? str.slice(0, pos) : str;
|
||||
},
|
||||
|
||||
strLeftBack: function(str, sep){
|
||||
if (str == null) return '';
|
||||
str += ''; sep = sep != null ? ''+sep : sep;
|
||||
var pos = str.lastIndexOf(sep);
|
||||
return ~pos ? str.slice(0, pos) : str;
|
||||
},
|
||||
|
||||
toSentence: function(array, separator, lastSeparator, serial) {
|
||||
separator = separator || ', '
|
||||
lastSeparator = lastSeparator || ' and '
|
||||
var a = array.slice(), lastMember = a.pop();
|
||||
|
||||
if (array.length > 2 && serial) lastSeparator = _s.rtrim(separator) + lastSeparator;
|
||||
|
||||
return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
|
||||
},
|
||||
|
||||
toSentenceSerial: function() {
|
||||
var args = slice.call(arguments);
|
||||
args[3] = true;
|
||||
return _s.toSentence.apply(_s, args);
|
||||
},
|
||||
|
||||
slugify: function(str) {
|
||||
if (str == null) return '';
|
||||
|
||||
var from = "ąàáäâãåæćęèéëêìíïîłńòóöôõøùúüûñçżź",
|
||||
to = "aaaaaaaaceeeeeiiiilnoooooouuuunczz",
|
||||
regex = new RegExp(defaultToWhiteSpace(from), 'g');
|
||||
|
||||
str = String(str).toLowerCase().replace(regex, function(c){
|
||||
var index = from.indexOf(c);
|
||||
return to.charAt(index) || '-';
|
||||
});
|
||||
|
||||
return _s.dasherize(str.replace(/[^\w\s-]/g, ''));
|
||||
},
|
||||
|
||||
surround: function(str, wrapper) {
|
||||
return [wrapper, str, wrapper].join('');
|
||||
},
|
||||
|
||||
quote: function(str) {
|
||||
return _s.surround(str, '"');
|
||||
},
|
||||
|
||||
exports: function() {
|
||||
var result = {};
|
||||
|
||||
for (var prop in this) {
|
||||
if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse)$/)) continue;
|
||||
result[prop] = this[prop];
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
repeat: function(str, qty, separator){
|
||||
if (str == null) return '';
|
||||
|
||||
qty = ~~qty;
|
||||
|
||||
// using faster implementation if separator is not needed;
|
||||
if (separator == null) return strRepeat(String(str), qty);
|
||||
|
||||
// this one is about 300x slower in Google Chrome
|
||||
for (var repeat = []; qty > 0; repeat[--qty] = str) {}
|
||||
return repeat.join(separator);
|
||||
},
|
||||
|
||||
levenshtein: function(str1, str2) {
|
||||
if (str1 == null && str2 == null) return 0;
|
||||
if (str1 == null) return String(str2).length;
|
||||
if (str2 == null) return String(str1).length;
|
||||
|
||||
str1 = String(str1); str2 = String(str2);
|
||||
|
||||
var current = [], prev, value;
|
||||
|
||||
for (var i = 0; i <= str2.length; i++)
|
||||
for (var j = 0; j <= str1.length; j++) {
|
||||
if (i && j)
|
||||
if (str1.charAt(j - 1) === str2.charAt(i - 1))
|
||||
value = prev;
|
||||
else
|
||||
value = Math.min(current[j], current[j - 1], prev) + 1;
|
||||
else
|
||||
value = i + j;
|
||||
|
||||
prev = current[j];
|
||||
current[j] = value;
|
||||
}
|
||||
|
||||
return current.pop();
|
||||
}
|
||||
};
|
||||
|
||||
// Aliases
|
||||
|
||||
_s.strip = _s.trim;
|
||||
_s.lstrip = _s.ltrim;
|
||||
_s.rstrip = _s.rtrim;
|
||||
_s.center = _s.lrpad;
|
||||
_s.rjust = _s.lpad;
|
||||
_s.ljust = _s.rpad;
|
||||
_s.contains = _s.include;
|
||||
_s.q = _s.quote;
|
||||
|
||||
// CommonJS module is defined
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
// Export module
|
||||
module.exports = _s;
|
||||
}
|
||||
exports._s = _s;
|
||||
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
// Register as a named module with AMD.
|
||||
define('underscore.string', [], function() {
|
||||
return _s;
|
||||
});
|
||||
|
||||
} else {
|
||||
// Integrate with Underscore.js if defined
|
||||
// or create our own underscore object.
|
||||
root._ = root._ || {};
|
||||
root._.string = root._.str = _s;
|
||||
}
|
||||
|
||||
}(this, String);
|
Loading…
Reference in New Issue
Block a user