Remove the Libraries dir and fix paths in converse.js
This commit is contained in:
parent
883c64cc16
commit
62c314ff66
File diff suppressed because it is too large
Load Diff
@ -1,192 +0,0 @@
|
||||
/**
|
||||
* Backbone localStorage Adapter
|
||||
* Version 1.1.0
|
||||
*
|
||||
* https://github.com/jeromegn/Backbone.localStorage
|
||||
*/
|
||||
(function (root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["underscore","backbone"], function(_, Backbone) {
|
||||
// Use global variables if the locals is undefined.
|
||||
return factory(_ || root._, Backbone || root.Backbone);
|
||||
});
|
||||
} else {
|
||||
// RequireJS isn't being used. Assume underscore and backbone is loaded in <script> tags
|
||||
factory(_, Backbone);
|
||||
}
|
||||
}(this, function(_, Backbone) {
|
||||
// A simple module to replace `Backbone.sync` with *localStorage*-based
|
||||
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
|
||||
// as that.
|
||||
|
||||
// Hold reference to Underscore.js and Backbone.js in the closure in order
|
||||
// to make things work even if they are removed from the global namespace
|
||||
|
||||
// Generate four random hex digits.
|
||||
function S4() {
|
||||
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||
};
|
||||
|
||||
// Generate a pseudo-GUID by concatenating random hexadecimal.
|
||||
function guid() {
|
||||
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||
};
|
||||
|
||||
// Our Store is represented by a single JS object in *localStorage*. Create it
|
||||
// with a meaningful name, like the name you'd give a table.
|
||||
// window.Store is deprectated, use Backbone.LocalStorage instead
|
||||
Backbone.LocalStorage = window.Store = function(name) {
|
||||
this.name = name;
|
||||
var store = this.localStorage().getItem(this.name);
|
||||
this.records = (store && store.split(",")) || [];
|
||||
};
|
||||
|
||||
_.extend(Backbone.LocalStorage.prototype, {
|
||||
|
||||
// Save the current state of the **Store** to *localStorage*.
|
||||
save: function() {
|
||||
this.localStorage().setItem(this.name, this.records.join(","));
|
||||
},
|
||||
|
||||
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
|
||||
// have an id of it's own.
|
||||
create: function(model) {
|
||||
if (!model.id) {
|
||||
model.id = guid();
|
||||
model.set(model.idAttribute, model.id);
|
||||
}
|
||||
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
|
||||
this.records.push(model.id.toString());
|
||||
this.save();
|
||||
return this.find(model);
|
||||
},
|
||||
|
||||
// Update a model by replacing its copy in `this.data`.
|
||||
update: function(model) {
|
||||
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
|
||||
if (!_.include(this.records, model.id.toString()))
|
||||
this.records.push(model.id.toString()); this.save();
|
||||
return this.find(model);
|
||||
},
|
||||
|
||||
// Retrieve a model from `this.data` by id.
|
||||
find: function(model) {
|
||||
return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
|
||||
},
|
||||
|
||||
// Return the array of all models currently in storage.
|
||||
findAll: function() {
|
||||
return _(this.records).chain()
|
||||
.map(function(id){
|
||||
return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
|
||||
}, this)
|
||||
.compact()
|
||||
.value();
|
||||
},
|
||||
|
||||
// Delete a model from `this.data`, returning it.
|
||||
destroy: function(model) {
|
||||
if (model.isNew())
|
||||
return false
|
||||
this.localStorage().removeItem(this.name+"-"+model.id);
|
||||
this.records = _.reject(this.records, function(id){
|
||||
return id === model.id.toString();
|
||||
});
|
||||
this.save();
|
||||
return model;
|
||||
},
|
||||
|
||||
localStorage: function() {
|
||||
return localStorage;
|
||||
},
|
||||
|
||||
// fix for "illegal access" error on Android when JSON.parse is passed null
|
||||
jsonData: function (data) {
|
||||
return data && JSON.parse(data);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// localSync delegate to the model or collection's
|
||||
// *localStorage* property, which should be an instance of `Store`.
|
||||
// window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead
|
||||
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
|
||||
var store = model.localStorage || model.collection.localStorage;
|
||||
|
||||
var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
|
||||
|
||||
try {
|
||||
|
||||
switch (method) {
|
||||
case "read":
|
||||
resp = model.id != undefined ? store.find(model) : store.findAll();
|
||||
break;
|
||||
case "create":
|
||||
resp = store.create(model);
|
||||
break;
|
||||
case "update":
|
||||
resp = store.update(model);
|
||||
break;
|
||||
case "delete":
|
||||
resp = store.destroy(model);
|
||||
break;
|
||||
}
|
||||
|
||||
} catch(error) {
|
||||
if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0)
|
||||
errorMessage = "Private browsing is unsupported";
|
||||
else
|
||||
errorMessage = error.message;
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
if (options && options.success)
|
||||
if (Backbone.VERSION === "0.9.10") {
|
||||
options.success(model, resp, options);
|
||||
} else {
|
||||
options.success(resp);
|
||||
}
|
||||
if (syncDfd)
|
||||
syncDfd.resolve(resp);
|
||||
|
||||
} else {
|
||||
errorMessage = errorMessage ? errorMessage
|
||||
: "Record Not Found";
|
||||
|
||||
if (options && options.error)
|
||||
if (Backbone.VERSION === "0.9.10") {
|
||||
options.error(model, errorMessage, options);
|
||||
} else {
|
||||
options.error(errorMessage);
|
||||
}
|
||||
|
||||
if (syncDfd)
|
||||
syncDfd.reject(errorMessage);
|
||||
}
|
||||
|
||||
// add compatibility with $.ajax
|
||||
// always execute callback for success and error
|
||||
if (options && options.complete) options.complete(resp);
|
||||
|
||||
return syncDfd && syncDfd.promise();
|
||||
};
|
||||
|
||||
Backbone.ajaxSync = Backbone.sync;
|
||||
|
||||
Backbone.getSyncMethod = function(model) {
|
||||
if(model.localStorage || (model.collection && model.collection.localStorage)) {
|
||||
return Backbone.localSync;
|
||||
}
|
||||
|
||||
return Backbone.ajaxSync;
|
||||
};
|
||||
|
||||
// Override 'Backbone.sync' to default to localSync,
|
||||
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
|
||||
Backbone.sync = function(method, model, options) {
|
||||
return Backbone.getSyncMethod(model).apply(this, [method, model, options]);
|
||||
};
|
||||
|
||||
return Backbone.LocalStorage;
|
||||
}));
|
@ -1,20 +0,0 @@
|
||||
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.
|
@ -1,681 +0,0 @@
|
||||
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);
|
||||
setExceptionHandling();
|
||||
|
||||
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 = jasmine.HtmlReporter.parameters(doc);
|
||||
|
||||
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'},
|
||||
self.createDom('span', { className: 'exceptions' },
|
||||
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
|
||||
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
|
||||
function noTryCatch() {
|
||||
return window.location.search.match(/catch=false/);
|
||||
}
|
||||
|
||||
function searchWithCatch() {
|
||||
var params = jasmine.HtmlReporter.parameters(window.document);
|
||||
var removed = false;
|
||||
var i = 0;
|
||||
|
||||
while (!removed && i < params.length) {
|
||||
if (params[i].match(/catch=/)) {
|
||||
params.splice(i, 1);
|
||||
removed = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (jasmine.CATCH_EXCEPTIONS) {
|
||||
params.push("catch=false");
|
||||
}
|
||||
|
||||
return params.join("&");
|
||||
}
|
||||
|
||||
function setExceptionHandling() {
|
||||
var chxCatch = document.getElementById('no_try_catch');
|
||||
|
||||
if (noTryCatch()) {
|
||||
chxCatch.setAttribute('checked', true);
|
||||
jasmine.CATCH_EXCEPTIONS = false;
|
||||
}
|
||||
chxCatch.onclick = function() {
|
||||
window.location.search = searchWithCatch();
|
||||
};
|
||||
}
|
||||
};
|
||||
jasmine.HtmlReporter.parameters = function(doc) {
|
||||
var paramStr = doc.location.search.substring(1);
|
||||
var params = [];
|
||||
|
||||
if (paramStr.length > 0) {
|
||||
params = paramStr.split('&');
|
||||
}
|
||||
return params;
|
||||
}
|
||||
jasmine.HtmlReporter.sectionLink = function(sectionName) {
|
||||
var link = '?';
|
||||
var params = [];
|
||||
|
||||
if (sectionName) {
|
||||
params.push('spec=' + encodeURIComponent(sectionName));
|
||||
}
|
||||
if (!jasmine.CATCH_EXCEPTIONS) {
|
||||
params.push("catch=false");
|
||||
}
|
||||
if (params.length > 0) {
|
||||
link += params.join("&");
|
||||
}
|
||||
|
||||
return link;
|
||||
};
|
||||
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: jasmine.HtmlReporter.sectionLink(), 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: jasmine.HtmlReporter.sectionLink(), 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: jasmine.HtmlReporter.sectionLink(), 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: jasmine.HtmlReporter.sectionLink(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: jasmine.HtmlReporter.sectionLink(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;
|
||||
};
|
@ -1,82 +0,0 @@
|
||||
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 .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
|
||||
#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; }
|
File diff suppressed because it is too large
Load Diff
1008
Libraries/jed.js
1008
Libraries/jed.js
File diff suppressed because it is too large
Load Diff
@ -1,211 +0,0 @@
|
||||
/*! TinySort 1.4.29
|
||||
* Copyright (c) 2008-2012 Ron Valstar http://www.sjeiti.com/
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*//*
|
||||
* Description:
|
||||
* A jQuery plugin to sort child nodes by (sub) contents or attributes.
|
||||
*
|
||||
* Contributors:
|
||||
* brian.gibson@gmail.com
|
||||
* michael.thornberry@gmail.com
|
||||
*
|
||||
* Usage:
|
||||
* $("ul#people>li").tsort();
|
||||
* $("ul#people>li").tsort("span.surname");
|
||||
* $("ul#people>li").tsort("span.surname",{order:"desc"});
|
||||
* $("ul#people>li").tsort({place:"end"});
|
||||
*
|
||||
* Change default like so:
|
||||
* $.tinysort.defaults.order = "desc";
|
||||
*
|
||||
* in this update:
|
||||
* - added plugin hook
|
||||
* - stripped non-latin character ordering and turned it into a plugin
|
||||
*
|
||||
* in last update:
|
||||
* - header comment no longer stripped in minified version
|
||||
* - revision number no longer corresponds to svn revision since it's now git
|
||||
*
|
||||
* Todos:
|
||||
* - todo: uppercase vs lowercase
|
||||
* - todo: 'foobar' != 'foobars' in non-latin
|
||||
*
|
||||
*/
|
||||
;(function($) {
|
||||
// private vars
|
||||
var fls = !1 // minify placeholder
|
||||
,nll = null // minify placeholder
|
||||
,prsflt = parseFloat // minify placeholder
|
||||
,mathmn = Math.min // minify placeholder
|
||||
,rxLastNr = /(-?\d+\.?\d*)$/g // regex for testing strings ending on numbers
|
||||
,aPluginPrepare = []
|
||||
,aPluginSort = []
|
||||
;
|
||||
//
|
||||
// init plugin
|
||||
$.tinysort = {
|
||||
id: 'TinySort'
|
||||
,version: '1.4.29'
|
||||
,copyright: 'Copyright (c) 2008-2012 Ron Valstar'
|
||||
,uri: 'http://tinysort.sjeiti.com/'
|
||||
,licensed: {
|
||||
MIT: 'http://www.opensource.org/licenses/mit-license.php'
|
||||
,GPL: 'http://www.gnu.org/licenses/gpl.html'
|
||||
}
|
||||
,plugin: function(prepare,sort){
|
||||
aPluginPrepare.push(prepare); // function(settings){doStuff();}
|
||||
aPluginSort.push(sort); // function(valuesAreNumeric,sA,sB,iReturn){doStuff();return iReturn;}
|
||||
}
|
||||
,defaults: { // default settings
|
||||
|
||||
order: 'asc' // order: asc, desc or rand
|
||||
|
||||
,attr: nll // order by attribute value
|
||||
,data: nll // use the data attribute for sorting
|
||||
,useVal: fls // use element value instead of text
|
||||
|
||||
,place: 'start' // place ordered elements at position: start, end, org (original position), first
|
||||
,returns: fls // return all elements or only the sorted ones (true/false)
|
||||
|
||||
,cases: fls // a case sensitive sort orders [aB,aa,ab,bb]
|
||||
,forceStrings:fls // if false the string '2' will sort with the value 2, not the string '2'
|
||||
|
||||
,sortFunction: nll // override the default sort function
|
||||
}
|
||||
};
|
||||
$.fn.extend({
|
||||
tinysort: function(_find,_settings) {
|
||||
if (_find&&typeof(_find)!='string') {
|
||||
_settings = _find;
|
||||
_find = nll;
|
||||
}
|
||||
|
||||
var oSettings = $.extend({}, $.tinysort.defaults, _settings)
|
||||
,sParent
|
||||
,oThis = this
|
||||
,iLen = $(this).length
|
||||
,oElements = {} // contains sortable- and non-sortable list per parent
|
||||
,bFind = !(!_find||_find=='')
|
||||
,bAttr = !(oSettings.attr===nll||oSettings.attr=="")
|
||||
,bData = oSettings.data!==nll
|
||||
// since jQuery's filter within each works on array index and not actual index we have to create the filter in advance
|
||||
,bFilter = bFind&&_find[0]==':'
|
||||
,$Filter = bFilter?oThis.filter(_find):oThis
|
||||
,fnSort = oSettings.sortFunction
|
||||
,iAsc = oSettings.order=='asc'?1:-1
|
||||
,aNewOrder = []
|
||||
;
|
||||
|
||||
$.each(aPluginPrepare,function(i,fn){
|
||||
fn.call(fn,oSettings);
|
||||
});
|
||||
|
||||
|
||||
if (!fnSort) fnSort = oSettings.order=='rand'?function() {
|
||||
return Math.random()<.5?1:-1;
|
||||
}:function(a,b) {
|
||||
var bNumeric = fls
|
||||
// maybe toLower
|
||||
,sA = !oSettings.cases?toLowerCase(a.s):a.s
|
||||
,sB = !oSettings.cases?toLowerCase(b.s):b.s;
|
||||
// maybe force Strings
|
||||
// var bAString = typeof(sA)=='string';
|
||||
// var bBString = typeof(sB)=='string';
|
||||
// if (!oSettings.forceStrings&&(bAString||bBString)) {
|
||||
// if (!bAString) sA = ''+sA;
|
||||
// if (!bBString) sB = ''+sB;
|
||||
if (!oSettings.forceStrings) {
|
||||
// maybe mixed
|
||||
var aAnum = sA&&sA.match(rxLastNr)
|
||||
,aBnum = sB&&sB.match(rxLastNr);
|
||||
if (aAnum&&aBnum) {
|
||||
var sAprv = sA.substr(0,sA.length-aAnum[0].length)
|
||||
,sBprv = sB.substr(0,sB.length-aBnum[0].length);
|
||||
if (sAprv==sBprv) {
|
||||
bNumeric = !fls;
|
||||
sA = prsflt(aAnum[0]);
|
||||
sB = prsflt(aBnum[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return sort-integer
|
||||
var iReturn = iAsc*(sA<sB?-1:(sA>sB?1:0));
|
||||
|
||||
$.each(aPluginSort,function(i,fn){
|
||||
iReturn = fn.call(fn,bNumeric,sA,sB,iReturn);
|
||||
});
|
||||
|
||||
return iReturn;
|
||||
};
|
||||
|
||||
oThis.each(function(i,el) {
|
||||
var $Elm = $(el)
|
||||
// element or sub selection
|
||||
,mElmOrSub = bFind?(bFilter?$Filter.filter(el):$Elm.find(_find)):$Elm
|
||||
// text or attribute value
|
||||
,sSort = bData?''+mElmOrSub.data(oSettings.data):(bAttr?mElmOrSub.attr(oSettings.attr):(oSettings.useVal?mElmOrSub.val():mElmOrSub.text()))
|
||||
// to sort or not to sort
|
||||
,mParent = $Elm.parent();
|
||||
if (!oElements[mParent]) oElements[mParent] = {s:[],n:[]}; // s: sort, n: not sort
|
||||
if (mElmOrSub.length>0) oElements[mParent].s.push({s:sSort,e:$Elm,n:i}); // s:string, e:element, n:number
|
||||
else oElements[mParent].n.push({e:$Elm,n:i});
|
||||
});
|
||||
//
|
||||
// sort
|
||||
for (sParent in oElements) oElements[sParent].s.sort(fnSort);
|
||||
//
|
||||
// order elements and fill new order
|
||||
for (sParent in oElements) {
|
||||
var oParent = oElements[sParent]
|
||||
,aOrg = [] // list for original position
|
||||
,iLow = iLen
|
||||
,aCnt = [0,0] // count how much we've sorted for retreival from either the sort list or the non-sort list (oParent.s/oParent.n)
|
||||
,i;
|
||||
switch (oSettings.place) {
|
||||
case 'first': $.each(oParent.s,function(i,obj) { iLow = mathmn(iLow,obj.n) }); break;
|
||||
case 'org': $.each(oParent.s,function(i,obj) { aOrg.push(obj.n) }); break;
|
||||
case 'end': iLow = oParent.n.length; break;
|
||||
default: iLow = 0;
|
||||
}
|
||||
for (i = 0;i<iLen;i++) {
|
||||
var bSList = contains(aOrg,i)?!fls:i>=iLow&&i<iLow+oParent.s.length
|
||||
,mEl = (bSList?oParent.s:oParent.n)[aCnt[bSList?0:1]].e;
|
||||
mEl.parent().append(mEl);
|
||||
if (bSList||!oSettings.returns) aNewOrder.push(mEl.get(0));
|
||||
aCnt[bSList?0:1]++;
|
||||
}
|
||||
}
|
||||
oThis.length = 0;
|
||||
Array.prototype.push.apply(oThis,aNewOrder);
|
||||
return oThis;
|
||||
}
|
||||
});
|
||||
// toLowerCase
|
||||
function toLowerCase(s) {
|
||||
return s&&s.toLowerCase?s.toLowerCase():s;
|
||||
}
|
||||
// array contains
|
||||
function contains(a,n) {
|
||||
for (var i=0,l=a.length;i<l;i++) if (a[i]==n) return !fls;
|
||||
return fls;
|
||||
}
|
||||
// set functions
|
||||
$.fn.TinySort = $.fn.Tinysort = $.fn.tsort = $.fn.tinysort;
|
||||
})(jQuery);
|
||||
|
||||
/*! Array.prototype.indexOf for IE (issue #26) */
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function(elt /*, from*/) {
|
||||
var len = this.length
|
||||
,from = Number(arguments[1])||0;
|
||||
from = from<0?Math.ceil(from):Math.floor(from);
|
||||
if (from<0) from += len;
|
||||
for (;from<len;from++){
|
||||
if (from in this && this[from]===elt) return from;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
||||
"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)}};
|
@ -1,232 +0,0 @@
|
||||
/*
|
||||
Copyright 2010, François de Metz <francois@2metz.fr>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disco Strophe Plugin
|
||||
* Implement http://xmpp.org/extensions/xep-0030.html
|
||||
* TODO: manage node hierarchies, and node on info request
|
||||
*/
|
||||
Strophe.addConnectionPlugin('disco',
|
||||
{
|
||||
_connection: null,
|
||||
_identities : [],
|
||||
_features : [],
|
||||
_items : [],
|
||||
/** Function: init
|
||||
* Plugin init
|
||||
*
|
||||
* Parameters:
|
||||
* (Strophe.Connection) conn - Strophe connection
|
||||
*/
|
||||
init: function(conn)
|
||||
{
|
||||
this._connection = conn;
|
||||
this._identities = [];
|
||||
this._features = [];
|
||||
this._items = [];
|
||||
// disco info
|
||||
conn.addHandler(this._onDiscoInfo.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
|
||||
// disco items
|
||||
conn.addHandler(this._onDiscoItems.bind(this), Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null);
|
||||
},
|
||||
/** Function: addIdentity
|
||||
* See http://xmpp.org/registrar/disco-categories.html
|
||||
* Parameters:
|
||||
* (String) category - category of identity (like client, automation, etc ...)
|
||||
* (String) type - type of identity (like pc, web, bot , etc ...)
|
||||
* (String) name - name of identity in natural language
|
||||
* (String) lang - lang of name parameter
|
||||
*
|
||||
* Returns:
|
||||
* Boolean
|
||||
*/
|
||||
addIdentity: function(category, type, name, lang)
|
||||
{
|
||||
for (var i=0; i<this._identities.length; i++)
|
||||
{
|
||||
if (this._identities[i].category == category &&
|
||||
this._identities[i].type == type &&
|
||||
this._identities[i].name == name &&
|
||||
this._identities[i].lang == lang)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this._identities.push({category: category, type: type, name: name, lang: lang});
|
||||
return true;
|
||||
},
|
||||
/** Function: addFeature
|
||||
*
|
||||
* Parameters:
|
||||
* (String) var_name - feature name (like jabber:iq:version)
|
||||
*
|
||||
* Returns:
|
||||
* boolean
|
||||
*/
|
||||
addFeature: function(var_name)
|
||||
{
|
||||
for (var i=0; i<this._features.length; i++)
|
||||
{
|
||||
if (this._features[i] == var_name)
|
||||
return false;
|
||||
}
|
||||
this._features.push(var_name);
|
||||
return true;
|
||||
},
|
||||
/** Function: removeFeature
|
||||
*
|
||||
* Parameters:
|
||||
* (String) var_name - feature name (like jabber:iq:version)
|
||||
*
|
||||
* Returns:
|
||||
* boolean
|
||||
*/
|
||||
removeFeature: function(var_name)
|
||||
{
|
||||
for (var i=0; i<this._features.length; i++)
|
||||
{
|
||||
if (this._features[i] === var_name){
|
||||
this._features.splice(i,1)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/** Function: addItem
|
||||
*
|
||||
* Parameters:
|
||||
* (String) jid
|
||||
* (String) name
|
||||
* (String) node
|
||||
* (Function) call_back
|
||||
*
|
||||
* Returns:
|
||||
* boolean
|
||||
*/
|
||||
addItem: function(jid, name, node, call_back)
|
||||
{
|
||||
if (node && !call_back)
|
||||
return false;
|
||||
this._items.push({jid: jid, name: name, node: node, call_back: call_back});
|
||||
return true;
|
||||
},
|
||||
/** Function: info
|
||||
* Info query
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) call_back
|
||||
* (String) jid
|
||||
* (String) node
|
||||
*/
|
||||
info: function(jid, node, success, error, timeout)
|
||||
{
|
||||
var attrs = {xmlns: Strophe.NS.DISCO_INFO};
|
||||
if (node)
|
||||
attrs.node = node;
|
||||
|
||||
var info = $iq({from:this._connection.jid,
|
||||
to:jid, type:'get'}).c('query', attrs);
|
||||
this._connection.sendIQ(info, success, error, timeout);
|
||||
},
|
||||
/** Function: items
|
||||
* Items query
|
||||
*
|
||||
* Parameters:
|
||||
* (Function) call_back
|
||||
* (String) jid
|
||||
* (String) node
|
||||
*/
|
||||
items: function(jid, node, success, error, timeout)
|
||||
{
|
||||
var attrs = {xmlns: Strophe.NS.DISCO_ITEMS};
|
||||
if (node)
|
||||
attrs.node = node;
|
||||
|
||||
var items = $iq({from:this._connection.jid,
|
||||
to:jid, type:'get'}).c('query', attrs);
|
||||
this._connection.sendIQ(items, success, error, timeout);
|
||||
},
|
||||
|
||||
/** PrivateFunction: _buildIQResult
|
||||
*/
|
||||
_buildIQResult: function(stanza, query_attrs)
|
||||
{
|
||||
var id = stanza.getAttribute('id');
|
||||
var from = stanza.getAttribute('from');
|
||||
var iqresult = $iq({type: 'result', id: id});
|
||||
|
||||
if (from !== null) {
|
||||
iqresult.attrs({to: from});
|
||||
}
|
||||
|
||||
return iqresult.c('query', query_attrs);
|
||||
},
|
||||
|
||||
/** PrivateFunction: _onDiscoInfo
|
||||
* Called when receive info request
|
||||
*/
|
||||
_onDiscoInfo: function(stanza)
|
||||
{
|
||||
var node = stanza.getElementsByTagName('query')[0].getAttribute('node');
|
||||
var attrs = {xmlns: Strophe.NS.DISCO_INFO};
|
||||
if (node)
|
||||
{
|
||||
attrs.node = node;
|
||||
}
|
||||
var iqresult = this._buildIQResult(stanza, attrs);
|
||||
for (var i=0; i<this._identities.length; i++)
|
||||
{
|
||||
var attrs = {category: this._identities[i].category,
|
||||
type : this._identities[i].type};
|
||||
if (this._identities[i].name)
|
||||
attrs.name = this._identities[i].name;
|
||||
if (this._identities[i].lang)
|
||||
attrs['xml:lang'] = this._identities[i].lang;
|
||||
iqresult.c('identity', attrs).up();
|
||||
}
|
||||
for (var i=0; i<this._features.length; i++)
|
||||
{
|
||||
iqresult.c('feature', {'var':this._features[i]}).up();
|
||||
}
|
||||
this._connection.send(iqresult.tree());
|
||||
return true;
|
||||
},
|
||||
/** PrivateFunction: _onDiscoItems
|
||||
* Called when receive items request
|
||||
*/
|
||||
_onDiscoItems: function(stanza)
|
||||
{
|
||||
var query_attrs = {xmlns: Strophe.NS.DISCO_ITEMS};
|
||||
var node = stanza.getElementsByTagName('query')[0].getAttribute('node');
|
||||
if (node)
|
||||
{
|
||||
query_attrs.node = node;
|
||||
var items = [];
|
||||
for (var i = 0; i < this._items.length; i++)
|
||||
{
|
||||
if (this._items[i].node == node)
|
||||
{
|
||||
items = this._items[i].call_back(stanza);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = this._items;
|
||||
}
|
||||
var iqresult = this._buildIQResult(stanza, query_attrs);
|
||||
for (var i = 0; i < items.length; i++)
|
||||
{
|
||||
var attrs = {jid: items[i].jid};
|
||||
if (items[i].name)
|
||||
attrs.name = items[i].name;
|
||||
if (items[i].node)
|
||||
attrs.node = items[i].node;
|
||||
iqresult.c('item', attrs).up();
|
||||
}
|
||||
this._connection.send(iqresult.tree());
|
||||
return true;
|
||||
}
|
||||
});
|
4200
Libraries/strophe.js
4200
Libraries/strophe.js
File diff suppressed because it is too large
Load Diff
@ -1,963 +0,0 @@
|
||||
/*
|
||||
*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>
|
||||
*Cleanup, AMD/global registrations and bugfixes:
|
||||
JC Brand <jc@opkode.com>
|
||||
*/
|
||||
|
||||
// AMD/global registrations
|
||||
(function (root, factory) {
|
||||
if (typeof console === undefined || typeof console.log === undefined) {
|
||||
console = { log: function () {}, error: function () {} };
|
||||
}
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([
|
||||
"strophe"
|
||||
], function () {
|
||||
if (console===undefined || console.log===undefined) {
|
||||
console = { log: function () {}, error: function () {} };
|
||||
}
|
||||
return factory(jQuery, console);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
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: [],
|
||||
init: function(conn) {
|
||||
/* Initialize the MUC plugin. Sets the correct connection object and
|
||||
* extends the namesace.
|
||||
*/
|
||||
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");
|
||||
},
|
||||
|
||||
join: function(room, nick, msg_handler_cb, pres_handler_cb, roster_cb, password) {
|
||||
/* Join a multi-user chat room
|
||||
*
|
||||
* Parameters:
|
||||
* (String) room - The multi-user chat room to join.
|
||||
* (String) nick - Optional nickname to use in the chat room.
|
||||
* (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.
|
||||
* (Function) roster_cb - The function call back to handle roster changes in the chat room.
|
||||
* (String) password - The optional password to use. (password protected rooms only)
|
||||
*/
|
||||
var msg, room_nick, _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');
|
||||
if (!from) { return true; }
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_.each(handlers, function (handler, id, handlers) {
|
||||
if (!handler(stanza, room)) { delete handlers[id]; }
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
if (!_.has(this.rooms, room)) {
|
||||
this.rooms[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);
|
||||
},
|
||||
|
||||
removeRoom: function (room) {
|
||||
delete this.rooms[room];
|
||||
if (this.rooms.length === 0) {
|
||||
this._connection.deleteHandler(this._muc_handler);
|
||||
this._muc_handler = null;
|
||||
}
|
||||
},
|
||||
|
||||
leave: function(room, nick, handler_cb, exit_msg) {
|
||||
/* 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.
|
||||
*/
|
||||
var presence, presenceid, room_nick;
|
||||
this.removeRoom(room);
|
||||
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;
|
||||
},
|
||||
|
||||
message: function(room, nick, message, html_message, type) {
|
||||
/* 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
|
||||
*/
|
||||
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;
|
||||
},
|
||||
|
||||
groupchat: function(room, message, html_message) {
|
||||
/* 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
|
||||
*/
|
||||
return this.message(room, null, message, html_message);
|
||||
},
|
||||
|
||||
invite: function(room, receiver, reason) {
|
||||
/* 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
|
||||
*/
|
||||
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;
|
||||
},
|
||||
|
||||
directInvite: function(room, receiver, reason, password) {
|
||||
/* 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
|
||||
*/
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
queryOccupants: function(room, success_cb, error_cb) {
|
||||
/* 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
|
||||
*/
|
||||
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);
|
||||
},
|
||||
|
||||
configure: function(room, handler_cb) {
|
||||
/* 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
|
||||
*/
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
cancelConfigure: function(room) {
|
||||
/* Cancel the room configuration
|
||||
* Parameters:
|
||||
* (String) room - The multi-user chat room name.
|
||||
* Returns:
|
||||
* id - the unique id used to cancel the configuration.
|
||||
*/
|
||||
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);
|
||||
},
|
||||
|
||||
saveConfiguration: function(room, configarray, callback, errback) {
|
||||
/* 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.
|
||||
*/
|
||||
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, callback, errback);
|
||||
},
|
||||
|
||||
createInstantRoom: function(room) {
|
||||
/* Parameters:
|
||||
* (String) room - The multi-user chat room name.
|
||||
* Returns:
|
||||
* id - the unique id used to create the chat 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());
|
||||
},
|
||||
|
||||
setTopic: function(room, topic) {
|
||||
/* Set the topic of the chat room.
|
||||
* Parameters:
|
||||
* (String) room - The multi-user chat room name.
|
||||
* (String) topic - Topic message.
|
||||
*/
|
||||
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());
|
||||
},
|
||||
|
||||
_modifyPrivilege: function(room, item, reason, handler_cb, error_cb) {
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
},
|
||||
|
||||
modifyRole: function(room, nick, role, reason, handler_cb, error_cb) {
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
},
|
||||
|
||||
modifyAffiliation: function(room, jid, affiliation, reason, handler_cb, error_cb) {
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
},
|
||||
|
||||
changeNick: function(room, user) {
|
||||
/* Change the current users nick name.
|
||||
* Parameters:
|
||||
* (String) room - The multi-user chat room name.
|
||||
* (String) user - The new nick name.
|
||||
*/
|
||||
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());
|
||||
},
|
||||
|
||||
setStatus: function(room, user, show, status) {
|
||||
/* 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.
|
||||
*/
|
||||
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());
|
||||
},
|
||||
|
||||
listRooms: function(server, callback, errback) {
|
||||
/* List all chat room available on a server.
|
||||
* Parameters:
|
||||
* (String) server - name of chat server.
|
||||
* (String) callback - Function to call for room list return.
|
||||
*/
|
||||
var iq;
|
||||
iq = $iq({
|
||||
to: server,
|
||||
from: this._connection.jid,
|
||||
type: "get"
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.DISCO_ITEMS
|
||||
});
|
||||
return this._connection.sendIQ(iq, callback, errback);
|
||||
},
|
||||
test_append_nick: function(room, nick) {
|
||||
return room + (nick !== null ? "/" + (Strophe.escapeNode(nick)) : "");
|
||||
}
|
||||
});
|
||||
|
||||
XmppRoom = (function() {
|
||||
function XmppRoom(client, name, nick, password) {
|
||||
this.roster = {};
|
||||
this._message_handlers = {};
|
||||
this._presence_handlers = {};
|
||||
this._roster_handlers = {};
|
||||
this._handler_ids = 0;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
XmppRoom.prototype.addHandler = function(handler_type, handler) {
|
||||
/* 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.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
XmppRoom.prototype.removeHandler = function(id) {
|
||||
/* 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
|
||||
*/
|
||||
delete this._presence_handlers[id];
|
||||
delete this._message_handlers[id];
|
||||
return delete this._roster_handlers[id];
|
||||
};
|
||||
|
||||
XmppRoom.prototype._addOccupant = function(data) {
|
||||
/* Creates and adds an Occupant to the Room Roster.
|
||||
* Parameters:
|
||||
* (Object) data - the data the Occupant is filled with
|
||||
* Returns:
|
||||
* occ - the created Occupant.
|
||||
*/
|
||||
var occ;
|
||||
occ = new Occupant(data, this);
|
||||
this.roster[occ.nick] = occ;
|
||||
return occ;
|
||||
};
|
||||
|
||||
XmppRoom.prototype._roomRosterHandler = function(pres) {
|
||||
/* The standard handler that managed the Room Roster.
|
||||
* Parameters:
|
||||
* (Object) pres - the presence stanza containing user information
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
XmppRoom._parsePresence = function(pres) {
|
||||
/* Parses a presence stanza into a map
|
||||
* Parameters:
|
||||
* (Object) pres - the presence stanza
|
||||
* Returns:
|
||||
* (Object) data - the data extracted from the presence stanza
|
||||
*/
|
||||
var $pres, data, i, j, children, item;
|
||||
$pres = $(pres);
|
||||
data = {};
|
||||
data.nick = Strophe.getResourceFromJid($pres.attr('from'));
|
||||
data.type = $pres.attr('type');
|
||||
data.states = [];
|
||||
for (i=0; i < $pres.children().length; i++) {
|
||||
child = $pres.children()[0];
|
||||
switch (child.nodeName) {
|
||||
case 'status':
|
||||
data.status = child.textContent || null;
|
||||
break;
|
||||
case 'show':
|
||||
data.show = child.textContent || null;
|
||||
break;
|
||||
case 'x':
|
||||
if ($(child).attr('xmlns') === Strophe.NS.MUC_USER) {
|
||||
children = $(child).children();
|
||||
for (j=0; j < children.length; j++) {
|
||||
item = children[0];
|
||||
switch (item.nodeName) {
|
||||
case "item":
|
||||
a = item.attributes;
|
||||
data.affiliation = $(item).attr('affiliation') || null;
|
||||
data.role = $(item).attr('role') || null;
|
||||
data.jid = $(item).attr('jid') || null;
|
||||
data.newnick = $(item).attr('nick') || null;
|
||||
break;
|
||||
case "status":
|
||||
if ($(item).attr('code')) {
|
||||
data.states.push($(item).attr('code'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}));
|
@ -1,443 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
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');
|
||||
Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
|
||||
},
|
||||
/** 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);
|
||||
return 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 (optional)
|
||||
* (String) nick (optional)
|
||||
*/
|
||||
subscribe: function(jid, message, nick) {
|
||||
var pres = $pres({to: jid, type: "subscribe"});
|
||||
if (message && message !== "") {
|
||||
pres.c("status").t(message);
|
||||
}
|
||||
if (nick && nick !== "") {
|
||||
pres.c('nick', {'xmlns': Strophe.NS.NICK}).t(nick);
|
||||
}
|
||||
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();
|
||||
}
|
||||
return 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;
|
||||
}
|
||||
}
|
||||
});
|
@ -1,66 +0,0 @@
|
||||
// Generated by CoffeeScript 1.3.3
|
||||
/*
|
||||
Plugin to implement the vCard extension.
|
||||
http://xmpp.org/extensions/xep-0054.html
|
||||
|
||||
Author: Nathan Zorn (nathan.zorn@gmail.com)
|
||||
CoffeeScript port: Andreas Guth (guth@dbis.rwth-aachen.de)
|
||||
*/
|
||||
|
||||
/* jslint configuration:
|
||||
*/
|
||||
|
||||
/* global document, window, setTimeout, clearTimeout, console,
|
||||
XMLHttpRequest, ActiveXObject,
|
||||
Base64, MD5,
|
||||
Strophe, $build, $msg, $iq, $pres
|
||||
*/
|
||||
|
||||
var buildIq;
|
||||
|
||||
buildIq = function(type, jid, vCardEl) {
|
||||
var iq;
|
||||
iq = $iq(jid ? {
|
||||
type: type,
|
||||
to: jid
|
||||
} : {
|
||||
type: type
|
||||
});
|
||||
iq.c("vCard", {
|
||||
xmlns: Strophe.NS.VCARD
|
||||
});
|
||||
if (vCardEl) {
|
||||
iq.cnode(vCardEl);
|
||||
}
|
||||
return iq;
|
||||
};
|
||||
|
||||
Strophe.addConnectionPlugin('vcard', {
|
||||
_connection: null,
|
||||
init: function(conn) {
|
||||
this._connection = conn;
|
||||
return Strophe.addNamespace('VCARD', 'vcard-temp');
|
||||
},
|
||||
/*Function
|
||||
Retrieve a vCard for a JID/Entity
|
||||
Parameters:
|
||||
(Function) handler_cb - The callback function used to handle the request.
|
||||
(String) jid - optional - The name of the entity to request the vCard
|
||||
If no jid is given, this function retrieves the current user's vcard.
|
||||
*/
|
||||
|
||||
get: function(handler_cb, jid, error_cb) {
|
||||
var iq;
|
||||
iq = buildIq("get", jid);
|
||||
return this._connection.sendIQ(iq, handler_cb, error_cb);
|
||||
},
|
||||
/* Function
|
||||
Set an entity's vCard.
|
||||
*/
|
||||
|
||||
set: function(handler_cb, vCardEl, jid, error_cb) {
|
||||
var iq;
|
||||
iq = buildIq("set", jid, vCardEl);
|
||||
return this._connection.sendIQ(iq, handler_cb, error_rb);
|
||||
}
|
||||
});
|
File diff suppressed because it is too large
Load Diff
20
converse.js
20
converse.js
@ -15,16 +15,16 @@
|
||||
require.config({
|
||||
paths: {
|
||||
"locales": "locale/locales",
|
||||
"sjcl": "Libraries/sjcl",
|
||||
"tinysort": "Libraries/jquery.tinysort",
|
||||
"underscore": "Libraries/underscore",
|
||||
"backbone": "Libraries/backbone",
|
||||
"localstorage": "Libraries/backbone.localStorage",
|
||||
"strophe": "Libraries/strophe",
|
||||
"strophe.muc": "Libraries/strophe.muc",
|
||||
"strophe.roster": "Libraries/strophe.roster",
|
||||
"strophe.vcard": "Libraries/strophe.vcard",
|
||||
"strophe.disco": "Libraries/strophe.disco"
|
||||
"sjcl": "components/sjcl/sjcl",
|
||||
"tinysort": "components/tinysort/src/jquery.tinysort",
|
||||
"underscore": "components/underscore/underscore",
|
||||
"backbone": "components/backbone/backbone",
|
||||
"localstorage": "components/backbone.localStorage/backbone.localStorage",
|
||||
"strophe": "components/strophe/strophe",
|
||||
"strophe.muc": "components/strophe.muc/index",
|
||||
"strophe.roster": "components/strophe.roster/index",
|
||||
"strophe.vcard": "components/strophe.vcard/index",
|
||||
"strophe.disco": "components/strophe.disco/index"
|
||||
},
|
||||
|
||||
// define module dependencies for modules not using define
|
||||
|
Loading…
Reference in New Issue
Block a user