react-tinymce-mention
Version:
@Mention functionality for TinyMCE, built with React and Redux.
1,784 lines (1,502 loc) • 1.07 MB
JavaScript
// 4.2.4 (2015-08-17)
/**
* Compiled inline version. (Library mode)
*/
/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
/*globals $code */
(function(exports, undefined) {
"use strict";
var modules = {};
function require(ids, callback) {
var module, defs = [];
for (var i = 0; i < ids.length; ++i) {
module = modules[ids[i]] || resolve(ids[i]);
if (!module) {
throw 'module definition dependecy not found: ' + ids[i];
}
defs.push(module);
}
callback.apply(null, defs);
}
function define(id, dependencies, definition) {
if (typeof id !== 'string') {
throw 'invalid module definition, module id must be defined and be a string';
}
if (dependencies === undefined) {
throw 'invalid module definition, dependencies must be specified';
}
if (definition === undefined) {
throw 'invalid module definition, definition function must be specified';
}
require(dependencies, function() {
modules[id] = definition.apply(null, arguments);
});
}
function defined(id) {
return !!modules[id];
}
function resolve(id) {
var target = exports;
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length; ++fi) {
if (!target[fragments[fi]]) {
return;
}
target = target[fragments[fi]];
}
return target;
}
function expose(ids) {
for (var i = 0; i < ids.length; i++) {
var target = exports;
var id = ids[i];
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length - 1; ++fi) {
if (target[fragments[fi]] === undefined) {
target[fragments[fi]] = {};
}
target = target[fragments[fi]];
}
target[fragments[fragments.length - 1]] = modules[id];
}
}
// Included from: js/tinymce/classes/dom/EventUtils.js
/**
* EventUtils.js
*
* Released under LGPL License.
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/*jshint loopfunc:true*/
/*eslint no-loop-func:0 */
/**
* This class wraps the browsers native event logic with more convenient methods.
*
* @class tinymce.dom.EventUtils
*/
define("tinymce/dom/EventUtils", [], function() {
"use strict";
var eventExpandoPrefix = "mce-data-";
var mouseEventRe = /^(?:mouse|contextmenu)|click/;
var deprecated = {keyLocation: 1, layerX: 1, layerY: 1, returnValue: 1, webkitMovementX: 1, webkitMovementY: 1};
/**
* Binds a native event to a callback on the speified target.
*/
function addEvent(target, name, callback, capture) {
if (target.addEventListener) {
target.addEventListener(name, callback, capture || false);
} else if (target.attachEvent) {
target.attachEvent('on' + name, callback);
}
}
/**
* Unbinds a native event callback on the specified target.
*/
function removeEvent(target, name, callback, capture) {
if (target.removeEventListener) {
target.removeEventListener(name, callback, capture || false);
} else if (target.detachEvent) {
target.detachEvent('on' + name, callback);
}
}
/**
* Normalizes a native event object or just adds the event specific methods on a custom event.
*/
function fix(originalEvent, data) {
var name, event = data || {}, undef;
// Dummy function that gets replaced on the delegation state functions
function returnFalse() {
return false;
}
// Dummy function that gets replaced on the delegation state functions
function returnTrue() {
return true;
}
// Copy all properties from the original event
for (name in originalEvent) {
// layerX/layerY is deprecated in Chrome and produces a warning
if (!deprecated[name]) {
event[name] = originalEvent[name];
}
}
// Normalize target IE uses srcElement
if (!event.target) {
event.target = event.srcElement || document;
}
// Calculate pageX/Y if missing and clientX/Y available
if (originalEvent && mouseEventRe.test(originalEvent.type) && originalEvent.pageX === undef && originalEvent.clientX !== undef) {
var eventDoc = event.target.ownerDocument || document;
var doc = eventDoc.documentElement;
var body = eventDoc.body;
event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0);
}
// Add preventDefault method
event.preventDefault = function() {
event.isDefaultPrevented = returnTrue;
// Execute preventDefault on the original event object
if (originalEvent) {
if (originalEvent.preventDefault) {
originalEvent.preventDefault();
} else {
originalEvent.returnValue = false; // IE
}
}
};
// Add stopPropagation
event.stopPropagation = function() {
event.isPropagationStopped = returnTrue;
// Execute stopPropagation on the original event object
if (originalEvent) {
if (originalEvent.stopPropagation) {
originalEvent.stopPropagation();
} else {
originalEvent.cancelBubble = true; // IE
}
}
};
// Add stopImmediatePropagation
event.stopImmediatePropagation = function() {
event.isImmediatePropagationStopped = returnTrue;
event.stopPropagation();
};
// Add event delegation states
if (!event.isDefaultPrevented) {
event.isDefaultPrevented = returnFalse;
event.isPropagationStopped = returnFalse;
event.isImmediatePropagationStopped = returnFalse;
}
// Add missing metaKey for IE 8
if (typeof event.metaKey == 'undefined') {
event.metaKey = false;
}
return event;
}
/**
* Bind a DOMContentLoaded event across browsers and executes the callback once the page DOM is initialized.
* It will also set/check the domLoaded state of the event_utils instance so ready isn't called multiple times.
*/
function bindOnReady(win, callback, eventUtils) {
var doc = win.document, event = {type: 'ready'};
if (eventUtils.domLoaded) {
callback(event);
return;
}
// Gets called when the DOM is ready
function readyHandler() {
if (!eventUtils.domLoaded) {
eventUtils.domLoaded = true;
callback(event);
}
}
function waitForDomLoaded() {
// Check complete or interactive state if there is a body
// element on some iframes IE 8 will produce a null body
if (doc.readyState === "complete" || (doc.readyState === "interactive" && doc.body)) {
removeEvent(doc, "readystatechange", waitForDomLoaded);
readyHandler();
}
}
function tryScroll() {
try {
// If IE is used, use the trick by Diego Perini licensed under MIT by request to the author.
// http://javascript.nwbox.com/IEContentLoaded/
doc.documentElement.doScroll("left");
} catch (ex) {
setTimeout(tryScroll, 0);
return;
}
readyHandler();
}
// Use W3C method
if (doc.addEventListener) {
if (doc.readyState === "complete") {
readyHandler();
} else {
addEvent(win, 'DOMContentLoaded', readyHandler);
}
} else {
// Use IE method
addEvent(doc, "readystatechange", waitForDomLoaded);
// Wait until we can scroll, when we can the DOM is initialized
if (doc.documentElement.doScroll && win.self === win.top) {
tryScroll();
}
}
// Fallback if any of the above methods should fail for some odd reason
addEvent(win, 'load', readyHandler);
}
/**
* This class enables you to bind/unbind native events to elements and normalize it's behavior across browsers.
*/
function EventUtils() {
var self = this, events = {}, count, expando, hasFocusIn, hasMouseEnterLeave, mouseEnterLeave;
expando = eventExpandoPrefix + (+new Date()).toString(32);
hasMouseEnterLeave = "onmouseenter" in document.documentElement;
hasFocusIn = "onfocusin" in document.documentElement;
mouseEnterLeave = {mouseenter: 'mouseover', mouseleave: 'mouseout'};
count = 1;
// State if the DOMContentLoaded was executed or not
self.domLoaded = false;
self.events = events;
/**
* Executes all event handler callbacks for a specific event.
*
* @private
* @param {Event} evt Event object.
* @param {String} id Expando id value to look for.
*/
function executeHandlers(evt, id) {
var callbackList, i, l, callback, container = events[id];
callbackList = container && container[evt.type];
if (callbackList) {
for (i = 0, l = callbackList.length; i < l; i++) {
callback = callbackList[i];
// Check if callback exists might be removed if a unbind is called inside the callback
if (callback && callback.func.call(callback.scope, evt) === false) {
evt.preventDefault();
}
// Should we stop propagation to immediate listeners
if (evt.isImmediatePropagationStopped()) {
return;
}
}
}
}
/**
* Binds a callback to an event on the specified target.
*
* @method bind
* @param {Object} target Target node/window or custom object.
* @param {String} names Name of the event to bind.
* @param {function} callback Callback function to execute when the event occurs.
* @param {Object} scope Scope to call the callback function on, defaults to target.
* @return {function} Callback function that got bound.
*/
self.bind = function(target, names, callback, scope) {
var id, callbackList, i, name, fakeName, nativeHandler, capture, win = window;
// Native event handler function patches the event and executes the callbacks for the expando
function defaultNativeHandler(evt) {
executeHandlers(fix(evt || win.event), id);
}
// Don't bind to text nodes or comments
if (!target || target.nodeType === 3 || target.nodeType === 8) {
return;
}
// Create or get events id for the target
if (!target[expando]) {
id = count++;
target[expando] = id;
events[id] = {};
} else {
id = target[expando];
}
// Setup the specified scope or use the target as a default
scope = scope || target;
// Split names and bind each event, enables you to bind multiple events with one call
names = names.split(' ');
i = names.length;
while (i--) {
name = names[i];
nativeHandler = defaultNativeHandler;
fakeName = capture = false;
// Use ready instead of DOMContentLoaded
if (name === "DOMContentLoaded") {
name = "ready";
}
// DOM is already ready
if (self.domLoaded && name === "ready" && target.readyState == 'complete') {
callback.call(scope, fix({type: name}));
continue;
}
// Handle mouseenter/mouseleaver
if (!hasMouseEnterLeave) {
fakeName = mouseEnterLeave[name];
if (fakeName) {
nativeHandler = function(evt) {
var current, related;
current = evt.currentTarget;
related = evt.relatedTarget;
// Check if related is inside the current target if it's not then the event should
// be ignored since it's a mouseover/mouseout inside the element
if (related && current.contains) {
// Use contains for performance
related = current.contains(related);
} else {
while (related && related !== current) {
related = related.parentNode;
}
}
// Fire fake event
if (!related) {
evt = fix(evt || win.event);
evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
evt.target = current;
executeHandlers(evt, id);
}
};
}
}
// Fake bubbeling of focusin/focusout
if (!hasFocusIn && (name === "focusin" || name === "focusout")) {
capture = true;
fakeName = name === "focusin" ? "focus" : "blur";
nativeHandler = function(evt) {
evt = fix(evt || win.event);
evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
executeHandlers(evt, id);
};
}
// Setup callback list and bind native event
callbackList = events[id][name];
if (!callbackList) {
events[id][name] = callbackList = [{func: callback, scope: scope}];
callbackList.fakeName = fakeName;
callbackList.capture = capture;
//callbackList.callback = callback;
// Add the nativeHandler to the callback list so that we can later unbind it
callbackList.nativeHandler = nativeHandler;
// Check if the target has native events support
if (name === "ready") {
bindOnReady(target, nativeHandler, self);
} else {
addEvent(target, fakeName || name, nativeHandler, capture);
}
} else {
if (name === "ready" && self.domLoaded) {
callback({type: name});
} else {
// If it already has an native handler then just push the callback
callbackList.push({func: callback, scope: scope});
}
}
}
target = callbackList = 0; // Clean memory for IE
return callback;
};
/**
* Unbinds the specified event by name, name and callback or all events on the target.
*
* @method unbind
* @param {Object} target Target node/window or custom object.
* @param {String} names Optional event name to unbind.
* @param {function} callback Optional callback function to unbind.
* @return {EventUtils} Event utils instance.
*/
self.unbind = function(target, names, callback) {
var id, callbackList, i, ci, name, eventMap;
// Don't bind to text nodes or comments
if (!target || target.nodeType === 3 || target.nodeType === 8) {
return self;
}
// Unbind event or events if the target has the expando
id = target[expando];
if (id) {
eventMap = events[id];
// Specific callback
if (names) {
names = names.split(' ');
i = names.length;
while (i--) {
name = names[i];
callbackList = eventMap[name];
// Unbind the event if it exists in the map
if (callbackList) {
// Remove specified callback
if (callback) {
ci = callbackList.length;
while (ci--) {
if (callbackList[ci].func === callback) {
var nativeHandler = callbackList.nativeHandler;
var fakeName = callbackList.fakeName, capture = callbackList.capture;
// Clone callbackList since unbind inside a callback would otherwise break the handlers loop
callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
callbackList.nativeHandler = nativeHandler;
callbackList.fakeName = fakeName;
callbackList.capture = capture;
eventMap[name] = callbackList;
}
}
}
// Remove all callbacks if there isn't a specified callback or there is no callbacks left
if (!callback || callbackList.length === 0) {
delete eventMap[name];
removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
}
}
}
} else {
// All events for a specific element
for (name in eventMap) {
callbackList = eventMap[name];
removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
}
eventMap = {};
}
// Check if object is empty, if it isn't then we won't remove the expando map
for (name in eventMap) {
return self;
}
// Delete event object
delete events[id];
// Remove expando from target
try {
// IE will fail here since it can't delete properties from window
delete target[expando];
} catch (ex) {
// IE will set it to null
target[expando] = null;
}
}
return self;
};
/**
* Fires the specified event on the specified target.
*
* @method fire
* @param {Object} target Target node/window or custom object.
* @param {String} name Event name to fire.
* @param {Object} args Optional arguments to send to the observers.
* @return {EventUtils} Event utils instance.
*/
self.fire = function(target, name, args) {
var id;
// Don't bind to text nodes or comments
if (!target || target.nodeType === 3 || target.nodeType === 8) {
return self;
}
// Build event object by patching the args
args = fix(null, args);
args.type = name;
args.target = target;
do {
// Found an expando that means there is listeners to execute
id = target[expando];
if (id) {
executeHandlers(args, id);
}
// Walk up the DOM
target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
} while (target && !args.isPropagationStopped());
return self;
};
/**
* Removes all bound event listeners for the specified target. This will also remove any bound
* listeners to child nodes within that target.
*
* @method clean
* @param {Object} target Target node/window object.
* @return {EventUtils} Event utils instance.
*/
self.clean = function(target) {
var i, children, unbind = self.unbind;
// Don't bind to text nodes or comments
if (!target || target.nodeType === 3 || target.nodeType === 8) {
return self;
}
// Unbind any element on the specificed target
if (target[expando]) {
unbind(target);
}
// Target doesn't have getElementsByTagName it's probably a window object then use it's document to find the children
if (!target.getElementsByTagName) {
target = target.document;
}
// Remove events from each child element
if (target && target.getElementsByTagName) {
unbind(target);
children = target.getElementsByTagName('*');
i = children.length;
while (i--) {
target = children[i];
if (target[expando]) {
unbind(target);
}
}
}
return self;
};
/**
* Destroys the event object. Call this on IE to remove memory leaks.
*/
self.destroy = function() {
events = {};
};
// Legacy function for canceling events
self.cancel = function(e) {
if (e) {
e.preventDefault();
e.stopImmediatePropagation();
}
return false;
};
}
EventUtils.Event = new EventUtils();
EventUtils.Event.bind(window, 'ready', function() {});
return EventUtils;
});
// Included from: js/tinymce/classes/dom/Sizzle.js
/**
* Sizzle.js
*
* Released under LGPL License.
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*
* @ignore-file
*/
/*jshint bitwise:false, expr:true, noempty:false, sub:true, eqnull:true, latedef:false, maxlen:255 */
/*eslint-disable */
/**
* Sizzle CSS Selector Engine v@VERSION
* http://sizzlejs.com/
*
* Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: @DATE
*/
define("tinymce/dom/Sizzle", [], function() {
var i,
support,
Expr,
getText,
isXML,
tokenize,
compile,
select,
outermostContext,
sortInput,
hasDuplicate,
// Local document vars
setDocument,
document,
docElem,
documentIsHTML,
rbuggyQSA,
rbuggyMatches,
matches,
contains,
// Instance-specific data
expando = "sizzle" + -(new Date()),
preferredDoc = window.document,
dirruns = 0,
done = 0,
classCache = createCache(),
tokenCache = createCache(),
compilerCache = createCache(),
sortOrder = function( a, b ) {
if ( a === b ) {
hasDuplicate = true;
}
return 0;
},
// General-purpose constants
strundefined = typeof undefined,
MAX_NEGATIVE = 1 << 31,
// Instance methods
hasOwn = ({}).hasOwnProperty,
arr = [],
pop = arr.pop,
push_native = arr.push,
push = arr.push,
slice = arr.slice,
// Use a stripped-down indexOf if we can't use a native one
indexOf = arr.indexOf || function( elem ) {
var i = 0,
len = this.length;
for ( ; i < len; i++ ) {
if ( this[i] === elem ) {
return i;
}
}
return -1;
},
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
// Regular expressions
// http://www.w3.org/TR/css3-selectors/#whitespace
whitespace = "[\\x20\\t\\r\\n\\f]",
// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
// Operator (capture 2)
"*([*^$|!~]?=)" + whitespace +
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
"*\\]",
pseudos = ":(" + identifier + ")(?:\\((" +
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
// 1. quoted (capture 3; capture 4 or capture 5)
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
// 2. simple (capture 6)
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
// 3. anything else (capture 2)
".*" +
")\\)|)",
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
rpseudo = new RegExp( pseudos ),
ridentifier = new RegExp( "^" + identifier + "$" ),
matchExpr = {
"ID": new RegExp( "^#(" + identifier + ")" ),
"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
"TAG": new RegExp( "^(" + identifier + "|[*])" ),
"ATTR": new RegExp( "^" + attributes ),
"PSEUDO": new RegExp( "^" + pseudos ),
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
// For use in libraries implementing .is()
// We use this for POS matching in `select`
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
},
rinputs = /^(?:input|select|textarea|button)$/i,
rheader = /^h\d$/i,
rnative = /^[^{]+\{\s*\[native \w/,
// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
rsibling = /[+~]/,
rescape = /'|\\/g,
// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
funescape = function( _, escaped, escapedWhitespace ) {
var high = "0x" + escaped - 0x10000;
// NaN means non-codepoint
// Support: Firefox<24
// Workaround erroneous numeric interpretation of +"0x"
return high !== high || escapedWhitespace ?
escaped :
high < 0 ?
// BMP codepoint
String.fromCharCode( high + 0x10000 ) :
// Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
};
// Optimize for push.apply( _, NodeList )
try {
push.apply(
(arr = slice.call( preferredDoc.childNodes )),
preferredDoc.childNodes
);
// Support: Android<4.0
// Detect silently failing push.apply
arr[ preferredDoc.childNodes.length ].nodeType;
} catch ( e ) {
push = { apply: arr.length ?
// Leverage slice if possible
function( target, els ) {
push_native.apply( target, slice.call(els) );
} :
// Support: IE<9
// Otherwise append directly
function( target, els ) {
var j = target.length,
i = 0;
// Can't trust NodeList.length
while ( (target[j++] = els[i++]) ) {}
target.length = j - 1;
}
};
}
function Sizzle( selector, context, results, seed ) {
var match, elem, m, nodeType,
// QSA vars
i, groups, old, nid, newContext, newSelector;
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
setDocument( context );
}
context = context || document;
results = results || [];
if ( !selector || typeof selector !== "string" ) {
return results;
}
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
return [];
}
if ( documentIsHTML && !seed ) {
// Shortcuts
if ( (match = rquickExpr.exec( selector )) ) {
// Speed-up: Sizzle("#ID")
if ( (m = match[1]) ) {
if ( nodeType === 9 ) {
elem = context.getElementById( m );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document (jQuery #6963)
if ( elem && elem.parentNode ) {
// Handle the case where IE, Opera, and Webkit return items
// by name instead of ID
if ( elem.id === m ) {
results.push( elem );
return results;
}
} else {
return results;
}
} else {
// Context is not a document
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
contains( context, elem ) && elem.id === m ) {
results.push( elem );
return results;
}
}
// Speed-up: Sizzle("TAG")
} else if ( match[2] ) {
push.apply( results, context.getElementsByTagName( selector ) );
return results;
// Speed-up: Sizzle(".CLASS")
} else if ( (m = match[3]) && support.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) );
return results;
}
}
// QSA path
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
nid = old = expando;
newContext = context;
newSelector = nodeType === 9 && selector;
// qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root
// and working up from there (Thanks to Andrew Dupont for the technique)
// IE 8 doesn't work on object elements
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
groups = tokenize( selector );
if ( (old = context.getAttribute("id")) ) {
nid = old.replace( rescape, "\\$&" );
} else {
context.setAttribute( "id", nid );
}
nid = "[id='" + nid + "'] ";
i = groups.length;
while ( i-- ) {
groups[i] = nid + toSelector( groups[i] );
}
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
newSelector = groups.join(",");
}
if ( newSelector ) {
try {
push.apply( results,
newContext.querySelectorAll( newSelector )
);
return results;
} catch(qsaError) {
} finally {
if ( !old ) {
context.removeAttribute("id");
}
}
}
}
}
// All others
return select( selector.replace( rtrim, "$1" ), context, results, seed );
}
/**
* Create key-value caches of limited size
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
* deleting the oldest entry
*/
function createCache() {
var keys = [];
function cache( key, value ) {
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
if ( keys.push( key + " " ) > Expr.cacheLength ) {
// Only keep the most recent entries
delete cache[ keys.shift() ];
}
return (cache[ key + " " ] = value);
}
return cache;
}
/**
* Mark a function for special use by Sizzle
* @param {Function} fn The function to mark
*/
function markFunction( fn ) {
fn[ expando ] = true;
return fn;
}
/**
* Support testing using an element
* @param {Function} fn Passed the created div and expects a boolean result
*/
function assert( fn ) {
var div = document.createElement("div");
try {
return !!fn( div );
} catch (e) {
return false;
} finally {
// Remove from its parent by default
if ( div.parentNode ) {
div.parentNode.removeChild( div );
}
// release memory in IE
div = null;
}
}
/**
* Adds the same handler for all of the specified attrs
* @param {String} attrs Pipe-separated list of attributes
* @param {Function} handler The method that will be applied
*/
function addHandle( attrs, handler ) {
var arr = attrs.split("|"),
i = attrs.length;
while ( i-- ) {
Expr.attrHandle[ arr[i] ] = handler;
}
}
/**
* Checks document order of two siblings
* @param {Element} a
* @param {Element} b
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
*/
function siblingCheck( a, b ) {
var cur = b && a,
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
( ~b.sourceIndex || MAX_NEGATIVE ) -
( ~a.sourceIndex || MAX_NEGATIVE );
// Use IE sourceIndex if available on both nodes
if ( diff ) {
return diff;
}
// Check if b follows a
if ( cur ) {
while ( (cur = cur.nextSibling) ) {
if ( cur === b ) {
return -1;
}
}
}
return a ? 1 : -1;
}
/**
* Returns a function to use in pseudos for input types
* @param {String} type
*/
function createInputPseudo( type ) {
return function( elem ) {
var name = elem.nodeName.toLowerCase();
return name === "input" && elem.type === type;
};
}
/**
* Returns a function to use in pseudos for buttons
* @param {String} type
*/
function createButtonPseudo( type ) {
return function( elem ) {
var name = elem.nodeName.toLowerCase();
return (name === "input" || name === "button") && elem.type === type;
};
}
/**
* Returns a function to use in pseudos for positionals
* @param {Function} fn
*/
function createPositionalPseudo( fn ) {
return markFunction(function( argument ) {
argument = +argument;
return markFunction(function( seed, matches ) {
var j,
matchIndexes = fn( [], seed.length, argument ),
i = matchIndexes.length;
// Match elements found at the specified indexes
while ( i-- ) {
if ( seed[ (j = matchIndexes[i]) ] ) {
seed[j] = !(matches[j] = seed[j]);
}
}
});
});
}
/**
* Checks a node for validity as a Sizzle context
* @param {Element|Object=} context
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/
function testContext( context ) {
return context && typeof context.getElementsByTagName !== strundefined && context;
}
// Expose support vars for convenience
support = Sizzle.support = {};
/**
* Detects XML nodes
* @param {Element|Object} elem An element or a document
* @returns {Boolean} True iff elem is a non-HTML XML node
*/
isXML = Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist
// (such as loading iframes in IE - #4833)
var documentElement = elem && (elem.ownerDocument || elem).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
};
/**
* Sets document-related variables once based on the current document
* @param {Element|Object} [doc] An element or document object to use to set the document
* @returns {Object} Returns the current document
*/
setDocument = Sizzle.setDocument = function( node ) {
var hasCompare,
doc = node ? node.ownerDocument || node : preferredDoc,
parent = doc.defaultView;
// If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
return document;
}
// Set our document
document = doc;
docElem = doc.documentElement;
// Support tests
documentIsHTML = !isXML( doc );
// Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
// IE6-8 do not support the defaultView property so parent will be undefined
if ( parent && parent !== parent.top ) {
// IE11 does not have attachEvent, so all must suffer
if ( parent.addEventListener ) {
parent.addEventListener( "unload", function() {
setDocument();
}, false );
} else if ( parent.attachEvent ) {
parent.attachEvent( "onunload", function() {
setDocument();
});
}
}
/* Attributes
---------------------------------------------------------------------- */
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
support.attributes = assert(function( div ) {
div.className = "i";
return !div.getAttribute("className");
});
/* getElement(s)By*
---------------------------------------------------------------------- */
// Check if getElementsByTagName("*") returns only elements
support.getElementsByTagName = assert(function( div ) {
div.appendChild( doc.createComment("") );
return !div.getElementsByTagName("*").length;
});
// Support: IE<9
support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
// Support: IE<10
// Check if getElementById returns elements by name
// The broken getElementById methods don't pick up programatically-set names,
// so use a roundabout getElementsByName test
support.getById = assert(function( div ) {
docElem.appendChild( div ).id = expando;
return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
});
// ID find and filter
if ( support.getById ) {
Expr.find["ID"] = function( id, context ) {
if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
var m = context.getElementById( id );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
return m && m.parentNode ? [ m ] : [];
}
};
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
return elem.getAttribute("id") === attrId;
};
};
} else {
// Support: IE6/7
// getElementById is not reliable as a find shortcut
delete Expr.find["ID"];
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
return node && node.value === attrId;
};
};
}
// Tag
Expr.find["TAG"] = support.getElementsByTagName ?
function( tag, context ) {
if ( typeof context.getElementsByTagName !== strundefined ) {
return context.getElementsByTagName( tag );
}
} :
function( tag, context ) {
var elem,
tmp = [],
i = 0,
results = context.getElementsByTagName( tag );
// Filter out possible comments
if ( tag === "*" ) {
while ( (elem = results[i++]) ) {
if ( elem.nodeType === 1 ) {
tmp.push( elem );
}
}
return tmp;
}
return results;
};
// Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
if ( documentIsHTML ) {
return context.getElementsByClassName( className );
}
};
/* QSA/matchesSelector
---------------------------------------------------------------------- */
// QSA and matchesSelector support
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
rbuggyMatches = [];
// qSa(:focus) reports false when true (Chrome 21)
// We allow this because of a bug in IE8/9 that throws an error
// whenever `document.activeElement` is accessed on an iframe
// So, we allow :focus to pass through QSA all the time to avoid the IE error
// See http://bugs.jquery.com/ticket/13378
rbuggyQSA = [];
if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
// Build QSA regex
// Regex strategy adopted from Diego Perini
assert(function( div ) {
// Select is set to empty string on purpose
// This is to test IE's treatment of not explicitly
// setting a boolean content attribute,
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
div.innerHTML = "<select msallowcapture=''><option selected=''></option></select>";
// Support: IE8, Opera 11-12.16
// Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( div.querySelectorAll("[msallowcapture^='']").length ) {
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
}
// Support: IE8
// Boolean attributes and "value" are not treated correctly
if ( !div.querySelectorAll("[selected]").length ) {
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
}
// Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests
if ( !div.querySelectorAll(":checked").length ) {
rbuggyQSA.push(":checked");
}
});
assert(function( div ) {
// Support: Windows 8 Native Apps
// The type and name attributes are restricted during .innerHTML assignment
var input = doc.createElement("input");
input.setAttribute( "type", "hidden" );
div.appendChild( input ).setAttribute( "name", "D" );
// Support: IE8
// Enforce case-sensitivity of name attribute
if ( div.querySelectorAll("[name=d]").length ) {
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
}
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
// IE8 throws error here and will not see later tests
if ( !div.querySelectorAll(":enabled").length ) {
rbuggyQSA.push( ":enabled", ":disabled" );
}
// Opera 10-11 does not throw on post-comma invalid pseudos
div.querySelectorAll("*,:x");
rbuggyQSA.push(",.*:");
});
}
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
docElem.webkitMatchesSelector ||
docElem.mozMatchesSelector ||
docElem.oMatchesSelector ||
docElem.msMatchesSelector) )) ) {
assert(function( div ) {
// Check to see if it's possible to do matchesSelector
// on a disconnected node (IE 9)
support.disconnectedMatch = matches.call( div, "div" );
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( div, "[s!='']:x" );
rbuggyMatches.push( "!=", pseudos );
});
}
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
/* Contains
---------------------------------------------------------------------- */
hasCompare = rnative.test( docElem.compareDocumentPosition );
// Element contains another
// Purposefully does not implement inclusive descendent
// As in, an element does not contain itself
contains = hasCompare || rnative.test( docElem.contains ) ?
function( a, b ) {
var adown = a.nodeType === 9 ? a.documentElement : a,
bup = b && b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && (
adown.contains ?
adown.contains( bup ) :
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
));
} :
function( a, b ) {
if ( b ) {
while ( (b = b.parentNode) ) {
if ( b === a ) {
return true;
}
}
}
return false;
};
/* Sorting
---------------------------------------------------------------------- */
// Document order sorting
sortOrder = hasCompare ?
function( a, b ) {
// Flag for duplicate removal
if ( a === b ) {
hasDuplicate = true;
return 0;
}
// Sort on method existence if only one input has compareDocumentPosition
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
if ( compare ) {
return compare;
}
// Calculate position if both inputs belong to the same document
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
a.compareDocumentPosition( b ) :
// Otherwise we know they are disconnected
1;
// Disconnected nodes
if ( compare & 1 ||
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
// Choose the first element that is related to our preferred document
if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
return -1;
}
if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
return 1;
}
// Maintain original order
return sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
0;
}
return compare & 4 ? -1 : 1;
} :
function( a, b ) {
// Exit early if the nodes are identical
if ( a === b ) {
hasDuplicate = true;
return 0;
}
var cur,
i = 0,
aup = a.parentNode,
bup = b.parentNode,
ap = [ a ],
bp = [ b ];
// Parentless nodes are either documents or disconnected
if ( !aup || !bup ) {
return a === doc ? -1 :
b === doc ? 1 :
aup ? -1 :
bup ? 1 :
sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
0;
// If the nodes are siblings, we can do a quick check
} else if ( aup === bup ) {
return siblingCheck( a, b );
}
// Otherwise we need full lists of their ancestors for comparison
cur = a;
while ( (cur = cur.parentNode) ) {
ap.unshift( cur );
}
cur = b;
while ( (cur = cur.parentNode) ) {
bp.unshift( cur );
}
// Walk down the tree looking for a discrepancy
while ( ap[i] === bp[i] ) {
i++;
}
return i ?
// Do a sibling check if the nodes have a common ancestor
siblingCheck( ap[i], bp[i] ) :
// Otherwise nodes in our document sort first
ap[i] === preferredDoc ? -1 :
bp[i] === preferredDoc ? 1 :
0;
};
return doc;
};
Sizzle.matches = function( expr, elements ) {
return Sizzle( expr, null, null, elements );
};
Sizzle.matchesSelector = function( elem, expr ) {
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
setDocument( elem );
}
// Make sure that attribute selectors are quoted
expr = expr.replace( rattributeQuotes, "='$1']" );
if ( support.matchesSelector && documentIsHTML &&
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
try {
var ret = matches.call( elem, expr );
// IE 9's matchesSelector returns false on disconnected nodes
if ( ret || support.disconnectedMatch ||
// As well, disconnected nodes are said to be in a document
// fragment in IE 9
elem.document && elem.document.nodeType !== 11 ) {
return ret;
}
} catch(e) {}
}
return Sizzle( expr, document, null, [ elem ] ).length > 0;
};
Sizzle.contains = function( context, elem ) {
// Set document vars if needed
if ( ( context.ownerDocument || context ) !== document ) {
setDocument( context );
}
return contains( context, elem );
};
Sizzle.attr = function( elem, name ) {
// Set document vars if needed
if ( ( elem.ownerDocument || elem ) !== document ) {
setDocument( elem );
}
var fn = Expr.attrHandle[ name.toLowerCase() ],
// Don't get fooled by Object.prototype properties (jQuery #13807)
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
fn( elem, name, !documentIsHTML ) :
undefined;
return val !== undefined ?
val :
support.attributes || !documentIsHTML ?
elem.getAttribute( name ) :
(val = elem.getAttributeNode(name)) && val.specified ?
val.value :
null;
};
Sizzle.error = function( msg ) {
throw new Error( "Syntax error, unrecognized expression: " + msg );
};
/**
* Document sorting and removing duplicates
* @param {ArrayLike} results
*/
Sizzle.uniqueSort = function( results ) {
var elem,
duplicates = [],
j = 0,
i = 0;
// Unless we *know* we can detect duplicates, assume their presence
hasDuplicate = !support.detectDuplicates;
sortInput = !support.sortStable && results.slice( 0 );
results.sort( sortOrder );
if ( hasDuplicate ) {
while ( (elem = results[i++]) ) {
if ( elem === results[ i ] ) {
j = duplicates.push( i );
}
}
while ( j-- ) {
results.splice( duplicates[ j ], 1 );
}
}
// Clear input after sorting to release objects
// See https://github.com/jquery/sizzle/pull/225
sortInput = null;
return results;
};
/**
* Utility function for retrieving the text value of an array of DOM nodes
* @param {Array|Element} elem
*/
getText = Sizzle.getText = function( elem ) {
var node,
ret = "",
i = 0,
nodeType = elem.nodeType;
if ( !nodeType ) {
// If no nodeType, this is expected to be an array
while ( (node = elem[i++]) ) {
// Do not traverse comment nodes
ret += getText( node );
}
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
// Use textContent for elements
// innerText usage removed for consistency of new lines (jQuery #11153)
if ( typeof elem.textContent === "string" ) {
return elem.textContent;
} else {
// Traverse its children
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
ret += getText( elem );
}
}
} else if ( nodeType === 3 || nodeType === 4 ) {
return elem.nodeValue;
}
// Do not include comment or processing instruction nodes
return ret;
};
Expr = Sizzle.selectors = {
// Can be adjusted by the user
cacheLength: 50,
createPseudo: markFunction,
match: matchExpr,
attrHandle: {},
find: {},
relative: {
">": { dir: "parentNode", first: true },
" ": { dir: "parentNode" },
"+": { dir: "previousSibling", first: true },
"~": { dir: "previousSibling" }
},
preFilter: {
"ATTR": function( match ) {
match[1] = match[1].replace( runescape, funescape );
// Move the given value to match[3] whether quoted or unquoted
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
if ( match[2] === "~=" ) {
match[3] = " " + match[3] + " ";
}
return match.slice( 0, 4 );
},
"CHILD": function( match ) {
/* matches from matchExpr["CHILD"]
1 type (only|nth|...)
2 what (child|of-type)
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
4 xn-component of xn+y argument ([+-]?\d*n|)
5 sign of xn-component
6 x of xn-component
7 sign of y-component
8 y of y-component
*/
match[1] = match[1].toLowerCase();
if ( match[1].slice( 0, 3 ) === "nth" ) {
// nth-* requires argument
if ( !match[3] ) {
Sizzle.error( match[0] );
}
// numeric x and y parameters for Expr.filter.CHILD
// remember that false/true cast respectively to 0/1
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
// other types prohibit arguments
} else if ( match[3] ) {
Sizzle.error( match[0] );
}
return match;
},
"PSEUDO": function( match ) {
var excess,
unquoted = !match[6] && match[2];
if ( matchExpr["CHILD"].test( match[0] ) ) {
return null;
}
// Accept quoted arguments as-is
if ( match[3] ) {
match[2] = match[4] || match[5] || "";
// Strip excess characters from unquoted arguments
} else if ( unquoted && rpseudo.test( unquoted ) &&
// Get excess from tokenize (recursively)
(excess = tokenize( unquoted, true )) &&
// advance to the next closing parenthesis
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
// excess is a negative index
match[0] = match[0].slice( 0, excess );
match[2] = unquoted.slice( 0, excess );
}
// Return only captures needed by the pseudo filter method (type and argument)
return match.slice( 0, 3 );
}
},
filter: {
"TAG": function( nodeNameSelector ) {
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
return nodeNameSelector === "*" ?
function() { return true; } :
function( elem ) {
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
};
},
"CLASS": function( className ) {
var pattern = classCache[ className + " " ];
return pattern ||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
classCache( className, function( elem ) {
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
});
},
"ATTR": function( name, operator, check ) {
return function( elem ) {
var result = Sizzle.attr( elem, name );
if ( result == null ) {
return operator === "!=";
}
if ( !operator ) {
return true;
}
result += "";
return operator === "=" ? result === check :
operator === "!=" ? result !== check :
operator === "^=" ? check && result.indexOf( check ) === 0 :
operator === "*=" ? check && result.indexOf( check ) > -1 :
operator === "$=" ? check && result.slice( -check.length ) === check :
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
false;
};
},
"CHILD": function( type, what, argument, first, last ) {
var simple = type.slice( 0, 3 ) !== "nth",
forward = type.slice( -4 ) !== "last",
ofType = what === "of-type";
return first === 1 && last === 0 ?
// Shortcut for :nth-*(n)
function( elem ) {
return !!elem.parentNode;
} :
function( elem, context, xml ) {
var cache, outerCache, node, diff, nodeIndex, start,
dir = simple !== forward ? "nextSibling" : "previousSibling",
parent = elem.parentNode,
name = ofType && elem.nodeName.toLowerCase(),
useCache = !xml && !ofType;
if ( parent ) {
// :(first|last|only)-(child|of-type)
if ( simple ) {
while ( dir ) {
node = elem;
while ( (node = node[ dir ]) ) {
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {