mirror of https://gitee.com/bigwinds/arangodb
344 lines
8.7 KiB
JavaScript
344 lines
8.7 KiB
JavaScript
var _ = require('underscore'),
|
|
utils = require('../utils'),
|
|
isTag = utils.isTag,
|
|
decode = utils.decode,
|
|
encode = utils.encode,
|
|
hasOwn = Object.prototype.hasOwnProperty,
|
|
rspace = /\s+/,
|
|
|
|
// Lookup table for coercing string data-* attributes to their corresponding
|
|
// JavaScript primitives
|
|
primitives = {
|
|
null: null,
|
|
true: true,
|
|
false: false
|
|
},
|
|
|
|
// Attributes that are booleans
|
|
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
|
|
// Matches strings that look like JSON objects or arrays
|
|
rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/;
|
|
|
|
|
|
var setAttr = function(el, name, value) {
|
|
if (typeof name === 'object') return _.extend(el.attribs, name);
|
|
|
|
if (value === null) {
|
|
removeAttribute(el, name);
|
|
} else {
|
|
el.attribs[name] = encode(value);
|
|
}
|
|
|
|
return el.attribs;
|
|
};
|
|
|
|
var attr = exports.attr = function(name, value) {
|
|
// Set the value (with attr map support)
|
|
if (typeof name === 'object' || value !== undefined) {
|
|
if (_.isFunction(value)) {
|
|
return this.each(function(i, el) {
|
|
setAttr(el, name, value.call(this, i, el.attribs[name]));
|
|
});
|
|
}
|
|
return this.each(function(i, el) {
|
|
el.attribs = setAttr(el, name, value);
|
|
});
|
|
}
|
|
|
|
var elem = this[0];
|
|
|
|
if (!elem || !isTag(elem)) return;
|
|
|
|
if (!elem.attribs) {
|
|
elem.attribs = {};
|
|
}
|
|
|
|
// Return the entire attribs object if no attribute specified
|
|
if (!name) {
|
|
for (var a in elem.attribs) {
|
|
elem.attribs[a] = decode(elem.attribs[a]);
|
|
}
|
|
return elem.attribs;
|
|
}
|
|
|
|
if (hasOwn.call(elem.attribs, name)) {
|
|
// Get the (decoded) attribute
|
|
return decode(elem.attribs[name]);
|
|
}
|
|
};
|
|
|
|
var setData = function(el, name, value) {
|
|
if (typeof name === 'object') return _.extend(el.data, name);
|
|
if (typeof name === 'string' && value !== undefined) {
|
|
el.data[name] = encode(value);
|
|
} else if (typeof name === 'object') {
|
|
// If its an object, loop through it
|
|
_.each(name, function(value, key) {
|
|
el.data[key] = encode(value);
|
|
});
|
|
}
|
|
|
|
return el.data;
|
|
};
|
|
|
|
var data = exports.data = function(name, value) {
|
|
var elem = this[0];
|
|
|
|
if (!elem || !isTag(elem)) return;
|
|
|
|
if (!elem.data) {
|
|
elem.data = {};
|
|
}
|
|
|
|
// Return the entire data object if no data specified
|
|
if (!name) {
|
|
|
|
_.each(elem.data, function(value, key) {
|
|
elem.data[key] = decode(value);
|
|
});
|
|
|
|
return elem.data;
|
|
}
|
|
|
|
// Set the value (with attr map support)
|
|
if (typeof name === 'object' || value !== undefined) {
|
|
this.each(function(i, el) {
|
|
el.data = setData(el, name, value);
|
|
});
|
|
return this;
|
|
} else if (hasOwn.call(elem.data, name)) {
|
|
// Get the (decoded) data
|
|
var val = decode(elem.data[name]);
|
|
|
|
if (hasOwn.call(primitives, val)) {
|
|
val = primitives[val];
|
|
} else if (val === String(Number(val))) {
|
|
val = Number(val);
|
|
} else if (rbrace.test(val)) {
|
|
val = JSON.parse(val);
|
|
}
|
|
|
|
return val;
|
|
} else if (typeof name === 'string' && value === undefined) {
|
|
return undefined;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Get the value of an element
|
|
*/
|
|
|
|
var val = exports.val = function(value) {
|
|
var querying = arguments.length === 0,
|
|
element = this[0];
|
|
|
|
if(!element) return;
|
|
|
|
switch (element.name) {
|
|
case 'textarea':
|
|
return querying ? this.text() : this.each(function() {
|
|
this.text(value);
|
|
});
|
|
case 'input':
|
|
switch (this.attr('type')) {
|
|
case 'radio':
|
|
var queryString = 'input[type=radio][name=' + this.attr('name') + ']:checked';
|
|
var parentEl, root;
|
|
|
|
// Go up until we hit a form or root
|
|
parentEl = this.closest('form');
|
|
if (parentEl.length === 0) {
|
|
root = (this.parents().last()[0] || this[0]).root;
|
|
parentEl = this._make(root);
|
|
}
|
|
|
|
if (querying) {
|
|
return parentEl.find(queryString).attr('value');
|
|
} else {
|
|
parentEl.find(':checked').removeAttr('checked');
|
|
parentEl.find('input[type=radio][value="' + value + '"]').attr('checked', '');
|
|
return this;
|
|
}
|
|
break;
|
|
default:
|
|
return querying ? this.attr('value') : this.each(function() {
|
|
this.attr('value', value);
|
|
});
|
|
}
|
|
return;
|
|
case 'select':
|
|
var option = this.find('option:selected'),
|
|
returnValue;
|
|
if (option === undefined) return undefined;
|
|
if (!querying) {
|
|
if (!this.attr().hasOwnProperty('multiple') && typeof value == 'object') {
|
|
return this;
|
|
}
|
|
if (typeof value != 'object') {
|
|
value = [value];
|
|
}
|
|
this.find('option').removeAttr('selected');
|
|
for (var i = 0; i < value.length; i++) {
|
|
this.find('option[value="' + value[i] + '"]').attr('selected', '');
|
|
}
|
|
return this;
|
|
}
|
|
returnValue = option.attr('value');
|
|
if (this.attr().hasOwnProperty('multiple')) {
|
|
returnValue = [];
|
|
option.each(function() {
|
|
returnValue.push(this.attr('value'));
|
|
});
|
|
}
|
|
return returnValue;
|
|
case 'option':
|
|
if (!querying) {
|
|
this.attr('value', value);
|
|
return this;
|
|
}
|
|
return this.attr('value');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Remove an attribute
|
|
*/
|
|
|
|
var removeAttribute = function(elem, name) {
|
|
if (!isTag(elem.type) || !elem.attribs || !Object.hasOwnProperty.call(elem.attribs, name))
|
|
return;
|
|
|
|
if (rboolean.test(elem.attribs[name]))
|
|
elem.attribs[name] = false;
|
|
else
|
|
delete elem.attribs[name];
|
|
};
|
|
|
|
|
|
var removeAttr = exports.removeAttr = function(name) {
|
|
this.each(function(i, elem) {
|
|
removeAttribute(elem, name);
|
|
});
|
|
|
|
return this;
|
|
};
|
|
|
|
var hasClass = exports.hasClass = function(className) {
|
|
return _.any(this, function(elem) {
|
|
var attrs = elem.attribs;
|
|
return attrs && _.contains((attrs['class'] || '').split(rspace), className);
|
|
});
|
|
};
|
|
|
|
var addClass = exports.addClass = function(value) {
|
|
// Support functions
|
|
if (_.isFunction(value)) {
|
|
this.each(function(i) {
|
|
var className = this.attr('class') || '';
|
|
this.addClass(value.call(this[0], i, className));
|
|
});
|
|
}
|
|
|
|
// Return if no value or not a string or function
|
|
if (!value || !_.isString(value)) return this;
|
|
|
|
var classNames = value.split(rspace),
|
|
numElements = this.length,
|
|
numClasses,
|
|
setClass,
|
|
$elem;
|
|
|
|
|
|
for (var i = 0; i < numElements; i++) {
|
|
$elem = this._make(this[i]);
|
|
// If selected element isnt a tag, move on
|
|
if (!isTag(this[i])) continue;
|
|
|
|
// If we don't already have classes
|
|
if (!$elem.attr('class')) {
|
|
$elem.attr('class', classNames.join(' ').trim());
|
|
} else {
|
|
setClass = ' ' + $elem.attr('class') + ' ';
|
|
numClasses = classNames.length;
|
|
|
|
// Check if class already exists
|
|
for (var j = 0; j < numClasses; j++) {
|
|
if (!~setClass.indexOf(' ' + classNames[j] + ' '))
|
|
setClass += classNames[j] + ' ';
|
|
}
|
|
|
|
$elem.attr('class', setClass.trim());
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
var removeClass = exports.removeClass = function(value) {
|
|
var split = function(className) {
|
|
return className ? className.trim().split(rspace) : [];
|
|
};
|
|
var classes, removeAll;
|
|
|
|
// Handle if value is a function
|
|
if (_.isFunction(value)) {
|
|
return this.each(function(i, el) {
|
|
this.removeClass(value.call(this[0], i, el.attribs['class'] || ''));
|
|
});
|
|
}
|
|
|
|
classes = split(value);
|
|
removeAll = arguments.length === 0;
|
|
|
|
return this.each(function(i, el) {
|
|
if (!isTag(el)) return;
|
|
el.attribs.class = removeAll ?
|
|
'' :
|
|
_.difference(split(el.attribs.class), classes).join(' ');
|
|
});
|
|
};
|
|
|
|
var toggleClass = exports.toggleClass = function(value, stateVal) {
|
|
// Support functions
|
|
if (_.isFunction(value)) {
|
|
return this.each(function(i, el) {
|
|
this.toggleClass(value.call(this, i, el.attribs['class'] || '', stateVal), stateVal);
|
|
});
|
|
}
|
|
|
|
// Return if no value or not a string or function
|
|
if (!value || !_.isString(value)) return this;
|
|
|
|
var classNames = value.split(rspace),
|
|
numClasses = classNames.length,
|
|
isBool = typeof stateVal === 'boolean',
|
|
numElements = this.length,
|
|
$elem,
|
|
state;
|
|
|
|
for (var i = 0; i < numElements; i++) {
|
|
$elem = this._make(this[i]);
|
|
// If selected element isnt a tag, move on
|
|
if (!isTag(this[i])) continue;
|
|
|
|
// Check if class already exists
|
|
for (var j = 0; j < numClasses; j++) {
|
|
// check each className given, space separated list
|
|
state = isBool ? stateVal : !$elem.hasClass(classNames[j]);
|
|
$elem[state ? 'addClass' : 'removeClass'](classNames[j]);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
var is = exports.is = function (selector) {
|
|
if (selector) {
|
|
return this.filter(selector).length > 0;
|
|
}
|
|
return false;
|
|
};
|
|
|