Created
July 22, 2016 12:15
-
-
Save N1kto/0646a9a06e2ddf1dec4ff54519cfbf30 to your computer and use it in GitHub Desktop.
[ROLLUP] Modules ordering issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var index = require("./index.js"), | |
DomHandler = index.DomHandler, | |
DomUtils = index.DomUtils; | |
//TODO: make this a streamable handler | |
function FeedHandler(callback, options){ | |
this.init(callback, options); | |
} | |
require("util").inherits(FeedHandler, DomHandler); | |
FeedHandler.prototype.init = DomHandler; | |
function getElements(what, where){ | |
return DomUtils.getElementsByTagName(what, where, true); | |
} | |
function getOneElement(what, where){ | |
return DomUtils.getElementsByTagName(what, where, true, 1)[0]; | |
} | |
function fetch(what, where, recurse){ | |
return DomUtils.getText( | |
DomUtils.getElementsByTagName(what, where, recurse, 1) | |
).trim(); | |
} | |
function addConditionally(obj, prop, what, where, recurse){ | |
var tmp = fetch(what, where, recurse); | |
if(tmp) obj[prop] = tmp; | |
} | |
var isValidFeed = function(value){ | |
return value === "rss" || value === "feed" || value === "rdf:RDF"; | |
}; | |
FeedHandler.prototype.onend = function(){ | |
var feed = {}, | |
feedRoot = getOneElement(isValidFeed, this.dom), | |
tmp, childs; | |
if(feedRoot){ | |
if(feedRoot.name === "feed"){ | |
childs = feedRoot.children; | |
feed.type = "atom"; | |
addConditionally(feed, "id", "id", childs); | |
addConditionally(feed, "title", "title", childs); | |
if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp; | |
addConditionally(feed, "description", "subtitle", childs); | |
if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp); | |
addConditionally(feed, "author", "email", childs, true); | |
feed.items = getElements("entry", childs).map(function(item){ | |
var entry = {}, tmp; | |
item = item.children; | |
addConditionally(entry, "id", "id", item); | |
addConditionally(entry, "title", "title", item); | |
if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp; | |
if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp; | |
if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp); | |
return entry; | |
}); | |
} else { | |
childs = getOneElement("channel", feedRoot.children).children; | |
feed.type = feedRoot.name.substr(0, 3); | |
feed.id = ""; | |
addConditionally(feed, "title", "title", childs); | |
addConditionally(feed, "link", "link", childs); | |
addConditionally(feed, "description", "description", childs); | |
if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp); | |
addConditionally(feed, "author", "managingEditor", childs, true); | |
feed.items = getElements("item", feedRoot.children).map(function(item){ | |
var entry = {}, tmp; | |
item = item.children; | |
addConditionally(entry, "id", "guid", item); | |
addConditionally(entry, "title", "title", item); | |
addConditionally(entry, "link", "link", item); | |
addConditionally(entry, "description", "description", item); | |
if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp); | |
return entry; | |
}); | |
} | |
} | |
this.dom = feed; | |
DomHandler.prototype._handleCallback.call( | |
this, feedRoot ? null : Error("couldn't find root of feed") | |
); | |
}; | |
module.exports = FeedHandler; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Parser = require("./Parser.js"), | |
DomHandler = require("domhandler"); | |
function defineProp(name, value){ | |
delete module.exports[name]; | |
module.exports[name] = value; | |
return value; | |
} | |
module.exports = { | |
Parser: Parser, | |
Tokenizer: require("./Tokenizer.js"), | |
ElementType: require("domelementtype"), | |
DomHandler: DomHandler, | |
get FeedHandler(){ | |
return defineProp("FeedHandler", require("./FeedHandler.js")); | |
}, | |
get Stream(){ | |
return defineProp("Stream", require("./Stream.js")); | |
}, | |
get WritableStream(){ | |
return defineProp("WritableStream", require("./WritableStream.js")); | |
}, | |
get ProxyHandler(){ | |
return defineProp("ProxyHandler", require("./ProxyHandler.js")); | |
}, | |
get DomUtils(){ | |
return defineProp("DomUtils", require("domutils")); | |
}, | |
get CollectingHandler(){ | |
return defineProp("CollectingHandler", require("./CollectingHandler.js")); | |
}, | |
// For legacy support | |
DefaultHandler: DomHandler, | |
get RssHandler(){ | |
return defineProp("RssHandler", this.FeedHandler); | |
}, | |
//helper methods | |
parseDOM: function(data, options){ | |
var handler = new DomHandler(options); | |
new Parser(handler, options).end(data); | |
return handler.dom; | |
}, | |
parseFeed: function(feed, options){ | |
var handler = new module.exports.FeedHandler(options); | |
new Parser(handler, options).end(feed); | |
return handler.dom; | |
}, | |
createDomStream: function(cb, options, elementCb){ | |
var handler = new DomHandler(cb, options, elementCb); | |
return new Parser(handler, options); | |
}, | |
// List of all events that the parser emits | |
EVENTS: { /* Format: eventname: number of arguments */ | |
attribute: 2, | |
cdatastart: 0, | |
cdataend: 0, | |
text: 1, | |
processinginstruction: 2, | |
comment: 1, | |
commentend: 0, | |
closetag: 1, | |
opentag: 2, | |
opentagname: 1, | |
error: 1, | |
end: 0 | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import babel from 'rollup-plugin-babel' | |
import json from 'rollup-plugin-json' | |
import commonjs from 'rollup-plugin-commonjs' | |
import nodeResolve from 'rollup-plugin-node-resolve' | |
import replace from 'rollup-plugin-replace' | |
import builtins from 'rollup-plugin-node-builtins' | |
const NODE_ENV = process.env.NODE_ENV || 'development' | |
export default { | |
entry: 'lib/index.js', | |
dest: './dist/slate.rollup.js', | |
moduleName: 'Slate', | |
exports: 'named', | |
format: 'iife', | |
plugins: [ | |
nodeResolve({ | |
jsnext: true, // Default: false | |
main: true, // Default: true | |
skip: [], // Default: [] | |
browser: true, // Default: false | |
extensions: [ '.js', '.json' ], // Default: ['.js'] | |
preferBuiltins: true // Default: true | |
}), | |
commonjs({ | |
include: 'node_modules/**', | |
ignoreGlobal: true, | |
namedExports: { | |
'node_modules/immutable/dist/immutable.js': [ | |
'Iterable', 'Seq', 'Collection', 'Map', 'OrderedMap', 'List', 'Stack', 'Set', | |
'OrderedSet', 'Record', 'Range', 'Repeat', 'is', 'fromJS' | |
], | |
'node_modules/esrever/esrever.js': [ 'reverse' ] | |
} | |
}), | |
babel({ | |
include: [ | |
'lib/**' | |
], | |
babelrc: false, | |
presets: ['react', 'es2015-rollup', 'stage-0'] | |
}), | |
builtins(), | |
json(), | |
replace({ | |
'process.env.NODE_ENV': JSON.stringify(NODE_ENV), | |
'process.browser': JSON.stringify(true) | |
}) | |
] | |
} |
This file has been truncated, but you can view the full file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (exports) { | |
'use strict'; | |
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {} | |
function interopDefault(ex) { | |
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex; | |
} | |
function createCommonjsModule(fn, module) { | |
return module = { exports: {} }, fn(module, module.exports), module.exports; | |
} | |
var uaParser = createCommonjsModule(function (module, exports) { | |
/** | |
* UAParser.js v0.7.10 | |
* Lightweight JavaScript-based User-Agent string parser | |
* https://github.com/faisalman/ua-parser-js | |
* | |
* Copyright © 2012-2015 Faisal Salman <[email protected]> | |
* Dual licensed under GPLv2 & MIT | |
*/ | |
(function (window, undefined) { | |
'use strict'; | |
////////////// | |
// Constants | |
///////////// | |
var LIBVERSION = '0.7.10', | |
EMPTY = '', | |
UNKNOWN = '?', | |
FUNC_TYPE = 'function', | |
UNDEF_TYPE = 'undefined', | |
OBJ_TYPE = 'object', | |
STR_TYPE = 'string', | |
MAJOR = 'major', // deprecated | |
MODEL = 'model', | |
NAME = 'name', | |
TYPE = 'type', | |
VENDOR = 'vendor', | |
VERSION = 'version', | |
ARCHITECTURE= 'architecture', | |
CONSOLE = 'console', | |
MOBILE = 'mobile', | |
TABLET = 'tablet', | |
SMARTTV = 'smarttv', | |
WEARABLE = 'wearable', | |
EMBEDDED = 'embedded'; | |
/////////// | |
// Helper | |
////////// | |
var util = { | |
extend : function (regexes, extensions) { | |
for (var i in extensions) { | |
if ("browser cpu device engine os".indexOf(i) !== -1 && extensions[i].length % 2 === 0) { | |
regexes[i] = extensions[i].concat(regexes[i]); | |
} | |
} | |
return regexes; | |
}, | |
has : function (str1, str2) { | |
if (typeof str1 === "string") { | |
return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; | |
} else { | |
return false; | |
} | |
}, | |
lowerize : function (str) { | |
return str.toLowerCase(); | |
}, | |
major : function (version) { | |
return typeof(version) === STR_TYPE ? version.split(".")[0] : undefined; | |
} | |
}; | |
/////////////// | |
// Map helper | |
////////////// | |
var mapper = { | |
rgx : function () { | |
var result, i = 0, j, k, p, q, matches, match, args = arguments; | |
// loop through all regexes maps | |
while (i < args.length && !matches) { | |
var regex = args[i], // even sequence (0,2,4,..) | |
props = args[i + 1]; // odd sequence (1,3,5,..) | |
// construct object barebones | |
if (typeof result === UNDEF_TYPE) { | |
result = {}; | |
for (p in props) { | |
if (props.hasOwnProperty(p)){ | |
q = props[p]; | |
if (typeof q === OBJ_TYPE) { | |
result[q[0]] = undefined; | |
} else { | |
result[q] = undefined; | |
} | |
} | |
} | |
} | |
// try matching uastring with regexes | |
j = k = 0; | |
while (j < regex.length && !matches) { | |
matches = regex[j++].exec(this.getUA()); | |
if (!!matches) { | |
for (p = 0; p < props.length; p++) { | |
match = matches[++k]; | |
q = props[p]; | |
// check if given property is actually array | |
if (typeof q === OBJ_TYPE && q.length > 0) { | |
if (q.length == 2) { | |
if (typeof q[1] == FUNC_TYPE) { | |
// assign modified match | |
result[q[0]] = q[1].call(this, match); | |
} else { | |
// assign given value, ignore regex match | |
result[q[0]] = q[1]; | |
} | |
} else if (q.length == 3) { | |
// check whether function or regex | |
if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { | |
// call function (usually string mapper) | |
result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; | |
} else { | |
// sanitize match using given regex | |
result[q[0]] = match ? match.replace(q[1], q[2]) : undefined; | |
} | |
} else if (q.length == 4) { | |
result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; | |
} | |
} else { | |
result[q] = match ? match : undefined; | |
} | |
} | |
} | |
} | |
i += 2; | |
} | |
return result; | |
}, | |
str : function (str, map) { | |
for (var i in map) { | |
// check if array | |
if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { | |
for (var j = 0; j < map[i].length; j++) { | |
if (util.has(map[i][j], str)) { | |
return (i === UNKNOWN) ? undefined : i; | |
} | |
} | |
} else if (util.has(map[i], str)) { | |
return (i === UNKNOWN) ? undefined : i; | |
} | |
} | |
return str; | |
} | |
}; | |
/////////////// | |
// String map | |
////////////// | |
var maps = { | |
browser : { | |
oldsafari : { | |
version : { | |
'1.0' : '/8', | |
'1.2' : '/1', | |
'1.3' : '/3', | |
'2.0' : '/412', | |
'2.0.2' : '/416', | |
'2.0.3' : '/417', | |
'2.0.4' : '/419', | |
'?' : '/' | |
} | |
} | |
}, | |
device : { | |
amazon : { | |
model : { | |
'Fire Phone' : ['SD', 'KF'] | |
} | |
}, | |
sprint : { | |
model : { | |
'Evo Shift 4G' : '7373KT' | |
}, | |
vendor : { | |
'HTC' : 'APA', | |
'Sprint' : 'Sprint' | |
} | |
} | |
}, | |
os : { | |
windows : { | |
version : { | |
'ME' : '4.90', | |
'NT 3.11' : 'NT3.51', | |
'NT 4.0' : 'NT4.0', | |
'2000' : 'NT 5.0', | |
'XP' : ['NT 5.1', 'NT 5.2'], | |
'Vista' : 'NT 6.0', | |
'7' : 'NT 6.1', | |
'8' : 'NT 6.2', | |
'8.1' : 'NT 6.3', | |
'10' : ['NT 6.4', 'NT 10.0'], | |
'RT' : 'ARM' | |
} | |
} | |
} | |
}; | |
////////////// | |
// Regex map | |
///////////// | |
var regexes = { | |
browser : [[ | |
// Presto based | |
/(opera\smini)\/([\w\.-]+)/i, // Opera Mini | |
/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet | |
/(opera).+version\/([\w\.]+)/i, // Opera > 9.80 | |
/(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80 | |
], [NAME, VERSION], [ | |
/\s(opr)\/([\w\.]+)/i // Opera Webkit | |
], [[NAME, 'Opera'], VERSION], [ | |
// Mixed | |
/(kindle)\/([\w\.]+)/i, // Kindle | |
/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i, | |
// Lunascape/Maxthon/Netfront/Jasmine/Blazer | |
// Trident based | |
/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i, | |
// Avant/IEMobile/SlimBrowser/Baidu | |
/(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer | |
// Webkit/KHTML based | |
/(rekonq)\/([\w\.]+)*/i, // Rekonq | |
/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs)\/([\w\.-]+)/i | |
// Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS | |
], [NAME, VERSION], [ | |
/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11 | |
], [[NAME, 'IE'], VERSION], [ | |
/(edge)\/((\d+)?[\w\.]+)/i // Microsoft Edge | |
], [NAME, VERSION], [ | |
/(yabrowser)\/([\w\.]+)/i // Yandex | |
], [[NAME, 'Yandex'], VERSION], [ | |
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon | |
], [[NAME, /_/g, ' '], VERSION], [ | |
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i, | |
// Chrome/OmniWeb/Arora/Tizen/Nokia | |
/(qqbrowser)[\/\s]?([\w\.]+)/i | |
// QQBrowser | |
], [NAME, VERSION], [ | |
/(uc\s?browser)[\/\s]?([\w\.]+)/i, | |
/ucweb.+(ucbrowser)[\/\s]?([\w\.]+)/i, | |
/JUC.+(ucweb)[\/\s]?([\w\.]+)/i | |
// UCBrowser | |
], [[NAME, 'UCBrowser'], VERSION], [ | |
/(dolfin)\/([\w\.]+)/i // Dolphin | |
], [[NAME, 'Dolphin'], VERSION], [ | |
/((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS | |
], [[NAME, 'Chrome'], VERSION], [ | |
/XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser | |
], [VERSION, [NAME, 'MIUI Browser']], [ | |
/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser | |
], [VERSION, [NAME, 'Android Browser']], [ | |
/FBAV\/([\w\.]+);/i // Facebook App for iOS | |
], [VERSION, [NAME, 'Facebook']], [ | |
/fxios\/([\w\.-]+)/i // Firefox for iOS | |
], [VERSION, [NAME, 'Firefox']], [ | |
/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari | |
], [VERSION, [NAME, 'Mobile Safari']], [ | |
/version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile | |
], [VERSION, NAME], [ | |
/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0 | |
], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [ | |
/(konqueror)\/([\w\.]+)/i, // Konqueror | |
/(webkit|khtml)\/([\w\.]+)/i | |
], [NAME, VERSION], [ | |
// Gecko based | |
/(navigator|netscape)\/([\w\.-]+)/i // Netscape | |
], [[NAME, 'Netscape'], VERSION], [ | |
/(swiftfox)/i, // Swiftfox | |
/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i, | |
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror | |
/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i, | |
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix | |
/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla | |
// Other | |
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i, | |
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir | |
/(links)\s\(([\w\.]+)/i, // Links | |
/(gobrowser)\/?([\w\.]+)*/i, // GoBrowser | |
/(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser | |
/(mosaic)[\/\s]([\w\.]+)/i // Mosaic | |
], [NAME, VERSION] | |
/* ///////////////////// | |
// Media players BEGIN | |
//////////////////////// | |
, [ | |
/(apple(?:coremedia|))\/((\d+)[\w\._]+)/i, // Generic Apple CoreMedia | |
/(coremedia) v((\d+)[\w\._]+)/i | |
], [NAME, VERSION], [ | |
/(aqualung|lyssna|bsplayer)\/((\d+)?[\w\.-]+)/i // Aqualung/Lyssna/BSPlayer | |
], [NAME, VERSION], [ | |
/(ares|ossproxy)\s((\d+)[\w\.-]+)/i // Ares/OSSProxy | |
], [NAME, VERSION], [ | |
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/((\d+)[\w\.-]+)/i, | |
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC | |
// NSPlayer/PSP-InternetRadioPlayer/Videos | |
/(clementine|music player daemon)\s((\d+)[\w\.-]+)/i, // Clementine/MPD | |
/(lg player|nexplayer)\s((\d+)[\d\.]+)/i, | |
/player\/(nexplayer|lg player)\s((\d+)[\w\.-]+)/i // NexPlayer/LG Player | |
], [NAME, VERSION], [ | |
/(nexplayer)\s((\d+)[\w\.-]+)/i // Nexplayer | |
], [NAME, VERSION], [ | |
/(flrp)\/((\d+)[\w\.-]+)/i // Flip Player | |
], [[NAME, 'Flip Player'], VERSION], [ | |
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i | |
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit | |
], [NAME], [ | |
/(gstreamer) souphttpsrc (?:\([^\)]+\)){0,1} libsoup\/((\d+)[\w\.-]+)/i | |
// Gstreamer | |
], [NAME, VERSION], [ | |
/(htc streaming player)\s[\w_]+\s\/\s((\d+)[\d\.]+)/i, // HTC Streaming Player | |
/(java|python-urllib|python-requests|wget|libcurl)\/((\d+)[\w\.-_]+)/i, | |
// Java/urllib/requests/wget/cURL | |
/(lavf)((\d+)[\d\.]+)/i // Lavf (FFMPEG) | |
], [NAME, VERSION], [ | |
/(htc_one_s)\/((\d+)[\d\.]+)/i // HTC One S | |
], [[NAME, /_/g, ' '], VERSION], [ | |
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+){0,1})/i | |
// MPlayer SVN | |
], [NAME, VERSION], [ | |
/(mplayer)(?:\s|\/|[unkow-]+)((\d+)[\w\.-]+)/i // MPlayer | |
], [NAME, VERSION], [ | |
/(mplayer)/i, // MPlayer (no other info) | |
/(yourmuze)/i, // YourMuze | |
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime | |
], [NAME], [ | |
/(nero (?:home|scout))\/((\d+)[\w\.-]+)/i // Nero Home/Nero Scout | |
], [NAME, VERSION], [ | |
/(nokia\d+)\/((\d+)[\w\.-]+)/i // Nokia | |
], [NAME, VERSION], [ | |
/\s(songbird)\/((\d+)[\w\.-]+)/i // Songbird/Philips-Songbird | |
], [NAME, VERSION], [ | |
/(winamp)3 version ((\d+)[\w\.-]+)/i, // Winamp | |
/(winamp)\s((\d+)[\w\.-]+)/i, | |
/(winamp)mpeg\/((\d+)[\w\.-]+)/i | |
], [NAME, VERSION], [ | |
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info) | |
// inlight radio | |
], [NAME], [ | |
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/((\d+)[\w\.-]+)/i | |
// QuickTime/RealMedia/RadioApp/RadioClientApplication/ | |
// SoundTap/Totem/Stagefright/Streamium | |
], [NAME, VERSION], [ | |
/(smp)((\d+)[\d\.]+)/i // SMP | |
], [NAME, VERSION], [ | |
/(vlc) media player - version ((\d+)[\w\.]+)/i, // VLC Videolan | |
/(vlc)\/((\d+)[\w\.-]+)/i, | |
/(xbmc|gvfs|xine|xmms|irapp)\/((\d+)[\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp | |
/(foobar2000)\/((\d+)[\d\.]+)/i, // Foobar2000 | |
/(itunes)\/((\d+)[\d\.]+)/i // iTunes | |
], [NAME, VERSION], [ | |
/(wmplayer)\/((\d+)[\w\.-]+)/i, // Windows Media Player | |
/(windows-media-player)\/((\d+)[\w\.-]+)/i | |
], [[NAME, /-/g, ' '], VERSION], [ | |
/windows\/((\d+)[\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i | |
// Windows Media Server | |
], [VERSION, [NAME, 'Windows']], [ | |
/(com\.riseupradioalarm)\/((\d+)[\d\.]*)/i // RiseUP Radio Alarm | |
], [NAME, VERSION], [ | |
/(rad.io)\s((\d+)[\d\.]+)/i, // Rad.io | |
/(radio.(?:de|at|fr))\s((\d+)[\d\.]+)/i | |
], [[NAME, 'rad.io'], VERSION] | |
////////////////////// | |
// Media players END | |
////////////////////*/ | |
], | |
cpu : [[ | |
/(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i // AMD64 | |
], [[ARCHITECTURE, 'amd64']], [ | |
/(ia32(?=;))/i // IA32 (quicktime) | |
], [[ARCHITECTURE, util.lowerize]], [ | |
/((?:i[346]|x)86)[;\)]/i // IA32 | |
], [[ARCHITECTURE, 'ia32']], [ | |
// PocketPC mistakenly identified as PowerPC | |
/windows\s(ce|mobile);\sppc;/i | |
], [[ARCHITECTURE, 'arm']], [ | |
/((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i // PowerPC | |
], [[ARCHITECTURE, /ower/, '', util.lowerize]], [ | |
/(sun4\w)[;\)]/i // SPARC | |
], [[ARCHITECTURE, 'sparc']], [ | |
/((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i | |
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC | |
], [[ARCHITECTURE, util.lowerize]] | |
], | |
device : [[ | |
/\((ipad|playbook);[\w\s\);-]+(rim|apple)/i // iPad/PlayBook | |
], [MODEL, VENDOR, [TYPE, TABLET]], [ | |
/applecoremedia\/[\w\.]+ \((ipad)/ // iPad | |
], [MODEL, [VENDOR, 'Apple'], [TYPE, TABLET]], [ | |
/(apple\s{0,1}tv)/i // Apple TV | |
], [[MODEL, 'Apple TV'], [VENDOR, 'Apple']], [ | |
/(archos)\s(gamepad2?)/i, // Archos | |
/(hp).+(touchpad)/i, // HP TouchPad | |
/(kindle)\/([\w\.]+)/i, // Kindle | |
/\s(nook)[\w\s]+build\/(\w+)/i, // Nook | |
/(dell)\s(strea[kpr\s\d]*[\dko])/i // Dell Streak | |
], [VENDOR, MODEL, [TYPE, TABLET]], [ | |
/(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i // Kindle Fire HD | |
], [MODEL, [VENDOR, 'Amazon'], [TYPE, TABLET]], [ | |
/(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i // Fire Phone | |
], [[MODEL, mapper.str, maps.device.amazon.model], [VENDOR, 'Amazon'], [TYPE, MOBILE]], [ | |
/\((ip[honed|\s\w*]+);.+(apple)/i // iPod/iPhone | |
], [MODEL, VENDOR, [TYPE, MOBILE]], [ | |
/\((ip[honed|\s\w*]+);/i // iPod/iPhone | |
], [MODEL, [VENDOR, 'Apple'], [TYPE, MOBILE]], [ | |
/(blackberry)[\s-]?(\w+)/i, // BlackBerry | |
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i, | |
// BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Huawei/Meizu/Motorola/Polytron | |
/(hp)\s([\w\s]+\w)/i, // HP iPAQ | |
/(asus)-?(\w+)/i // Asus | |
], [VENDOR, MODEL, [TYPE, MOBILE]], [ | |
/\(bb10;\s(\w+)/i // BlackBerry 10 | |
], [MODEL, [VENDOR, 'BlackBerry'], [TYPE, MOBILE]], [ | |
// Asus Tablets | |
/android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i | |
], [MODEL, [VENDOR, 'Asus'], [TYPE, TABLET]], [ | |
/(sony)\s(tablet\s[ps])\sbuild\//i, // Sony | |
/(sony)?(?:sgp.+)\sbuild\//i | |
], [[VENDOR, 'Sony'], [MODEL, 'Xperia Tablet'], [TYPE, TABLET]], [ | |
/(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i | |
], [[VENDOR, 'Sony'], [MODEL, 'Xperia Phone'], [TYPE, MOBILE]], [ | |
/\s(ouya)\s/i, // Ouya | |
/(nintendo)\s([wids3u]+)/i // Nintendo | |
], [VENDOR, MODEL, [TYPE, CONSOLE]], [ | |
/android.+;\s(shield)\sbuild/i // Nvidia | |
], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [ | |
/(playstation\s[34portablevi]+)/i // Playstation | |
], [MODEL, [VENDOR, 'Sony'], [TYPE, CONSOLE]], [ | |
/(sprint\s(\w+))/i // Sprint Phones | |
], [[VENDOR, mapper.str, maps.device.sprint.vendor], [MODEL, mapper.str, maps.device.sprint.model], [TYPE, MOBILE]], [ | |
/(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i // Lenovo tablets | |
], [VENDOR, MODEL, [TYPE, TABLET]], [ | |
/(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i, // HTC | |
/(zte)-(\w+)*/i, // ZTE | |
/(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i | |
// Alcatel/GeeksPhone/Huawei/Lenovo/Nexian/Panasonic/Sony | |
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [ | |
/(nexus\s9)/i // HTC Nexus 9 | |
], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [ | |
/[\s\(;](xbox(?:\sone)?)[\s\);]/i // Microsoft Xbox | |
], [MODEL, [VENDOR, 'Microsoft'], [TYPE, CONSOLE]], [ | |
/(kin\.[onetw]{3})/i // Microsoft Kin | |
], [[MODEL, /\./g, ' '], [VENDOR, 'Microsoft'], [TYPE, MOBILE]], [ | |
// Motorola | |
/\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i, | |
/mot[\s-]?(\w+)*/i, | |
/(XT\d{3,4}) build\//i, | |
/(nexus\s[6])/i | |
], [MODEL, [VENDOR, 'Motorola'], [TYPE, MOBILE]], [ | |
/android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i | |
], [MODEL, [VENDOR, 'Motorola'], [TYPE, TABLET]], [ | |
/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i, | |
/((SM-T\w+))/i | |
], [[VENDOR, 'Samsung'], MODEL, [TYPE, TABLET]], [ // Samsung | |
/((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i, | |
/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i, | |
/sec-((sgh\w+))/i | |
], [[VENDOR, 'Samsung'], MODEL, [TYPE, MOBILE]], [ | |
/(samsung);smarttv/i | |
], [VENDOR, MODEL, [TYPE, SMARTTV]], [ | |
/\(dtv[\);].+(aquos)/i // Sharp | |
], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [ | |
/sie-(\w+)*/i // Siemens | |
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [ | |
/(maemo|nokia).*(n900|lumia\s\d+)/i, // Nokia | |
/(nokia)[\s_-]?([\w-]+)*/i | |
], [[VENDOR, 'Nokia'], MODEL, [TYPE, MOBILE]], [ | |
/android\s3\.[\s\w;-]{10}(a\d{3})/i // Acer | |
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [ | |
/android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i // LG Tablet | |
], [[VENDOR, 'LG'], MODEL, [TYPE, TABLET]], [ | |
/(lg) netcast\.tv/i // LG SmartTV | |
], [VENDOR, MODEL, [TYPE, SMARTTV]], [ | |
/(nexus\s[45])/i, // LG | |
/lg[e;\s\/-]+(\w+)*/i | |
], [MODEL, [VENDOR, 'LG'], [TYPE, MOBILE]], [ | |
/android.+(ideatab[a-z0-9\-\s]+)/i // Lenovo | |
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [ | |
/linux;.+((jolla));/i // Jolla | |
], [VENDOR, MODEL, [TYPE, MOBILE]], [ | |
/((pebble))app\/[\d\.]+\s/i // Pebble | |
], [VENDOR, MODEL, [TYPE, WEARABLE]], [ | |
/android.+;\s(glass)\s\d/i // Google Glass | |
], [MODEL, [VENDOR, 'Google'], [TYPE, WEARABLE]], [ | |
/android.+(\w+)\s+build\/hm\1/i, // Xiaomi Hongmi 'numeric' models | |
/android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i, // Xiaomi Hongmi | |
/android.+(mi[\s\-_]*(?:one|one[\s_]plus)?[\s_]*(?:\d\w)?)\s+build/i // Xiaomi Mi | |
], [[MODEL, /_/g, ' '], [VENDOR, 'Xiaomi'], [TYPE, MOBILE]], [ | |
/\s(tablet)[;\/\s]/i, // Unidentifiable Tablet | |
/\s(mobile)[;\/\s]/i // Unidentifiable Mobile | |
], [[TYPE, util.lowerize], VENDOR, MODEL] | |
/*////////////////////////// | |
// TODO: move to string map | |
//////////////////////////// | |
/(C6603)/i // Sony Xperia Z C6603 | |
], [[MODEL, 'Xperia Z C6603'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ | |
/(C6903)/i // Sony Xperia Z 1 | |
], [[MODEL, 'Xperia Z 1'], [VENDOR, 'Sony'], [TYPE, MOBILE]], [ | |
/(SM-G900[F|H])/i // Samsung Galaxy S5 | |
], [[MODEL, 'Galaxy S5'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ | |
/(SM-G7102)/i // Samsung Galaxy Grand 2 | |
], [[MODEL, 'Galaxy Grand 2'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ | |
/(SM-G530H)/i // Samsung Galaxy Grand Prime | |
], [[MODEL, 'Galaxy Grand Prime'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ | |
/(SM-G313HZ)/i // Samsung Galaxy V | |
], [[MODEL, 'Galaxy V'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ | |
/(SM-T805)/i // Samsung Galaxy Tab S 10.5 | |
], [[MODEL, 'Galaxy Tab S 10.5'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ | |
/(SM-G800F)/i // Samsung Galaxy S5 Mini | |
], [[MODEL, 'Galaxy S5 Mini'], [VENDOR, 'Samsung'], [TYPE, MOBILE]], [ | |
/(SM-T311)/i // Samsung Galaxy Tab 3 8.0 | |
], [[MODEL, 'Galaxy Tab 3 8.0'], [VENDOR, 'Samsung'], [TYPE, TABLET]], [ | |
/(R1001)/i // Oppo R1001 | |
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [ | |
/(X9006)/i // Oppo Find 7a | |
], [[MODEL, 'Find 7a'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ | |
/(R2001)/i // Oppo YOYO R2001 | |
], [[MODEL, 'Yoyo R2001'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ | |
/(R815)/i // Oppo Clover R815 | |
], [[MODEL, 'Clover R815'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ | |
/(U707)/i // Oppo Find Way S | |
], [[MODEL, 'Find Way S'], [VENDOR, 'Oppo'], [TYPE, MOBILE]], [ | |
/(T3C)/i // Advan Vandroid T3C | |
], [MODEL, [VENDOR, 'Advan'], [TYPE, TABLET]], [ | |
/(ADVAN T1J\+)/i // Advan Vandroid T1J+ | |
], [[MODEL, 'Vandroid T1J+'], [VENDOR, 'Advan'], [TYPE, TABLET]], [ | |
/(ADVAN S4A)/i // Advan Vandroid S4A | |
], [[MODEL, 'Vandroid S4A'], [VENDOR, 'Advan'], [TYPE, MOBILE]], [ | |
/(V972M)/i // ZTE V972M | |
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [ | |
/(i-mobile)\s(IQ\s[\d\.]+)/i // i-mobile IQ | |
], [VENDOR, MODEL, [TYPE, MOBILE]], [ | |
/(IQ6.3)/i // i-mobile IQ IQ 6.3 | |
], [[MODEL, 'IQ 6.3'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ | |
/(i-mobile)\s(i-style\s[\d\.]+)/i // i-mobile i-STYLE | |
], [VENDOR, MODEL, [TYPE, MOBILE]], [ | |
/(i-STYLE2.1)/i // i-mobile i-STYLE 2.1 | |
], [[MODEL, 'i-STYLE 2.1'], [VENDOR, 'i-mobile'], [TYPE, MOBILE]], [ | |
/(mobiistar touch LAI 512)/i // mobiistar touch LAI 512 | |
], [[MODEL, 'Touch LAI 512'], [VENDOR, 'mobiistar'], [TYPE, MOBILE]], [ | |
///////////// | |
// END TODO | |
///////////*/ | |
], | |
engine : [[ | |
/windows.+\sedge\/([\w\.]+)/i // EdgeHTML | |
], [VERSION, [NAME, 'EdgeHTML']], [ | |
/(presto)\/([\w\.]+)/i, // Presto | |
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m | |
/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links | |
/(icab)[\/\s]([23]\.[\d\.]+)/i // iCab | |
], [NAME, VERSION], [ | |
/rv\:([\w\.]+).*(gecko)/i // Gecko | |
], [VERSION, NAME] | |
], | |
os : [[ | |
// Windows based | |
/microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes) | |
], [NAME, VERSION], [ | |
/(windows)\snt\s6\.2;\s(arm)/i, // Windows RT | |
/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i | |
], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ | |
/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i | |
], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ | |
// Mobile/Embedded OS | |
/\((bb)(10);/i // BlackBerry 10 | |
], [[NAME, 'BlackBerry'], VERSION], [ | |
/(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry | |
/(tizen)[\/\s]([\w\.]+)/i, // Tizen | |
/(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i, | |
// Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki | |
/linux;.+(sailfish);/i // Sailfish OS | |
], [NAME, VERSION], [ | |
/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian | |
], [[NAME, 'Symbian'], VERSION], [ | |
/\((series40);/i // Series 40 | |
], [NAME], [ | |
/mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS | |
], [[NAME, 'Firefox OS'], VERSION], [ | |
// Console | |
/(nintendo|playstation)\s([wids34portablevu]+)/i, // Nintendo/Playstation | |
// GNU/Linux based | |
/(mint)[\/\s\(]?(\w+)*/i, // Mint | |
/(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux | |
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i, | |
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware | |
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus | |
/(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux | |
/(gnu)\s?([\w\.]+)*/i // GNU | |
], [NAME, VERSION], [ | |
/(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS | |
], [[NAME, 'Chromium OS'], VERSION],[ | |
// Solaris | |
/(sunos)\s?([\w\.]+\d)*/i // Solaris | |
], [[NAME, 'Solaris'], VERSION], [ | |
// BSD based | |
/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly | |
], [NAME, VERSION],[ | |
/(ip[honead]+)(?:.*os\s([\w]+)*\slike\smac|;\sopera)/i // iOS | |
], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [ | |
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i, | |
/(macintosh|mac(?=_powerpc)\s)/i // Mac OS | |
], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [ | |
// Other | |
/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris | |
/(haiku)\s(\w+)/i, // Haiku | |
/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX | |
/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i, | |
// Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS | |
/(unix)\s?([\w\.]+)*/i // UNIX | |
], [NAME, VERSION] | |
] | |
}; | |
///////////////// | |
// Constructor | |
//////////////// | |
var UAParser = function (uastring, extensions) { | |
if (!(this instanceof UAParser)) { | |
return new UAParser(uastring, extensions).getResult(); | |
} | |
var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); | |
var rgxmap = extensions ? util.extend(regexes, extensions) : regexes; | |
this.getBrowser = function () { | |
var browser = mapper.rgx.apply(this, rgxmap.browser); | |
browser.major = util.major(browser.version); | |
return browser; | |
}; | |
this.getCPU = function () { | |
return mapper.rgx.apply(this, rgxmap.cpu); | |
}; | |
this.getDevice = function () { | |
return mapper.rgx.apply(this, rgxmap.device); | |
}; | |
this.getEngine = function () { | |
return mapper.rgx.apply(this, rgxmap.engine); | |
}; | |
this.getOS = function () { | |
return mapper.rgx.apply(this, rgxmap.os); | |
}; | |
this.getResult = function() { | |
return { | |
ua : this.getUA(), | |
browser : this.getBrowser(), | |
engine : this.getEngine(), | |
os : this.getOS(), | |
device : this.getDevice(), | |
cpu : this.getCPU() | |
}; | |
}; | |
this.getUA = function () { | |
return ua; | |
}; | |
this.setUA = function (uastring) { | |
ua = uastring; | |
return this; | |
}; | |
this.setUA(ua); | |
return this; | |
}; | |
UAParser.VERSION = LIBVERSION; | |
UAParser.BROWSER = { | |
NAME : NAME, | |
MAJOR : MAJOR, // deprecated | |
VERSION : VERSION | |
}; | |
UAParser.CPU = { | |
ARCHITECTURE : ARCHITECTURE | |
}; | |
UAParser.DEVICE = { | |
MODEL : MODEL, | |
VENDOR : VENDOR, | |
TYPE : TYPE, | |
CONSOLE : CONSOLE, | |
MOBILE : MOBILE, | |
SMARTTV : SMARTTV, | |
TABLET : TABLET, | |
WEARABLE: WEARABLE, | |
EMBEDDED: EMBEDDED | |
}; | |
UAParser.ENGINE = { | |
NAME : NAME, | |
VERSION : VERSION | |
}; | |
UAParser.OS = { | |
NAME : NAME, | |
VERSION : VERSION | |
}; | |
/////////// | |
// Export | |
////////// | |
// check js environment | |
if (typeof(exports) !== UNDEF_TYPE) { | |
// nodejs env | |
if (typeof module !== UNDEF_TYPE && module.exports) { | |
exports = module.exports = UAParser; | |
} | |
exports.UAParser = UAParser; | |
} else { | |
// requirejs env (optional) | |
if (typeof(define) === FUNC_TYPE && define.amd) { | |
define(function () { | |
return UAParser; | |
}); | |
} else { | |
// browser env | |
window.UAParser = UAParser; | |
} | |
} | |
// jQuery/Zepto specific (optional) | |
// Note: | |
// In AMD env the global scope should be kept clean, but jQuery is an exception. | |
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used, | |
// and we should catch that. | |
var $ = window.jQuery || window.Zepto; | |
if (typeof $ !== UNDEF_TYPE) { | |
var parser = new UAParser(); | |
$.ua = parser.getResult(); | |
$.ua.get = function() { | |
return parser.getUA(); | |
}; | |
$.ua.set = function (uastring) { | |
parser.setUA(uastring); | |
var result = parser.getResult(); | |
for (var prop in result) { | |
$.ua[prop] = result[prop]; | |
} | |
}; | |
} | |
})(typeof window === 'object' ? window : this); | |
}); | |
var Parser = interopDefault(uaParser); | |
var detectBrowser = createCommonjsModule(function (module) { | |
module.exports = function detectBrowser(userAgentString) { | |
var browsers = [ | |
[ 'edge', /Edge\/([0-9\._]+)/ ], | |
[ 'chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/ ], | |
[ 'firefox', /Firefox\/([0-9\.]+)(?:\s|$)/ ], | |
[ 'opera', /Opera\/([0-9\.]+)(?:\s|$)/ ], | |
[ 'opera', /OPR\/([0-9\.]+)(:?\s|$)$/ ], | |
[ 'ie', /Trident\/7\.0.*rv\:([0-9\.]+)\).*Gecko$/ ], | |
[ 'ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/ ], | |
[ 'ie', /MSIE\s(7\.0)/ ], | |
[ 'bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/ ], | |
[ 'android', /Android\s([0-9\.]+)/ ], | |
[ 'ios', /iPad.*Version\/([0-9\._]+)/ ], | |
[ 'ios', /iPhone.*Version\/([0-9\._]+)/ ], | |
[ 'safari', /Version\/([0-9\._]+).*Safari/ ] | |
]; | |
var i = 0, mapped =[]; | |
for (i = 0; i < browsers.length; i++) { | |
browsers[i] = createMatch(browsers[i]); | |
if (isMatch(browsers[i])) { | |
mapped.push(browsers[i]); | |
} | |
} | |
var match = mapped[0]; | |
var parts = match && match[3].split(/[._]/).slice(0,3); | |
while (parts && parts.length < 3) { | |
parts.push('0'); | |
} | |
function createMatch(pair) { | |
return pair.concat(pair[1].exec(userAgentString)); | |
} | |
function isMatch(pair) { | |
return !!pair[2]; | |
} | |
// return the name and version | |
return { | |
name: match && match[0], | |
version: parts && parts.join('.'), | |
}; | |
}; | |
}); | |
var detectBrowser$1 = interopDefault(detectBrowser); | |
var require$$0 = Object.freeze({ | |
default: detectBrowser$1 | |
}); | |
var browser = createCommonjsModule(function (module) { | |
var detectBrowser = interopDefault(require$$0); | |
module.exports = detectBrowser(navigator.userAgent); | |
}); | |
interopDefault(browser); | |
var _indexOfNaN = createCommonjsModule(function (module) { | |
/** | |
* Gets the index at which the first occurrence of `NaN` is found in `array`. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @param {number} fromIndex The index to search from. | |
* @param {boolean} [fromRight] Specify iterating from right to left. | |
* @returns {number} Returns the index of the matched `NaN`, else `-1`. | |
*/ | |
function indexOfNaN(array, fromIndex, fromRight) { | |
var length = array.length, | |
index = fromIndex + (fromRight ? 1 : -1); | |
while ((fromRight ? index-- : ++index < length)) { | |
var other = array[index]; | |
if (other !== other) { | |
return index; | |
} | |
} | |
return -1; | |
} | |
module.exports = indexOfNaN; | |
}); | |
var _indexOfNaN$1 = interopDefault(_indexOfNaN); | |
var require$$0$2 = Object.freeze({ | |
default: _indexOfNaN$1 | |
}); | |
var _baseIndexOf = createCommonjsModule(function (module) { | |
var indexOfNaN = interopDefault(require$$0$2); | |
/** | |
* The base implementation of `_.indexOf` without `fromIndex` bounds checks. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @param {*} value The value to search for. | |
* @param {number} fromIndex The index to search from. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
*/ | |
function baseIndexOf(array, value, fromIndex) { | |
if (value !== value) { | |
return indexOfNaN(array, fromIndex); | |
} | |
var index = fromIndex - 1, | |
length = array.length; | |
while (++index < length) { | |
if (array[index] === value) { | |
return index; | |
} | |
} | |
return -1; | |
} | |
module.exports = baseIndexOf; | |
}); | |
var _baseIndexOf$1 = interopDefault(_baseIndexOf); | |
var require$$0$1 = Object.freeze({ | |
default: _baseIndexOf$1 | |
}); | |
var _baseProperty = createCommonjsModule(function (module) { | |
/** | |
* The base implementation of `_.property` without support for deep paths. | |
* | |
* @private | |
* @param {string} key The key of the property to get. | |
* @returns {Function} Returns the new accessor function. | |
*/ | |
function baseProperty(key) { | |
return function(object) { | |
return object == null ? undefined : object[key]; | |
}; | |
} | |
module.exports = baseProperty; | |
}); | |
var _baseProperty$1 = interopDefault(_baseProperty); | |
var require$$0$3 = Object.freeze({ | |
default: _baseProperty$1 | |
}); | |
var _getLength = createCommonjsModule(function (module) { | |
var baseProperty = interopDefault(require$$0$3); | |
/** | |
* Gets the "length" property value of `object`. | |
* | |
* **Note:** This function is used to avoid a | |
* [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects | |
* Safari on at least iOS 8.1-8.3 ARM64. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {*} Returns the "length" value. | |
*/ | |
var getLength = baseProperty('length'); | |
module.exports = getLength; | |
}); | |
var _getLength$1 = interopDefault(_getLength); | |
var require$$2 = Object.freeze({ | |
default: _getLength$1 | |
}); | |
var isObject = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is the | |
* [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) | |
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) | |
* | |
* @static | |
* @memberOf _ | |
* @since 0.1.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is an object, else `false`. | |
* @example | |
* | |
* _.isObject({}); | |
* // => true | |
* | |
* _.isObject([1, 2, 3]); | |
* // => true | |
* | |
* _.isObject(_.noop); | |
* // => true | |
* | |
* _.isObject(null); | |
* // => false | |
*/ | |
function isObject(value) { | |
var type = typeof value; | |
return !!value && (type == 'object' || type == 'function'); | |
} | |
module.exports = isObject; | |
}); | |
var isObject$1 = interopDefault(isObject); | |
var require$$1$1 = Object.freeze({ | |
default: isObject$1 | |
}); | |
var isFunction = createCommonjsModule(function (module) { | |
var isObject = interopDefault(require$$1$1); | |
/** `Object#toString` result references. */ | |
var funcTag = '[object Function]', | |
genTag = '[object GeneratorFunction]'; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** | |
* Used to resolve the | |
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) | |
* of values. | |
*/ | |
var objectToString = objectProto.toString; | |
/** | |
* Checks if `value` is classified as a `Function` object. | |
* | |
* @static | |
* @memberOf _ | |
* @since 0.1.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, | |
* else `false`. | |
* @example | |
* | |
* _.isFunction(_); | |
* // => true | |
* | |
* _.isFunction(/abc/); | |
* // => false | |
*/ | |
function isFunction(value) { | |
// The use of `Object#toString` avoids issues with the `typeof` operator | |
// in Safari 8 which returns 'object' for typed array and weak map constructors, | |
// and PhantomJS 1.9 which returns 'function' for `NodeList` instances. | |
var tag = isObject(value) ? objectToString.call(value) : ''; | |
return tag == funcTag || tag == genTag; | |
} | |
module.exports = isFunction; | |
}); | |
var isFunction$1 = interopDefault(isFunction); | |
var require$$4 = Object.freeze({ | |
default: isFunction$1 | |
}); | |
var isLength = createCommonjsModule(function (module) { | |
/** Used as references for various `Number` constants. */ | |
var MAX_SAFE_INTEGER = 9007199254740991; | |
/** | |
* Checks if `value` is a valid array-like length. | |
* | |
* **Note:** This function is loosely based on | |
* [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is a valid length, | |
* else `false`. | |
* @example | |
* | |
* _.isLength(3); | |
* // => true | |
* | |
* _.isLength(Number.MIN_VALUE); | |
* // => false | |
* | |
* _.isLength(Infinity); | |
* // => false | |
* | |
* _.isLength('3'); | |
* // => false | |
*/ | |
function isLength(value) { | |
return typeof value == 'number' && | |
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; | |
} | |
module.exports = isLength; | |
}); | |
var isLength$1 = interopDefault(isLength); | |
var require$$1$2 = Object.freeze({ | |
default: isLength$1 | |
}); | |
var isArrayLike = createCommonjsModule(function (module) { | |
var getLength = interopDefault(require$$2), | |
isFunction = interopDefault(require$$4), | |
isLength = interopDefault(require$$1$2); | |
/** | |
* Checks if `value` is array-like. A value is considered array-like if it's | |
* not a function and has a `value.length` that's an integer greater than or | |
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is array-like, else `false`. | |
* @example | |
* | |
* _.isArrayLike([1, 2, 3]); | |
* // => true | |
* | |
* _.isArrayLike(document.body.children); | |
* // => true | |
* | |
* _.isArrayLike('abc'); | |
* // => true | |
* | |
* _.isArrayLike(_.noop); | |
* // => false | |
*/ | |
function isArrayLike(value) { | |
return value != null && isLength(getLength(value)) && !isFunction(value); | |
} | |
module.exports = isArrayLike; | |
}); | |
var isArrayLike$1 = interopDefault(isArrayLike); | |
var require$$1 = Object.freeze({ | |
default: isArrayLike$1 | |
}); | |
var isArray = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is classified as an `Array` object. | |
* | |
* @static | |
* @memberOf _ | |
* @since 0.1.0 | |
* @type {Function} | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, | |
* else `false`. | |
* @example | |
* | |
* _.isArray([1, 2, 3]); | |
* // => true | |
* | |
* _.isArray(document.body.children); | |
* // => false | |
* | |
* _.isArray('abc'); | |
* // => false | |
* | |
* _.isArray(_.noop); | |
* // => false | |
*/ | |
var isArray = Array.isArray; | |
module.exports = isArray; | |
}); | |
var isArray$1 = interopDefault(isArray); | |
var require$$2$1 = Object.freeze({ | |
default: isArray$1 | |
}); | |
var isObjectLike = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is object-like. A value is object-like if it's not `null` | |
* and has a `typeof` result of "object". | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is object-like, else `false`. | |
* @example | |
* | |
* _.isObjectLike({}); | |
* // => true | |
* | |
* _.isObjectLike([1, 2, 3]); | |
* // => true | |
* | |
* _.isObjectLike(_.noop); | |
* // => false | |
* | |
* _.isObjectLike(null); | |
* // => false | |
*/ | |
function isObjectLike(value) { | |
return !!value && typeof value == 'object'; | |
} | |
module.exports = isObjectLike; | |
}); | |
var isObjectLike$1 = interopDefault(isObjectLike); | |
var require$$0$5 = Object.freeze({ | |
default: isObjectLike$1 | |
}); | |
var isString = createCommonjsModule(function (module) { | |
var isArray = interopDefault(require$$2$1), | |
isObjectLike = interopDefault(require$$0$5); | |
/** `Object#toString` result references. */ | |
var stringTag = '[object String]'; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** | |
* Used to resolve the | |
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) | |
* of values. | |
*/ | |
var objectToString = objectProto.toString; | |
/** | |
* Checks if `value` is classified as a `String` primitive or object. | |
* | |
* @static | |
* @since 0.1.0 | |
* @memberOf _ | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, | |
* else `false`. | |
* @example | |
* | |
* _.isString('abc'); | |
* // => true | |
* | |
* _.isString(1); | |
* // => false | |
*/ | |
function isString(value) { | |
return typeof value == 'string' || | |
(!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); | |
} | |
module.exports = isString; | |
}); | |
var isString$1 = interopDefault(isString); | |
var require$$0$4 = Object.freeze({ | |
default: isString$1 | |
}); | |
var isSymbol = createCommonjsModule(function (module) { | |
var isObjectLike = interopDefault(require$$0$5); | |
/** `Object#toString` result references. */ | |
var symbolTag = '[object Symbol]'; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** | |
* Used to resolve the | |
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) | |
* of values. | |
*/ | |
var objectToString = objectProto.toString; | |
/** | |
* Checks if `value` is classified as a `Symbol` primitive or object. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, | |
* else `false`. | |
* @example | |
* | |
* _.isSymbol(Symbol.iterator); | |
* // => true | |
* | |
* _.isSymbol('abc'); | |
* // => false | |
*/ | |
function isSymbol(value) { | |
return typeof value == 'symbol' || | |
(isObjectLike(value) && objectToString.call(value) == symbolTag); | |
} | |
module.exports = isSymbol; | |
}); | |
var isSymbol$1 = interopDefault(isSymbol); | |
var require$$0$9 = Object.freeze({ | |
default: isSymbol$1 | |
}); | |
var toNumber = createCommonjsModule(function (module) { | |
var isFunction = interopDefault(require$$4), | |
isObject = interopDefault(require$$1$1), | |
isSymbol = interopDefault(require$$0$9); | |
/** Used as references for various `Number` constants. */ | |
var NAN = 0 / 0; | |
/** Used to match leading and trailing whitespace. */ | |
var reTrim = /^\s+|\s+$/g; | |
/** Used to detect bad signed hexadecimal string values. */ | |
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; | |
/** Used to detect binary string values. */ | |
var reIsBinary = /^0b[01]+$/i; | |
/** Used to detect octal string values. */ | |
var reIsOctal = /^0o[0-7]+$/i; | |
/** Built-in method references without a dependency on `root`. */ | |
var freeParseInt = parseInt; | |
/** | |
* Converts `value` to a number. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to process. | |
* @returns {number} Returns the number. | |
* @example | |
* | |
* _.toNumber(3.2); | |
* // => 3.2 | |
* | |
* _.toNumber(Number.MIN_VALUE); | |
* // => 5e-324 | |
* | |
* _.toNumber(Infinity); | |
* // => Infinity | |
* | |
* _.toNumber('3.2'); | |
* // => 3.2 | |
*/ | |
function toNumber(value) { | |
if (typeof value == 'number') { | |
return value; | |
} | |
if (isSymbol(value)) { | |
return NAN; | |
} | |
if (isObject(value)) { | |
var other = isFunction(value.valueOf) ? value.valueOf() : value; | |
value = isObject(other) ? (other + '') : other; | |
} | |
if (typeof value != 'string') { | |
return value === 0 ? value : +value; | |
} | |
value = value.replace(reTrim, ''); | |
var isBinary = reIsBinary.test(value); | |
return (isBinary || reIsOctal.test(value)) | |
? freeParseInt(value.slice(2), isBinary ? 2 : 8) | |
: (reIsBadHex.test(value) ? NAN : +value); | |
} | |
module.exports = toNumber; | |
}); | |
var toNumber$1 = interopDefault(toNumber); | |
var require$$0$8 = Object.freeze({ | |
default: toNumber$1 | |
}); | |
var toFinite = createCommonjsModule(function (module) { | |
var toNumber = interopDefault(require$$0$8); | |
/** Used as references for various `Number` constants. */ | |
var INFINITY = 1 / 0, | |
MAX_INTEGER = 1.7976931348623157e+308; | |
/** | |
* Converts `value` to a finite number. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.12.0 | |
* @category Lang | |
* @param {*} value The value to convert. | |
* @returns {number} Returns the converted number. | |
* @example | |
* | |
* _.toFinite(3.2); | |
* // => 3.2 | |
* | |
* _.toFinite(Number.MIN_VALUE); | |
* // => 5e-324 | |
* | |
* _.toFinite(Infinity); | |
* // => 1.7976931348623157e+308 | |
* | |
* _.toFinite('3.2'); | |
* // => 3.2 | |
*/ | |
function toFinite(value) { | |
if (!value) { | |
return value === 0 ? value : 0; | |
} | |
value = toNumber(value); | |
if (value === INFINITY || value === -INFINITY) { | |
var sign = (value < 0 ? -1 : 1); | |
return sign * MAX_INTEGER; | |
} | |
return value === value ? value : 0; | |
} | |
module.exports = toFinite; | |
}); | |
var toFinite$1 = interopDefault(toFinite); | |
var require$$0$7 = Object.freeze({ | |
default: toFinite$1 | |
}); | |
var toInteger = createCommonjsModule(function (module) { | |
var toFinite = interopDefault(require$$0$7); | |
/** | |
* Converts `value` to an integer. | |
* | |
* **Note:** This method is loosely based on | |
* [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to convert. | |
* @returns {number} Returns the converted integer. | |
* @example | |
* | |
* _.toInteger(3.2); | |
* // => 3 | |
* | |
* _.toInteger(Number.MIN_VALUE); | |
* // => 0 | |
* | |
* _.toInteger(Infinity); | |
* // => 1.7976931348623157e+308 | |
* | |
* _.toInteger('3.2'); | |
* // => 3 | |
*/ | |
function toInteger(value) { | |
var result = toFinite(value), | |
remainder = result % 1; | |
return result === result ? (remainder ? result - remainder : result) : 0; | |
} | |
module.exports = toInteger; | |
}); | |
var toInteger$1 = interopDefault(toInteger); | |
var require$$0$6 = Object.freeze({ | |
default: toInteger$1 | |
}); | |
var _arrayMap = createCommonjsModule(function (module) { | |
/** | |
* A specialized version of `_.map` for arrays without support for iteratee | |
* shorthands. | |
* | |
* @private | |
* @param {Array} [array] The array to iterate over. | |
* @param {Function} iteratee The function invoked per iteration. | |
* @returns {Array} Returns the new mapped array. | |
*/ | |
function arrayMap(array, iteratee) { | |
var index = -1, | |
length = array ? array.length : 0, | |
result = Array(length); | |
while (++index < length) { | |
result[index] = iteratee(array[index], index, array); | |
} | |
return result; | |
} | |
module.exports = arrayMap; | |
}); | |
var _arrayMap$1 = interopDefault(_arrayMap); | |
var require$$2$2 = Object.freeze({ | |
default: _arrayMap$1 | |
}); | |
var _baseValues = createCommonjsModule(function (module) { | |
var arrayMap = interopDefault(require$$2$2); | |
/** | |
* The base implementation of `_.values` and `_.valuesIn` which creates an | |
* array of `object` property values corresponding to the property names | |
* of `props`. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @param {Array} props The property names to get values for. | |
* @returns {Object} Returns the array of property values. | |
*/ | |
function baseValues(object, props) { | |
return arrayMap(props, function(key) { | |
return object[key]; | |
}); | |
} | |
module.exports = baseValues; | |
}); | |
var _baseValues$1 = interopDefault(_baseValues); | |
var require$$1$3 = Object.freeze({ | |
default: _baseValues$1 | |
}); | |
var _getPrototype = createCommonjsModule(function (module) { | |
/* Built-in method references for those with the same name as other `lodash` methods. */ | |
var nativeGetPrototype = Object.getPrototypeOf; | |
/** | |
* Gets the `[[Prototype]]` of `value`. | |
* | |
* @private | |
* @param {*} value The value to query. | |
* @returns {null|Object} Returns the `[[Prototype]]`. | |
*/ | |
function getPrototype(value) { | |
return nativeGetPrototype(Object(value)); | |
} | |
module.exports = getPrototype; | |
}); | |
var _getPrototype$1 = interopDefault(_getPrototype); | |
var require$$0$12 = Object.freeze({ | |
default: _getPrototype$1 | |
}); | |
var _baseHas = createCommonjsModule(function (module) { | |
var getPrototype = interopDefault(require$$0$12); | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** | |
* The base implementation of `_.has` without support for deep paths. | |
* | |
* @private | |
* @param {Object} [object] The object to query. | |
* @param {Array|string} key The key to check. | |
* @returns {boolean} Returns `true` if `key` exists, else `false`. | |
*/ | |
function baseHas(object, key) { | |
// Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, | |
// that are composed entirely of index properties, return `false` for | |
// `hasOwnProperty` checks of them. | |
return object != null && | |
(hasOwnProperty.call(object, key) || | |
(typeof object == 'object' && key in object && getPrototype(object) === null)); | |
} | |
module.exports = baseHas; | |
}); | |
var _baseHas$1 = interopDefault(_baseHas); | |
var require$$5 = Object.freeze({ | |
default: _baseHas$1 | |
}); | |
var _baseKeys = createCommonjsModule(function (module) { | |
/* Built-in method references for those with the same name as other `lodash` methods. */ | |
var nativeKeys = Object.keys; | |
/** | |
* The base implementation of `_.keys` which doesn't skip the constructor | |
* property of prototypes or treat sparse arrays as dense. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of property names. | |
*/ | |
function baseKeys(object) { | |
return nativeKeys(Object(object)); | |
} | |
module.exports = baseKeys; | |
}); | |
var _baseKeys$1 = interopDefault(_baseKeys); | |
var require$$4$1 = Object.freeze({ | |
default: _baseKeys$1 | |
}); | |
var _baseTimes = createCommonjsModule(function (module) { | |
/** | |
* The base implementation of `_.times` without support for iteratee shorthands | |
* or max array length checks. | |
* | |
* @private | |
* @param {number} n The number of times to invoke `iteratee`. | |
* @param {Function} iteratee The function invoked per iteration. | |
* @returns {Array} Returns the array of results. | |
*/ | |
function baseTimes(n, iteratee) { | |
var index = -1, | |
result = Array(n); | |
while (++index < n) { | |
result[index] = iteratee(index); | |
} | |
return result; | |
} | |
module.exports = baseTimes; | |
}); | |
var _baseTimes$1 = interopDefault(_baseTimes); | |
var require$$4$2 = Object.freeze({ | |
default: _baseTimes$1 | |
}); | |
var isArrayLikeObject = createCommonjsModule(function (module) { | |
var isArrayLike = interopDefault(require$$1), | |
isObjectLike = interopDefault(require$$0$5); | |
/** | |
* This method is like `_.isArrayLike` except that it also checks if `value` | |
* is an object. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is an array-like object, | |
* else `false`. | |
* @example | |
* | |
* _.isArrayLikeObject([1, 2, 3]); | |
* // => true | |
* | |
* _.isArrayLikeObject(document.body.children); | |
* // => true | |
* | |
* _.isArrayLikeObject('abc'); | |
* // => false | |
* | |
* _.isArrayLikeObject(_.noop); | |
* // => false | |
*/ | |
function isArrayLikeObject(value) { | |
return isObjectLike(value) && isArrayLike(value); | |
} | |
module.exports = isArrayLikeObject; | |
}); | |
var isArrayLikeObject$1 = interopDefault(isArrayLikeObject); | |
var require$$1$4 = Object.freeze({ | |
default: isArrayLikeObject$1 | |
}); | |
var isArguments = createCommonjsModule(function (module) { | |
var isArrayLikeObject = interopDefault(require$$1$4); | |
/** `Object#toString` result references. */ | |
var argsTag = '[object Arguments]'; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** | |
* Used to resolve the | |
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) | |
* of values. | |
*/ | |
var objectToString = objectProto.toString; | |
/** Built-in value references. */ | |
var propertyIsEnumerable = objectProto.propertyIsEnumerable; | |
/** | |
* Checks if `value` is likely an `arguments` object. | |
* | |
* @static | |
* @memberOf _ | |
* @since 0.1.0 | |
* @category Lang | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is correctly classified, | |
* else `false`. | |
* @example | |
* | |
* _.isArguments(function() { return arguments; }()); | |
* // => true | |
* | |
* _.isArguments([1, 2, 3]); | |
* // => false | |
*/ | |
function isArguments(value) { | |
// Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. | |
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && | |
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); | |
} | |
module.exports = isArguments; | |
}); | |
var isArguments$1 = interopDefault(isArguments); | |
var require$$3$1 = Object.freeze({ | |
default: isArguments$1 | |
}); | |
var _indexKeys = createCommonjsModule(function (module) { | |
var baseTimes = interopDefault(require$$4$2), | |
isArguments = interopDefault(require$$3$1), | |
isArray = interopDefault(require$$2$1), | |
isLength = interopDefault(require$$1$2), | |
isString = interopDefault(require$$0$4); | |
/** | |
* Creates an array of index keys for `object` values of arrays, | |
* `arguments` objects, and strings, otherwise `null` is returned. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @returns {Array|null} Returns index keys, else `null`. | |
*/ | |
function indexKeys(object) { | |
var length = object ? object.length : undefined; | |
if (isLength(length) && | |
(isArray(object) || isString(object) || isArguments(object))) { | |
return baseTimes(length, String); | |
} | |
return null; | |
} | |
module.exports = indexKeys; | |
}); | |
var _indexKeys$1 = interopDefault(_indexKeys); | |
var require$$3 = Object.freeze({ | |
default: _indexKeys$1 | |
}); | |
var _isIndex = createCommonjsModule(function (module) { | |
/** Used as references for various `Number` constants. */ | |
var MAX_SAFE_INTEGER = 9007199254740991; | |
/** Used to detect unsigned integer values. */ | |
var reIsUint = /^(?:0|[1-9]\d*)$/; | |
/** | |
* Checks if `value` is a valid array-like index. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. | |
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`. | |
*/ | |
function isIndex(value, length) { | |
length = length == null ? MAX_SAFE_INTEGER : length; | |
return !!length && | |
(typeof value == 'number' || reIsUint.test(value)) && | |
(value > -1 && value % 1 == 0 && value < length); | |
} | |
module.exports = isIndex; | |
}); | |
var _isIndex$1 = interopDefault(_isIndex); | |
var require$$1$5 = Object.freeze({ | |
default: _isIndex$1 | |
}); | |
var _isPrototype = createCommonjsModule(function (module) { | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** | |
* Checks if `value` is likely a prototype object. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`. | |
*/ | |
function isPrototype(value) { | |
var Ctor = value && value.constructor, | |
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; | |
return value === proto; | |
} | |
module.exports = isPrototype; | |
}); | |
var _isPrototype$1 = interopDefault(_isPrototype); | |
var require$$0$13 = Object.freeze({ | |
default: _isPrototype$1 | |
}); | |
var keys = createCommonjsModule(function (module) { | |
var baseHas = interopDefault(require$$5), | |
baseKeys = interopDefault(require$$4$1), | |
indexKeys = interopDefault(require$$3), | |
isArrayLike = interopDefault(require$$1), | |
isIndex = interopDefault(require$$1$5), | |
isPrototype = interopDefault(require$$0$13); | |
/** | |
* Creates an array of the own enumerable property names of `object`. | |
* | |
* **Note:** Non-object values are coerced to objects. See the | |
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) | |
* for more details. | |
* | |
* @static | |
* @since 0.1.0 | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of property names. | |
* @example | |
* | |
* function Foo() { | |
* this.a = 1; | |
* this.b = 2; | |
* } | |
* | |
* Foo.prototype.c = 3; | |
* | |
* _.keys(new Foo); | |
* // => ['a', 'b'] (iteration order is not guaranteed) | |
* | |
* _.keys('hi'); | |
* // => ['0', '1'] | |
*/ | |
function keys(object) { | |
var isProto = isPrototype(object); | |
if (!(isProto || isArrayLike(object))) { | |
return baseKeys(object); | |
} | |
var indexes = indexKeys(object), | |
skipIndexes = !!indexes, | |
result = indexes || [], | |
length = result.length; | |
for (var key in object) { | |
if (baseHas(object, key) && | |
!(skipIndexes && (key == 'length' || isIndex(key, length))) && | |
!(isProto && key == 'constructor')) { | |
result.push(key); | |
} | |
} | |
return result; | |
} | |
module.exports = keys; | |
}); | |
var keys$1 = interopDefault(keys); | |
var require$$0$11 = Object.freeze({ | |
default: keys$1 | |
}); | |
var values = createCommonjsModule(function (module) { | |
var baseValues = interopDefault(require$$1$3), | |
keys = interopDefault(require$$0$11); | |
/** | |
* Creates an array of the own enumerable string keyed property values of `object`. | |
* | |
* **Note:** Non-object values are coerced to objects. | |
* | |
* @static | |
* @since 0.1.0 | |
* @memberOf _ | |
* @category Object | |
* @param {Object} object The object to query. | |
* @returns {Array} Returns the array of property values. | |
* @example | |
* | |
* function Foo() { | |
* this.a = 1; | |
* this.b = 2; | |
* } | |
* | |
* Foo.prototype.c = 3; | |
* | |
* _.values(new Foo); | |
* // => [1, 2] (iteration order is not guaranteed) | |
* | |
* _.values('hi'); | |
* // => ['h', 'i'] | |
*/ | |
function values(object) { | |
return object ? baseValues(object, keys(object)) : []; | |
} | |
module.exports = values; | |
}); | |
var values$1 = interopDefault(values); | |
var require$$0$10 = Object.freeze({ | |
default: values$1 | |
}); | |
var includes = createCommonjsModule(function (module) { | |
var baseIndexOf = interopDefault(require$$0$1), | |
isArrayLike = interopDefault(require$$1), | |
isString = interopDefault(require$$0$4), | |
toInteger = interopDefault(require$$0$6), | |
values = interopDefault(require$$0$10); | |
/* Built-in method references for those with the same name as other `lodash` methods. */ | |
var nativeMax = Math.max; | |
/** | |
* Checks if `value` is in `collection`. If `collection` is a string, it's | |
* checked for a substring of `value`, otherwise | |
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* is used for equality comparisons. If `fromIndex` is negative, it's used as | |
* the offset from the end of `collection`. | |
* | |
* @static | |
* @memberOf _ | |
* @since 0.1.0 | |
* @category Collection | |
* @param {Array|Object|string} collection The collection to search. | |
* @param {*} value The value to search for. | |
* @param {number} [fromIndex=0] The index to search from. | |
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. | |
* @returns {boolean} Returns `true` if `value` is found, else `false`. | |
* @example | |
* | |
* _.includes([1, 2, 3], 1); | |
* // => true | |
* | |
* _.includes([1, 2, 3], 1, 2); | |
* // => false | |
* | |
* _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); | |
* // => true | |
* | |
* _.includes('pebbles', 'eb'); | |
* // => true | |
*/ | |
function includes(collection, value, fromIndex, guard) { | |
collection = isArrayLike(collection) ? collection : values(collection); | |
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; | |
var length = collection.length; | |
if (fromIndex < 0) { | |
fromIndex = nativeMax(length + fromIndex, 0); | |
} | |
return isString(collection) | |
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) | |
: (!!length && baseIndexOf(collection, value, fromIndex) > -1); | |
} | |
module.exports = includes; | |
}); | |
var includes$1 = interopDefault(includes); | |
var IS_MAC = true && new Parser().getOS().name == 'Mac OS'; | |
var IS_UBUNTU = true && new Parser().getOS().name == 'Ubuntu'; | |
var IS_WINDOWS = true && includes$1(new Parser().getOS().name, 'Windows'); | |
/** | |
* Does an `e` have the alt modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isAlt(e) { | |
return e.altKey; | |
} | |
/** | |
* Does an `e` have the command modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isCommand(e) { | |
return IS_MAC ? e.metaKey && !e.altKey : e.ctrlKey && !e.altKey; | |
} | |
/** | |
* Does an `e` have the control modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isCtrl(e) { | |
return e.ctrlKey && !e.altKey; | |
} | |
/** | |
* Does an `e` have the line-level modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isLine(e) { | |
return IS_MAC ? e.metaKey : false; | |
} | |
/** | |
* Does an `e` have the Mac command modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isMacCommand(e) { | |
return IS_MAC && isCommand(e); | |
} | |
/** | |
* Does an `e` have the option modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isOption(e) { | |
return IS_MAC && e.altKey; | |
} | |
/** | |
* Does an `e` have the shift modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isShift(e) { | |
return e.shiftKey; | |
} | |
/** | |
* Does an `e` have the Windows command modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isWindowsCommand(e) { | |
return IS_WINDOWS && isCommand(e); | |
} | |
/** | |
* Does an `e` have the word-level modifier? | |
* | |
* @param {Event} e | |
* @return {Boolean} | |
*/ | |
function isWord(e) { | |
return IS_MAC ? e.altKey : e.ctrlKey; | |
} | |
/** | |
* Export. | |
*/ | |
var Key = { | |
isAlt: isAlt, | |
isCommand: isCommand, | |
isCtrl: isCtrl, | |
isLine: isLine, | |
isMacCommand: isMacCommand, | |
isOption: isOption, | |
isShift: isShift, | |
isWindowsCommand: isWindowsCommand, | |
isWord: isWord | |
}; | |
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { | |
return typeof obj; | |
} : function (obj) { | |
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; | |
}; | |
var classCallCheck = function (instance, Constructor) { | |
if (!(instance instanceof Constructor)) { | |
throw new TypeError("Cannot call a class as a function"); | |
} | |
}; | |
var createClass = function () { | |
function defineProperties(target, props) { | |
for (var i = 0; i < props.length; i++) { | |
var descriptor = props[i]; | |
descriptor.enumerable = descriptor.enumerable || false; | |
descriptor.configurable = true; | |
if ("value" in descriptor) descriptor.writable = true; | |
Object.defineProperty(target, descriptor.key, descriptor); | |
} | |
} | |
return function (Constructor, protoProps, staticProps) { | |
if (protoProps) defineProperties(Constructor.prototype, protoProps); | |
if (staticProps) defineProperties(Constructor, staticProps); | |
return Constructor; | |
}; | |
}(); | |
var _extends = Object.assign || function (target) { | |
for (var i = 1; i < arguments.length; i++) { | |
var source = arguments[i]; | |
for (var key in source) { | |
if (Object.prototype.hasOwnProperty.call(source, key)) { | |
target[key] = source[key]; | |
} | |
} | |
} | |
return target; | |
}; | |
var inherits = function (subClass, superClass) { | |
if (typeof superClass !== "function" && superClass !== null) { | |
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); | |
} | |
subClass.prototype = Object.create(superClass && superClass.prototype, { | |
constructor: { | |
value: subClass, | |
enumerable: false, | |
writable: true, | |
configurable: true | |
} | |
}); | |
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; | |
}; | |
var objectWithoutProperties = function (obj, keys) { | |
var target = {}; | |
for (var i in obj) { | |
if (keys.indexOf(i) >= 0) continue; | |
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; | |
target[i] = obj[i]; | |
} | |
return target; | |
}; | |
var possibleConstructorReturn = function (self, call) { | |
if (!self) { | |
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | |
} | |
return call && (typeof call === "object" || typeof call === "function") ? call : self; | |
}; | |
var slicedToArray = function () { | |
function sliceIterator(arr, i) { | |
var _arr = []; | |
var _n = true; | |
var _d = false; | |
var _e = undefined; | |
try { | |
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | |
_arr.push(_s.value); | |
if (i && _arr.length === i) break; | |
} | |
} catch (err) { | |
_d = true; | |
_e = err; | |
} finally { | |
try { | |
if (!_n && _i["return"]) _i["return"](); | |
} finally { | |
if (_d) throw _e; | |
} | |
} | |
return _arr; | |
} | |
return function (arr, i) { | |
if (Array.isArray(arr)) { | |
return arr; | |
} else if (Symbol.iterator in Object(arr)) { | |
return sliceIterator(arr, i); | |
} else { | |
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | |
} | |
}; | |
}(); | |
var toArray = function (arr) { | |
return Array.isArray(arr) ? arr : Array.from(arr); | |
}; | |
var toConsumableArray = function (arr) { | |
if (Array.isArray(arr)) { | |
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | |
return arr2; | |
} else { | |
return Array.from(arr); | |
} | |
}; | |
/** | |
* Offset key parser regex. | |
*/ | |
var PARSER = /^(\w+)(?::(\d+)-(\d+))?$/; | |
/** | |
* Offset key attribute name. | |
*/ | |
var ATTRIBUTE = 'data-offset-key'; | |
var SELECTOR = '[' + ATTRIBUTE + ']'; | |
/** | |
* From a `node`, find the closest parent's offset key. | |
* | |
* @param {Node} node | |
* @return {String} key | |
*/ | |
function findKey(node) { | |
if (node.nodeType == 3) node = node.parentNode; | |
// If a parent with an offset key exists, use it. | |
var parent = node.closest(SELECTOR); | |
if (parent) return parent.getAttribute(ATTRIBUTE); | |
// Otherwise, if a child with an offset key exists, use it. | |
var child = node.querySelector(SELECTOR); | |
if (child) return child.getAttribute(ATTRIBUTE); | |
// Otherwise, move up the tree looking for cousin offset keys in parents. | |
while (node = node.parentNode) { | |
var cousin = node.querySelector(SELECTOR); | |
if (cousin) return cousin.getAttribute(ATTRIBUTE); | |
} | |
// Shouldn't get here... else we have an edge case to handle. | |
throw new Error('No offset key found for node.'); | |
} | |
/** | |
* From a `node` and `offset`, find the closest parent's point. | |
* | |
* @param {Node} node | |
* @param {Offset} offset | |
* @return {String} key | |
*/ | |
function findPoint(node, offset) { | |
var key = findKey(node); | |
var parsed = parse(key); | |
// Don't let the offset be outside the start and end bounds. | |
offset = parsed.start + offset; | |
offset = Math.max(offset, parsed.start); | |
offset = Math.min(offset, parsed.end); | |
return { | |
key: parsed.key, | |
offset: offset | |
}; | |
} | |
/** | |
* Parse an offset key `string`. | |
* | |
* @param {String} string | |
* @return {Object} parsed | |
*/ | |
function parse(string) { | |
var matches = PARSER.exec(string); | |
if (!matches) throw new Error('Invalid offset key string "' + string + '".'); | |
var _matches = slicedToArray(matches, 4); | |
var original = _matches[0]; | |
var key = _matches[1]; | |
var start = _matches[2]; | |
var end = _matches[3]; | |
start = parseInt(start, 10); | |
end = parseInt(end, 10); | |
return { | |
key: key, | |
start: start, | |
end: end | |
}; | |
} | |
/** | |
* Stringify an offset key `object`. | |
* | |
* @param {Object} object | |
* @property {String} key | |
* @property {Number} start | |
* @property {Number} end | |
* @return {String} key | |
*/ | |
function stringify(object) { | |
return object.key + ':' + object.start + '-' + object.end; | |
} | |
/** | |
* Export. | |
*/ | |
var OffsetKey = { | |
findKey: findKey, | |
findPoint: findPoint, | |
parse: parse, | |
stringify: stringify | |
}; | |
var immutable = createCommonjsModule(function (module, exports) { | |
/** | |
* Copyright (c) 2014-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
*/ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | |
typeof define === 'function' && define.amd ? define(factory) : | |
(global.Immutable = factory()); | |
}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice; | |
function createClass(ctor, superClass) { | |
if (superClass) { | |
ctor.prototype = Object.create(superClass.prototype); | |
} | |
ctor.prototype.constructor = ctor; | |
} | |
function Iterable(value) { | |
return isIterable(value) ? value : Seq(value); | |
} | |
createClass(KeyedIterable, Iterable); | |
function KeyedIterable(value) { | |
return isKeyed(value) ? value : KeyedSeq(value); | |
} | |
createClass(IndexedIterable, Iterable); | |
function IndexedIterable(value) { | |
return isIndexed(value) ? value : IndexedSeq(value); | |
} | |
createClass(SetIterable, Iterable); | |
function SetIterable(value) { | |
return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); | |
} | |
function isIterable(maybeIterable) { | |
return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); | |
} | |
function isKeyed(maybeKeyed) { | |
return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); | |
} | |
function isIndexed(maybeIndexed) { | |
return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); | |
} | |
function isAssociative(maybeAssociative) { | |
return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); | |
} | |
function isOrdered(maybeOrdered) { | |
return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); | |
} | |
Iterable.isIterable = isIterable; | |
Iterable.isKeyed = isKeyed; | |
Iterable.isIndexed = isIndexed; | |
Iterable.isAssociative = isAssociative; | |
Iterable.isOrdered = isOrdered; | |
Iterable.Keyed = KeyedIterable; | |
Iterable.Indexed = IndexedIterable; | |
Iterable.Set = SetIterable; | |
var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; | |
var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; | |
var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; | |
var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; | |
// Used for setting prototype methods that IE8 chokes on. | |
var DELETE = 'delete'; | |
// Constants describing the size of trie nodes. | |
var SHIFT = 5; // Resulted in best performance after ______? | |
var SIZE = 1 << SHIFT; | |
var MASK = SIZE - 1; | |
// A consistent shared value representing "not set" which equals nothing other | |
// than itself, and nothing that could be provided externally. | |
var NOT_SET = {}; | |
// Boolean references, Rough equivalent of `bool &`. | |
var CHANGE_LENGTH = { value: false }; | |
var DID_ALTER = { value: false }; | |
function MakeRef(ref) { | |
ref.value = false; | |
return ref; | |
} | |
function SetRef(ref) { | |
ref && (ref.value = true); | |
} | |
// A function which returns a value representing an "owner" for transient writes | |
// to tries. The return value will only ever equal itself, and will not equal | |
// the return of any subsequent call of this function. | |
function OwnerID() {} | |
// http://jsperf.com/copy-array-inline | |
function arrCopy(arr, offset) { | |
offset = offset || 0; | |
var len = Math.max(0, arr.length - offset); | |
var newArr = new Array(len); | |
for (var ii = 0; ii < len; ii++) { | |
newArr[ii] = arr[ii + offset]; | |
} | |
return newArr; | |
} | |
function ensureSize(iter) { | |
if (iter.size === undefined) { | |
iter.size = iter.__iterate(returnTrue); | |
} | |
return iter.size; | |
} | |
function wrapIndex(iter, index) { | |
// This implements "is array index" which the ECMAString spec defines as: | |
// | |
// A String property name P is an array index if and only if | |
// ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal | |
// to 2^32−1. | |
// | |
// http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects | |
if (typeof index !== 'number') { | |
var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32 | |
if ('' + uint32Index !== index || uint32Index === 4294967295) { | |
return NaN; | |
} | |
index = uint32Index; | |
} | |
return index < 0 ? ensureSize(iter) + index : index; | |
} | |
function returnTrue() { | |
return true; | |
} | |
function wholeSlice(begin, end, size) { | |
return (begin === 0 || (size !== undefined && begin <= -size)) && | |
(end === undefined || (size !== undefined && end >= size)); | |
} | |
function resolveBegin(begin, size) { | |
return resolveIndex(begin, size, 0); | |
} | |
function resolveEnd(end, size) { | |
return resolveIndex(end, size, size); | |
} | |
function resolveIndex(index, size, defaultIndex) { | |
return index === undefined ? | |
defaultIndex : | |
index < 0 ? | |
Math.max(0, size + index) : | |
size === undefined ? | |
index : | |
Math.min(size, index); | |
} | |
/* global Symbol */ | |
var ITERATE_KEYS = 0; | |
var ITERATE_VALUES = 1; | |
var ITERATE_ENTRIES = 2; | |
var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; | |
var FAUX_ITERATOR_SYMBOL = '@@iterator'; | |
var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; | |
function Iterator(next) { | |
this.next = next; | |
} | |
Iterator.prototype.toString = function() { | |
return '[Iterator]'; | |
}; | |
Iterator.KEYS = ITERATE_KEYS; | |
Iterator.VALUES = ITERATE_VALUES; | |
Iterator.ENTRIES = ITERATE_ENTRIES; | |
Iterator.prototype.inspect = | |
Iterator.prototype.toSource = function () { return this.toString(); } | |
Iterator.prototype[ITERATOR_SYMBOL] = function () { | |
return this; | |
}; | |
function iteratorValue(type, k, v, iteratorResult) { | |
var value = type === 0 ? k : type === 1 ? v : [k, v]; | |
iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { | |
value: value, done: false | |
}); | |
return iteratorResult; | |
} | |
function iteratorDone() { | |
return { value: undefined, done: true }; | |
} | |
function hasIterator(maybeIterable) { | |
return !!getIteratorFn(maybeIterable); | |
} | |
function isIterator(maybeIterator) { | |
return maybeIterator && typeof maybeIterator.next === 'function'; | |
} | |
function getIterator(iterable) { | |
var iteratorFn = getIteratorFn(iterable); | |
return iteratorFn && iteratorFn.call(iterable); | |
} | |
function getIteratorFn(iterable) { | |
var iteratorFn = iterable && ( | |
(REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || | |
iterable[FAUX_ITERATOR_SYMBOL] | |
); | |
if (typeof iteratorFn === 'function') { | |
return iteratorFn; | |
} | |
} | |
function isArrayLike(value) { | |
return value && typeof value.length === 'number'; | |
} | |
createClass(Seq, Iterable); | |
function Seq(value) { | |
return value === null || value === undefined ? emptySequence() : | |
isIterable(value) ? value.toSeq() : seqFromValue(value); | |
} | |
Seq.of = function(/*...values*/) { | |
return Seq(arguments); | |
}; | |
Seq.prototype.toSeq = function() { | |
return this; | |
}; | |
Seq.prototype.toString = function() { | |
return this.__toString('Seq {', '}'); | |
}; | |
Seq.prototype.cacheResult = function() { | |
if (!this._cache && this.__iterateUncached) { | |
this._cache = this.entrySeq().toArray(); | |
this.size = this._cache.length; | |
} | |
return this; | |
}; | |
// abstract __iterateUncached(fn, reverse) | |
Seq.prototype.__iterate = function(fn, reverse) { | |
return seqIterate(this, fn, reverse, true); | |
}; | |
// abstract __iteratorUncached(type, reverse) | |
Seq.prototype.__iterator = function(type, reverse) { | |
return seqIterator(this, type, reverse, true); | |
}; | |
createClass(KeyedSeq, Seq); | |
function KeyedSeq(value) { | |
return value === null || value === undefined ? | |
emptySequence().toKeyedSeq() : | |
isIterable(value) ? | |
(isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : | |
keyedSeqFromValue(value); | |
} | |
KeyedSeq.prototype.toKeyedSeq = function() { | |
return this; | |
}; | |
createClass(IndexedSeq, Seq); | |
function IndexedSeq(value) { | |
return value === null || value === undefined ? emptySequence() : | |
!isIterable(value) ? indexedSeqFromValue(value) : | |
isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); | |
} | |
IndexedSeq.of = function(/*...values*/) { | |
return IndexedSeq(arguments); | |
}; | |
IndexedSeq.prototype.toIndexedSeq = function() { | |
return this; | |
}; | |
IndexedSeq.prototype.toString = function() { | |
return this.__toString('Seq [', ']'); | |
}; | |
IndexedSeq.prototype.__iterate = function(fn, reverse) { | |
return seqIterate(this, fn, reverse, false); | |
}; | |
IndexedSeq.prototype.__iterator = function(type, reverse) { | |
return seqIterator(this, type, reverse, false); | |
}; | |
createClass(SetSeq, Seq); | |
function SetSeq(value) { | |
return ( | |
value === null || value === undefined ? emptySequence() : | |
!isIterable(value) ? indexedSeqFromValue(value) : | |
isKeyed(value) ? value.entrySeq() : value | |
).toSetSeq(); | |
} | |
SetSeq.of = function(/*...values*/) { | |
return SetSeq(arguments); | |
}; | |
SetSeq.prototype.toSetSeq = function() { | |
return this; | |
}; | |
Seq.isSeq = isSeq; | |
Seq.Keyed = KeyedSeq; | |
Seq.Set = SetSeq; | |
Seq.Indexed = IndexedSeq; | |
var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; | |
Seq.prototype[IS_SEQ_SENTINEL] = true; | |
createClass(ArraySeq, IndexedSeq); | |
function ArraySeq(array) { | |
this._array = array; | |
this.size = array.length; | |
} | |
ArraySeq.prototype.get = function(index, notSetValue) { | |
return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; | |
}; | |
ArraySeq.prototype.__iterate = function(fn, reverse) { | |
var array = this._array; | |
var maxIndex = array.length - 1; | |
for (var ii = 0; ii <= maxIndex; ii++) { | |
if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { | |
return ii + 1; | |
} | |
} | |
return ii; | |
}; | |
ArraySeq.prototype.__iterator = function(type, reverse) { | |
var array = this._array; | |
var maxIndex = array.length - 1; | |
var ii = 0; | |
return new Iterator(function() | |
{return ii > maxIndex ? | |
iteratorDone() : | |
iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])} | |
); | |
}; | |
createClass(ObjectSeq, KeyedSeq); | |
function ObjectSeq(object) { | |
var keys = Object.keys(object); | |
this._object = object; | |
this._keys = keys; | |
this.size = keys.length; | |
} | |
ObjectSeq.prototype.get = function(key, notSetValue) { | |
if (notSetValue !== undefined && !this.has(key)) { | |
return notSetValue; | |
} | |
return this._object[key]; | |
}; | |
ObjectSeq.prototype.has = function(key) { | |
return this._object.hasOwnProperty(key); | |
}; | |
ObjectSeq.prototype.__iterate = function(fn, reverse) { | |
var object = this._object; | |
var keys = this._keys; | |
var maxIndex = keys.length - 1; | |
for (var ii = 0; ii <= maxIndex; ii++) { | |
var key = keys[reverse ? maxIndex - ii : ii]; | |
if (fn(object[key], key, this) === false) { | |
return ii + 1; | |
} | |
} | |
return ii; | |
}; | |
ObjectSeq.prototype.__iterator = function(type, reverse) { | |
var object = this._object; | |
var keys = this._keys; | |
var maxIndex = keys.length - 1; | |
var ii = 0; | |
return new Iterator(function() { | |
var key = keys[reverse ? maxIndex - ii : ii]; | |
return ii++ > maxIndex ? | |
iteratorDone() : | |
iteratorValue(type, key, object[key]); | |
}); | |
}; | |
ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; | |
createClass(IterableSeq, IndexedSeq); | |
function IterableSeq(iterable) { | |
this._iterable = iterable; | |
this.size = iterable.length || iterable.size; | |
} | |
IterableSeq.prototype.__iterateUncached = function(fn, reverse) { | |
if (reverse) { | |
return this.cacheResult().__iterate(fn, reverse); | |
} | |
var iterable = this._iterable; | |
var iterator = getIterator(iterable); | |
var iterations = 0; | |
if (isIterator(iterator)) { | |
var step; | |
while (!(step = iterator.next()).done) { | |
if (fn(step.value, iterations++, this) === false) { | |
break; | |
} | |
} | |
} | |
return iterations; | |
}; | |
IterableSeq.prototype.__iteratorUncached = function(type, reverse) { | |
if (reverse) { | |
return this.cacheResult().__iterator(type, reverse); | |
} | |
var iterable = this._iterable; | |
var iterator = getIterator(iterable); | |
if (!isIterator(iterator)) { | |
return new Iterator(iteratorDone); | |
} | |
var iterations = 0; | |
return new Iterator(function() { | |
var step = iterator.next(); | |
return step.done ? step : iteratorValue(type, iterations++, step.value); | |
}); | |
}; | |
createClass(IteratorSeq, IndexedSeq); | |
function IteratorSeq(iterator) { | |
this._iterator = iterator; | |
this._iteratorCache = []; | |
} | |
IteratorSeq.prototype.__iterateUncached = function(fn, reverse) { | |
if (reverse) { | |
return this.cacheResult().__iterate(fn, reverse); | |
} | |
var iterator = this._iterator; | |
var cache = this._iteratorCache; | |
var iterations = 0; | |
while (iterations < cache.length) { | |
if (fn(cache[iterations], iterations++, this) === false) { | |
return iterations; | |
} | |
} | |
var step; | |
while (!(step = iterator.next()).done) { | |
var val = step.value; | |
cache[iterations] = val; | |
if (fn(val, iterations++, this) === false) { | |
break; | |
} | |
} | |
return iterations; | |
}; | |
IteratorSeq.prototype.__iteratorUncached = function(type, reverse) { | |
if (reverse) { | |
return this.cacheResult().__iterator(type, reverse); | |
} | |
var iterator = this._iterator; | |
var cache = this._iteratorCache; | |
var iterations = 0; | |
return new Iterator(function() { | |
if (iterations >= cache.length) { | |
var step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
cache[iterations] = step.value; | |
} | |
return iteratorValue(type, iterations, cache[iterations++]); | |
}); | |
}; | |
// # pragma Helper functions | |
function isSeq(maybeSeq) { | |
return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); | |
} | |
var EMPTY_SEQ; | |
function emptySequence() { | |
return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); | |
} | |
function keyedSeqFromValue(value) { | |
var seq = | |
Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : | |
isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : | |
hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : | |
typeof value === 'object' ? new ObjectSeq(value) : | |
undefined; | |
if (!seq) { | |
throw new TypeError( | |
'Expected Array or iterable object of [k, v] entries, '+ | |
'or keyed object: ' + value | |
); | |
} | |
return seq; | |
} | |
function indexedSeqFromValue(value) { | |
var seq = maybeIndexedSeqFromValue(value); | |
if (!seq) { | |
throw new TypeError( | |
'Expected Array or iterable object of values: ' + value | |
); | |
} | |
return seq; | |
} | |
function seqFromValue(value) { | |
var seq = maybeIndexedSeqFromValue(value) || | |
(typeof value === 'object' && new ObjectSeq(value)); | |
if (!seq) { | |
throw new TypeError( | |
'Expected Array or iterable object of values, or keyed object: ' + value | |
); | |
} | |
return seq; | |
} | |
function maybeIndexedSeqFromValue(value) { | |
return ( | |
isArrayLike(value) ? new ArraySeq(value) : | |
isIterator(value) ? new IteratorSeq(value) : | |
hasIterator(value) ? new IterableSeq(value) : | |
undefined | |
); | |
} | |
function seqIterate(seq, fn, reverse, useKeys) { | |
var cache = seq._cache; | |
if (cache) { | |
var maxIndex = cache.length - 1; | |
for (var ii = 0; ii <= maxIndex; ii++) { | |
var entry = cache[reverse ? maxIndex - ii : ii]; | |
if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { | |
return ii + 1; | |
} | |
} | |
return ii; | |
} | |
return seq.__iterateUncached(fn, reverse); | |
} | |
function seqIterator(seq, type, reverse, useKeys) { | |
var cache = seq._cache; | |
if (cache) { | |
var maxIndex = cache.length - 1; | |
var ii = 0; | |
return new Iterator(function() { | |
var entry = cache[reverse ? maxIndex - ii : ii]; | |
return ii++ > maxIndex ? | |
iteratorDone() : | |
iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); | |
}); | |
} | |
return seq.__iteratorUncached(type, reverse); | |
} | |
function fromJS(json, converter) { | |
return converter ? | |
fromJSWith(converter, json, '', {'': json}) : | |
fromJSDefault(json); | |
} | |
function fromJSWith(converter, json, key, parentJSON) { | |
if (Array.isArray(json)) { | |
return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); | |
} | |
if (isPlainObj(json)) { | |
return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); | |
} | |
return json; | |
} | |
function fromJSDefault(json) { | |
if (Array.isArray(json)) { | |
return IndexedSeq(json).map(fromJSDefault).toList(); | |
} | |
if (isPlainObj(json)) { | |
return KeyedSeq(json).map(fromJSDefault).toMap(); | |
} | |
return json; | |
} | |
function isPlainObj(value) { | |
return value && (value.constructor === Object || value.constructor === undefined); | |
} | |
/** | |
* An extension of the "same-value" algorithm as [described for use by ES6 Map | |
* and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) | |
* | |
* NaN is considered the same as NaN, however -0 and 0 are considered the same | |
* value, which is different from the algorithm described by | |
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). | |
* | |
* This is extended further to allow Objects to describe the values they | |
* represent, by way of `valueOf` or `equals` (and `hashCode`). | |
* | |
* Note: because of this extension, the key equality of Immutable.Map and the | |
* value equality of Immutable.Set will differ from ES6 Map and Set. | |
* | |
* ### Defining custom values | |
* | |
* The easiest way to describe the value an object represents is by implementing | |
* `valueOf`. For example, `Date` represents a value by returning a unix | |
* timestamp for `valueOf`: | |
* | |
* var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... | |
* var date2 = new Date(1234567890000); | |
* date1.valueOf(); // 1234567890000 | |
* assert( date1 !== date2 ); | |
* assert( Immutable.is( date1, date2 ) ); | |
* | |
* Note: overriding `valueOf` may have other implications if you use this object | |
* where JavaScript expects a primitive, such as implicit string coercion. | |
* | |
* For more complex types, especially collections, implementing `valueOf` may | |
* not be performant. An alternative is to implement `equals` and `hashCode`. | |
* | |
* `equals` takes another object, presumably of similar type, and returns true | |
* if the it is equal. Equality is symmetrical, so the same result should be | |
* returned if this and the argument are flipped. | |
* | |
* assert( a.equals(b) === b.equals(a) ); | |
* | |
* `hashCode` returns a 32bit integer number representing the object which will | |
* be used to determine how to store the value object in a Map or Set. You must | |
* provide both or neither methods, one must not exist without the other. | |
* | |
* Also, an important relationship between these methods must be upheld: if two | |
* values are equal, they *must* return the same hashCode. If the values are not | |
* equal, they might have the same hashCode; this is called a hash collision, | |
* and while undesirable for performance reasons, it is acceptable. | |
* | |
* if (a.equals(b)) { | |
* assert( a.hashCode() === b.hashCode() ); | |
* } | |
* | |
* All Immutable collections implement `equals` and `hashCode`. | |
* | |
*/ | |
function is(valueA, valueB) { | |
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { | |
return true; | |
} | |
if (!valueA || !valueB) { | |
return false; | |
} | |
if (typeof valueA.valueOf === 'function' && | |
typeof valueB.valueOf === 'function') { | |
valueA = valueA.valueOf(); | |
valueB = valueB.valueOf(); | |
if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { | |
return true; | |
} | |
if (!valueA || !valueB) { | |
return false; | |
} | |
} | |
if (typeof valueA.equals === 'function' && | |
typeof valueB.equals === 'function' && | |
valueA.equals(valueB)) { | |
return true; | |
} | |
return false; | |
} | |
function deepEqual(a, b) { | |
if (a === b) { | |
return true; | |
} | |
if ( | |
!isIterable(b) || | |
a.size !== undefined && b.size !== undefined && a.size !== b.size || | |
a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash || | |
isKeyed(a) !== isKeyed(b) || | |
isIndexed(a) !== isIndexed(b) || | |
isOrdered(a) !== isOrdered(b) | |
) { | |
return false; | |
} | |
if (a.size === 0 && b.size === 0) { | |
return true; | |
} | |
var notAssociative = !isAssociative(a); | |
if (isOrdered(a)) { | |
var entries = a.entries(); | |
return b.every(function(v, k) { | |
var entry = entries.next().value; | |
return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); | |
}) && entries.next().done; | |
} | |
var flipped = false; | |
if (a.size === undefined) { | |
if (b.size === undefined) { | |
if (typeof a.cacheResult === 'function') { | |
a.cacheResult(); | |
} | |
} else { | |
flipped = true; | |
var _ = a; | |
a = b; | |
b = _; | |
} | |
} | |
var allEqual = true; | |
var bSize = b.__iterate(function(v, k) { | |
if (notAssociative ? !a.has(v) : | |
flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { | |
allEqual = false; | |
return false; | |
} | |
}); | |
return allEqual && a.size === bSize; | |
} | |
createClass(Repeat, IndexedSeq); | |
function Repeat(value, times) { | |
if (!(this instanceof Repeat)) { | |
return new Repeat(value, times); | |
} | |
this._value = value; | |
this.size = times === undefined ? Infinity : Math.max(0, times); | |
if (this.size === 0) { | |
if (EMPTY_REPEAT) { | |
return EMPTY_REPEAT; | |
} | |
EMPTY_REPEAT = this; | |
} | |
} | |
Repeat.prototype.toString = function() { | |
if (this.size === 0) { | |
return 'Repeat []'; | |
} | |
return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; | |
}; | |
Repeat.prototype.get = function(index, notSetValue) { | |
return this.has(index) ? this._value : notSetValue; | |
}; | |
Repeat.prototype.includes = function(searchValue) { | |
return is(this._value, searchValue); | |
}; | |
Repeat.prototype.slice = function(begin, end) { | |
var size = this.size; | |
return wholeSlice(begin, end, size) ? this : | |
new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); | |
}; | |
Repeat.prototype.reverse = function() { | |
return this; | |
}; | |
Repeat.prototype.indexOf = function(searchValue) { | |
if (is(this._value, searchValue)) { | |
return 0; | |
} | |
return -1; | |
}; | |
Repeat.prototype.lastIndexOf = function(searchValue) { | |
if (is(this._value, searchValue)) { | |
return this.size; | |
} | |
return -1; | |
}; | |
Repeat.prototype.__iterate = function(fn, reverse) { | |
for (var ii = 0; ii < this.size; ii++) { | |
if (fn(this._value, ii, this) === false) { | |
return ii + 1; | |
} | |
} | |
return ii; | |
}; | |
Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this; | |
var ii = 0; | |
return new Iterator(function() | |
{return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()} | |
); | |
}; | |
Repeat.prototype.equals = function(other) { | |
return other instanceof Repeat ? | |
is(this._value, other._value) : | |
deepEqual(other); | |
}; | |
var EMPTY_REPEAT; | |
function invariant(condition, error) { | |
if (!condition) throw new Error(error); | |
} | |
createClass(Range, IndexedSeq); | |
function Range(start, end, step) { | |
if (!(this instanceof Range)) { | |
return new Range(start, end, step); | |
} | |
invariant(step !== 0, 'Cannot step a Range by 0'); | |
start = start || 0; | |
if (end === undefined) { | |
end = Infinity; | |
} | |
step = step === undefined ? 1 : Math.abs(step); | |
if (end < start) { | |
step = -step; | |
} | |
this._start = start; | |
this._end = end; | |
this._step = step; | |
this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); | |
if (this.size === 0) { | |
if (EMPTY_RANGE) { | |
return EMPTY_RANGE; | |
} | |
EMPTY_RANGE = this; | |
} | |
} | |
Range.prototype.toString = function() { | |
if (this.size === 0) { | |
return 'Range []'; | |
} | |
return 'Range [ ' + | |
this._start + '...' + this._end + | |
(this._step !== 1 ? ' by ' + this._step : '') + | |
' ]'; | |
}; | |
Range.prototype.get = function(index, notSetValue) { | |
return this.has(index) ? | |
this._start + wrapIndex(this, index) * this._step : | |
notSetValue; | |
}; | |
Range.prototype.includes = function(searchValue) { | |
var possibleIndex = (searchValue - this._start) / this._step; | |
return possibleIndex >= 0 && | |
possibleIndex < this.size && | |
possibleIndex === Math.floor(possibleIndex); | |
}; | |
Range.prototype.slice = function(begin, end) { | |
if (wholeSlice(begin, end, this.size)) { | |
return this; | |
} | |
begin = resolveBegin(begin, this.size); | |
end = resolveEnd(end, this.size); | |
if (end <= begin) { | |
return new Range(0, 0); | |
} | |
return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); | |
}; | |
Range.prototype.indexOf = function(searchValue) { | |
var offsetValue = searchValue - this._start; | |
if (offsetValue % this._step === 0) { | |
var index = offsetValue / this._step; | |
if (index >= 0 && index < this.size) { | |
return index | |
} | |
} | |
return -1; | |
}; | |
Range.prototype.lastIndexOf = function(searchValue) { | |
return this.indexOf(searchValue); | |
}; | |
Range.prototype.__iterate = function(fn, reverse) { | |
var maxIndex = this.size - 1; | |
var step = this._step; | |
var value = reverse ? this._start + maxIndex * step : this._start; | |
for (var ii = 0; ii <= maxIndex; ii++) { | |
if (fn(value, ii, this) === false) { | |
return ii + 1; | |
} | |
value += reverse ? -step : step; | |
} | |
return ii; | |
}; | |
Range.prototype.__iterator = function(type, reverse) { | |
var maxIndex = this.size - 1; | |
var step = this._step; | |
var value = reverse ? this._start + maxIndex * step : this._start; | |
var ii = 0; | |
return new Iterator(function() { | |
var v = value; | |
value += reverse ? -step : step; | |
return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); | |
}); | |
}; | |
Range.prototype.equals = function(other) { | |
return other instanceof Range ? | |
this._start === other._start && | |
this._end === other._end && | |
this._step === other._step : | |
deepEqual(this, other); | |
}; | |
var EMPTY_RANGE; | |
createClass(Collection, Iterable); | |
function Collection() { | |
throw TypeError('Abstract'); | |
} | |
createClass(KeyedCollection, Collection);function KeyedCollection() {} | |
createClass(IndexedCollection, Collection);function IndexedCollection() {} | |
createClass(SetCollection, Collection);function SetCollection() {} | |
Collection.Keyed = KeyedCollection; | |
Collection.Indexed = IndexedCollection; | |
Collection.Set = SetCollection; | |
var imul = | |
typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ? | |
Math.imul : | |
function imul(a, b) { | |
a = a | 0; // int | |
b = b | 0; // int | |
var c = a & 0xffff; | |
var d = b & 0xffff; | |
// Shift by 0 fixes the sign on the high part. | |
return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int | |
}; | |
// v8 has an optimization for storing 31-bit signed numbers. | |
// Values which have either 00 or 11 as the high order bits qualify. | |
// This function drops the highest order bit in a signed number, maintaining | |
// the sign bit. | |
function smi(i32) { | |
return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF); | |
} | |
function hash(o) { | |
if (o === false || o === null || o === undefined) { | |
return 0; | |
} | |
if (typeof o.valueOf === 'function') { | |
o = o.valueOf(); | |
if (o === false || o === null || o === undefined) { | |
return 0; | |
} | |
} | |
if (o === true) { | |
return 1; | |
} | |
var type = typeof o; | |
if (type === 'number') { | |
if (o !== o || o === Infinity) { | |
return 0; | |
} | |
var h = o | 0; | |
if (h !== o) { | |
h ^= o * 0xFFFFFFFF; | |
} | |
while (o > 0xFFFFFFFF) { | |
o /= 0xFFFFFFFF; | |
h ^= o; | |
} | |
return smi(h); | |
} | |
if (type === 'string') { | |
return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); | |
} | |
if (typeof o.hashCode === 'function') { | |
return o.hashCode(); | |
} | |
if (type === 'object') { | |
return hashJSObj(o); | |
} | |
if (typeof o.toString === 'function') { | |
return hashString(o.toString()); | |
} | |
throw new Error('Value type ' + type + ' cannot be hashed.'); | |
} | |
function cachedHashString(string) { | |
var hash = stringHashCache[string]; | |
if (hash === undefined) { | |
hash = hashString(string); | |
if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { | |
STRING_HASH_CACHE_SIZE = 0; | |
stringHashCache = {}; | |
} | |
STRING_HASH_CACHE_SIZE++; | |
stringHashCache[string] = hash; | |
} | |
return hash; | |
} | |
// http://jsperf.com/hashing-strings | |
function hashString(string) { | |
// This is the hash from JVM | |
// The hash code for a string is computed as | |
// s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], | |
// where s[i] is the ith character of the string and n is the length of | |
// the string. We "mod" the result to make it between 0 (inclusive) and 2^31 | |
// (exclusive) by dropping high bits. | |
var hash = 0; | |
for (var ii = 0; ii < string.length; ii++) { | |
hash = 31 * hash + string.charCodeAt(ii) | 0; | |
} | |
return smi(hash); | |
} | |
function hashJSObj(obj) { | |
var hash; | |
if (usingWeakMap) { | |
hash = weakMap.get(obj); | |
if (hash !== undefined) { | |
return hash; | |
} | |
} | |
hash = obj[UID_HASH_KEY]; | |
if (hash !== undefined) { | |
return hash; | |
} | |
if (!canDefineProperty) { | |
hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; | |
if (hash !== undefined) { | |
return hash; | |
} | |
hash = getIENodeHash(obj); | |
if (hash !== undefined) { | |
return hash; | |
} | |
} | |
hash = ++objHashUID; | |
if (objHashUID & 0x40000000) { | |
objHashUID = 0; | |
} | |
if (usingWeakMap) { | |
weakMap.set(obj, hash); | |
} else if (isExtensible !== undefined && isExtensible(obj) === false) { | |
throw new Error('Non-extensible objects are not allowed as keys.'); | |
} else if (canDefineProperty) { | |
Object.defineProperty(obj, UID_HASH_KEY, { | |
'enumerable': false, | |
'configurable': false, | |
'writable': false, | |
'value': hash | |
}); | |
} else if (obj.propertyIsEnumerable !== undefined && | |
obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { | |
// Since we can't define a non-enumerable property on the object | |
// we'll hijack one of the less-used non-enumerable properties to | |
// save our hash on it. Since this is a function it will not show up in | |
// `JSON.stringify` which is what we want. | |
obj.propertyIsEnumerable = function() { | |
return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); | |
}; | |
obj.propertyIsEnumerable[UID_HASH_KEY] = hash; | |
} else if (obj.nodeType !== undefined) { | |
// At this point we couldn't get the IE `uniqueID` to use as a hash | |
// and we couldn't use a non-enumerable property to exploit the | |
// dontEnum bug so we simply add the `UID_HASH_KEY` on the node | |
// itself. | |
obj[UID_HASH_KEY] = hash; | |
} else { | |
throw new Error('Unable to set a non-enumerable property on object.'); | |
} | |
return hash; | |
} | |
// Get references to ES5 object methods. | |
var isExtensible = Object.isExtensible; | |
// True if Object.defineProperty works as expected. IE8 fails this test. | |
var canDefineProperty = (function() { | |
try { | |
Object.defineProperty({}, '@', {}); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
}()); | |
// IE has a `uniqueID` property on DOM nodes. We can construct the hash from it | |
// and avoid memory leaks from the IE cloneNode bug. | |
function getIENodeHash(node) { | |
if (node && node.nodeType > 0) { | |
switch (node.nodeType) { | |
case 1: // Element | |
return node.uniqueID; | |
case 9: // Document | |
return node.documentElement && node.documentElement.uniqueID; | |
} | |
} | |
} | |
// If possible, use a WeakMap. | |
var usingWeakMap = typeof WeakMap === 'function'; | |
var weakMap; | |
if (usingWeakMap) { | |
weakMap = new WeakMap(); | |
} | |
var objHashUID = 0; | |
var UID_HASH_KEY = '__immutablehash__'; | |
if (typeof Symbol === 'function') { | |
UID_HASH_KEY = Symbol(UID_HASH_KEY); | |
} | |
var STRING_HASH_CACHE_MIN_STRLEN = 16; | |
var STRING_HASH_CACHE_MAX_SIZE = 255; | |
var STRING_HASH_CACHE_SIZE = 0; | |
var stringHashCache = {}; | |
function assertNotInfinite(size) { | |
invariant( | |
size !== Infinity, | |
'Cannot perform this action with an infinite size.' | |
); | |
} | |
createClass(Map, KeyedCollection); | |
// @pragma Construction | |
function Map(value) { | |
return value === null || value === undefined ? emptyMap() : | |
isMap(value) && !isOrdered(value) ? value : | |
emptyMap().withMutations(function(map ) { | |
var iter = KeyedIterable(value); | |
assertNotInfinite(iter.size); | |
iter.forEach(function(v, k) {return map.set(k, v)}); | |
}); | |
} | |
Map.of = function() {var keyValues = SLICE$0.call(arguments, 0); | |
return emptyMap().withMutations(function(map ) { | |
for (var i = 0; i < keyValues.length; i += 2) { | |
if (i + 1 >= keyValues.length) { | |
throw new Error('Missing value for key: ' + keyValues[i]); | |
} | |
map.set(keyValues[i], keyValues[i + 1]); | |
} | |
}); | |
}; | |
Map.prototype.toString = function() { | |
return this.__toString('Map {', '}'); | |
}; | |
// @pragma Access | |
Map.prototype.get = function(k, notSetValue) { | |
return this._root ? | |
this._root.get(0, undefined, k, notSetValue) : | |
notSetValue; | |
}; | |
// @pragma Modification | |
Map.prototype.set = function(k, v) { | |
return updateMap(this, k, v); | |
}; | |
Map.prototype.setIn = function(keyPath, v) { | |
return this.updateIn(keyPath, NOT_SET, function() {return v}); | |
}; | |
Map.prototype.remove = function(k) { | |
return updateMap(this, k, NOT_SET); | |
}; | |
Map.prototype.deleteIn = function(keyPath) { | |
return this.updateIn(keyPath, function() {return NOT_SET}); | |
}; | |
Map.prototype.update = function(k, notSetValue, updater) { | |
return arguments.length === 1 ? | |
k(this) : | |
this.updateIn([k], notSetValue, updater); | |
}; | |
Map.prototype.updateIn = function(keyPath, notSetValue, updater) { | |
if (!updater) { | |
updater = notSetValue; | |
notSetValue = undefined; | |
} | |
var updatedValue = updateInDeepMap( | |
this, | |
forceIterator(keyPath), | |
notSetValue, | |
updater | |
); | |
return updatedValue === NOT_SET ? undefined : updatedValue; | |
}; | |
Map.prototype.clear = function() { | |
if (this.size === 0) { | |
return this; | |
} | |
if (this.__ownerID) { | |
this.size = 0; | |
this._root = null; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return emptyMap(); | |
}; | |
// @pragma Composition | |
Map.prototype.merge = function(/*...iters*/) { | |
return mergeIntoMapWith(this, undefined, arguments); | |
}; | |
Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); | |
return mergeIntoMapWith(this, merger, iters); | |
}; | |
Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); | |
return this.updateIn( | |
keyPath, | |
emptyMap(), | |
function(m ) {return typeof m.merge === 'function' ? | |
m.merge.apply(m, iters) : | |
iters[iters.length - 1]} | |
); | |
}; | |
Map.prototype.mergeDeep = function(/*...iters*/) { | |
return mergeIntoMapWith(this, deepMerger, arguments); | |
}; | |
Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); | |
return mergeIntoMapWith(this, deepMergerWith(merger), iters); | |
}; | |
Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); | |
return this.updateIn( | |
keyPath, | |
emptyMap(), | |
function(m ) {return typeof m.mergeDeep === 'function' ? | |
m.mergeDeep.apply(m, iters) : | |
iters[iters.length - 1]} | |
); | |
}; | |
Map.prototype.sort = function(comparator) { | |
// Late binding | |
return OrderedMap(sortFactory(this, comparator)); | |
}; | |
Map.prototype.sortBy = function(mapper, comparator) { | |
// Late binding | |
return OrderedMap(sortFactory(this, comparator, mapper)); | |
}; | |
// @pragma Mutability | |
Map.prototype.withMutations = function(fn) { | |
var mutable = this.asMutable(); | |
fn(mutable); | |
return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; | |
}; | |
Map.prototype.asMutable = function() { | |
return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); | |
}; | |
Map.prototype.asImmutable = function() { | |
return this.__ensureOwner(); | |
}; | |
Map.prototype.wasAltered = function() { | |
return this.__altered; | |
}; | |
Map.prototype.__iterator = function(type, reverse) { | |
return new MapIterator(this, type, reverse); | |
}; | |
Map.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
var iterations = 0; | |
this._root && this._root.iterate(function(entry ) { | |
iterations++; | |
return fn(entry[1], entry[0], this$0); | |
}, reverse); | |
return iterations; | |
}; | |
Map.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
this.__altered = false; | |
return this; | |
} | |
return makeMap(this.size, this._root, ownerID, this.__hash); | |
}; | |
function isMap(maybeMap) { | |
return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); | |
} | |
Map.isMap = isMap; | |
var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; | |
var MapPrototype = Map.prototype; | |
MapPrototype[IS_MAP_SENTINEL] = true; | |
MapPrototype[DELETE] = MapPrototype.remove; | |
MapPrototype.removeIn = MapPrototype.deleteIn; | |
// #pragma Trie Nodes | |
function ArrayMapNode(ownerID, entries) { | |
this.ownerID = ownerID; | |
this.entries = entries; | |
} | |
ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { | |
var entries = this.entries; | |
for (var ii = 0, len = entries.length; ii < len; ii++) { | |
if (is(key, entries[ii][0])) { | |
return entries[ii][1]; | |
} | |
} | |
return notSetValue; | |
}; | |
ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
var removed = value === NOT_SET; | |
var entries = this.entries; | |
var idx = 0; | |
for (var len = entries.length; idx < len; idx++) { | |
if (is(key, entries[idx][0])) { | |
break; | |
} | |
} | |
var exists = idx < len; | |
if (exists ? entries[idx][1] === value : removed) { | |
return this; | |
} | |
SetRef(didAlter); | |
(removed || !exists) && SetRef(didChangeSize); | |
if (removed && entries.length === 1) { | |
return; // undefined | |
} | |
if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { | |
return createNodes(ownerID, entries, key, value); | |
} | |
var isEditable = ownerID && ownerID === this.ownerID; | |
var newEntries = isEditable ? entries : arrCopy(entries); | |
if (exists) { | |
if (removed) { | |
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); | |
} else { | |
newEntries[idx] = [key, value]; | |
} | |
} else { | |
newEntries.push([key, value]); | |
} | |
if (isEditable) { | |
this.entries = newEntries; | |
return this; | |
} | |
return new ArrayMapNode(ownerID, newEntries); | |
}; | |
function BitmapIndexedNode(ownerID, bitmap, nodes) { | |
this.ownerID = ownerID; | |
this.bitmap = bitmap; | |
this.nodes = nodes; | |
} | |
BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) { | |
if (keyHash === undefined) { | |
keyHash = hash(key); | |
} | |
var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); | |
var bitmap = this.bitmap; | |
return (bitmap & bit) === 0 ? notSetValue : | |
this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); | |
}; | |
BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
if (keyHash === undefined) { | |
keyHash = hash(key); | |
} | |
var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; | |
var bit = 1 << keyHashFrag; | |
var bitmap = this.bitmap; | |
var exists = (bitmap & bit) !== 0; | |
if (!exists && value === NOT_SET) { | |
return this; | |
} | |
var idx = popCount(bitmap & (bit - 1)); | |
var nodes = this.nodes; | |
var node = exists ? nodes[idx] : undefined; | |
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); | |
if (newNode === node) { | |
return this; | |
} | |
if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { | |
return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); | |
} | |
if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { | |
return nodes[idx ^ 1]; | |
} | |
if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { | |
return newNode; | |
} | |
var isEditable = ownerID && ownerID === this.ownerID; | |
var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; | |
var newNodes = exists ? newNode ? | |
setIn(nodes, idx, newNode, isEditable) : | |
spliceOut(nodes, idx, isEditable) : | |
spliceIn(nodes, idx, newNode, isEditable); | |
if (isEditable) { | |
this.bitmap = newBitmap; | |
this.nodes = newNodes; | |
return this; | |
} | |
return new BitmapIndexedNode(ownerID, newBitmap, newNodes); | |
}; | |
function HashArrayMapNode(ownerID, count, nodes) { | |
this.ownerID = ownerID; | |
this.count = count; | |
this.nodes = nodes; | |
} | |
HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { | |
if (keyHash === undefined) { | |
keyHash = hash(key); | |
} | |
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; | |
var node = this.nodes[idx]; | |
return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; | |
}; | |
HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
if (keyHash === undefined) { | |
keyHash = hash(key); | |
} | |
var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; | |
var removed = value === NOT_SET; | |
var nodes = this.nodes; | |
var node = nodes[idx]; | |
if (removed && !node) { | |
return this; | |
} | |
var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); | |
if (newNode === node) { | |
return this; | |
} | |
var newCount = this.count; | |
if (!node) { | |
newCount++; | |
} else if (!newNode) { | |
newCount--; | |
if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { | |
return packNodes(ownerID, nodes, newCount, idx); | |
} | |
} | |
var isEditable = ownerID && ownerID === this.ownerID; | |
var newNodes = setIn(nodes, idx, newNode, isEditable); | |
if (isEditable) { | |
this.count = newCount; | |
this.nodes = newNodes; | |
return this; | |
} | |
return new HashArrayMapNode(ownerID, newCount, newNodes); | |
}; | |
function HashCollisionNode(ownerID, keyHash, entries) { | |
this.ownerID = ownerID; | |
this.keyHash = keyHash; | |
this.entries = entries; | |
} | |
HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) { | |
var entries = this.entries; | |
for (var ii = 0, len = entries.length; ii < len; ii++) { | |
if (is(key, entries[ii][0])) { | |
return entries[ii][1]; | |
} | |
} | |
return notSetValue; | |
}; | |
HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
if (keyHash === undefined) { | |
keyHash = hash(key); | |
} | |
var removed = value === NOT_SET; | |
if (keyHash !== this.keyHash) { | |
if (removed) { | |
return this; | |
} | |
SetRef(didAlter); | |
SetRef(didChangeSize); | |
return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); | |
} | |
var entries = this.entries; | |
var idx = 0; | |
for (var len = entries.length; idx < len; idx++) { | |
if (is(key, entries[idx][0])) { | |
break; | |
} | |
} | |
var exists = idx < len; | |
if (exists ? entries[idx][1] === value : removed) { | |
return this; | |
} | |
SetRef(didAlter); | |
(removed || !exists) && SetRef(didChangeSize); | |
if (removed && len === 2) { | |
return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); | |
} | |
var isEditable = ownerID && ownerID === this.ownerID; | |
var newEntries = isEditable ? entries : arrCopy(entries); | |
if (exists) { | |
if (removed) { | |
idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); | |
} else { | |
newEntries[idx] = [key, value]; | |
} | |
} else { | |
newEntries.push([key, value]); | |
} | |
if (isEditable) { | |
this.entries = newEntries; | |
return this; | |
} | |
return new HashCollisionNode(ownerID, this.keyHash, newEntries); | |
}; | |
function ValueNode(ownerID, keyHash, entry) { | |
this.ownerID = ownerID; | |
this.keyHash = keyHash; | |
this.entry = entry; | |
} | |
ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) { | |
return is(key, this.entry[0]) ? this.entry[1] : notSetValue; | |
}; | |
ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
var removed = value === NOT_SET; | |
var keyMatch = is(key, this.entry[0]); | |
if (keyMatch ? value === this.entry[1] : removed) { | |
return this; | |
} | |
SetRef(didAlter); | |
if (removed) { | |
SetRef(didChangeSize); | |
return; // undefined | |
} | |
if (keyMatch) { | |
if (ownerID && ownerID === this.ownerID) { | |
this.entry[1] = value; | |
return this; | |
} | |
return new ValueNode(ownerID, this.keyHash, [key, value]); | |
} | |
SetRef(didChangeSize); | |
return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); | |
}; | |
// #pragma Iterators | |
ArrayMapNode.prototype.iterate = | |
HashCollisionNode.prototype.iterate = function (fn, reverse) { | |
var entries = this.entries; | |
for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { | |
if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { | |
return false; | |
} | |
} | |
} | |
BitmapIndexedNode.prototype.iterate = | |
HashArrayMapNode.prototype.iterate = function (fn, reverse) { | |
var nodes = this.nodes; | |
for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { | |
var node = nodes[reverse ? maxIndex - ii : ii]; | |
if (node && node.iterate(fn, reverse) === false) { | |
return false; | |
} | |
} | |
} | |
ValueNode.prototype.iterate = function (fn, reverse) { | |
return fn(this.entry); | |
} | |
createClass(MapIterator, Iterator); | |
function MapIterator(map, type, reverse) { | |
this._type = type; | |
this._reverse = reverse; | |
this._stack = map._root && mapIteratorFrame(map._root); | |
} | |
MapIterator.prototype.next = function() { | |
var type = this._type; | |
var stack = this._stack; | |
while (stack) { | |
var node = stack.node; | |
var index = stack.index++; | |
var maxIndex; | |
if (node.entry) { | |
if (index === 0) { | |
return mapIteratorValue(type, node.entry); | |
} | |
} else if (node.entries) { | |
maxIndex = node.entries.length - 1; | |
if (index <= maxIndex) { | |
return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); | |
} | |
} else { | |
maxIndex = node.nodes.length - 1; | |
if (index <= maxIndex) { | |
var subNode = node.nodes[this._reverse ? maxIndex - index : index]; | |
if (subNode) { | |
if (subNode.entry) { | |
return mapIteratorValue(type, subNode.entry); | |
} | |
stack = this._stack = mapIteratorFrame(subNode, stack); | |
} | |
continue; | |
} | |
} | |
stack = this._stack = this._stack.__prev; | |
} | |
return iteratorDone(); | |
}; | |
function mapIteratorValue(type, entry) { | |
return iteratorValue(type, entry[0], entry[1]); | |
} | |
function mapIteratorFrame(node, prev) { | |
return { | |
node: node, | |
index: 0, | |
__prev: prev | |
}; | |
} | |
function makeMap(size, root, ownerID, hash) { | |
var map = Object.create(MapPrototype); | |
map.size = size; | |
map._root = root; | |
map.__ownerID = ownerID; | |
map.__hash = hash; | |
map.__altered = false; | |
return map; | |
} | |
var EMPTY_MAP; | |
function emptyMap() { | |
return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); | |
} | |
function updateMap(map, k, v) { | |
var newRoot; | |
var newSize; | |
if (!map._root) { | |
if (v === NOT_SET) { | |
return map; | |
} | |
newSize = 1; | |
newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); | |
} else { | |
var didChangeSize = MakeRef(CHANGE_LENGTH); | |
var didAlter = MakeRef(DID_ALTER); | |
newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); | |
if (!didAlter.value) { | |
return map; | |
} | |
newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); | |
} | |
if (map.__ownerID) { | |
map.size = newSize; | |
map._root = newRoot; | |
map.__hash = undefined; | |
map.__altered = true; | |
return map; | |
} | |
return newRoot ? makeMap(newSize, newRoot) : emptyMap(); | |
} | |
function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { | |
if (!node) { | |
if (value === NOT_SET) { | |
return node; | |
} | |
SetRef(didAlter); | |
SetRef(didChangeSize); | |
return new ValueNode(ownerID, keyHash, [key, value]); | |
} | |
return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); | |
} | |
function isLeafNode(node) { | |
return node.constructor === ValueNode || node.constructor === HashCollisionNode; | |
} | |
function mergeIntoNode(node, ownerID, shift, keyHash, entry) { | |
if (node.keyHash === keyHash) { | |
return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); | |
} | |
var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; | |
var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; | |
var newNode; | |
var nodes = idx1 === idx2 ? | |
[mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : | |
((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); | |
return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); | |
} | |
function createNodes(ownerID, entries, key, value) { | |
if (!ownerID) { | |
ownerID = new OwnerID(); | |
} | |
var node = new ValueNode(ownerID, hash(key), [key, value]); | |
for (var ii = 0; ii < entries.length; ii++) { | |
var entry = entries[ii]; | |
node = node.update(ownerID, 0, undefined, entry[0], entry[1]); | |
} | |
return node; | |
} | |
function packNodes(ownerID, nodes, count, excluding) { | |
var bitmap = 0; | |
var packedII = 0; | |
var packedNodes = new Array(count); | |
for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { | |
var node = nodes[ii]; | |
if (node !== undefined && ii !== excluding) { | |
bitmap |= bit; | |
packedNodes[packedII++] = node; | |
} | |
} | |
return new BitmapIndexedNode(ownerID, bitmap, packedNodes); | |
} | |
function expandNodes(ownerID, nodes, bitmap, including, node) { | |
var count = 0; | |
var expandedNodes = new Array(SIZE); | |
for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { | |
expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; | |
} | |
expandedNodes[including] = node; | |
return new HashArrayMapNode(ownerID, count + 1, expandedNodes); | |
} | |
function mergeIntoMapWith(map, merger, iterables) { | |
var iters = []; | |
for (var ii = 0; ii < iterables.length; ii++) { | |
var value = iterables[ii]; | |
var iter = KeyedIterable(value); | |
if (!isIterable(value)) { | |
iter = iter.map(function(v ) {return fromJS(v)}); | |
} | |
iters.push(iter); | |
} | |
return mergeIntoCollectionWith(map, merger, iters); | |
} | |
function deepMerger(existing, value, key) { | |
return existing && existing.mergeDeep && isIterable(value) ? | |
existing.mergeDeep(value) : | |
is(existing, value) ? existing : value; | |
} | |
function deepMergerWith(merger) { | |
return function(existing, value, key) { | |
if (existing && existing.mergeDeepWith && isIterable(value)) { | |
return existing.mergeDeepWith(merger, value); | |
} | |
var nextValue = merger(existing, value, key); | |
return is(existing, nextValue) ? existing : nextValue; | |
}; | |
} | |
function mergeIntoCollectionWith(collection, merger, iters) { | |
iters = iters.filter(function(x ) {return x.size !== 0}); | |
if (iters.length === 0) { | |
return collection; | |
} | |
if (collection.size === 0 && !collection.__ownerID && iters.length === 1) { | |
return collection.constructor(iters[0]); | |
} | |
return collection.withMutations(function(collection ) { | |
var mergeIntoMap = merger ? | |
function(value, key) { | |
collection.update(key, NOT_SET, function(existing ) | |
{return existing === NOT_SET ? value : merger(existing, value, key)} | |
); | |
} : | |
function(value, key) { | |
collection.set(key, value); | |
} | |
for (var ii = 0; ii < iters.length; ii++) { | |
iters[ii].forEach(mergeIntoMap); | |
} | |
}); | |
} | |
function updateInDeepMap(existing, keyPathIter, notSetValue, updater) { | |
var isNotSet = existing === NOT_SET; | |
var step = keyPathIter.next(); | |
if (step.done) { | |
var existingValue = isNotSet ? notSetValue : existing; | |
var newValue = updater(existingValue); | |
return newValue === existingValue ? existing : newValue; | |
} | |
invariant( | |
isNotSet || (existing && existing.set), | |
'invalid keyPath' | |
); | |
var key = step.value; | |
var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET); | |
var nextUpdated = updateInDeepMap( | |
nextExisting, | |
keyPathIter, | |
notSetValue, | |
updater | |
); | |
return nextUpdated === nextExisting ? existing : | |
nextUpdated === NOT_SET ? existing.remove(key) : | |
(isNotSet ? emptyMap() : existing).set(key, nextUpdated); | |
} | |
function popCount(x) { | |
x = x - ((x >> 1) & 0x55555555); | |
x = (x & 0x33333333) + ((x >> 2) & 0x33333333); | |
x = (x + (x >> 4)) & 0x0f0f0f0f; | |
x = x + (x >> 8); | |
x = x + (x >> 16); | |
return x & 0x7f; | |
} | |
function setIn(array, idx, val, canEdit) { | |
var newArray = canEdit ? array : arrCopy(array); | |
newArray[idx] = val; | |
return newArray; | |
} | |
function spliceIn(array, idx, val, canEdit) { | |
var newLen = array.length + 1; | |
if (canEdit && idx + 1 === newLen) { | |
array[idx] = val; | |
return array; | |
} | |
var newArray = new Array(newLen); | |
var after = 0; | |
for (var ii = 0; ii < newLen; ii++) { | |
if (ii === idx) { | |
newArray[ii] = val; | |
after = -1; | |
} else { | |
newArray[ii] = array[ii + after]; | |
} | |
} | |
return newArray; | |
} | |
function spliceOut(array, idx, canEdit) { | |
var newLen = array.length - 1; | |
if (canEdit && idx === newLen) { | |
array.pop(); | |
return array; | |
} | |
var newArray = new Array(newLen); | |
var after = 0; | |
for (var ii = 0; ii < newLen; ii++) { | |
if (ii === idx) { | |
after = 1; | |
} | |
newArray[ii] = array[ii + after]; | |
} | |
return newArray; | |
} | |
var MAX_ARRAY_MAP_SIZE = SIZE / 4; | |
var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; | |
var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; | |
createClass(List, IndexedCollection); | |
// @pragma Construction | |
function List(value) { | |
var empty = emptyList(); | |
if (value === null || value === undefined) { | |
return empty; | |
} | |
if (isList(value)) { | |
return value; | |
} | |
var iter = IndexedIterable(value); | |
var size = iter.size; | |
if (size === 0) { | |
return empty; | |
} | |
assertNotInfinite(size); | |
if (size > 0 && size < SIZE) { | |
return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); | |
} | |
return empty.withMutations(function(list ) { | |
list.setSize(size); | |
iter.forEach(function(v, i) {return list.set(i, v)}); | |
}); | |
} | |
List.of = function(/*...values*/) { | |
return this(arguments); | |
}; | |
List.prototype.toString = function() { | |
return this.__toString('List [', ']'); | |
}; | |
// @pragma Access | |
List.prototype.get = function(index, notSetValue) { | |
index = wrapIndex(this, index); | |
if (index >= 0 && index < this.size) { | |
index += this._origin; | |
var node = listNodeFor(this, index); | |
return node && node.array[index & MASK]; | |
} | |
return notSetValue; | |
}; | |
// @pragma Modification | |
List.prototype.set = function(index, value) { | |
return updateList(this, index, value); | |
}; | |
List.prototype.remove = function(index) { | |
return !this.has(index) ? this : | |
index === 0 ? this.shift() : | |
index === this.size - 1 ? this.pop() : | |
this.splice(index, 1); | |
}; | |
List.prototype.insert = function(index, value) { | |
return this.splice(index, 0, value); | |
}; | |
List.prototype.clear = function() { | |
if (this.size === 0) { | |
return this; | |
} | |
if (this.__ownerID) { | |
this.size = this._origin = this._capacity = 0; | |
this._level = SHIFT; | |
this._root = this._tail = null; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return emptyList(); | |
}; | |
List.prototype.push = function(/*...values*/) { | |
var values = arguments; | |
var oldSize = this.size; | |
return this.withMutations(function(list ) { | |
setListBounds(list, 0, oldSize + values.length); | |
for (var ii = 0; ii < values.length; ii++) { | |
list.set(oldSize + ii, values[ii]); | |
} | |
}); | |
}; | |
List.prototype.pop = function() { | |
return setListBounds(this, 0, -1); | |
}; | |
List.prototype.unshift = function(/*...values*/) { | |
var values = arguments; | |
return this.withMutations(function(list ) { | |
setListBounds(list, -values.length); | |
for (var ii = 0; ii < values.length; ii++) { | |
list.set(ii, values[ii]); | |
} | |
}); | |
}; | |
List.prototype.shift = function() { | |
return setListBounds(this, 1); | |
}; | |
// @pragma Composition | |
List.prototype.merge = function(/*...iters*/) { | |
return mergeIntoListWith(this, undefined, arguments); | |
}; | |
List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); | |
return mergeIntoListWith(this, merger, iters); | |
}; | |
List.prototype.mergeDeep = function(/*...iters*/) { | |
return mergeIntoListWith(this, deepMerger, arguments); | |
}; | |
List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); | |
return mergeIntoListWith(this, deepMergerWith(merger), iters); | |
}; | |
List.prototype.setSize = function(size) { | |
return setListBounds(this, 0, size); | |
}; | |
// @pragma Iteration | |
List.prototype.slice = function(begin, end) { | |
var size = this.size; | |
if (wholeSlice(begin, end, size)) { | |
return this; | |
} | |
return setListBounds( | |
this, | |
resolveBegin(begin, size), | |
resolveEnd(end, size) | |
); | |
}; | |
List.prototype.__iterator = function(type, reverse) { | |
var index = 0; | |
var values = iterateList(this, reverse); | |
return new Iterator(function() { | |
var value = values(); | |
return value === DONE ? | |
iteratorDone() : | |
iteratorValue(type, index++, value); | |
}); | |
}; | |
List.prototype.__iterate = function(fn, reverse) { | |
var index = 0; | |
var values = iterateList(this, reverse); | |
var value; | |
while ((value = values()) !== DONE) { | |
if (fn(value, index++, this) === false) { | |
break; | |
} | |
} | |
return index; | |
}; | |
List.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
return this; | |
} | |
return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); | |
}; | |
function isList(maybeList) { | |
return !!(maybeList && maybeList[IS_LIST_SENTINEL]); | |
} | |
List.isList = isList; | |
var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; | |
var ListPrototype = List.prototype; | |
ListPrototype[IS_LIST_SENTINEL] = true; | |
ListPrototype[DELETE] = ListPrototype.remove; | |
ListPrototype.setIn = MapPrototype.setIn; | |
ListPrototype.deleteIn = | |
ListPrototype.removeIn = MapPrototype.removeIn; | |
ListPrototype.update = MapPrototype.update; | |
ListPrototype.updateIn = MapPrototype.updateIn; | |
ListPrototype.mergeIn = MapPrototype.mergeIn; | |
ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; | |
ListPrototype.withMutations = MapPrototype.withMutations; | |
ListPrototype.asMutable = MapPrototype.asMutable; | |
ListPrototype.asImmutable = MapPrototype.asImmutable; | |
ListPrototype.wasAltered = MapPrototype.wasAltered; | |
function VNode(array, ownerID) { | |
this.array = array; | |
this.ownerID = ownerID; | |
} | |
// TODO: seems like these methods are very similar | |
VNode.prototype.removeBefore = function(ownerID, level, index) { | |
if (index === level ? 1 << level : 0 || this.array.length === 0) { | |
return this; | |
} | |
var originIndex = (index >>> level) & MASK; | |
if (originIndex >= this.array.length) { | |
return new VNode([], ownerID); | |
} | |
var removingFirst = originIndex === 0; | |
var newChild; | |
if (level > 0) { | |
var oldChild = this.array[originIndex]; | |
newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); | |
if (newChild === oldChild && removingFirst) { | |
return this; | |
} | |
} | |
if (removingFirst && !newChild) { | |
return this; | |
} | |
var editable = editableVNode(this, ownerID); | |
if (!removingFirst) { | |
for (var ii = 0; ii < originIndex; ii++) { | |
editable.array[ii] = undefined; | |
} | |
} | |
if (newChild) { | |
editable.array[originIndex] = newChild; | |
} | |
return editable; | |
}; | |
VNode.prototype.removeAfter = function(ownerID, level, index) { | |
if (index === (level ? 1 << level : 0) || this.array.length === 0) { | |
return this; | |
} | |
var sizeIndex = ((index - 1) >>> level) & MASK; | |
if (sizeIndex >= this.array.length) { | |
return this; | |
} | |
var newChild; | |
if (level > 0) { | |
var oldChild = this.array[sizeIndex]; | |
newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); | |
if (newChild === oldChild && sizeIndex === this.array.length - 1) { | |
return this; | |
} | |
} | |
var editable = editableVNode(this, ownerID); | |
editable.array.splice(sizeIndex + 1); | |
if (newChild) { | |
editable.array[sizeIndex] = newChild; | |
} | |
return editable; | |
}; | |
var DONE = {}; | |
function iterateList(list, reverse) { | |
var left = list._origin; | |
var right = list._capacity; | |
var tailPos = getTailOffset(right); | |
var tail = list._tail; | |
return iterateNodeOrLeaf(list._root, list._level, 0); | |
function iterateNodeOrLeaf(node, level, offset) { | |
return level === 0 ? | |
iterateLeaf(node, offset) : | |
iterateNode(node, level, offset); | |
} | |
function iterateLeaf(node, offset) { | |
var array = offset === tailPos ? tail && tail.array : node && node.array; | |
var from = offset > left ? 0 : left - offset; | |
var to = right - offset; | |
if (to > SIZE) { | |
to = SIZE; | |
} | |
return function() { | |
if (from === to) { | |
return DONE; | |
} | |
var idx = reverse ? --to : from++; | |
return array && array[idx]; | |
}; | |
} | |
function iterateNode(node, level, offset) { | |
var values; | |
var array = node && node.array; | |
var from = offset > left ? 0 : (left - offset) >> level; | |
var to = ((right - offset) >> level) + 1; | |
if (to > SIZE) { | |
to = SIZE; | |
} | |
return function() { | |
do { | |
if (values) { | |
var value = values(); | |
if (value !== DONE) { | |
return value; | |
} | |
values = null; | |
} | |
if (from === to) { | |
return DONE; | |
} | |
var idx = reverse ? --to : from++; | |
values = iterateNodeOrLeaf( | |
array && array[idx], level - SHIFT, offset + (idx << level) | |
); | |
} while (true); | |
}; | |
} | |
} | |
function makeList(origin, capacity, level, root, tail, ownerID, hash) { | |
var list = Object.create(ListPrototype); | |
list.size = capacity - origin; | |
list._origin = origin; | |
list._capacity = capacity; | |
list._level = level; | |
list._root = root; | |
list._tail = tail; | |
list.__ownerID = ownerID; | |
list.__hash = hash; | |
list.__altered = false; | |
return list; | |
} | |
var EMPTY_LIST; | |
function emptyList() { | |
return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); | |
} | |
function updateList(list, index, value) { | |
index = wrapIndex(list, index); | |
if (index !== index) { | |
return list; | |
} | |
if (index >= list.size || index < 0) { | |
return list.withMutations(function(list ) { | |
index < 0 ? | |
setListBounds(list, index).set(0, value) : | |
setListBounds(list, 0, index + 1).set(index, value) | |
}); | |
} | |
index += list._origin; | |
var newTail = list._tail; | |
var newRoot = list._root; | |
var didAlter = MakeRef(DID_ALTER); | |
if (index >= getTailOffset(list._capacity)) { | |
newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); | |
} else { | |
newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); | |
} | |
if (!didAlter.value) { | |
return list; | |
} | |
if (list.__ownerID) { | |
list._root = newRoot; | |
list._tail = newTail; | |
list.__hash = undefined; | |
list.__altered = true; | |
return list; | |
} | |
return makeList(list._origin, list._capacity, list._level, newRoot, newTail); | |
} | |
function updateVNode(node, ownerID, level, index, value, didAlter) { | |
var idx = (index >>> level) & MASK; | |
var nodeHas = node && idx < node.array.length; | |
if (!nodeHas && value === undefined) { | |
return node; | |
} | |
var newNode; | |
if (level > 0) { | |
var lowerNode = node && node.array[idx]; | |
var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); | |
if (newLowerNode === lowerNode) { | |
return node; | |
} | |
newNode = editableVNode(node, ownerID); | |
newNode.array[idx] = newLowerNode; | |
return newNode; | |
} | |
if (nodeHas && node.array[idx] === value) { | |
return node; | |
} | |
SetRef(didAlter); | |
newNode = editableVNode(node, ownerID); | |
if (value === undefined && idx === newNode.array.length - 1) { | |
newNode.array.pop(); | |
} else { | |
newNode.array[idx] = value; | |
} | |
return newNode; | |
} | |
function editableVNode(node, ownerID) { | |
if (ownerID && node && ownerID === node.ownerID) { | |
return node; | |
} | |
return new VNode(node ? node.array.slice() : [], ownerID); | |
} | |
function listNodeFor(list, rawIndex) { | |
if (rawIndex >= getTailOffset(list._capacity)) { | |
return list._tail; | |
} | |
if (rawIndex < 1 << (list._level + SHIFT)) { | |
var node = list._root; | |
var level = list._level; | |
while (node && level > 0) { | |
node = node.array[(rawIndex >>> level) & MASK]; | |
level -= SHIFT; | |
} | |
return node; | |
} | |
} | |
function setListBounds(list, begin, end) { | |
// Sanitize begin & end using this shorthand for ToInt32(argument) | |
// http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 | |
if (begin !== undefined) { | |
begin = begin | 0; | |
} | |
if (end !== undefined) { | |
end = end | 0; | |
} | |
var owner = list.__ownerID || new OwnerID(); | |
var oldOrigin = list._origin; | |
var oldCapacity = list._capacity; | |
var newOrigin = oldOrigin + begin; | |
var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; | |
if (newOrigin === oldOrigin && newCapacity === oldCapacity) { | |
return list; | |
} | |
// If it's going to end after it starts, it's empty. | |
if (newOrigin >= newCapacity) { | |
return list.clear(); | |
} | |
var newLevel = list._level; | |
var newRoot = list._root; | |
// New origin might need creating a higher root. | |
var offsetShift = 0; | |
while (newOrigin + offsetShift < 0) { | |
newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); | |
newLevel += SHIFT; | |
offsetShift += 1 << newLevel; | |
} | |
if (offsetShift) { | |
newOrigin += offsetShift; | |
oldOrigin += offsetShift; | |
newCapacity += offsetShift; | |
oldCapacity += offsetShift; | |
} | |
var oldTailOffset = getTailOffset(oldCapacity); | |
var newTailOffset = getTailOffset(newCapacity); | |
// New size might need creating a higher root. | |
while (newTailOffset >= 1 << (newLevel + SHIFT)) { | |
newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); | |
newLevel += SHIFT; | |
} | |
// Locate or create the new tail. | |
var oldTail = list._tail; | |
var newTail = newTailOffset < oldTailOffset ? | |
listNodeFor(list, newCapacity - 1) : | |
newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; | |
// Merge Tail into tree. | |
if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { | |
newRoot = editableVNode(newRoot, owner); | |
var node = newRoot; | |
for (var level = newLevel; level > SHIFT; level -= SHIFT) { | |
var idx = (oldTailOffset >>> level) & MASK; | |
node = node.array[idx] = editableVNode(node.array[idx], owner); | |
} | |
node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; | |
} | |
// If the size has been reduced, there's a chance the tail needs to be trimmed. | |
if (newCapacity < oldCapacity) { | |
newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); | |
} | |
// If the new origin is within the tail, then we do not need a root. | |
if (newOrigin >= newTailOffset) { | |
newOrigin -= newTailOffset; | |
newCapacity -= newTailOffset; | |
newLevel = SHIFT; | |
newRoot = null; | |
newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); | |
// Otherwise, if the root has been trimmed, garbage collect. | |
} else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { | |
offsetShift = 0; | |
// Identify the new top root node of the subtree of the old root. | |
while (newRoot) { | |
var beginIndex = (newOrigin >>> newLevel) & MASK; | |
if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { | |
break; | |
} | |
if (beginIndex) { | |
offsetShift += (1 << newLevel) * beginIndex; | |
} | |
newLevel -= SHIFT; | |
newRoot = newRoot.array[beginIndex]; | |
} | |
// Trim the new sides of the new root. | |
if (newRoot && newOrigin > oldOrigin) { | |
newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); | |
} | |
if (newRoot && newTailOffset < oldTailOffset) { | |
newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); | |
} | |
if (offsetShift) { | |
newOrigin -= offsetShift; | |
newCapacity -= offsetShift; | |
} | |
} | |
if (list.__ownerID) { | |
list.size = newCapacity - newOrigin; | |
list._origin = newOrigin; | |
list._capacity = newCapacity; | |
list._level = newLevel; | |
list._root = newRoot; | |
list._tail = newTail; | |
list.__hash = undefined; | |
list.__altered = true; | |
return list; | |
} | |
return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); | |
} | |
function mergeIntoListWith(list, merger, iterables) { | |
var iters = []; | |
var maxSize = 0; | |
for (var ii = 0; ii < iterables.length; ii++) { | |
var value = iterables[ii]; | |
var iter = IndexedIterable(value); | |
if (iter.size > maxSize) { | |
maxSize = iter.size; | |
} | |
if (!isIterable(value)) { | |
iter = iter.map(function(v ) {return fromJS(v)}); | |
} | |
iters.push(iter); | |
} | |
if (maxSize > list.size) { | |
list = list.setSize(maxSize); | |
} | |
return mergeIntoCollectionWith(list, merger, iters); | |
} | |
function getTailOffset(size) { | |
return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); | |
} | |
createClass(OrderedMap, Map); | |
// @pragma Construction | |
function OrderedMap(value) { | |
return value === null || value === undefined ? emptyOrderedMap() : | |
isOrderedMap(value) ? value : | |
emptyOrderedMap().withMutations(function(map ) { | |
var iter = KeyedIterable(value); | |
assertNotInfinite(iter.size); | |
iter.forEach(function(v, k) {return map.set(k, v)}); | |
}); | |
} | |
OrderedMap.of = function(/*...values*/) { | |
return this(arguments); | |
}; | |
OrderedMap.prototype.toString = function() { | |
return this.__toString('OrderedMap {', '}'); | |
}; | |
// @pragma Access | |
OrderedMap.prototype.get = function(k, notSetValue) { | |
var index = this._map.get(k); | |
return index !== undefined ? this._list.get(index)[1] : notSetValue; | |
}; | |
// @pragma Modification | |
OrderedMap.prototype.clear = function() { | |
if (this.size === 0) { | |
return this; | |
} | |
if (this.__ownerID) { | |
this.size = 0; | |
this._map.clear(); | |
this._list.clear(); | |
return this; | |
} | |
return emptyOrderedMap(); | |
}; | |
OrderedMap.prototype.set = function(k, v) { | |
return updateOrderedMap(this, k, v); | |
}; | |
OrderedMap.prototype.remove = function(k) { | |
return updateOrderedMap(this, k, NOT_SET); | |
}; | |
OrderedMap.prototype.wasAltered = function() { | |
return this._map.wasAltered() || this._list.wasAltered(); | |
}; | |
OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
return this._list.__iterate( | |
function(entry ) {return entry && fn(entry[1], entry[0], this$0)}, | |
reverse | |
); | |
}; | |
OrderedMap.prototype.__iterator = function(type, reverse) { | |
return this._list.fromEntrySeq().__iterator(type, reverse); | |
}; | |
OrderedMap.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
var newMap = this._map.__ensureOwner(ownerID); | |
var newList = this._list.__ensureOwner(ownerID); | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
this._map = newMap; | |
this._list = newList; | |
return this; | |
} | |
return makeOrderedMap(newMap, newList, ownerID, this.__hash); | |
}; | |
function isOrderedMap(maybeOrderedMap) { | |
return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); | |
} | |
OrderedMap.isOrderedMap = isOrderedMap; | |
OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; | |
OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; | |
function makeOrderedMap(map, list, ownerID, hash) { | |
var omap = Object.create(OrderedMap.prototype); | |
omap.size = map ? map.size : 0; | |
omap._map = map; | |
omap._list = list; | |
omap.__ownerID = ownerID; | |
omap.__hash = hash; | |
return omap; | |
} | |
var EMPTY_ORDERED_MAP; | |
function emptyOrderedMap() { | |
return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); | |
} | |
function updateOrderedMap(omap, k, v) { | |
var map = omap._map; | |
var list = omap._list; | |
var i = map.get(k); | |
var has = i !== undefined; | |
var newMap; | |
var newList; | |
if (v === NOT_SET) { // removed | |
if (!has) { | |
return omap; | |
} | |
if (list.size >= SIZE && list.size >= map.size * 2) { | |
newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx}); | |
newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap(); | |
if (omap.__ownerID) { | |
newMap.__ownerID = newList.__ownerID = omap.__ownerID; | |
} | |
} else { | |
newMap = map.remove(k); | |
newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); | |
} | |
} else { | |
if (has) { | |
if (v === list.get(i)[1]) { | |
return omap; | |
} | |
newMap = map; | |
newList = list.set(i, [k, v]); | |
} else { | |
newMap = map.set(k, list.size); | |
newList = list.set(list.size, [k, v]); | |
} | |
} | |
if (omap.__ownerID) { | |
omap.size = newMap.size; | |
omap._map = newMap; | |
omap._list = newList; | |
omap.__hash = undefined; | |
return omap; | |
} | |
return makeOrderedMap(newMap, newList); | |
} | |
createClass(ToKeyedSequence, KeyedSeq); | |
function ToKeyedSequence(indexed, useKeys) { | |
this._iter = indexed; | |
this._useKeys = useKeys; | |
this.size = indexed.size; | |
} | |
ToKeyedSequence.prototype.get = function(key, notSetValue) { | |
return this._iter.get(key, notSetValue); | |
}; | |
ToKeyedSequence.prototype.has = function(key) { | |
return this._iter.has(key); | |
}; | |
ToKeyedSequence.prototype.valueSeq = function() { | |
return this._iter.valueSeq(); | |
}; | |
ToKeyedSequence.prototype.reverse = function() {var this$0 = this; | |
var reversedSequence = reverseFactory(this, true); | |
if (!this._useKeys) { | |
reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()}; | |
} | |
return reversedSequence; | |
}; | |
ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this; | |
var mappedSequence = mapFactory(this, mapper, context); | |
if (!this._useKeys) { | |
mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)}; | |
} | |
return mappedSequence; | |
}; | |
ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
var ii; | |
return this._iter.__iterate( | |
this._useKeys ? | |
function(v, k) {return fn(v, k, this$0)} : | |
((ii = reverse ? resolveSize(this) : 0), | |
function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}), | |
reverse | |
); | |
}; | |
ToKeyedSequence.prototype.__iterator = function(type, reverse) { | |
if (this._useKeys) { | |
return this._iter.__iterator(type, reverse); | |
} | |
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); | |
var ii = reverse ? resolveSize(this) : 0; | |
return new Iterator(function() { | |
var step = iterator.next(); | |
return step.done ? step : | |
iteratorValue(type, reverse ? --ii : ii++, step.value, step); | |
}); | |
}; | |
ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; | |
createClass(ToIndexedSequence, IndexedSeq); | |
function ToIndexedSequence(iter) { | |
this._iter = iter; | |
this.size = iter.size; | |
} | |
ToIndexedSequence.prototype.includes = function(value) { | |
return this._iter.includes(value); | |
}; | |
ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
var iterations = 0; | |
return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse); | |
}; | |
ToIndexedSequence.prototype.__iterator = function(type, reverse) { | |
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); | |
var iterations = 0; | |
return new Iterator(function() { | |
var step = iterator.next(); | |
return step.done ? step : | |
iteratorValue(type, iterations++, step.value, step) | |
}); | |
}; | |
createClass(ToSetSequence, SetSeq); | |
function ToSetSequence(iter) { | |
this._iter = iter; | |
this.size = iter.size; | |
} | |
ToSetSequence.prototype.has = function(key) { | |
return this._iter.includes(key); | |
}; | |
ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse); | |
}; | |
ToSetSequence.prototype.__iterator = function(type, reverse) { | |
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); | |
return new Iterator(function() { | |
var step = iterator.next(); | |
return step.done ? step : | |
iteratorValue(type, step.value, step.value, step); | |
}); | |
}; | |
createClass(FromEntriesSequence, KeyedSeq); | |
function FromEntriesSequence(entries) { | |
this._iter = entries; | |
this.size = entries.size; | |
} | |
FromEntriesSequence.prototype.entrySeq = function() { | |
return this._iter.toSeq(); | |
}; | |
FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
return this._iter.__iterate(function(entry ) { | |
// Check if entry exists first so array access doesn't throw for holes | |
// in the parent iteration. | |
if (entry) { | |
validateEntry(entry); | |
var indexedIterable = isIterable(entry); | |
return fn( | |
indexedIterable ? entry.get(1) : entry[1], | |
indexedIterable ? entry.get(0) : entry[0], | |
this$0 | |
); | |
} | |
}, reverse); | |
}; | |
FromEntriesSequence.prototype.__iterator = function(type, reverse) { | |
var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); | |
return new Iterator(function() { | |
while (true) { | |
var step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
var entry = step.value; | |
// Check if entry exists first so array access doesn't throw for holes | |
// in the parent iteration. | |
if (entry) { | |
validateEntry(entry); | |
var indexedIterable = isIterable(entry); | |
return iteratorValue( | |
type, | |
indexedIterable ? entry.get(0) : entry[0], | |
indexedIterable ? entry.get(1) : entry[1], | |
step | |
); | |
} | |
} | |
}); | |
}; | |
ToIndexedSequence.prototype.cacheResult = | |
ToKeyedSequence.prototype.cacheResult = | |
ToSetSequence.prototype.cacheResult = | |
FromEntriesSequence.prototype.cacheResult = | |
cacheResultThrough; | |
function flipFactory(iterable) { | |
var flipSequence = makeSequence(iterable); | |
flipSequence._iter = iterable; | |
flipSequence.size = iterable.size; | |
flipSequence.flip = function() {return iterable}; | |
flipSequence.reverse = function () { | |
var reversedSequence = iterable.reverse.apply(this); // super.reverse() | |
reversedSequence.flip = function() {return iterable.reverse()}; | |
return reversedSequence; | |
}; | |
flipSequence.has = function(key ) {return iterable.includes(key)}; | |
flipSequence.includes = function(key ) {return iterable.has(key)}; | |
flipSequence.cacheResult = cacheResultThrough; | |
flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; | |
return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse); | |
} | |
flipSequence.__iteratorUncached = function(type, reverse) { | |
if (type === ITERATE_ENTRIES) { | |
var iterator = iterable.__iterator(type, reverse); | |
return new Iterator(function() { | |
var step = iterator.next(); | |
if (!step.done) { | |
var k = step.value[0]; | |
step.value[0] = step.value[1]; | |
step.value[1] = k; | |
} | |
return step; | |
}); | |
} | |
return iterable.__iterator( | |
type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, | |
reverse | |
); | |
} | |
return flipSequence; | |
} | |
function mapFactory(iterable, mapper, context) { | |
var mappedSequence = makeSequence(iterable); | |
mappedSequence.size = iterable.size; | |
mappedSequence.has = function(key ) {return iterable.has(key)}; | |
mappedSequence.get = function(key, notSetValue) { | |
var v = iterable.get(key, NOT_SET); | |
return v === NOT_SET ? | |
notSetValue : | |
mapper.call(context, v, key, iterable); | |
}; | |
mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; | |
return iterable.__iterate( | |
function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false}, | |
reverse | |
); | |
} | |
mappedSequence.__iteratorUncached = function (type, reverse) { | |
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); | |
return new Iterator(function() { | |
var step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
var entry = step.value; | |
var key = entry[0]; | |
return iteratorValue( | |
type, | |
key, | |
mapper.call(context, entry[1], key, iterable), | |
step | |
); | |
}); | |
} | |
return mappedSequence; | |
} | |
function reverseFactory(iterable, useKeys) { | |
var reversedSequence = makeSequence(iterable); | |
reversedSequence._iter = iterable; | |
reversedSequence.size = iterable.size; | |
reversedSequence.reverse = function() {return iterable}; | |
if (iterable.flip) { | |
reversedSequence.flip = function () { | |
var flipSequence = flipFactory(iterable); | |
flipSequence.reverse = function() {return iterable.flip()}; | |
return flipSequence; | |
}; | |
} | |
reversedSequence.get = function(key, notSetValue) | |
{return iterable.get(useKeys ? key : -1 - key, notSetValue)}; | |
reversedSequence.has = function(key ) | |
{return iterable.has(useKeys ? key : -1 - key)}; | |
reversedSequence.includes = function(value ) {return iterable.includes(value)}; | |
reversedSequence.cacheResult = cacheResultThrough; | |
reversedSequence.__iterate = function (fn, reverse) {var this$0 = this; | |
return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse); | |
}; | |
reversedSequence.__iterator = | |
function(type, reverse) {return iterable.__iterator(type, !reverse)}; | |
return reversedSequence; | |
} | |
function filterFactory(iterable, predicate, context, useKeys) { | |
var filterSequence = makeSequence(iterable); | |
if (useKeys) { | |
filterSequence.has = function(key ) { | |
var v = iterable.get(key, NOT_SET); | |
return v !== NOT_SET && !!predicate.call(context, v, key, iterable); | |
}; | |
filterSequence.get = function(key, notSetValue) { | |
var v = iterable.get(key, NOT_SET); | |
return v !== NOT_SET && predicate.call(context, v, key, iterable) ? | |
v : notSetValue; | |
}; | |
} | |
filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; | |
var iterations = 0; | |
iterable.__iterate(function(v, k, c) { | |
if (predicate.call(context, v, k, c)) { | |
iterations++; | |
return fn(v, useKeys ? k : iterations - 1, this$0); | |
} | |
}, reverse); | |
return iterations; | |
}; | |
filterSequence.__iteratorUncached = function (type, reverse) { | |
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); | |
var iterations = 0; | |
return new Iterator(function() { | |
while (true) { | |
var step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
var entry = step.value; | |
var key = entry[0]; | |
var value = entry[1]; | |
if (predicate.call(context, value, key, iterable)) { | |
return iteratorValue(type, useKeys ? key : iterations++, value, step); | |
} | |
} | |
}); | |
} | |
return filterSequence; | |
} | |
function countByFactory(iterable, grouper, context) { | |
var groups = Map().asMutable(); | |
iterable.__iterate(function(v, k) { | |
groups.update( | |
grouper.call(context, v, k, iterable), | |
0, | |
function(a ) {return a + 1} | |
); | |
}); | |
return groups.asImmutable(); | |
} | |
function groupByFactory(iterable, grouper, context) { | |
var isKeyedIter = isKeyed(iterable); | |
var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable(); | |
iterable.__iterate(function(v, k) { | |
groups.update( | |
grouper.call(context, v, k, iterable), | |
function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)} | |
); | |
}); | |
var coerce = iterableClass(iterable); | |
return groups.map(function(arr ) {return reify(iterable, coerce(arr))}); | |
} | |
function sliceFactory(iterable, begin, end, useKeys) { | |
var originalSize = iterable.size; | |
// Sanitize begin & end using this shorthand for ToInt32(argument) | |
// http://www.ecma-international.org/ecma-262/6.0/#sec-toint32 | |
if (begin !== undefined) { | |
begin = begin | 0; | |
} | |
if (end !== undefined) { | |
if (end === Infinity) { | |
end = originalSize; | |
} else { | |
end = end | 0; | |
} | |
} | |
if (wholeSlice(begin, end, originalSize)) { | |
return iterable; | |
} | |
var resolvedBegin = resolveBegin(begin, originalSize); | |
var resolvedEnd = resolveEnd(end, originalSize); | |
// begin or end will be NaN if they were provided as negative numbers and | |
// this iterable's size is unknown. In that case, cache first so there is | |
// a known size and these do not resolve to NaN. | |
if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { | |
return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys); | |
} | |
// Note: resolvedEnd is undefined when the original sequence's length is | |
// unknown and this slice did not supply an end and should contain all | |
// elements after resolvedBegin. | |
// In that case, resolvedSize will be NaN and sliceSize will remain undefined. | |
var resolvedSize = resolvedEnd - resolvedBegin; | |
var sliceSize; | |
if (resolvedSize === resolvedSize) { | |
sliceSize = resolvedSize < 0 ? 0 : resolvedSize; | |
} | |
var sliceSeq = makeSequence(iterable); | |
// If iterable.size is undefined, the size of the realized sliceSeq is | |
// unknown at this point unless the number of items to slice is 0 | |
sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined; | |
if (!useKeys && isSeq(iterable) && sliceSize >= 0) { | |
sliceSeq.get = function (index, notSetValue) { | |
index = wrapIndex(this, index); | |
return index >= 0 && index < sliceSize ? | |
iterable.get(index + resolvedBegin, notSetValue) : | |
notSetValue; | |
} | |
} | |
sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this; | |
if (sliceSize === 0) { | |
return 0; | |
} | |
if (reverse) { | |
return this.cacheResult().__iterate(fn, reverse); | |
} | |
var skipped = 0; | |
var isSkipping = true; | |
var iterations = 0; | |
iterable.__iterate(function(v, k) { | |
if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { | |
iterations++; | |
return fn(v, useKeys ? k : iterations - 1, this$0) !== false && | |
iterations !== sliceSize; | |
} | |
}); | |
return iterations; | |
}; | |
sliceSeq.__iteratorUncached = function(type, reverse) { | |
if (sliceSize !== 0 && reverse) { | |
return this.cacheResult().__iterator(type, reverse); | |
} | |
// Don't bother instantiating parent iterator if taking 0. | |
var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse); | |
var skipped = 0; | |
var iterations = 0; | |
return new Iterator(function() { | |
while (skipped++ < resolvedBegin) { | |
iterator.next(); | |
} | |
if (++iterations > sliceSize) { | |
return iteratorDone(); | |
} | |
var step = iterator.next(); | |
if (useKeys || type === ITERATE_VALUES) { | |
return step; | |
} else if (type === ITERATE_KEYS) { | |
return iteratorValue(type, iterations - 1, undefined, step); | |
} else { | |
return iteratorValue(type, iterations - 1, step.value[1], step); | |
} | |
}); | |
} | |
return sliceSeq; | |
} | |
function takeWhileFactory(iterable, predicate, context) { | |
var takeSequence = makeSequence(iterable); | |
takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; | |
if (reverse) { | |
return this.cacheResult().__iterate(fn, reverse); | |
} | |
var iterations = 0; | |
iterable.__iterate(function(v, k, c) | |
{return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)} | |
); | |
return iterations; | |
}; | |
takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; | |
if (reverse) { | |
return this.cacheResult().__iterator(type, reverse); | |
} | |
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); | |
var iterating = true; | |
return new Iterator(function() { | |
if (!iterating) { | |
return iteratorDone(); | |
} | |
var step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
var entry = step.value; | |
var k = entry[0]; | |
var v = entry[1]; | |
if (!predicate.call(context, v, k, this$0)) { | |
iterating = false; | |
return iteratorDone(); | |
} | |
return type === ITERATE_ENTRIES ? step : | |
iteratorValue(type, k, v, step); | |
}); | |
}; | |
return takeSequence; | |
} | |
function skipWhileFactory(iterable, predicate, context, useKeys) { | |
var skipSequence = makeSequence(iterable); | |
skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; | |
if (reverse) { | |
return this.cacheResult().__iterate(fn, reverse); | |
} | |
var isSkipping = true; | |
var iterations = 0; | |
iterable.__iterate(function(v, k, c) { | |
if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { | |
iterations++; | |
return fn(v, useKeys ? k : iterations - 1, this$0); | |
} | |
}); | |
return iterations; | |
}; | |
skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; | |
if (reverse) { | |
return this.cacheResult().__iterator(type, reverse); | |
} | |
var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); | |
var skipping = true; | |
var iterations = 0; | |
return new Iterator(function() { | |
var step, k, v; | |
do { | |
step = iterator.next(); | |
if (step.done) { | |
if (useKeys || type === ITERATE_VALUES) { | |
return step; | |
} else if (type === ITERATE_KEYS) { | |
return iteratorValue(type, iterations++, undefined, step); | |
} else { | |
return iteratorValue(type, iterations++, step.value[1], step); | |
} | |
} | |
var entry = step.value; | |
k = entry[0]; | |
v = entry[1]; | |
skipping && (skipping = predicate.call(context, v, k, this$0)); | |
} while (skipping); | |
return type === ITERATE_ENTRIES ? step : | |
iteratorValue(type, k, v, step); | |
}); | |
}; | |
return skipSequence; | |
} | |
function concatFactory(iterable, values) { | |
var isKeyedIterable = isKeyed(iterable); | |
var iters = [iterable].concat(values).map(function(v ) { | |
if (!isIterable(v)) { | |
v = isKeyedIterable ? | |
keyedSeqFromValue(v) : | |
indexedSeqFromValue(Array.isArray(v) ? v : [v]); | |
} else if (isKeyedIterable) { | |
v = KeyedIterable(v); | |
} | |
return v; | |
}).filter(function(v ) {return v.size !== 0}); | |
if (iters.length === 0) { | |
return iterable; | |
} | |
if (iters.length === 1) { | |
var singleton = iters[0]; | |
if (singleton === iterable || | |
isKeyedIterable && isKeyed(singleton) || | |
isIndexed(iterable) && isIndexed(singleton)) { | |
return singleton; | |
} | |
} | |
var concatSeq = new ArraySeq(iters); | |
if (isKeyedIterable) { | |
concatSeq = concatSeq.toKeyedSeq(); | |
} else if (!isIndexed(iterable)) { | |
concatSeq = concatSeq.toSetSeq(); | |
} | |
concatSeq = concatSeq.flatten(true); | |
concatSeq.size = iters.reduce( | |
function(sum, seq) { | |
if (sum !== undefined) { | |
var size = seq.size; | |
if (size !== undefined) { | |
return sum + size; | |
} | |
} | |
}, | |
0 | |
); | |
return concatSeq; | |
} | |
function flattenFactory(iterable, depth, useKeys) { | |
var flatSequence = makeSequence(iterable); | |
flatSequence.__iterateUncached = function(fn, reverse) { | |
var iterations = 0; | |
var stopped = false; | |
function flatDeep(iter, currentDepth) {var this$0 = this; | |
iter.__iterate(function(v, k) { | |
if ((!depth || currentDepth < depth) && isIterable(v)) { | |
flatDeep(v, currentDepth + 1); | |
} else if (fn(v, useKeys ? k : iterations++, this$0) === false) { | |
stopped = true; | |
} | |
return !stopped; | |
}, reverse); | |
} | |
flatDeep(iterable, 0); | |
return iterations; | |
} | |
flatSequence.__iteratorUncached = function(type, reverse) { | |
var iterator = iterable.__iterator(type, reverse); | |
var stack = []; | |
var iterations = 0; | |
return new Iterator(function() { | |
while (iterator) { | |
var step = iterator.next(); | |
if (step.done !== false) { | |
iterator = stack.pop(); | |
continue; | |
} | |
var v = step.value; | |
if (type === ITERATE_ENTRIES) { | |
v = v[1]; | |
} | |
if ((!depth || stack.length < depth) && isIterable(v)) { | |
stack.push(iterator); | |
iterator = v.__iterator(type, reverse); | |
} else { | |
return useKeys ? step : iteratorValue(type, iterations++, v, step); | |
} | |
} | |
return iteratorDone(); | |
}); | |
} | |
return flatSequence; | |
} | |
function flatMapFactory(iterable, mapper, context) { | |
var coerce = iterableClass(iterable); | |
return iterable.toSeq().map( | |
function(v, k) {return coerce(mapper.call(context, v, k, iterable))} | |
).flatten(true); | |
} | |
function interposeFactory(iterable, separator) { | |
var interposedSequence = makeSequence(iterable); | |
interposedSequence.size = iterable.size && iterable.size * 2 -1; | |
interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; | |
var iterations = 0; | |
iterable.__iterate(function(v, k) | |
{return (!iterations || fn(separator, iterations++, this$0) !== false) && | |
fn(v, iterations++, this$0) !== false}, | |
reverse | |
); | |
return iterations; | |
}; | |
interposedSequence.__iteratorUncached = function(type, reverse) { | |
var iterator = iterable.__iterator(ITERATE_VALUES, reverse); | |
var iterations = 0; | |
var step; | |
return new Iterator(function() { | |
if (!step || iterations % 2) { | |
step = iterator.next(); | |
if (step.done) { | |
return step; | |
} | |
} | |
return iterations % 2 ? | |
iteratorValue(type, iterations++, separator) : | |
iteratorValue(type, iterations++, step.value, step); | |
}); | |
}; | |
return interposedSequence; | |
} | |
function sortFactory(iterable, comparator, mapper) { | |
if (!comparator) { | |
comparator = defaultComparator; | |
} | |
var isKeyedIterable = isKeyed(iterable); | |
var index = 0; | |
var entries = iterable.toSeq().map( | |
function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]} | |
).toArray(); | |
entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach( | |
isKeyedIterable ? | |
function(v, i) { entries[i].length = 2; } : | |
function(v, i) { entries[i] = v[1]; } | |
); | |
return isKeyedIterable ? KeyedSeq(entries) : | |
isIndexed(iterable) ? IndexedSeq(entries) : | |
SetSeq(entries); | |
} | |
function maxFactory(iterable, comparator, mapper) { | |
if (!comparator) { | |
comparator = defaultComparator; | |
} | |
if (mapper) { | |
var entry = iterable.toSeq() | |
.map(function(v, k) {return [v, mapper(v, k, iterable)]}) | |
.reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a}); | |
return entry && entry[0]; | |
} else { | |
return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a}); | |
} | |
} | |
function maxCompare(comparator, a, b) { | |
var comp = comparator(b, a); | |
// b is considered the new max if the comparator declares them equal, but | |
// they are not equal and b is in fact a nullish value. | |
return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0; | |
} | |
function zipWithFactory(keyIter, zipper, iters) { | |
var zipSequence = makeSequence(keyIter); | |
zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min(); | |
// Note: this a generic base implementation of __iterate in terms of | |
// __iterator which may be more generically useful in the future. | |
zipSequence.__iterate = function(fn, reverse) { | |
/* generic: | |
var iterator = this.__iterator(ITERATE_ENTRIES, reverse); | |
var step; | |
var iterations = 0; | |
while (!(step = iterator.next()).done) { | |
iterations++; | |
if (fn(step.value[1], step.value[0], this) === false) { | |
break; | |
} | |
} | |
return iterations; | |
*/ | |
// indexed: | |
var iterator = this.__iterator(ITERATE_VALUES, reverse); | |
var step; | |
var iterations = 0; | |
while (!(step = iterator.next()).done) { | |
if (fn(step.value, iterations++, this) === false) { | |
break; | |
} | |
} | |
return iterations; | |
}; | |
zipSequence.__iteratorUncached = function(type, reverse) { | |
var iterators = iters.map(function(i ) | |
{return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))} | |
); | |
var iterations = 0; | |
var isDone = false; | |
return new Iterator(function() { | |
var steps; | |
if (!isDone) { | |
steps = iterators.map(function(i ) {return i.next()}); | |
isDone = steps.some(function(s ) {return s.done}); | |
} | |
if (isDone) { | |
return iteratorDone(); | |
} | |
return iteratorValue( | |
type, | |
iterations++, | |
zipper.apply(null, steps.map(function(s ) {return s.value})) | |
); | |
}); | |
}; | |
return zipSequence | |
} | |
// #pragma Helper Functions | |
function reify(iter, seq) { | |
return isSeq(iter) ? seq : iter.constructor(seq); | |
} | |
function validateEntry(entry) { | |
if (entry !== Object(entry)) { | |
throw new TypeError('Expected [K, V] tuple: ' + entry); | |
} | |
} | |
function resolveSize(iter) { | |
assertNotInfinite(iter.size); | |
return ensureSize(iter); | |
} | |
function iterableClass(iterable) { | |
return isKeyed(iterable) ? KeyedIterable : | |
isIndexed(iterable) ? IndexedIterable : | |
SetIterable; | |
} | |
function makeSequence(iterable) { | |
return Object.create( | |
( | |
isKeyed(iterable) ? KeyedSeq : | |
isIndexed(iterable) ? IndexedSeq : | |
SetSeq | |
).prototype | |
); | |
} | |
function cacheResultThrough() { | |
if (this._iter.cacheResult) { | |
this._iter.cacheResult(); | |
this.size = this._iter.size; | |
return this; | |
} else { | |
return Seq.prototype.cacheResult.call(this); | |
} | |
} | |
function defaultComparator(a, b) { | |
return a > b ? 1 : a < b ? -1 : 0; | |
} | |
function forceIterator(keyPath) { | |
var iter = getIterator(keyPath); | |
if (!iter) { | |
// Array might not be iterable in this environment, so we need a fallback | |
// to our wrapped type. | |
if (!isArrayLike(keyPath)) { | |
throw new TypeError('Expected iterable or array-like: ' + keyPath); | |
} | |
iter = getIterator(Iterable(keyPath)); | |
} | |
return iter; | |
} | |
createClass(Record, KeyedCollection); | |
function Record(defaultValues, name) { | |
var hasInitialized; | |
var RecordType = function Record(values) { | |
if (values instanceof RecordType) { | |
return values; | |
} | |
if (!(this instanceof RecordType)) { | |
return new RecordType(values); | |
} | |
if (!hasInitialized) { | |
hasInitialized = true; | |
var keys = Object.keys(defaultValues); | |
setProps(RecordTypePrototype, keys); | |
RecordTypePrototype.size = keys.length; | |
RecordTypePrototype._name = name; | |
RecordTypePrototype._keys = keys; | |
RecordTypePrototype._defaultValues = defaultValues; | |
} | |
this._map = Map(values); | |
}; | |
var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); | |
RecordTypePrototype.constructor = RecordType; | |
return RecordType; | |
} | |
Record.prototype.toString = function() { | |
return this.__toString(recordName(this) + ' {', '}'); | |
}; | |
// @pragma Access | |
Record.prototype.has = function(k) { | |
return this._defaultValues.hasOwnProperty(k); | |
}; | |
Record.prototype.get = function(k, notSetValue) { | |
if (!this.has(k)) { | |
return notSetValue; | |
} | |
var defaultVal = this._defaultValues[k]; | |
return this._map ? this._map.get(k, defaultVal) : defaultVal; | |
}; | |
// @pragma Modification | |
Record.prototype.clear = function() { | |
if (this.__ownerID) { | |
this._map && this._map.clear(); | |
return this; | |
} | |
var RecordType = this.constructor; | |
return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap())); | |
}; | |
Record.prototype.set = function(k, v) { | |
if (!this.has(k)) { | |
throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); | |
} | |
if (this._map && !this._map.has(k)) { | |
var defaultVal = this._defaultValues[k]; | |
if (v === defaultVal) { | |
return this; | |
} | |
} | |
var newMap = this._map && this._map.set(k, v); | |
if (this.__ownerID || newMap === this._map) { | |
return this; | |
} | |
return makeRecord(this, newMap); | |
}; | |
Record.prototype.remove = function(k) { | |
if (!this.has(k)) { | |
return this; | |
} | |
var newMap = this._map && this._map.remove(k); | |
if (this.__ownerID || newMap === this._map) { | |
return this; | |
} | |
return makeRecord(this, newMap); | |
}; | |
Record.prototype.wasAltered = function() { | |
return this._map.wasAltered(); | |
}; | |
Record.prototype.__iterator = function(type, reverse) {var this$0 = this; | |
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse); | |
}; | |
Record.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse); | |
}; | |
Record.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
var newMap = this._map && this._map.__ensureOwner(ownerID); | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
this._map = newMap; | |
return this; | |
} | |
return makeRecord(this, newMap, ownerID); | |
}; | |
var RecordPrototype = Record.prototype; | |
RecordPrototype[DELETE] = RecordPrototype.remove; | |
RecordPrototype.deleteIn = | |
RecordPrototype.removeIn = MapPrototype.removeIn; | |
RecordPrototype.merge = MapPrototype.merge; | |
RecordPrototype.mergeWith = MapPrototype.mergeWith; | |
RecordPrototype.mergeIn = MapPrototype.mergeIn; | |
RecordPrototype.mergeDeep = MapPrototype.mergeDeep; | |
RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; | |
RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; | |
RecordPrototype.setIn = MapPrototype.setIn; | |
RecordPrototype.update = MapPrototype.update; | |
RecordPrototype.updateIn = MapPrototype.updateIn; | |
RecordPrototype.withMutations = MapPrototype.withMutations; | |
RecordPrototype.asMutable = MapPrototype.asMutable; | |
RecordPrototype.asImmutable = MapPrototype.asImmutable; | |
function makeRecord(likeRecord, map, ownerID) { | |
var record = Object.create(Object.getPrototypeOf(likeRecord)); | |
record._map = map; | |
record.__ownerID = ownerID; | |
return record; | |
} | |
function recordName(record) { | |
return record._name || record.constructor.name || 'Record'; | |
} | |
function setProps(prototype, names) { | |
try { | |
names.forEach(setProp.bind(undefined, prototype)); | |
} catch (error) { | |
// Object.defineProperty failed. Probably IE8. | |
} | |
} | |
function setProp(prototype, name) { | |
Object.defineProperty(prototype, name, { | |
get: function() { | |
return this.get(name); | |
}, | |
set: function(value) { | |
invariant(this.__ownerID, 'Cannot set on an immutable record.'); | |
this.set(name, value); | |
} | |
}); | |
} | |
createClass(Set, SetCollection); | |
// @pragma Construction | |
function Set(value) { | |
return value === null || value === undefined ? emptySet() : | |
isSet(value) && !isOrdered(value) ? value : | |
emptySet().withMutations(function(set ) { | |
var iter = SetIterable(value); | |
assertNotInfinite(iter.size); | |
iter.forEach(function(v ) {return set.add(v)}); | |
}); | |
} | |
Set.of = function(/*...values*/) { | |
return this(arguments); | |
}; | |
Set.fromKeys = function(value) { | |
return this(KeyedIterable(value).keySeq()); | |
}; | |
Set.prototype.toString = function() { | |
return this.__toString('Set {', '}'); | |
}; | |
// @pragma Access | |
Set.prototype.has = function(value) { | |
return this._map.has(value); | |
}; | |
// @pragma Modification | |
Set.prototype.add = function(value) { | |
return updateSet(this, this._map.set(value, true)); | |
}; | |
Set.prototype.remove = function(value) { | |
return updateSet(this, this._map.remove(value)); | |
}; | |
Set.prototype.clear = function() { | |
return updateSet(this, this._map.clear()); | |
}; | |
// @pragma Composition | |
Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0); | |
iters = iters.filter(function(x ) {return x.size !== 0}); | |
if (iters.length === 0) { | |
return this; | |
} | |
if (this.size === 0 && !this.__ownerID && iters.length === 1) { | |
return this.constructor(iters[0]); | |
} | |
return this.withMutations(function(set ) { | |
for (var ii = 0; ii < iters.length; ii++) { | |
SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)}); | |
} | |
}); | |
}; | |
Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0); | |
if (iters.length === 0) { | |
return this; | |
} | |
iters = iters.map(function(iter ) {return SetIterable(iter)}); | |
var originalSet = this; | |
return this.withMutations(function(set ) { | |
originalSet.forEach(function(value ) { | |
if (!iters.every(function(iter ) {return iter.includes(value)})) { | |
set.remove(value); | |
} | |
}); | |
}); | |
}; | |
Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0); | |
if (iters.length === 0) { | |
return this; | |
} | |
iters = iters.map(function(iter ) {return SetIterable(iter)}); | |
var originalSet = this; | |
return this.withMutations(function(set ) { | |
originalSet.forEach(function(value ) { | |
if (iters.some(function(iter ) {return iter.includes(value)})) { | |
set.remove(value); | |
} | |
}); | |
}); | |
}; | |
Set.prototype.merge = function() { | |
return this.union.apply(this, arguments); | |
}; | |
Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); | |
return this.union.apply(this, iters); | |
}; | |
Set.prototype.sort = function(comparator) { | |
// Late binding | |
return OrderedSet(sortFactory(this, comparator)); | |
}; | |
Set.prototype.sortBy = function(mapper, comparator) { | |
// Late binding | |
return OrderedSet(sortFactory(this, comparator, mapper)); | |
}; | |
Set.prototype.wasAltered = function() { | |
return this._map.wasAltered(); | |
}; | |
Set.prototype.__iterate = function(fn, reverse) {var this$0 = this; | |
return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse); | |
}; | |
Set.prototype.__iterator = function(type, reverse) { | |
return this._map.map(function(_, k) {return k}).__iterator(type, reverse); | |
}; | |
Set.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
var newMap = this._map.__ensureOwner(ownerID); | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
this._map = newMap; | |
return this; | |
} | |
return this.__make(newMap, ownerID); | |
}; | |
function isSet(maybeSet) { | |
return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); | |
} | |
Set.isSet = isSet; | |
var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; | |
var SetPrototype = Set.prototype; | |
SetPrototype[IS_SET_SENTINEL] = true; | |
SetPrototype[DELETE] = SetPrototype.remove; | |
SetPrototype.mergeDeep = SetPrototype.merge; | |
SetPrototype.mergeDeepWith = SetPrototype.mergeWith; | |
SetPrototype.withMutations = MapPrototype.withMutations; | |
SetPrototype.asMutable = MapPrototype.asMutable; | |
SetPrototype.asImmutable = MapPrototype.asImmutable; | |
SetPrototype.__empty = emptySet; | |
SetPrototype.__make = makeSet; | |
function updateSet(set, newMap) { | |
if (set.__ownerID) { | |
set.size = newMap.size; | |
set._map = newMap; | |
return set; | |
} | |
return newMap === set._map ? set : | |
newMap.size === 0 ? set.__empty() : | |
set.__make(newMap); | |
} | |
function makeSet(map, ownerID) { | |
var set = Object.create(SetPrototype); | |
set.size = map ? map.size : 0; | |
set._map = map; | |
set.__ownerID = ownerID; | |
return set; | |
} | |
var EMPTY_SET; | |
function emptySet() { | |
return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); | |
} | |
createClass(OrderedSet, Set); | |
// @pragma Construction | |
function OrderedSet(value) { | |
return value === null || value === undefined ? emptyOrderedSet() : | |
isOrderedSet(value) ? value : | |
emptyOrderedSet().withMutations(function(set ) { | |
var iter = SetIterable(value); | |
assertNotInfinite(iter.size); | |
iter.forEach(function(v ) {return set.add(v)}); | |
}); | |
} | |
OrderedSet.of = function(/*...values*/) { | |
return this(arguments); | |
}; | |
OrderedSet.fromKeys = function(value) { | |
return this(KeyedIterable(value).keySeq()); | |
}; | |
OrderedSet.prototype.toString = function() { | |
return this.__toString('OrderedSet {', '}'); | |
}; | |
function isOrderedSet(maybeOrderedSet) { | |
return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); | |
} | |
OrderedSet.isOrderedSet = isOrderedSet; | |
var OrderedSetPrototype = OrderedSet.prototype; | |
OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; | |
OrderedSetPrototype.__empty = emptyOrderedSet; | |
OrderedSetPrototype.__make = makeOrderedSet; | |
function makeOrderedSet(map, ownerID) { | |
var set = Object.create(OrderedSetPrototype); | |
set.size = map ? map.size : 0; | |
set._map = map; | |
set.__ownerID = ownerID; | |
return set; | |
} | |
var EMPTY_ORDERED_SET; | |
function emptyOrderedSet() { | |
return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); | |
} | |
createClass(Stack, IndexedCollection); | |
// @pragma Construction | |
function Stack(value) { | |
return value === null || value === undefined ? emptyStack() : | |
isStack(value) ? value : | |
emptyStack().unshiftAll(value); | |
} | |
Stack.of = function(/*...values*/) { | |
return this(arguments); | |
}; | |
Stack.prototype.toString = function() { | |
return this.__toString('Stack [', ']'); | |
}; | |
// @pragma Access | |
Stack.prototype.get = function(index, notSetValue) { | |
var head = this._head; | |
index = wrapIndex(this, index); | |
while (head && index--) { | |
head = head.next; | |
} | |
return head ? head.value : notSetValue; | |
}; | |
Stack.prototype.peek = function() { | |
return this._head && this._head.value; | |
}; | |
// @pragma Modification | |
Stack.prototype.push = function(/*...values*/) { | |
if (arguments.length === 0) { | |
return this; | |
} | |
var newSize = this.size + arguments.length; | |
var head = this._head; | |
for (var ii = arguments.length - 1; ii >= 0; ii--) { | |
head = { | |
value: arguments[ii], | |
next: head | |
}; | |
} | |
if (this.__ownerID) { | |
this.size = newSize; | |
this._head = head; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return makeStack(newSize, head); | |
}; | |
Stack.prototype.pushAll = function(iter) { | |
iter = IndexedIterable(iter); | |
if (iter.size === 0) { | |
return this; | |
} | |
assertNotInfinite(iter.size); | |
var newSize = this.size; | |
var head = this._head; | |
iter.reverse().forEach(function(value ) { | |
newSize++; | |
head = { | |
value: value, | |
next: head | |
}; | |
}); | |
if (this.__ownerID) { | |
this.size = newSize; | |
this._head = head; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return makeStack(newSize, head); | |
}; | |
Stack.prototype.pop = function() { | |
return this.slice(1); | |
}; | |
Stack.prototype.unshift = function(/*...values*/) { | |
return this.push.apply(this, arguments); | |
}; | |
Stack.prototype.unshiftAll = function(iter) { | |
return this.pushAll(iter); | |
}; | |
Stack.prototype.shift = function() { | |
return this.pop.apply(this, arguments); | |
}; | |
Stack.prototype.clear = function() { | |
if (this.size === 0) { | |
return this; | |
} | |
if (this.__ownerID) { | |
this.size = 0; | |
this._head = undefined; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return emptyStack(); | |
}; | |
Stack.prototype.slice = function(begin, end) { | |
if (wholeSlice(begin, end, this.size)) { | |
return this; | |
} | |
var resolvedBegin = resolveBegin(begin, this.size); | |
var resolvedEnd = resolveEnd(end, this.size); | |
if (resolvedEnd !== this.size) { | |
// super.slice(begin, end); | |
return IndexedCollection.prototype.slice.call(this, begin, end); | |
} | |
var newSize = this.size - resolvedBegin; | |
var head = this._head; | |
while (resolvedBegin--) { | |
head = head.next; | |
} | |
if (this.__ownerID) { | |
this.size = newSize; | |
this._head = head; | |
this.__hash = undefined; | |
this.__altered = true; | |
return this; | |
} | |
return makeStack(newSize, head); | |
}; | |
// @pragma Mutability | |
Stack.prototype.__ensureOwner = function(ownerID) { | |
if (ownerID === this.__ownerID) { | |
return this; | |
} | |
if (!ownerID) { | |
this.__ownerID = ownerID; | |
this.__altered = false; | |
return this; | |
} | |
return makeStack(this.size, this._head, ownerID, this.__hash); | |
}; | |
// @pragma Iteration | |
Stack.prototype.__iterate = function(fn, reverse) { | |
if (reverse) { | |
return this.reverse().__iterate(fn); | |
} | |
var iterations = 0; | |
var node = this._head; | |
while (node) { | |
if (fn(node.value, iterations++, this) === false) { | |
break; | |
} | |
node = node.next; | |
} | |
return iterations; | |
}; | |
Stack.prototype.__iterator = function(type, reverse) { | |
if (reverse) { | |
return this.reverse().__iterator(type); | |
} | |
var iterations = 0; | |
var node = this._head; | |
return new Iterator(function() { | |
if (node) { | |
var value = node.value; | |
node = node.next; | |
return iteratorValue(type, iterations++, value); | |
} | |
return iteratorDone(); | |
}); | |
}; | |
function isStack(maybeStack) { | |
return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); | |
} | |
Stack.isStack = isStack; | |
var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; | |
var StackPrototype = Stack.prototype; | |
StackPrototype[IS_STACK_SENTINEL] = true; | |
StackPrototype.withMutations = MapPrototype.withMutations; | |
StackPrototype.asMutable = MapPrototype.asMutable; | |
StackPrototype.asImmutable = MapPrototype.asImmutable; | |
StackPrototype.wasAltered = MapPrototype.wasAltered; | |
function makeStack(size, head, ownerID, hash) { | |
var map = Object.create(StackPrototype); | |
map.size = size; | |
map._head = head; | |
map.__ownerID = ownerID; | |
map.__hash = hash; | |
map.__altered = false; | |
return map; | |
} | |
var EMPTY_STACK; | |
function emptyStack() { | |
return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); | |
} | |
/** | |
* Contributes additional methods to a constructor | |
*/ | |
function mixin(ctor, methods) { | |
var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; }; | |
Object.keys(methods).forEach(keyCopier); | |
Object.getOwnPropertySymbols && | |
Object.getOwnPropertySymbols(methods).forEach(keyCopier); | |
return ctor; | |
} | |
Iterable.Iterator = Iterator; | |
mixin(Iterable, { | |
// ### Conversion to other types | |
toArray: function() { | |
assertNotInfinite(this.size); | |
var array = new Array(this.size || 0); | |
this.valueSeq().__iterate(function(v, i) { array[i] = v; }); | |
return array; | |
}, | |
toIndexedSeq: function() { | |
return new ToIndexedSequence(this); | |
}, | |
toJS: function() { | |
return this.toSeq().map( | |
function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value} | |
).__toJS(); | |
}, | |
toJSON: function() { | |
return this.toSeq().map( | |
function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value} | |
).__toJS(); | |
}, | |
toKeyedSeq: function() { | |
return new ToKeyedSequence(this, true); | |
}, | |
toMap: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return Map(this.toKeyedSeq()); | |
}, | |
toObject: function() { | |
assertNotInfinite(this.size); | |
var object = {}; | |
this.__iterate(function(v, k) { object[k] = v; }); | |
return object; | |
}, | |
toOrderedMap: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return OrderedMap(this.toKeyedSeq()); | |
}, | |
toOrderedSet: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return OrderedSet(isKeyed(this) ? this.valueSeq() : this); | |
}, | |
toSet: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return Set(isKeyed(this) ? this.valueSeq() : this); | |
}, | |
toSetSeq: function() { | |
return new ToSetSequence(this); | |
}, | |
toSeq: function() { | |
return isIndexed(this) ? this.toIndexedSeq() : | |
isKeyed(this) ? this.toKeyedSeq() : | |
this.toSetSeq(); | |
}, | |
toStack: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return Stack(isKeyed(this) ? this.valueSeq() : this); | |
}, | |
toList: function() { | |
// Use Late Binding here to solve the circular dependency. | |
return List(isKeyed(this) ? this.valueSeq() : this); | |
}, | |
// ### Common JavaScript methods and properties | |
toString: function() { | |
return '[Iterable]'; | |
}, | |
__toString: function(head, tail) { | |
if (this.size === 0) { | |
return head + tail; | |
} | |
return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; | |
}, | |
// ### ES6 Collection methods (ES6 Array and Map) | |
concat: function() {var values = SLICE$0.call(arguments, 0); | |
return reify(this, concatFactory(this, values)); | |
}, | |
includes: function(searchValue) { | |
return this.some(function(value ) {return is(value, searchValue)}); | |
}, | |
entries: function() { | |
return this.__iterator(ITERATE_ENTRIES); | |
}, | |
every: function(predicate, context) { | |
assertNotInfinite(this.size); | |
var returnValue = true; | |
this.__iterate(function(v, k, c) { | |
if (!predicate.call(context, v, k, c)) { | |
returnValue = false; | |
return false; | |
} | |
}); | |
return returnValue; | |
}, | |
filter: function(predicate, context) { | |
return reify(this, filterFactory(this, predicate, context, true)); | |
}, | |
find: function(predicate, context, notSetValue) { | |
var entry = this.findEntry(predicate, context); | |
return entry ? entry[1] : notSetValue; | |
}, | |
forEach: function(sideEffect, context) { | |
assertNotInfinite(this.size); | |
return this.__iterate(context ? sideEffect.bind(context) : sideEffect); | |
}, | |
join: function(separator) { | |
assertNotInfinite(this.size); | |
separator = separator !== undefined ? '' + separator : ','; | |
var joined = ''; | |
var isFirst = true; | |
this.__iterate(function(v ) { | |
isFirst ? (isFirst = false) : (joined += separator); | |
joined += v !== null && v !== undefined ? v.toString() : ''; | |
}); | |
return joined; | |
}, | |
keys: function() { | |
return this.__iterator(ITERATE_KEYS); | |
}, | |
map: function(mapper, context) { | |
return reify(this, mapFactory(this, mapper, context)); | |
}, | |
reduce: function(reducer, initialReduction, context) { | |
assertNotInfinite(this.size); | |
var reduction; | |
var useFirst; | |
if (arguments.length < 2) { | |
useFirst = true; | |
} else { | |
reduction = initialReduction; | |
} | |
this.__iterate(function(v, k, c) { | |
if (useFirst) { | |
useFirst = false; | |
reduction = v; | |
} else { | |
reduction = reducer.call(context, reduction, v, k, c); | |
} | |
}); | |
return reduction; | |
}, | |
reduceRight: function(reducer, initialReduction, context) { | |
var reversed = this.toKeyedSeq().reverse(); | |
return reversed.reduce.apply(reversed, arguments); | |
}, | |
reverse: function() { | |
return reify(this, reverseFactory(this, true)); | |
}, | |
slice: function(begin, end) { | |
return reify(this, sliceFactory(this, begin, end, true)); | |
}, | |
some: function(predicate, context) { | |
return !this.every(not(predicate), context); | |
}, | |
sort: function(comparator) { | |
return reify(this, sortFactory(this, comparator)); | |
}, | |
values: function() { | |
return this.__iterator(ITERATE_VALUES); | |
}, | |
// ### More sequential methods | |
butLast: function() { | |
return this.slice(0, -1); | |
}, | |
isEmpty: function() { | |
return this.size !== undefined ? this.size === 0 : !this.some(function() {return true}); | |
}, | |
count: function(predicate, context) { | |
return ensureSize( | |
predicate ? this.toSeq().filter(predicate, context) : this | |
); | |
}, | |
countBy: function(grouper, context) { | |
return countByFactory(this, grouper, context); | |
}, | |
equals: function(other) { | |
return deepEqual(this, other); | |
}, | |
entrySeq: function() { | |
var iterable = this; | |
if (iterable._cache) { | |
// We cache as an entries array, so we can just return the cache! | |
return new ArraySeq(iterable._cache); | |
} | |
var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); | |
entriesSequence.fromEntrySeq = function() {return iterable.toSeq()}; | |
return entriesSequence; | |
}, | |
filterNot: function(predicate, context) { | |
return this.filter(not(predicate), context); | |
}, | |
findEntry: function(predicate, context, notSetValue) { | |
var found = notSetValue; | |
this.__iterate(function(v, k, c) { | |
if (predicate.call(context, v, k, c)) { | |
found = [k, v]; | |
return false; | |
} | |
}); | |
return found; | |
}, | |
findKey: function(predicate, context) { | |
var entry = this.findEntry(predicate, context); | |
return entry && entry[0]; | |
}, | |
findLast: function(predicate, context, notSetValue) { | |
return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); | |
}, | |
findLastEntry: function(predicate, context, notSetValue) { | |
return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue); | |
}, | |
findLastKey: function(predicate, context) { | |
return this.toKeyedSeq().reverse().findKey(predicate, context); | |
}, | |
first: function() { | |
return this.find(returnTrue); | |
}, | |
flatMap: function(mapper, context) { | |
return reify(this, flatMapFactory(this, mapper, context)); | |
}, | |
flatten: function(depth) { | |
return reify(this, flattenFactory(this, depth, true)); | |
}, | |
fromEntrySeq: function() { | |
return new FromEntriesSequence(this); | |
}, | |
get: function(searchKey, notSetValue) { | |
return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue); | |
}, | |
getIn: function(searchKeyPath, notSetValue) { | |
var nested = this; | |
// Note: in an ES6 environment, we would prefer: | |
// for (var key of searchKeyPath) { | |
var iter = forceIterator(searchKeyPath); | |
var step; | |
while (!(step = iter.next()).done) { | |
var key = step.value; | |
nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET; | |
if (nested === NOT_SET) { | |
return notSetValue; | |
} | |
} | |
return nested; | |
}, | |
groupBy: function(grouper, context) { | |
return groupByFactory(this, grouper, context); | |
}, | |
has: function(searchKey) { | |
return this.get(searchKey, NOT_SET) !== NOT_SET; | |
}, | |
hasIn: function(searchKeyPath) { | |
return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET; | |
}, | |
isSubset: function(iter) { | |
iter = typeof iter.includes === 'function' ? iter : Iterable(iter); | |
return this.every(function(value ) {return iter.includes(value)}); | |
}, | |
isSuperset: function(iter) { | |
iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter); | |
return iter.isSubset(this); | |
}, | |
keyOf: function(searchValue) { | |
return this.findKey(function(value ) {return is(value, searchValue)}); | |
}, | |
keySeq: function() { | |
return this.toSeq().map(keyMapper).toIndexedSeq(); | |
}, | |
last: function() { | |
return this.toSeq().reverse().first(); | |
}, | |
lastKeyOf: function(searchValue) { | |
return this.toKeyedSeq().reverse().keyOf(searchValue); | |
}, | |
max: function(comparator) { | |
return maxFactory(this, comparator); | |
}, | |
maxBy: function(mapper, comparator) { | |
return maxFactory(this, comparator, mapper); | |
}, | |
min: function(comparator) { | |
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); | |
}, | |
minBy: function(mapper, comparator) { | |
return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); | |
}, | |
rest: function() { | |
return this.slice(1); | |
}, | |
skip: function(amount) { | |
return this.slice(Math.max(0, amount)); | |
}, | |
skipLast: function(amount) { | |
return reify(this, this.toSeq().reverse().skip(amount).reverse()); | |
}, | |
skipWhile: function(predicate, context) { | |
return reify(this, skipWhileFactory(this, predicate, context, true)); | |
}, | |
skipUntil: function(predicate, context) { | |
return this.skipWhile(not(predicate), context); | |
}, | |
sortBy: function(mapper, comparator) { | |
return reify(this, sortFactory(this, comparator, mapper)); | |
}, | |
take: function(amount) { | |
return this.slice(0, Math.max(0, amount)); | |
}, | |
takeLast: function(amount) { | |
return reify(this, this.toSeq().reverse().take(amount).reverse()); | |
}, | |
takeWhile: function(predicate, context) { | |
return reify(this, takeWhileFactory(this, predicate, context)); | |
}, | |
takeUntil: function(predicate, context) { | |
return this.takeWhile(not(predicate), context); | |
}, | |
valueSeq: function() { | |
return this.toIndexedSeq(); | |
}, | |
// ### Hashable Object | |
hashCode: function() { | |
return this.__hash || (this.__hash = hashIterable(this)); | |
} | |
// ### Internal | |
// abstract __iterate(fn, reverse) | |
// abstract __iterator(type, reverse) | |
}); | |
// var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; | |
// var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; | |
// var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; | |
// var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; | |
var IterablePrototype = Iterable.prototype; | |
IterablePrototype[IS_ITERABLE_SENTINEL] = true; | |
IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; | |
IterablePrototype.__toJS = IterablePrototype.toArray; | |
IterablePrototype.__toStringMapper = quoteString; | |
IterablePrototype.inspect = | |
IterablePrototype.toSource = function() { return this.toString(); }; | |
IterablePrototype.chain = IterablePrototype.flatMap; | |
IterablePrototype.contains = IterablePrototype.includes; | |
mixin(KeyedIterable, { | |
// ### More sequential methods | |
flip: function() { | |
return reify(this, flipFactory(this)); | |
}, | |
mapEntries: function(mapper, context) {var this$0 = this; | |
var iterations = 0; | |
return reify(this, | |
this.toSeq().map( | |
function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)} | |
).fromEntrySeq() | |
); | |
}, | |
mapKeys: function(mapper, context) {var this$0 = this; | |
return reify(this, | |
this.toSeq().flip().map( | |
function(k, v) {return mapper.call(context, k, v, this$0)} | |
).flip() | |
); | |
} | |
}); | |
var KeyedIterablePrototype = KeyedIterable.prototype; | |
KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; | |
KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; | |
KeyedIterablePrototype.__toJS = IterablePrototype.toObject; | |
KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)}; | |
mixin(IndexedIterable, { | |
// ### Conversion to other types | |
toKeyedSeq: function() { | |
return new ToKeyedSequence(this, false); | |
}, | |
// ### ES6 Collection methods (ES6 Array and Map) | |
filter: function(predicate, context) { | |
return reify(this, filterFactory(this, predicate, context, false)); | |
}, | |
findIndex: function(predicate, context) { | |
var entry = this.findEntry(predicate, context); | |
return entry ? entry[0] : -1; | |
}, | |
indexOf: function(searchValue) { | |
var key = this.keyOf(searchValue); | |
return key === undefined ? -1 : key; | |
}, | |
lastIndexOf: function(searchValue) { | |
var key = this.lastKeyOf(searchValue); | |
return key === undefined ? -1 : key; | |
}, | |
reverse: function() { | |
return reify(this, reverseFactory(this, false)); | |
}, | |
slice: function(begin, end) { | |
return reify(this, sliceFactory(this, begin, end, false)); | |
}, | |
splice: function(index, removeNum /*, ...values*/) { | |
var numArgs = arguments.length; | |
removeNum = Math.max(removeNum | 0, 0); | |
if (numArgs === 0 || (numArgs === 2 && !removeNum)) { | |
return this; | |
} | |
// If index is negative, it should resolve relative to the size of the | |
// collection. However size may be expensive to compute if not cached, so | |
// only call count() if the number is in fact negative. | |
index = resolveBegin(index, index < 0 ? this.count() : this.size); | |
var spliced = this.slice(0, index); | |
return reify( | |
this, | |
numArgs === 1 ? | |
spliced : | |
spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) | |
); | |
}, | |
// ### More collection methods | |
findLastIndex: function(predicate, context) { | |
var entry = this.findLastEntry(predicate, context); | |
return entry ? entry[0] : -1; | |
}, | |
first: function() { | |
return this.get(0); | |
}, | |
flatten: function(depth) { | |
return reify(this, flattenFactory(this, depth, false)); | |
}, | |
get: function(index, notSetValue) { | |
index = wrapIndex(this, index); | |
return (index < 0 || (this.size === Infinity || | |
(this.size !== undefined && index > this.size))) ? | |
notSetValue : | |
this.find(function(_, key) {return key === index}, undefined, notSetValue); | |
}, | |
has: function(index) { | |
index = wrapIndex(this, index); | |
return index >= 0 && (this.size !== undefined ? | |
this.size === Infinity || index < this.size : | |
this.indexOf(index) !== -1 | |
); | |
}, | |
interpose: function(separator) { | |
return reify(this, interposeFactory(this, separator)); | |
}, | |
interleave: function(/*...iterables*/) { | |
var iterables = [this].concat(arrCopy(arguments)); | |
var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables); | |
var interleaved = zipped.flatten(true); | |
if (zipped.size) { | |
interleaved.size = zipped.size * iterables.length; | |
} | |
return reify(this, interleaved); | |
}, | |
keySeq: function() { | |
return Range(0, this.size); | |
}, | |
last: function() { | |
return this.get(-1); | |
}, | |
skipWhile: function(predicate, context) { | |
return reify(this, skipWhileFactory(this, predicate, context, false)); | |
}, | |
zip: function(/*, ...iterables */) { | |
var iterables = [this].concat(arrCopy(arguments)); | |
return reify(this, zipWithFactory(this, defaultZipper, iterables)); | |
}, | |
zipWith: function(zipper/*, ...iterables */) { | |
var iterables = arrCopy(arguments); | |
iterables[0] = this; | |
return reify(this, zipWithFactory(this, zipper, iterables)); | |
} | |
}); | |
IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; | |
IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; | |
mixin(SetIterable, { | |
// ### ES6 Collection methods (ES6 Array and Map) | |
get: function(value, notSetValue) { | |
return this.has(value) ? value : notSetValue; | |
}, | |
includes: function(value) { | |
return this.has(value); | |
}, | |
// ### More sequential methods | |
keySeq: function() { | |
return this.valueSeq(); | |
} | |
}); | |
SetIterable.prototype.has = IterablePrototype.includes; | |
SetIterable.prototype.contains = SetIterable.prototype.includes; | |
// Mixin subclasses | |
mixin(KeyedSeq, KeyedIterable.prototype); | |
mixin(IndexedSeq, IndexedIterable.prototype); | |
mixin(SetSeq, SetIterable.prototype); | |
mixin(KeyedCollection, KeyedIterable.prototype); | |
mixin(IndexedCollection, IndexedIterable.prototype); | |
mixin(SetCollection, SetIterable.prototype); | |
// #pragma Helper functions | |
function keyMapper(v, k) { | |
return k; | |
} | |
function entryMapper(v, k) { | |
return [k, v]; | |
} | |
function not(predicate) { | |
return function() { | |
return !predicate.apply(this, arguments); | |
} | |
} | |
function neg(predicate) { | |
return function() { | |
return -predicate.apply(this, arguments); | |
} | |
} | |
function quoteString(value) { | |
return typeof value === 'string' ? JSON.stringify(value) : String(value); | |
} | |
function defaultZipper() { | |
return arrCopy(arguments); | |
} | |
function defaultNegComparator(a, b) { | |
return a < b ? 1 : a > b ? -1 : 0; | |
} | |
function hashIterable(iterable) { | |
if (iterable.size === Infinity) { | |
return 0; | |
} | |
var ordered = isOrdered(iterable); | |
var keyed = isKeyed(iterable); | |
var h = ordered ? 1 : 0; | |
var size = iterable.__iterate( | |
keyed ? | |
ordered ? | |
function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } : | |
function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } : | |
ordered ? | |
function(v ) { h = 31 * h + hash(v) | 0; } : | |
function(v ) { h = h + hash(v) | 0; } | |
); | |
return murmurHashOfSize(size, h); | |
} | |
function murmurHashOfSize(size, h) { | |
h = imul(h, 0xCC9E2D51); | |
h = imul(h << 15 | h >>> -15, 0x1B873593); | |
h = imul(h << 13 | h >>> -13, 5); | |
h = (h + 0xE6546B64 | 0) ^ size; | |
h = imul(h ^ h >>> 16, 0x85EBCA6B); | |
h = imul(h ^ h >>> 13, 0xC2B2AE35); | |
h = smi(h ^ h >>> 16); | |
return h; | |
} | |
function hashMerge(a, b) { | |
return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int | |
} | |
var Immutable = { | |
Iterable: Iterable, | |
Seq: Seq, | |
Collection: Collection, | |
Map: Map, | |
OrderedMap: OrderedMap, | |
List: List, | |
Stack: Stack, | |
Set: Set, | |
OrderedSet: OrderedSet, | |
Record: Record, | |
Range: Range, | |
Repeat: Repeat, | |
is: is, | |
fromJS: fromJS | |
}; | |
return Immutable; | |
})); | |
}); | |
interopDefault(immutable); | |
var Map = immutable.Map; | |
var OrderedMap = immutable.OrderedMap; | |
var List = immutable.List; | |
var Stack = immutable.Stack; | |
var Set = immutable.Set; | |
var Record = immutable.Record; | |
/** | |
* Data. | |
* | |
* This isn't an immutable record, it's just a thin wrapper around `Map` so that | |
* we can allow for more convenient creation. | |
*/ | |
var Data = { | |
/** | |
* Create a new `Data` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Data} data | |
*/ | |
create: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
return Map.isMap(properties) ? properties : new Map(properties); | |
} | |
}; | |
/** | |
* Record. | |
*/ | |
var DEFAULTS$3 = { | |
data: new Map(), | |
type: null | |
}; | |
/** | |
* Mark. | |
*/ | |
var Mark = function (_ref) { | |
inherits(Mark, _ref); | |
function Mark() { | |
classCallCheck(this, Mark); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Mark).apply(this, arguments)); | |
} | |
createClass(Mark, [{ | |
key: 'kind', | |
/** | |
* Get the kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'mark'; | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Mark` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Mark} mark | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Mark) return properties; | |
if (!properties.type) throw new Error('You must provide a `type` for the mark.'); | |
properties.data = Data.create(properties.data); | |
return new Mark(properties); | |
} | |
/** | |
* Create a marks set from an array of marks. | |
* | |
* @param {Array} array | |
* @return {Set} marks | |
*/ | |
}, { | |
key: 'createSet', | |
value: function createSet() { | |
var array = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; | |
if (Set.isSet(array)) return array; | |
return new Set(array.map(Mark.create)); | |
} | |
}]); | |
return Mark; | |
}(new Record(DEFAULTS$3)); | |
/** | |
* Record. | |
*/ | |
var CharacterRecord = new Record({ | |
marks: new Set(), | |
text: '' | |
}); | |
/** | |
* Character. | |
*/ | |
var Character = function (_CharacterRecord) { | |
inherits(Character, _CharacterRecord); | |
function Character() { | |
classCallCheck(this, Character); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Character).apply(this, arguments)); | |
} | |
createClass(Character, [{ | |
key: 'kind', | |
/** | |
* Get the kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'character'; | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a character record with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Character} character | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Character) return properties; | |
properties.marks = Mark.createSet(properties.marks); | |
return new Character(properties); | |
} | |
/** | |
* Create a characters list from an array of characters. | |
* | |
* @param {Array} array | |
* @return {List} characters | |
*/ | |
}, { | |
key: 'createList', | |
value: function createList() { | |
var array = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; | |
if (List.isList(array)) return array; | |
return new List(array.map(Character.create)); | |
} | |
}]); | |
return Character; | |
}(CharacterRecord); | |
/** | |
* The leaf node of a cache tree. | |
* | |
* An object, so that immutable maps will key it by reference. | |
* | |
* @type {Object} | |
*/ | |
var LEAF = {}; | |
/** | |
* Memoize all of the `properties` on a `object`. | |
* | |
* @param {Object} object | |
* @param {Array} properties | |
* @return {Record} | |
*/ | |
function memoize(object, properties) { | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
var _loop = function _loop() { | |
var property = _step.value; | |
var original = object[property]; | |
if (!original) { | |
throw new Error('Object does not have a property named "' + property + '".'); | |
} | |
object[property] = function () { | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
var keys = [property].concat(args, [LEAF]); | |
var cache = this.cache = this.cache || new Map(); | |
if (cache.hasIn(keys)) return cache.getIn(keys); | |
var value = original.apply(this, args); | |
this.cache = cache.setIn(keys, value); | |
return value; | |
}; | |
}; | |
for (var _iterator = properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
_loop(); | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
} | |
/** | |
* Start-and-end convenience methods to auto-generate. | |
*/ | |
var START_END_METHODS = ['collapseTo%']; | |
/** | |
* Start-end-and-edge convenience methods to auto-generate. | |
*/ | |
var EDGE_METHODS = ['has%AtStartOf', 'has%AtEndOf', 'has%Between', 'has%In']; | |
/** | |
* Default properties. | |
*/ | |
var DEFAULTS$4 = { | |
anchorKey: null, | |
anchorOffset: 0, | |
focusKey: null, | |
focusOffset: 0, | |
isBackward: null, | |
isFocused: false | |
}; | |
/** | |
* Selection. | |
*/ | |
var Selection = function (_ref) { | |
inherits(Selection, _ref); | |
function Selection() { | |
classCallCheck(this, Selection); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Selection).apply(this, arguments)); | |
} | |
createClass(Selection, [{ | |
key: 'hasAnchorAtStartOf', | |
/** | |
* Check whether anchor point of the selection is at the start of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
value: function hasAnchorAtStartOf(node) { | |
if (this.anchorOffset != 0) return false; | |
var first = node.kind == 'text' ? node : node.getTexts().first(); | |
return this.anchorKey == first.key; | |
} | |
/** | |
* Check whether anchor point of the selection is at the end of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasAnchorAtEndOf', | |
value: function hasAnchorAtEndOf(node) { | |
var last = node.kind == 'text' ? node : node.getTexts().last(); | |
return this.anchorKey == last.key && this.anchorOffset == last.length; | |
} | |
/** | |
* Check whether the anchor edge of a selection is in a `node` and at an | |
* offset between `start` and `end`. | |
* | |
* @param {Node} node | |
* @param {Number} start | |
* @param {Number} end | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasAnchorBetween', | |
value: function hasAnchorBetween(node, start, end) { | |
return this.anchorOffset <= end && start <= this.anchorOffset && this.hasAnchorIn(node); | |
} | |
/** | |
* Check whether the anchor edge of a selection is in a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasAnchorIn', | |
value: function hasAnchorIn(node) { | |
var _this2 = this; | |
var nodes = node.kind == 'text' ? [node] : node.getTexts(); | |
return nodes.some(function (n) { | |
return n.key == _this2.anchorKey; | |
}); | |
} | |
/** | |
* Check whether focus point of the selection is at the end of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasFocusAtEndOf', | |
value: function hasFocusAtEndOf(node) { | |
var last = node.kind == 'text' ? node : node.getTexts().last(); | |
return this.focusKey == last.key && this.focusOffset == last.length; | |
} | |
/** | |
* Check whether focus point of the selection is at the start of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasFocusAtStartOf', | |
value: function hasFocusAtStartOf(node) { | |
if (this.focusOffset != 0) return false; | |
var first = node.kind == 'text' ? node : node.getTexts().first(); | |
return this.focusKey == first.key; | |
} | |
/** | |
* Check whether the focus edge of a selection is in a `node` and at an | |
* offset between `start` and `end`. | |
* | |
* @param {Node} node | |
* @param {Number} start | |
* @param {Number} end | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasFocusBetween', | |
value: function hasFocusBetween(node, start, end) { | |
return start <= this.focusOffset && this.focusOffset <= end && this.hasFocusIn(node); | |
} | |
/** | |
* Check whether the focus edge of a selection is in a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'hasFocusIn', | |
value: function hasFocusIn(node) { | |
var _this3 = this; | |
var nodes = node.kind == 'text' ? [node] : node.getTexts(); | |
return nodes.some(function (n) { | |
return n.key == _this3.focusKey; | |
}); | |
} | |
/** | |
* Check whether the selection is at the start of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} isAtStart | |
*/ | |
}, { | |
key: 'isAtStartOf', | |
value: function isAtStartOf(node) { | |
var isExpanded = this.isExpanded; | |
var startKey = this.startKey; | |
var startOffset = this.startOffset; | |
if (isExpanded) return false; | |
if (startOffset != 0) return false; | |
var first = node.kind == 'text' ? node : node.getTexts().first(); | |
return startKey == first.key; | |
} | |
/** | |
* Check whether the selection is at the end of a `node`. | |
* | |
* @param {Node} node | |
* @return {Boolean} isAtEnd | |
*/ | |
}, { | |
key: 'isAtEndOf', | |
value: function isAtEndOf(node) { | |
var endKey = this.endKey; | |
var endOffset = this.endOffset; | |
var isExpanded = this.isExpanded; | |
if (isExpanded) return false; | |
var last = node.kind == 'text' ? node : node.getTexts().last(); | |
return endKey == last.key && endOffset == last.length; | |
} | |
/** | |
* Normalize the selection, relative to a `node`, ensuring that the anchor | |
* and focus nodes of the selection always refer to leaf text nodes. | |
* | |
* @param {Node} node | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'normalize', | |
value: function normalize(node) { | |
var selection = this; | |
var isCollapsed = selection.isCollapsed; | |
var anchorKey = selection.anchorKey; | |
var anchorOffset = selection.anchorOffset; | |
var focusKey = selection.focusKey; | |
var focusOffset = selection.focusOffset; | |
var isBackward = selection.isBackward; | |
// If the selection isn't formed yet or is malformed, set it to the | |
// beginning of the node. | |
if (anchorKey == null || focusKey == null || !node.hasDescendant(anchorKey) || !node.hasDescendant(focusKey)) { | |
var first = node.getTexts().first(); | |
return selection.merge({ | |
anchorKey: first.key, | |
anchorOffset: 0, | |
focusKey: first.key, | |
focusOffset: 0, | |
isBackward: false | |
}); | |
} | |
// Get the anchor and focus nodes. | |
var anchorNode = node.getDescendant(anchorKey); | |
var focusNode = node.getDescendant(focusKey); | |
// If the anchor node isn't a text node, match it to one. | |
if (anchorNode.kind != 'text') { | |
var anchorText = anchorNode.getTextAtOffset(anchorOffset); | |
var offset = anchorNode.getOffset(anchorText); | |
anchorOffset = anchorOffset - offset; | |
anchorNode = anchorText; | |
} | |
// If the focus node isn't a text node, match it to one. | |
if (focusNode.kind != 'text') { | |
var focusText = focusNode.getTextAtOffset(focusOffset); | |
var _offset = focusNode.getOffset(focusText); | |
focusOffset = focusOffset - _offset; | |
focusNode = focusText; | |
} | |
// If `isBackward` is not set, derive it. | |
if (isBackward == null) { | |
var texts = node.getTexts(); | |
var anchorIndex = texts.indexOf(anchorNode); | |
var focusIndex = texts.indexOf(focusNode); | |
isBackward = anchorIndex == focusIndex ? anchorOffset > focusOffset : anchorIndex > focusIndex; | |
} | |
// Merge in any updated properties. | |
return selection.merge({ | |
anchorKey: anchorNode.key, | |
anchorOffset: anchorOffset, | |
focusKey: focusNode.key, | |
focusOffset: focusOffset, | |
isBackward: isBackward | |
}); | |
} | |
/** | |
* Focus the selection. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'focus', | |
value: function focus() { | |
return this.merge({ | |
isFocused: true | |
}); | |
} | |
/** | |
* Blur the selection. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'blur', | |
value: function blur() { | |
return this.merge({ | |
isFocused: false | |
}); | |
} | |
/** | |
* Move the focus point to the anchor point. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'collapseToAnchor', | |
value: function collapseToAnchor() { | |
return this.merge({ | |
focusKey: this.anchorKey, | |
focusOffset: this.anchorOffset, | |
isBackward: false | |
}); | |
} | |
/** | |
* Move the anchor point to the focus point. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'collapseToFocus', | |
value: function collapseToFocus() { | |
return this.merge({ | |
anchorKey: this.focusKey, | |
anchorOffset: this.focusOffset, | |
isBackward: false | |
}); | |
} | |
/** | |
* Move to the start of a `node`. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'collapseToStartOf', | |
value: function collapseToStartOf(node) { | |
return this.merge({ | |
anchorKey: node.key, | |
anchorOffset: 0, | |
focusKey: node.key, | |
focusOffset: 0, | |
isBackward: false | |
}); | |
} | |
/** | |
* Move to the end of a `node`. | |
* | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'collapseToEndOf', | |
value: function collapseToEndOf(node) { | |
return this.merge({ | |
anchorKey: node.key, | |
anchorOffset: node.length, | |
focusKey: node.key, | |
focusOffset: node.length, | |
isBackward: false | |
}); | |
} | |
/** | |
* Move to the entire range of `start` and `end` nodes. | |
* | |
* @param {Node} start | |
* @param {Node} end (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'moveToRangeOf', | |
value: function moveToRangeOf(start) { | |
var end = arguments.length <= 1 || arguments[1] === undefined ? start : arguments[1]; | |
return this.merge({ | |
anchorKey: start.key, | |
anchorOffset: 0, | |
focusKey: end.key, | |
focusOffset: end.length, | |
isBackward: null | |
}); | |
} | |
/** | |
* Move the selection forward `n` characters. | |
* | |
* @param {Number} n (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'moveForward', | |
value: function moveForward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
return this.merge({ | |
anchorOffset: this.anchorOffset + n, | |
focusOffset: this.focusOffset + n | |
}); | |
} | |
/** | |
* Move the selection backward `n` characters. | |
* | |
* @param {Number} n (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'moveBackward', | |
value: function moveBackward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
return this.merge({ | |
anchorOffset: this.anchorOffset - n, | |
focusOffset: this.focusOffset - n | |
}); | |
} | |
/** | |
* Move the selection to `anchor` and `focus` offsets. | |
* | |
* @param {Number} anchor | |
* @param {Number} focus (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'moveToOffsets', | |
value: function moveToOffsets(anchor) { | |
var focus = arguments.length <= 1 || arguments[1] === undefined ? anchor : arguments[1]; | |
return this.merge({ | |
anchorOffset: anchor, | |
focusOffset: focus, | |
isBackward: null | |
}); | |
} | |
/** | |
* Extend the focus point forward `n` characters. | |
* | |
* @param {Number} n (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'extendForward', | |
value: function extendForward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
return this.merge({ | |
focusOffset: this.focusOffset + n, | |
isBackward: null | |
}); | |
} | |
/** | |
* Extend the focus point backward `n` characters. | |
* | |
* @param {Number} n (optional) | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'extendBackward', | |
value: function extendBackward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
return this.merge({ | |
focusOffset: this.focusOffset - n, | |
isBackward: null | |
}); | |
} | |
/** | |
* Extend the focus point to the start of a `node`. | |
* | |
* @param {Node} node | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'extendToStartOf', | |
value: function extendToStartOf(node) { | |
return this.merge({ | |
focusKey: node.key, | |
focusOffset: 0, | |
isBackward: null | |
}); | |
} | |
/** | |
* Extend the focus point to the end of a `node`. | |
* | |
* @param {Node} node | |
* @return {Selection} selection | |
*/ | |
}, { | |
key: 'extendToEndOf', | |
value: function extendToEndOf(node) { | |
return this.merge({ | |
focusKey: node.key, | |
focusOffset: node.length, | |
isBackward: null | |
}); | |
} | |
}, { | |
key: 'kind', | |
/** | |
* Get the kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'selection'; | |
} | |
/** | |
* Get whether the selection is blurred. | |
* | |
* @return {Boolean} isBlurred | |
*/ | |
}, { | |
key: 'isBlurred', | |
get: function get() { | |
return !this.isFocused; | |
} | |
/** | |
* Get whether the selection is collapsed. | |
* | |
* @return {Boolean} isCollapsed | |
*/ | |
}, { | |
key: 'isCollapsed', | |
get: function get() { | |
return this.anchorKey == this.focusKey && this.anchorOffset == this.focusOffset; | |
} | |
/** | |
* Get whether the selection is expanded. | |
* | |
* @return {Boolean} isExpanded | |
*/ | |
}, { | |
key: 'isExpanded', | |
get: function get() { | |
return !this.isCollapsed; | |
} | |
/** | |
* Get whether the selection is forward. | |
* | |
* @return {Boolean} isForward | |
*/ | |
}, { | |
key: 'isForward', | |
get: function get() { | |
return this.isBackward == null ? null : !this.isBackward; | |
} | |
/** | |
* Get the start key. | |
* | |
* @return {String} startKey | |
*/ | |
}, { | |
key: 'startKey', | |
get: function get() { | |
return this.isBackward ? this.focusKey : this.anchorKey; | |
} | |
}, { | |
key: 'startOffset', | |
get: function get() { | |
return this.isBackward ? this.focusOffset : this.anchorOffset; | |
} | |
}, { | |
key: 'endKey', | |
get: function get() { | |
return this.isBackward ? this.anchorKey : this.focusKey; | |
} | |
}, { | |
key: 'endOffset', | |
get: function get() { | |
return this.isBackward ? this.anchorOffset : this.focusOffset; | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Selection` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Selection} selection | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Selection) return properties; | |
return new Selection(properties); | |
} | |
}]); | |
return Selection; | |
}(new Record(DEFAULTS$4)); | |
/** | |
* Add start, end and edge convenience methods. | |
*/ | |
START_END_METHODS.concat(EDGE_METHODS).forEach(function (pattern) { | |
var _pattern$split = pattern.split('%'); | |
var _pattern$split2 = slicedToArray(_pattern$split, 2); | |
var p = _pattern$split2[0]; | |
var s = _pattern$split2[1]; | |
var anchor = p + 'Anchor' + s; | |
var edge = p + 'Edge' + s; | |
var end = p + 'End' + s; | |
var focus = p + 'Focus' + s; | |
var start = p + 'Start' + s; | |
Selection.prototype[start] = function () { | |
return this.isBackward ? this[focus].apply(this, arguments) : this[anchor].apply(this, arguments); | |
}; | |
Selection.prototype[end] = function () { | |
return this.isBackward ? this[anchor].apply(this, arguments) : this[focus].apply(this, arguments); | |
}; | |
if (!includes$1(EDGE_METHODS, pattern)) return; | |
Selection.prototype[edge] = function () { | |
return this[anchor].apply(this, arguments) || this[focus].apply(this, arguments); | |
}; | |
}); | |
/** | |
* Memoize read methods. | |
*/ | |
memoize(Selection.prototype, ['hasAnchorAtStartOf', 'hasAnchorAtEndOf', 'hasAnchorBetween', 'hasAnchorIn', 'hasFocusAtEndOf', 'hasFocusAtStartOf', 'hasFocusBetween', 'hasFocusIn', 'isAtStartOf', 'isAtEndOf']); | |
var index$1 = createCommonjsModule(function (module) { | |
/** | |
* Export `uid` | |
*/ | |
module.exports = uid; | |
/** | |
* Create a `uid` | |
* | |
* @param {String} len | |
* @return {String} uid | |
*/ | |
function uid(len) { | |
len = len || 7; | |
return Math.random().toString(35).substr(2, len); | |
} | |
}); | |
var generate = interopDefault(index$1); | |
/** | |
* Create a unique identifier. | |
* | |
* @return {String} uid | |
*/ | |
function uid() { | |
return generate(4); | |
} | |
/** | |
* Default properties. | |
*/ | |
var DEFAULTS$5 = { | |
characters: new List(), | |
decorations: null, | |
key: null, | |
cache: null | |
}; | |
/** | |
* Text. | |
*/ | |
var Text = function (_ref) { | |
inherits(Text, _ref); | |
function Text() { | |
classCallCheck(this, Text); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Text).apply(this, arguments)); | |
} | |
createClass(Text, [{ | |
key: 'decorateCharacters', | |
/** | |
* Decorate the text node's characters with a `decorator` function. | |
* | |
* @param {Function} decorator | |
* @return {Text} text | |
*/ | |
value: function decorateCharacters(decorator) { | |
var characters = this.characters; | |
var cache = this.cache; | |
if (characters == cache) return this; | |
var decorations = decorator(this); | |
if (decorations == characters) return this; | |
return this.merge({ | |
cache: characters, | |
decorations: decorations | |
}); | |
} | |
/** | |
* Remove characters from the text node from `start` to `end`. | |
* | |
* @param {Number} start | |
* @param {Number} end | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'removeCharacters', | |
value: function removeCharacters(start, end) { | |
var characters = this.characters; | |
characters = characters.filterNot(function (char, i) { | |
return start <= i && i < end; | |
}); | |
return this.merge({ characters: characters }); | |
} | |
/** | |
* Insert text `string` at `index`. | |
* | |
* @param {Numbder} index | |
* @param {String} string | |
* @param {String} marks (optional) | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'insertText', | |
value: function insertText(index, string, marks) { | |
var characters = this.characters; | |
if (!marks) { | |
var prev = index ? characters.get(index - 1) : null; | |
marks = prev ? prev.marks : Mark.createSet(); | |
} | |
var chars = Character.createList(string.split('').map(function (char) { | |
return { | |
text: char, | |
marks: marks | |
}; | |
})); | |
characters = characters.slice(0, index).concat(chars).concat(characters.slice(index)); | |
return this.merge({ characters: characters }); | |
} | |
}, { | |
key: 'kind', | |
/** | |
* Get the node's kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'text'; | |
} | |
/** | |
* Get the length of the concatenated text of the node. | |
* | |
* @return {Number} length | |
*/ | |
}, { | |
key: 'length', | |
get: function get() { | |
return this.text.length; | |
} | |
/** | |
* Get the concatenated text of the node. | |
* | |
* @return {String} text | |
*/ | |
}, { | |
key: 'text', | |
get: function get() { | |
return this.characters.map(function (char) { | |
return char.text; | |
}).join(''); | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Text` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Text} text | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Text) return properties; | |
properties.key = uid(4); | |
properties.characters = Character.createList(properties.characters); | |
properties.decorations = null; | |
properties.cache = null; | |
return new Text(properties); | |
} | |
/** | |
* Create a list of `Texts` from an array. | |
* | |
* @param {Array} elements | |
* @return {List} map | |
*/ | |
}, { | |
key: 'createList', | |
value: function createList() { | |
var elements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; | |
if (List.isList(elements)) return elements; | |
return new List(elements.map(Text.create)); | |
} | |
}]); | |
return Text; | |
}(new Record(DEFAULTS$5)); | |
/** | |
* Transforms. | |
* | |
* These are pulled out into their own file because they can get complex. | |
*/ | |
var Transforms = { | |
/** | |
* Delete everything in a `range`. | |
* | |
* @param {Selection} range | |
* @return {Node} node | |
*/ | |
deleteAtRange: function deleteAtRange(range) { | |
if (range.isCollapsed) return this; | |
var node = this; | |
// Make sure the children exist. | |
var startKey = range.startKey; | |
var startOffset = range.startOffset; | |
var endKey = range.endKey; | |
var endOffset = range.endOffset; | |
node.assertDescendant(startKey); | |
node.assertDescendant(endKey); | |
// If the start and end nodes are the same, just remove characters. | |
if (startKey == endKey) { | |
var text = node.getDescendant(startKey); | |
text = text.removeCharacters(startOffset, endOffset); | |
node = node.updateDescendant(text); | |
return node; | |
} | |
// Split the blocks and determine the edge boundaries. | |
var start = range.collapseToStart(); | |
var end = range.collapseToEnd(); | |
node = node.splitBlockAtRange(start, Infinity); | |
node = node.splitBlockAtRange(end, Infinity); | |
var startText = node.getDescendant(startKey); | |
var startEdgeText = node.getNextText(startKey); | |
var endText = node.getNextText(endKey); | |
var endEdgeText = node.getDescendant(endKey); | |
// Remove the new blocks inside the edges. | |
var startEdgeBlock = node.getFurthestBlock(startEdgeText); | |
var endEdgeBlock = node.getFurthestBlock(endEdgeText); | |
var nodes = node.nodes.takeUntil(function (n) { | |
return n == startEdgeBlock; | |
}).concat(node.nodes.skipUntil(function (n) { | |
return n == endEdgeBlock; | |
}).rest()); | |
node = node.merge({ nodes: nodes }); | |
// Take the end edge's split text and move it to the start edge. | |
var startBlock = node.getClosestBlock(startText); | |
var endChild = node.getFurthestInline(endText) || endText; | |
var startNodes = startBlock.nodes.push(endChild); | |
startBlock = startBlock.merge({ nodes: startNodes }); | |
node = node.updateDescendant(startBlock); | |
// While the end child is an only child, remove the block it's in. | |
var endParent = node.getClosestBlock(endChild); | |
while (endParent && endParent.nodes.size == 1) { | |
endChild = endParent; | |
endParent = node.getClosestBlock(endParent); | |
} | |
node = node.removeDescendant(endChild); | |
// Normalize the adjacent text nodes. | |
return node.normalize(); | |
}, | |
/** | |
* Delete backward `n` characters at a `range`. | |
* | |
* @param {Selection} range | |
* @param {Number} n (optional) | |
* @return {Node} node | |
*/ | |
deleteBackwardAtRange: function deleteBackwardAtRange(range) { | |
var n = arguments.length <= 1 || arguments[1] === undefined ? 1 : arguments[1]; | |
var node = this; | |
var _range = range; | |
var startKey = _range.startKey; | |
var startOffset = _range.startOffset; | |
// When the range is still expanded, just do a regular delete. | |
if (range.isExpanded) return node.deleteAtRange(range); | |
// When collapsed at the start of the node, there's nothing to do. | |
if (range.isAtStartOf(node)) return node; | |
// When collapsed in a void node, remove that node. | |
var block = node.getClosestBlock(startKey); | |
if (block && block.isVoid) return node.removeDescendant(block); | |
var inline = node.getClosestInline(startKey); | |
if (inline && inline.isVoid) return node.removeDescendant(inline); | |
// When at start of a text node, merge forwards into the next text node. | |
var startNode = node.getDescendant(startKey); | |
if (range.isAtStartOf(startNode)) { | |
var previous = node.getPreviousText(startNode); | |
// If the previous descendant is void, remove it. | |
var prevBlock = node.getClosestBlock(previous); | |
if (prevBlock && prevBlock.isVoid) return node.removeDescendant(prevBlock); | |
var prevInline = node.getClosestInline(previous); | |
if (prevInline && prevInline.isVoid) return node.removeDescendant(prevInline); | |
range = range.extendToEndOf(previous); | |
range = range.normalize(node); | |
return node.deleteAtRange(range); | |
} | |
// Otherwise, remove `n` characters behind of the cursor. | |
range = range.extendBackward(n); | |
range = range.normalize(node); | |
return node.deleteAtRange(range); | |
}, | |
/** | |
* Delete forward `n` characters at a `range`. | |
* | |
* @param {Selection} range | |
* @param {Number} n (optional) | |
* @return {Node} node | |
*/ | |
deleteForwardAtRange: function deleteForwardAtRange(range) { | |
var n = arguments.length <= 1 || arguments[1] === undefined ? 1 : arguments[1]; | |
var node = this; | |
var _range2 = range; | |
var startKey = _range2.startKey; | |
// When the range is still expanded, just do a regular delete. | |
if (range.isExpanded) return node.deleteAtRange(range); | |
// When collapsed at the end of the node, there's nothing to do. | |
if (range.isAtEndOf(node)) return node; | |
// When collapsed in a void node, remove that node. | |
var block = node.getClosestBlock(startKey); | |
if (block && block.isVoid) return node.removeDescendant(block); | |
var inline = node.getClosestInline(startKey); | |
if (inline && inline.isVoid) return node.removeDescendant(inline); | |
// When at end of a text node, merge forwards into the next text node. | |
var startNode = node.getDescendant(startKey); | |
if (range.isAtEndOf(startNode)) { | |
var next = node.getNextText(startNode); | |
range = range.extendToStartOf(next); | |
range = range.normalize(node); | |
return node.deleteAtRange(range); | |
} | |
// Otherwise, remove `n` characters ahead of the cursor. | |
range = range.extendForward(n); | |
range = range.normalize(node); | |
return node.deleteAtRange(range); | |
}, | |
/** | |
* Insert a `fragment` at a `range`. | |
* | |
* @param {Selection} range | |
* @param {List} fragment | |
* @return {Node} node | |
*/ | |
insertFragmentAtRange: function insertFragmentAtRange(range, fragment) { | |
range = range.normalize(this); | |
var node = this; | |
// If the range is expanded, delete first. | |
if (range.isExpanded) { | |
node = node.deleteAtRange(range); | |
range = range.collapseToStart(); | |
} | |
// If the fragment is empty, do nothing. | |
if (!fragment.length) return node; | |
// Make sure each node in the fragment has a unique key. | |
fragment = fragment.mapDescendants(function (child) { | |
return child.set('key', uid()); | |
}); | |
// Split the inlines if need be. | |
if (!node.isInlineSplitAtRange(range)) { | |
node = node.splitInlineAtRange(range); | |
} | |
// Determine the start and next children to insert into. | |
var _range3 = range; | |
var startKey = _range3.startKey; | |
var endKey = _range3.endKey; | |
var block = node.getClosestBlock(startKey); | |
var start = node.getDescendant(startKey); | |
var startChild = void 0; | |
var nextChild = void 0; | |
if (range.isAtStartOf(node)) { | |
nextChild = node.getClosestBlock(node.getTexts().first()); | |
} | |
if (range.isAtStartOf(block)) { | |
nextChild = block.getHighestChild(block.getTexts().first()); | |
} else if (range.isAtStartOf(start)) { | |
startChild = block.getHighestChild(block.getPreviousText(start)); | |
nextChild = block.getNextSibling(startChild); | |
} else { | |
startChild = block.getHighestChild(start); | |
nextChild = block.getNextSibling(startChild); | |
} | |
// Get the first and last block of the fragment. | |
var blocks = fragment.getBlocks(); | |
var firstBlock = blocks.first(); | |
var lastBlock = blocks.last(); | |
// If the block is empty, merge in the first block's type and data. | |
if (block.length == 0) { | |
block = block.merge({ | |
type: firstBlock.type, | |
data: firstBlock.data | |
}); | |
} | |
// Insert the first blocks nodes into the starting block. | |
if (startChild) { | |
block = block.insertChildrenAfter(startChild, firstBlock.nodes); | |
} else { | |
block = block.insertChildrenBefore(nextChild, firstBlock.nodes); | |
} | |
node = node.updateDescendant(block); | |
// If there are no other siblings, that's it. | |
if (firstBlock == lastBlock) return node.normalize(); | |
// Otherwise, remove the fragment's first block's highest solo parent... | |
var highestParent = fragment.getHighestOnlyChildParent(firstBlock); | |
fragment = fragment.removeDescendant(highestParent || firstBlock); | |
// Then, add the inlines after the cursor from the current block to the | |
// start of the last block in the fragment. | |
if (nextChild) { | |
lastBlock = lastBlock.concatChildren(block.getChildrenAfterIncluding(nextChild)); | |
fragment = fragment.updateDescendant(lastBlock); | |
block = block.removeChildrenAfterIncluding(nextChild); | |
node = node.updateDescendant(block); | |
} | |
// Finally, add the fragment's children after the block. | |
node = node.insertChildrenAfter(block, fragment.nodes); | |
return node.normalize(); | |
}, | |
/** | |
* Insert text `string` at a `range`, with optional `marks`. | |
* | |
* @param {Selection} range | |
* @param {String} string | |
* @param {Set} marks (optional) | |
* @return {Node} node | |
*/ | |
insertTextAtRange: function insertTextAtRange(range, string, marks) { | |
var node = this; | |
// When still expanded, remove the current range first. | |
if (range.isExpanded) { | |
node = node.deleteAtRange(range); | |
range = range.collapseToStart(); | |
} | |
// Insert text at the range's offset. | |
var _range4 = range; | |
var startKey = _range4.startKey; | |
var startOffset = _range4.startOffset; | |
var text = node.getDescendant(startKey); | |
text = text.insertText(startOffset, string, marks); | |
node = node.updateDescendant(text); | |
return node; | |
}, | |
/** | |
* Add a new `mark` to the characters at `range`. | |
* | |
* @param {Selection} range | |
* @param {Mark or String} mark | |
* @return {Node} node | |
*/ | |
addMarkAtRange: function addMarkAtRange(range, mark) { | |
var node = this; | |
// Allow for just passing a type for convenience. | |
if (typeof mark == 'string') { | |
mark = new Mark({ type: mark }); | |
} | |
// When the range is collapsed, do nothing. | |
if (range.isCollapsed) return node; | |
// Otherwise, find each of the text nodes within the range. | |
var startKey = range.startKey; | |
var startOffset = range.startOffset; | |
var endKey = range.endKey; | |
var endOffset = range.endOffset; | |
var texts = node.getTextsAtRange(range); | |
// Apply the mark to each of the text nodes's matching characters. | |
texts = texts.map(function (text) { | |
var characters = text.characters.map(function (char, i) { | |
if (!isInRange$1(i, text, range)) return char; | |
var marks = char.marks; | |
marks = marks.add(mark); | |
return char.merge({ marks: marks }); | |
}); | |
return text.merge({ characters: characters }); | |
}); | |
// Update each of the text nodes. | |
texts.forEach(function (text) { | |
node = node.updateDescendant(text); | |
}); | |
return node; | |
}, | |
/** | |
* Set the `properties` of block nodes in a `range`. | |
* | |
* @param {Selection} range | |
* @param {Object or String} properties | |
* @return {Node} node | |
*/ | |
setBlockAtRange: function setBlockAtRange(range) { | |
var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | |
var node = this; | |
// Allow for properties to be a string `type` for convenience. | |
if (typeof properties == 'string') { | |
properties = { type: properties }; | |
} | |
// Update each of the blocks. | |
var blocks = node.getBlocksAtRange(range); | |
blocks.forEach(function (block) { | |
if (properties.data) properties.data = Data.create(properties.data); | |
block = block.merge(properties); | |
node = node.updateDescendant(block); | |
}); | |
return node.normalize(); | |
}, | |
/** | |
* Set the `properties` of inline nodes in a `range`. | |
* | |
* @param {Selection} range | |
* @param {Object or String} properties | |
* @return {Node} node | |
*/ | |
setInlineAtRange: function setInlineAtRange(range) { | |
var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | |
var node = this; | |
// Allow for properties to be a string `type` for convenience. | |
if (typeof properties == 'string') { | |
properties = { type: properties }; | |
} | |
// Update each of the inlines. | |
var inlines = node.getInlinesAtRange(range); | |
inlines.forEach(function (inline) { | |
if (properties.data) properties.data = Data.create(properties.data); | |
inline = inline.merge(properties); | |
node = node.updateDescendant(inline); | |
}); | |
return node.normalize(); | |
}, | |
/** | |
* Split the block nodes at a `range`, to optional `depth`. | |
* | |
* @param {Selection} range | |
* @param {Number} depth (optional) | |
* @return {Node} node | |
*/ | |
splitBlockAtRange: function splitBlockAtRange(range) { | |
var depth = arguments.length <= 1 || arguments[1] === undefined ? 1 : arguments[1]; | |
var node = this; | |
// If the range is expanded, remove it first. | |
if (range.isExpanded) { | |
node = node.deleteAtRange(range); | |
range = range.collapseToStart(); | |
} | |
// Split the inline nodes at the range. | |
node = node.splitInlineAtRange(range); | |
// Find the highest inline elements that were split. | |
var _range5 = range; | |
var startKey = _range5.startKey; | |
var firstText = node.getDescendant(startKey); | |
var secondText = node.getNextText(startKey); | |
var firstChild = node.getFurthestInline(firstText) || firstText; | |
var secondChild = node.getFurthestInline(secondText) || secondText; | |
var parent = node.getClosestBlock(firstChild); | |
var firstChildren = void 0; | |
var secondChildren = void 0; | |
var d = 0; | |
// While the parent is a block, split the block nodes. | |
while (parent && d < depth) { | |
firstChildren = parent.nodes.takeUntil(function (n) { | |
return n == firstChild; | |
}).push(firstChild); | |
secondChildren = parent.nodes.skipUntil(function (n) { | |
return n == secondChild; | |
}); | |
firstChild = parent.merge({ nodes: firstChildren }); | |
secondChild = Block.create({ | |
nodes: secondChildren, | |
type: parent.type, | |
data: parent.data | |
}); | |
// Add the new children. | |
var grandparent = node.getParent(parent); | |
var nodes = grandparent.nodes.takeUntil(function (n) { | |
return n.key == firstChild.key; | |
}).push(firstChild).push(secondChild).concat(grandparent.nodes.skipUntil(function (n) { | |
return n.key == firstChild.key; | |
}).rest()); | |
// Update the grandparent. | |
node = grandparent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(grandparent.merge({ nodes: nodes })); | |
d++; | |
parent = node.getClosestBlock(firstChild); | |
} | |
return node; | |
}, | |
/** | |
* Split the inline nodes at a `range`, to optional `depth`. | |
* | |
* @param {Selection} range | |
* @param {Number} depth (optiona) | |
* @return {Node} node | |
*/ | |
splitInlineAtRange: function splitInlineAtRange(range) { | |
var depth = arguments.length <= 1 || arguments[1] === undefined ? Infinity : arguments[1]; | |
var node = this; | |
// If the range is expanded, remove it first. | |
if (range.isExpanded) { | |
node = node.deleteAtRange(range); | |
range = range.collapseToStart(); | |
} | |
// First split the text nodes. | |
node = node.splitTextAtRange(range); | |
// Find the children that were split. | |
var _range6 = range; | |
var startKey = _range6.startKey; | |
var firstChild = node.getDescendant(startKey); | |
var secondChild = node.getNextText(firstChild); | |
var parent = node.getClosestInline(firstChild); | |
var d = 0; | |
// While the parent is an inline parent, split the inline nodes. | |
while (parent && d < depth) { | |
firstChild = parent.merge({ nodes: Inline.createList([firstChild]) }); | |
secondChild = Inline.create({ | |
nodes: [secondChild], | |
type: parent.type, | |
data: parent.data | |
}); | |
// Split the children. | |
var grandparent = node.getParent(parent); | |
var nodes = grandparent.nodes.takeUntil(function (n) { | |
return n.key == firstChild.key; | |
}).push(firstChild).push(secondChild).concat(grandparent.nodes.skipUntil(function (n) { | |
return n.key == firstChild.key; | |
}).rest()); | |
// Update the grandparent. | |
node = grandparent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(grandparent.merge({ nodes: nodes })); | |
d++; | |
parent = node.getClosestInline(firstChild); | |
} | |
return node; | |
}, | |
/** | |
* Split the text nodes at a `range`. | |
* | |
* @param {Selection} range | |
* @return {Node} node | |
*/ | |
splitTextAtRange: function splitTextAtRange(range) { | |
var node = this; | |
// If the range is expanded, remove it first. | |
if (range.isExpanded) { | |
node = node.deleteAtRange(range); | |
range = range.collapseToStart(); | |
} | |
// Split the text node's characters. | |
var _range7 = range; | |
var startKey = _range7.startKey; | |
var startOffset = _range7.startOffset; | |
var text = node.getDescendant(startKey); | |
var characters = text.characters; | |
var firstChars = characters.take(startOffset); | |
var secondChars = characters.skip(startOffset); | |
var firstChild = text.merge({ characters: firstChars }); | |
var secondChild = Text.create({ characters: secondChars }); | |
// Split the text nodes. | |
var parent = node.getParent(text); | |
var nodes = parent.nodes.takeUntil(function (c) { | |
return c.key == firstChild.key; | |
}).push(firstChild).push(secondChild).concat(parent.nodes.skipUntil(function (n) { | |
return n.key == firstChild.key; | |
}).rest()); | |
// Update the nodes. | |
parent = parent.merge({ nodes: nodes }); | |
node = node.updateDescendant(parent); | |
return node; | |
}, | |
/** | |
* Remove an existing `mark` to the characters at `range`. | |
* | |
* @param {Selection} range | |
* @param {Mark or String} mark (optional) | |
* @return {Node} node | |
*/ | |
removeMarkAtRange: function removeMarkAtRange(range, mark) { | |
var node = this; | |
// Allow for just passing a type for convenience. | |
if (typeof mark == 'string') { | |
mark = new Mark({ type: mark }); | |
} | |
// When the range is collapsed, do nothing. | |
if (range.isCollapsed) return node; | |
// Otherwise, find each of the text nodes within the range. | |
var texts = node.getTextsAtRange(range); | |
// Apply the mark to each of the text nodes's matching characters. | |
texts = texts.map(function (text) { | |
var characters = text.characters.map(function (char, i) { | |
if (!isInRange$1(i, text, range)) return char; | |
var marks = char.marks; | |
marks = mark ? marks.remove(mark) : marks.clear(); | |
return char.merge({ marks: marks }); | |
}); | |
return text.merge({ characters: characters }); | |
}); | |
// Update each of the text nodes. | |
texts.forEach(function (text) { | |
node = node.updateDescendant(text); | |
}); | |
return node; | |
}, | |
/** | |
* Unwrap all of the block nodes in a `range` from a block node of `type.` | |
* | |
* @param {Selection} range | |
* @param {String} type (optional) | |
* @param {Data or Object} data (optional) | |
* @return {Node} node | |
*/ | |
unwrapBlockAtRange: function unwrapBlockAtRange(range, type, data) { | |
var node = this; | |
// Allow for only data. | |
if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) == 'object') { | |
data = type; | |
type = null; | |
} | |
// Ensure that data is immutable. | |
if (data) data = Data.create(data); | |
// Get the deepest blocks in the range. | |
var blocks = node.getBlocksAtRange(range); | |
// Get the matching wrapper blocks. | |
var wrappers = blocks.reduce(function (memo, text) { | |
var match = node.getClosest(text, function (parent) { | |
if (parent.kind != 'block') return false; | |
if (type && parent.type != type) return false; | |
if (data && !parent.data.isSuperset(data)) return false; | |
return true; | |
}); | |
if (match) memo = memo.add(match); | |
return memo; | |
}, new Set()); | |
// For each of the wrapper blocks... | |
wrappers.forEach(function (wrapper) { | |
var first = wrapper.nodes.first(); | |
var last = wrapper.nodes.last(); | |
var parent = node.getParent(wrapper); | |
// Get the wrapped direct children. | |
var children = wrapper.nodes.filter(function (child) { | |
return blocks.some(function (block) { | |
return child == block || child.hasDescendant(block); | |
}); | |
}); | |
// Determine what the new nodes should be... | |
var firstMatch = children.first(); | |
var lastMatch = children.last(); | |
var nodes = void 0; | |
// If the first and last both match, remove the wrapper completely. | |
if (first == firstMatch && last == lastMatch) { | |
nodes = parent.nodes.takeUntil(function (n) { | |
return n == wrapper; | |
}).concat(wrapper.nodes).concat(parent.nodes.skipUntil(function (n) { | |
return n == wrapper; | |
}).rest()); | |
} | |
// If only the last child matches, move the last nodes. | |
else if (last == lastMatch) { | |
var remain = wrapper.nodes.takeUntil(function (n) { | |
return n == firstMatch; | |
}); | |
var updated = wrapper.merge({ nodes: remain }); | |
nodes = parent.nodes.takeUntil(function (n) { | |
return n == wrapper; | |
}).push(updated).concat(children).concat(parent.nodes.skipUntil(function (n) { | |
return n == wrapper; | |
}).rest()); | |
} | |
// If only the first child matches, move the first ones. | |
else if (first == firstMatch) { | |
var _remain = wrapper.nodes.skipUntil(function (n) { | |
return n == lastMatch; | |
}).rest(); | |
var _updated = wrapper.merge({ nodes: _remain }); | |
nodes = parent.nodes.takeUntil(function (n) { | |
return n == wrapper; | |
}).concat(children).push(_updated).concat(parent.nodes.skipUntil(function (n) { | |
return n == wrapper; | |
}).rest()); | |
} | |
// Otherwise, move the middle ones. | |
else { | |
var firsts = wrapper.nodes.takeUntil(function (n) { | |
return n == firstMatch; | |
}); | |
var lasts = wrapper.nodes.skipUntil(function (n) { | |
return n == lastMatch; | |
}).rest(); | |
var updatedFirst = wrapper.merge({ nodes: firsts }); | |
var updatedLast = wrapper.merge({ nodes: lasts }); | |
nodes = parent.nodes.takeUntil(function (n) { | |
return n == wrapper; | |
}).push(updatedFirst).concat(children).push(updatedLast).concat(parent.nodes.skipUntil(function (n) { | |
return n == wrapper; | |
}).rest()); | |
} | |
node = parent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(parent.merge({ nodes: nodes })); | |
}); | |
return node.normalize(); | |
}, | |
/** | |
* Unwrap the inline nodes in a `range` from an parent inline with `type`. | |
* | |
* @param {Selection} range | |
* @param {String} type (optional) | |
* @param {Data} data (optional) | |
* @return {Node} node | |
*/ | |
unwrapInlineAtRange: function unwrapInlineAtRange(range, type, data) { | |
var node = this; | |
var blocks = node.getInlinesAtRange(range); | |
// Allow for no type. | |
if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) == 'object') { | |
data = type; | |
type = null; | |
} | |
// Ensure that data is immutable. | |
if (data) data = Data.create(data); | |
// Find the closest matching inline wrappers of each text node. | |
var texts = this.getTexts(); | |
var wrappers = texts.reduce(function (memo, text) { | |
var match = node.getClosest(text, function (parent) { | |
if (parent.kind != 'inline') return false; | |
if (type && parent.type != type) return false; | |
if (data && !parent.data.isSuperset(data)) return false; | |
return true; | |
}); | |
if (match) memo = memo.add(match); | |
return memo; | |
}, new Set()); | |
// Replace each of the wrappers with their child nodes. | |
wrappers.forEach(function (wrapper) { | |
var parent = node.getParent(wrapper); | |
// Replace the wrapper in the parent's nodes with the block. | |
var nodes = parent.nodes.takeUntil(function (n) { | |
return n == wrapper; | |
}).concat(wrapper.nodes).concat(parent.nodes.skipUntil(function (n) { | |
return n == wrapper; | |
}).rest()); | |
// Update the parent. | |
node = parent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(parent.merge({ nodes: nodes })); | |
}); | |
return node.normalize(); | |
}, | |
/** | |
* Wrap all of the blocks in a `range` in a new block node of `type`. | |
* | |
* @param {Selection} range | |
* @param {String} type | |
* @param {Data} data (optional) | |
* @return {Node} node | |
*/ | |
wrapBlockAtRange: function wrapBlockAtRange(range, type, data) { | |
data = Data.create(data); | |
var node = this; | |
// Get the block nodes, sorted by depth. | |
var blocks = node.getBlocksAtRange(range); | |
var sorted = blocks.sort(function (a, b) { | |
var da = node.getDepth(a); | |
var db = node.getDepth(b); | |
if (da == db) return 0;else if (da > db) return -1;else return 1; | |
}); | |
// Get the lowest common siblings, relative to the highest block. | |
var highest = sorted.first(); | |
var depth = node.getDepth(highest); | |
var siblings = blocks.reduce(function (memo, block) { | |
var sibling = node.getDepth(block) == depth ? block : node.getClosest(block, function (p) { | |
return node.getDepth(p) == depth; | |
}); | |
memo = memo.push(sibling); | |
return memo; | |
}, Block.createList()); | |
// Wrap the siblings in a new block. | |
var wrapper = Block.create({ | |
nodes: siblings, | |
type: type, | |
data: data | |
}); | |
// Replace the siblings with the wrapper. | |
var first = siblings.first(); | |
var last = siblings.last(); | |
var parent = node.getParent(highest); | |
var nodes = parent.nodes.takeUntil(function (n) { | |
return n == first; | |
}).push(wrapper).concat(parent.nodes.skipUntil(function (n) { | |
return n == last; | |
}).rest()); | |
// Update the parent. | |
node = parent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(parent.merge({ nodes: nodes })); | |
return node; | |
}, | |
/** | |
* Wrap the text and inline nodes in a `range` with a new inline node. | |
* | |
* @param {Selection} range | |
* @param {String} type | |
* @param {Data} data (optional) | |
* @return {Node} node | |
*/ | |
wrapInlineAtRange: function wrapInlineAtRange(range, type, data) { | |
data = Data.create(data); | |
var node = this; | |
// If collapsed, there's nothing to wrap. | |
if (range.isCollapsed) return node; | |
// Split at the start of the range. | |
var start = range.collapseToStart(); | |
node = node.splitInlineAtRange(start); | |
// Determine the new end of the range, and split there. | |
var _range8 = range; | |
var startKey = _range8.startKey; | |
var startOffset = _range8.startOffset; | |
var endKey = _range8.endKey; | |
var endOffset = _range8.endOffset; | |
var firstNode = node.getDescendant(startKey); | |
var nextNode = node.getNextText(startKey); | |
var end = startKey != endKey ? range.collapseToEnd() : Selection.create({ | |
anchorKey: nextNode.key, | |
anchorOffset: endOffset - startOffset, | |
focusKey: nextNode.key, | |
focusOffset: endOffset - startOffset | |
}); | |
node = node.splitInlineAtRange(end); | |
// Calculate the new range to wrap around. | |
var endNode = node.getDescendant(end.anchorKey); | |
range = Selection.create({ | |
anchorKey: nextNode.key, | |
anchorOffset: 0, | |
focusKey: endNode.key, | |
focusOffset: endNode.length | |
}); | |
// Get the furthest inline nodes in the range. | |
var texts = node.getTextsAtRange(range); | |
var children = texts.map(function (text) { | |
return node.getFurthestInline(text) || text; | |
}); | |
// Iterate each of the child nodes, wrapping them. | |
children.forEach(function (child) { | |
var obj = {}; | |
obj.nodes = [child]; | |
obj.type = type; | |
if (data) obj.data = data; | |
var wrapper = Inline.create(obj); | |
// Replace the child in it's parent with the wrapper. | |
var parent = node.getParent(child); | |
var nodes = parent.nodes.takeUntil(function (n) { | |
return n == child; | |
}).push(wrapper).concat(parent.nodes.skipUntil(function (n) { | |
return n == child; | |
}).rest()); | |
// Update the parent. | |
node = parent == node ? node.merge({ nodes: nodes }) : node.updateDescendant(parent.merge({ nodes: nodes })); | |
}); | |
return node; | |
} | |
}; | |
/** | |
* Check if an `index` of a `text` node is in a `range`. | |
* | |
* @param {Number} index | |
* @param {Text} text | |
* @param {Selection} range | |
* @return {Set} characters | |
*/ | |
function isInRange$1(index, text, range) { | |
var startKey = range.startKey; | |
var startOffset = range.startOffset; | |
var endKey = range.endKey; | |
var endOffset = range.endOffset; | |
var matcher = void 0; | |
if (text.key == startKey && text.key == endKey) { | |
return startOffset <= index && index < endOffset; | |
} else if (text.key == startKey) { | |
return startOffset <= index; | |
} else if (text.key == endKey) { | |
return index < endOffset; | |
} else { | |
return true; | |
} | |
} | |
/** | |
* Node. | |
* | |
* And interface that `Document`, `Block` and `Inline` all implement, to make | |
* working with the recursive node tree easier. | |
*/ | |
var Node$1 = { | |
/** | |
* Assert that a node has a child by `key` and return it. | |
* | |
* @param {String or Node} key | |
* @return {Node} | |
*/ | |
assertChild: function assertChild(key) { | |
var child = this.getChild(key); | |
if (!child) { | |
key = normalizeKey(key); | |
throw new Error('Could not find a child node with key "' + key + '".'); | |
} | |
return child; | |
}, | |
/** | |
* Assert that a node has a descendant by `key` and return it. | |
* | |
* @param {String or Node} key | |
* @return {Node} | |
*/ | |
assertDescendant: function assertDescendant(key) { | |
var descendant = this.getDescendant(key); | |
if (!descendant) { | |
key = normalizeKey(key); | |
throw new Error('Could not find a descendant node with key "' + key + '".'); | |
} | |
return descendant; | |
}, | |
/** | |
* Concat children `nodes` on to the end of the node. | |
* | |
* @param {List} nodes | |
* @return {Node} node | |
*/ | |
concatChildren: function concatChildren(nodes) { | |
nodes = this.nodes.concat(nodes); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Decorate all of the text nodes with a `decorator` function. | |
* | |
* @param {Function} decorator | |
* @return {Node} node | |
*/ | |
decorateTexts: function decorateTexts(decorator) { | |
return this.mapDescendants(function (child) { | |
return child.kind == 'text' ? child.decorateCharacters(decorator) : child; | |
}); | |
}, | |
/** | |
* Recursively find all ancestor nodes by `iterator`. | |
* | |
* @param {Function} iterator | |
* @return {Node} node | |
*/ | |
findDescendant: function findDescendant(iterator) { | |
return this.nodes.find(iterator) || this.nodes.map(function (node) { | |
return node.kind == 'text' ? null : node.findDescendant(iterator); | |
}).find(function (exists) { | |
return exists; | |
}); | |
}, | |
/** | |
* Recursively filter all ancestor nodes with `iterator`. | |
* | |
* @param {Function} iterator | |
* @return {List} nodes | |
*/ | |
filterDescendants: function filterDescendants(iterator) { | |
return this.nodes.reduce(function (matches, child, i, nodes) { | |
if (iterator(child, i, nodes)) matches = matches.push(child); | |
if (child.kind != 'text') matches = matches.concat(child.filterDescendants(iterator)); | |
return matches; | |
}, Block.createList()); | |
}, | |
/** | |
* Get the closest block nodes for each text node in the node. | |
* | |
* @return {List} nodes | |
*/ | |
getBlocks: function getBlocks() { | |
var _this = this; | |
return this.getTexts().map(function (text) { | |
return _this.getClosestBlock(text); | |
}).toSet().toList(); | |
}, | |
/** | |
* Get the closest block nodes for each text node in a `range`. | |
* | |
* @param {Selection} range | |
* @return {List} nodes | |
*/ | |
getBlocksAtRange: function getBlocksAtRange(range) { | |
var _this2 = this; | |
return this.getTextsAtRange(range).map(function (text) { | |
return _this2.getClosestBlock(text); | |
}); | |
}, | |
/** | |
* Get a list of the characters in a `range`. | |
* | |
* @param {Selection} range | |
* @return {List} characters | |
*/ | |
getCharactersAtRange: function getCharactersAtRange(range) { | |
return this.getTextsAtRange(range).reduce(function (characters, text) { | |
var chars = text.characters.filter(function (char, i) { | |
return isInRange(i, text, range); | |
}); | |
return characters.concat(chars); | |
}, Character.createList()); | |
}, | |
/** | |
* Get children after a child by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
getChildrenAfter: function getChildrenAfter(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
return this.nodes.slice(index + 1); | |
}, | |
/** | |
* Get children after a child by `key`, including the child. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
getChildrenAfterIncluding: function getChildrenAfterIncluding(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
return this.nodes.slice(index); | |
}, | |
/** | |
* Get children before a child by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
getChildrenBefore: function getChildrenBefore(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
return this.nodes.slice(0, index); | |
}, | |
/** | |
* Get children before a child by `key`, including the child. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
getChildrenBeforeIncluding: function getChildrenBeforeIncluding(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
return this.nodes.slice(0, index + 1); | |
}, | |
/** | |
* Get children between two child keys. | |
* | |
* @param {String or Node} start | |
* @param {String or Node} end | |
* @return {Node} node | |
*/ | |
getChildrenBetween: function getChildrenBetween(start, end) { | |
start = this.assertChild(start); | |
start = this.nodes.indexOf(start); | |
end = this.assertChild(end); | |
end = this.nodes.indexOf(end); | |
return this.nodes.slice(start + 1, end); | |
}, | |
/** | |
* Get children between two child keys, including the two children. | |
* | |
* @param {String or Node} start | |
* @param {String or Node} end | |
* @return {Node} node | |
*/ | |
getChildrenBetweenIncluding: function getChildrenBetweenIncluding(start, end) { | |
start = this.assertChild(start); | |
start = this.nodes.indexOf(start); | |
end = this.assertChild(end); | |
end = this.nodes.indexOf(end); | |
return this.nodes.slice(start, end + 1); | |
}, | |
/** | |
* Get closest parent of node by `key` that matches `iterator`. | |
* | |
* @param {String or Node} key | |
* @param {Function} iterator | |
* @return {Node or Null} node | |
*/ | |
getClosest: function getClosest(key, iterator) { | |
var node = this.assertDescendant(key); | |
while (node = this.getParent(node)) { | |
if (node == this) return null; | |
if (iterator(node)) return node; | |
} | |
return null; | |
}, | |
/** | |
* Get the closest block parent of a `node`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getClosestBlock: function getClosestBlock(key) { | |
return this.getClosest(key, function (parent) { | |
return parent.kind == 'block'; | |
}); | |
}, | |
/** | |
* Get the closest inline parent of a `node`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getClosestInline: function getClosestInline(key) { | |
return this.getClosest(key, function (parent) { | |
return parent.kind == 'inline'; | |
}); | |
}, | |
/** | |
* Get a child node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getChild: function getChild(key) { | |
key = normalizeKey(key); | |
return this.nodes.find(function (node) { | |
return node.key == key; | |
}); | |
}, | |
/** | |
* Get a descendant node by `key`. | |
* | |
* @param {String} key | |
* @return {Node or Null} node | |
*/ | |
getDescendant: function getDescendant(key) { | |
key = normalizeKey(key); | |
var child = this.getChild(key); | |
if (child) return child; | |
this.nodes.find(function (node) { | |
if (node.kind == 'text') return false; | |
child = node.getDescendant(key); | |
return child; | |
}); | |
return child; | |
}, | |
/** | |
* Get the depth of a child node by `key`, with optional `startAt`. | |
* | |
* @param {String or Node} key | |
* @param {Number} startAt (optional) | |
* @return {Number} depth | |
*/ | |
getDepth: function getDepth(key) { | |
var startAt = arguments.length <= 1 || arguments[1] === undefined ? 1 : arguments[1]; | |
this.assertDescendant(key); | |
return this.hasChild(key) ? startAt : this.getHighestChild(key).getDepth(key, startAt + 1); | |
}, | |
/** | |
* Get a fragment of the node at a `range`. | |
* | |
* @param {Selection} range | |
* @return {List} nodes | |
*/ | |
getFragmentAtRange: function getFragmentAtRange(range) { | |
var node = this; | |
var nodes = Block.createList(); | |
// If the range is collapsed, there's nothing to do. | |
if (range.isCollapsed) return Document.create({ nodes: nodes }); | |
// Make sure the children exist. | |
var startKey = range.startKey; | |
var startOffset = range.startOffset; | |
var endKey = range.endKey; | |
var endOffset = range.endOffset; | |
node.assertDescendant(startKey); | |
node.assertDescendant(endKey); | |
// Split at the start and end. | |
var start = range.collapseToStart(); | |
node = node.splitBlockAtRange(start, Infinity); | |
var next = node.getNextText(startKey); | |
var end = startKey == endKey ? range.collapseToStartOf(next).moveForward(endOffset - startOffset) : range.collapseToEnd(); | |
node = node.splitBlockAtRange(end, Infinity); | |
// Get the start and end nodes. | |
var startNode = node.getNextSibling(node.getHighestChild(startKey)); | |
var endNode = startKey == endKey ? node.getHighestChild(next) : node.getHighestChild(endKey); | |
nodes = node.getChildrenBetweenIncluding(startNode, endNode); | |
// Return a new document fragment. | |
return Document.create({ nodes: nodes }); | |
}, | |
/** | |
* Get the furthest parent of a node by `key` that matches an `iterator`. | |
* | |
* @param {String or Node} key | |
* @param {Function} iterator | |
* @return {Node or Null} | |
*/ | |
getFurthest: function getFurthest(key, iterator) { | |
var node = this.assertDescendant(key); | |
var furthest = null; | |
while (node = this.getClosest(node, iterator)) { | |
furthest = node; | |
} | |
return furthest; | |
}, | |
/** | |
* Get the furthest block parent of a node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getFurthestBlock: function getFurthestBlock(key) { | |
return this.getFurthest(key, function (node) { | |
return node.kind == 'block'; | |
}); | |
}, | |
/** | |
* Get the furthest inline parent of a node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getFurthestInline: function getFurthestInline(key) { | |
return this.getFurthest(key, function (node) { | |
return node.kind == 'inline'; | |
}); | |
}, | |
/** | |
* Get the highest child ancestor of a node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getHighestChild: function getHighestChild(key) { | |
key = normalizeKey(key); | |
return this.nodes.find(function (node) { | |
if (node.key == key) return true; | |
if (node.kind == 'text') return false; | |
return node.hasDescendant(key); | |
}); | |
}, | |
/** | |
* Get the highest parent of a node by `key` which has an only child. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} | |
*/ | |
getHighestOnlyChildParent: function getHighestOnlyChildParent(key) { | |
var child = this.assertChild(key); | |
var match = null; | |
var parent = void 0; | |
while (parent = this.getParent(child)) { | |
if (parent == null || parent.nodes.size > 1) return match; | |
match = parent; | |
child = parent; | |
} | |
}, | |
/** | |
* Get the closest inline nodes for each text node in a `range`. | |
* | |
* @param {Selection} range | |
* @return {List} nodes | |
*/ | |
getInlinesAtRange: function getInlinesAtRange(range) { | |
var _this3 = this; | |
return this.getTextsAtRange(range).map(function (text) { | |
return _this3.getClosestInline(text); | |
}).filter(function (exists) { | |
return exists; | |
}).toSet().toList(); | |
}, | |
/** | |
* Get a set of the marks in a `range`. | |
* | |
* @param {Selection} range | |
* @return {Set} marks | |
*/ | |
getMarksAtRange: function getMarksAtRange(range) { | |
range = range.normalize(this); | |
var _range = range; | |
var startKey = _range.startKey; | |
var startOffset = _range.startOffset; | |
var marks = Mark.createSet(); | |
// If the range is collapsed at the start of the node, check the previous. | |
if (range.isCollapsed && startOffset == 0) { | |
var text = this.getDescendant(startKey); | |
var previous = this.getPreviousText(startKey); | |
if (!previous || !previous.length) return marks; | |
var char = previous.characters.get(previous.length - 1); | |
return char.marks; | |
} | |
// If the range is collapsed, check the character before the start. | |
if (range.isCollapsed) { | |
var _text = this.getDescendant(startKey); | |
var _char = _text.characters.get(range.startOffset - 1); | |
return _char.marks; | |
} | |
// Otherwise, get a set of the marks for each character in the range. | |
return this.getCharactersAtRange(range).map(function (char) { | |
return char.marks; | |
}).toSet(); | |
}, | |
/** | |
* Get the block node before a descendant text node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getNextBlock: function getNextBlock(key) { | |
var child = this.assertDescendant(key); | |
var last = void 0; | |
if (child.kind == 'block') { | |
last = child.getTexts().last(); | |
} else { | |
var block = this.getClosestBlock(key); | |
last = block.getTexts().last(); | |
} | |
var next = this.getNextText(last); | |
if (!next) return null; | |
return this.getClosestBlock(next); | |
}, | |
/** | |
* Get the node after a descendant by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getNextSibling: function getNextSibling(key) { | |
var node = this.assertDescendant(key); | |
return this.getParent(node).nodes.skipUntil(function (child) { | |
return child == node; | |
}).get(1); | |
}, | |
/** | |
* Get the text node after a descendant text node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getNextText: function getNextText(key) { | |
key = normalizeKey(key); | |
return this.getTexts().skipUntil(function (text) { | |
return text.key == key; | |
}).get(1); | |
}, | |
/** | |
* Get the offset for a descendant text node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Number} offset | |
*/ | |
getOffset: function getOffset(key) { | |
this.assertDescendant(key); | |
// Calculate the offset of the nodes before the highest child. | |
var child = this.getHighestChild(key); | |
var offset = this.nodes.takeUntil(function (n) { | |
return n == child; | |
}).reduce(function (memo, n) { | |
return memo + n.length; | |
}, 0); | |
// Recurse if need be. | |
return this.hasChild(key) ? offset : offset + child.getOffset(key); | |
}, | |
/** | |
* Get the offset from a `range`. | |
* | |
* @param {Selection} range | |
* @return {Number} offset | |
*/ | |
getOffsetAtRange: function getOffsetAtRange(range) { | |
range = range.normalize(this); | |
if (range.isExpanded) { | |
throw new Error('The range must be collapsed to calculcate its offset.'); | |
} | |
var _range2 = range; | |
var startKey = _range2.startKey; | |
var startOffset = _range2.startOffset; | |
return this.getOffset(startKey) + startOffset; | |
}, | |
/** | |
* Get the parent of a child node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getParent: function getParent(key) { | |
if (this.hasChild(key)) return this; | |
var node = null; | |
this.nodes.forEach(function (child) { | |
if (child.kind == 'text') return; | |
var match = child.getParent(key); | |
if (match) node = match; | |
}); | |
return node; | |
}, | |
/** | |
* Get the node before a descendant node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getPreviousSibling: function getPreviousSibling(key) { | |
var node = this.assertDescendant(key); | |
return this.getParent(node).nodes.takeUntil(function (child) { | |
return child == node; | |
}).last(); | |
}, | |
/** | |
* Get the text node before a descendant text node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getPreviousText: function getPreviousText(key) { | |
key = normalizeKey(key); | |
return this.getTexts().takeUntil(function (text) { | |
return text.key == key; | |
}).last(); | |
}, | |
/** | |
* Get the block node before a descendant text node by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node or Null} node | |
*/ | |
getPreviousBlock: function getPreviousBlock(key) { | |
var child = this.assertDescendant(key); | |
var first = void 0; | |
if (child.kind == 'block') { | |
first = child.getTexts().first(); | |
} else { | |
var block = this.getClosestBlock(key); | |
first = block.getTexts().first(); | |
} | |
var previous = this.getPreviousText(first); | |
if (!previous) return null; | |
return this.getClosestBlock(previous); | |
}, | |
/** | |
* Get the descendent text node at an `offset`. | |
* | |
* @param {String} offset | |
* @return {Node or Null} node | |
*/ | |
getTextAtOffset: function getTextAtOffset(offset) { | |
var length = 0; | |
return this.getTexts().find(function (text) { | |
length += text.length; | |
return length >= offset; | |
}); | |
}, | |
/** | |
* Recursively get all of the child text nodes in order of appearance. | |
* | |
* @return {List} nodes | |
*/ | |
getTexts: function getTexts() { | |
return this.nodes.reduce(function (texts, node) { | |
return node.kind == 'text' ? texts.push(node) : texts.concat(node.getTexts()); | |
}, Block.createList()); | |
}, | |
/** | |
* Get all of the text nodes in a `range`. | |
* | |
* @param {Selection} range | |
* @return {List} nodes | |
*/ | |
getTextsAtRange: function getTextsAtRange(range) { | |
range = range.normalize(this); | |
var _range3 = range; | |
var startKey = _range3.startKey; | |
var endKey = _range3.endKey; | |
var texts = this.getTexts(); | |
var startText = this.getDescendant(startKey); | |
var endText = this.getDescendant(endKey); | |
var start = texts.indexOf(startText); | |
var end = texts.indexOf(endText); | |
return texts.slice(start, end + 1); | |
}, | |
/** | |
* Check if a child node exists by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Boolean} exists | |
*/ | |
hasChild: function hasChild(key) { | |
return !!this.getChild(key); | |
}, | |
/** | |
* Recursively check if a child node exists by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Boolean} exists | |
*/ | |
hasDescendant: function hasDescendant(key) { | |
return !!this.getDescendant(key); | |
}, | |
/** | |
* Check if a node has a void parent by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Boolean} | |
*/ | |
hasVoidParent: function hasVoidParent(key) { | |
return !!this.getClosest(key, function (parent) { | |
return parent.isVoid; | |
}); | |
}, | |
/** | |
* Insert child `nodes` after child by `key`. | |
* | |
* @param {String or Node} key | |
* @param {List} nodes | |
* @return {Node} node | |
*/ | |
insertChildrenAfter: function insertChildrenAfter(key, nodes) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
nodes = this.nodes.slice(0, index + 1).concat(nodes).concat(this.nodes.slice(index + 1)); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Insert child `nodes` before child by `key`. | |
* | |
* @param {String or Node} key | |
* @param {List} nodes | |
* @return {Node} node | |
*/ | |
insertChildrenBefore: function insertChildrenBefore(key, nodes) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
nodes = this.nodes.slice(0, index).concat(nodes).concat(this.nodes.slice(index)); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Check if the inline nodes are split at a `range`. | |
* | |
* @param {Selection} range | |
* @return {Boolean} isSplit | |
*/ | |
isInlineSplitAtRange: function isInlineSplitAtRange(range) { | |
range = range.normalize(this); | |
if (range.isExpanded) throw new Error(); | |
var _range4 = range; | |
var startKey = _range4.startKey; | |
var start = this.getFurthestInline(startKey) || this.getDescendant(startKey); | |
return range.isAtStartOf(start) || range.isAtEndOf(start); | |
}, | |
/** | |
* Map all child nodes, updating them in their parents. This method is | |
* optimized to not return a new node if no changes are made. | |
* | |
* @param {Function} iterator | |
* @return {Node} node | |
*/ | |
mapChildren: function mapChildren(iterator) { | |
var _this4 = this; | |
var nodes = this.nodes; | |
nodes.forEach(function (node, i) { | |
var ret = iterator(node, i, _this4.nodes); | |
if (ret != node) nodes = nodes.set(ret.key, ret); | |
}); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Map all descendant nodes, updating them in their parents. This method is | |
* optimized to not return a new node if no changes are made. | |
* | |
* @param {Function} iterator | |
* @return {Node} node | |
*/ | |
mapDescendants: function mapDescendants(iterator) { | |
var _this5 = this; | |
var nodes = this.nodes; | |
nodes.forEach(function (node, i) { | |
var ret = node; | |
if (ret.kind != 'text') ret = ret.mapDescendants(iterator); | |
ret = iterator(ret, i, _this5.nodes); | |
if (ret == node) return; | |
var index = nodes.indexOf(node); | |
nodes = nodes.set(index, ret); | |
}); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Normalize the node by joining any two adjacent text child nodes. | |
* | |
* @return {Node} node | |
*/ | |
normalize: function normalize() { | |
var node = this; | |
// Map this node's descendants, ensuring... ensuring there are no duplicate keys. | |
var keys = []; | |
node = node.mapDescendants(function (desc) { | |
// That there are no duplicate keys. | |
if (includes$1(keys, desc.key)) desc = desc.set('key', uid()); | |
keys.push(desc.key); | |
// That void nodes contain no text. | |
if (desc.isVoid && desc.length) { | |
var text = desc.getTexts().first(); | |
var _characters = text.characters.clear(); | |
text = text.merge({ characters: _characters }); | |
var nodes = desc.nodes.clear().push(text); | |
desc = desc.merge({ nodes: nodes }); | |
} | |
// That no block or inline node is empty. | |
if (desc.kind != 'text' && desc.nodes.size == 0) { | |
var _text2 = Text.create(); | |
var _nodes = desc.nodes.push(_text2); | |
desc = desc.merge({ nodes: _nodes }); | |
} | |
return desc; | |
}); | |
// See if there are any adjacent text nodes. | |
var first = node.findDescendant(function (child) { | |
if (child.kind != 'text') return; | |
var parent = node.getParent(child); | |
var next = parent.getNextSibling(child); | |
return next && next.kind == 'text'; | |
}); | |
// If no text nodes are adjacent, abort. | |
if (!first) return node; | |
// Fix an adjacent text node if one exists. | |
var parent = node.getParent(first); | |
var isParent = node == parent; | |
var second = parent.getNextSibling(first); | |
var characters = first.characters.concat(second.characters); | |
first = first.merge({ characters: characters }); | |
parent = parent.updateDescendant(first); | |
// Then remove the second text node. | |
parent = parent.removeDescendant(second); | |
// And update the node. | |
node = isParent ? parent : node.updateDescendant(parent); | |
// Recurse by normalizing again. | |
return node.normalize(); | |
}, | |
/** | |
* Remove children after a child by `key`. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
removeChildrenAfter: function removeChildrenAfter(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
var nodes = this.nodes.slice(0, index + 1); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Remove children after a child by `key`, including the child. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
removeChildrenAfterIncluding: function removeChildrenAfterIncluding(key) { | |
var child = this.assertChild(key); | |
var index = this.nodes.indexOf(child); | |
var nodes = this.nodes.slice(0, index); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Remove a `node` from the children node map. | |
* | |
* @param {String or Node} key | |
* @return {Node} node | |
*/ | |
removeDescendant: function removeDescendant(key) { | |
this.assertDescendant(key); | |
var child = this.getChild(key); | |
if (child) { | |
var _nodes2 = this.nodes.filterNot(function (node) { | |
return node == child; | |
}); | |
return this.merge({ nodes: _nodes2 }); | |
} | |
var nodes = this.mapChildren(function (n) { | |
return n.kind == 'text' ? n : n.removeDescendant(key); | |
}); | |
return this.merge({ nodes: nodes }); | |
}, | |
/** | |
* Set a new value for a child node by `key`. | |
* | |
* @param {Node} node | |
* @return {Node} node | |
*/ | |
updateDescendant: function updateDescendant(node) { | |
this.assertDescendant(node); | |
return this.mapDescendants(function (d) { | |
return d.key == node.key ? node : d; | |
}); | |
} | |
}; | |
/** | |
* Normalize a `key`, from a key string or a node. | |
* | |
* @param {String or Node} key | |
* @return {String} key | |
*/ | |
function normalizeKey(key) { | |
if (typeof key == 'string') return key; | |
return key.key; | |
} | |
/** | |
* Check if an `index` of a `text` node is in a `range`. | |
* | |
* @param {Number} index | |
* @param {Text} text | |
* @param {Selection} range | |
* @return {Set} characters | |
*/ | |
function isInRange(index, text, range) { | |
var startKey = range.startKey; | |
var startOffset = range.startOffset; | |
var endKey = range.endKey; | |
var endOffset = range.endOffset; | |
var matcher = void 0; | |
if (text.key == startKey && text.key == endKey) { | |
return startOffset <= index && index < endOffset; | |
} else if (text.key == startKey) { | |
return startOffset <= index; | |
} else if (text.key == endKey) { | |
return index < endOffset; | |
} else { | |
return true; | |
} | |
} | |
/** | |
* Transforms. | |
*/ | |
for (var key in Transforms) { | |
Node$1[key] = Transforms[key]; | |
} | |
/** | |
* Memoize read methods. | |
*/ | |
memoize(Node$1, ['assertChild', 'assertDescendant', 'findDescendant', 'filterDescendants', 'getBlocks', 'getBlocksAtRange', 'getCharactersAtRange', 'getChildrenAfter', 'getChildrenAfterIncluding', 'getChildrenBefore', 'getChildrenBeforeIncluding', 'getChildrenBetween', 'getChildrenBetweenIncluding', 'getClosest', 'getClosestBlock', 'getClosestInline', 'getChild', 'getDescendant', 'getDepth', 'getFragmentAtRange', 'getFurthest', 'getFurthestBlock', 'getFurthestInline', 'getHighestChild', 'getHighestOnlyChildParent', 'getInlinesAtRange', 'getMarksAtRange', 'getNextBlock', 'getNextSibling', 'getNextText', 'getOffset', 'getOffsetAtRange', 'getParent', 'getPreviousSibling', 'getPreviousText', 'getPreviousBlock', 'getTextAtOffset', 'getTexts', 'getTextsAtRange', 'hasChild', 'hasDescendant', 'hasVoidParent', 'isInlineSplitAtRange']); | |
/** | |
* Record. | |
*/ | |
var DEFAULTS$2 = { | |
data: new Map(), | |
isVoid: false, | |
key: null, | |
nodes: new List(), | |
type: null | |
}; | |
/** | |
* Inline. | |
*/ | |
var Inline = function (_ref) { | |
inherits(Inline, _ref); | |
function Inline() { | |
classCallCheck(this, Inline); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Inline).apply(this, arguments)); | |
} | |
createClass(Inline, [{ | |
key: 'kind', | |
/** | |
* Get the node's kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'inline'; | |
} | |
/** | |
* Get the length of the concatenated text of the node. | |
* | |
* @return {Number} length | |
*/ | |
}, { | |
key: 'length', | |
get: function get() { | |
return this.text.length; | |
} | |
/** | |
* Get the concatenated text `string` of all child nodes. | |
* | |
* @return {String} text | |
*/ | |
}, { | |
key: 'text', | |
get: function get() { | |
return this.nodes.map(function (node) { | |
return node.text; | |
}).join(''); | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Inline` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Inline} element | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Block) return properties; | |
if (properties instanceof Inline) return properties; | |
if (properties instanceof Text) return properties; | |
if (!properties.type) throw new Error('You must pass an inline `type`.'); | |
properties.key = uid(4); | |
properties.data = Data.create(properties.data); | |
properties.isVoid = !!properties.isVoid; | |
properties.nodes = Inline.createList(properties.nodes); | |
return new Inline(properties).normalize(); | |
} | |
/** | |
* Create a list of `Inlines` from an array. | |
* | |
* @param {Array} elements | |
* @return {List} map | |
*/ | |
}, { | |
key: 'createList', | |
value: function createList() { | |
var elements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; | |
if (List.isList(elements)) return elements; | |
return new List(elements.map(Inline.create)); | |
} | |
}]); | |
return Inline; | |
}(new Record(DEFAULTS$2)); | |
/** | |
* Mix in `Node` methods. | |
*/ | |
for (var method$2 in Node$1) { | |
Inline.prototype[method$2] = Node$1[method$2]; | |
} | |
/** | |
* Defaults. | |
*/ | |
var DEFAULTS$1 = { | |
nodes: new OrderedMap() | |
}; | |
/** | |
* Document. | |
*/ | |
var Document = function (_ref) { | |
inherits(Document, _ref); | |
function Document() { | |
classCallCheck(this, Document); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Document).apply(this, arguments)); | |
} | |
createClass(Document, [{ | |
key: 'kind', | |
/** | |
* Get the node's kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'document'; | |
} | |
/** | |
* Get the length of the concatenated text of the node. | |
* | |
* @return {Number} length | |
*/ | |
}, { | |
key: 'length', | |
get: function get() { | |
return this.text.length; | |
} | |
/** | |
* Get the concatenated text `string` of all child nodes. | |
* | |
* @return {String} text | |
*/ | |
}, { | |
key: 'text', | |
get: function get() { | |
return this.nodes.map(function (node) { | |
return node.text; | |
}).join(''); | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Document` with `properties`. | |
* | |
* @param {Objetc} properties | |
* @return {Document} document | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Document) return properties; | |
properties.nodes = Block.createList(properties.nodes); | |
return new Document(properties).normalize(); | |
} | |
}]); | |
return Document; | |
}(new Record(DEFAULTS$1)); | |
/** | |
* Mix in `Node` methods. | |
*/ | |
for (var method$1 in Node$1) { | |
Document.prototype[method$1] = Node$1[method$1]; | |
} | |
/** | |
* Default properties. | |
*/ | |
var DEFAULTS = { | |
data: new Map(), | |
isVoid: false, | |
key: null, | |
nodes: new List(), | |
type: null | |
}; | |
/** | |
* Block. | |
*/ | |
var Block = function (_ref) { | |
inherits(Block, _ref); | |
function Block() { | |
classCallCheck(this, Block); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Block).apply(this, arguments)); | |
} | |
createClass(Block, [{ | |
key: 'kind', | |
/** | |
* Get the node's kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'block'; | |
} | |
/** | |
* Get the length of the concatenated text of the node. | |
* | |
* @return {Number} length | |
*/ | |
}, { | |
key: 'length', | |
get: function get() { | |
return this.text.length; | |
} | |
/** | |
* Get the concatenated text `string` of all child nodes. | |
* | |
* @return {String} text | |
*/ | |
}, { | |
key: 'text', | |
get: function get() { | |
return this.nodes.map(function (node) { | |
return node.text; | |
}).join(''); | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `Block` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {Block} element | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof Block) return properties; | |
if (properties instanceof Inline) return properties; | |
if (properties instanceof Text) return properties; | |
if (!properties.type) throw new Error('You must pass a block `type`.'); | |
properties.key = uid(4); | |
properties.data = Data.create(properties.data); | |
properties.isVoid = !!properties.isVoid; | |
properties.nodes = Block.createList(properties.nodes); | |
return new Block(properties).normalize(); | |
} | |
/** | |
* Create a list of `Blocks` from an array. | |
* | |
* @param {Array} elements | |
* @return {List} list | |
*/ | |
}, { | |
key: 'createList', | |
value: function createList() { | |
var elements = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; | |
if (List.isList(elements)) return elements; | |
return new List(elements.map(Block.create)); | |
} | |
}]); | |
return Block; | |
}(new Record(DEFAULTS)); | |
/** | |
* Mix in `Node` methods. | |
*/ | |
for (var method in Node$1) { | |
Block.prototype[method] = Node$1[method]; | |
} | |
var _arrayFilter = createCommonjsModule(function (module) { | |
/** | |
* A specialized version of `_.filter` for arrays without support for | |
* iteratee shorthands. | |
* | |
* @private | |
* @param {Array} [array] The array to iterate over. | |
* @param {Function} predicate The function invoked per iteration. | |
* @returns {Array} Returns the new filtered array. | |
*/ | |
function arrayFilter(array, predicate) { | |
var index = -1, | |
length = array ? array.length : 0, | |
resIndex = 0, | |
result = []; | |
while (++index < length) { | |
var value = array[index]; | |
if (predicate(value, index, array)) { | |
result[resIndex++] = value; | |
} | |
} | |
return result; | |
} | |
module.exports = arrayFilter; | |
}); | |
var _arrayFilter$1 = interopDefault(_arrayFilter); | |
var require$$3$2 = Object.freeze({ | |
default: _arrayFilter$1 | |
}); | |
var _arrayPush = createCommonjsModule(function (module) { | |
/** | |
* Appends the elements of `values` to `array`. | |
* | |
* @private | |
* @param {Array} array The array to modify. | |
* @param {Array} values The values to append. | |
* @returns {Array} Returns `array`. | |
*/ | |
function arrayPush(array, values) { | |
var index = -1, | |
length = values.length, | |
offset = array.length; | |
while (++index < length) { | |
array[offset + index] = values[index]; | |
} | |
return array; | |
} | |
module.exports = arrayPush; | |
}); | |
var _arrayPush$1 = interopDefault(_arrayPush); | |
var require$$2$4 = Object.freeze({ | |
default: _arrayPush$1 | |
}); | |
var _isHostObject = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is a host object in IE < 9. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is a host object, else `false`. | |
*/ | |
function isHostObject(value) { | |
// Many host objects are `Object` objects that can coerce to strings | |
// despite having improperly defined `toString` methods. | |
var result = false; | |
if (value != null && typeof value.toString != 'function') { | |
try { | |
result = !!(value + ''); | |
} catch (e) {} | |
} | |
return result; | |
} | |
module.exports = isHostObject; | |
}); | |
var _isHostObject$1 = interopDefault(_isHostObject); | |
var require$$3$3 = Object.freeze({ | |
default: _isHostObject$1 | |
}); | |
var _checkGlobal = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is a global object. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {null|Object} Returns `value` if it's a global object, else `null`. | |
*/ | |
function checkGlobal(value) { | |
return (value && value.Object === Object) ? value : null; | |
} | |
module.exports = checkGlobal; | |
}); | |
var _checkGlobal$1 = interopDefault(_checkGlobal); | |
var require$$0$17 = Object.freeze({ | |
default: _checkGlobal$1 | |
}); | |
var _root = createCommonjsModule(function (module) { | |
var checkGlobal = interopDefault(require$$0$17); | |
/** Detect free variable `global` from Node.js. */ | |
var freeGlobal = checkGlobal(typeof commonjsGlobal == 'object' && commonjsGlobal); | |
/** Detect free variable `self`. */ | |
var freeSelf = checkGlobal(typeof self == 'object' && self); | |
/** Detect `this` as the global object. */ | |
var thisGlobal = checkGlobal(typeof this == 'object' && this); | |
/** Used as a reference to the global object. */ | |
var root = freeGlobal || freeSelf || thisGlobal || Function('return this')(); | |
module.exports = root; | |
}); | |
var _root$1 = interopDefault(_root); | |
var require$$0$16 = Object.freeze({ | |
default: _root$1 | |
}); | |
var _coreJsData = createCommonjsModule(function (module) { | |
var root = interopDefault(require$$0$16); | |
/** Used to detect overreaching core-js shims. */ | |
var coreJsData = root['__core-js_shared__']; | |
module.exports = coreJsData; | |
}); | |
var _coreJsData$1 = interopDefault(_coreJsData); | |
var require$$0$15 = Object.freeze({ | |
default: _coreJsData$1 | |
}); | |
var _isMasked = createCommonjsModule(function (module) { | |
var coreJsData = interopDefault(require$$0$15); | |
/** Used to detect methods masquerading as native. */ | |
var maskSrcKey = (function() { | |
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); | |
return uid ? ('Symbol(src)_1.' + uid) : ''; | |
}()); | |
/** | |
* Checks if `func` has its source masked. | |
* | |
* @private | |
* @param {Function} func The function to check. | |
* @returns {boolean} Returns `true` if `func` is masked, else `false`. | |
*/ | |
function isMasked(func) { | |
return !!maskSrcKey && (maskSrcKey in func); | |
} | |
module.exports = isMasked; | |
}); | |
var _isMasked$1 = interopDefault(_isMasked); | |
var require$$2$7 = Object.freeze({ | |
default: _isMasked$1 | |
}); | |
var _toSource = createCommonjsModule(function (module) { | |
/** Used to resolve the decompiled source of functions. */ | |
var funcToString = Function.prototype.toString; | |
/** | |
* Converts `func` to its source code. | |
* | |
* @private | |
* @param {Function} func The function to process. | |
* @returns {string} Returns the source code. | |
*/ | |
function toSource(func) { | |
if (func != null) { | |
try { | |
return funcToString.call(func); | |
} catch (e) {} | |
try { | |
return (func + ''); | |
} catch (e) {} | |
} | |
return ''; | |
} | |
module.exports = toSource; | |
}); | |
var _toSource$1 = interopDefault(_toSource); | |
var require$$0$18 = Object.freeze({ | |
default: _toSource$1 | |
}); | |
var _baseIsNative = createCommonjsModule(function (module) { | |
var isFunction = interopDefault(require$$4), | |
isHostObject = interopDefault(require$$3$3), | |
isMasked = interopDefault(require$$2$7), | |
isObject = interopDefault(require$$1$1), | |
toSource = interopDefault(require$$0$18); | |
/** | |
* Used to match `RegExp` | |
* [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). | |
*/ | |
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; | |
/** Used to detect host constructors (Safari). */ | |
var reIsHostCtor = /^\[object .+?Constructor\]$/; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** Used to resolve the decompiled source of functions. */ | |
var funcToString = Function.prototype.toString; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** Used to detect if a method is native. */ | |
var reIsNative = RegExp('^' + | |
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') | |
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' | |
); | |
/** | |
* The base implementation of `_.isNative` without bad shim checks. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is a native function, | |
* else `false`. | |
*/ | |
function baseIsNative(value) { | |
if (!isObject(value) || isMasked(value)) { | |
return false; | |
} | |
var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; | |
return pattern.test(toSource(value)); | |
} | |
module.exports = baseIsNative; | |
}); | |
var _baseIsNative$1 = interopDefault(_baseIsNative); | |
var require$$1$8 = Object.freeze({ | |
default: _baseIsNative$1 | |
}); | |
var _getValue = createCommonjsModule(function (module) { | |
/** | |
* Gets the value at `key` of `object`. | |
* | |
* @private | |
* @param {Object} [object] The object to query. | |
* @param {string} key The key of the property to get. | |
* @returns {*} Returns the property value. | |
*/ | |
function getValue(object, key) { | |
return object == null ? undefined : object[key]; | |
} | |
module.exports = getValue; | |
}); | |
var _getValue$1 = interopDefault(_getValue); | |
var require$$0$19 = Object.freeze({ | |
default: _getValue$1 | |
}); | |
var _getNative = createCommonjsModule(function (module) { | |
var baseIsNative = interopDefault(require$$1$8), | |
getValue = interopDefault(require$$0$19); | |
/** | |
* Gets the native function at `key` of `object`. | |
* | |
* @private | |
* @param {Object} object The object to query. | |
* @param {string} key The key of the method to get. | |
* @returns {*} Returns the function if it's native, else `undefined`. | |
*/ | |
function getNative(object, key) { | |
var value = getValue(object, key); | |
return baseIsNative(value) ? value : undefined; | |
} | |
module.exports = getNative; | |
}); | |
var _getNative$1 = interopDefault(_getNative); | |
var require$$1$7 = Object.freeze({ | |
default: _getNative$1 | |
}); | |
var _nativeCreate = createCommonjsModule(function (module) { | |
var getNative = interopDefault(require$$1$7); | |
/* Built-in method references that are verified to be native. */ | |
var nativeCreate = getNative(Object, 'create'); | |
module.exports = nativeCreate; | |
}); | |
var _nativeCreate$1 = interopDefault(_nativeCreate); | |
var require$$0$14 = Object.freeze({ | |
default: _nativeCreate$1 | |
}); | |
var _hashClear = createCommonjsModule(function (module) { | |
var nativeCreate = interopDefault(require$$0$14); | |
/** | |
* Removes all key-value entries from the hash. | |
* | |
* @private | |
* @name clear | |
* @memberOf Hash | |
*/ | |
function hashClear() { | |
this.__data__ = nativeCreate ? nativeCreate(null) : {}; | |
} | |
module.exports = hashClear; | |
}); | |
var _hashClear$1 = interopDefault(_hashClear); | |
var require$$4$4 = Object.freeze({ | |
default: _hashClear$1 | |
}); | |
var _hashDelete = createCommonjsModule(function (module) { | |
/** | |
* Removes `key` and its value from the hash. | |
* | |
* @private | |
* @name delete | |
* @memberOf Hash | |
* @param {Object} hash The hash to modify. | |
* @param {string} key The key of the value to remove. | |
* @returns {boolean} Returns `true` if the entry was removed, else `false`. | |
*/ | |
function hashDelete(key) { | |
return this.has(key) && delete this.__data__[key]; | |
} | |
module.exports = hashDelete; | |
}); | |
var _hashDelete$1 = interopDefault(_hashDelete); | |
var require$$3$4 = Object.freeze({ | |
default: _hashDelete$1 | |
}); | |
var _hashGet = createCommonjsModule(function (module) { | |
var nativeCreate = interopDefault(require$$0$14); | |
/** Used to stand-in for `undefined` hash values. */ | |
var HASH_UNDEFINED = '__lodash_hash_undefined__'; | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** | |
* Gets the hash value for `key`. | |
* | |
* @private | |
* @name get | |
* @memberOf Hash | |
* @param {string} key The key of the value to get. | |
* @returns {*} Returns the entry value. | |
*/ | |
function hashGet(key) { | |
var data = this.__data__; | |
if (nativeCreate) { | |
var result = data[key]; | |
return result === HASH_UNDEFINED ? undefined : result; | |
} | |
return hasOwnProperty.call(data, key) ? data[key] : undefined; | |
} | |
module.exports = hashGet; | |
}); | |
var _hashGet$1 = interopDefault(_hashGet); | |
var require$$2$8 = Object.freeze({ | |
default: _hashGet$1 | |
}); | |
var _hashHas = createCommonjsModule(function (module) { | |
var nativeCreate = interopDefault(require$$0$14); | |
/** Used for built-in method references. */ | |
var objectProto = Object.prototype; | |
/** Used to check objects for own properties. */ | |
var hasOwnProperty = objectProto.hasOwnProperty; | |
/** | |
* Checks if a hash value for `key` exists. | |
* | |
* @private | |
* @name has | |
* @memberOf Hash | |
* @param {string} key The key of the entry to check. | |
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. | |
*/ | |
function hashHas(key) { | |
var data = this.__data__; | |
return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); | |
} | |
module.exports = hashHas; | |
}); | |
var _hashHas$1 = interopDefault(_hashHas); | |
var require$$1$9 = Object.freeze({ | |
default: _hashHas$1 | |
}); | |
var _hashSet = createCommonjsModule(function (module) { | |
var nativeCreate = interopDefault(require$$0$14); | |
/** Used to stand-in for `undefined` hash values. */ | |
var HASH_UNDEFINED = '__lodash_hash_undefined__'; | |
/** | |
* Sets the hash `key` to `value`. | |
* | |
* @private | |
* @name set | |
* @memberOf Hash | |
* @param {string} key The key of the value to set. | |
* @param {*} value The value to set. | |
* @returns {Object} Returns the hash instance. | |
*/ | |
function hashSet(key, value) { | |
var data = this.__data__; | |
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; | |
return this; | |
} | |
module.exports = hashSet; | |
}); | |
var _hashSet$1 = interopDefault(_hashSet); | |
var require$$0$20 = Object.freeze({ | |
default: _hashSet$1 | |
}); | |
var _Hash = createCommonjsModule(function (module) { | |
var hashClear = interopDefault(require$$4$4), | |
hashDelete = interopDefault(require$$3$4), | |
hashGet = interopDefault(require$$2$8), | |
hashHas = interopDefault(require$$1$9), | |
hashSet = interopDefault(require$$0$20); | |
/** | |
* Creates a hash object. | |
* | |
* @private | |
* @constructor | |
* @param {Array} [entries] The key-value pairs to cache. | |
*/ | |
function Hash(entries) { | |
var index = -1, | |
length = entries ? entries.length : 0; | |
this.clear(); | |
while (++index < length) { | |
var entry = entries[index]; | |
this.set(entry[0], entry[1]); | |
} | |
} | |
// Add methods to `Hash`. | |
Hash.prototype.clear = hashClear; | |
Hash.prototype['delete'] = hashDelete; | |
Hash.prototype.get = hashGet; | |
Hash.prototype.has = hashHas; | |
Hash.prototype.set = hashSet; | |
module.exports = Hash; | |
}); | |
var _Hash$1 = interopDefault(_Hash); | |
var require$$2$6 = Object.freeze({ | |
default: _Hash$1 | |
}); | |
var _listCacheClear = createCommonjsModule(function (module) { | |
/** | |
* Removes all key-value entries from the list cache. | |
* | |
* @private | |
* @name clear | |
* @memberOf ListCache | |
*/ | |
function listCacheClear() { | |
this.__data__ = []; | |
} | |
module.exports = listCacheClear; | |
}); | |
var _listCacheClear$1 = interopDefault(_listCacheClear); | |
var require$$4$5 = Object.freeze({ | |
default: _listCacheClear$1 | |
}); | |
var eq = createCommonjsModule(function (module) { | |
/** | |
* Performs a | |
* [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) | |
* comparison between two values to determine if they are equivalent. | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Lang | |
* @param {*} value The value to compare. | |
* @param {*} other The other value to compare. | |
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. | |
* @example | |
* | |
* var object = { 'user': 'fred' }; | |
* var other = { 'user': 'fred' }; | |
* | |
* _.eq(object, object); | |
* // => true | |
* | |
* _.eq(object, other); | |
* // => false | |
* | |
* _.eq('a', 'a'); | |
* // => true | |
* | |
* _.eq('a', Object('a')); | |
* // => false | |
* | |
* _.eq(NaN, NaN); | |
* // => true | |
*/ | |
function eq(value, other) { | |
return value === other || (value !== value && other !== other); | |
} | |
module.exports = eq; | |
}); | |
var eq$1 = interopDefault(eq); | |
var require$$0$22 = Object.freeze({ | |
default: eq$1 | |
}); | |
var _assocIndexOf = createCommonjsModule(function (module) { | |
var eq = interopDefault(require$$0$22); | |
/** | |
* Gets the index at which the `key` is found in `array` of key-value pairs. | |
* | |
* @private | |
* @param {Array} array The array to search. | |
* @param {*} key The key to search for. | |
* @returns {number} Returns the index of the matched value, else `-1`. | |
*/ | |
function assocIndexOf(array, key) { | |
var length = array.length; | |
while (length--) { | |
if (eq(array[length][0], key)) { | |
return length; | |
} | |
} | |
return -1; | |
} | |
module.exports = assocIndexOf; | |
}); | |
var _assocIndexOf$1 = interopDefault(_assocIndexOf); | |
var require$$0$21 = Object.freeze({ | |
default: _assocIndexOf$1 | |
}); | |
var _listCacheDelete = createCommonjsModule(function (module) { | |
var assocIndexOf = interopDefault(require$$0$21); | |
/** Used for built-in method references. */ | |
var arrayProto = Array.prototype; | |
/** Built-in value references. */ | |
var splice = arrayProto.splice; | |
/** | |
* Removes `key` and its value from the list cache. | |
* | |
* @private | |
* @name delete | |
* @memberOf ListCache | |
* @param {string} key The key of the value to remove. | |
* @returns {boolean} Returns `true` if the entry was removed, else `false`. | |
*/ | |
function listCacheDelete(key) { | |
var data = this.__data__, | |
index = assocIndexOf(data, key); | |
if (index < 0) { | |
return false; | |
} | |
var lastIndex = data.length - 1; | |
if (index == lastIndex) { | |
data.pop(); | |
} else { | |
splice.call(data, index, 1); | |
} | |
return true; | |
} | |
module.exports = listCacheDelete; | |
}); | |
var _listCacheDelete$1 = interopDefault(_listCacheDelete); | |
var require$$3$5 = Object.freeze({ | |
default: _listCacheDelete$1 | |
}); | |
var _listCacheGet = createCommonjsModule(function (module) { | |
var assocIndexOf = interopDefault(require$$0$21); | |
/** | |
* Gets the list cache value for `key`. | |
* | |
* @private | |
* @name get | |
* @memberOf ListCache | |
* @param {string} key The key of the value to get. | |
* @returns {*} Returns the entry value. | |
*/ | |
function listCacheGet(key) { | |
var data = this.__data__, | |
index = assocIndexOf(data, key); | |
return index < 0 ? undefined : data[index][1]; | |
} | |
module.exports = listCacheGet; | |
}); | |
var _listCacheGet$1 = interopDefault(_listCacheGet); | |
var require$$2$9 = Object.freeze({ | |
default: _listCacheGet$1 | |
}); | |
var _listCacheHas = createCommonjsModule(function (module) { | |
var assocIndexOf = interopDefault(require$$0$21); | |
/** | |
* Checks if a list cache value for `key` exists. | |
* | |
* @private | |
* @name has | |
* @memberOf ListCache | |
* @param {string} key The key of the entry to check. | |
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. | |
*/ | |
function listCacheHas(key) { | |
return assocIndexOf(this.__data__, key) > -1; | |
} | |
module.exports = listCacheHas; | |
}); | |
var _listCacheHas$1 = interopDefault(_listCacheHas); | |
var require$$1$11 = Object.freeze({ | |
default: _listCacheHas$1 | |
}); | |
var _listCacheSet = createCommonjsModule(function (module) { | |
var assocIndexOf = interopDefault(require$$0$21); | |
/** | |
* Sets the list cache `key` to `value`. | |
* | |
* @private | |
* @name set | |
* @memberOf ListCache | |
* @param {string} key The key of the value to set. | |
* @param {*} value The value to set. | |
* @returns {Object} Returns the list cache instance. | |
*/ | |
function listCacheSet(key, value) { | |
var data = this.__data__, | |
index = assocIndexOf(data, key); | |
if (index < 0) { | |
data.push([key, value]); | |
} else { | |
data[index][1] = value; | |
} | |
return this; | |
} | |
module.exports = listCacheSet; | |
}); | |
var _listCacheSet$1 = interopDefault(_listCacheSet); | |
var require$$0$23 = Object.freeze({ | |
default: _listCacheSet$1 | |
}); | |
var _ListCache = createCommonjsModule(function (module) { | |
var listCacheClear = interopDefault(require$$4$5), | |
listCacheDelete = interopDefault(require$$3$5), | |
listCacheGet = interopDefault(require$$2$9), | |
listCacheHas = interopDefault(require$$1$11), | |
listCacheSet = interopDefault(require$$0$23); | |
/** | |
* Creates an list cache object. | |
* | |
* @private | |
* @constructor | |
* @param {Array} [entries] The key-value pairs to cache. | |
*/ | |
function ListCache(entries) { | |
var index = -1, | |
length = entries ? entries.length : 0; | |
this.clear(); | |
while (++index < length) { | |
var entry = entries[index]; | |
this.set(entry[0], entry[1]); | |
} | |
} | |
// Add methods to `ListCache`. | |
ListCache.prototype.clear = listCacheClear; | |
ListCache.prototype['delete'] = listCacheDelete; | |
ListCache.prototype.get = listCacheGet; | |
ListCache.prototype.has = listCacheHas; | |
ListCache.prototype.set = listCacheSet; | |
module.exports = ListCache; | |
}); | |
var _ListCache$1 = interopDefault(_ListCache); | |
var require$$1$10 = Object.freeze({ | |
default: _ListCache$1 | |
}); | |
var _Map = createCommonjsModule(function (module) { | |
var getNative = interopDefault(require$$1$7), | |
root = interopDefault(require$$0$16); | |
/* Built-in method references that are verified to be native. */ | |
var Map = getNative(root, 'Map'); | |
module.exports = Map; | |
}); | |
var _Map$1 = interopDefault(_Map); | |
var require$$0$24 = Object.freeze({ | |
default: _Map$1 | |
}); | |
var _mapCacheClear = createCommonjsModule(function (module) { | |
var Hash = interopDefault(require$$2$6), | |
ListCache = interopDefault(require$$1$10), | |
Map = interopDefault(require$$0$24); | |
/** | |
* Removes all key-value entries from the map. | |
* | |
* @private | |
* @name clear | |
* @memberOf MapCache | |
*/ | |
function mapCacheClear() { | |
this.__data__ = { | |
'hash': new Hash, | |
'map': new (Map || ListCache), | |
'string': new Hash | |
}; | |
} | |
module.exports = mapCacheClear; | |
}); | |
var _mapCacheClear$1 = interopDefault(_mapCacheClear); | |
var require$$4$3 = Object.freeze({ | |
default: _mapCacheClear$1 | |
}); | |
var _isKeyable = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is suitable for use as unique object key. | |
* | |
* @private | |
* @param {*} value The value to check. | |
* @returns {boolean} Returns `true` if `value` is suitable, else `false`. | |
*/ | |
function isKeyable(value) { | |
var type = typeof value; | |
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') | |
? (value !== '__proto__') | |
: (value === null); | |
} | |
module.exports = isKeyable; | |
}); | |
var _isKeyable$1 = interopDefault(_isKeyable); | |
var require$$0$26 = Object.freeze({ | |
default: _isKeyable$1 | |
}); | |
var _getMapData = createCommonjsModule(function (module) { | |
var isKeyable = interopDefault(require$$0$26); | |
/** | |
* Gets the data for `map`. | |
* | |
* @private | |
* @param {Object} map The map to query. | |
* @param {string} key The reference key. | |
* @returns {*} Returns the map data. | |
*/ | |
function getMapData(map, key) { | |
var data = map.__data__; | |
return isKeyable(key) | |
? data[typeof key == 'string' ? 'string' : 'hash'] | |
: data.map; | |
} | |
module.exports = getMapData; | |
}); | |
var _getMapData$1 = interopDefault(_getMapData); | |
var require$$0$25 = Object.freeze({ | |
default: _getMapData$1 | |
}); | |
var _mapCacheDelete = createCommonjsModule(function (module) { | |
var getMapData = interopDefault(require$$0$25); | |
/** | |
* Removes `key` and its value from the map. | |
* | |
* @private | |
* @name delete | |
* @memberOf MapCache | |
* @param {string} key The key of the value to remove. | |
* @returns {boolean} Returns `true` if the entry was removed, else `false`. | |
*/ | |
function mapCacheDelete(key) { | |
return getMapData(this, key)['delete'](key); | |
} | |
module.exports = mapCacheDelete; | |
}); | |
var _mapCacheDelete$1 = interopDefault(_mapCacheDelete); | |
var require$$3$6 = Object.freeze({ | |
default: _mapCacheDelete$1 | |
}); | |
var _mapCacheGet = createCommonjsModule(function (module) { | |
var getMapData = interopDefault(require$$0$25); | |
/** | |
* Gets the map value for `key`. | |
* | |
* @private | |
* @name get | |
* @memberOf MapCache | |
* @param {string} key The key of the value to get. | |
* @returns {*} Returns the entry value. | |
*/ | |
function mapCacheGet(key) { | |
return getMapData(this, key).get(key); | |
} | |
module.exports = mapCacheGet; | |
}); | |
var _mapCacheGet$1 = interopDefault(_mapCacheGet); | |
var require$$2$10 = Object.freeze({ | |
default: _mapCacheGet$1 | |
}); | |
var _mapCacheHas = createCommonjsModule(function (module) { | |
var getMapData = interopDefault(require$$0$25); | |
/** | |
* Checks if a map value for `key` exists. | |
* | |
* @private | |
* @name has | |
* @memberOf MapCache | |
* @param {string} key The key of the entry to check. | |
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. | |
*/ | |
function mapCacheHas(key) { | |
return getMapData(this, key).has(key); | |
} | |
module.exports = mapCacheHas; | |
}); | |
var _mapCacheHas$1 = interopDefault(_mapCacheHas); | |
var require$$1$12 = Object.freeze({ | |
default: _mapCacheHas$1 | |
}); | |
var _mapCacheSet = createCommonjsModule(function (module) { | |
var getMapData = interopDefault(require$$0$25); | |
/** | |
* Sets the map `key` to `value`. | |
* | |
* @private | |
* @name set | |
* @memberOf MapCache | |
* @param {string} key The key of the value to set. | |
* @param {*} value The value to set. | |
* @returns {Object} Returns the map cache instance. | |
*/ | |
function mapCacheSet(key, value) { | |
getMapData(this, key).set(key, value); | |
return this; | |
} | |
module.exports = mapCacheSet; | |
}); | |
var _mapCacheSet$1 = interopDefault(_mapCacheSet); | |
var require$$0$27 = Object.freeze({ | |
default: _mapCacheSet$1 | |
}); | |
var _MapCache = createCommonjsModule(function (module) { | |
var mapCacheClear = interopDefault(require$$4$3), | |
mapCacheDelete = interopDefault(require$$3$6), | |
mapCacheGet = interopDefault(require$$2$10), | |
mapCacheHas = interopDefault(require$$1$12), | |
mapCacheSet = interopDefault(require$$0$27); | |
/** | |
* Creates a map cache object to store key-value pairs. | |
* | |
* @private | |
* @constructor | |
* @param {Array} [entries] The key-value pairs to cache. | |
*/ | |
function MapCache(entries) { | |
var index = -1, | |
length = entries ? entries.length : 0; | |
this.clear(); | |
while (++index < length) { | |
var entry = entries[index]; | |
this.set(entry[0], entry[1]); | |
} | |
} | |
// Add methods to `MapCache`. | |
MapCache.prototype.clear = mapCacheClear; | |
MapCache.prototype['delete'] = mapCacheDelete; | |
MapCache.prototype.get = mapCacheGet; | |
MapCache.prototype.has = mapCacheHas; | |
MapCache.prototype.set = mapCacheSet; | |
module.exports = MapCache; | |
}); | |
var _MapCache$1 = interopDefault(_MapCache); | |
var require$$2$5 = Object.freeze({ | |
default: _MapCache$1 | |
}); | |
var _setCacheAdd = createCommonjsModule(function (module) { | |
/** Used to stand-in for `undefined` hash values. */ | |
var HASH_UNDEFINED = '__lodash_hash_undefined__'; | |
/** | |
* Adds `value` to the array cache. | |
* | |
* @private | |
* @name add | |
* @memberOf SetCache | |
* @alias push | |
* @param {*} value The value to cache. | |
* @returns {Object} Returns the cache instance. | |
*/ | |
function setCacheAdd(value) { | |
this.__data__.set(value, HASH_UNDEFINED); | |
return this; | |
} | |
module.exports = setCacheAdd; | |
}); | |
var _setCacheAdd$1 = interopDefault(_setCacheAdd); | |
var require$$1$13 = Object.freeze({ | |
default: _setCacheAdd$1 | |
}); | |
var _setCacheHas = createCommonjsModule(function (module) { | |
/** | |
* Checks if `value` is in the array cache. | |
* | |
* @private | |
* @name has | |
* @memberOf SetCache | |
* @param {*} value The value to search for. | |
* @returns {number} Returns `true` if `value` is found, else `false`. | |
*/ | |
function setCacheHas(value) { | |
return this.__data__.has(value); | |
} | |
module.exports = setCacheHas; | |
}); | |
var _setCacheHas$1 = interopDefault(_setCacheHas); | |
var require$$0$28 = Object.freeze({ | |
default: _setCacheHas$1 | |
}); | |
var _SetCache = createCommonjsModule(function (module) { | |
var MapCache = interopDefault(require$$2$5), | |
setCacheAdd = interopDefault(require$$1$13), | |
setCacheHas = interopDefault(require$$0$28); | |
/** | |
* | |
* Creates an array cache object to store unique values. | |
* | |
* @private | |
* @constructor | |
* @param {Array} [values] The values to cache. | |
*/ | |
function SetCache(values) { | |
var index = -1, | |
length = values ? values.length : 0; | |
this.__data__ = new MapCache; | |
while (++index < length) { | |
this.add(values[index]); | |
} | |
} | |
// Add methods to `SetCache`. | |
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; | |
SetCache.prototype.has = setCacheHas; | |
module.exports = SetCache; | |
}); | |
var _SetCache$1 = interopDefault(_SetCache); | |
var require$$5$1 = Object.freeze({ | |
default: _SetCache$1 | |
}); | |
var _arrayIncludes = createCommonjsModule(function (module) { | |
var baseIndexOf = interopDefault(require$$0$1); | |
/** | |
* A specialized version of `_.includes` for arrays without support for | |
* specifying an index to search from. | |
* | |
* @private | |
* @param {Array} [array] The array to search. | |
* @param {*} target The value to search for. | |
* @returns {boolean} Returns `true` if `target` is found, else `false`. | |
*/ | |
function arrayIncludes(array, value) { | |
var length = array ? array.length : 0; | |
return !!length && baseIndexOf(array, value, 0) > -1; | |
} | |
module.exports = arrayIncludes; | |
}); | |
var _arrayIncludes$1 = interopDefault(_arrayIncludes); | |
var require$$4$6 = Object.freeze({ | |
default: _arrayIncludes$1 | |
}); | |
var _arrayIncludesWith = createCommonjsModule(function (module) { | |
/** | |
* This function is like `arrayIncludes` except that it accepts a comparator. | |
* | |
* @private | |
* @param {Array} [array] The array to search. | |
* @param {*} target The value to search for. | |
* @param {Function} comparator The comparator invoked per element. | |
* @returns {boolean} Returns `true` if `target` is found, else `false`. | |
*/ | |
function arrayIncludesWith(array, value, comparator) { | |
var index = -1, | |
length = array ? array.length : 0; | |
while (++index < length) { | |
if (comparator(value, array[index])) { | |
return true; | |
} | |
} | |
return false; | |
} | |
module.exports = arrayIncludesWith; | |
}); | |
var _arrayIncludesWith$1 = interopDefault(_arrayIncludesWith); | |
var require$$3$7 = Object.freeze({ | |
default: _arrayIncludesWith$1 | |
}); | |
var _baseUnary = createCommonjsModule(function (module) { | |
/** | |
* The base implementation of `_.unary` without support for storing wrapper metadata. | |
* | |
* @private | |
* @param {Function} func The function to cap arguments for. | |
* @returns {Function} Returns the new capped function. | |
*/ | |
function baseUnary(func) { | |
return function(value) { | |
return func(value); | |
}; | |
} | |
module.exports = baseUnary; | |
}); | |
var _baseUnary$1 = interopDefault(_baseUnary); | |
var require$$1$14 = Object.freeze({ | |
default: _baseUnary$1 | |
}); | |
var _cacheHas = createCommonjsModule(function (module) { | |
/** | |
* Checks if a cache value for `key` exists. | |
* | |
* @private | |
* @param {Object} cache The cache to query. | |
* @param {string} key The key of the entry to check. | |
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. | |
*/ | |
function cacheHas(cache, key) { | |
return cache.has(key); | |
} | |
module.exports = cacheHas; | |
}); | |
var _cacheHas$1 = interopDefault(_cacheHas); | |
var require$$2$11 = Object.freeze({ | |
default: _cacheHas$1 | |
}); | |
var _baseDifference = createCommonjsModule(function (module) { | |
var SetCache = interopDefault(require$$5$1), | |
arrayIncludes = interopDefault(require$$4$6), | |
arrayIncludesWith = interopDefault(require$$3$7), | |
arrayMap = interopDefault(require$$2$2), | |
baseUnary = interopDefault(require$$1$14), | |
cacheHas = interopDefault(require$$2$11); | |
/** Used as the size to enable large array optimizations. */ | |
var LARGE_ARRAY_SIZE = 200; | |
/** | |
* The base implementation of methods like `_.difference` without support | |
* for excluding multiple arrays or iteratee shorthands. | |
* | |
* @private | |
* @param {Array} array The array to inspect. | |
* @param {Array} values The values to exclude. | |
* @param {Function} [iteratee] The iteratee invoked per element. | |
* @param {Function} [comparator] The comparator invoked per element. | |
* @returns {Array} Returns the new array of filtered values. | |
*/ | |
function baseDifference(array, values, iteratee, comparator) { | |
var index = -1, | |
includes = arrayIncludes, | |
isCommon = true, | |
length = array.length, | |
result = [], | |
valuesLength = values.length; | |
if (!length) { | |
return result; | |
} | |
if (iteratee) { | |
values = arrayMap(values, baseUnary(iteratee)); | |
} | |
if (comparator) { | |
includes = arrayIncludesWith; | |
isCommon = false; | |
} | |
else if (values.length >= LARGE_ARRAY_SIZE) { | |
includes = cacheHas; | |
isCommon = false; | |
values = new SetCache(values); | |
} | |
outer: | |
while (++index < length) { | |
var value = array[index], | |
computed = iteratee ? iteratee(value) : value; | |
value = (comparator || value !== 0) ? value : 0; | |
if (isCommon && computed === computed) { | |
var valuesIndex = valuesLength; | |
while (valuesIndex--) { | |
if (values[valuesIndex] === computed) { | |
continue outer; | |
} | |
} | |
result.push(value); | |
} | |
else if (!includes(values, computed, comparator)) { | |
result.push(value); | |
} | |
} | |
return result; | |
} | |
module.exports = baseDifference; | |
}); | |
var _baseDifference$1 = interopDefault(_baseDifference); | |
var require$$1$6 = Object.freeze({ | |
default: _baseDifference$1 | |
}); | |
var _Set = createCommonjsModule(function (module) { | |
var getNative = interopDefault(require$$1$7), | |
root = interopDefault(require$$0$16); | |
/* Built-in method references that are verified to be native. */ | |
var Set = getNative(root, 'Set'); | |
module.exports = Set; | |
}); | |
var _Set$1 = interopDefault(_Set); | |
var require$$2$12 = Object.freeze({ | |
default: _Set$1 | |
}); | |
var noop$2 = createCommonjsModule(function (module) { | |
/** | |
* A method that returns `undefined`. | |
* | |
* @static | |
* @memberOf _ | |
* @since 2.3.0 | |
* @category Util | |
* @example | |
* | |
* _.times(2, _.noop); | |
* // => [undefined, undefined] | |
*/ | |
function noop() { | |
// No operation performed. | |
} | |
module.exports = noop; | |
}); | |
var noop$3 = interopDefault(noop$2); | |
var require$$1$16 = Object.freeze({ | |
default: noop$3 | |
}); | |
var _setToArray = createCommonjsModule(function (module) { | |
/** | |
* Converts `set` to an array of its values. | |
* | |
* @private | |
* @param {Object} set The set to convert. | |
* @returns {Array} Returns the values. | |
*/ | |
function setToArray(set) { | |
var index = -1, | |
result = Array(set.size); | |
set.forEach(function(value) { | |
result[++index] = value; | |
}); | |
return result; | |
} | |
module.exports = setToArray; | |
}); | |
var _setToArray$1 = interopDefault(_setToArray); | |
var require$$0$30 = Object.freeze({ | |
default: _setToArray$1 | |
}); | |
var _createSet = createCommonjsModule(function (module) { | |
var Set = interopDefault(require$$2$12), | |
noop = interopDefault(require$$1$16), | |
setToArray = interopDefault(require$$0$30); | |
/** Used as references for various `Number` constants. */ | |
var INFINITY = 1 / 0; | |
/** | |
* Creates a set of `values`. | |
* | |
* @private | |
* @param {Array} values The values to add to the set. | |
* @returns {Object} Returns the new set. | |
*/ | |
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { | |
return new Set(values); | |
}; | |
module.exports = createSet; | |
}); | |
var _createSet$1 = interopDefault(_createSet); | |
var require$$1$15 = Object.freeze({ | |
default: _createSet$1 | |
}); | |
var _baseUniq = createCommonjsModule(function (module) { | |
var SetCache = interopDefault(require$$5$1), | |
arrayIncludes = interopDefault(require$$4$6), | |
arrayIncludesWith = interopDefault(require$$3$7), | |
cacheHas = interopDefault(require$$2$11), | |
createSet = interopDefault(require$$1$15), | |
setToArray = interopDefault(require$$0$30); | |
/** Used as the size to enable large array optimizations. */ | |
var LARGE_ARRAY_SIZE = 200; | |
/** | |
* The base implementation of `_.uniqBy` without support for iteratee shorthands. | |
* | |
* @private | |
* @param {Array} array The array to inspect. | |
* @param {Function} [iteratee] The iteratee invoked per element. | |
* @param {Function} [comparator] The comparator invoked per element. | |
* @returns {Array} Returns the new duplicate free array. | |
*/ | |
function baseUniq(array, iteratee, comparator) { | |
var index = -1, | |
includes = arrayIncludes, | |
length = array.length, | |
isCommon = true, | |
result = [], | |
seen = result; | |
if (comparator) { | |
isCommon = false; | |
includes = arrayIncludesWith; | |
} | |
else if (length >= LARGE_ARRAY_SIZE) { | |
var set = iteratee ? null : createSet(array); | |
if (set) { | |
return setToArray(set); | |
} | |
isCommon = false; | |
includes = cacheHas; | |
seen = new SetCache; | |
} | |
else { | |
seen = iteratee ? [] : result; | |
} | |
outer: | |
while (++index < length) { | |
var value = array[index], | |
computed = iteratee ? iteratee(value) : value; | |
value = (comparator || value !== 0) ? value : 0; | |
if (isCommon && computed === computed) { | |
var seenIndex = seen.length; | |
while (seenIndex--) { | |
if (seen[seenIndex] === computed) { | |
continue outer; | |
} | |
} | |
if (iteratee) { | |
seen.push(computed); | |
} | |
result.push(value); | |
} | |
else if (!includes(seen, computed, comparator)) { | |
if (seen !== result) { | |
seen.push(computed); | |
} | |
result.push(value); | |
} | |
} | |
return result; | |
} | |
module.exports = baseUniq; | |
}); | |
var _baseUniq$1 = interopDefault(_baseUniq); | |
var require$$0$29 = Object.freeze({ | |
default: _baseUniq$1 | |
}); | |
var _baseXor = createCommonjsModule(function (module) { | |
var arrayPush = interopDefault(require$$2$4), | |
baseDifference = interopDefault(require$$1$6), | |
baseUniq = interopDefault(require$$0$29); | |
/** | |
* The base implementation of methods like `_.xor`, without support for | |
* iteratee shorthands, that accepts an array of arrays to inspect. | |
* | |
* @private | |
* @param {Array} arrays The arrays to inspect. | |
* @param {Function} [iteratee] The iteratee invoked per element. | |
* @param {Function} [comparator] The comparator invoked per element. | |
* @returns {Array} Returns the new array of values. | |
*/ | |
function baseXor(arrays, iteratee, comparator) { | |
var index = -1, | |
length = arrays.length; | |
while (++index < length) { | |
var result = result | |
? arrayPush( | |
baseDifference(result, arrays[index], iteratee, comparator), | |
baseDifference(arrays[index], result, iteratee, comparator) | |
) | |
: arrays[index]; | |
} | |
return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; | |
} | |
module.exports = baseXor; | |
}); | |
var _baseXor$1 = interopDefault(_baseXor); | |
var require$$2$3 = Object.freeze({ | |
default: _baseXor$1 | |
}); | |
var _apply = createCommonjsModule(function (module) { | |
/** | |
* A faster alternative to `Function#apply`, this function invokes `func` | |
* with the `this` binding of `thisArg` and the arguments of `args`. | |
* | |
* @private | |
* @param {Function} func The function to invoke. | |
* @param {*} thisArg The `this` binding of `func`. | |
* @param {Array} args The arguments to invoke `func` with. | |
* @returns {*} Returns the result of `func`. | |
*/ | |
function apply(func, thisArg, args) { | |
var length = args.length; | |
switch (length) { | |
case 0: return func.call(thisArg); | |
case 1: return func.call(thisArg, args[0]); | |
case 2: return func.call(thisArg, args[0], args[1]); | |
case 3: return func.call(thisArg, args[0], args[1], args[2]); | |
} | |
return func.apply(thisArg, args); | |
} | |
module.exports = apply; | |
}); | |
var _apply$1 = interopDefault(_apply); | |
var require$$1$17 = Object.freeze({ | |
default: _apply$1 | |
}); | |
var rest = createCommonjsModule(function (module) { | |
var apply = interopDefault(require$$1$17), | |
toInteger = interopDefault(require$$0$6); | |
/** Used as the `TypeError` message for "Functions" methods. */ | |
var FUNC_ERROR_TEXT = 'Expected a function'; | |
/* Built-in method references for those with the same name as other `lodash` methods. */ | |
var nativeMax = Math.max; | |
/** | |
* Creates a function that invokes `func` with the `this` binding of the | |
* created function and arguments from `start` and beyond provided as | |
* an array. | |
* | |
* **Note:** This method is based on the | |
* [rest parameter](https://mdn.io/rest_parameters). | |
* | |
* @static | |
* @memberOf _ | |
* @since 4.0.0 | |
* @category Function | |
* @param {Function} func The function to apply a rest parameter to. | |
* @param {number} [start=func.length-1] The start position of the rest parameter. | |
* @returns {Function} Returns the new function. | |
* @example | |
* | |
* var say = _.rest(function(what, names) { | |
* return what + ' ' + _.initial(names).join(', ') + | |
* (_.size(names) > 1 ? ', & ' : '') + _.last(names); | |
* }); | |
* | |
* say('hello', 'fred', 'barney', 'pebbles'); | |
* // => 'hello fred, barney, & pebbles' | |
*/ | |
function rest(func, start) { | |
if (typeof func != 'function') { | |
throw new TypeError(FUNC_ERROR_TEXT); | |
} | |
start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); | |
return function() { | |
var args = arguments, | |
index = -1, | |
length = nativeMax(args.length - start, 0), | |
array = Array(length); | |
while (++index < length) { | |
array[index] = args[start + index]; | |
} | |
switch (start) { | |
case 0: return func.call(this, array); | |
case 1: return func.call(this, args[0], array); | |
case 2: return func.call(this, args[0], args[1], array); | |
} | |
var otherArgs = Array(start + 1); | |
index = -1; | |
while (++index < start) { | |
otherArgs[index] = args[index]; | |
} | |
otherArgs[start] = array; | |
return apply(func, this, otherArgs); | |
}; | |
} | |
module.exports = rest; | |
}); | |
var rest$1 = interopDefault(rest); | |
var require$$0$31 = Object.freeze({ | |
default: rest$1 | |
}); | |
var xor = createCommonjsModule(function (module) { | |
var arrayFilter = interopDefault(require$$3$2), | |
baseXor = interopDefault(require$$2$3), | |
isArrayLikeObject = interopDefault(require$$1$4), | |
rest = interopDefault(require$$0$31); | |
/** | |
* Creates an array of unique values that is the | |
* [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) | |
* of the given arrays. The order of result values is determined by the order | |
* they occur in the arrays. | |
* | |
* @static | |
* @memberOf _ | |
* @since 2.4.0 | |
* @category Array | |
* @param {...Array} [arrays] The arrays to inspect. | |
* @returns {Array} Returns the new array of filtered values. | |
* @see _.difference, _.without | |
* @example | |
* | |
* _.xor([2, 1], [2, 3]); | |
* // => [1, 3] | |
*/ | |
var xor = rest(function(arrays) { | |
return baseXor(arrayFilter(arrays, isArrayLikeObject)); | |
}); | |
module.exports = xor; | |
}); | |
var xor$1 = interopDefault(xor); | |
/** | |
* Snapshot, with a state-like shape. | |
*/ | |
var Snapshot = new Record({ | |
document: null, | |
selection: null, | |
steps: new List() | |
}); | |
/** | |
* Step. | |
*/ | |
var Step = new Record({ | |
type: null, | |
args: null | |
}); | |
/** | |
* Document transforms. | |
*/ | |
var DOCUMENT_TRANSFORMS = ['deleteAtRange', 'deleteBackwardAtRange', 'deleteForwardAtRange', 'insertFragmentAtRange', 'insertTextAtRange', 'addMarkAtRange', 'setBlockAtRange', 'setInlineAtRange', 'splitBlockAtRange', 'splitInlineAtRange', 'removeMarkAtRange', 'unwrapBlockAtRange', 'unwrapInlineAtRange', 'wrapBlockAtRange', 'wrapInlineAtRange']; | |
/** | |
* Selection transforms. | |
*/ | |
var SELECTION_TRANSFORMS = ['blur', 'collapseToAnchor', 'collapseToEnd', 'collapseToEndOf', 'collapseToFocus', 'collapseToStart', 'collapseToStartOf', 'extendBackward', 'extendForward', 'extendToEndOf', 'extendToStartOf', 'focus', 'moveBackward', 'moveForward', 'moveToOffsets', 'moveToRangeOf']; | |
/** | |
* State-level document transforms. | |
*/ | |
var STATE_DOCUMENT_TRANSFORMS = ['delete', 'deleteBackward', 'deleteForward', 'insertFragment', 'insertText', 'addMark', 'setBlock', 'setInline', 'splitBlock', 'splitInline', 'removeMark', 'unwrapBlock', 'unwrapInline', 'wrapBlock', 'wrapInline']; | |
/** | |
* State selection transforms. | |
*/ | |
var STATE_SELECTION_TRANSFORMS = ['collapseToEndOfNextBlock', 'collapseToEndOfNextText', 'collapseToEndOfPreviousBlock', 'collapseToEndOfPreviousText', 'collapseToStartOfNextBlock', 'collapseToStartOfNextText', 'collapseToStartOfPreviousBlock', 'collapseToStartOfPreviousText', 'moveTo']; | |
/** | |
* All state-level transforms. | |
*/ | |
var STATE_TRANSFORMS = [].concat(STATE_DOCUMENT_TRANSFORMS).concat(STATE_SELECTION_TRANSFORMS); | |
/** | |
* All transforms. | |
*/ | |
var TRANSFORMS = [].concat(DOCUMENT_TRANSFORMS).concat(SELECTION_TRANSFORMS).concat(STATE_TRANSFORMS); | |
/** | |
* Defaults. | |
*/ | |
var DEFAULT_PROPERTIES = { | |
state: null, | |
steps: new List() | |
}; | |
/** | |
* Transform. | |
*/ | |
var Transform = function (_ref) { | |
inherits(Transform, _ref); | |
function Transform() { | |
classCallCheck(this, Transform); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(Transform).apply(this, arguments)); | |
} | |
createClass(Transform, [{ | |
key: 'apply', | |
/** | |
* Apply the transform and return the new state. | |
* | |
* @param {Object} options | |
* @property {Boolean} isNative | |
* @property {Boolean} snapshot | |
* @return {State} state | |
*/ | |
value: function apply() { | |
var _this2 = this; | |
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
var transform = this; | |
var state = transform.state; | |
var steps = transform.steps; | |
var _state = state; | |
var cursorMarks = _state.cursorMarks; | |
var history = _state.history; | |
var selection = _state.selection; | |
var _history = history; | |
var undos = _history.undos; | |
var redos = _history.redos; | |
// Determine whether we need to create a new snapshot. | |
var shouldSnapshot = options.snapshot == null ? this.shouldSnapshot() : options.snapshot; | |
// If we should, save a snapshot into the history before transforming. | |
if (shouldSnapshot) { | |
var snapshot = transform.snapshot(); | |
undos = undos.push(snapshot); | |
if (undos.size > 100) undos = undos.take(100); | |
redos = redos.clear(); | |
history = history.merge({ undos: undos, redos: redos }); | |
state = state.merge({ history: history }); | |
} | |
// Apply each of the steps in the transform, arriving at a new state. | |
state = steps.reduce(function (memo, step) { | |
return _this2.applyStep(memo, step); | |
}, state); | |
// If the selection has changed, clear any existing cursor marks. | |
if (state.selection != selection) { | |
state = state.merge({ | |
cursorMarks: null | |
}); | |
} | |
// Apply the "isNative" flag, which is used to allow for natively-handled | |
// content changes to skip rerendering the editor for performance. | |
state = state.merge({ | |
isNative: !!options.isNative | |
}); | |
return state; | |
} | |
/** | |
* Apply a single `step` to a `state`, differentiating between types. | |
* | |
* @param {State} state | |
* @param {Step} step | |
* @return {State} state | |
*/ | |
}, { | |
key: 'applyStep', | |
value: function applyStep(state, step) { | |
var type = step.type; | |
var args = step.args; | |
if (includes$1(DOCUMENT_TRANSFORMS, type)) { | |
var _document; | |
var _state2 = state; | |
var document = _state2.document; | |
var selection = _state2.selection; | |
var _args = toArray(args); | |
var range = _args[0]; | |
var rest = _args.slice(1); | |
range = range.normalize(document); | |
document = (_document = document)[type].apply(_document, [range].concat(toConsumableArray(rest))); | |
selection = selection.normalize(document); | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} else if (includes$1(SELECTION_TRANSFORMS, type)) { | |
var _selection2; | |
var _state3 = state; | |
var _document2 = _state3.document; | |
var _selection = _state3.selection; | |
_selection = (_selection2 = _selection)[type].apply(_selection2, toConsumableArray(args)); | |
_selection = _selection.normalize(_document2); | |
state = state.merge({ selection: _selection }); | |
return state; | |
} else if (includes$1(STATE_TRANSFORMS, type)) { | |
var _state4; | |
state = (_state4 = state)[type].apply(_state4, toConsumableArray(args)); | |
return state; | |
} | |
} | |
/** | |
* Check whether the current transform steps should create a snapshot. | |
* | |
* @return {Boolean} | |
*/ | |
}, { | |
key: 'shouldSnapshot', | |
value: function shouldSnapshot() { | |
var transform = this; | |
var state = transform.state; | |
var steps = transform.steps; | |
var cursorMarks = state.cursorMarks; | |
var history = state.history; | |
var selection = state.selection; | |
var undos = history.undos; | |
var redos = history.redos; | |
var previous = undos.peek(); | |
// If the only steps applied are selection transforms, don't snapshot. | |
var onlySelections = steps.every(function (step) { | |
return includes$1(SELECTION_TRANSFORMS, step.type) || includes$1(STATE_SELECTION_TRANSFORMS, step.type); | |
}); | |
if (onlySelections) return false; | |
// If there isn't a previous state, snapshot. | |
if (!previous) return true; | |
// If there is a previous state but the steps are different, snapshot. | |
var types = steps.map(function (step) { | |
return step.type; | |
}); | |
var prevTypes = previous.steps.map(function (step) { | |
return step.type; | |
}); | |
var diff = xor$1(types.toArray(), prevTypes.toArray()); | |
if (diff.length) return true; | |
// If the current steps aren't one of the "combinable" types, snapshot. | |
var allCombinable = steps.every(function (step) { | |
return step.type == 'insertText'; | |
}) || steps.every(function (step) { | |
return step.type == 'deleteForward'; | |
}) || steps.every(function (step) { | |
return step.type == 'deleteBackward'; | |
}); | |
if (!allCombinable) return true; | |
// Otherwise, don't snapshot. | |
return false; | |
} | |
/** | |
* Create a history-ready snapshot of the current state. | |
* | |
* @return {Snapshot} snapshot | |
*/ | |
}, { | |
key: 'snapshot', | |
value: function snapshot() { | |
var state = this.state; | |
var steps = this.steps; | |
var document = state.document; | |
var selection = state.selection; | |
return new Snapshot({ document: document, selection: selection, steps: steps }); | |
} | |
/** | |
* Undo to the previous state in the history. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'undo', | |
value: function undo() { | |
var transform = this; | |
var state = transform.state; | |
var _state5 = state; | |
var history = _state5.history; | |
var _history2 = history; | |
var undos = _history2.undos; | |
var redos = _history2.redos; | |
// If there's no previous snapshot, return the current state. | |
var previous = undos.peek(); | |
if (!previous) return state; | |
// Remove the previous snapshot from the undo stack. | |
undos = undos.pop(); | |
// Snapshot the current state, and move it into the redos stack. | |
var snapshot = transform.snapshot(); | |
redos = redos.push(snapshot); | |
// Return the previous state, with the updated history. | |
var document = previous.document; | |
var selection = previous.selection; | |
history = history.merge({ undos: undos, redos: redos }); | |
state = state.merge({ document: document, selection: selection, history: history }); | |
return state; | |
} | |
/** | |
* Redo to the next state in the history. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'redo', | |
value: function redo() { | |
var transform = this; | |
var state = transform.state; | |
var _state6 = state; | |
var history = _state6.history; | |
var _history3 = history; | |
var undos = _history3.undos; | |
var redos = _history3.redos; | |
// If there's no next snapshot, return the current state. | |
var next = redos.peek(); | |
if (!next) return state; | |
// Remove the next history from the redo stack. | |
redos = redos.pop(); | |
// Snapshot the current state, and move it into the undos stack. | |
var snapshot = transform.snapshot(); | |
undos = undos.push(snapshot); | |
// Return the next state, with the updated history. | |
var document = next.document; | |
var selection = next.selection; | |
history = history.merge({ undos: undos, redos: redos }); | |
state = state.merge({ document: document, selection: selection, history: history }); | |
return state; | |
} | |
}, { | |
key: 'kind', | |
/** | |
* Get the kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'transform'; | |
} | |
}]); | |
return Transform; | |
}(new Record(DEFAULT_PROPERTIES)); | |
/** | |
* Add a step-creating method for each of the transforms. | |
*/ | |
TRANSFORMS.forEach(function (type) { | |
Transform.prototype[type] = function () { | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
var transform = this; | |
var _transform = transform; | |
var steps = _transform.steps; | |
steps = steps.push(new Step({ type: type, args: args })); | |
transform = transform.merge({ steps: steps }); | |
return transform; | |
}; | |
}); | |
/** | |
* History. | |
*/ | |
var History = new Record({ | |
undos: new Stack(), | |
redos: new Stack() | |
}); | |
/** | |
* Default properties. | |
*/ | |
var DEFAULTS$6 = { | |
cursorMarks: null, | |
document: new Document(), | |
selection: new Selection(), | |
history: new History(), | |
isNative: false | |
}; | |
/** | |
* State. | |
*/ | |
var State = function (_ref) { | |
inherits(State, _ref); | |
function State() { | |
classCallCheck(this, State); | |
return possibleConstructorReturn(this, Object.getPrototypeOf(State).apply(this, arguments)); | |
} | |
createClass(State, [{ | |
key: 'transform', | |
/** | |
* Return a new `Transform` with the current state as a starting point. | |
* | |
* @return {Transform} transform | |
*/ | |
value: function transform() { | |
var state = this; | |
return new Transform({ state: state }); | |
} | |
/** | |
* Move the selection to the start of the previous block. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToStartOfPreviousBlock', | |
value: function collapseToStartOfPreviousBlock() { | |
var state = this; | |
var _state = state; | |
var document = _state.document; | |
var selection = _state.selection; | |
var blocks = document.getBlocksAtRange(selection); | |
var block = blocks.first(); | |
if (!block) return state; | |
var previous = document.getPreviousBlock(block); | |
if (!previous) return state; | |
selection = selection.collapseToStartOf(previous); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the end of the previous block. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToEndOfPreviousBlock', | |
value: function collapseToEndOfPreviousBlock() { | |
var state = this; | |
var _state2 = state; | |
var document = _state2.document; | |
var selection = _state2.selection; | |
var blocks = document.getBlocksAtRange(selection); | |
var block = blocks.first(); | |
if (!block) return state; | |
var previous = document.getPreviousBlock(block); | |
if (!previous) return state; | |
selection = selection.collapseToEndOf(previous); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the start of the next block. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToStartOfNextBlock', | |
value: function collapseToStartOfNextBlock() { | |
var state = this; | |
var _state3 = state; | |
var document = _state3.document; | |
var selection = _state3.selection; | |
var blocks = document.getBlocksAtRange(selection); | |
var block = blocks.last(); | |
if (!block) return state; | |
var next = document.getNextBlock(block); | |
if (!next) return state; | |
selection = selection.collapseToStartOf(next); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the end of the next block. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToEndOfNextBlock', | |
value: function collapseToEndOfNextBlock() { | |
var state = this; | |
var _state4 = state; | |
var document = _state4.document; | |
var selection = _state4.selection; | |
var blocks = document.getBlocksAtRange(selection); | |
var block = blocks.last(); | |
if (!block) return state; | |
var next = document.getNextBlock(block); | |
if (!next) return state; | |
selection = selection.collapseToEndOf(next); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the start of the previous text. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToStartOfPreviousText', | |
value: function collapseToStartOfPreviousText() { | |
var state = this; | |
var _state5 = state; | |
var document = _state5.document; | |
var selection = _state5.selection; | |
var texts = document.getTextsAtRange(selection); | |
var text = texts.first(); | |
if (!text) return state; | |
var previous = document.getPreviousText(text); | |
if (!previous) return state; | |
selection = selection.collapseToStartOf(previous); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the end of the previous text. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToEndOfPreviousText', | |
value: function collapseToEndOfPreviousText() { | |
var state = this; | |
var _state6 = state; | |
var document = _state6.document; | |
var selection = _state6.selection; | |
var texts = document.getTextsAtRange(selection); | |
var text = texts.first(); | |
if (!text) return state; | |
var previous = document.getPreviousText(text); | |
if (!previous) return state; | |
selection = selection.collapseToEndOf(previous); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the start of the next text. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToStartOfNextText', | |
value: function collapseToStartOfNextText() { | |
var state = this; | |
var _state7 = state; | |
var document = _state7.document; | |
var selection = _state7.selection; | |
var texts = document.getTextsAtRange(selection); | |
var text = texts.last(); | |
if (!text) return state; | |
var next = document.getNextText(text); | |
if (!next) return state; | |
selection = selection.collapseToStartOf(next); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Move the selection to the end of the next text. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'collapseToEndOfNextText', | |
value: function collapseToEndOfNextText() { | |
var state = this; | |
var _state8 = state; | |
var document = _state8.document; | |
var selection = _state8.selection; | |
var texts = document.getTextsAtRange(selection); | |
var text = texts.last(); | |
if (!text) return state; | |
var next = document.getNextText(text); | |
if (!next) return state; | |
selection = selection.collapseToEndOf(next); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Delete at the current selection. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'delete', | |
value: function _delete() { | |
var state = this; | |
var _state9 = state; | |
var document = _state9.document; | |
var selection = _state9.selection; | |
// When collapsed, there's nothing to do. | |
if (selection.isCollapsed) return state; | |
// Otherwise, delete and update the selection. | |
document = document.deleteAtRange(selection); | |
selection = selection.collapseToStart(); | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Delete backward `n` characters at the current selection. | |
* | |
* @param {Number} n (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'deleteBackward', | |
value: function deleteBackward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
var state = this; | |
var _state10 = state; | |
var document = _state10.document; | |
var selection = _state10.selection; | |
var after = selection; | |
// Determine what the selection should be after deleting. | |
var _selection = selection; | |
var startKey = _selection.startKey; | |
var startNode = document.getDescendant(startKey); | |
if (selection.isExpanded) { | |
after = selection.collapseToStart(); | |
} else if (selection.isAtStartOf(document)) { | |
after = selection; | |
} else if (selection.isAtStartOf(startNode)) { | |
var previous = document.getPreviousText(startNode); | |
var prevBlock = document.getClosestBlock(previous); | |
var prevInline = document.getClosestInline(previous); | |
if (prevBlock && prevBlock.isVoid) { | |
after = selection; | |
} else if (prevInline && prevInline.isVoid) { | |
after = selection; | |
} else { | |
after = selection.collapseToEndOf(previous); | |
} | |
} else { | |
after = selection.moveBackward(n); | |
} | |
// Delete backward and then update the selection. | |
document = document.deleteBackwardAtRange(selection, n); | |
selection = after; | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Delete forward `n` characters at the current selection. | |
* | |
* @param {Number} n (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'deleteForward', | |
value: function deleteForward() { | |
var n = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0]; | |
var state = this; | |
var _state11 = state; | |
var document = _state11.document; | |
var selection = _state11.selection; | |
var _selection2 = selection; | |
var startKey = _selection2.startKey; | |
var after = selection; | |
// Determine what the selection should be after deleting. | |
var block = document.getClosestBlock(startKey); | |
var inline = document.getClosestInline(startKey); | |
if (selection.isExpanded) { | |
after = selection.collapseToStart(); | |
} else if (block && block.isVoid || inline && inline.isVoid) { | |
var next = document.getNextText(startKey); | |
var previous = document.getPreviousText(startKey); | |
after = next ? selection.collapseToStartOf(next) : selection.collapseToEndOf(previous); | |
} | |
// Delete forward and then update the selection. | |
document = document.deleteForwardAtRange(selection, n); | |
selection = after; | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Insert a `fragment` at the current selection. | |
* | |
* @param {List} fragment | |
* @return {State} state | |
*/ | |
}, { | |
key: 'insertFragment', | |
value: function insertFragment(fragment) { | |
var state = this; | |
var _state12 = state; | |
var document = _state12.document; | |
var selection = _state12.selection; | |
var after = selection; | |
// If there's nothing in the fragment, do nothing. | |
if (!fragment.length) return state; | |
// Lookup some nodes for determining the selection next. | |
var texts = fragment.getTexts(); | |
var lastText = texts.last(); | |
var lastInline = fragment.getClosestInline(lastText); | |
var startText = document.getDescendant(selection.startKey); | |
var startBlock = document.getClosestBlock(startText); | |
var startInline = document.getClosestInline(startText); | |
var nextText = document.getNextText(startText); | |
var nextBlock = nextText ? document.getClosestBlock(nextText) : null; | |
var nextNextText = nextText ? document.getNextText(nextText) : null; | |
var docTexts = document.getTexts(); | |
// Insert the fragment. | |
document = document.insertFragmentAtRange(selection, fragment); | |
// Determine what the selection should be after inserting. | |
var keys = docTexts.map(function (text) { | |
return text.key; | |
}); | |
var text = document.getTexts().findLast(function (n) { | |
return !keys.includes(n.key); | |
}); | |
after = text ? selection.collapseToStartOf(text).moveForward(lastText.length) : selection.collapseToStart().moveForward(lastText.length); | |
// Update the document and selection. | |
selection = after; | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Insert a `text` string at the current selection. | |
* | |
* @param {String} text | |
* @return {State} state | |
*/ | |
}, { | |
key: 'insertText', | |
value: function insertText(text) { | |
var state = this; | |
var _state13 = state; | |
var cursorMarks = _state13.cursorMarks; | |
var document = _state13.document; | |
var selection = _state13.selection; | |
var after = selection; | |
// Determine what the selection should be after inserting. | |
if (selection.isExpanded) { | |
after = selection.collapseToStart().moveForward(text.length); | |
} else { | |
after = selection.moveForward(text.length); | |
} | |
// Insert the text and update the selection. | |
document = document.insertTextAtRange(selection, text, cursorMarks); | |
selection = after; | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Add a `mark` to the characters in the current selection. | |
* | |
* @param {Mark} mark | |
* @return {State} state | |
*/ | |
}, { | |
key: 'addMark', | |
value: function addMark(mark) { | |
var state = this; | |
var _state14 = state; | |
var cursorMarks = _state14.cursorMarks; | |
var document = _state14.document; | |
var selection = _state14.selection; | |
// If the selection is collapsed, add the mark to the cursor instead. | |
if (selection.isCollapsed) { | |
if (typeof mark == 'string') mark = new Mark({ type: mark }); | |
var marks = document.getMarksAtRange(selection); | |
state = state.merge({ cursorMarks: marks.add(mark) }); | |
return state; | |
} | |
document = document.addMarkAtRange(selection, mark); | |
state = state.merge({ document: document }); | |
return state; | |
} | |
/** | |
* Move the selection to a specific anchor and focus point. | |
* | |
* @param {Object} properties | |
* @return {State} state | |
*/ | |
}, { | |
key: 'moveTo', | |
value: function moveTo(properties) { | |
var state = this; | |
var _state15 = state; | |
var document = _state15.document; | |
var selection = _state15.selection; | |
// Pass in properties, and force `isBackward` to be re-resolved. | |
selection = selection.merge(_extends({}, properties, { | |
isBackward: null | |
})); | |
selection = selection.normalize(document); | |
state = state.merge({ selection: selection }); | |
return state; | |
} | |
/** | |
* Set `properties` of the block nodes in the current selection. | |
* | |
* @param {Object} properties | |
* @return {State} state | |
*/ | |
}, { | |
key: 'setBlock', | |
value: function setBlock(properties) { | |
var state = this; | |
var _state16 = state; | |
var document = _state16.document; | |
var selection = _state16.selection; | |
document = document.setBlockAtRange(selection, properties); | |
state = state.merge({ document: document }); | |
return state; | |
} | |
/** | |
* Set `properties` of the inline nodes in the current selection. | |
* | |
* @param {Object} properties | |
* @return {State} state | |
*/ | |
}, { | |
key: 'setInline', | |
value: function setInline(properties) { | |
var state = this; | |
var _state17 = state; | |
var document = _state17.document; | |
var selection = _state17.selection; | |
document = document.setInlineAtRange(selection, properties); | |
state = state.merge({ document: document }); | |
return state; | |
} | |
/** | |
* Split the block node at the current selection. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'splitBlock', | |
value: function splitBlock() { | |
var state = this; | |
var _state18 = state; | |
var document = _state18.document; | |
var selection = _state18.selection; | |
// Split the document. | |
document = document.splitBlockAtRange(selection); | |
// Determine what the selection should be after splitting. | |
var _selection3 = selection; | |
var startKey = _selection3.startKey; | |
var startNode = document.getDescendant(startKey); | |
var nextNode = document.getNextText(startNode); | |
selection = selection.collapseToStartOf(nextNode); | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Split the inline nodes at the current selection. | |
* | |
* @return {State} state | |
*/ | |
}, { | |
key: 'splitInline', | |
value: function splitInline() { | |
var state = this; | |
var _state19 = state; | |
var document = _state19.document; | |
var selection = _state19.selection; | |
// Split the document. | |
document = document.splitInlineAtRange(selection); | |
// Determine what the selection should be after splitting. | |
var _selection4 = selection; | |
var startKey = _selection4.startKey; | |
var inlineParent = document.getClosestInline(startKey); | |
if (inlineParent) { | |
var startNode = document.getDescendant(startKey); | |
var nextNode = document.getNextText(startNode); | |
selection = selection.collapseToStartOf(nextNode); | |
} | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Remove a `mark` from the characters in the current selection. | |
* | |
* @param {Mark} mark | |
* @return {State} state | |
*/ | |
}, { | |
key: 'removeMark', | |
value: function removeMark(mark) { | |
var state = this; | |
var _state20 = state; | |
var cursorMarks = _state20.cursorMarks; | |
var document = _state20.document; | |
var selection = _state20.selection; | |
// If the selection is collapsed, remove the mark from the cursor instead. | |
if (selection.isCollapsed) { | |
if (typeof mark == 'string') mark = new Mark({ type: mark }); | |
var marks = document.getMarksAtRange(selection); | |
state = state.merge({ cursorMarks: marks.remove(mark) }); | |
return state; | |
} | |
document = document.removeMarkAtRange(selection, mark); | |
state = state.merge({ document: document }); | |
return state; | |
} | |
/** | |
* Wrap the block nodes in the current selection in new nodes of `type`. | |
* | |
* @param {String} type | |
* @param {Data} data (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'wrapBlock', | |
value: function wrapBlock(type, data) { | |
var state = this; | |
var _state21 = state; | |
var document = _state21.document; | |
var selection = _state21.selection; | |
document = document.wrapBlockAtRange(selection, type, data); | |
state = state.merge({ document: document }); | |
return state; | |
} | |
/** | |
* Unwrap the current selection from a block parent of `type`. | |
* | |
* @param {String} type (optional) | |
* @param {Data} data (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'unwrapBlock', | |
value: function unwrapBlock(type, data) { | |
var state = this; | |
var _state22 = state; | |
var document = _state22.document; | |
var selection = _state22.selection; | |
document = document.unwrapBlockAtRange(selection, type, data); | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Wrap the current selection in new inline nodes of `type`. | |
* | |
* @param {String} type | |
* @param {Data} data (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'wrapInline', | |
value: function wrapInline(type, data) { | |
var state = this; | |
var _state23 = state; | |
var document = _state23.document; | |
var selection = _state23.selection; | |
document = document.wrapInlineAtRange(selection, type, data); | |
// Determine what the selection should be after wrapping. | |
if (selection.isCollapsed) { | |
selection = selection; | |
} else if (selection.startOffset == 0) { | |
var text = document.getDescendant(selection.startKey); | |
selection = selection.moveToRangeOf(text); | |
selection = selection.normalize(document); | |
} else { | |
var _text = document.getNextText(selection.startKey); | |
selection = selection.moveToRangeOf(_text); | |
selection = selection.normalize(document); | |
} | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
/** | |
* Unwrap the current selection from an inline parent of `type`. | |
* | |
* @param {String} type (optional) | |
* @param {Data} data (optional) | |
* @return {State} state | |
*/ | |
}, { | |
key: 'unwrapInline', | |
value: function unwrapInline(type, data) { | |
var state = this; | |
var _state24 = state; | |
var document = _state24.document; | |
var selection = _state24.selection; | |
document = document.unwrapInlineAtRange(selection, type, data); | |
state = state.merge({ document: document, selection: selection }); | |
return state; | |
} | |
}, { | |
key: 'kind', | |
/** | |
* Get the kind. | |
* | |
* @return {String} kind | |
*/ | |
get: function get() { | |
return 'state'; | |
} | |
/** | |
* Is the current selection blurred? | |
* | |
* @return {Boolean} isBlurred | |
*/ | |
}, { | |
key: 'isBlurred', | |
get: function get() { | |
return this.selection.isBlurred; | |
} | |
/** | |
* Is the current selection focused? | |
* | |
* @return {Boolean} isFocused | |
*/ | |
}, { | |
key: 'isFocused', | |
get: function get() { | |
return this.selection.isFocused; | |
} | |
/** | |
* Is the current selection collapsed? | |
* | |
* @return {Boolean} isCollapsed | |
*/ | |
}, { | |
key: 'isCollapsed', | |
get: function get() { | |
return this.selection.isCollapsed; | |
} | |
/** | |
* Is the current selection expanded? | |
* | |
* @return {Boolean} isExpanded | |
*/ | |
}, { | |
key: 'isExpanded', | |
get: function get() { | |
return this.selection.isExpanded; | |
} | |
/** | |
* Is the current selection backward? | |
* | |
* @return {Boolean} isBackward | |
*/ | |
}, { | |
key: 'isBackward', | |
get: function get() { | |
return this.selection.isBackward; | |
} | |
/** | |
* Is the current selection forward? | |
* | |
* @return {Boolean} isForward | |
*/ | |
}, { | |
key: 'isForward', | |
get: function get() { | |
return this.selection.isForward; | |
} | |
/** | |
* Get the current start key. | |
* | |
* @return {String} startKey | |
*/ | |
}, { | |
key: 'startKey', | |
get: function get() { | |
return this.selection.startKey; | |
} | |
/** | |
* Get the current end key. | |
* | |
* @return {String} endKey | |
*/ | |
}, { | |
key: 'endKey', | |
get: function get() { | |
return this.selection.endKey; | |
} | |
/** | |
* Get the current start offset. | |
* | |
* @return {String} startOffset | |
*/ | |
}, { | |
key: 'startOffset', | |
get: function get() { | |
return this.selection.startOffset; | |
} | |
/** | |
* Get the current end offset. | |
* | |
* @return {String} endOffset | |
*/ | |
}, { | |
key: 'endOffset', | |
get: function get() { | |
return this.selection.endOffset; | |
} | |
/** | |
* Get the current anchor key. | |
* | |
* @return {String} anchorKey | |
*/ | |
}, { | |
key: 'anchorKey', | |
get: function get() { | |
return this.selection.anchorKey; | |
} | |
/** | |
* Get the current focus key. | |
* | |
* @return {String} focusKey | |
*/ | |
}, { | |
key: 'focusKey', | |
get: function get() { | |
return this.selection.focusKey; | |
} | |
/** | |
* Get the current anchor offset. | |
* | |
* @return {String} anchorOffset | |
*/ | |
}, { | |
key: 'anchorOffset', | |
get: function get() { | |
return this.selection.anchorOffset; | |
} | |
/** | |
* Get the current focus offset. | |
* | |
* @return {String} focusOffset | |
*/ | |
}, { | |
key: 'focusOffset', | |
get: function get() { | |
return this.selection.focusOffset; | |
} | |
/** | |
* Get the current start text node. | |
* | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'startText', | |
get: function get() { | |
return this.document.getDescendant(this.selection.startKey); | |
} | |
/** | |
* Get the current end node. | |
* | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'endText', | |
get: function get() { | |
return this.document.getDescendant(this.selection.endKey); | |
} | |
/** | |
* Get the current anchor node. | |
* | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'anchorText', | |
get: function get() { | |
return this.document.getDescendant(this.selection.anchorKey); | |
} | |
/** | |
* Get the current focus node. | |
* | |
* @return {Text} text | |
*/ | |
}, { | |
key: 'focusText', | |
get: function get() { | |
return this.document.getDescendant(this.selection.focusKey); | |
} | |
/** | |
* Get the current start text node's closest block parent. | |
* | |
* @return {Block} block | |
*/ | |
}, { | |
key: 'startBlock', | |
get: function get() { | |
return this.document.getClosestBlock(this.selection.startKey); | |
} | |
/** | |
* Get the current end text node's closest block parent. | |
* | |
* @return {Block} block | |
*/ | |
}, { | |
key: 'endBlock', | |
get: function get() { | |
return this.document.getClosestBlock(this.selection.endKey); | |
} | |
/** | |
* Get the current anchor text node's closest block parent. | |
* | |
* @return {Block} block | |
*/ | |
}, { | |
key: 'anchorBlock', | |
get: function get() { | |
return this.document.getClosestBlock(this.selection.anchorKey); | |
} | |
/** | |
* Get the current focus text node's closest block parent. | |
* | |
* @return {Block} block | |
*/ | |
}, { | |
key: 'focusBlock', | |
get: function get() { | |
return this.document.getClosestBlock(this.selection.focusKey); | |
} | |
/** | |
* Get the characters in the current selection. | |
* | |
* @return {List} characters | |
*/ | |
}, { | |
key: 'characters', | |
get: function get() { | |
return this.document.getCharactersAtRange(this.selection); | |
} | |
/** | |
* Get the marks of the current selection. | |
* | |
* @return {Set} marks | |
*/ | |
}, { | |
key: 'marks', | |
get: function get() { | |
return this.cursorMarks || this.document.getMarksAtRange(this.selection); | |
} | |
/** | |
* Get the block nodes in the current selection. | |
* | |
* @return {List} nodes | |
*/ | |
}, { | |
key: 'blocks', | |
get: function get() { | |
return this.document.getBlocksAtRange(this.selection); | |
} | |
/** | |
* Get the fragment of the current selection. | |
* | |
* @return {List} nodes | |
*/ | |
}, { | |
key: 'fragment', | |
get: function get() { | |
return this.document.getFragmentAtRange(this.selection); | |
} | |
/** | |
* Get the inline nodes in the current selection. | |
* | |
* @return {List} nodes | |
*/ | |
}, { | |
key: 'inlines', | |
get: function get() { | |
return this.document.getInlinesAtRange(this.selection); | |
} | |
/** | |
* Get the text nodes in the current selection. | |
* | |
* @return {List} nodes | |
*/ | |
}, { | |
key: 'texts', | |
get: function get() { | |
return this.document.getTextsAtRange(this.selection); | |
} | |
}], [{ | |
key: 'create', | |
/** | |
* Create a new `State` with `properties`. | |
* | |
* @param {Object} properties | |
* @return {State} state | |
*/ | |
value: function create() { | |
var properties = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | |
if (properties instanceof State) return properties; | |
properties.document = Document.create(properties.document); | |
properties.selection = Selection.create(properties.selection).normalize(properties.document); | |
return new State(properties); | |
} | |
}]); | |
return State; | |
}(new Record(DEFAULTS$6)); | |
/** | |
* Range. | |
*/ | |
var Range$1 = new Record({ | |
kind: 'range', | |
marks: new Set(), | |
text: '' | |
}); | |
/** | |
* Group a list of `characters` into ranges by the marks they have. | |
* | |
* @param {List} characters | |
* @return {List} ranges | |
*/ | |
function groupByMarks(characters) { | |
if (characters.size == 0) { | |
var ranges = new List(); | |
ranges = ranges.push(new Range$1()); | |
return ranges; | |
} | |
return characters.toList().reduce(function (ranges, char, i) { | |
var marks = char.marks; | |
var text = char.text; | |
// The first one can always just be created. | |
if (i == 0) { | |
return ranges.push(new Range$1({ text: text, marks: marks })); | |
} | |
// Otherwise, compare to the previous and see if a new range should be | |
// created, or whether the text should be added to the previous range. | |
var previous = characters.get(i - 1); | |
var prevMarks = previous.marks; | |
var added = marks.filterNot(function (mark) { | |
return prevMarks.includes(mark); | |
}); | |
var removed = prevMarks.filterNot(function (mark) { | |
return marks.includes(mark); | |
}); | |
var isSame = !added.size && !removed.size; | |
// If the marks are the same, add the text to the previous range. | |
if (isSame) { | |
var index = ranges.size - 1; | |
var prevRange = ranges.get(index); | |
var prevText = prevRange.get('text'); | |
prevRange = prevRange.set('text', prevText += text); | |
return ranges.set(index, prevRange); | |
} | |
// Otherwise, create a new range. | |
return ranges.push(new Range$1({ text: text, marks: marks })); | |
}, new List()); | |
} | |
/** | |
* Serialize a `state`. | |
* | |
* @param {State} state | |
* @return {Object} object | |
*/ | |
function serialize(state) { | |
return serializeNode(state.document); | |
} | |
/** | |
* Serialize a `node`. | |
* | |
* @param {Node} node | |
* @return {Object} object | |
*/ | |
function serializeNode(node) { | |
switch (node.kind) { | |
case 'document': | |
{ | |
return { | |
nodes: node.nodes.toArray().map(function (child) { | |
return serializeNode(child); | |
}) | |
}; | |
} | |
case 'text': | |
{ | |
return { | |
kind: node.kind, | |
ranges: serializeCharacters(node.characters) | |
}; | |
} | |
case 'block': | |
case 'inline': | |
{ | |
var obj = {}; | |
obj.kind = node.kind; | |
obj.type = node.type; | |
obj.nodes = node.nodes.toArray().map(function (child) { | |
return serializeNode(child); | |
}); | |
if (node.isVoid) obj.isVoid = node.isVoid; | |
if (node.data.size) obj.data = node.data.toJSON(); | |
return obj; | |
} | |
default: | |
{ | |
throw new Error('Unknown node kind "' + node.kind + '".'); | |
} | |
} | |
} | |
/** | |
* Serialize a list of `characters`. | |
* | |
* @param {List} characters | |
* @return {Array} | |
*/ | |
function serializeCharacters(characters) { | |
return groupByMarks(characters).toArray().map(function (range) { | |
var obj = {}; | |
obj.text = range.text; | |
if (range.marks.size) obj.marks = range.marks.toArray().map(serializeMark); | |
return obj; | |
}); | |
} | |
/** | |
* Serialize a `mark`. | |
* | |
* @param {Mark} mark | |
* @return {Object} Object | |
*/ | |
function serializeMark(mark) { | |
var obj = {}; | |
obj.type = mark.type; | |
if (mark.data.size) obj.data = mark.data.toJSON(); | |
return obj; | |
} | |
/** | |
* Deserialize a state JSON `object`. | |
* | |
* @param {Object} object | |
* @return {State} state | |
*/ | |
function deserialize(object) { | |
return State.create({ | |
document: Document.create({ | |
nodes: Block.createList(object.nodes.map(deserializeNode)) | |
}) | |
}); | |
} | |
/** | |
* Deserialize a node JSON `object`. | |
* | |
* @param {Object} object | |
* @return {Node} node | |
*/ | |
function deserializeNode(object) { | |
switch (object.kind) { | |
case 'block': | |
{ | |
return Block.create({ | |
type: object.type, | |
data: object.data, | |
isVoid: object.isVoid, | |
nodes: Block.createList((object.nodes || []).map(deserializeNode)) | |
}); | |
} | |
case 'inline': | |
{ | |
return Inline.create({ | |
type: object.type, | |
data: object.data, | |
isVoid: object.isVoid, | |
nodes: Inline.createList((object.nodes || []).map(deserializeNode)) | |
}); | |
} | |
case 'text': | |
{ | |
return Text.create({ | |
characters: object.ranges ? deserializeRanges(object.ranges) : '' | |
}); | |
} | |
default: | |
{ | |
throw new Error('Unknown node kind "' + object.kind + '".'); | |
} | |
} | |
} | |
/** | |
* Deserialize a JSON `array` of ranges. | |
* | |
* @param {Array} array | |
* @return {List} characters | |
*/ | |
function deserializeRanges(array) { | |
return array.reduce(function (characters, object) { | |
var marks = object.marks || []; | |
var chars = object.text.split('').map(function (char) { | |
return Character.create({ | |
text: char, | |
marks: Mark.createSet(marks.map(deserializeMark)) | |
}); | |
}); | |
return characters.push.apply(characters, toConsumableArray(chars)); | |
}, Character.createList()); | |
} | |
/** | |
* Deserialize a mark JSON `object`. | |
* | |
* @param {Object} object | |
* @return {Mark} mark | |
*/ | |
function deserializeMark(object) { | |
return Mark.create(object); | |
} | |
/** | |
* Export. | |
*/ | |
var Raw = { | |
serialize: serialize, | |
serializeCharacters: serializeCharacters, | |
serializeMark: serializeMark, | |
serializeNode: serializeNode, | |
deserialize: deserialize, | |
deserializeNode: deserializeNode, | |
deserializeRanges: deserializeRanges | |
}; | |
var index$2 = createCommonjsModule(function (module) { | |
'use strict'; | |
/* eslint-disable no-unused-vars */ | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
var propIsEnumerable = Object.prototype.propertyIsEnumerable; | |
function toObject(val) { | |
if (val === null || val === undefined) { | |
throw new TypeError('Object.assign cannot be called with null or undefined'); | |
} | |
return Object(val); | |
} | |
function shouldUseNative() { | |
try { | |
if (!Object.assign) { | |
return false; | |
} | |
// Detect buggy property enumeration order in older V8 versions. | |
// https://bugs.chromium.org/p/v8/issues/detail?id=4118 | |
var test1 = new String('abc'); // eslint-disable-line | |
test1[5] = 'de'; | |
if (Object.getOwnPropertyNames(test1)[0] === '5') { | |
return false; | |
} | |
// https://bugs.chromium.org/p/v8/issues/detail?id=3056 | |
var test2 = {}; | |
for (var i = 0; i < 10; i++) { | |
test2['_' + String.fromCharCode(i)] = i; | |
} | |
var order2 = Object.getOwnPropertyNames(test2).map(function (n) { | |
return test2[n]; | |
}); | |
if (order2.join('') !== '0123456789') { | |
return false; | |
} | |
// https://bugs.chromium.org/p/v8/issues/detail?id=3056 | |
var test3 = {}; | |
'abcdefghijklmnopqrst'.split('').forEach(function (letter) { | |
test3[letter] = letter; | |
}); | |
if (Object.keys(Object.assign({}, test3)).join('') !== | |
'abcdefghijklmnopqrst') { | |
return false; | |
} | |
return true; | |
} catch (e) { | |
// We don't expect any of the above to throw, but better to be safe. | |
return false; | |
} | |
} | |
module.exports = shouldUseNative() ? Object.assign : function (target, source) { | |
var from; | |
var to = toObject(target); | |
var symbols; | |
for (var s = 1; s < arguments.length; s++) { | |
from = Object(arguments[s]); | |
for (var key in from) { | |
if (hasOwnProperty.call(from, key)) { | |
to[key] = from[key]; | |
} | |
} | |
if (Object.getOwnPropertySymbols) { | |
symbols = Object.getOwnPropertySymbols(from); | |
for (var i = 0; i < symbols.length; i++) { | |
if (propIsEnumerable.call(from, symbols[i])) { | |
to[symbols[i]] = from[symbols[i]]; | |
} | |
} | |
} | |
} | |
return to; | |
}; | |
}); | |
var index$3 = interopDefault(index$2); | |
var require$$7 = Object.freeze({ | |
default: index$3 | |
}); | |
var reactProdInvariant = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule reactProdInvariant | |
* | |
*/ | |
'use strict'; | |
/** | |
* WARNING: DO NOT manually require this module. | |
* This is a replacement for `invariant(...)` used by the error code system | |
* and will _only_ be required by the corresponding babel pass. | |
* It always throws. | |
*/ | |
function reactProdInvariant(code) { | |
var argCount = arguments.length - 1; | |
var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; | |
for (var argIdx = 0; argIdx < argCount; argIdx++) { | |
message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); | |
} | |
message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; | |
var error = new Error(message); | |
error.name = 'Invariant Violation'; | |
error.framesToPop = 1; // we don't care about reactProdInvariant's own frame | |
throw error; | |
} | |
module.exports = reactProdInvariant; | |
}); | |
var reactProdInvariant$1 = interopDefault(reactProdInvariant); | |
var require$$12 = Object.freeze({ | |
default: reactProdInvariant$1 | |
}); | |
var invariant = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
/** | |
* Use invariant() to assert state which your program assumes to be true. | |
* | |
* Provide sprintf-style format (only %s is supported) and arguments | |
* to provide information about what broke and what you were | |
* expecting. | |
* | |
* The invariant message will be stripped in production, but the invariant | |
* will remain to ensure logic does not differ in production. | |
*/ | |
function invariant(condition, format, a, b, c, d, e, f) { | |
if ("development" !== 'production') { | |
if (format === undefined) { | |
throw new Error('invariant requires an error message argument'); | |
} | |
} | |
if (!condition) { | |
var error; | |
if (format === undefined) { | |
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); | |
} else { | |
var args = [a, b, c, d, e, f]; | |
var argIndex = 0; | |
error = new Error(format.replace(/%s/g, function () { | |
return args[argIndex++]; | |
})); | |
error.name = 'Invariant Violation'; | |
} | |
error.framesToPop = 1; // we don't care about invariant's own frame | |
throw error; | |
} | |
} | |
module.exports = invariant; | |
}); | |
var invariant$1 = interopDefault(invariant); | |
var require$$0$33 = Object.freeze({ | |
default: invariant$1 | |
}); | |
var PooledClass = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule PooledClass | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Static poolers. Several custom versions for each potential number of | |
* arguments. A completely generic pooler is easy to implement, but would | |
* require accessing the `arguments` object. In each of these, `this` refers to | |
* the Class itself, not an instance. If any others are needed, simply add them | |
* here, or in their own files. | |
*/ | |
var oneArgumentPooler = function (copyFieldsFrom) { | |
var Klass = this; | |
if (Klass.instancePool.length) { | |
var instance = Klass.instancePool.pop(); | |
Klass.call(instance, copyFieldsFrom); | |
return instance; | |
} else { | |
return new Klass(copyFieldsFrom); | |
} | |
}; | |
var twoArgumentPooler = function (a1, a2) { | |
var Klass = this; | |
if (Klass.instancePool.length) { | |
var instance = Klass.instancePool.pop(); | |
Klass.call(instance, a1, a2); | |
return instance; | |
} else { | |
return new Klass(a1, a2); | |
} | |
}; | |
var threeArgumentPooler = function (a1, a2, a3) { | |
var Klass = this; | |
if (Klass.instancePool.length) { | |
var instance = Klass.instancePool.pop(); | |
Klass.call(instance, a1, a2, a3); | |
return instance; | |
} else { | |
return new Klass(a1, a2, a3); | |
} | |
}; | |
var fourArgumentPooler = function (a1, a2, a3, a4) { | |
var Klass = this; | |
if (Klass.instancePool.length) { | |
var instance = Klass.instancePool.pop(); | |
Klass.call(instance, a1, a2, a3, a4); | |
return instance; | |
} else { | |
return new Klass(a1, a2, a3, a4); | |
} | |
}; | |
var fiveArgumentPooler = function (a1, a2, a3, a4, a5) { | |
var Klass = this; | |
if (Klass.instancePool.length) { | |
var instance = Klass.instancePool.pop(); | |
Klass.call(instance, a1, a2, a3, a4, a5); | |
return instance; | |
} else { | |
return new Klass(a1, a2, a3, a4, a5); | |
} | |
}; | |
var standardReleaser = function (instance) { | |
var Klass = this; | |
!(instance instanceof Klass) ? invariant(false, 'Trying to release an instance into a pool of a different type.') : void 0; | |
instance.destructor(); | |
if (Klass.instancePool.length < Klass.poolSize) { | |
Klass.instancePool.push(instance); | |
} | |
}; | |
var DEFAULT_POOL_SIZE = 10; | |
var DEFAULT_POOLER = oneArgumentPooler; | |
/** | |
* Augments `CopyConstructor` to be a poolable class, augmenting only the class | |
* itself (statically) not adding any prototypical fields. Any CopyConstructor | |
* you give this may have a `poolSize` property, and will look for a | |
* prototypical `destructor` on instances. | |
* | |
* @param {Function} CopyConstructor Constructor that can be used to reset. | |
* @param {Function} pooler Customizable pooler. | |
*/ | |
var addPoolingTo = function (CopyConstructor, pooler) { | |
var NewKlass = CopyConstructor; | |
NewKlass.instancePool = []; | |
NewKlass.getPooled = pooler || DEFAULT_POOLER; | |
if (!NewKlass.poolSize) { | |
NewKlass.poolSize = DEFAULT_POOL_SIZE; | |
} | |
NewKlass.release = standardReleaser; | |
return NewKlass; | |
}; | |
var PooledClass = { | |
addPoolingTo: addPoolingTo, | |
oneArgumentPooler: oneArgumentPooler, | |
twoArgumentPooler: twoArgumentPooler, | |
threeArgumentPooler: threeArgumentPooler, | |
fourArgumentPooler: fourArgumentPooler, | |
fiveArgumentPooler: fiveArgumentPooler | |
}; | |
module.exports = PooledClass; | |
}); | |
var PooledClass$1 = interopDefault(PooledClass); | |
var require$$5$2 = Object.freeze({ | |
default: PooledClass$1 | |
}); | |
var ReactCurrentOwner = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactCurrentOwner | |
*/ | |
'use strict'; | |
/** | |
* Keeps track of the current owner. | |
* | |
* The current owner is the component who should own any components that are | |
* currently being constructed. | |
*/ | |
var ReactCurrentOwner = { | |
/** | |
* @internal | |
* @type {ReactComponent} | |
*/ | |
current: null | |
}; | |
module.exports = ReactCurrentOwner; | |
}); | |
var ReactCurrentOwner$1 = interopDefault(ReactCurrentOwner); | |
var require$$5$3 = Object.freeze({ | |
default: ReactCurrentOwner$1 | |
}); | |
var emptyFunction = createCommonjsModule(function (module) { | |
"use strict"; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* | |
*/ | |
function makeEmptyFunction(arg) { | |
return function () { | |
return arg; | |
}; | |
} | |
/** | |
* This function accepts and discards inputs; it has no side effects. This is | |
* primarily useful idiomatically for overridable function endpoints which | |
* always need to be callable, since JS lacks a null-call idiom ala Cocoa. | |
*/ | |
var emptyFunction = function emptyFunction() {}; | |
emptyFunction.thatReturns = makeEmptyFunction; | |
emptyFunction.thatReturnsFalse = makeEmptyFunction(false); | |
emptyFunction.thatReturnsTrue = makeEmptyFunction(true); | |
emptyFunction.thatReturnsNull = makeEmptyFunction(null); | |
emptyFunction.thatReturnsThis = function () { | |
return this; | |
}; | |
emptyFunction.thatReturnsArgument = function (arg) { | |
return arg; | |
}; | |
module.exports = emptyFunction; | |
}); | |
var emptyFunction$1 = interopDefault(emptyFunction); | |
var require$$3$10 = Object.freeze({ | |
default: emptyFunction$1 | |
}); | |
var warning = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2014-2015, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
var emptyFunction = interopDefault(require$$3$10); | |
/** | |
* Similar to invariant but only logs a warning if the condition is not met. | |
* This can be used to log issues in development environments in critical | |
* paths. Removing the logging code for production environments will keep the | |
* same logic and follow the same code paths. | |
*/ | |
var warning = emptyFunction; | |
if ("development" !== 'production') { | |
warning = function warning(condition, format) { | |
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | |
args[_key - 2] = arguments[_key]; | |
} | |
if (format === undefined) { | |
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); | |
} | |
if (format.indexOf('Failed Composite propType: ') === 0) { | |
return; // Ignore CompositeComponent proptype check. | |
} | |
if (!condition) { | |
var argIndex = 0; | |
var message = 'Warning: ' + format.replace(/%s/g, function () { | |
return args[argIndex++]; | |
}); | |
if (typeof console !== 'undefined') { | |
console.error(message); | |
} | |
try { | |
// --- Welcome to debugging React --- | |
// This error was thrown as a convenience so that you can use this stack | |
// to find the callsite that caused this warning to fire. | |
throw new Error(message); | |
} catch (x) {} | |
} | |
}; | |
} | |
module.exports = warning; | |
}); | |
var warning$1 = interopDefault(warning); | |
var require$$0$34 = Object.freeze({ | |
default: warning$1 | |
}); | |
var canDefineProperty = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule canDefineProperty | |
*/ | |
'use strict'; | |
var canDefineProperty = false; | |
if ("development" !== 'production') { | |
try { | |
Object.defineProperty({}, 'x', { get: function () {} }); | |
canDefineProperty = true; | |
} catch (x) { | |
// IE will fail on defineProperty | |
} | |
} | |
module.exports = canDefineProperty; | |
}); | |
var canDefineProperty$1 = interopDefault(canDefineProperty); | |
var require$$2$13 = Object.freeze({ | |
default: canDefineProperty$1 | |
}); | |
var ReactElement = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2014-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactElement | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var ReactCurrentOwner = interopDefault(require$$5$3); | |
var warning = interopDefault(require$$0$34); | |
var canDefineProperty = interopDefault(require$$2$13); | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
// The Symbol used to tag the ReactElement type. If there is no native Symbol | |
// nor polyfill, then a plain number is used for performance. | |
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; | |
var RESERVED_PROPS = { | |
key: true, | |
ref: true, | |
__self: true, | |
__source: true | |
}; | |
var specialPropKeyWarningShown, specialPropRefWarningShown; | |
function hasValidRef(config) { | |
if ("development" !== 'production') { | |
if (hasOwnProperty.call(config, 'ref')) { | |
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get; | |
if (getter && getter.isReactWarning) { | |
return false; | |
} | |
} | |
} | |
return config.ref !== undefined; | |
} | |
function hasValidKey(config) { | |
if ("development" !== 'production') { | |
if (hasOwnProperty.call(config, 'key')) { | |
var getter = Object.getOwnPropertyDescriptor(config, 'key').get; | |
if (getter && getter.isReactWarning) { | |
return false; | |
} | |
} | |
} | |
return config.key !== undefined; | |
} | |
/** | |
* Factory method to create a new React element. This no longer adheres to | |
* the class pattern, so do not use new to call it. Also, no instanceof check | |
* will work. Instead test $$typeof field against Symbol.for('react.element') to check | |
* if something is a React Element. | |
* | |
* @param {*} type | |
* @param {*} key | |
* @param {string|object} ref | |
* @param {*} self A *temporary* helper to detect places where `this` is | |
* different from the `owner` when React.createElement is called, so that we | |
* can warn. We want to get rid of owner and replace string `ref`s with arrow | |
* functions, and as long as `this` and owner are the same, there will be no | |
* change in behavior. | |
* @param {*} source An annotation object (added by a transpiler or otherwise) | |
* indicating filename, line number, and/or other information. | |
* @param {*} owner | |
* @param {*} props | |
* @internal | |
*/ | |
var ReactElement = function (type, key, ref, self, source, owner, props) { | |
var element = { | |
// This tag allow us to uniquely identify this as a React Element | |
$$typeof: REACT_ELEMENT_TYPE, | |
// Built-in properties that belong on the element | |
type: type, | |
key: key, | |
ref: ref, | |
props: props, | |
// Record the component responsible for creating this element. | |
_owner: owner | |
}; | |
if ("development" !== 'production') { | |
// The validation flag is currently mutative. We put it on | |
// an external backing store so that we can freeze the whole object. | |
// This can be replaced with a WeakMap once they are implemented in | |
// commonly used development environments. | |
element._store = {}; | |
// To make comparing ReactElements easier for testing purposes, we make | |
// the validation flag non-enumerable (where possible, which should | |
// include every environment we run tests in), so the test framework | |
// ignores it. | |
if (canDefineProperty) { | |
Object.defineProperty(element._store, 'validated', { | |
configurable: false, | |
enumerable: false, | |
writable: true, | |
value: false | |
}); | |
// self and source are DEV only properties. | |
Object.defineProperty(element, '_self', { | |
configurable: false, | |
enumerable: false, | |
writable: false, | |
value: self | |
}); | |
// Two elements created in two different places should be considered | |
// equal for testing purposes and therefore we hide it from enumeration. | |
Object.defineProperty(element, '_source', { | |
configurable: false, | |
enumerable: false, | |
writable: false, | |
value: source | |
}); | |
} else { | |
element._store.validated = false; | |
element._self = self; | |
element._source = source; | |
} | |
if (Object.freeze) { | |
Object.freeze(element.props); | |
Object.freeze(element); | |
} | |
} | |
return element; | |
}; | |
/** | |
* Create and return a new ReactElement of the given type. | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.createelement | |
*/ | |
ReactElement.createElement = function (type, config, children) { | |
var propName; | |
// Reserved names are extracted | |
var props = {}; | |
var key = null; | |
var ref = null; | |
var self = null; | |
var source = null; | |
if (config != null) { | |
if ("development" !== 'production') { | |
warning( | |
/* eslint-disable no-proto */ | |
config.__proto__ == null || config.__proto__ === Object.prototype, | |
/* eslint-enable no-proto */ | |
'React.createElement(...): Expected props argument to be a plain object. ' + 'Properties defined in its prototype chain will be ignored.'); | |
} | |
if (hasValidRef(config)) { | |
ref = config.ref; | |
} | |
if (hasValidKey(config)) { | |
key = '' + config.key; | |
} | |
self = config.__self === undefined ? null : config.__self; | |
source = config.__source === undefined ? null : config.__source; | |
// Remaining properties are added to a new props object | |
for (propName in config) { | |
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { | |
props[propName] = config[propName]; | |
} | |
} | |
} | |
// Children can be more than one argument, and those are transferred onto | |
// the newly allocated props object. | |
var childrenLength = arguments.length - 2; | |
if (childrenLength === 1) { | |
props.children = children; | |
} else if (childrenLength > 1) { | |
var childArray = Array(childrenLength); | |
for (var i = 0; i < childrenLength; i++) { | |
childArray[i] = arguments[i + 2]; | |
} | |
props.children = childArray; | |
} | |
// Resolve default props | |
if (type && type.defaultProps) { | |
var defaultProps = type.defaultProps; | |
for (propName in defaultProps) { | |
if (props[propName] === undefined) { | |
props[propName] = defaultProps[propName]; | |
} | |
} | |
} | |
if ("development" !== 'production') { | |
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; | |
// Create dummy `key` and `ref` property to `props` to warn users against its use | |
var warnAboutAccessingKey = function () { | |
if (!specialPropKeyWarningShown) { | |
specialPropKeyWarningShown = true; | |
warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName); | |
} | |
return undefined; | |
}; | |
warnAboutAccessingKey.isReactWarning = true; | |
var warnAboutAccessingRef = function () { | |
if (!specialPropRefWarningShown) { | |
specialPropRefWarningShown = true; | |
warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName); | |
} | |
return undefined; | |
}; | |
warnAboutAccessingRef.isReactWarning = true; | |
if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) { | |
if (!props.hasOwnProperty('key')) { | |
Object.defineProperty(props, 'key', { | |
get: warnAboutAccessingKey, | |
configurable: true | |
}); | |
} | |
if (!props.hasOwnProperty('ref')) { | |
Object.defineProperty(props, 'ref', { | |
get: warnAboutAccessingRef, | |
configurable: true | |
}); | |
} | |
} | |
} | |
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); | |
}; | |
/** | |
* Return a function that produces ReactElements of a given type. | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory | |
*/ | |
ReactElement.createFactory = function (type) { | |
var factory = ReactElement.createElement.bind(null, type); | |
// Expose the type on the factory and the prototype so that it can be | |
// easily accessed on elements. E.g. `<Foo />.type === Foo`. | |
// This should not be named `constructor` since this may not be the function | |
// that created the element, and it may not even be a constructor. | |
// Legacy hook TODO: Warn if this is accessed | |
factory.type = type; | |
return factory; | |
}; | |
ReactElement.cloneAndReplaceKey = function (oldElement, newKey) { | |
var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props); | |
return newElement; | |
}; | |
/** | |
* Clone and return a new ReactElement using element as the starting point. | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement | |
*/ | |
ReactElement.cloneElement = function (element, config, children) { | |
var propName; | |
// Original props are copied | |
var props = _assign({}, element.props); | |
// Reserved names are extracted | |
var key = element.key; | |
var ref = element.ref; | |
// Self is preserved since the owner is preserved. | |
var self = element._self; | |
// Source is preserved since cloneElement is unlikely to be targeted by a | |
// transpiler, and the original source is probably a better indicator of the | |
// true owner. | |
var source = element._source; | |
// Owner will be preserved, unless ref is overridden | |
var owner = element._owner; | |
if (config != null) { | |
if ("development" !== 'production') { | |
warning( | |
/* eslint-disable no-proto */ | |
config.__proto__ == null || config.__proto__ === Object.prototype, | |
/* eslint-enable no-proto */ | |
'React.cloneElement(...): Expected props argument to be a plain object. ' + 'Properties defined in its prototype chain will be ignored.'); | |
} | |
if (hasValidRef(config)) { | |
// Silently steal the ref from the parent. | |
ref = config.ref; | |
owner = ReactCurrentOwner.current; | |
} | |
if (hasValidKey(config)) { | |
key = '' + config.key; | |
} | |
// Remaining properties override existing props | |
var defaultProps; | |
if (element.type && element.type.defaultProps) { | |
defaultProps = element.type.defaultProps; | |
} | |
for (propName in config) { | |
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { | |
if (config[propName] === undefined && defaultProps !== undefined) { | |
// Resolve default props | |
props[propName] = defaultProps[propName]; | |
} else { | |
props[propName] = config[propName]; | |
} | |
} | |
} | |
} | |
// Children can be more than one argument, and those are transferred onto | |
// the newly allocated props object. | |
var childrenLength = arguments.length - 2; | |
if (childrenLength === 1) { | |
props.children = children; | |
} else if (childrenLength > 1) { | |
var childArray = Array(childrenLength); | |
for (var i = 0; i < childrenLength; i++) { | |
childArray[i] = arguments[i + 2]; | |
} | |
props.children = childArray; | |
} | |
return ReactElement(element.type, key, ref, self, source, owner, props); | |
}; | |
/** | |
* Verifies the object is a ReactElement. | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement | |
* @param {?object} object | |
* @return {boolean} True if `object` is a valid component. | |
* @final | |
*/ | |
ReactElement.isValidElement = function (object) { | |
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; | |
}; | |
ReactElement.REACT_ELEMENT_TYPE = REACT_ELEMENT_TYPE; | |
module.exports = ReactElement; | |
}); | |
var ReactElement$1 = interopDefault(ReactElement); | |
var require$$9 = Object.freeze({ | |
default: ReactElement$1 | |
}); | |
var getIteratorFn = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule getIteratorFn | |
* | |
*/ | |
'use strict'; | |
/* global Symbol */ | |
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; | |
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. | |
/** | |
* Returns the iterator method function contained on the iterable object. | |
* | |
* Be sure to invoke the function with the iterable as context: | |
* | |
* var iteratorFn = getIteratorFn(myIterable); | |
* if (iteratorFn) { | |
* var iterator = iteratorFn.call(myIterable); | |
* ... | |
* } | |
* | |
* @param {?object} maybeIterable | |
* @return {?function} | |
*/ | |
function getIteratorFn(maybeIterable) { | |
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); | |
if (typeof iteratorFn === 'function') { | |
return iteratorFn; | |
} | |
} | |
module.exports = getIteratorFn; | |
}); | |
var getIteratorFn$1 = interopDefault(getIteratorFn); | |
var require$$0$35 = Object.freeze({ | |
default: getIteratorFn$1 | |
}); | |
var KeyEscapeUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule KeyEscapeUtils | |
* | |
*/ | |
'use strict'; | |
/** | |
* Escape and wrap key so it is safe to use as a reactid | |
* | |
* @param {string} key to be escaped. | |
* @return {string} the escaped key. | |
*/ | |
function escape(key) { | |
var escapeRegex = /[=:]/g; | |
var escaperLookup = { | |
'=': '=0', | |
':': '=2' | |
}; | |
var escapedString = ('' + key).replace(escapeRegex, function (match) { | |
return escaperLookup[match]; | |
}); | |
return '$' + escapedString; | |
} | |
/** | |
* Unescape and unwrap key for human-readable display | |
* | |
* @param {string} key to unescape. | |
* @return {string} the unescaped key. | |
*/ | |
function unescape(key) { | |
var unescapeRegex = /(=0|=2)/g; | |
var unescaperLookup = { | |
'=0': '=', | |
'=2': ':' | |
}; | |
var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); | |
return ('' + keySubstring).replace(unescapeRegex, function (match) { | |
return unescaperLookup[match]; | |
}); | |
} | |
var KeyEscapeUtils = { | |
escape: escape, | |
unescape: unescape | |
}; | |
module.exports = KeyEscapeUtils; | |
}); | |
var KeyEscapeUtils$1 = interopDefault(KeyEscapeUtils); | |
var require$$3$11 = Object.freeze({ | |
default: KeyEscapeUtils$1 | |
}); | |
var traverseAllChildren = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule traverseAllChildren | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactCurrentOwner = interopDefault(require$$5$3); | |
var ReactElement = interopDefault(require$$9); | |
var getIteratorFn = interopDefault(require$$0$35); | |
var invariant = interopDefault(require$$0$33); | |
var KeyEscapeUtils = interopDefault(require$$3$11); | |
var warning = interopDefault(require$$0$34); | |
var SEPARATOR = '.'; | |
var SUBSEPARATOR = ':'; | |
/** | |
* TODO: Test that a single child and an array with one item have the same key | |
* pattern. | |
*/ | |
var didWarnAboutMaps = false; | |
/** | |
* Generate a key string that identifies a component within a set. | |
* | |
* @param {*} component A component that could contain a manual key. | |
* @param {number} index Index that is used if a manual key is not provided. | |
* @return {string} | |
*/ | |
function getComponentKey(component, index) { | |
// Do some typechecking here since we call this blindly. We want to ensure | |
// that we don't block potential future ES APIs. | |
if (component && typeof component === 'object' && component.key != null) { | |
// Explicit key | |
return KeyEscapeUtils.escape(component.key); | |
} | |
// Implicit key determined by the index in the set | |
return index.toString(36); | |
} | |
/** | |
* @param {?*} children Children tree container. | |
* @param {!string} nameSoFar Name of the key path so far. | |
* @param {!function} callback Callback to invoke with each child found. | |
* @param {?*} traverseContext Used to pass information throughout the traversal | |
* process. | |
* @return {!number} The number of children in this subtree. | |
*/ | |
function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { | |
var type = typeof children; | |
if (type === 'undefined' || type === 'boolean') { | |
// All of the above are perceived as null. | |
children = null; | |
} | |
if (children === null || type === 'string' || type === 'number' || ReactElement.isValidElement(children)) { | |
callback(traverseContext, children, | |
// If it's the only child, treat the name as if it was wrapped in an array | |
// so that it's consistent if the number of children grows. | |
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); | |
return 1; | |
} | |
var child; | |
var nextName; | |
var subtreeCount = 0; // Count of children found in the current subtree. | |
var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; | |
if (Array.isArray(children)) { | |
for (var i = 0; i < children.length; i++) { | |
child = children[i]; | |
nextName = nextNamePrefix + getComponentKey(child, i); | |
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); | |
} | |
} else { | |
var iteratorFn = getIteratorFn(children); | |
if (iteratorFn) { | |
var iterator = iteratorFn.call(children); | |
var step; | |
if (iteratorFn !== children.entries) { | |
var ii = 0; | |
while (!(step = iterator.next()).done) { | |
child = step.value; | |
nextName = nextNamePrefix + getComponentKey(child, ii++); | |
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); | |
} | |
} else { | |
if ("development" !== 'production') { | |
warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.'); | |
didWarnAboutMaps = true; | |
} | |
// Iterator will provide entry [k,v] tuples rather than values. | |
while (!(step = iterator.next()).done) { | |
var entry = step.value; | |
if (entry) { | |
child = entry[1]; | |
nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); | |
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); | |
} | |
} | |
} | |
} else if (type === 'object') { | |
var addendum = ''; | |
if ("development" !== 'production') { | |
addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; | |
if (children._isReactElement) { | |
addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; | |
} | |
if (ReactCurrentOwner.current) { | |
var name = ReactCurrentOwner.current.getName(); | |
if (name) { | |
addendum += ' Check the render method of `' + name + '`.'; | |
} | |
} | |
} | |
var childrenString = String(children); | |
invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum); | |
} | |
} | |
return subtreeCount; | |
} | |
/** | |
* Traverses children that are typically specified as `props.children`, but | |
* might also be specified through attributes: | |
* | |
* - `traverseAllChildren(this.props.children, ...)` | |
* - `traverseAllChildren(this.props.leftPanelChildren, ...)` | |
* | |
* The `traverseContext` is an optional argument that is passed through the | |
* entire traversal. It can be used to store accumulations or anything else that | |
* the callback might find relevant. | |
* | |
* @param {?*} children Children tree object. | |
* @param {!function} callback To invoke upon traversing each child. | |
* @param {?*} traverseContext Context for traversal. | |
* @return {!number} The number of children in this subtree. | |
*/ | |
function traverseAllChildren(children, callback, traverseContext) { | |
if (children == null) { | |
return 0; | |
} | |
return traverseAllChildrenImpl(children, '', callback, traverseContext); | |
} | |
module.exports = traverseAllChildren; | |
}); | |
var traverseAllChildren$1 = interopDefault(traverseAllChildren); | |
var require$$2$14 = Object.freeze({ | |
default: traverseAllChildren$1 | |
}); | |
var ReactChildren = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactChildren | |
*/ | |
'use strict'; | |
var PooledClass = interopDefault(require$$5$2); | |
var ReactElement = interopDefault(require$$9); | |
var emptyFunction = interopDefault(require$$3$10); | |
var traverseAllChildren = interopDefault(require$$2$14); | |
var twoArgumentPooler = PooledClass.twoArgumentPooler; | |
var fourArgumentPooler = PooledClass.fourArgumentPooler; | |
var userProvidedKeyEscapeRegex = /\/+/g; | |
function escapeUserProvidedKey(text) { | |
return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/'); | |
} | |
/** | |
* PooledClass representing the bookkeeping associated with performing a child | |
* traversal. Allows avoiding binding callbacks. | |
* | |
* @constructor ForEachBookKeeping | |
* @param {!function} forEachFunction Function to perform traversal with. | |
* @param {?*} forEachContext Context to perform context with. | |
*/ | |
function ForEachBookKeeping(forEachFunction, forEachContext) { | |
this.func = forEachFunction; | |
this.context = forEachContext; | |
this.count = 0; | |
} | |
ForEachBookKeeping.prototype.destructor = function () { | |
this.func = null; | |
this.context = null; | |
this.count = 0; | |
}; | |
PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); | |
function forEachSingleChild(bookKeeping, child, name) { | |
var func = bookKeeping.func; | |
var context = bookKeeping.context; | |
func.call(context, child, bookKeeping.count++); | |
} | |
/** | |
* Iterates through children that are typically specified as `props.children`. | |
* | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.foreach | |
* | |
* The provided forEachFunc(child, index) will be called for each | |
* leaf child. | |
* | |
* @param {?*} children Children tree container. | |
* @param {function(*, int)} forEachFunc | |
* @param {*} forEachContext Context for forEachContext. | |
*/ | |
function forEachChildren(children, forEachFunc, forEachContext) { | |
if (children == null) { | |
return children; | |
} | |
var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); | |
traverseAllChildren(children, forEachSingleChild, traverseContext); | |
ForEachBookKeeping.release(traverseContext); | |
} | |
/** | |
* PooledClass representing the bookkeeping associated with performing a child | |
* mapping. Allows avoiding binding callbacks. | |
* | |
* @constructor MapBookKeeping | |
* @param {!*} mapResult Object containing the ordered map of results. | |
* @param {!function} mapFunction Function to perform mapping with. | |
* @param {?*} mapContext Context to perform mapping with. | |
*/ | |
function MapBookKeeping(mapResult, keyPrefix, mapFunction, mapContext) { | |
this.result = mapResult; | |
this.keyPrefix = keyPrefix; | |
this.func = mapFunction; | |
this.context = mapContext; | |
this.count = 0; | |
} | |
MapBookKeeping.prototype.destructor = function () { | |
this.result = null; | |
this.keyPrefix = null; | |
this.func = null; | |
this.context = null; | |
this.count = 0; | |
}; | |
PooledClass.addPoolingTo(MapBookKeeping, fourArgumentPooler); | |
function mapSingleChildIntoContext(bookKeeping, child, childKey) { | |
var result = bookKeeping.result; | |
var keyPrefix = bookKeeping.keyPrefix; | |
var func = bookKeeping.func; | |
var context = bookKeeping.context; | |
var mappedChild = func.call(context, child, bookKeeping.count++); | |
if (Array.isArray(mappedChild)) { | |
mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, emptyFunction.thatReturnsArgument); | |
} else if (mappedChild != null) { | |
if (ReactElement.isValidElement(mappedChild)) { | |
mappedChild = ReactElement.cloneAndReplaceKey(mappedChild, | |
// Keep both the (mapped) and old keys if they differ, just as | |
// traverseAllChildren used to do for objects as children | |
keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + '/' : '') + childKey); | |
} | |
result.push(mappedChild); | |
} | |
} | |
function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) { | |
var escapedPrefix = ''; | |
if (prefix != null) { | |
escapedPrefix = escapeUserProvidedKey(prefix) + '/'; | |
} | |
var traverseContext = MapBookKeeping.getPooled(array, escapedPrefix, func, context); | |
traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); | |
MapBookKeeping.release(traverseContext); | |
} | |
/** | |
* Maps children that are typically specified as `props.children`. | |
* | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.map | |
* | |
* The provided mapFunction(child, key, index) will be called for each | |
* leaf child. | |
* | |
* @param {?*} children Children tree container. | |
* @param {function(*, int)} func The map function. | |
* @param {*} context Context for mapFunction. | |
* @return {object} Object containing the ordered map of results. | |
*/ | |
function mapChildren(children, func, context) { | |
if (children == null) { | |
return children; | |
} | |
var result = []; | |
mapIntoWithKeyPrefixInternal(children, result, null, func, context); | |
return result; | |
} | |
function forEachSingleChildDummy(traverseContext, child, name) { | |
return null; | |
} | |
/** | |
* Count the number of children that are typically specified as | |
* `props.children`. | |
* | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.count | |
* | |
* @param {?*} children Children tree container. | |
* @return {number} The number of children. | |
*/ | |
function countChildren(children, context) { | |
return traverseAllChildren(children, forEachSingleChildDummy, null); | |
} | |
/** | |
* Flatten a children object (typically specified as `props.children`) and | |
* return an array with appropriately re-keyed children. | |
* | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.toarray | |
*/ | |
function toArray(children) { | |
var result = []; | |
mapIntoWithKeyPrefixInternal(children, result, null, emptyFunction.thatReturnsArgument); | |
return result; | |
} | |
var ReactChildren = { | |
forEach: forEachChildren, | |
map: mapChildren, | |
mapIntoWithKeyPrefixInternal: mapIntoWithKeyPrefixInternal, | |
count: countChildren, | |
toArray: toArray | |
}; | |
module.exports = ReactChildren; | |
}); | |
var ReactChildren$1 = interopDefault(ReactChildren); | |
var require$$3$9 = Object.freeze({ | |
default: ReactChildren$1 | |
}); | |
var ReactNoopUpdateQueue = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2015-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactNoopUpdateQueue | |
*/ | |
'use strict'; | |
var warning = interopDefault(require$$0$34); | |
function warnNoop(publicInstance, callerName) { | |
if ("development" !== 'production') { | |
var constructor = publicInstance.constructor; | |
warning(false, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass'); | |
} | |
} | |
/** | |
* This is the abstract API for an update queue. | |
*/ | |
var ReactNoopUpdateQueue = { | |
/** | |
* Checks whether or not this composite component is mounted. | |
* @param {ReactClass} publicInstance The instance we want to test. | |
* @return {boolean} True if mounted, false otherwise. | |
* @protected | |
* @final | |
*/ | |
isMounted: function (publicInstance) { | |
return false; | |
}, | |
/** | |
* Enqueue a callback that will be executed after all the pending updates | |
* have processed. | |
* | |
* @param {ReactClass} publicInstance The instance to use as `this` context. | |
* @param {?function} callback Called after state is updated. | |
* @internal | |
*/ | |
enqueueCallback: function (publicInstance, callback) {}, | |
/** | |
* Forces an update. This should only be invoked when it is known with | |
* certainty that we are **not** in a DOM transaction. | |
* | |
* You may want to call this when you know that some deeper aspect of the | |
* component's state has changed but `setState` was not called. | |
* | |
* This will not invoke `shouldComponentUpdate`, but it will invoke | |
* `componentWillUpdate` and `componentDidUpdate`. | |
* | |
* @param {ReactClass} publicInstance The instance that should rerender. | |
* @internal | |
*/ | |
enqueueForceUpdate: function (publicInstance) { | |
warnNoop(publicInstance, 'forceUpdate'); | |
}, | |
/** | |
* Replaces all of the state. Always use this or `setState` to mutate state. | |
* You should treat `this.state` as immutable. | |
* | |
* There is no guarantee that `this.state` will be immediately updated, so | |
* accessing `this.state` after calling this method may return the old value. | |
* | |
* @param {ReactClass} publicInstance The instance that should rerender. | |
* @param {object} completeState Next state. | |
* @internal | |
*/ | |
enqueueReplaceState: function (publicInstance, completeState) { | |
warnNoop(publicInstance, 'replaceState'); | |
}, | |
/** | |
* Sets a subset of the state. This only exists because _pendingState is | |
* internal. This provides a merging strategy that is not available to deep | |
* properties which is confusing. TODO: Expose pendingState or don't use it | |
* during the merge. | |
* | |
* @param {ReactClass} publicInstance The instance that should rerender. | |
* @param {object} partialState Next partial state to be merged with state. | |
* @internal | |
*/ | |
enqueueSetState: function (publicInstance, partialState) { | |
warnNoop(publicInstance, 'setState'); | |
} | |
}; | |
module.exports = ReactNoopUpdateQueue; | |
}); | |
var ReactNoopUpdateQueue$1 = interopDefault(ReactNoopUpdateQueue); | |
var require$$5$4 = Object.freeze({ | |
default: ReactNoopUpdateQueue$1 | |
}); | |
var emptyObject = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
var emptyObject = {}; | |
if ("development" !== 'production') { | |
Object.freeze(emptyObject); | |
} | |
module.exports = emptyObject; | |
}); | |
var emptyObject$1 = interopDefault(emptyObject); | |
var require$$2$15 = Object.freeze({ | |
default: emptyObject$1 | |
}); | |
var ReactComponent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactComponent | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactNoopUpdateQueue = interopDefault(require$$5$4); | |
var canDefineProperty = interopDefault(require$$2$13); | |
var emptyObject = interopDefault(require$$2$15); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
/** | |
* Base class helpers for the updating state of a component. | |
*/ | |
function ReactComponent(props, context, updater) { | |
this.props = props; | |
this.context = context; | |
this.refs = emptyObject; | |
// We initialize the default updater but the real one gets injected by the | |
// renderer. | |
this.updater = updater || ReactNoopUpdateQueue; | |
} | |
ReactComponent.prototype.isReactComponent = {}; | |
/** | |
* Sets a subset of the state. Always use this to mutate | |
* state. You should treat `this.state` as immutable. | |
* | |
* There is no guarantee that `this.state` will be immediately updated, so | |
* accessing `this.state` after calling this method may return the old value. | |
* | |
* There is no guarantee that calls to `setState` will run synchronously, | |
* as they may eventually be batched together. You can provide an optional | |
* callback that will be executed when the call to setState is actually | |
* completed. | |
* | |
* When a function is provided to setState, it will be called at some point in | |
* the future (not synchronously). It will be called with the up to date | |
* component arguments (state, props, context). These values can be different | |
* from this.* because your function may be called after receiveProps but before | |
* shouldComponentUpdate, and this new state, props, and context will not yet be | |
* assigned to this. | |
* | |
* @param {object|function} partialState Next partial state or function to | |
* produce next partial state to be merged with current state. | |
* @param {?function} callback Called after state is updated. | |
* @final | |
* @protected | |
*/ | |
ReactComponent.prototype.setState = function (partialState, callback) { | |
!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : void 0; | |
this.updater.enqueueSetState(this, partialState); | |
if (callback) { | |
this.updater.enqueueCallback(this, callback, 'setState'); | |
} | |
}; | |
/** | |
* Forces an update. This should only be invoked when it is known with | |
* certainty that we are **not** in a DOM transaction. | |
* | |
* You may want to call this when you know that some deeper aspect of the | |
* component's state has changed but `setState` was not called. | |
* | |
* This will not invoke `shouldComponentUpdate`, but it will invoke | |
* `componentWillUpdate` and `componentDidUpdate`. | |
* | |
* @param {?function} callback Called after update is complete. | |
* @final | |
* @protected | |
*/ | |
ReactComponent.prototype.forceUpdate = function (callback) { | |
this.updater.enqueueForceUpdate(this); | |
if (callback) { | |
this.updater.enqueueCallback(this, callback, 'forceUpdate'); | |
} | |
}; | |
/** | |
* Deprecated APIs. These APIs used to exist on classic React classes but since | |
* we would like to deprecate them, we're not going to move them over to this | |
* modern base class. Instead, we define a getter that warns if it's accessed. | |
*/ | |
if ("development" !== 'production') { | |
var deprecatedAPIs = { | |
isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'], | |
replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).'] | |
}; | |
var defineDeprecationWarning = function (methodName, info) { | |
if (canDefineProperty) { | |
Object.defineProperty(ReactComponent.prototype, methodName, { | |
get: function () { | |
warning(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]); | |
return undefined; | |
} | |
}); | |
} | |
}; | |
for (var fnName in deprecatedAPIs) { | |
if (deprecatedAPIs.hasOwnProperty(fnName)) { | |
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); | |
} | |
} | |
} | |
module.exports = ReactComponent; | |
}); | |
var ReactComponent$1 = interopDefault(ReactComponent); | |
var require$$9$1 = Object.freeze({ | |
default: ReactComponent$1 | |
}); | |
var keyMirror = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks static-only | |
*/ | |
'use strict'; | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Constructs an enumeration with keys equal to their value. | |
* | |
* For example: | |
* | |
* var COLORS = keyMirror({blue: null, red: null}); | |
* var myColor = COLORS.blue; | |
* var isColorValid = !!COLORS[myColor]; | |
* | |
* The last line could not be performed if the values of the generated enum were | |
* not equal to their keys. | |
* | |
* Input: {key1: val1, key2: val2} | |
* Output: {key1: key1, key2: key2} | |
* | |
* @param {object} obj | |
* @return {object} | |
*/ | |
var keyMirror = function keyMirror(obj) { | |
var ret = {}; | |
var key; | |
!(obj instanceof Object && !Array.isArray(obj)) ? invariant(false, 'keyMirror(...): Argument must be an object.') : void 0; | |
for (key in obj) { | |
if (!obj.hasOwnProperty(key)) { | |
continue; | |
} | |
ret[key] = key; | |
} | |
return ret; | |
}; | |
module.exports = keyMirror; | |
}); | |
var keyMirror$1 = interopDefault(keyMirror); | |
var require$$0$36 = Object.freeze({ | |
default: keyMirror$1 | |
}); | |
var ReactPropTypeLocations = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactPropTypeLocations | |
*/ | |
'use strict'; | |
var keyMirror = interopDefault(require$$0$36); | |
var ReactPropTypeLocations = keyMirror({ | |
prop: null, | |
context: null, | |
childContext: null | |
}); | |
module.exports = ReactPropTypeLocations; | |
}); | |
var ReactPropTypeLocations$1 = interopDefault(ReactPropTypeLocations); | |
var require$$6 = Object.freeze({ | |
default: ReactPropTypeLocations$1 | |
}); | |
var ReactPropTypeLocationNames = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactPropTypeLocationNames | |
*/ | |
'use strict'; | |
var ReactPropTypeLocationNames = {}; | |
if ("development" !== 'production') { | |
ReactPropTypeLocationNames = { | |
prop: 'prop', | |
context: 'context', | |
childContext: 'child context' | |
}; | |
} | |
module.exports = ReactPropTypeLocationNames; | |
}); | |
var ReactPropTypeLocationNames$1 = interopDefault(ReactPropTypeLocationNames); | |
var require$$2$16 = Object.freeze({ | |
default: ReactPropTypeLocationNames$1 | |
}); | |
var keyOf = createCommonjsModule(function (module) { | |
"use strict"; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
/** | |
* Allows extraction of a minified key. Let's the build system minify keys | |
* without losing the ability to dynamically use key strings as values | |
* themselves. Pass in an object with a single key/val pair and it will return | |
* you the string key of that single record. Suppose you want to grab the | |
* value for a key 'className' inside of an object. Key/val minification may | |
* have aliased that key to be 'xa12'. keyOf({className: null}) will return | |
* 'xa12' in that case. Resolve keys you want to use once at startup time, then | |
* reuse those resolutions. | |
*/ | |
var keyOf = function keyOf(oneKeyObj) { | |
var key; | |
for (key in oneKeyObj) { | |
if (!oneKeyObj.hasOwnProperty(key)) { | |
continue; | |
} | |
return key; | |
} | |
return null; | |
}; | |
module.exports = keyOf; | |
}); | |
var keyOf$1 = interopDefault(keyOf); | |
var require$$0$37 = Object.freeze({ | |
default: keyOf$1 | |
}); | |
var ReactClass = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactClass | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12), | |
_assign = interopDefault(require$$7); | |
var ReactComponent = interopDefault(require$$9$1); | |
var ReactElement = interopDefault(require$$9); | |
var ReactPropTypeLocations = interopDefault(require$$6); | |
var ReactPropTypeLocationNames = interopDefault(require$$2$16); | |
var ReactNoopUpdateQueue = interopDefault(require$$5$4); | |
var emptyObject = interopDefault(require$$2$15); | |
var invariant = interopDefault(require$$0$33); | |
var keyMirror = interopDefault(require$$0$36); | |
var keyOf = interopDefault(require$$0$37); | |
var warning = interopDefault(require$$0$34); | |
var MIXINS_KEY = keyOf({ mixins: null }); | |
/** | |
* Policies that describe methods in `ReactClassInterface`. | |
*/ | |
var SpecPolicy = keyMirror({ | |
/** | |
* These methods may be defined only once by the class specification or mixin. | |
*/ | |
DEFINE_ONCE: null, | |
/** | |
* These methods may be defined by both the class specification and mixins. | |
* Subsequent definitions will be chained. These methods must return void. | |
*/ | |
DEFINE_MANY: null, | |
/** | |
* These methods are overriding the base class. | |
*/ | |
OVERRIDE_BASE: null, | |
/** | |
* These methods are similar to DEFINE_MANY, except we assume they return | |
* objects. We try to merge the keys of the return values of all the mixed in | |
* functions. If there is a key conflict we throw. | |
*/ | |
DEFINE_MANY_MERGED: null | |
}); | |
var injectedMixins = []; | |
/** | |
* Composite components are higher-level components that compose other composite | |
* or host components. | |
* | |
* To create a new type of `ReactClass`, pass a specification of | |
* your new class to `React.createClass`. The only requirement of your class | |
* specification is that you implement a `render` method. | |
* | |
* var MyComponent = React.createClass({ | |
* render: function() { | |
* return <div>Hello World</div>; | |
* } | |
* }); | |
* | |
* The class specification supports a specific protocol of methods that have | |
* special meaning (e.g. `render`). See `ReactClassInterface` for | |
* more the comprehensive protocol. Any other properties and methods in the | |
* class specification will be available on the prototype. | |
* | |
* @interface ReactClassInterface | |
* @internal | |
*/ | |
var ReactClassInterface = { | |
/** | |
* An array of Mixin objects to include when defining your component. | |
* | |
* @type {array} | |
* @optional | |
*/ | |
mixins: SpecPolicy.DEFINE_MANY, | |
/** | |
* An object containing properties and methods that should be defined on | |
* the component's constructor instead of its prototype (static methods). | |
* | |
* @type {object} | |
* @optional | |
*/ | |
statics: SpecPolicy.DEFINE_MANY, | |
/** | |
* Definition of prop types for this component. | |
* | |
* @type {object} | |
* @optional | |
*/ | |
propTypes: SpecPolicy.DEFINE_MANY, | |
/** | |
* Definition of context types for this component. | |
* | |
* @type {object} | |
* @optional | |
*/ | |
contextTypes: SpecPolicy.DEFINE_MANY, | |
/** | |
* Definition of context types this component sets for its children. | |
* | |
* @type {object} | |
* @optional | |
*/ | |
childContextTypes: SpecPolicy.DEFINE_MANY, | |
// ==== Definition methods ==== | |
/** | |
* Invoked when the component is mounted. Values in the mapping will be set on | |
* `this.props` if that prop is not specified (i.e. using an `in` check). | |
* | |
* This method is invoked before `getInitialState` and therefore cannot rely | |
* on `this.state` or use `this.setState`. | |
* | |
* @return {object} | |
* @optional | |
*/ | |
getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, | |
/** | |
* Invoked once before the component is mounted. The return value will be used | |
* as the initial value of `this.state`. | |
* | |
* getInitialState: function() { | |
* return { | |
* isOn: false, | |
* fooBaz: new BazFoo() | |
* } | |
* } | |
* | |
* @return {object} | |
* @optional | |
*/ | |
getInitialState: SpecPolicy.DEFINE_MANY_MERGED, | |
/** | |
* @return {object} | |
* @optional | |
*/ | |
getChildContext: SpecPolicy.DEFINE_MANY_MERGED, | |
/** | |
* Uses props from `this.props` and state from `this.state` to render the | |
* structure of the component. | |
* | |
* No guarantees are made about when or how often this method is invoked, so | |
* it must not have side effects. | |
* | |
* render: function() { | |
* var name = this.props.name; | |
* return <div>Hello, {name}!</div>; | |
* } | |
* | |
* @return {ReactComponent} | |
* @nosideeffects | |
* @required | |
*/ | |
render: SpecPolicy.DEFINE_ONCE, | |
// ==== Delegate methods ==== | |
/** | |
* Invoked when the component is initially created and about to be mounted. | |
* This may have side effects, but any external subscriptions or data created | |
* by this method must be cleaned up in `componentWillUnmount`. | |
* | |
* @optional | |
*/ | |
componentWillMount: SpecPolicy.DEFINE_MANY, | |
/** | |
* Invoked when the component has been mounted and has a DOM representation. | |
* However, there is no guarantee that the DOM node is in the document. | |
* | |
* Use this as an opportunity to operate on the DOM when the component has | |
* been mounted (initialized and rendered) for the first time. | |
* | |
* @param {DOMElement} rootNode DOM element representing the component. | |
* @optional | |
*/ | |
componentDidMount: SpecPolicy.DEFINE_MANY, | |
/** | |
* Invoked before the component receives new props. | |
* | |
* Use this as an opportunity to react to a prop transition by updating the | |
* state using `this.setState`. Current props are accessed via `this.props`. | |
* | |
* componentWillReceiveProps: function(nextProps, nextContext) { | |
* this.setState({ | |
* likesIncreasing: nextProps.likeCount > this.props.likeCount | |
* }); | |
* } | |
* | |
* NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop | |
* transition may cause a state change, but the opposite is not true. If you | |
* need it, you are probably looking for `componentWillUpdate`. | |
* | |
* @param {object} nextProps | |
* @optional | |
*/ | |
componentWillReceiveProps: SpecPolicy.DEFINE_MANY, | |
/** | |
* Invoked while deciding if the component should be updated as a result of | |
* receiving new props, state and/or context. | |
* | |
* Use this as an opportunity to `return false` when you're certain that the | |
* transition to the new props/state/context will not require a component | |
* update. | |
* | |
* shouldComponentUpdate: function(nextProps, nextState, nextContext) { | |
* return !equal(nextProps, this.props) || | |
* !equal(nextState, this.state) || | |
* !equal(nextContext, this.context); | |
* } | |
* | |
* @param {object} nextProps | |
* @param {?object} nextState | |
* @param {?object} nextContext | |
* @return {boolean} True if the component should update. | |
* @optional | |
*/ | |
shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, | |
/** | |
* Invoked when the component is about to update due to a transition from | |
* `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` | |
* and `nextContext`. | |
* | |
* Use this as an opportunity to perform preparation before an update occurs. | |
* | |
* NOTE: You **cannot** use `this.setState()` in this method. | |
* | |
* @param {object} nextProps | |
* @param {?object} nextState | |
* @param {?object} nextContext | |
* @param {ReactReconcileTransaction} transaction | |
* @optional | |
*/ | |
componentWillUpdate: SpecPolicy.DEFINE_MANY, | |
/** | |
* Invoked when the component's DOM representation has been updated. | |
* | |
* Use this as an opportunity to operate on the DOM when the component has | |
* been updated. | |
* | |
* @param {object} prevProps | |
* @param {?object} prevState | |
* @param {?object} prevContext | |
* @param {DOMElement} rootNode DOM element representing the component. | |
* @optional | |
*/ | |
componentDidUpdate: SpecPolicy.DEFINE_MANY, | |
/** | |
* Invoked when the component is about to be removed from its parent and have | |
* its DOM representation destroyed. | |
* | |
* Use this as an opportunity to deallocate any external resources. | |
* | |
* NOTE: There is no `componentDidUnmount` since your component will have been | |
* destroyed by that point. | |
* | |
* @optional | |
*/ | |
componentWillUnmount: SpecPolicy.DEFINE_MANY, | |
// ==== Advanced methods ==== | |
/** | |
* Updates the component's currently mounted DOM representation. | |
* | |
* By default, this implements React's rendering and reconciliation algorithm. | |
* Sophisticated clients may wish to override this. | |
* | |
* @param {ReactReconcileTransaction} transaction | |
* @internal | |
* @overridable | |
*/ | |
updateComponent: SpecPolicy.OVERRIDE_BASE | |
}; | |
/** | |
* Mapping from class specification keys to special processing functions. | |
* | |
* Although these are declared like instance properties in the specification | |
* when defining classes using `React.createClass`, they are actually static | |
* and are accessible on the constructor instead of the prototype. Despite | |
* being static, they must be defined outside of the "statics" key under | |
* which all other static methods are defined. | |
*/ | |
var RESERVED_SPEC_KEYS = { | |
displayName: function (Constructor, displayName) { | |
Constructor.displayName = displayName; | |
}, | |
mixins: function (Constructor, mixins) { | |
if (mixins) { | |
for (var i = 0; i < mixins.length; i++) { | |
mixSpecIntoComponent(Constructor, mixins[i]); | |
} | |
} | |
}, | |
childContextTypes: function (Constructor, childContextTypes) { | |
if ("development" !== 'production') { | |
validateTypeDef(Constructor, childContextTypes, ReactPropTypeLocations.childContext); | |
} | |
Constructor.childContextTypes = _assign({}, Constructor.childContextTypes, childContextTypes); | |
}, | |
contextTypes: function (Constructor, contextTypes) { | |
if ("development" !== 'production') { | |
validateTypeDef(Constructor, contextTypes, ReactPropTypeLocations.context); | |
} | |
Constructor.contextTypes = _assign({}, Constructor.contextTypes, contextTypes); | |
}, | |
/** | |
* Special case getDefaultProps which should move into statics but requires | |
* automatic merging. | |
*/ | |
getDefaultProps: function (Constructor, getDefaultProps) { | |
if (Constructor.getDefaultProps) { | |
Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps); | |
} else { | |
Constructor.getDefaultProps = getDefaultProps; | |
} | |
}, | |
propTypes: function (Constructor, propTypes) { | |
if ("development" !== 'production') { | |
validateTypeDef(Constructor, propTypes, ReactPropTypeLocations.prop); | |
} | |
Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes); | |
}, | |
statics: function (Constructor, statics) { | |
mixStaticSpecIntoComponent(Constructor, statics); | |
}, | |
autobind: function () {} }; | |
// noop | |
function validateTypeDef(Constructor, typeDef, location) { | |
for (var propName in typeDef) { | |
if (typeDef.hasOwnProperty(propName)) { | |
// use a warning instead of an invariant so components | |
// don't show up in prod but only in __DEV__ | |
warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName); | |
} | |
} | |
} | |
function validateMethodOverride(isAlreadyDefined, name) { | |
var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null; | |
// Disallow overriding of base class methods unless explicitly allowed. | |
if (ReactClassMixin.hasOwnProperty(name)) { | |
!(specPolicy === SpecPolicy.OVERRIDE_BASE) ? invariant(false, 'ReactClassInterface: You are attempting to override `%s` from your class specification. Ensure that your method names do not overlap with React methods.', name) : void 0; | |
} | |
// Disallow defining methods more than once unless explicitly allowed. | |
if (isAlreadyDefined) { | |
!(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED) ? invariant(false, 'ReactClassInterface: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : void 0; | |
} | |
} | |
/** | |
* Mixin helper which handles policy validation and reserved | |
* specification keys when building React classes. | |
*/ | |
function mixSpecIntoComponent(Constructor, spec) { | |
if (!spec) { | |
return; | |
} | |
!(typeof spec !== 'function') ? invariant(false, 'ReactClass: You\'re attempting to use a component class or function as a mixin. Instead, just use a regular object.') : void 0; | |
!!ReactElement.isValidElement(spec) ? invariant(false, 'ReactClass: You\'re attempting to use a component as a mixin. Instead, just use a regular object.') : void 0; | |
var proto = Constructor.prototype; | |
var autoBindPairs = proto.__reactAutoBindPairs; | |
// By handling mixins before any other properties, we ensure the same | |
// chaining order is applied to methods with DEFINE_MANY policy, whether | |
// mixins are listed before or after these methods in the spec. | |
if (spec.hasOwnProperty(MIXINS_KEY)) { | |
RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); | |
} | |
for (var name in spec) { | |
if (!spec.hasOwnProperty(name)) { | |
continue; | |
} | |
if (name === MIXINS_KEY) { | |
// We have already handled mixins in a special case above. | |
continue; | |
} | |
var property = spec[name]; | |
var isAlreadyDefined = proto.hasOwnProperty(name); | |
validateMethodOverride(isAlreadyDefined, name); | |
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { | |
RESERVED_SPEC_KEYS[name](Constructor, property); | |
} else { | |
// Setup methods on prototype: | |
// The following member methods should not be automatically bound: | |
// 1. Expected ReactClass methods (in the "interface"). | |
// 2. Overridden methods (that were mixed in). | |
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name); | |
var isFunction = typeof property === 'function'; | |
var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false; | |
if (shouldAutoBind) { | |
autoBindPairs.push(name, property); | |
proto[name] = property; | |
} else { | |
if (isAlreadyDefined) { | |
var specPolicy = ReactClassInterface[name]; | |
// These cases should already be caught by validateMethodOverride. | |
!(isReactClassMethod && (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)) ? invariant(false, 'ReactClass: Unexpected spec policy %s for key %s when mixing in component specs.', specPolicy, name) : void 0; | |
// For methods which are defined more than once, call the existing | |
// methods before calling the new property, merging if appropriate. | |
if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { | |
proto[name] = createMergedResultFunction(proto[name], property); | |
} else if (specPolicy === SpecPolicy.DEFINE_MANY) { | |
proto[name] = createChainedFunction(proto[name], property); | |
} | |
} else { | |
proto[name] = property; | |
if ("development" !== 'production') { | |
// Add verbose displayName to the function, which helps when looking | |
// at profiling tools. | |
if (typeof property === 'function' && spec.displayName) { | |
proto[name].displayName = spec.displayName + '_' + name; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
function mixStaticSpecIntoComponent(Constructor, statics) { | |
if (!statics) { | |
return; | |
} | |
for (var name in statics) { | |
var property = statics[name]; | |
if (!statics.hasOwnProperty(name)) { | |
continue; | |
} | |
var isReserved = name in RESERVED_SPEC_KEYS; | |
!!isReserved ? invariant(false, 'ReactClass: You are attempting to define a reserved property, `%s`, that shouldn\'t be on the "statics" key. Define it as an instance property instead; it will still be accessible on the constructor.', name) : void 0; | |
var isInherited = name in Constructor; | |
!!isInherited ? invariant(false, 'ReactClass: You are attempting to define `%s` on your component more than once. This conflict may be due to a mixin.', name) : void 0; | |
Constructor[name] = property; | |
} | |
} | |
/** | |
* Merge two objects, but throw if both contain the same key. | |
* | |
* @param {object} one The first object, which is mutated. | |
* @param {object} two The second object | |
* @return {object} one after it has been mutated to contain everything in two. | |
*/ | |
function mergeIntoWithNoDuplicateKeys(one, two) { | |
!(one && two && typeof one === 'object' && typeof two === 'object') ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.') : void 0; | |
for (var key in two) { | |
if (two.hasOwnProperty(key)) { | |
!(one[key] === undefined) ? invariant(false, 'mergeIntoWithNoDuplicateKeys(): Tried to merge two objects with the same key: `%s`. This conflict may be due to a mixin; in particular, this may be caused by two getInitialState() or getDefaultProps() methods returning objects with clashing keys.', key) : void 0; | |
one[key] = two[key]; | |
} | |
} | |
return one; | |
} | |
/** | |
* Creates a function that invokes two functions and merges their return values. | |
* | |
* @param {function} one Function to invoke first. | |
* @param {function} two Function to invoke second. | |
* @return {function} Function that invokes the two argument functions. | |
* @private | |
*/ | |
function createMergedResultFunction(one, two) { | |
return function mergedResult() { | |
var a = one.apply(this, arguments); | |
var b = two.apply(this, arguments); | |
if (a == null) { | |
return b; | |
} else if (b == null) { | |
return a; | |
} | |
var c = {}; | |
mergeIntoWithNoDuplicateKeys(c, a); | |
mergeIntoWithNoDuplicateKeys(c, b); | |
return c; | |
}; | |
} | |
/** | |
* Creates a function that invokes two functions and ignores their return vales. | |
* | |
* @param {function} one Function to invoke first. | |
* @param {function} two Function to invoke second. | |
* @return {function} Function that invokes the two argument functions. | |
* @private | |
*/ | |
function createChainedFunction(one, two) { | |
return function chainedFunction() { | |
one.apply(this, arguments); | |
two.apply(this, arguments); | |
}; | |
} | |
/** | |
* Binds a method to the component. | |
* | |
* @param {object} component Component whose method is going to be bound. | |
* @param {function} method Method to be bound. | |
* @return {function} The bound method. | |
*/ | |
function bindAutoBindMethod(component, method) { | |
var boundMethod = method.bind(component); | |
if ("development" !== 'production') { | |
boundMethod.__reactBoundContext = component; | |
boundMethod.__reactBoundMethod = method; | |
boundMethod.__reactBoundArguments = null; | |
var componentName = component.constructor.displayName; | |
var _bind = boundMethod.bind; | |
boundMethod.bind = function (newThis) { | |
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | |
args[_key - 1] = arguments[_key]; | |
} | |
// User is trying to bind() an autobound method; we effectively will | |
// ignore the value of "this" that the user is trying to use, so | |
// let's warn. | |
if (newThis !== component && newThis !== null) { | |
warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName); | |
} else if (!args.length) { | |
warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName); | |
return boundMethod; | |
} | |
var reboundMethod = _bind.apply(boundMethod, arguments); | |
reboundMethod.__reactBoundContext = component; | |
reboundMethod.__reactBoundMethod = method; | |
reboundMethod.__reactBoundArguments = args; | |
return reboundMethod; | |
}; | |
} | |
return boundMethod; | |
} | |
/** | |
* Binds all auto-bound methods in a component. | |
* | |
* @param {object} component Component whose method is going to be bound. | |
*/ | |
function bindAutoBindMethods(component) { | |
var pairs = component.__reactAutoBindPairs; | |
for (var i = 0; i < pairs.length; i += 2) { | |
var autoBindKey = pairs[i]; | |
var method = pairs[i + 1]; | |
component[autoBindKey] = bindAutoBindMethod(component, method); | |
} | |
} | |
/** | |
* Add more to the ReactClass base class. These are all legacy features and | |
* therefore not already part of the modern ReactComponent. | |
*/ | |
var ReactClassMixin = { | |
/** | |
* TODO: This will be deprecated because state should always keep a consistent | |
* type signature and the only use case for this, is to avoid that. | |
*/ | |
replaceState: function (newState, callback) { | |
this.updater.enqueueReplaceState(this, newState); | |
if (callback) { | |
this.updater.enqueueCallback(this, callback, 'replaceState'); | |
} | |
}, | |
/** | |
* Checks whether or not this composite component is mounted. | |
* @return {boolean} True if mounted, false otherwise. | |
* @protected | |
* @final | |
*/ | |
isMounted: function () { | |
return this.updater.isMounted(this); | |
} | |
}; | |
var ReactClassComponent = function () {}; | |
_assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin); | |
/** | |
* Module for creating composite components. | |
* | |
* @class ReactClass | |
*/ | |
var ReactClass = { | |
/** | |
* Creates a composite component class given a class specification. | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.createclass | |
* | |
* @param {object} spec Class specification (which must define `render`). | |
* @return {function} Component constructor function. | |
* @public | |
*/ | |
createClass: function (spec) { | |
var Constructor = function (props, context, updater) { | |
// This constructor gets overridden by mocks. The argument is used | |
// by mocks to assert on what gets mounted. | |
if ("development" !== 'production') { | |
warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory'); | |
} | |
// Wire up auto-binding | |
if (this.__reactAutoBindPairs.length) { | |
bindAutoBindMethods(this); | |
} | |
this.props = props; | |
this.context = context; | |
this.refs = emptyObject; | |
this.updater = updater || ReactNoopUpdateQueue; | |
this.state = null; | |
// ReactClasses doesn't have constructors. Instead, they use the | |
// getInitialState and componentWillMount methods for initialization. | |
var initialState = this.getInitialState ? this.getInitialState() : null; | |
if ("development" !== 'production') { | |
// We allow auto-mocks to proceed as if they're returning null. | |
if (initialState === undefined && this.getInitialState._isMockFunction) { | |
// This is probably bad practice. Consider warning here and | |
// deprecating this convenience. | |
initialState = null; | |
} | |
} | |
!(typeof initialState === 'object' && !Array.isArray(initialState)) ? invariant(false, '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent') : void 0; | |
this.state = initialState; | |
}; | |
Constructor.prototype = new ReactClassComponent(); | |
Constructor.prototype.constructor = Constructor; | |
Constructor.prototype.__reactAutoBindPairs = []; | |
injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); | |
mixSpecIntoComponent(Constructor, spec); | |
// Initialize the defaultProps property after all mixins have been merged. | |
if (Constructor.getDefaultProps) { | |
Constructor.defaultProps = Constructor.getDefaultProps(); | |
} | |
if ("development" !== 'production') { | |
// This is a tag to indicate that the use of these method names is ok, | |
// since it's used with createClass. If it's not, then it's likely a | |
// mistake so we'll warn you to use the static property, property | |
// initializer or constructor respectively. | |
if (Constructor.getDefaultProps) { | |
Constructor.getDefaultProps.isReactClassApproved = {}; | |
} | |
if (Constructor.prototype.getInitialState) { | |
Constructor.prototype.getInitialState.isReactClassApproved = {}; | |
} | |
} | |
!Constructor.prototype.render ? invariant(false, 'createClass(...): Class specification must implement a `render` method.') : void 0; | |
if ("development" !== 'production') { | |
warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component'); | |
warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component'); | |
} | |
// Reduce time spent doing lookups by setting these on the prototype. | |
for (var methodName in ReactClassInterface) { | |
if (!Constructor.prototype[methodName]) { | |
Constructor.prototype[methodName] = null; | |
} | |
} | |
return Constructor; | |
}, | |
injection: { | |
injectMixin: function (mixin) { | |
injectedMixins.push(mixin); | |
} | |
} | |
}; | |
module.exports = ReactClass; | |
}); | |
var ReactClass$1 = interopDefault(ReactClass); | |
var require$$4$7 = Object.freeze({ | |
default: ReactClass$1 | |
}); | |
var mapObject = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
/** | |
* Executes the provided `callback` once for each enumerable own property in the | |
* object and constructs a new object from the results. The `callback` is | |
* invoked with three arguments: | |
* | |
* - the property value | |
* - the property name | |
* - the object being traversed | |
* | |
* Properties that are added after the call to `mapObject` will not be visited | |
* by `callback`. If the values of existing properties are changed, the value | |
* passed to `callback` will be the value at the time `mapObject` visits them. | |
* Properties that are deleted before being visited are not visited. | |
* | |
* @grep function objectMap() | |
* @grep function objMap() | |
* | |
* @param {?object} object | |
* @param {function} callback | |
* @param {*} context | |
* @return {?object} | |
*/ | |
function mapObject(object, callback, context) { | |
if (!object) { | |
return null; | |
} | |
var result = {}; | |
for (var name in object) { | |
if (hasOwnProperty.call(object, name)) { | |
result[name] = callback.call(context, object[name], name, object); | |
} | |
} | |
return result; | |
} | |
module.exports = mapObject; | |
}); | |
var mapObject$1 = interopDefault(mapObject); | |
var require$$1$18 = Object.freeze({ | |
default: mapObject$1 | |
}); | |
var ReactComponentTreeDevtool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactComponentTreeDevtool | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactCurrentOwner = interopDefault(require$$5$3); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
var tree = {}; | |
var unmountedIDs = {}; | |
var rootIDs = {}; | |
function updateTree(id, update) { | |
if (!tree[id]) { | |
tree[id] = { | |
element: null, | |
parentID: null, | |
ownerID: null, | |
text: null, | |
childIDs: [], | |
displayName: 'Unknown', | |
isMounted: false, | |
updateCount: 0 | |
}; | |
} | |
update(tree[id]); | |
} | |
function purgeDeep(id) { | |
var item = tree[id]; | |
if (item) { | |
var childIDs = item.childIDs; | |
delete tree[id]; | |
childIDs.forEach(purgeDeep); | |
} | |
} | |
function describeComponentFrame(name, source, ownerName) { | |
return '\n in ' + name + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); | |
} | |
function describeID(id) { | |
var name = ReactComponentTreeDevtool.getDisplayName(id); | |
var element = ReactComponentTreeDevtool.getElement(id); | |
var ownerID = ReactComponentTreeDevtool.getOwnerID(id); | |
var ownerName; | |
if (ownerID) { | |
ownerName = ReactComponentTreeDevtool.getDisplayName(ownerID); | |
} | |
warning(element, 'ReactComponentTreeDevtool: Missing React element for debugID %s when ' + 'building stack', id); | |
return describeComponentFrame(name, element && element._source, ownerName); | |
} | |
var ReactComponentTreeDevtool = { | |
onSetDisplayName: function (id, displayName) { | |
updateTree(id, function (item) { | |
return item.displayName = displayName; | |
}); | |
}, | |
onSetChildren: function (id, nextChildIDs) { | |
updateTree(id, function (item) { | |
item.childIDs = nextChildIDs; | |
nextChildIDs.forEach(function (nextChildID) { | |
var nextChild = tree[nextChildID]; | |
!nextChild ? invariant(false, 'Expected devtool events to fire for the child before its parent includes it in onSetChildren().') : void 0; | |
!(nextChild.displayName != null) ? invariant(false, 'Expected onSetDisplayName() to fire for the child before its parent includes it in onSetChildren().') : void 0; | |
!(nextChild.childIDs != null || nextChild.text != null) ? invariant(false, 'Expected onSetChildren() or onSetText() to fire for the child before its parent includes it in onSetChildren().') : void 0; | |
!nextChild.isMounted ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : void 0; | |
if (nextChild.parentID == null) { | |
nextChild.parentID = id; | |
// TODO: This shouldn't be necessary but mounting a new root during in | |
// componentWillMount currently causes not-yet-mounted components to | |
// be purged from our tree data so their parent ID is missing. | |
} | |
!(nextChild.parentID === id) ? invariant(false, 'Expected onSetParent() and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : void 0; | |
}); | |
}); | |
}, | |
onSetOwner: function (id, ownerID) { | |
updateTree(id, function (item) { | |
return item.ownerID = ownerID; | |
}); | |
}, | |
onSetParent: function (id, parentID) { | |
updateTree(id, function (item) { | |
return item.parentID = parentID; | |
}); | |
}, | |
onSetText: function (id, text) { | |
updateTree(id, function (item) { | |
return item.text = text; | |
}); | |
}, | |
onBeforeMountComponent: function (id, element) { | |
updateTree(id, function (item) { | |
return item.element = element; | |
}); | |
}, | |
onBeforeUpdateComponent: function (id, element) { | |
updateTree(id, function (item) { | |
return item.element = element; | |
}); | |
}, | |
onMountComponent: function (id) { | |
updateTree(id, function (item) { | |
return item.isMounted = true; | |
}); | |
}, | |
onMountRootComponent: function (id) { | |
rootIDs[id] = true; | |
}, | |
onUpdateComponent: function (id) { | |
updateTree(id, function (item) { | |
return item.updateCount++; | |
}); | |
}, | |
onUnmountComponent: function (id) { | |
updateTree(id, function (item) { | |
return item.isMounted = false; | |
}); | |
unmountedIDs[id] = true; | |
delete rootIDs[id]; | |
}, | |
purgeUnmountedComponents: function () { | |
if (ReactComponentTreeDevtool._preventPurging) { | |
// Should only be used for testing. | |
return; | |
} | |
for (var id in unmountedIDs) { | |
purgeDeep(id); | |
} | |
unmountedIDs = {}; | |
}, | |
isMounted: function (id) { | |
var item = tree[id]; | |
return item ? item.isMounted : false; | |
}, | |
getCurrentStackAddendum: function (topElement) { | |
var info = ''; | |
if (topElement) { | |
var type = topElement.type; | |
var name = typeof type === 'function' ? type.displayName || type.name : type; | |
var owner = topElement._owner; | |
info += describeComponentFrame(name || 'Unknown', topElement._source, owner && owner.getName()); | |
} | |
var currentOwner = ReactCurrentOwner.current; | |
var id = currentOwner && currentOwner._debugID; | |
info += ReactComponentTreeDevtool.getStackAddendumByID(id); | |
return info; | |
}, | |
getStackAddendumByID: function (id) { | |
var info = ''; | |
while (id) { | |
info += describeID(id); | |
id = ReactComponentTreeDevtool.getParentID(id); | |
} | |
return info; | |
}, | |
getChildIDs: function (id) { | |
var item = tree[id]; | |
return item ? item.childIDs : []; | |
}, | |
getDisplayName: function (id) { | |
var item = tree[id]; | |
return item ? item.displayName : 'Unknown'; | |
}, | |
getElement: function (id) { | |
var item = tree[id]; | |
return item ? item.element : null; | |
}, | |
getOwnerID: function (id) { | |
var item = tree[id]; | |
return item ? item.ownerID : null; | |
}, | |
getParentID: function (id) { | |
var item = tree[id]; | |
return item ? item.parentID : null; | |
}, | |
getSource: function (id) { | |
var item = tree[id]; | |
var element = item ? item.element : null; | |
var source = element != null ? element._source : null; | |
return source; | |
}, | |
getText: function (id) { | |
var item = tree[id]; | |
return item ? item.text : null; | |
}, | |
getUpdateCount: function (id) { | |
var item = tree[id]; | |
return item ? item.updateCount : 0; | |
}, | |
getRootIDs: function () { | |
return Object.keys(rootIDs); | |
}, | |
getRegisteredIDs: function () { | |
return Object.keys(tree); | |
} | |
}; | |
module.exports = ReactComponentTreeDevtool; | |
}); | |
var ReactComponentTreeDevtool$1 = interopDefault(ReactComponentTreeDevtool); | |
var require$$0$39 = Object.freeze({ | |
default: ReactComponentTreeDevtool$1 | |
}); | |
var checkReactTypeSpec = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule checkReactTypeSpec | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactPropTypeLocationNames = interopDefault(require$$2$16); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
var loggedTypeFailures = {}; | |
/** | |
* Assert that the values match with the type specs. | |
* Error messages are memorized and will only be shown once. | |
* | |
* @param {object} typeSpecs Map of name to a ReactPropType | |
* @param {object} values Runtime values that need to be type-checked | |
* @param {string} location e.g. "prop", "context", "child context" | |
* @param {string} componentName Name of the component for error messages. | |
* @param {?object} element The React element that is being type-checked | |
* @param {?number} debugID The React component instance that is being type-checked | |
* @private | |
*/ | |
function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { | |
for (var typeSpecName in typeSpecs) { | |
if (typeSpecs.hasOwnProperty(typeSpecName)) { | |
var error; | |
// Prop type validation may throw. In case they do, we don't want to | |
// fail the render phase where it didn't fail before. So we log it. | |
// After these have been cleaned up, we'll let them throw. | |
try { | |
// This is intentionally an invariant that gets caught. It's the same | |
// behavior as without this statement except with a better message. | |
!(typeof typeSpecs[typeSpecName] === 'function') ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; | |
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location); | |
} catch (ex) { | |
error = ex; | |
} | |
warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error); | |
if (error instanceof Error && !(error.message in loggedTypeFailures)) { | |
// Only monitor this failure once because there tends to be a lot of the | |
// same error. | |
loggedTypeFailures[error.message] = true; | |
var componentStackInfo = ''; | |
if ("development" !== 'production') { | |
var ReactComponentTreeDevtool = interopDefault(require$$0$39); | |
if (debugID !== null) { | |
componentStackInfo = ReactComponentTreeDevtool.getStackAddendumByID(debugID); | |
} else if (element !== null) { | |
componentStackInfo = ReactComponentTreeDevtool.getCurrentStackAddendum(element); | |
} | |
} | |
warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo); | |
} | |
} | |
} | |
} | |
module.exports = checkReactTypeSpec; | |
}); | |
var checkReactTypeSpec$1 = interopDefault(checkReactTypeSpec); | |
var require$$4$8 = Object.freeze({ | |
default: checkReactTypeSpec$1 | |
}); | |
var ReactElementValidator = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2014-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactElementValidator | |
*/ | |
/** | |
* ReactElementValidator provides a wrapper around a element factory | |
* which validates the props passed to the element. This is intended to be | |
* used only in DEV and could be replaced by a static type checker for languages | |
* that support it. | |
*/ | |
'use strict'; | |
var ReactCurrentOwner = interopDefault(require$$5$3); | |
var ReactComponentTreeDevtool = interopDefault(require$$0$39); | |
var ReactElement = interopDefault(require$$9); | |
var ReactPropTypeLocations = interopDefault(require$$6); | |
var checkReactTypeSpec = interopDefault(require$$4$8); | |
var canDefineProperty = interopDefault(require$$2$13); | |
var getIteratorFn = interopDefault(require$$0$35); | |
var warning = interopDefault(require$$0$34); | |
function getDeclarationErrorAddendum() { | |
if (ReactCurrentOwner.current) { | |
var name = ReactCurrentOwner.current.getName(); | |
if (name) { | |
return ' Check the render method of `' + name + '`.'; | |
} | |
} | |
return ''; | |
} | |
/** | |
* Warn if there's no key explicitly set on dynamic arrays of children or | |
* object keys are not valid. This allows us to keep track of children between | |
* updates. | |
*/ | |
var ownerHasKeyUseWarning = {}; | |
function getCurrentComponentErrorInfo(parentType) { | |
var info = getDeclarationErrorAddendum(); | |
if (!info) { | |
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name; | |
if (parentName) { | |
info = ' Check the top-level render call using <' + parentName + '>.'; | |
} | |
} | |
return info; | |
} | |
/** | |
* Warn if the element doesn't have an explicit key assigned to it. | |
* This element is in an array. The array could grow and shrink or be | |
* reordered. All children that haven't already been validated are required to | |
* have a "key" property assigned to it. Error statuses are cached so a warning | |
* will only be shown once. | |
* | |
* @internal | |
* @param {ReactElement} element Element that requires a key. | |
* @param {*} parentType element's parent's type. | |
*/ | |
function validateExplicitKey(element, parentType) { | |
if (!element._store || element._store.validated || element.key != null) { | |
return; | |
} | |
element._store.validated = true; | |
var memoizer = ownerHasKeyUseWarning.uniqueKey || (ownerHasKeyUseWarning.uniqueKey = {}); | |
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); | |
if (memoizer[currentComponentErrorInfo]) { | |
return; | |
} | |
memoizer[currentComponentErrorInfo] = true; | |
// Usually the current owner is the offender, but if it accepts children as a | |
// property, it may be the creator of the child that's responsible for | |
// assigning it a key. | |
var childOwner = ''; | |
if (element && element._owner && element._owner !== ReactCurrentOwner.current) { | |
// Give the component that originally created this child. | |
childOwner = ' It was passed a child from ' + element._owner.getName() + '.'; | |
} | |
warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, ReactComponentTreeDevtool.getCurrentStackAddendum(element)); | |
} | |
/** | |
* Ensure that every element either is passed in a static location, in an | |
* array with an explicit keys property defined, or in an object literal | |
* with valid key property. | |
* | |
* @internal | |
* @param {ReactNode} node Statically passed child of any type. | |
* @param {*} parentType node's parent's type. | |
*/ | |
function validateChildKeys(node, parentType) { | |
if (typeof node !== 'object') { | |
return; | |
} | |
if (Array.isArray(node)) { | |
for (var i = 0; i < node.length; i++) { | |
var child = node[i]; | |
if (ReactElement.isValidElement(child)) { | |
validateExplicitKey(child, parentType); | |
} | |
} | |
} else if (ReactElement.isValidElement(node)) { | |
// This element was passed in a valid location. | |
if (node._store) { | |
node._store.validated = true; | |
} | |
} else if (node) { | |
var iteratorFn = getIteratorFn(node); | |
// Entry iterators provide implicit keys. | |
if (iteratorFn) { | |
if (iteratorFn !== node.entries) { | |
var iterator = iteratorFn.call(node); | |
var step; | |
while (!(step = iterator.next()).done) { | |
if (ReactElement.isValidElement(step.value)) { | |
validateExplicitKey(step.value, parentType); | |
} | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Given an element, validate that its props follow the propTypes definition, | |
* provided by the type. | |
* | |
* @param {ReactElement} element | |
*/ | |
function validatePropTypes(element) { | |
var componentClass = element.type; | |
if (typeof componentClass !== 'function') { | |
return; | |
} | |
var name = componentClass.displayName || componentClass.name; | |
if (componentClass.propTypes) { | |
checkReactTypeSpec(componentClass.propTypes, element.props, ReactPropTypeLocations.prop, name, element, null); | |
} | |
if (typeof componentClass.getDefaultProps === 'function') { | |
warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.'); | |
} | |
} | |
var ReactElementValidator = { | |
createElement: function (type, props, children) { | |
var validType = typeof type === 'string' || typeof type === 'function'; | |
// We warn in this case but don't throw. We expect the element creation to | |
// succeed and there will likely be errors in render. | |
warning(validType, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()); | |
var element = ReactElement.createElement.apply(this, arguments); | |
// The result can be nullish if a mock or a custom function is used. | |
// TODO: Drop this when these are no longer allowed as the type argument. | |
if (element == null) { | |
return element; | |
} | |
// Skip key warning if the type isn't valid since our key validation logic | |
// doesn't expect a non-string/function type and can throw confusing errors. | |
// We don't want exception behavior to differ between dev and prod. | |
// (Rendering will throw with a helpful message and as soon as the type is | |
// fixed, the key warnings will appear.) | |
if (validType) { | |
for (var i = 2; i < arguments.length; i++) { | |
validateChildKeys(arguments[i], type); | |
} | |
} | |
validatePropTypes(element); | |
return element; | |
}, | |
createFactory: function (type) { | |
var validatedFactory = ReactElementValidator.createElement.bind(null, type); | |
// Legacy hook TODO: Warn if this is accessed | |
validatedFactory.type = type; | |
if ("development" !== 'production') { | |
if (canDefineProperty) { | |
Object.defineProperty(validatedFactory, 'type', { | |
enumerable: false, | |
get: function () { | |
warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.'); | |
Object.defineProperty(this, 'type', { | |
value: type | |
}); | |
return type; | |
} | |
}); | |
} | |
} | |
return validatedFactory; | |
}, | |
cloneElement: function (element, props, children) { | |
var newElement = ReactElement.cloneElement.apply(this, arguments); | |
for (var i = 2; i < arguments.length; i++) { | |
validateChildKeys(arguments[i], newElement.type); | |
} | |
validatePropTypes(newElement); | |
return newElement; | |
} | |
}; | |
module.exports = ReactElementValidator; | |
}); | |
var ReactElementValidator$1 = interopDefault(ReactElementValidator); | |
var require$$0$38 = Object.freeze({ | |
default: ReactElementValidator$1 | |
}); | |
var ReactDOMFactories = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMFactories | |
*/ | |
'use strict'; | |
var ReactElement = interopDefault(require$$9); | |
var mapObject = interopDefault(require$$1$18); | |
/** | |
* Create a factory that creates HTML tag elements. | |
* | |
* @param {string} tag Tag name (e.g. `div`). | |
* @private | |
*/ | |
function createDOMFactory(tag) { | |
if ("development" !== 'production') { | |
var ReactElementValidator = interopDefault(require$$0$38); | |
return ReactElementValidator.createFactory(tag); | |
} | |
return ReactElement.createFactory(tag); | |
} | |
/** | |
* Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. | |
* This is also accessible via `React.DOM`. | |
* | |
* @public | |
*/ | |
var ReactDOMFactories = mapObject({ | |
a: 'a', | |
abbr: 'abbr', | |
address: 'address', | |
area: 'area', | |
article: 'article', | |
aside: 'aside', | |
audio: 'audio', | |
b: 'b', | |
base: 'base', | |
bdi: 'bdi', | |
bdo: 'bdo', | |
big: 'big', | |
blockquote: 'blockquote', | |
body: 'body', | |
br: 'br', | |
button: 'button', | |
canvas: 'canvas', | |
caption: 'caption', | |
cite: 'cite', | |
code: 'code', | |
col: 'col', | |
colgroup: 'colgroup', | |
data: 'data', | |
datalist: 'datalist', | |
dd: 'dd', | |
del: 'del', | |
details: 'details', | |
dfn: 'dfn', | |
dialog: 'dialog', | |
div: 'div', | |
dl: 'dl', | |
dt: 'dt', | |
em: 'em', | |
embed: 'embed', | |
fieldset: 'fieldset', | |
figcaption: 'figcaption', | |
figure: 'figure', | |
footer: 'footer', | |
form: 'form', | |
h1: 'h1', | |
h2: 'h2', | |
h3: 'h3', | |
h4: 'h4', | |
h5: 'h5', | |
h6: 'h6', | |
head: 'head', | |
header: 'header', | |
hgroup: 'hgroup', | |
hr: 'hr', | |
html: 'html', | |
i: 'i', | |
iframe: 'iframe', | |
img: 'img', | |
input: 'input', | |
ins: 'ins', | |
kbd: 'kbd', | |
keygen: 'keygen', | |
label: 'label', | |
legend: 'legend', | |
li: 'li', | |
link: 'link', | |
main: 'main', | |
map: 'map', | |
mark: 'mark', | |
menu: 'menu', | |
menuitem: 'menuitem', | |
meta: 'meta', | |
meter: 'meter', | |
nav: 'nav', | |
noscript: 'noscript', | |
object: 'object', | |
ol: 'ol', | |
optgroup: 'optgroup', | |
option: 'option', | |
output: 'output', | |
p: 'p', | |
param: 'param', | |
picture: 'picture', | |
pre: 'pre', | |
progress: 'progress', | |
q: 'q', | |
rp: 'rp', | |
rt: 'rt', | |
ruby: 'ruby', | |
s: 's', | |
samp: 'samp', | |
script: 'script', | |
section: 'section', | |
select: 'select', | |
small: 'small', | |
source: 'source', | |
span: 'span', | |
strong: 'strong', | |
style: 'style', | |
sub: 'sub', | |
summary: 'summary', | |
sup: 'sup', | |
table: 'table', | |
tbody: 'tbody', | |
td: 'td', | |
textarea: 'textarea', | |
tfoot: 'tfoot', | |
th: 'th', | |
thead: 'thead', | |
time: 'time', | |
title: 'title', | |
tr: 'tr', | |
track: 'track', | |
u: 'u', | |
ul: 'ul', | |
'var': 'var', | |
video: 'video', | |
wbr: 'wbr', | |
// SVG | |
circle: 'circle', | |
clipPath: 'clipPath', | |
defs: 'defs', | |
ellipse: 'ellipse', | |
g: 'g', | |
image: 'image', | |
line: 'line', | |
linearGradient: 'linearGradient', | |
mask: 'mask', | |
path: 'path', | |
pattern: 'pattern', | |
polygon: 'polygon', | |
polyline: 'polyline', | |
radialGradient: 'radialGradient', | |
rect: 'rect', | |
stop: 'stop', | |
svg: 'svg', | |
text: 'text', | |
tspan: 'tspan' | |
}, createDOMFactory); | |
module.exports = ReactDOMFactories; | |
}); | |
var ReactDOMFactories$1 = interopDefault(ReactDOMFactories); | |
var require$$6$1 = Object.freeze({ | |
default: ReactDOMFactories$1 | |
}); | |
var ReactPropTypes = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactPropTypes | |
*/ | |
'use strict'; | |
var ReactElement = interopDefault(require$$9); | |
var ReactPropTypeLocationNames = interopDefault(require$$2$16); | |
var emptyFunction = interopDefault(require$$3$10); | |
var getIteratorFn = interopDefault(require$$0$35); | |
/** | |
* Collection of methods that allow declaration and validation of props that are | |
* supplied to React components. Example usage: | |
* | |
* var Props = require('ReactPropTypes'); | |
* var MyArticle = React.createClass({ | |
* propTypes: { | |
* // An optional string prop named "description". | |
* description: Props.string, | |
* | |
* // A required enum prop named "category". | |
* category: Props.oneOf(['News','Photos']).isRequired, | |
* | |
* // A prop named "dialog" that requires an instance of Dialog. | |
* dialog: Props.instanceOf(Dialog).isRequired | |
* }, | |
* render: function() { ... } | |
* }); | |
* | |
* A more formal specification of how these methods are used: | |
* | |
* type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) | |
* decl := ReactPropTypes.{type}(.isRequired)? | |
* | |
* Each and every declaration produces a function with the same signature. This | |
* allows the creation of custom validation functions. For example: | |
* | |
* var MyLink = React.createClass({ | |
* propTypes: { | |
* // An optional string or URI prop named "href". | |
* href: function(props, propName, componentName) { | |
* var propValue = props[propName]; | |
* if (propValue != null && typeof propValue !== 'string' && | |
* !(propValue instanceof URI)) { | |
* return new Error( | |
* 'Expected a string or an URI for ' + propName + ' in ' + | |
* componentName | |
* ); | |
* } | |
* } | |
* }, | |
* render: function() {...} | |
* }); | |
* | |
* @internal | |
*/ | |
var ANONYMOUS = '<<anonymous>>'; | |
var ReactPropTypes = { | |
array: createPrimitiveTypeChecker('array'), | |
bool: createPrimitiveTypeChecker('boolean'), | |
func: createPrimitiveTypeChecker('function'), | |
number: createPrimitiveTypeChecker('number'), | |
object: createPrimitiveTypeChecker('object'), | |
string: createPrimitiveTypeChecker('string'), | |
symbol: createPrimitiveTypeChecker('symbol'), | |
any: createAnyTypeChecker(), | |
arrayOf: createArrayOfTypeChecker, | |
element: createElementTypeChecker(), | |
instanceOf: createInstanceTypeChecker, | |
node: createNodeChecker(), | |
objectOf: createObjectOfTypeChecker, | |
oneOf: createEnumTypeChecker, | |
oneOfType: createUnionTypeChecker, | |
shape: createShapeTypeChecker | |
}; | |
/** | |
* inlined Object.is polyfill to avoid requiring consumers ship their own | |
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is | |
*/ | |
/*eslint-disable no-self-compare*/ | |
function is(x, y) { | |
// SameValue algorithm | |
if (x === y) { | |
// Steps 1-5, 7-10 | |
// Steps 6.b-6.e: +0 != -0 | |
return x !== 0 || 1 / x === 1 / y; | |
} else { | |
// Step 6.a: NaN == NaN | |
return x !== x && y !== y; | |
} | |
} | |
/*eslint-enable no-self-compare*/ | |
function createChainableTypeChecker(validate) { | |
function checkType(isRequired, props, propName, componentName, location, propFullName) { | |
componentName = componentName || ANONYMOUS; | |
propFullName = propFullName || propName; | |
if (props[propName] == null) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
if (isRequired) { | |
return new Error('Required ' + locationName + ' `' + propFullName + '` was not specified in ' + ('`' + componentName + '`.')); | |
} | |
return null; | |
} else { | |
return validate(props, propName, componentName, location, propFullName); | |
} | |
} | |
var chainedCheckType = checkType.bind(null, false); | |
chainedCheckType.isRequired = checkType.bind(null, true); | |
return chainedCheckType; | |
} | |
function createPrimitiveTypeChecker(expectedType) { | |
function validate(props, propName, componentName, location, propFullName) { | |
var propValue = props[propName]; | |
var propType = getPropType(propValue); | |
if (propType !== expectedType) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
// `propValue` being instance of, say, date/regexp, pass the 'object' | |
// check, but we can offer a more precise error message here rather than | |
// 'of type `object`'. | |
var preciseType = getPreciseType(propValue); | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createAnyTypeChecker() { | |
return createChainableTypeChecker(emptyFunction.thatReturns(null)); | |
} | |
function createArrayOfTypeChecker(typeChecker) { | |
function validate(props, propName, componentName, location, propFullName) { | |
if (typeof typeChecker !== 'function') { | |
return new Error('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); | |
} | |
var propValue = props[propName]; | |
if (!Array.isArray(propValue)) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
var propType = getPropType(propValue); | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); | |
} | |
for (var i = 0; i < propValue.length; i++) { | |
var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']'); | |
if (error instanceof Error) { | |
return error; | |
} | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createElementTypeChecker() { | |
function validate(props, propName, componentName, location, propFullName) { | |
if (!ReactElement.isValidElement(props[propName])) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a single ReactElement.')); | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createInstanceTypeChecker(expectedClass) { | |
function validate(props, propName, componentName, location, propFullName) { | |
if (!(props[propName] instanceof expectedClass)) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
var expectedClassName = expectedClass.name || ANONYMOUS; | |
var actualClassName = getClassName(props[propName]); | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createEnumTypeChecker(expectedValues) { | |
if (!Array.isArray(expectedValues)) { | |
return createChainableTypeChecker(function () { | |
return new Error('Invalid argument supplied to oneOf, expected an instance of array.'); | |
}); | |
} | |
function validate(props, propName, componentName, location, propFullName) { | |
var propValue = props[propName]; | |
for (var i = 0; i < expectedValues.length; i++) { | |
if (is(propValue, expectedValues[i])) { | |
return null; | |
} | |
} | |
var locationName = ReactPropTypeLocationNames[location]; | |
var valuesString = JSON.stringify(expectedValues); | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createObjectOfTypeChecker(typeChecker) { | |
function validate(props, propName, componentName, location, propFullName) { | |
if (typeof typeChecker !== 'function') { | |
return new Error('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); | |
} | |
var propValue = props[propName]; | |
var propType = getPropType(propValue); | |
if (propType !== 'object') { | |
var locationName = ReactPropTypeLocationNames[location]; | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); | |
} | |
for (var key in propValue) { | |
if (propValue.hasOwnProperty(key)) { | |
var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key); | |
if (error instanceof Error) { | |
return error; | |
} | |
} | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createUnionTypeChecker(arrayOfTypeCheckers) { | |
if (!Array.isArray(arrayOfTypeCheckers)) { | |
return createChainableTypeChecker(function () { | |
return new Error('Invalid argument supplied to oneOfType, expected an instance of array.'); | |
}); | |
} | |
function validate(props, propName, componentName, location, propFullName) { | |
for (var i = 0; i < arrayOfTypeCheckers.length; i++) { | |
var checker = arrayOfTypeCheckers[i]; | |
if (checker(props, propName, componentName, location, propFullName) == null) { | |
return null; | |
} | |
} | |
var locationName = ReactPropTypeLocationNames[location]; | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createNodeChecker() { | |
function validate(props, propName, componentName, location, propFullName) { | |
if (!isNode(props[propName])) { | |
var locationName = ReactPropTypeLocationNames[location]; | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function createShapeTypeChecker(shapeTypes) { | |
function validate(props, propName, componentName, location, propFullName) { | |
var propValue = props[propName]; | |
var propType = getPropType(propValue); | |
if (propType !== 'object') { | |
var locationName = ReactPropTypeLocationNames[location]; | |
return new Error('Invalid ' + locationName + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); | |
} | |
for (var key in shapeTypes) { | |
var checker = shapeTypes[key]; | |
if (!checker) { | |
continue; | |
} | |
var error = checker(propValue, key, componentName, location, propFullName + '.' + key); | |
if (error) { | |
return error; | |
} | |
} | |
return null; | |
} | |
return createChainableTypeChecker(validate); | |
} | |
function isNode(propValue) { | |
switch (typeof propValue) { | |
case 'number': | |
case 'string': | |
case 'undefined': | |
return true; | |
case 'boolean': | |
return !propValue; | |
case 'object': | |
if (Array.isArray(propValue)) { | |
return propValue.every(isNode); | |
} | |
if (propValue === null || ReactElement.isValidElement(propValue)) { | |
return true; | |
} | |
var iteratorFn = getIteratorFn(propValue); | |
if (iteratorFn) { | |
var iterator = iteratorFn.call(propValue); | |
var step; | |
if (iteratorFn !== propValue.entries) { | |
while (!(step = iterator.next()).done) { | |
if (!isNode(step.value)) { | |
return false; | |
} | |
} | |
} else { | |
// Iterator will provide entry [k,v] tuples rather than values. | |
while (!(step = iterator.next()).done) { | |
var entry = step.value; | |
if (entry) { | |
if (!isNode(entry[1])) { | |
return false; | |
} | |
} | |
} | |
} | |
} else { | |
return false; | |
} | |
return true; | |
default: | |
return false; | |
} | |
} | |
function isSymbol(propType, propValue) { | |
// Native Symbol. | |
if (propType === 'symbol') { | |
return true; | |
} | |
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | |
if (propValue['@@toStringTag'] === 'Symbol') { | |
return true; | |
} | |
// Fallback for non-spec compliant Symbols which are polyfilled. | |
if (typeof Symbol === 'function' && propValue instanceof Symbol) { | |
return true; | |
} | |
return false; | |
} | |
// Equivalent of `typeof` but with special handling for array and regexp. | |
function getPropType(propValue) { | |
var propType = typeof propValue; | |
if (Array.isArray(propValue)) { | |
return 'array'; | |
} | |
if (propValue instanceof RegExp) { | |
// Old webkits (at least until Android 4.0) return 'function' rather than | |
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/ | |
// passes PropTypes.object. | |
return 'object'; | |
} | |
if (isSymbol(propType, propValue)) { | |
return 'symbol'; | |
} | |
return propType; | |
} | |
// This handles more types than `getPropType`. Only used for error messages. | |
// See `createPrimitiveTypeChecker`. | |
function getPreciseType(propValue) { | |
var propType = getPropType(propValue); | |
if (propType === 'object') { | |
if (propValue instanceof Date) { | |
return 'date'; | |
} else if (propValue instanceof RegExp) { | |
return 'regexp'; | |
} | |
} | |
return propType; | |
} | |
// Returns class name of the object, if any. | |
function getClassName(propValue) { | |
if (!propValue.constructor || !propValue.constructor.name) { | |
return ANONYMOUS; | |
} | |
return propValue.constructor.name; | |
} | |
module.exports = ReactPropTypes; | |
}); | |
var ReactPropTypes$1 = interopDefault(ReactPropTypes); | |
var require$$3$12 = Object.freeze({ | |
default: ReactPropTypes$1 | |
}); | |
var ReactVersion = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactVersion | |
*/ | |
'use strict'; | |
module.exports = '15.2.1'; | |
}); | |
var ReactVersion$1 = interopDefault(ReactVersion); | |
var require$$0$40 = Object.freeze({ | |
default: ReactVersion$1 | |
}); | |
var onlyChild = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule onlyChild | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactElement = interopDefault(require$$9); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Returns the first child in a collection of children and verifies that there | |
* is only one child in the collection. | |
* | |
* See https://facebook.github.io/react/docs/top-level-api.html#react.children.only | |
* | |
* The current implementation of this function assumes that a single child gets | |
* passed without a wrapper, but the purpose of this helper function is to | |
* abstract away the particular structure of children. | |
* | |
* @param {?object} children Child collection structure. | |
* @return {ReactElement} The first and only `ReactElement` contained in the | |
* structure. | |
*/ | |
function onlyChild(children) { | |
!ReactElement.isValidElement(children) ? invariant(false, 'onlyChild must be passed a children with exactly one child.') : void 0; | |
return children; | |
} | |
module.exports = onlyChild; | |
}); | |
var onlyChild$1 = interopDefault(onlyChild); | |
var require$$2$17 = Object.freeze({ | |
default: onlyChild$1 | |
}); | |
var React$1 = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule React | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var ReactChildren = interopDefault(require$$3$9); | |
var ReactComponent = interopDefault(require$$9$1); | |
var ReactClass = interopDefault(require$$4$7); | |
var ReactDOMFactories = interopDefault(require$$6$1); | |
var ReactElement = interopDefault(require$$9); | |
var ReactPropTypes = interopDefault(require$$3$12); | |
var ReactVersion = interopDefault(require$$0$40); | |
var onlyChild = interopDefault(require$$2$17); | |
var warning = interopDefault(require$$0$34); | |
var createElement = ReactElement.createElement; | |
var createFactory = ReactElement.createFactory; | |
var cloneElement = ReactElement.cloneElement; | |
if ("development" !== 'production') { | |
var ReactElementValidator = interopDefault(require$$0$38); | |
createElement = ReactElementValidator.createElement; | |
createFactory = ReactElementValidator.createFactory; | |
cloneElement = ReactElementValidator.cloneElement; | |
} | |
var __spread = _assign; | |
if ("development" !== 'production') { | |
var warned = false; | |
__spread = function () { | |
warning(warned, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.'); | |
warned = true; | |
return _assign.apply(null, arguments); | |
}; | |
} | |
var React = { | |
// Modern | |
Children: { | |
map: ReactChildren.map, | |
forEach: ReactChildren.forEach, | |
count: ReactChildren.count, | |
toArray: ReactChildren.toArray, | |
only: onlyChild | |
}, | |
Component: ReactComponent, | |
createElement: createElement, | |
cloneElement: cloneElement, | |
isValidElement: ReactElement.isValidElement, | |
// Classic | |
PropTypes: ReactPropTypes, | |
createClass: ReactClass.createClass, | |
createFactory: createFactory, | |
createMixin: function (mixin) { | |
// Currently a noop. Will be used to validate and trace mixins. | |
return mixin; | |
}, | |
// This looks DOM specific but these are actually isomorphic helpers | |
// since they are just generating DOM strings. | |
DOM: ReactDOMFactories, | |
version: ReactVersion, | |
// Deprecated hook for JSX spread, don't use this for anything. | |
__spread: __spread | |
}; | |
module.exports = React; | |
}); | |
var React$2 = interopDefault(React$1); | |
var require$$0$32 = Object.freeze({ | |
default: React$2 | |
}); | |
var react = createCommonjsModule(function (module) { | |
'use strict'; | |
module.exports = interopDefault(require$$0$32); | |
}); | |
var React = interopDefault(react); | |
var require$$3$8 = Object.freeze({ | |
default: React | |
}); | |
var DOMProperty = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DOMProperty | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
function checkMask(value, bitmask) { | |
return (value & bitmask) === bitmask; | |
} | |
var DOMPropertyInjection = { | |
/** | |
* Mapping from normalized, camelcased property names to a configuration that | |
* specifies how the associated DOM property should be accessed or rendered. | |
*/ | |
MUST_USE_PROPERTY: 0x1, | |
HAS_BOOLEAN_VALUE: 0x4, | |
HAS_NUMERIC_VALUE: 0x8, | |
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, | |
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, | |
/** | |
* Inject some specialized knowledge about the DOM. This takes a config object | |
* with the following properties: | |
* | |
* isCustomAttribute: function that given an attribute name will return true | |
* if it can be inserted into the DOM verbatim. Useful for data-* or aria-* | |
* attributes where it's impossible to enumerate all of the possible | |
* attribute names, | |
* | |
* Properties: object mapping DOM property name to one of the | |
* DOMPropertyInjection constants or null. If your attribute isn't in here, | |
* it won't get written to the DOM. | |
* | |
* DOMAttributeNames: object mapping React attribute name to the DOM | |
* attribute name. Attribute names not specified use the **lowercase** | |
* normalized name. | |
* | |
* DOMAttributeNamespaces: object mapping React attribute name to the DOM | |
* attribute namespace URL. (Attribute names not specified use no namespace.) | |
* | |
* DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. | |
* Property names not specified use the normalized name. | |
* | |
* DOMMutationMethods: Properties that require special mutation methods. If | |
* `value` is undefined, the mutation method should unset the property. | |
* | |
* @param {object} domPropertyConfig the config as described above. | |
*/ | |
injectDOMPropertyConfig: function (domPropertyConfig) { | |
var Injection = DOMPropertyInjection; | |
var Properties = domPropertyConfig.Properties || {}; | |
var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; | |
var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; | |
var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; | |
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; | |
if (domPropertyConfig.isCustomAttribute) { | |
DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute); | |
} | |
for (var propName in Properties) { | |
!!DOMProperty.properties.hasOwnProperty(propName) ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : void 0; | |
var lowerCased = propName.toLowerCase(); | |
var propConfig = Properties[propName]; | |
var propertyInfo = { | |
attributeName: lowerCased, | |
attributeNamespace: null, | |
propertyName: propName, | |
mutationMethod: null, | |
mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), | |
hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), | |
hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), | |
hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), | |
hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) | |
}; | |
!(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : void 0; | |
if ("development" !== 'production') { | |
DOMProperty.getPossibleStandardName[lowerCased] = propName; | |
} | |
if (DOMAttributeNames.hasOwnProperty(propName)) { | |
var attributeName = DOMAttributeNames[propName]; | |
propertyInfo.attributeName = attributeName; | |
if ("development" !== 'production') { | |
DOMProperty.getPossibleStandardName[attributeName] = propName; | |
} | |
} | |
if (DOMAttributeNamespaces.hasOwnProperty(propName)) { | |
propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; | |
} | |
if (DOMPropertyNames.hasOwnProperty(propName)) { | |
propertyInfo.propertyName = DOMPropertyNames[propName]; | |
} | |
if (DOMMutationMethods.hasOwnProperty(propName)) { | |
propertyInfo.mutationMethod = DOMMutationMethods[propName]; | |
} | |
DOMProperty.properties[propName] = propertyInfo; | |
} | |
} | |
}; | |
/* eslint-disable max-len */ | |
var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; | |
/* eslint-enable max-len */ | |
/** | |
* DOMProperty exports lookup objects that can be used like functions: | |
* | |
* > DOMProperty.isValid['id'] | |
* true | |
* > DOMProperty.isValid['foobar'] | |
* undefined | |
* | |
* Although this may be confusing, it performs better in general. | |
* | |
* @see http://jsperf.com/key-exists | |
* @see http://jsperf.com/key-missing | |
*/ | |
var DOMProperty = { | |
ID_ATTRIBUTE_NAME: 'data-reactid', | |
ROOT_ATTRIBUTE_NAME: 'data-reactroot', | |
ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, | |
ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040', | |
/** | |
* Map from property "standard name" to an object with info about how to set | |
* the property in the DOM. Each object contains: | |
* | |
* attributeName: | |
* Used when rendering markup or with `*Attribute()`. | |
* attributeNamespace | |
* propertyName: | |
* Used on DOM node instances. (This includes properties that mutate due to | |
* external factors.) | |
* mutationMethod: | |
* If non-null, used instead of the property or `setAttribute()` after | |
* initial render. | |
* mustUseProperty: | |
* Whether the property must be accessed and mutated as an object property. | |
* hasBooleanValue: | |
* Whether the property should be removed when set to a falsey value. | |
* hasNumericValue: | |
* Whether the property must be numeric or parse as a numeric and should be | |
* removed when set to a falsey value. | |
* hasPositiveNumericValue: | |
* Whether the property must be positive numeric or parse as a positive | |
* numeric and should be removed when set to a falsey value. | |
* hasOverloadedBooleanValue: | |
* Whether the property can be used as a flag as well as with a value. | |
* Removed when strictly equal to false; present without a value when | |
* strictly equal to true; present with a value otherwise. | |
*/ | |
properties: {}, | |
/** | |
* Mapping from lowercase property names to the properly cased version, used | |
* to warn in the case of missing properties. Available only in __DEV__. | |
* @type {Object} | |
*/ | |
getPossibleStandardName: {}, | |
/** | |
* All of the isCustomAttribute() functions that have been injected. | |
*/ | |
_isCustomAttributeFunctions: [], | |
/** | |
* Checks whether a property name is a custom attribute. | |
* @method | |
*/ | |
isCustomAttribute: function (attributeName) { | |
for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { | |
var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; | |
if (isCustomAttributeFn(attributeName)) { | |
return true; | |
} | |
} | |
return false; | |
}, | |
injection: DOMPropertyInjection | |
}; | |
module.exports = DOMProperty; | |
}); | |
var DOMProperty$1 = interopDefault(DOMProperty); | |
var require$$19 = Object.freeze({ | |
default: DOMProperty$1 | |
}); | |
var ReactDOMComponentFlags = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2015-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMComponentFlags | |
*/ | |
'use strict'; | |
var ReactDOMComponentFlags = { | |
hasCachedChildNodes: 1 << 0 | |
}; | |
module.exports = ReactDOMComponentFlags; | |
}); | |
var ReactDOMComponentFlags$1 = interopDefault(ReactDOMComponentFlags); | |
var require$$16 = Object.freeze({ | |
default: ReactDOMComponentFlags$1 | |
}); | |
var ReactDOMComponentTree = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMComponentTree | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var DOMProperty = interopDefault(require$$19); | |
var ReactDOMComponentFlags = interopDefault(require$$16); | |
var invariant = interopDefault(require$$0$33); | |
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; | |
var Flags = ReactDOMComponentFlags; | |
var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2); | |
/** | |
* Drill down (through composites and empty components) until we get a host or | |
* host text component. | |
* | |
* This is pretty polymorphic but unavoidable with the current structure we have | |
* for `_renderedChildren`. | |
*/ | |
function getRenderedHostOrTextFromComponent(component) { | |
var rendered; | |
while (rendered = component._renderedComponent) { | |
component = rendered; | |
} | |
return component; | |
} | |
/** | |
* Populate `_hostNode` on the rendered host/text component with the given | |
* DOM node. The passed `inst` can be a composite. | |
*/ | |
function precacheNode(inst, node) { | |
var hostInst = getRenderedHostOrTextFromComponent(inst); | |
hostInst._hostNode = node; | |
node[internalInstanceKey] = hostInst; | |
} | |
function uncacheNode(inst) { | |
var node = inst._hostNode; | |
if (node) { | |
delete node[internalInstanceKey]; | |
inst._hostNode = null; | |
} | |
} | |
/** | |
* Populate `_hostNode` on each child of `inst`, assuming that the children | |
* match up with the DOM (element) children of `node`. | |
* | |
* We cache entire levels at once to avoid an n^2 problem where we access the | |
* children of a node sequentially and have to walk from the start to our target | |
* node every time. | |
* | |
* Since we update `_renderedChildren` and the actual DOM at (slightly) | |
* different times, we could race here and see a newer `_renderedChildren` than | |
* the DOM nodes we see. To avoid this, ReactMultiChild calls | |
* `prepareToManageChildren` before we change `_renderedChildren`, at which | |
* time the container's child nodes are always cached (until it unmounts). | |
*/ | |
function precacheChildNodes(inst, node) { | |
if (inst._flags & Flags.hasCachedChildNodes) { | |
return; | |
} | |
var children = inst._renderedChildren; | |
var childNode = node.firstChild; | |
outer: for (var name in children) { | |
if (!children.hasOwnProperty(name)) { | |
continue; | |
} | |
var childInst = children[name]; | |
var childID = getRenderedHostOrTextFromComponent(childInst)._domID; | |
if (childID == null) { | |
// We're currently unmounting this child in ReactMultiChild; skip it. | |
continue; | |
} | |
// We assume the child nodes are in the same order as the child instances. | |
for (; childNode !== null; childNode = childNode.nextSibling) { | |
if (childNode.nodeType === 1 && childNode.getAttribute(ATTR_NAME) === String(childID) || childNode.nodeType === 8 && childNode.nodeValue === ' react-text: ' + childID + ' ' || childNode.nodeType === 8 && childNode.nodeValue === ' react-empty: ' + childID + ' ') { | |
precacheNode(childInst, childNode); | |
continue outer; | |
} | |
} | |
// We reached the end of the DOM children without finding an ID match. | |
invariant(false, 'Unable to find element with ID %s.', childID); | |
} | |
inst._flags |= Flags.hasCachedChildNodes; | |
} | |
/** | |
* Given a DOM node, return the closest ReactDOMComponent or | |
* ReactDOMTextComponent instance ancestor. | |
*/ | |
function getClosestInstanceFromNode(node) { | |
if (node[internalInstanceKey]) { | |
return node[internalInstanceKey]; | |
} | |
// Walk up the tree until we find an ancestor whose instance we have cached. | |
var parents = []; | |
while (!node[internalInstanceKey]) { | |
parents.push(node); | |
if (node.parentNode) { | |
node = node.parentNode; | |
} else { | |
// Top of the tree. This node must not be part of a React tree (or is | |
// unmounted, potentially). | |
return null; | |
} | |
} | |
var closest; | |
var inst; | |
for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { | |
closest = inst; | |
if (parents.length) { | |
precacheChildNodes(inst, node); | |
} | |
} | |
return closest; | |
} | |
/** | |
* Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent | |
* instance, or null if the node was not rendered by this React. | |
*/ | |
function getInstanceFromNode(node) { | |
var inst = getClosestInstanceFromNode(node); | |
if (inst != null && inst._hostNode === node) { | |
return inst; | |
} else { | |
return null; | |
} | |
} | |
/** | |
* Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding | |
* DOM node. | |
*/ | |
function getNodeFromInstance(inst) { | |
// Without this first invariant, passing a non-DOM-component triggers the next | |
// invariant for a missing parent, which is super confusing. | |
!(inst._hostNode !== undefined) ? invariant(false, 'getNodeFromInstance: Invalid argument.') : void 0; | |
if (inst._hostNode) { | |
return inst._hostNode; | |
} | |
// Walk up the tree until we find an ancestor whose DOM node we have cached. | |
var parents = []; | |
while (!inst._hostNode) { | |
parents.push(inst); | |
!inst._hostParent ? invariant(false, 'React DOM tree root should always have a node reference.') : void 0; | |
inst = inst._hostParent; | |
} | |
// Now parents contains each ancestor that does *not* have a cached native | |
// node, and `inst` is the deepest ancestor that does. | |
for (; parents.length; inst = parents.pop()) { | |
precacheChildNodes(inst, inst._hostNode); | |
} | |
return inst._hostNode; | |
} | |
var ReactDOMComponentTree = { | |
getClosestInstanceFromNode: getClosestInstanceFromNode, | |
getInstanceFromNode: getInstanceFromNode, | |
getNodeFromInstance: getNodeFromInstance, | |
precacheChildNodes: precacheChildNodes, | |
precacheNode: precacheNode, | |
uncacheNode: uncacheNode | |
}; | |
module.exports = ReactDOMComponentTree; | |
}); | |
var ReactDOMComponentTree$1 = interopDefault(ReactDOMComponentTree); | |
var require$$4$9 = Object.freeze({ | |
default: ReactDOMComponentTree$1 | |
}); | |
var EventConstants = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EventConstants | |
*/ | |
'use strict'; | |
var keyMirror = interopDefault(require$$0$36); | |
var PropagationPhases = keyMirror({ bubbled: null, captured: null }); | |
/** | |
* Types of raw signals from the browser caught at the top level. | |
*/ | |
var topLevelTypes = keyMirror({ | |
topAbort: null, | |
topAnimationEnd: null, | |
topAnimationIteration: null, | |
topAnimationStart: null, | |
topBlur: null, | |
topCanPlay: null, | |
topCanPlayThrough: null, | |
topChange: null, | |
topClick: null, | |
topCompositionEnd: null, | |
topCompositionStart: null, | |
topCompositionUpdate: null, | |
topContextMenu: null, | |
topCopy: null, | |
topCut: null, | |
topDoubleClick: null, | |
topDrag: null, | |
topDragEnd: null, | |
topDragEnter: null, | |
topDragExit: null, | |
topDragLeave: null, | |
topDragOver: null, | |
topDragStart: null, | |
topDrop: null, | |
topDurationChange: null, | |
topEmptied: null, | |
topEncrypted: null, | |
topEnded: null, | |
topError: null, | |
topFocus: null, | |
topInput: null, | |
topInvalid: null, | |
topKeyDown: null, | |
topKeyPress: null, | |
topKeyUp: null, | |
topLoad: null, | |
topLoadedData: null, | |
topLoadedMetadata: null, | |
topLoadStart: null, | |
topMouseDown: null, | |
topMouseMove: null, | |
topMouseOut: null, | |
topMouseOver: null, | |
topMouseUp: null, | |
topPaste: null, | |
topPause: null, | |
topPlay: null, | |
topPlaying: null, | |
topProgress: null, | |
topRateChange: null, | |
topReset: null, | |
topScroll: null, | |
topSeeked: null, | |
topSeeking: null, | |
topSelectionChange: null, | |
topStalled: null, | |
topSubmit: null, | |
topSuspend: null, | |
topTextInput: null, | |
topTimeUpdate: null, | |
topTouchCancel: null, | |
topTouchEnd: null, | |
topTouchMove: null, | |
topTouchStart: null, | |
topTransitionEnd: null, | |
topVolumeChange: null, | |
topWaiting: null, | |
topWheel: null | |
}); | |
var EventConstants = { | |
topLevelTypes: topLevelTypes, | |
PropagationPhases: PropagationPhases | |
}; | |
module.exports = EventConstants; | |
}); | |
var EventConstants$1 = interopDefault(EventConstants); | |
var require$$18 = Object.freeze({ | |
default: EventConstants$1 | |
}); | |
var EventPluginRegistry = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EventPluginRegistry | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Injectable ordering of event plugins. | |
*/ | |
var EventPluginOrder = null; | |
/** | |
* Injectable mapping from names to event plugin modules. | |
*/ | |
var namesToPlugins = {}; | |
/** | |
* Recomputes the plugin list using the injected plugins and plugin ordering. | |
* | |
* @private | |
*/ | |
function recomputePluginOrdering() { | |
if (!EventPluginOrder) { | |
// Wait until an `EventPluginOrder` is injected. | |
return; | |
} | |
for (var pluginName in namesToPlugins) { | |
var PluginModule = namesToPlugins[pluginName]; | |
var pluginIndex = EventPluginOrder.indexOf(pluginName); | |
!(pluginIndex > -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0; | |
if (EventPluginRegistry.plugins[pluginIndex]) { | |
continue; | |
} | |
!PluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0; | |
EventPluginRegistry.plugins[pluginIndex] = PluginModule; | |
var publishedEvents = PluginModule.eventTypes; | |
for (var eventName in publishedEvents) { | |
!publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0; | |
} | |
} | |
} | |
/** | |
* Publishes an event so that it can be dispatched by the supplied plugin. | |
* | |
* @param {object} dispatchConfig Dispatch configuration for the event. | |
* @param {object} PluginModule Plugin publishing the event. | |
* @return {boolean} True if the event was successfully published. | |
* @private | |
*/ | |
function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { | |
!!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0; | |
EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; | |
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; | |
if (phasedRegistrationNames) { | |
for (var phaseName in phasedRegistrationNames) { | |
if (phasedRegistrationNames.hasOwnProperty(phaseName)) { | |
var phasedRegistrationName = phasedRegistrationNames[phaseName]; | |
publishRegistrationName(phasedRegistrationName, PluginModule, eventName); | |
} | |
} | |
return true; | |
} else if (dispatchConfig.registrationName) { | |
publishRegistrationName(dispatchConfig.registrationName, PluginModule, eventName); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Publishes a registration name that is used to identify dispatched events and | |
* can be used with `EventPluginHub.putListener` to register listeners. | |
* | |
* @param {string} registrationName Registration name to add. | |
* @param {object} PluginModule Plugin publishing the event. | |
* @private | |
*/ | |
function publishRegistrationName(registrationName, PluginModule, eventName) { | |
!!EventPluginRegistry.registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0; | |
EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; | |
EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies; | |
if ("development" !== 'production') { | |
var lowerCasedName = registrationName.toLowerCase(); | |
EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; | |
if (registrationName === 'onDoubleClick') { | |
EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; | |
} | |
} | |
} | |
/** | |
* Registers plugins so that they can extract and dispatch events. | |
* | |
* @see {EventPluginHub} | |
*/ | |
var EventPluginRegistry = { | |
/** | |
* Ordered list of injected plugins. | |
*/ | |
plugins: [], | |
/** | |
* Mapping from event name to dispatch config | |
*/ | |
eventNameDispatchConfigs: {}, | |
/** | |
* Mapping from registration name to plugin module | |
*/ | |
registrationNameModules: {}, | |
/** | |
* Mapping from registration name to event name | |
*/ | |
registrationNameDependencies: {}, | |
/** | |
* Mapping from lowercase registration names to the properly cased version, | |
* used to warn in the case of missing event handlers. Available | |
* only in __DEV__. | |
* @type {Object} | |
*/ | |
possibleRegistrationNames: {}, | |
/** | |
* Injects an ordering of plugins (by plugin name). This allows the ordering | |
* to be decoupled from injection of the actual plugins so that ordering is | |
* always deterministic regardless of packaging, on-the-fly injection, etc. | |
* | |
* @param {array} InjectedEventPluginOrder | |
* @internal | |
* @see {EventPluginHub.injection.injectEventPluginOrder} | |
*/ | |
injectEventPluginOrder: function (InjectedEventPluginOrder) { | |
!!EventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0; | |
// Clone the ordering so it cannot be dynamically mutated. | |
EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); | |
recomputePluginOrdering(); | |
}, | |
/** | |
* Injects plugins to be used by `EventPluginHub`. The plugin names must be | |
* in the ordering injected by `injectEventPluginOrder`. | |
* | |
* Plugins can be injected as part of page initialization or on-the-fly. | |
* | |
* @param {object} injectedNamesToPlugins Map from names to plugin modules. | |
* @internal | |
* @see {EventPluginHub.injection.injectEventPluginsByName} | |
*/ | |
injectEventPluginsByName: function (injectedNamesToPlugins) { | |
var isOrderingDirty = false; | |
for (var pluginName in injectedNamesToPlugins) { | |
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { | |
continue; | |
} | |
var PluginModule = injectedNamesToPlugins[pluginName]; | |
if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== PluginModule) { | |
!!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0; | |
namesToPlugins[pluginName] = PluginModule; | |
isOrderingDirty = true; | |
} | |
} | |
if (isOrderingDirty) { | |
recomputePluginOrdering(); | |
} | |
}, | |
/** | |
* Looks up the plugin for the supplied event. | |
* | |
* @param {object} event A synthetic event. | |
* @return {?object} The plugin that created the supplied event. | |
* @internal | |
*/ | |
getPluginModuleForEvent: function (event) { | |
var dispatchConfig = event.dispatchConfig; | |
if (dispatchConfig.registrationName) { | |
return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName] || null; | |
} | |
for (var phase in dispatchConfig.phasedRegistrationNames) { | |
if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { | |
continue; | |
} | |
var PluginModule = EventPluginRegistry.registrationNameModules[dispatchConfig.phasedRegistrationNames[phase]]; | |
if (PluginModule) { | |
return PluginModule; | |
} | |
} | |
return null; | |
}, | |
/** | |
* Exposed for unit testing. | |
* @private | |
*/ | |
_resetEventPlugins: function () { | |
EventPluginOrder = null; | |
for (var pluginName in namesToPlugins) { | |
if (namesToPlugins.hasOwnProperty(pluginName)) { | |
delete namesToPlugins[pluginName]; | |
} | |
} | |
EventPluginRegistry.plugins.length = 0; | |
var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; | |
for (var eventName in eventNameDispatchConfigs) { | |
if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { | |
delete eventNameDispatchConfigs[eventName]; | |
} | |
} | |
var registrationNameModules = EventPluginRegistry.registrationNameModules; | |
for (var registrationName in registrationNameModules) { | |
if (registrationNameModules.hasOwnProperty(registrationName)) { | |
delete registrationNameModules[registrationName]; | |
} | |
} | |
if ("development" !== 'production') { | |
var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames; | |
for (var lowerCasedName in possibleRegistrationNames) { | |
if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) { | |
delete possibleRegistrationNames[lowerCasedName]; | |
} | |
} | |
} | |
} | |
}; | |
module.exports = EventPluginRegistry; | |
}); | |
var EventPluginRegistry$1 = interopDefault(EventPluginRegistry); | |
var require$$4$10 = Object.freeze({ | |
default: EventPluginRegistry$1 | |
}); | |
var ReactErrorUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactErrorUtils | |
*/ | |
'use strict'; | |
var caughtError = null; | |
/** | |
* Call a function while guarding against errors that happens within it. | |
* | |
* @param {?String} name of the guard to use for logging or debugging | |
* @param {Function} func The function to invoke | |
* @param {*} a First argument | |
* @param {*} b Second argument | |
*/ | |
function invokeGuardedCallback(name, func, a, b) { | |
try { | |
return func(a, b); | |
} catch (x) { | |
if (caughtError === null) { | |
caughtError = x; | |
} | |
return undefined; | |
} | |
} | |
var ReactErrorUtils = { | |
invokeGuardedCallback: invokeGuardedCallback, | |
/** | |
* Invoked by ReactTestUtils.Simulate so that any errors thrown by the event | |
* handler are sure to be rethrown by rethrowCaughtError. | |
*/ | |
invokeGuardedCallbackWithCatch: invokeGuardedCallback, | |
/** | |
* During execution of guarded functions we will capture the first error which | |
* we will rethrow to be handled by the top level error handler. | |
*/ | |
rethrowCaughtError: function () { | |
if (caughtError) { | |
var error = caughtError; | |
caughtError = null; | |
throw error; | |
} | |
} | |
}; | |
if ("development" !== 'production') { | |
/** | |
* To help development we can get better devtools integration by simulating a | |
* real browser event. | |
*/ | |
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { | |
var fakeNode = document.createElement('react'); | |
ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) { | |
var boundFunc = func.bind(null, a, b); | |
var evtType = 'react-' + name; | |
fakeNode.addEventListener(evtType, boundFunc, false); | |
var evt = document.createEvent('Event'); | |
evt.initEvent(evtType, false, false); | |
fakeNode.dispatchEvent(evt); | |
fakeNode.removeEventListener(evtType, boundFunc, false); | |
}; | |
} | |
} | |
module.exports = ReactErrorUtils; | |
}); | |
var ReactErrorUtils$1 = interopDefault(ReactErrorUtils); | |
var require$$10 = Object.freeze({ | |
default: ReactErrorUtils$1 | |
}); | |
var EventPluginUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EventPluginUtils | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var EventConstants = interopDefault(require$$18); | |
var ReactErrorUtils = interopDefault(require$$10); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
/** | |
* Injected dependencies: | |
*/ | |
/** | |
* - `ComponentTree`: [required] Module that can convert between React instances | |
* and actual node references. | |
*/ | |
var ComponentTree; | |
var TreeTraversal; | |
var injection = { | |
injectComponentTree: function (Injected) { | |
ComponentTree = Injected; | |
if ("development" !== 'production') { | |
warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.'); | |
} | |
}, | |
injectTreeTraversal: function (Injected) { | |
TreeTraversal = Injected; | |
if ("development" !== 'production') { | |
warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.'); | |
} | |
} | |
}; | |
var topLevelTypes = EventConstants.topLevelTypes; | |
function isEndish(topLevelType) { | |
return topLevelType === topLevelTypes.topMouseUp || topLevelType === topLevelTypes.topTouchEnd || topLevelType === topLevelTypes.topTouchCancel; | |
} | |
function isMoveish(topLevelType) { | |
return topLevelType === topLevelTypes.topMouseMove || topLevelType === topLevelTypes.topTouchMove; | |
} | |
function isStartish(topLevelType) { | |
return topLevelType === topLevelTypes.topMouseDown || topLevelType === topLevelTypes.topTouchStart; | |
} | |
var validateEventDispatches; | |
if ("development" !== 'production') { | |
validateEventDispatches = function (event) { | |
var dispatchListeners = event._dispatchListeners; | |
var dispatchInstances = event._dispatchInstances; | |
var listenersIsArr = Array.isArray(dispatchListeners); | |
var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; | |
var instancesIsArr = Array.isArray(dispatchInstances); | |
var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; | |
warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.'); | |
}; | |
} | |
/** | |
* Dispatch the event to the listener. | |
* @param {SyntheticEvent} event SyntheticEvent to handle | |
* @param {boolean} simulated If the event is simulated (changes exn behavior) | |
* @param {function} listener Application-level callback | |
* @param {*} inst Internal component instance | |
*/ | |
function executeDispatch(event, simulated, listener, inst) { | |
var type = event.type || 'unknown-event'; | |
event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); | |
if (simulated) { | |
ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event); | |
} else { | |
ReactErrorUtils.invokeGuardedCallback(type, listener, event); | |
} | |
event.currentTarget = null; | |
} | |
/** | |
* Standard/simple iteration through an event's collected dispatches. | |
*/ | |
function executeDispatchesInOrder(event, simulated) { | |
var dispatchListeners = event._dispatchListeners; | |
var dispatchInstances = event._dispatchInstances; | |
if ("development" !== 'production') { | |
validateEventDispatches(event); | |
} | |
if (Array.isArray(dispatchListeners)) { | |
for (var i = 0; i < dispatchListeners.length; i++) { | |
if (event.isPropagationStopped()) { | |
break; | |
} | |
// Listeners and Instances are two parallel arrays that are always in sync. | |
executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); | |
} | |
} else if (dispatchListeners) { | |
executeDispatch(event, simulated, dispatchListeners, dispatchInstances); | |
} | |
event._dispatchListeners = null; | |
event._dispatchInstances = null; | |
} | |
/** | |
* Standard/simple iteration through an event's collected dispatches, but stops | |
* at the first dispatch execution returning true, and returns that id. | |
* | |
* @return {?string} id of the first dispatch execution who's listener returns | |
* true, or null if no listener returned true. | |
*/ | |
function executeDispatchesInOrderStopAtTrueImpl(event) { | |
var dispatchListeners = event._dispatchListeners; | |
var dispatchInstances = event._dispatchInstances; | |
if ("development" !== 'production') { | |
validateEventDispatches(event); | |
} | |
if (Array.isArray(dispatchListeners)) { | |
for (var i = 0; i < dispatchListeners.length; i++) { | |
if (event.isPropagationStopped()) { | |
break; | |
} | |
// Listeners and Instances are two parallel arrays that are always in sync. | |
if (dispatchListeners[i](event, dispatchInstances[i])) { | |
return dispatchInstances[i]; | |
} | |
} | |
} else if (dispatchListeners) { | |
if (dispatchListeners(event, dispatchInstances)) { | |
return dispatchInstances; | |
} | |
} | |
return null; | |
} | |
/** | |
* @see executeDispatchesInOrderStopAtTrueImpl | |
*/ | |
function executeDispatchesInOrderStopAtTrue(event) { | |
var ret = executeDispatchesInOrderStopAtTrueImpl(event); | |
event._dispatchInstances = null; | |
event._dispatchListeners = null; | |
return ret; | |
} | |
/** | |
* Execution of a "direct" dispatch - there must be at most one dispatch | |
* accumulated on the event or it is considered an error. It doesn't really make | |
* sense for an event with multiple dispatches (bubbled) to keep track of the | |
* return values at each dispatch execution, but it does tend to make sense when | |
* dealing with "direct" dispatches. | |
* | |
* @return {*} The return value of executing the single dispatch. | |
*/ | |
function executeDirectDispatch(event) { | |
if ("development" !== 'production') { | |
validateEventDispatches(event); | |
} | |
var dispatchListener = event._dispatchListeners; | |
var dispatchInstance = event._dispatchInstances; | |
!!Array.isArray(dispatchListener) ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : void 0; | |
event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; | |
var res = dispatchListener ? dispatchListener(event) : null; | |
event.currentTarget = null; | |
event._dispatchListeners = null; | |
event._dispatchInstances = null; | |
return res; | |
} | |
/** | |
* @param {SyntheticEvent} event | |
* @return {boolean} True iff number of dispatches accumulated is greater than 0. | |
*/ | |
function hasDispatches(event) { | |
return !!event._dispatchListeners; | |
} | |
/** | |
* General utilities that are useful in creating custom Event Plugins. | |
*/ | |
var EventPluginUtils = { | |
isEndish: isEndish, | |
isMoveish: isMoveish, | |
isStartish: isStartish, | |
executeDirectDispatch: executeDirectDispatch, | |
executeDispatchesInOrder: executeDispatchesInOrder, | |
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, | |
hasDispatches: hasDispatches, | |
getInstanceFromNode: function (node) { | |
return ComponentTree.getInstanceFromNode(node); | |
}, | |
getNodeFromInstance: function (node) { | |
return ComponentTree.getNodeFromInstance(node); | |
}, | |
isAncestor: function (a, b) { | |
return TreeTraversal.isAncestor(a, b); | |
}, | |
getLowestCommonAncestor: function (a, b) { | |
return TreeTraversal.getLowestCommonAncestor(a, b); | |
}, | |
getParentInstance: function (inst) { | |
return TreeTraversal.getParentInstance(inst); | |
}, | |
traverseTwoPhase: function (target, fn, arg) { | |
return TreeTraversal.traverseTwoPhase(target, fn, arg); | |
}, | |
traverseEnterLeave: function (from, to, fn, argFrom, argTo) { | |
return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); | |
}, | |
injection: injection | |
}; | |
module.exports = EventPluginUtils; | |
}); | |
var EventPluginUtils$1 = interopDefault(EventPluginUtils); | |
var require$$6$2 = Object.freeze({ | |
default: EventPluginUtils$1 | |
}); | |
var accumulateInto = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2014-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule accumulateInto | |
* | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Accumulates items that must not be null or undefined into the first one. This | |
* is used to conserve memory by avoiding array allocations, and thus sacrifices | |
* API cleanness. Since `current` can be null before being passed in and not | |
* null after this function, make sure to assign it back to `current`: | |
* | |
* `a = accumulateInto(a, b);` | |
* | |
* This API should be sparingly used. Try `accumulate` for something cleaner. | |
* | |
* @return {*|array<*>} An accumulation of items. | |
*/ | |
function accumulateInto(current, next) { | |
!(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0; | |
if (current == null) { | |
return next; | |
} | |
// Both are not empty. Warning: Never call x.concat(y) when you are not | |
// certain that x is an Array (x could be a string with concat method). | |
if (Array.isArray(current)) { | |
if (Array.isArray(next)) { | |
current.push.apply(current, next); | |
return current; | |
} | |
current.push(next); | |
return current; | |
} | |
if (Array.isArray(next)) { | |
// A bit too dangerous to mutate `next`. | |
return [current].concat(next); | |
} | |
return [current, next]; | |
} | |
module.exports = accumulateInto; | |
}); | |
var accumulateInto$1 = interopDefault(accumulateInto); | |
var require$$2$20 = Object.freeze({ | |
default: accumulateInto$1 | |
}); | |
var forEachAccumulated = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule forEachAccumulated | |
* | |
*/ | |
'use strict'; | |
/** | |
* @param {array} arr an "accumulation" of items which is either an Array or | |
* a single item. Useful when paired with the `accumulate` module. This is a | |
* simple utility that allows us to reason about a collection of items, but | |
* handling the case when there is exactly one item (and we do not need to | |
* allocate an array). | |
*/ | |
function forEachAccumulated(arr, cb, scope) { | |
if (Array.isArray(arr)) { | |
arr.forEach(cb, scope); | |
} else if (arr) { | |
cb.call(scope, arr); | |
} | |
} | |
module.exports = forEachAccumulated; | |
}); | |
var forEachAccumulated$1 = interopDefault(forEachAccumulated); | |
var require$$1$19 = Object.freeze({ | |
default: forEachAccumulated$1 | |
}); | |
var EventPluginHub = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EventPluginHub | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var EventPluginRegistry = interopDefault(require$$4$10); | |
var EventPluginUtils = interopDefault(require$$6$2); | |
var ReactErrorUtils = interopDefault(require$$10); | |
var accumulateInto = interopDefault(require$$2$20); | |
var forEachAccumulated = interopDefault(require$$1$19); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Internal store for event listeners | |
*/ | |
var listenerBank = {}; | |
/** | |
* Internal queue of events that have accumulated their dispatches and are | |
* waiting to have their dispatches executed. | |
*/ | |
var eventQueue = null; | |
/** | |
* Dispatches an event and releases it back into the pool, unless persistent. | |
* | |
* @param {?object} event Synthetic event to be dispatched. | |
* @param {boolean} simulated If the event is simulated (changes exn behavior) | |
* @private | |
*/ | |
var executeDispatchesAndRelease = function (event, simulated) { | |
if (event) { | |
EventPluginUtils.executeDispatchesInOrder(event, simulated); | |
if (!event.isPersistent()) { | |
event.constructor.release(event); | |
} | |
} | |
}; | |
var executeDispatchesAndReleaseSimulated = function (e) { | |
return executeDispatchesAndRelease(e, true); | |
}; | |
var executeDispatchesAndReleaseTopLevel = function (e) { | |
return executeDispatchesAndRelease(e, false); | |
}; | |
/** | |
* This is a unified interface for event plugins to be installed and configured. | |
* | |
* Event plugins can implement the following properties: | |
* | |
* `extractEvents` {function(string, DOMEventTarget, string, object): *} | |
* Required. When a top-level event is fired, this method is expected to | |
* extract synthetic events that will in turn be queued and dispatched. | |
* | |
* `eventTypes` {object} | |
* Optional, plugins that fire events must publish a mapping of registration | |
* names that are used to register listeners. Values of this mapping must | |
* be objects that contain `registrationName` or `phasedRegistrationNames`. | |
* | |
* `executeDispatch` {function(object, function, string)} | |
* Optional, allows plugins to override how an event gets dispatched. By | |
* default, the listener is simply invoked. | |
* | |
* Each plugin that is injected into `EventsPluginHub` is immediately operable. | |
* | |
* @public | |
*/ | |
var EventPluginHub = { | |
/** | |
* Methods for injecting dependencies. | |
*/ | |
injection: { | |
/** | |
* @param {array} InjectedEventPluginOrder | |
* @public | |
*/ | |
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, | |
/** | |
* @param {object} injectedNamesToPlugins Map from names to plugin modules. | |
*/ | |
injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName | |
}, | |
/** | |
* Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. | |
* | |
* @param {object} inst The instance, which is the source of events. | |
* @param {string} registrationName Name of listener (e.g. `onClick`). | |
* @param {function} listener The callback to store. | |
*/ | |
putListener: function (inst, registrationName, listener) { | |
!(typeof listener === 'function') ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : void 0; | |
var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); | |
bankForRegistrationName[inst._rootNodeID] = listener; | |
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; | |
if (PluginModule && PluginModule.didPutListener) { | |
PluginModule.didPutListener(inst, registrationName, listener); | |
} | |
}, | |
/** | |
* @param {object} inst The instance, which is the source of events. | |
* @param {string} registrationName Name of listener (e.g. `onClick`). | |
* @return {?function} The stored callback. | |
*/ | |
getListener: function (inst, registrationName) { | |
var bankForRegistrationName = listenerBank[registrationName]; | |
return bankForRegistrationName && bankForRegistrationName[inst._rootNodeID]; | |
}, | |
/** | |
* Deletes a listener from the registration bank. | |
* | |
* @param {object} inst The instance, which is the source of events. | |
* @param {string} registrationName Name of listener (e.g. `onClick`). | |
*/ | |
deleteListener: function (inst, registrationName) { | |
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; | |
if (PluginModule && PluginModule.willDeleteListener) { | |
PluginModule.willDeleteListener(inst, registrationName); | |
} | |
var bankForRegistrationName = listenerBank[registrationName]; | |
// TODO: This should never be null -- when is it? | |
if (bankForRegistrationName) { | |
delete bankForRegistrationName[inst._rootNodeID]; | |
} | |
}, | |
/** | |
* Deletes all listeners for the DOM element with the supplied ID. | |
* | |
* @param {object} inst The instance, which is the source of events. | |
*/ | |
deleteAllListeners: function (inst) { | |
for (var registrationName in listenerBank) { | |
if (!listenerBank.hasOwnProperty(registrationName)) { | |
continue; | |
} | |
if (!listenerBank[registrationName][inst._rootNodeID]) { | |
continue; | |
} | |
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; | |
if (PluginModule && PluginModule.willDeleteListener) { | |
PluginModule.willDeleteListener(inst, registrationName); | |
} | |
delete listenerBank[registrationName][inst._rootNodeID]; | |
} | |
}, | |
/** | |
* Allows registered plugins an opportunity to extract events from top-level | |
* native browser events. | |
* | |
* @return {*} An accumulation of synthetic events. | |
* @internal | |
*/ | |
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
var events; | |
var plugins = EventPluginRegistry.plugins; | |
for (var i = 0; i < plugins.length; i++) { | |
// Not every plugin in the ordering may be loaded at runtime. | |
var possiblePlugin = plugins[i]; | |
if (possiblePlugin) { | |
var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); | |
if (extractedEvents) { | |
events = accumulateInto(events, extractedEvents); | |
} | |
} | |
} | |
return events; | |
}, | |
/** | |
* Enqueues a synthetic event that should be dispatched when | |
* `processEventQueue` is invoked. | |
* | |
* @param {*} events An accumulation of synthetic events. | |
* @internal | |
*/ | |
enqueueEvents: function (events) { | |
if (events) { | |
eventQueue = accumulateInto(eventQueue, events); | |
} | |
}, | |
/** | |
* Dispatches all synthetic events on the event queue. | |
* | |
* @internal | |
*/ | |
processEventQueue: function (simulated) { | |
// Set `eventQueue` to null before processing it so that we can tell if more | |
// events get enqueued while processing. | |
var processingEventQueue = eventQueue; | |
eventQueue = null; | |
if (simulated) { | |
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); | |
} else { | |
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); | |
} | |
!!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0; | |
// This would be a good time to rethrow if any of the event handlers threw. | |
ReactErrorUtils.rethrowCaughtError(); | |
}, | |
/** | |
* These are needed for tests only. Do not use! | |
*/ | |
__purge: function () { | |
listenerBank = {}; | |
}, | |
__getListenerBank: function () { | |
return listenerBank; | |
} | |
}; | |
module.exports = EventPluginHub; | |
}); | |
var EventPluginHub$1 = interopDefault(EventPluginHub); | |
var require$$7$1 = Object.freeze({ | |
default: EventPluginHub$1 | |
}); | |
var EventPropagators = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EventPropagators | |
*/ | |
'use strict'; | |
var EventConstants = interopDefault(require$$18); | |
var EventPluginHub = interopDefault(require$$7$1); | |
var EventPluginUtils = interopDefault(require$$6$2); | |
var accumulateInto = interopDefault(require$$2$20); | |
var forEachAccumulated = interopDefault(require$$1$19); | |
var warning = interopDefault(require$$0$34); | |
var PropagationPhases = EventConstants.PropagationPhases; | |
var getListener = EventPluginHub.getListener; | |
/** | |
* Some event types have a notion of different registration names for different | |
* "phases" of propagation. This finds listeners by a given phase. | |
*/ | |
function listenerAtPhase(inst, event, propagationPhase) { | |
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; | |
return getListener(inst, registrationName); | |
} | |
/** | |
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function | |
* here, allows us to not have to bind or create functions for each event. | |
* Mutating the event's members allows us to not have to create a wrapping | |
* "dispatch" object that pairs the event with the listener. | |
*/ | |
function accumulateDirectionalDispatches(inst, upwards, event) { | |
if ("development" !== 'production') { | |
warning(inst, 'Dispatching inst must not be null'); | |
} | |
var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; | |
var listener = listenerAtPhase(inst, event, phase); | |
if (listener) { | |
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); | |
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); | |
} | |
} | |
/** | |
* Collect dispatches (must be entirely collected before dispatching - see unit | |
* tests). Lazily allocate the array to conserve memory. We must loop through | |
* each event and perform the traversal for each one. We cannot perform a | |
* single traversal for the entire collection of events because each event may | |
* have a different target. | |
*/ | |
function accumulateTwoPhaseDispatchesSingle(event) { | |
if (event && event.dispatchConfig.phasedRegistrationNames) { | |
EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); | |
} | |
} | |
/** | |
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. | |
*/ | |
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { | |
if (event && event.dispatchConfig.phasedRegistrationNames) { | |
var targetInst = event._targetInst; | |
var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null; | |
EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); | |
} | |
} | |
/** | |
* Accumulates without regard to direction, does not look for phased | |
* registration names. Same as `accumulateDirectDispatchesSingle` but without | |
* requiring that the `dispatchMarker` be the same as the dispatched ID. | |
*/ | |
function accumulateDispatches(inst, ignoredDirection, event) { | |
if (event && event.dispatchConfig.registrationName) { | |
var registrationName = event.dispatchConfig.registrationName; | |
var listener = getListener(inst, registrationName); | |
if (listener) { | |
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); | |
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); | |
} | |
} | |
} | |
/** | |
* Accumulates dispatches on an `SyntheticEvent`, but only for the | |
* `dispatchMarker`. | |
* @param {SyntheticEvent} event | |
*/ | |
function accumulateDirectDispatchesSingle(event) { | |
if (event && event.dispatchConfig.registrationName) { | |
accumulateDispatches(event._targetInst, null, event); | |
} | |
} | |
function accumulateTwoPhaseDispatches(events) { | |
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); | |
} | |
function accumulateTwoPhaseDispatchesSkipTarget(events) { | |
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); | |
} | |
function accumulateEnterLeaveDispatches(leave, enter, from, to) { | |
EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); | |
} | |
function accumulateDirectDispatches(events) { | |
forEachAccumulated(events, accumulateDirectDispatchesSingle); | |
} | |
/** | |
* A small set of propagation patterns, each of which will accept a small amount | |
* of information, and generate a set of "dispatch ready event objects" - which | |
* are sets of events that have already been annotated with a set of dispatched | |
* listener functions/ids. The API is designed this way to discourage these | |
* propagation strategies from actually executing the dispatches, since we | |
* always want to collect the entire set of dispatches before executing event a | |
* single one. | |
* | |
* @constructor EventPropagators | |
*/ | |
var EventPropagators = { | |
accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, | |
accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, | |
accumulateDirectDispatches: accumulateDirectDispatches, | |
accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches | |
}; | |
module.exports = EventPropagators; | |
}); | |
var EventPropagators$1 = interopDefault(EventPropagators); | |
var require$$16$1 = Object.freeze({ | |
default: EventPropagators$1 | |
}); | |
var ExecutionEnvironment = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); | |
/** | |
* Simple, lightweight module assisting with the detection and context of | |
* Worker. Helps avoid circular dependencies and allows code to reason about | |
* whether or not they are in a Worker, even if they never include the main | |
* `ReactWorker` dependency. | |
*/ | |
var ExecutionEnvironment = { | |
canUseDOM: canUseDOM, | |
canUseWorkers: typeof Worker !== 'undefined', | |
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), | |
canUseViewport: canUseDOM && !!window.screen, | |
isInWorker: !canUseDOM // For now, this is true - might change in the future. | |
}; | |
module.exports = ExecutionEnvironment; | |
}); | |
var ExecutionEnvironment$1 = interopDefault(ExecutionEnvironment); | |
var require$$7$2 = Object.freeze({ | |
default: ExecutionEnvironment$1 | |
}); | |
var getTextContentAccessor = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule getTextContentAccessor | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var contentKey = null; | |
/** | |
* Gets the key used to access text content on a DOM node. | |
* | |
* @return {?string} Key used to access text content. | |
* @internal | |
*/ | |
function getTextContentAccessor() { | |
if (!contentKey && ExecutionEnvironment.canUseDOM) { | |
// Prefer textContent to innerText because many browsers support both but | |
// SVG <text> elements don't support innerText even when <div> does. | |
contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText'; | |
} | |
return contentKey; | |
} | |
module.exports = getTextContentAccessor; | |
}); | |
var getTextContentAccessor$1 = interopDefault(getTextContentAccessor); | |
var require$$0$42 = Object.freeze({ | |
default: getTextContentAccessor$1 | |
}); | |
var FallbackCompositionState = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule FallbackCompositionState | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var PooledClass = interopDefault(require$$5$2); | |
var getTextContentAccessor = interopDefault(require$$0$42); | |
/** | |
* This helper class stores information about text content of a target node, | |
* allowing comparison of content before and after a given event. | |
* | |
* Identify the node where selection currently begins, then observe | |
* both its text content and its current position in the DOM. Since the | |
* browser may natively replace the target node during composition, we can | |
* use its position to find its replacement. | |
* | |
* @param {DOMEventTarget} root | |
*/ | |
function FallbackCompositionState(root) { | |
this._root = root; | |
this._startText = this.getText(); | |
this._fallbackText = null; | |
} | |
_assign(FallbackCompositionState.prototype, { | |
destructor: function () { | |
this._root = null; | |
this._startText = null; | |
this._fallbackText = null; | |
}, | |
/** | |
* Get current text of input. | |
* | |
* @return {string} | |
*/ | |
getText: function () { | |
if ('value' in this._root) { | |
return this._root.value; | |
} | |
return this._root[getTextContentAccessor()]; | |
}, | |
/** | |
* Determine the differing substring between the initially stored | |
* text content and the current content. | |
* | |
* @return {string} | |
*/ | |
getData: function () { | |
if (this._fallbackText) { | |
return this._fallbackText; | |
} | |
var start; | |
var startValue = this._startText; | |
var startLength = startValue.length; | |
var end; | |
var endValue = this.getText(); | |
var endLength = endValue.length; | |
for (start = 0; start < startLength; start++) { | |
if (startValue[start] !== endValue[start]) { | |
break; | |
} | |
} | |
var minEnd = startLength - start; | |
for (end = 1; end <= minEnd; end++) { | |
if (startValue[startLength - end] !== endValue[endLength - end]) { | |
break; | |
} | |
} | |
var sliceTail = end > 1 ? 1 - end : undefined; | |
this._fallbackText = endValue.slice(start, sliceTail); | |
return this._fallbackText; | |
} | |
}); | |
PooledClass.addPoolingTo(FallbackCompositionState); | |
module.exports = FallbackCompositionState; | |
}); | |
var FallbackCompositionState$1 = interopDefault(FallbackCompositionState); | |
var require$$3$13 = Object.freeze({ | |
default: FallbackCompositionState$1 | |
}); | |
var SyntheticEvent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule SyntheticEvent | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var PooledClass = interopDefault(require$$5$2); | |
var emptyFunction = interopDefault(require$$3$10); | |
var warning = interopDefault(require$$0$34); | |
var didWarnForAddedNewProperty = false; | |
var isProxySupported = typeof Proxy === 'function'; | |
var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; | |
/** | |
* @interface Event | |
* @see http://www.w3.org/TR/DOM-Level-3-Events/ | |
*/ | |
var EventInterface = { | |
type: null, | |
target: null, | |
// currentTarget is set when dispatching; no use in copying it here | |
currentTarget: emptyFunction.thatReturnsNull, | |
eventPhase: null, | |
bubbles: null, | |
cancelable: null, | |
timeStamp: function (event) { | |
return event.timeStamp || Date.now(); | |
}, | |
defaultPrevented: null, | |
isTrusted: null | |
}; | |
/** | |
* Synthetic events are dispatched by event plugins, typically in response to a | |
* top-level event delegation handler. | |
* | |
* These systems should generally use pooling to reduce the frequency of garbage | |
* collection. The system should check `isPersistent` to determine whether the | |
* event should be released into the pool after being dispatched. Users that | |
* need a persisted event should invoke `persist`. | |
* | |
* Synthetic events (and subclasses) implement the DOM Level 3 Events API by | |
* normalizing browser quirks. Subclasses do not necessarily have to implement a | |
* DOM interface; custom application-specific events can also subclass this. | |
* | |
* @param {object} dispatchConfig Configuration used to dispatch this event. | |
* @param {*} targetInst Marker identifying the event target. | |
* @param {object} nativeEvent Native browser event. | |
* @param {DOMEventTarget} nativeEventTarget Target node. | |
*/ | |
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { | |
if ("development" !== 'production') { | |
// these have a getter/setter for warnings | |
delete this.nativeEvent; | |
delete this.preventDefault; | |
delete this.stopPropagation; | |
} | |
this.dispatchConfig = dispatchConfig; | |
this._targetInst = targetInst; | |
this.nativeEvent = nativeEvent; | |
var Interface = this.constructor.Interface; | |
for (var propName in Interface) { | |
if (!Interface.hasOwnProperty(propName)) { | |
continue; | |
} | |
if ("development" !== 'production') { | |
delete this[propName]; // this has a getter/setter for warnings | |
} | |
var normalize = Interface[propName]; | |
if (normalize) { | |
this[propName] = normalize(nativeEvent); | |
} else { | |
if (propName === 'target') { | |
this.target = nativeEventTarget; | |
} else { | |
this[propName] = nativeEvent[propName]; | |
} | |
} | |
} | |
var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; | |
if (defaultPrevented) { | |
this.isDefaultPrevented = emptyFunction.thatReturnsTrue; | |
} else { | |
this.isDefaultPrevented = emptyFunction.thatReturnsFalse; | |
} | |
this.isPropagationStopped = emptyFunction.thatReturnsFalse; | |
return this; | |
} | |
_assign(SyntheticEvent.prototype, { | |
preventDefault: function () { | |
this.defaultPrevented = true; | |
var event = this.nativeEvent; | |
if (!event) { | |
return; | |
} | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} else { | |
event.returnValue = false; | |
} | |
this.isDefaultPrevented = emptyFunction.thatReturnsTrue; | |
}, | |
stopPropagation: function () { | |
var event = this.nativeEvent; | |
if (!event) { | |
return; | |
} | |
if (event.stopPropagation) { | |
event.stopPropagation(); | |
} else { | |
event.cancelBubble = true; | |
} | |
this.isPropagationStopped = emptyFunction.thatReturnsTrue; | |
}, | |
/** | |
* We release all dispatched `SyntheticEvent`s after each event loop, adding | |
* them back into the pool. This allows a way to hold onto a reference that | |
* won't be added back into the pool. | |
*/ | |
persist: function () { | |
this.isPersistent = emptyFunction.thatReturnsTrue; | |
}, | |
/** | |
* Checks if this event should be released back into the pool. | |
* | |
* @return {boolean} True if this should not be released, false otherwise. | |
*/ | |
isPersistent: emptyFunction.thatReturnsFalse, | |
/** | |
* `PooledClass` looks for `destructor` on each instance it releases. | |
*/ | |
destructor: function () { | |
var Interface = this.constructor.Interface; | |
for (var propName in Interface) { | |
if ("development" !== 'production') { | |
Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); | |
} else {} | |
} | |
for (var i = 0; i < shouldBeReleasedProperties.length; i++) { | |
this[shouldBeReleasedProperties[i]] = null; | |
} | |
if ("development" !== 'production') { | |
Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); | |
Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); | |
Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); | |
} | |
} | |
}); | |
SyntheticEvent.Interface = EventInterface; | |
if ("development" !== 'production') { | |
if (isProxySupported) { | |
/*eslint-disable no-func-assign */ | |
SyntheticEvent = new Proxy(SyntheticEvent, { | |
construct: function (target, args) { | |
return this.apply(target, Object.create(target.prototype), args); | |
}, | |
apply: function (constructor, that, args) { | |
return new Proxy(constructor.apply(that, args), { | |
set: function (target, prop, value) { | |
if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { | |
warning(didWarnForAddedNewProperty || target.isPersistent(), 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re adding a new property in the synthetic event object. ' + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.'); | |
didWarnForAddedNewProperty = true; | |
} | |
target[prop] = value; | |
return true; | |
} | |
}); | |
} | |
}); | |
/*eslint-enable no-func-assign */ | |
} | |
} | |
/** | |
* Helper to reduce boilerplate when creating subclasses. | |
* | |
* @param {function} Class | |
* @param {?object} Interface | |
*/ | |
SyntheticEvent.augmentClass = function (Class, Interface) { | |
var Super = this; | |
var E = function () {}; | |
E.prototype = Super.prototype; | |
var prototype = new E(); | |
_assign(prototype, Class.prototype); | |
Class.prototype = prototype; | |
Class.prototype.constructor = Class; | |
Class.Interface = _assign({}, Super.Interface, Interface); | |
Class.augmentClass = Super.augmentClass; | |
PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler); | |
}; | |
PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler); | |
module.exports = SyntheticEvent; | |
/** | |
* Helper to nullify syntheticEvent instance properties when destructing | |
* | |
* @param {object} SyntheticEvent | |
* @param {String} propName | |
* @return {object} defineProperty object | |
*/ | |
function getPooledWarningPropertyDefinition(propName, getVal) { | |
var isFunction = typeof getVal === 'function'; | |
return { | |
configurable: true, | |
set: set, | |
get: get | |
}; | |
function set(val) { | |
var action = isFunction ? 'setting the method' : 'setting the property'; | |
warn(action, 'This is effectively a no-op'); | |
return val; | |
} | |
function get() { | |
var action = isFunction ? 'accessing the method' : 'accessing the property'; | |
var result = isFunction ? 'This is a no-op function' : 'This is set to null'; | |
warn(action, result); | |
return getVal; | |
} | |
function warn(action, result) { | |
var warningCondition = false; | |
warning(warningCondition, 'This synthetic event is reused for performance reasons. If you\'re seeing this, ' + 'you\'re %s `%s` on a released/nullified synthetic event. %s. ' + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result); | |
} | |
} | |
}); | |
var SyntheticEvent$1 = interopDefault(SyntheticEvent); | |
var require$$0$43 = Object.freeze({ | |
default: SyntheticEvent$1 | |
}); | |
var SyntheticCompositionEvent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule SyntheticCompositionEvent | |
*/ | |
'use strict'; | |
var SyntheticEvent = interopDefault(require$$0$43); | |
/** | |
* @interface Event | |
* @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents | |
*/ | |
var CompositionEventInterface = { | |
data: null | |
}; | |
/** | |
* @param {object} dispatchConfig Configuration used to dispatch this event. | |
* @param {string} dispatchMarker Marker identifying the event target. | |
* @param {object} nativeEvent Native browser event. | |
* @extends {SyntheticUIEvent} | |
*/ | |
function SyntheticCompositionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { | |
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); | |
} | |
SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); | |
module.exports = SyntheticCompositionEvent; | |
}); | |
var SyntheticCompositionEvent$1 = interopDefault(SyntheticCompositionEvent); | |
var require$$2$21 = Object.freeze({ | |
default: SyntheticCompositionEvent$1 | |
}); | |
var SyntheticInputEvent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule SyntheticInputEvent | |
*/ | |
'use strict'; | |
var SyntheticEvent = interopDefault(require$$0$43); | |
/** | |
* @interface Event | |
* @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 | |
* /#events-inputevents | |
*/ | |
var InputEventInterface = { | |
data: null | |
}; | |
/** | |
* @param {object} dispatchConfig Configuration used to dispatch this event. | |
* @param {string} dispatchMarker Marker identifying the event target. | |
* @param {object} nativeEvent Native browser event. | |
* @extends {SyntheticUIEvent} | |
*/ | |
function SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { | |
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); | |
} | |
SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface); | |
module.exports = SyntheticInputEvent; | |
}); | |
var SyntheticInputEvent$1 = interopDefault(SyntheticInputEvent); | |
var require$$1$20 = Object.freeze({ | |
default: SyntheticInputEvent$1 | |
}); | |
var BeforeInputEventPlugin = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule BeforeInputEventPlugin | |
*/ | |
'use strict'; | |
var EventConstants = interopDefault(require$$18); | |
var EventPropagators = interopDefault(require$$16$1); | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var FallbackCompositionState = interopDefault(require$$3$13); | |
var SyntheticCompositionEvent = interopDefault(require$$2$21); | |
var SyntheticInputEvent = interopDefault(require$$1$20); | |
var keyOf = interopDefault(require$$0$37); | |
var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space | |
var START_KEYCODE = 229; | |
var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; | |
var documentMode = null; | |
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { | |
documentMode = document.documentMode; | |
} | |
// Webkit offers a very useful `textInput` event that can be used to | |
// directly represent `beforeInput`. The IE `textinput` event is not as | |
// useful, so we don't use it. | |
var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); | |
// In IE9+, we have access to composition events, but the data supplied | |
// by the native compositionend event may be incorrect. Japanese ideographic | |
// spaces, for instance (\u3000) are not recorded correctly. | |
var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); | |
/** | |
* Opera <= 12 includes TextEvent in window, but does not fire | |
* text input events. Rely on keypress instead. | |
*/ | |
function isPresto() { | |
var opera = window.opera; | |
return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; | |
} | |
var SPACEBAR_CODE = 32; | |
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); | |
var topLevelTypes = EventConstants.topLevelTypes; | |
// Events and their corresponding property names. | |
var eventTypes = { | |
beforeInput: { | |
phasedRegistrationNames: { | |
bubbled: keyOf({ onBeforeInput: null }), | |
captured: keyOf({ onBeforeInputCapture: null }) | |
}, | |
dependencies: [topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste] | |
}, | |
compositionEnd: { | |
phasedRegistrationNames: { | |
bubbled: keyOf({ onCompositionEnd: null }), | |
captured: keyOf({ onCompositionEndCapture: null }) | |
}, | |
dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] | |
}, | |
compositionStart: { | |
phasedRegistrationNames: { | |
bubbled: keyOf({ onCompositionStart: null }), | |
captured: keyOf({ onCompositionStartCapture: null }) | |
}, | |
dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] | |
}, | |
compositionUpdate: { | |
phasedRegistrationNames: { | |
bubbled: keyOf({ onCompositionUpdate: null }), | |
captured: keyOf({ onCompositionUpdateCapture: null }) | |
}, | |
dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] | |
} | |
}; | |
// Track whether we've ever handled a keypress on the space key. | |
var hasSpaceKeypress = false; | |
/** | |
* Return whether a native keypress event is assumed to be a command. | |
* This is required because Firefox fires `keypress` events for key commands | |
* (cut, copy, select-all, etc.) even though no character is inserted. | |
*/ | |
function isKeypressCommand(nativeEvent) { | |
return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && | |
// ctrlKey && altKey is equivalent to AltGr, and is not a command. | |
!(nativeEvent.ctrlKey && nativeEvent.altKey); | |
} | |
/** | |
* Translate native top level events into event types. | |
* | |
* @param {string} topLevelType | |
* @return {object} | |
*/ | |
function getCompositionEventType(topLevelType) { | |
switch (topLevelType) { | |
case topLevelTypes.topCompositionStart: | |
return eventTypes.compositionStart; | |
case topLevelTypes.topCompositionEnd: | |
return eventTypes.compositionEnd; | |
case topLevelTypes.topCompositionUpdate: | |
return eventTypes.compositionUpdate; | |
} | |
} | |
/** | |
* Does our fallback best-guess model think this event signifies that | |
* composition has begun? | |
* | |
* @param {string} topLevelType | |
* @param {object} nativeEvent | |
* @return {boolean} | |
*/ | |
function isFallbackCompositionStart(topLevelType, nativeEvent) { | |
return topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE; | |
} | |
/** | |
* Does our fallback mode think that this event is the end of composition? | |
* | |
* @param {string} topLevelType | |
* @param {object} nativeEvent | |
* @return {boolean} | |
*/ | |
function isFallbackCompositionEnd(topLevelType, nativeEvent) { | |
switch (topLevelType) { | |
case topLevelTypes.topKeyUp: | |
// Command keys insert or clear IME input. | |
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; | |
case topLevelTypes.topKeyDown: | |
// Expect IME keyCode on each keydown. If we get any other | |
// code we must have exited earlier. | |
return nativeEvent.keyCode !== START_KEYCODE; | |
case topLevelTypes.topKeyPress: | |
case topLevelTypes.topMouseDown: | |
case topLevelTypes.topBlur: | |
// Events are not possible without cancelling IME. | |
return true; | |
default: | |
return false; | |
} | |
} | |
/** | |
* Google Input Tools provides composition data via a CustomEvent, | |
* with the `data` property populated in the `detail` object. If this | |
* is available on the event object, use it. If not, this is a plain | |
* composition event and we have nothing special to extract. | |
* | |
* @param {object} nativeEvent | |
* @return {?string} | |
*/ | |
function getDataFromCustomEvent(nativeEvent) { | |
var detail = nativeEvent.detail; | |
if (typeof detail === 'object' && 'data' in detail) { | |
return detail.data; | |
} | |
return null; | |
} | |
// Track the current IME composition fallback object, if any. | |
var currentComposition = null; | |
/** | |
* @return {?object} A SyntheticCompositionEvent. | |
*/ | |
function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
var eventType; | |
var fallbackData; | |
if (canUseCompositionEvent) { | |
eventType = getCompositionEventType(topLevelType); | |
} else if (!currentComposition) { | |
if (isFallbackCompositionStart(topLevelType, nativeEvent)) { | |
eventType = eventTypes.compositionStart; | |
} | |
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { | |
eventType = eventTypes.compositionEnd; | |
} | |
if (!eventType) { | |
return null; | |
} | |
if (useFallbackCompositionData) { | |
// The current composition is stored statically and must not be | |
// overwritten while composition continues. | |
if (!currentComposition && eventType === eventTypes.compositionStart) { | |
currentComposition = FallbackCompositionState.getPooled(nativeEventTarget); | |
} else if (eventType === eventTypes.compositionEnd) { | |
if (currentComposition) { | |
fallbackData = currentComposition.getData(); | |
} | |
} | |
} | |
var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); | |
if (fallbackData) { | |
// Inject data generated from fallback path into the synthetic event. | |
// This matches the property of native CompositionEventInterface. | |
event.data = fallbackData; | |
} else { | |
var customData = getDataFromCustomEvent(nativeEvent); | |
if (customData !== null) { | |
event.data = customData; | |
} | |
} | |
EventPropagators.accumulateTwoPhaseDispatches(event); | |
return event; | |
} | |
/** | |
* @param {string} topLevelType Record from `EventConstants`. | |
* @param {object} nativeEvent Native browser event. | |
* @return {?string} The string corresponding to this `beforeInput` event. | |
*/ | |
function getNativeBeforeInputChars(topLevelType, nativeEvent) { | |
switch (topLevelType) { | |
case topLevelTypes.topCompositionEnd: | |
return getDataFromCustomEvent(nativeEvent); | |
case topLevelTypes.topKeyPress: | |
/** | |
* If native `textInput` events are available, our goal is to make | |
* use of them. However, there is a special case: the spacebar key. | |
* In Webkit, preventing default on a spacebar `textInput` event | |
* cancels character insertion, but it *also* causes the browser | |
* to fall back to its default spacebar behavior of scrolling the | |
* page. | |
* | |
* Tracking at: | |
* https://code.google.com/p/chromium/issues/detail?id=355103 | |
* | |
* To avoid this issue, use the keypress event as if no `textInput` | |
* event is available. | |
*/ | |
var which = nativeEvent.which; | |
if (which !== SPACEBAR_CODE) { | |
return null; | |
} | |
hasSpaceKeypress = true; | |
return SPACEBAR_CHAR; | |
case topLevelTypes.topTextInput: | |
// Record the characters to be added to the DOM. | |
var chars = nativeEvent.data; | |
// If it's a spacebar character, assume that we have already handled | |
// it at the keypress level and bail immediately. Android Chrome | |
// doesn't give us keycodes, so we need to blacklist it. | |
if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { | |
return null; | |
} | |
return chars; | |
default: | |
// For other native event types, do nothing. | |
return null; | |
} | |
} | |
/** | |
* For browsers that do not provide the `textInput` event, extract the | |
* appropriate string to use for SyntheticInputEvent. | |
* | |
* @param {string} topLevelType Record from `EventConstants`. | |
* @param {object} nativeEvent Native browser event. | |
* @return {?string} The fallback string for this `beforeInput` event. | |
*/ | |
function getFallbackBeforeInputChars(topLevelType, nativeEvent) { | |
// If we are currently composing (IME) and using a fallback to do so, | |
// try to extract the composed characters from the fallback object. | |
if (currentComposition) { | |
if (topLevelType === topLevelTypes.topCompositionEnd || isFallbackCompositionEnd(topLevelType, nativeEvent)) { | |
var chars = currentComposition.getData(); | |
FallbackCompositionState.release(currentComposition); | |
currentComposition = null; | |
return chars; | |
} | |
return null; | |
} | |
switch (topLevelType) { | |
case topLevelTypes.topPaste: | |
// If a paste event occurs after a keypress, throw out the input | |
// chars. Paste events should not lead to BeforeInput events. | |
return null; | |
case topLevelTypes.topKeyPress: | |
/** | |
* As of v27, Firefox may fire keypress events even when no character | |
* will be inserted. A few possibilities: | |
* | |
* - `which` is `0`. Arrow keys, Esc key, etc. | |
* | |
* - `which` is the pressed key code, but no char is available. | |
* Ex: 'AltGr + d` in Polish. There is no modified character for | |
* this key combination and no character is inserted into the | |
* document, but FF fires the keypress for char code `100` anyway. | |
* No `input` event will occur. | |
* | |
* - `which` is the pressed key code, but a command combination is | |
* being used. Ex: `Cmd+C`. No character is inserted, and no | |
* `input` event will occur. | |
*/ | |
if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { | |
return String.fromCharCode(nativeEvent.which); | |
} | |
return null; | |
case topLevelTypes.topCompositionEnd: | |
return useFallbackCompositionData ? null : nativeEvent.data; | |
default: | |
return null; | |
} | |
} | |
/** | |
* Extract a SyntheticInputEvent for `beforeInput`, based on either native | |
* `textInput` or fallback behavior. | |
* | |
* @return {?object} A SyntheticInputEvent. | |
*/ | |
function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
var chars; | |
if (canUseTextInputEvent) { | |
chars = getNativeBeforeInputChars(topLevelType, nativeEvent); | |
} else { | |
chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); | |
} | |
// If no characters are being inserted, no BeforeInput event should | |
// be fired. | |
if (!chars) { | |
return null; | |
} | |
var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); | |
event.data = chars; | |
EventPropagators.accumulateTwoPhaseDispatches(event); | |
return event; | |
} | |
/** | |
* Create an `onBeforeInput` event to match | |
* http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. | |
* | |
* This event plugin is based on the native `textInput` event | |
* available in Chrome, Safari, Opera, and IE. This event fires after | |
* `onKeyPress` and `onCompositionEnd`, but before `onInput`. | |
* | |
* `beforeInput` is spec'd but not implemented in any browsers, and | |
* the `input` event does not provide any useful information about what has | |
* actually been added, contrary to the spec. Thus, `textInput` is the best | |
* available event to identify the characters that have actually been inserted | |
* into the target node. | |
* | |
* This plugin is also responsible for emitting `composition` events, thus | |
* allowing us to share composition fallback code for both `beforeInput` and | |
* `composition` event types. | |
*/ | |
var BeforeInputEventPlugin = { | |
eventTypes: eventTypes, | |
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)]; | |
} | |
}; | |
module.exports = BeforeInputEventPlugin; | |
}); | |
var BeforeInputEventPlugin$1 = interopDefault(BeforeInputEventPlugin); | |
var require$$17 = Object.freeze({ | |
default: BeforeInputEventPlugin$1 | |
}); | |
var CallbackQueue = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule CallbackQueue | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12), | |
_assign = interopDefault(require$$7); | |
var PooledClass = interopDefault(require$$5$2); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* A specialized pseudo-event module to help keep track of components waiting to | |
* be notified when their DOM representations are available for use. | |
* | |
* This implements `PooledClass`, so you should never need to instantiate this. | |
* Instead, use `CallbackQueue.getPooled()`. | |
* | |
* @class ReactMountReady | |
* @implements PooledClass | |
* @internal | |
*/ | |
function CallbackQueue() { | |
this._callbacks = null; | |
this._contexts = null; | |
} | |
_assign(CallbackQueue.prototype, { | |
/** | |
* Enqueues a callback to be invoked when `notifyAll` is invoked. | |
* | |
* @param {function} callback Invoked when `notifyAll` is invoked. | |
* @param {?object} context Context to call `callback` with. | |
* @internal | |
*/ | |
enqueue: function (callback, context) { | |
this._callbacks = this._callbacks || []; | |
this._contexts = this._contexts || []; | |
this._callbacks.push(callback); | |
this._contexts.push(context); | |
}, | |
/** | |
* Invokes all enqueued callbacks and clears the queue. This is invoked after | |
* the DOM representation of a component has been created or updated. | |
* | |
* @internal | |
*/ | |
notifyAll: function () { | |
var callbacks = this._callbacks; | |
var contexts = this._contexts; | |
if (callbacks) { | |
!(callbacks.length === contexts.length) ? invariant(false, 'Mismatched list of contexts in callback queue') : void 0; | |
this._callbacks = null; | |
this._contexts = null; | |
for (var i = 0; i < callbacks.length; i++) { | |
callbacks[i].call(contexts[i]); | |
} | |
callbacks.length = 0; | |
contexts.length = 0; | |
} | |
}, | |
checkpoint: function () { | |
return this._callbacks ? this._callbacks.length : 0; | |
}, | |
rollback: function (len) { | |
if (this._callbacks) { | |
this._callbacks.length = len; | |
this._contexts.length = len; | |
} | |
}, | |
/** | |
* Resets the internal queue. | |
* | |
* @internal | |
*/ | |
reset: function () { | |
this._callbacks = null; | |
this._contexts = null; | |
}, | |
/** | |
* `PooledClass` looks for this. | |
*/ | |
destructor: function () { | |
this.reset(); | |
} | |
}); | |
PooledClass.addPoolingTo(CallbackQueue); | |
module.exports = CallbackQueue; | |
}); | |
var CallbackQueue$1 = interopDefault(CallbackQueue); | |
var require$$6$3 = Object.freeze({ | |
default: CallbackQueue$1 | |
}); | |
var ReactFeatureFlags = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactFeatureFlags | |
* | |
*/ | |
'use strict'; | |
var ReactFeatureFlags = { | |
// When true, call console.time() before and .timeEnd() after each top-level | |
// render (both initial renders and updates). Useful when looking at prod-mode | |
// timeline profiles in Chrome, for example. | |
logTopLevelRenders: false | |
}; | |
module.exports = ReactFeatureFlags; | |
}); | |
var ReactFeatureFlags$1 = interopDefault(ReactFeatureFlags); | |
var require$$12$1 = Object.freeze({ | |
default: ReactFeatureFlags$1 | |
}); | |
var ReactOwner = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactOwner | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* ReactOwners are capable of storing references to owned components. | |
* | |
* All components are capable of //being// referenced by owner components, but | |
* only ReactOwner components are capable of //referencing// owned components. | |
* The named reference is known as a "ref". | |
* | |
* Refs are available when mounted and updated during reconciliation. | |
* | |
* var MyComponent = React.createClass({ | |
* render: function() { | |
* return ( | |
* <div onClick={this.handleClick}> | |
* <CustomComponent ref="custom" /> | |
* </div> | |
* ); | |
* }, | |
* handleClick: function() { | |
* this.refs.custom.handleClick(); | |
* }, | |
* componentDidMount: function() { | |
* this.refs.custom.initialize(); | |
* } | |
* }); | |
* | |
* Refs should rarely be used. When refs are used, they should only be done to | |
* control data that is not handled by React's data flow. | |
* | |
* @class ReactOwner | |
*/ | |
var ReactOwner = { | |
/** | |
* @param {?object} object | |
* @return {boolean} True if `object` is a valid owner. | |
* @final | |
*/ | |
isValidOwner: function (object) { | |
return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function'); | |
}, | |
/** | |
* Adds a component by ref to an owner component. | |
* | |
* @param {ReactComponent} component Component to reference. | |
* @param {string} ref Name by which to refer to the component. | |
* @param {ReactOwner} owner Component on which to record the ref. | |
* @final | |
* @internal | |
*/ | |
addComponentAsRefTo: function (component, ref, owner) { | |
!ReactOwner.isValidOwner(owner) ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : void 0; | |
owner.attachRef(ref, component); | |
}, | |
/** | |
* Removes a component by ref from an owner component. | |
* | |
* @param {ReactComponent} component Component to dereference. | |
* @param {string} ref Name of the ref to remove. | |
* @param {ReactOwner} owner Component on which the ref is recorded. | |
* @final | |
* @internal | |
*/ | |
removeComponentAsRefFrom: function (component, ref, owner) { | |
!ReactOwner.isValidOwner(owner) ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : void 0; | |
var ownerPublicInstance = owner.getPublicInstance(); | |
// Check that `component`'s owner is still alive and that `component` is still the current ref | |
// because we do not want to detach the ref if another component stole it. | |
if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) { | |
owner.detachRef(ref); | |
} | |
} | |
}; | |
module.exports = ReactOwner; | |
}); | |
var ReactOwner$1 = interopDefault(ReactOwner); | |
var require$$0$44 = Object.freeze({ | |
default: ReactOwner$1 | |
}); | |
var ReactRef = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactRef | |
*/ | |
'use strict'; | |
var ReactOwner = interopDefault(require$$0$44); | |
var ReactRef = {}; | |
function attachRef(ref, component, owner) { | |
if (typeof ref === 'function') { | |
ref(component.getPublicInstance()); | |
} else { | |
// Legacy ref | |
ReactOwner.addComponentAsRefTo(component, ref, owner); | |
} | |
} | |
function detachRef(ref, component, owner) { | |
if (typeof ref === 'function') { | |
ref(null); | |
} else { | |
// Legacy ref | |
ReactOwner.removeComponentAsRefFrom(component, ref, owner); | |
} | |
} | |
ReactRef.attachRefs = function (instance, element) { | |
if (element === null || element === false) { | |
return; | |
} | |
var ref = element.ref; | |
if (ref != null) { | |
attachRef(ref, instance, element._owner); | |
} | |
}; | |
ReactRef.shouldUpdateRefs = function (prevElement, nextElement) { | |
// If either the owner or a `ref` has changed, make sure the newest owner | |
// has stored a reference to `this`, and the previous owner (if different) | |
// has forgotten the reference to `this`. We use the element instead | |
// of the public this.props because the post processing cannot determine | |
// a ref. The ref conceptually lives on the element. | |
// TODO: Should this even be possible? The owner cannot change because | |
// it's forbidden by shouldUpdateReactComponent. The ref can change | |
// if you swap the keys of but not the refs. Reconsider where this check | |
// is made. It probably belongs where the key checking and | |
// instantiateReactComponent is done. | |
var prevEmpty = prevElement === null || prevElement === false; | |
var nextEmpty = nextElement === null || nextElement === false; | |
return( | |
// This has a few false positives w/r/t empty components. | |
prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref | |
); | |
}; | |
ReactRef.detachRefs = function (instance, element) { | |
if (element === null || element === false) { | |
return; | |
} | |
var ref = element.ref; | |
if (ref != null) { | |
detachRef(ref, instance, element._owner); | |
} | |
}; | |
module.exports = ReactRef; | |
}); | |
var ReactRef$1 = interopDefault(ReactRef); | |
var require$$2$22 = Object.freeze({ | |
default: ReactRef$1 | |
}); | |
var ReactInvalidSetStateWarningDevTool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactInvalidSetStateWarningDevTool | |
*/ | |
'use strict'; | |
var warning = interopDefault(require$$0$34); | |
if ("development" !== 'production') { | |
var processingChildContext = false; | |
var warnInvalidSetState = function () { | |
warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()'); | |
}; | |
} | |
var ReactInvalidSetStateWarningDevTool = { | |
onBeginProcessingChildContext: function () { | |
processingChildContext = true; | |
}, | |
onEndProcessingChildContext: function () { | |
processingChildContext = false; | |
}, | |
onSetState: function () { | |
warnInvalidSetState(); | |
} | |
}; | |
module.exports = ReactInvalidSetStateWarningDevTool; | |
}); | |
var ReactInvalidSetStateWarningDevTool$1 = interopDefault(ReactInvalidSetStateWarningDevTool); | |
var require$$5$5 = Object.freeze({ | |
default: ReactInvalidSetStateWarningDevTool$1 | |
}); | |
var ReactHostOperationHistoryDevtool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactHostOperationHistoryDevtool | |
*/ | |
'use strict'; | |
var history = []; | |
var ReactHostOperationHistoryDevtool = { | |
onHostOperation: function (debugID, type, payload) { | |
history.push({ | |
instanceID: debugID, | |
type: type, | |
payload: payload | |
}); | |
}, | |
clearHistory: function () { | |
if (ReactHostOperationHistoryDevtool._preventClearing) { | |
// Should only be used for tests. | |
return; | |
} | |
history = []; | |
}, | |
getHistory: function () { | |
return history; | |
} | |
}; | |
module.exports = ReactHostOperationHistoryDevtool; | |
}); | |
var ReactHostOperationHistoryDevtool$1 = interopDefault(ReactHostOperationHistoryDevtool); | |
var require$$4$11 = Object.freeze({ | |
default: ReactHostOperationHistoryDevtool$1 | |
}); | |
var performance = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var performance; | |
if (ExecutionEnvironment.canUseDOM) { | |
performance = window.performance || window.msPerformance || window.webkitPerformance; | |
} | |
module.exports = performance || {}; | |
}); | |
var performance$1 = interopDefault(performance); | |
var require$$0$45 = Object.freeze({ | |
default: performance$1 | |
}); | |
var performanceNow = createCommonjsModule(function (module) { | |
'use strict'; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
var performance = interopDefault(require$$0$45); | |
var performanceNow; | |
/** | |
* Detect if we can use `window.performance.now()` and gracefully fallback to | |
* `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now | |
* because of Facebook's testing infrastructure. | |
*/ | |
if (performance.now) { | |
performanceNow = function performanceNow() { | |
return performance.now(); | |
}; | |
} else { | |
performanceNow = function performanceNow() { | |
return Date.now(); | |
}; | |
} | |
module.exports = performanceNow; | |
}); | |
var performanceNow$1 = interopDefault(performanceNow); | |
var require$$1$22 = Object.freeze({ | |
default: performanceNow$1 | |
}); | |
var ReactDebugTool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDebugTool | |
*/ | |
'use strict'; | |
var ReactInvalidSetStateWarningDevTool = interopDefault(require$$5$5); | |
var ReactHostOperationHistoryDevtool = interopDefault(require$$4$11); | |
var ReactComponentTreeDevtool = interopDefault(require$$0$39); | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var performanceNow = interopDefault(require$$1$22); | |
var warning = interopDefault(require$$0$34); | |
var eventHandlers = []; | |
var handlerDoesThrowForEvent = {}; | |
function emitEvent(handlerFunctionName, arg1, arg2, arg3, arg4, arg5) { | |
eventHandlers.forEach(function (handler) { | |
try { | |
if (handler[handlerFunctionName]) { | |
handler[handlerFunctionName](arg1, arg2, arg3, arg4, arg5); | |
} | |
} catch (e) { | |
warning(handlerDoesThrowForEvent[handlerFunctionName], 'exception thrown by devtool while handling %s: %s', handlerFunctionName, e + '\n' + e.stack); | |
handlerDoesThrowForEvent[handlerFunctionName] = true; | |
} | |
}); | |
} | |
var isProfiling = false; | |
var flushHistory = []; | |
var lifeCycleTimerStack = []; | |
var currentFlushNesting = 0; | |
var currentFlushMeasurements = null; | |
var currentFlushStartTime = null; | |
var currentTimerDebugID = null; | |
var currentTimerStartTime = null; | |
var currentTimerNestedFlushDuration = null; | |
var currentTimerType = null; | |
function clearHistory() { | |
ReactComponentTreeDevtool.purgeUnmountedComponents(); | |
ReactHostOperationHistoryDevtool.clearHistory(); | |
} | |
function getTreeSnapshot(registeredIDs) { | |
return registeredIDs.reduce(function (tree, id) { | |
var ownerID = ReactComponentTreeDevtool.getOwnerID(id); | |
var parentID = ReactComponentTreeDevtool.getParentID(id); | |
tree[id] = { | |
displayName: ReactComponentTreeDevtool.getDisplayName(id), | |
text: ReactComponentTreeDevtool.getText(id), | |
updateCount: ReactComponentTreeDevtool.getUpdateCount(id), | |
childIDs: ReactComponentTreeDevtool.getChildIDs(id), | |
// Text nodes don't have owners but this is close enough. | |
ownerID: ownerID || ReactComponentTreeDevtool.getOwnerID(parentID), | |
parentID: parentID | |
}; | |
return tree; | |
}, {}); | |
} | |
function resetMeasurements() { | |
var previousStartTime = currentFlushStartTime; | |
var previousMeasurements = currentFlushMeasurements || []; | |
var previousOperations = ReactHostOperationHistoryDevtool.getHistory(); | |
if (currentFlushNesting === 0) { | |
currentFlushStartTime = null; | |
currentFlushMeasurements = null; | |
clearHistory(); | |
return; | |
} | |
if (previousMeasurements.length || previousOperations.length) { | |
var registeredIDs = ReactComponentTreeDevtool.getRegisteredIDs(); | |
flushHistory.push({ | |
duration: performanceNow() - previousStartTime, | |
measurements: previousMeasurements || [], | |
operations: previousOperations || [], | |
treeSnapshot: getTreeSnapshot(registeredIDs) | |
}); | |
} | |
clearHistory(); | |
currentFlushStartTime = performanceNow(); | |
currentFlushMeasurements = []; | |
} | |
function checkDebugID(debugID) { | |
warning(debugID, 'ReactDebugTool: debugID may not be empty.'); | |
} | |
function beginLifeCycleTimer(debugID, timerType) { | |
if (currentFlushNesting === 0) { | |
return; | |
} | |
warning(!currentTimerType, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another'); | |
currentTimerStartTime = performanceNow(); | |
currentTimerNestedFlushDuration = 0; | |
currentTimerDebugID = debugID; | |
currentTimerType = timerType; | |
} | |
function endLifeCycleTimer(debugID, timerType) { | |
if (currentFlushNesting === 0) { | |
return; | |
} | |
warning(currentTimerType === timerType, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another'); | |
if (isProfiling) { | |
currentFlushMeasurements.push({ | |
timerType: timerType, | |
instanceID: debugID, | |
duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration | |
}); | |
} | |
currentTimerStartTime = null; | |
currentTimerNestedFlushDuration = null; | |
currentTimerDebugID = null; | |
currentTimerType = null; | |
} | |
function pauseCurrentLifeCycleTimer() { | |
var currentTimer = { | |
startTime: currentTimerStartTime, | |
nestedFlushStartTime: performanceNow(), | |
debugID: currentTimerDebugID, | |
timerType: currentTimerType | |
}; | |
lifeCycleTimerStack.push(currentTimer); | |
currentTimerStartTime = null; | |
currentTimerNestedFlushDuration = null; | |
currentTimerDebugID = null; | |
currentTimerType = null; | |
} | |
function resumeCurrentLifeCycleTimer() { | |
var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(); | |
var startTime = _lifeCycleTimerStack$.startTime; | |
var nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime; | |
var debugID = _lifeCycleTimerStack$.debugID; | |
var timerType = _lifeCycleTimerStack$.timerType; | |
var nestedFlushDuration = performanceNow() - nestedFlushStartTime; | |
currentTimerStartTime = startTime; | |
currentTimerNestedFlushDuration += nestedFlushDuration; | |
currentTimerDebugID = debugID; | |
currentTimerType = timerType; | |
} | |
var ReactDebugTool = { | |
addDevtool: function (devtool) { | |
eventHandlers.push(devtool); | |
}, | |
removeDevtool: function (devtool) { | |
for (var i = 0; i < eventHandlers.length; i++) { | |
if (eventHandlers[i] === devtool) { | |
eventHandlers.splice(i, 1); | |
i--; | |
} | |
} | |
}, | |
isProfiling: function () { | |
return isProfiling; | |
}, | |
beginProfiling: function () { | |
if (isProfiling) { | |
return; | |
} | |
isProfiling = true; | |
flushHistory.length = 0; | |
resetMeasurements(); | |
ReactDebugTool.addDevtool(ReactHostOperationHistoryDevtool); | |
}, | |
endProfiling: function () { | |
if (!isProfiling) { | |
return; | |
} | |
isProfiling = false; | |
resetMeasurements(); | |
ReactDebugTool.removeDevtool(ReactHostOperationHistoryDevtool); | |
}, | |
getFlushHistory: function () { | |
return flushHistory; | |
}, | |
onBeginFlush: function () { | |
currentFlushNesting++; | |
resetMeasurements(); | |
pauseCurrentLifeCycleTimer(); | |
emitEvent('onBeginFlush'); | |
}, | |
onEndFlush: function () { | |
resetMeasurements(); | |
currentFlushNesting--; | |
resumeCurrentLifeCycleTimer(); | |
emitEvent('onEndFlush'); | |
}, | |
onBeginLifeCycleTimer: function (debugID, timerType) { | |
checkDebugID(debugID); | |
emitEvent('onBeginLifeCycleTimer', debugID, timerType); | |
beginLifeCycleTimer(debugID, timerType); | |
}, | |
onEndLifeCycleTimer: function (debugID, timerType) { | |
checkDebugID(debugID); | |
endLifeCycleTimer(debugID, timerType); | |
emitEvent('onEndLifeCycleTimer', debugID, timerType); | |
}, | |
onBeginReconcilerTimer: function (debugID, timerType) { | |
checkDebugID(debugID); | |
emitEvent('onBeginReconcilerTimer', debugID, timerType); | |
}, | |
onEndReconcilerTimer: function (debugID, timerType) { | |
checkDebugID(debugID); | |
emitEvent('onEndReconcilerTimer', debugID, timerType); | |
}, | |
onError: function (debugID) { | |
if (currentTimerDebugID != null) { | |
endLifeCycleTimer(currentTimerDebugID, currentTimerType); | |
} | |
emitEvent('onError', debugID); | |
}, | |
onBeginProcessingChildContext: function () { | |
emitEvent('onBeginProcessingChildContext'); | |
}, | |
onEndProcessingChildContext: function () { | |
emitEvent('onEndProcessingChildContext'); | |
}, | |
onHostOperation: function (debugID, type, payload) { | |
checkDebugID(debugID); | |
emitEvent('onHostOperation', debugID, type, payload); | |
}, | |
onSetState: function () { | |
emitEvent('onSetState'); | |
}, | |
onSetDisplayName: function (debugID, displayName) { | |
checkDebugID(debugID); | |
emitEvent('onSetDisplayName', debugID, displayName); | |
}, | |
onSetChildren: function (debugID, childDebugIDs) { | |
checkDebugID(debugID); | |
childDebugIDs.forEach(checkDebugID); | |
emitEvent('onSetChildren', debugID, childDebugIDs); | |
}, | |
onSetOwner: function (debugID, ownerDebugID) { | |
checkDebugID(debugID); | |
emitEvent('onSetOwner', debugID, ownerDebugID); | |
}, | |
onSetParent: function (debugID, parentDebugID) { | |
checkDebugID(debugID); | |
emitEvent('onSetParent', debugID, parentDebugID); | |
}, | |
onSetText: function (debugID, text) { | |
checkDebugID(debugID); | |
emitEvent('onSetText', debugID, text); | |
}, | |
onMountRootComponent: function (debugID) { | |
checkDebugID(debugID); | |
emitEvent('onMountRootComponent', debugID); | |
}, | |
onBeforeMountComponent: function (debugID, element) { | |
checkDebugID(debugID); | |
emitEvent('onBeforeMountComponent', debugID, element); | |
}, | |
onMountComponent: function (debugID) { | |
checkDebugID(debugID); | |
emitEvent('onMountComponent', debugID); | |
}, | |
onBeforeUpdateComponent: function (debugID, element) { | |
checkDebugID(debugID); | |
emitEvent('onBeforeUpdateComponent', debugID, element); | |
}, | |
onUpdateComponent: function (debugID) { | |
checkDebugID(debugID); | |
emitEvent('onUpdateComponent', debugID); | |
}, | |
onUnmountComponent: function (debugID) { | |
checkDebugID(debugID); | |
emitEvent('onUnmountComponent', debugID); | |
}, | |
onTestEvent: function () { | |
emitEvent('onTestEvent'); | |
} | |
}; | |
ReactDebugTool.addDevtool(ReactInvalidSetStateWarningDevTool); | |
ReactDebugTool.addDevtool(ReactComponentTreeDevtool); | |
var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; | |
if (/[?&]react_perf\b/.test(url)) { | |
ReactDebugTool.beginProfiling(); | |
} | |
module.exports = ReactDebugTool; | |
}); | |
var ReactDebugTool$1 = interopDefault(ReactDebugTool); | |
var require$$1$21 = Object.freeze({ | |
default: ReactDebugTool$1 | |
}); | |
var ReactInstrumentation = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactInstrumentation | |
*/ | |
'use strict'; | |
var debugTool = null; | |
if ("development" !== 'production') { | |
var ReactDebugTool = interopDefault(require$$1$21); | |
debugTool = ReactDebugTool; | |
} | |
module.exports = { debugTool: debugTool }; | |
}); | |
var ReactInstrumentation$1 = interopDefault(ReactInstrumentation); | |
var debugTool = ReactInstrumentation.debugTool; | |
var require$$8 = Object.freeze({ | |
default: ReactInstrumentation$1, | |
debugTool: debugTool | |
}); | |
var ReactReconciler = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactReconciler | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactRef = interopDefault(require$$2$22); | |
var ReactInstrumentation = interopDefault(require$$8); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Helper to call ReactRef.attachRefs with this composite component, split out | |
* to avoid allocations in the transaction mount-ready queue. | |
*/ | |
function attachRefs() { | |
ReactRef.attachRefs(this, this._currentElement); | |
} | |
var ReactReconciler = { | |
/** | |
* Initializes the component, renders markup, and registers event listeners. | |
* | |
* @param {ReactComponent} internalInstance | |
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction | |
* @param {?object} the containing host component instance | |
* @param {?object} info about the host container | |
* @return {?string} Rendered markup to be inserted into the DOM. | |
* @final | |
* @internal | |
*/ | |
mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context) { | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement); | |
ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'mountComponent'); | |
} | |
} | |
var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context); | |
if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { | |
transaction.getReactMountReady().enqueue(attachRefs, internalInstance); | |
} | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'mountComponent'); | |
ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID); | |
} | |
} | |
return markup; | |
}, | |
/** | |
* Returns a value that can be passed to | |
* ReactComponentEnvironment.replaceNodeWithMarkup. | |
*/ | |
getHostNode: function (internalInstance) { | |
return internalInstance.getHostNode(); | |
}, | |
/** | |
* Releases any resources allocated by `mountComponent`. | |
* | |
* @final | |
* @internal | |
*/ | |
unmountComponent: function (internalInstance, safely) { | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'unmountComponent'); | |
} | |
} | |
ReactRef.detachRefs(internalInstance, internalInstance._currentElement); | |
internalInstance.unmountComponent(safely); | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'unmountComponent'); | |
ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID); | |
} | |
} | |
}, | |
/** | |
* Update a component using a new element. | |
* | |
* @param {ReactComponent} internalInstance | |
* @param {ReactElement} nextElement | |
* @param {ReactReconcileTransaction} transaction | |
* @param {object} context | |
* @internal | |
*/ | |
receiveComponent: function (internalInstance, nextElement, transaction, context) { | |
var prevElement = internalInstance._currentElement; | |
if (nextElement === prevElement && context === internalInstance._context) { | |
// Since elements are immutable after the owner is rendered, | |
// we can do a cheap identity compare here to determine if this is a | |
// superfluous reconcile. It's possible for state to be mutable but such | |
// change should trigger an update of the owner which would recreate | |
// the element. We explicitly check for the existence of an owner since | |
// it's possible for an element created outside a composite to be | |
// deeply mutated and reused. | |
// TODO: Bailing out early is just a perf optimization right? | |
// TODO: Removing the return statement should affect correctness? | |
return; | |
} | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement); | |
ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'receiveComponent'); | |
} | |
} | |
var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); | |
if (refsChanged) { | |
ReactRef.detachRefs(internalInstance, prevElement); | |
} | |
internalInstance.receiveComponent(nextElement, transaction, context); | |
if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) { | |
transaction.getReactMountReady().enqueue(attachRefs, internalInstance); | |
} | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'receiveComponent'); | |
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); | |
} | |
} | |
}, | |
/** | |
* Flush any dirty changes in a component. | |
* | |
* @param {ReactComponent} internalInstance | |
* @param {ReactReconcileTransaction} transaction | |
* @internal | |
*/ | |
performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) { | |
if (internalInstance._updateBatchNumber !== updateBatchNumber) { | |
// The component's enqueued batch number should always be the current | |
// batch or the following one. | |
!(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1) ? invariant(false, 'performUpdateIfNecessary: Unexpected batch number (current %s, pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0; | |
return; | |
} | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onBeginReconcilerTimer(internalInstance._debugID, 'performUpdateIfNecessary'); | |
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement); | |
} | |
} | |
internalInstance.performUpdateIfNecessary(transaction); | |
if ("development" !== 'production') { | |
if (internalInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onEndReconcilerTimer(internalInstance._debugID, 'performUpdateIfNecessary'); | |
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); | |
} | |
} | |
} | |
}; | |
module.exports = ReactReconciler; | |
}); | |
var ReactReconciler$1 = interopDefault(ReactReconciler); | |
var require$$6$4 = Object.freeze({ | |
default: ReactReconciler$1 | |
}); | |
var Transaction = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule Transaction | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* `Transaction` creates a black box that is able to wrap any method such that | |
* certain invariants are maintained before and after the method is invoked | |
* (Even if an exception is thrown while invoking the wrapped method). Whoever | |
* instantiates a transaction can provide enforcers of the invariants at | |
* creation time. The `Transaction` class itself will supply one additional | |
* automatic invariant for you - the invariant that any transaction instance | |
* should not be run while it is already being run. You would typically create a | |
* single instance of a `Transaction` for reuse multiple times, that potentially | |
* is used to wrap several different methods. Wrappers are extremely simple - | |
* they only require implementing two methods. | |
* | |
* <pre> | |
* wrappers (injected at creation time) | |
* + + | |
* | | | |
* +-----------------|--------|--------------+ | |
* | v | | | |
* | +---------------+ | | | |
* | +--| wrapper1 |---|----+ | | |
* | | +---------------+ v | | | |
* | | +-------------+ | | | |
* | | +----| wrapper2 |--------+ | | |
* | | | +-------------+ | | | | |
* | | | | | | | |
* | v v v v | wrapper | |
* | +---+ +---+ +---------+ +---+ +---+ | invariants | |
* perform(anyMethod) | | | | | | | | | | | | maintained | |
* +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> | |
* | | | | | | | | | | | | | |
* | | | | | | | | | | | | | |
* | | | | | | | | | | | | | |
* | +---+ +---+ +---------+ +---+ +---+ | | |
* | initialize close | | |
* +-----------------------------------------+ | |
* </pre> | |
* | |
* Use cases: | |
* - Preserving the input selection ranges before/after reconciliation. | |
* Restoring selection even in the event of an unexpected error. | |
* - Deactivating events while rearranging the DOM, preventing blurs/focuses, | |
* while guaranteeing that afterwards, the event system is reactivated. | |
* - Flushing a queue of collected DOM mutations to the main UI thread after a | |
* reconciliation takes place in a worker thread. | |
* - Invoking any collected `componentDidUpdate` callbacks after rendering new | |
* content. | |
* - (Future use case): Wrapping particular flushes of the `ReactWorker` queue | |
* to preserve the `scrollTop` (an automatic scroll aware DOM). | |
* - (Future use case): Layout calculations before and after DOM updates. | |
* | |
* Transactional plugin API: | |
* - A module that has an `initialize` method that returns any precomputation. | |
* - and a `close` method that accepts the precomputation. `close` is invoked | |
* when the wrapped process is completed, or has failed. | |
* | |
* @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules | |
* that implement `initialize` and `close`. | |
* @return {Transaction} Single transaction for reuse in thread. | |
* | |
* @class Transaction | |
*/ | |
var Mixin = { | |
/** | |
* Sets up this instance so that it is prepared for collecting metrics. Does | |
* so such that this setup method may be used on an instance that is already | |
* initialized, in a way that does not consume additional memory upon reuse. | |
* That can be useful if you decide to make your subclass of this mixin a | |
* "PooledClass". | |
*/ | |
reinitializeTransaction: function () { | |
this.transactionWrappers = this.getTransactionWrappers(); | |
if (this.wrapperInitData) { | |
this.wrapperInitData.length = 0; | |
} else { | |
this.wrapperInitData = []; | |
} | |
this._isInTransaction = false; | |
}, | |
_isInTransaction: false, | |
/** | |
* @abstract | |
* @return {Array<TransactionWrapper>} Array of transaction wrappers. | |
*/ | |
getTransactionWrappers: null, | |
isInTransaction: function () { | |
return !!this._isInTransaction; | |
}, | |
/** | |
* Executes the function within a safety window. Use this for the top level | |
* methods that result in large amounts of computation/mutations that would | |
* need to be safety checked. The optional arguments helps prevent the need | |
* to bind in many cases. | |
* | |
* @param {function} method Member of scope to call. | |
* @param {Object} scope Scope to invoke from. | |
* @param {Object?=} a Argument to pass to the method. | |
* @param {Object?=} b Argument to pass to the method. | |
* @param {Object?=} c Argument to pass to the method. | |
* @param {Object?=} d Argument to pass to the method. | |
* @param {Object?=} e Argument to pass to the method. | |
* @param {Object?=} f Argument to pass to the method. | |
* | |
* @return {*} Return value from `method`. | |
*/ | |
perform: function (method, scope, a, b, c, d, e, f) { | |
!!this.isInTransaction() ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : void 0; | |
var errorThrown; | |
var ret; | |
try { | |
this._isInTransaction = true; | |
// Catching errors makes debugging more difficult, so we start with | |
// errorThrown set to true before setting it to false after calling | |
// close -- if it's still set to true in the finally block, it means | |
// one of these calls threw. | |
errorThrown = true; | |
this.initializeAll(0); | |
ret = method.call(scope, a, b, c, d, e, f); | |
errorThrown = false; | |
} finally { | |
try { | |
if (errorThrown) { | |
// If `method` throws, prefer to show that stack trace over any thrown | |
// by invoking `closeAll`. | |
try { | |
this.closeAll(0); | |
} catch (err) {} | |
} else { | |
// Since `method` didn't throw, we don't want to silence the exception | |
// here. | |
this.closeAll(0); | |
} | |
} finally { | |
this._isInTransaction = false; | |
} | |
} | |
return ret; | |
}, | |
initializeAll: function (startIndex) { | |
var transactionWrappers = this.transactionWrappers; | |
for (var i = startIndex; i < transactionWrappers.length; i++) { | |
var wrapper = transactionWrappers[i]; | |
try { | |
// Catching errors makes debugging more difficult, so we start with the | |
// OBSERVED_ERROR state before overwriting it with the real return value | |
// of initialize -- if it's still set to OBSERVED_ERROR in the finally | |
// block, it means wrapper.initialize threw. | |
this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; | |
this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null; | |
} finally { | |
if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { | |
// The initializer for wrapper i threw an error; initialize the | |
// remaining wrappers but silence any exceptions from them to ensure | |
// that the first error is the one to bubble up. | |
try { | |
this.initializeAll(i + 1); | |
} catch (err) {} | |
} | |
} | |
} | |
}, | |
/** | |
* Invokes each of `this.transactionWrappers.close[i]` functions, passing into | |
* them the respective return values of `this.transactionWrappers.init[i]` | |
* (`close`rs that correspond to initializers that failed will not be | |
* invoked). | |
*/ | |
closeAll: function (startIndex) { | |
!this.isInTransaction() ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : void 0; | |
var transactionWrappers = this.transactionWrappers; | |
for (var i = startIndex; i < transactionWrappers.length; i++) { | |
var wrapper = transactionWrappers[i]; | |
var initData = this.wrapperInitData[i]; | |
var errorThrown; | |
try { | |
// Catching errors makes debugging more difficult, so we start with | |
// errorThrown set to true before setting it to false after calling | |
// close -- if it's still set to true in the finally block, it means | |
// wrapper.close threw. | |
errorThrown = true; | |
if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { | |
wrapper.close.call(this, initData); | |
} | |
errorThrown = false; | |
} finally { | |
if (errorThrown) { | |
// The closer for wrapper i threw an error; close the remaining | |
// wrappers but silence any exceptions from them to ensure that the | |
// first error is the one to bubble up. | |
try { | |
this.closeAll(i + 1); | |
} catch (e) {} | |
} | |
} | |
} | |
this.wrapperInitData.length = 0; | |
} | |
}; | |
var Transaction = { | |
Mixin: Mixin, | |
/** | |
* Token to look for to determine if an error occurred. | |
*/ | |
OBSERVED_ERROR: {} | |
}; | |
module.exports = Transaction; | |
}); | |
var Transaction$1 = interopDefault(Transaction); | |
var require$$1$23 = Object.freeze({ | |
default: Transaction$1 | |
}); | |
var ReactUpdates = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactUpdates | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12), | |
_assign = interopDefault(require$$7); | |
var CallbackQueue = interopDefault(require$$6$3); | |
var PooledClass = interopDefault(require$$5$2); | |
var ReactFeatureFlags = interopDefault(require$$12$1); | |
var ReactReconciler = interopDefault(require$$6$4); | |
var Transaction = interopDefault(require$$1$23); | |
var invariant = interopDefault(require$$0$33); | |
var dirtyComponents = []; | |
var updateBatchNumber = 0; | |
var asapCallbackQueue = CallbackQueue.getPooled(); | |
var asapEnqueued = false; | |
var batchingStrategy = null; | |
function ensureInjected() { | |
!(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : void 0; | |
} | |
var NESTED_UPDATES = { | |
initialize: function () { | |
this.dirtyComponentsLength = dirtyComponents.length; | |
}, | |
close: function () { | |
if (this.dirtyComponentsLength !== dirtyComponents.length) { | |
// Additional updates were enqueued by componentDidUpdate handlers or | |
// similar; before our own UPDATE_QUEUEING wrapper closes, we want to run | |
// these new updates so that if A's componentDidUpdate calls setState on | |
// B, B will update before the callback A's updater provided when calling | |
// setState. | |
dirtyComponents.splice(0, this.dirtyComponentsLength); | |
flushBatchedUpdates(); | |
} else { | |
dirtyComponents.length = 0; | |
} | |
} | |
}; | |
var UPDATE_QUEUEING = { | |
initialize: function () { | |
this.callbackQueue.reset(); | |
}, | |
close: function () { | |
this.callbackQueue.notifyAll(); | |
} | |
}; | |
var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; | |
function ReactUpdatesFlushTransaction() { | |
this.reinitializeTransaction(); | |
this.dirtyComponentsLength = null; | |
this.callbackQueue = CallbackQueue.getPooled(); | |
this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( | |
/* useCreateElement */true); | |
} | |
_assign(ReactUpdatesFlushTransaction.prototype, Transaction.Mixin, { | |
getTransactionWrappers: function () { | |
return TRANSACTION_WRAPPERS; | |
}, | |
destructor: function () { | |
this.dirtyComponentsLength = null; | |
CallbackQueue.release(this.callbackQueue); | |
this.callbackQueue = null; | |
ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); | |
this.reconcileTransaction = null; | |
}, | |
perform: function (method, scope, a) { | |
// Essentially calls `this.reconcileTransaction.perform(method, scope, a)` | |
// with this transaction's wrappers around it. | |
return Transaction.Mixin.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); | |
} | |
}); | |
PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); | |
function batchedUpdates(callback, a, b, c, d, e) { | |
ensureInjected(); | |
batchingStrategy.batchedUpdates(callback, a, b, c, d, e); | |
} | |
/** | |
* Array comparator for ReactComponents by mount ordering. | |
* | |
* @param {ReactComponent} c1 first component you're comparing | |
* @param {ReactComponent} c2 second component you're comparing | |
* @return {number} Return value usable by Array.prototype.sort(). | |
*/ | |
function mountOrderComparator(c1, c2) { | |
return c1._mountOrder - c2._mountOrder; | |
} | |
function runBatchedUpdates(transaction) { | |
var len = transaction.dirtyComponentsLength; | |
!(len === dirtyComponents.length) ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : void 0; | |
// Since reconciling a component higher in the owner hierarchy usually (not | |
// always -- see shouldComponentUpdate()) will reconcile children, reconcile | |
// them before their children by sorting the array. | |
dirtyComponents.sort(mountOrderComparator); | |
// Any updates enqueued while reconciling must be performed after this entire | |
// batch. Otherwise, if dirtyComponents is [A, B] where A has children B and | |
// C, B could update twice in a single batch if C's render enqueues an update | |
// to B (since B would have already updated, we should skip it, and the only | |
// way we can know to do so is by checking the batch counter). | |
updateBatchNumber++; | |
for (var i = 0; i < len; i++) { | |
// If a component is unmounted before pending changes apply, it will still | |
// be here, but we assume that it has cleared its _pendingCallbacks and | |
// that performUpdateIfNecessary is a noop. | |
var component = dirtyComponents[i]; | |
// If performUpdateIfNecessary happens to enqueue any new updates, we | |
// shouldn't execute the callbacks until the next render happens, so | |
// stash the callbacks first | |
var callbacks = component._pendingCallbacks; | |
component._pendingCallbacks = null; | |
var markerName; | |
if (ReactFeatureFlags.logTopLevelRenders) { | |
var namedComponent = component; | |
// Duck type TopLevelWrapper. This is probably always true. | |
if (component._currentElement.props === component._renderedComponent._currentElement) { | |
namedComponent = component._renderedComponent; | |
} | |
markerName = 'React update: ' + namedComponent.getName(); | |
console.time(markerName); | |
} | |
ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); | |
if (markerName) { | |
console.timeEnd(markerName); | |
} | |
if (callbacks) { | |
for (var j = 0; j < callbacks.length; j++) { | |
transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); | |
} | |
} | |
} | |
} | |
var flushBatchedUpdates = function () { | |
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents | |
// array and perform any updates enqueued by mount-ready handlers (i.e., | |
// componentDidUpdate) but we need to check here too in order to catch | |
// updates enqueued by setState callbacks and asap calls. | |
while (dirtyComponents.length || asapEnqueued) { | |
if (dirtyComponents.length) { | |
var transaction = ReactUpdatesFlushTransaction.getPooled(); | |
transaction.perform(runBatchedUpdates, null, transaction); | |
ReactUpdatesFlushTransaction.release(transaction); | |
} | |
if (asapEnqueued) { | |
asapEnqueued = false; | |
var queue = asapCallbackQueue; | |
asapCallbackQueue = CallbackQueue.getPooled(); | |
queue.notifyAll(); | |
CallbackQueue.release(queue); | |
} | |
} | |
}; | |
/** | |
* Mark a component as needing a rerender, adding an optional callback to a | |
* list of functions which will be executed once the rerender occurs. | |
*/ | |
function enqueueUpdate(component) { | |
ensureInjected(); | |
// Various parts of our code (such as ReactCompositeComponent's | |
// _renderValidatedComponent) assume that calls to render aren't nested; | |
// verify that that's the case. (This is called by each top-level update | |
// function, like setState, forceUpdate, etc.; creation and | |
// destruction of top-level components is guarded in ReactMount.) | |
if (!batchingStrategy.isBatchingUpdates) { | |
batchingStrategy.batchedUpdates(enqueueUpdate, component); | |
return; | |
} | |
dirtyComponents.push(component); | |
if (component._updateBatchNumber == null) { | |
component._updateBatchNumber = updateBatchNumber + 1; | |
} | |
} | |
/** | |
* Enqueue a callback to be run at the end of the current batching cycle. Throws | |
* if no updates are currently being performed. | |
*/ | |
function asap(callback, context) { | |
!batchingStrategy.isBatchingUpdates ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context whereupdates are not being batched.') : void 0; | |
asapCallbackQueue.enqueue(callback, context); | |
asapEnqueued = true; | |
} | |
var ReactUpdatesInjection = { | |
injectReconcileTransaction: function (ReconcileTransaction) { | |
!ReconcileTransaction ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : void 0; | |
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; | |
}, | |
injectBatchingStrategy: function (_batchingStrategy) { | |
!_batchingStrategy ? invariant(false, 'ReactUpdates: must provide a batching strategy') : void 0; | |
!(typeof _batchingStrategy.batchedUpdates === 'function') ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : void 0; | |
!(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : void 0; | |
batchingStrategy = _batchingStrategy; | |
} | |
}; | |
var ReactUpdates = { | |
/** | |
* React references `ReactReconcileTransaction` using this property in order | |
* to allow dependency injection. | |
* | |
* @internal | |
*/ | |
ReactReconcileTransaction: null, | |
batchedUpdates: batchedUpdates, | |
enqueueUpdate: enqueueUpdate, | |
flushBatchedUpdates: flushBatchedUpdates, | |
injection: ReactUpdatesInjection, | |
asap: asap | |
}; | |
module.exports = ReactUpdates; | |
}); | |
var ReactUpdates$1 = interopDefault(ReactUpdates); | |
var require$$3$14 = Object.freeze({ | |
default: ReactUpdates$1 | |
}); | |
var getEventTarget = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule getEventTarget | |
*/ | |
'use strict'; | |
/** | |
* Gets the target node from a native browser event by accounting for | |
* inconsistencies in browser DOM APIs. | |
* | |
* @param {object} nativeEvent Native browser event. | |
* @return {DOMEventTarget} Target node. | |
*/ | |
function getEventTarget(nativeEvent) { | |
var target = nativeEvent.target || nativeEvent.srcElement || window; | |
// Normalize SVG <use> element events #4963 | |
if (target.correspondingUseElement) { | |
target = target.correspondingUseElement; | |
} | |
// Safari may fire events on text nodes (Node.TEXT_NODE is 3). | |
// @see http://www.quirksmode.org/js/events_properties.html | |
return target.nodeType === 3 ? target.parentNode : target; | |
} | |
module.exports = getEventTarget; | |
}); | |
var getEventTarget$1 = interopDefault(getEventTarget); | |
var require$$1$24 = Object.freeze({ | |
default: getEventTarget$1 | |
}); | |
var isEventSupported = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule isEventSupported | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var useHasFeature; | |
if (ExecutionEnvironment.canUseDOM) { | |
useHasFeature = document.implementation && document.implementation.hasFeature && | |
// always returns true in newer browsers as per the standard. | |
// @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature | |
document.implementation.hasFeature('', '') !== true; | |
} | |
/** | |
* Checks if an event is supported in the current execution environment. | |
* | |
* NOTE: This will not work correctly for non-generic events such as `change`, | |
* `reset`, `load`, `error`, and `select`. | |
* | |
* Borrows from Modernizr. | |
* | |
* @param {string} eventNameSuffix Event name, e.g. "click". | |
* @param {?boolean} capture Check if the capture phase is supported. | |
* @return {boolean} True if the event is supported. | |
* @internal | |
* @license Modernizr 3.0.0pre (Custom Build) | MIT | |
*/ | |
function isEventSupported(eventNameSuffix, capture) { | |
if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { | |
return false; | |
} | |
var eventName = 'on' + eventNameSuffix; | |
var isSupported = eventName in document; | |
if (!isSupported) { | |
var element = document.createElement('div'); | |
element.setAttribute(eventName, 'return;'); | |
isSupported = typeof element[eventName] === 'function'; | |
} | |
if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { | |
// This is the only way to test support for the `wheel` event in IE9+. | |
isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); | |
} | |
return isSupported; | |
} | |
module.exports = isEventSupported; | |
}); | |
var isEventSupported$1 = interopDefault(isEventSupported); | |
var require$$0$46 = Object.freeze({ | |
default: isEventSupported$1 | |
}); | |
var isTextInputElement = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule isTextInputElement | |
* | |
*/ | |
'use strict'; | |
/** | |
* @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary | |
*/ | |
var supportedInputTypes = { | |
'color': true, | |
'date': true, | |
'datetime': true, | |
'datetime-local': true, | |
'email': true, | |
'month': true, | |
'number': true, | |
'password': true, | |
'range': true, | |
'search': true, | |
'tel': true, | |
'text': true, | |
'time': true, | |
'url': true, | |
'week': true | |
}; | |
function isTextInputElement(elem) { | |
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); | |
if (nodeName === 'input') { | |
return !!supportedInputTypes[elem.type]; | |
} | |
if (nodeName === 'textarea') { | |
return true; | |
} | |
return false; | |
} | |
module.exports = isTextInputElement; | |
}); | |
var isTextInputElement$1 = interopDefault(isTextInputElement); | |
var require$$2$23 = Object.freeze({ | |
default: isTextInputElement$1 | |
}); | |
var ChangeEventPlugin = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ChangeEventPlugin | |
*/ | |
'use strict'; | |
var EventConstants = interopDefault(require$$18); | |
var EventPluginHub = interopDefault(require$$7$1); | |
var EventPropagators = interopDefault(require$$16$1); | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactUpdates = interopDefault(require$$3$14); | |
var SyntheticEvent = interopDefault(require$$0$43); | |
var getEventTarget = interopDefault(require$$1$24); | |
var isEventSupported = interopDefault(require$$0$46); | |
var isTextInputElement = interopDefault(require$$2$23); | |
var keyOf = interopDefault(require$$0$37); | |
var topLevelTypes = EventConstants.topLevelTypes; | |
var eventTypes = { | |
change: { | |
phasedRegistrationNames: { | |
bubbled: keyOf({ onChange: null }), | |
captured: keyOf({ onChangeCapture: null }) | |
}, | |
dependencies: [topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange] | |
} | |
}; | |
/** | |
* For IE shims | |
*/ | |
var activeElement = null; | |
var activeElementInst = null; | |
var activeElementValue = null; | |
var activeElementValueProp = null; | |
/** | |
* SECTION: handle `change` event | |
*/ | |
function shouldUseChangeEvent(elem) { | |
var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); | |
return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; | |
} | |
var doesChangeEventBubble = false; | |
if (ExecutionEnvironment.canUseDOM) { | |
// See `handleChange` comment below | |
doesChangeEventBubble = isEventSupported('change') && (!('documentMode' in document) || document.documentMode > 8); | |
} | |
function manualDispatchChangeEvent(nativeEvent) { | |
var event = SyntheticEvent.getPooled(eventTypes.change, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); | |
EventPropagators.accumulateTwoPhaseDispatches(event); | |
// If change and propertychange bubbled, we'd just bind to it like all the | |
// other events and have it go through ReactBrowserEventEmitter. Since it | |
// doesn't, we manually listen for the events and so we have to enqueue and | |
// process the abstract event manually. | |
// | |
// Batching is necessary here in order to ensure that all event handlers run | |
// before the next rerender (including event handlers attached to ancestor | |
// elements instead of directly on the input). Without this, controlled | |
// components don't work properly in conjunction with event bubbling because | |
// the component is rerendered and the value reverted before all the event | |
// handlers can run. See https://github.com/facebook/react/issues/708. | |
ReactUpdates.batchedUpdates(runEventInBatch, event); | |
} | |
function runEventInBatch(event) { | |
EventPluginHub.enqueueEvents(event); | |
EventPluginHub.processEventQueue(false); | |
} | |
function startWatchingForChangeEventIE8(target, targetInst) { | |
activeElement = target; | |
activeElementInst = targetInst; | |
activeElement.attachEvent('onchange', manualDispatchChangeEvent); | |
} | |
function stopWatchingForChangeEventIE8() { | |
if (!activeElement) { | |
return; | |
} | |
activeElement.detachEvent('onchange', manualDispatchChangeEvent); | |
activeElement = null; | |
activeElementInst = null; | |
} | |
function getTargetInstForChangeEvent(topLevelType, targetInst) { | |
if (topLevelType === topLevelTypes.topChange) { | |
return targetInst; | |
} | |
} | |
function handleEventsForChangeEventIE8(topLevelType, target, targetInst) { | |
if (topLevelType === topLevelTypes.topFocus) { | |
// stopWatching() should be a noop here but we call it just in case we | |
// missed a blur event somehow. | |
stopWatchingForChangeEventIE8(); | |
startWatchingForChangeEventIE8(target, targetInst); | |
} else if (topLevelType === topLevelTypes.topBlur) { | |
stopWatchingForChangeEventIE8(); | |
} | |
} | |
/** | |
* SECTION: handle `input` event | |
*/ | |
var isInputEventSupported = false; | |
if (ExecutionEnvironment.canUseDOM) { | |
// IE9 claims to support the input event but fails to trigger it when | |
// deleting text, so we ignore its input events. | |
// IE10+ fire input events to often, such when a placeholder | |
// changes or when an input with a placeholder is focused. | |
isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 11); | |
} | |
/** | |
* (For IE <=11) Replacement getter/setter for the `value` property that gets | |
* set on the active element. | |
*/ | |
var newValueProp = { | |
get: function () { | |
return activeElementValueProp.get.call(this); | |
}, | |
set: function (val) { | |
// Cast to a string so we can do equality checks. | |
activeElementValue = '' + val; | |
activeElementValueProp.set.call(this, val); | |
} | |
}; | |
/** | |
* (For IE <=11) Starts tracking propertychange events on the passed-in element | |
* and override the value property so that we can distinguish user events from | |
* value changes in JS. | |
*/ | |
function startWatchingForValueChange(target, targetInst) { | |
activeElement = target; | |
activeElementInst = targetInst; | |
activeElementValue = target.value; | |
activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); | |
// Not guarded in a canDefineProperty check: IE8 supports defineProperty only | |
// on DOM elements | |
Object.defineProperty(activeElement, 'value', newValueProp); | |
if (activeElement.attachEvent) { | |
activeElement.attachEvent('onpropertychange', handlePropertyChange); | |
} else { | |
activeElement.addEventListener('propertychange', handlePropertyChange, false); | |
} | |
} | |
/** | |
* (For IE <=11) Removes the event listeners from the currently-tracked element, | |
* if any exists. | |
*/ | |
function stopWatchingForValueChange() { | |
if (!activeElement) { | |
return; | |
} | |
// delete restores the original property definition | |
delete activeElement.value; | |
if (activeElement.detachEvent) { | |
activeElement.detachEvent('onpropertychange', handlePropertyChange); | |
} else { | |
activeElement.removeEventListener('propertychange', handlePropertyChange, false); | |
} | |
activeElement = null; | |
activeElementInst = null; | |
activeElementValue = null; | |
activeElementValueProp = null; | |
} | |
/** | |
* (For IE <=11) Handles a propertychange event, sending a `change` event if | |
* the value of the active element has changed. | |
*/ | |
function handlePropertyChange(nativeEvent) { | |
if (nativeEvent.propertyName !== 'value') { | |
return; | |
} | |
var value = nativeEvent.srcElement.value; | |
if (value === activeElementValue) { | |
return; | |
} | |
activeElementValue = value; | |
manualDispatchChangeEvent(nativeEvent); | |
} | |
/** | |
* If a `change` event should be fired, returns the target's ID. | |
*/ | |
function getTargetInstForInputEvent(topLevelType, targetInst) { | |
if (topLevelType === topLevelTypes.topInput) { | |
// In modern browsers (i.e., not IE8 or IE9), the input event is exactly | |
// what we want so fall through here and trigger an abstract event | |
return targetInst; | |
} | |
} | |
function handleEventsForInputEventIE(topLevelType, target, targetInst) { | |
if (topLevelType === topLevelTypes.topFocus) { | |
// In IE8, we can capture almost all .value changes by adding a | |
// propertychange handler and looking for events with propertyName | |
// equal to 'value' | |
// In IE9-11, propertychange fires for most input events but is buggy and | |
// doesn't fire when text is deleted, but conveniently, selectionchange | |
// appears to fire in all of the remaining cases so we catch those and | |
// forward the event if the value has changed | |
// In either case, we don't want to call the event handler if the value | |
// is changed from JS so we redefine a setter for `.value` that updates | |
// our activeElementValue variable, allowing us to ignore those changes | |
// | |
// stopWatching() should be a noop here but we call it just in case we | |
// missed a blur event somehow. | |
stopWatchingForValueChange(); | |
startWatchingForValueChange(target, targetInst); | |
} else if (topLevelType === topLevelTypes.topBlur) { | |
stopWatchingForValueChange(); | |
} | |
} | |
// For IE8 and IE9. | |
function getTargetInstForInputEventIE(topLevelType, targetInst) { | |
if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) { | |
// On the selectionchange event, the target is just document which isn't | |
// helpful for us so just check activeElement instead. | |
// | |
// 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire | |
// propertychange on the first input event after setting `value` from a | |
// script and fires only keydown, keypress, keyup. Catching keyup usually | |
// gets it and catching keydown lets us fire an event for the first | |
// keystroke if user does a key repeat (it'll be a little delayed: right | |
// before the second keystroke). Other input methods (e.g., paste) seem to | |
// fire selectionchange normally. | |
if (activeElement && activeElement.value !== activeElementValue) { | |
activeElementValue = activeElement.value; | |
return activeElementInst; | |
} | |
} | |
} | |
/** | |
* SECTION: handle `click` event | |
*/ | |
function shouldUseClickEvent(elem) { | |
// Use the `click` event to detect changes to checkbox and radio inputs. | |
// This approach works across all browsers, whereas `change` does not fire | |
// until `blur` in IE8. | |
return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); | |
} | |
function getTargetInstForClickEvent(topLevelType, targetInst) { | |
if (topLevelType === topLevelTypes.topClick) { | |
return targetInst; | |
} | |
} | |
/** | |
* This plugin creates an `onChange` event that normalizes change events | |
* across form elements. This event fires at a time when it's possible to | |
* change the element's value without seeing a flicker. | |
* | |
* Supported elements are: | |
* - input (see `isTextInputElement`) | |
* - textarea | |
* - select | |
*/ | |
var ChangeEventPlugin = { | |
eventTypes: eventTypes, | |
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; | |
var getTargetInstFunc, handleEventFunc; | |
if (shouldUseChangeEvent(targetNode)) { | |
if (doesChangeEventBubble) { | |
getTargetInstFunc = getTargetInstForChangeEvent; | |
} else { | |
handleEventFunc = handleEventsForChangeEventIE8; | |
} | |
} else if (isTextInputElement(targetNode)) { | |
if (isInputEventSupported) { | |
getTargetInstFunc = getTargetInstForInputEvent; | |
} else { | |
getTargetInstFunc = getTargetInstForInputEventIE; | |
handleEventFunc = handleEventsForInputEventIE; | |
} | |
} else if (shouldUseClickEvent(targetNode)) { | |
getTargetInstFunc = getTargetInstForClickEvent; | |
} | |
if (getTargetInstFunc) { | |
var inst = getTargetInstFunc(topLevelType, targetInst); | |
if (inst) { | |
var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, nativeEventTarget); | |
event.type = 'change'; | |
EventPropagators.accumulateTwoPhaseDispatches(event); | |
return event; | |
} | |
} | |
if (handleEventFunc) { | |
handleEventFunc(topLevelType, targetNode, targetInst); | |
} | |
} | |
}; | |
module.exports = ChangeEventPlugin; | |
}); | |
var ChangeEventPlugin$1 = interopDefault(ChangeEventPlugin); | |
var require$$16$2 = Object.freeze({ | |
default: ChangeEventPlugin$1 | |
}); | |
var DefaultEventPluginOrder = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DefaultEventPluginOrder | |
*/ | |
'use strict'; | |
var keyOf = interopDefault(require$$0$37); | |
/** | |
* Module that is injectable into `EventPluginHub`, that specifies a | |
* deterministic ordering of `EventPlugin`s. A convenient way to reason about | |
* plugins, without having to package every one of them. This is better than | |
* having plugins be ordered in the same order that they are injected because | |
* that ordering would be influenced by the packaging order. | |
* `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that | |
* preventing default on events is convenient in `SimpleEventPlugin` handlers. | |
*/ | |
var DefaultEventPluginOrder = [keyOf({ ResponderEventPlugin: null }), keyOf({ SimpleEventPlugin: null }), keyOf({ TapEventPlugin: null }), keyOf({ EnterLeaveEventPlugin: null }), keyOf({ ChangeEventPlugin: null }), keyOf({ SelectEventPlugin: null }), keyOf({ BeforeInputEventPlugin: null })]; | |
module.exports = DefaultEventPluginOrder; | |
}); | |
var DefaultEventPluginOrder$1 = interopDefault(DefaultEventPluginOrder); | |
var require$$15 = Object.freeze({ | |
default: DefaultEventPluginOrder$1 | |
}); | |
var SyntheticUIEvent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule SyntheticUIEvent | |
*/ | |
'use strict'; | |
var SyntheticEvent = interopDefault(require$$0$43); | |
var getEventTarget = interopDefault(require$$1$24); | |
/** | |
* @interface UIEvent | |
* @see http://www.w3.org/TR/DOM-Level-3-Events/ | |
*/ | |
var UIEventInterface = { | |
view: function (event) { | |
if (event.view) { | |
return event.view; | |
} | |
var target = getEventTarget(event); | |
if (target.window === target) { | |
// target is a window object | |
return target; | |
} | |
var doc = target.ownerDocument; | |
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. | |
if (doc) { | |
return doc.defaultView || doc.parentWindow; | |
} else { | |
return window; | |
} | |
}, | |
detail: function (event) { | |
return event.detail || 0; | |
} | |
}; | |
/** | |
* @param {object} dispatchConfig Configuration used to dispatch this event. | |
* @param {string} dispatchMarker Marker identifying the event target. | |
* @param {object} nativeEvent Native browser event. | |
* @extends {SyntheticEvent} | |
*/ | |
function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { | |
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); | |
} | |
SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); | |
module.exports = SyntheticUIEvent; | |
}); | |
var SyntheticUIEvent$1 = interopDefault(SyntheticUIEvent); | |
var require$$1$25 = Object.freeze({ | |
default: SyntheticUIEvent$1 | |
}); | |
var ViewportMetrics = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ViewportMetrics | |
*/ | |
'use strict'; | |
var ViewportMetrics = { | |
currentScrollLeft: 0, | |
currentScrollTop: 0, | |
refreshScrollValues: function (scrollPosition) { | |
ViewportMetrics.currentScrollLeft = scrollPosition.x; | |
ViewportMetrics.currentScrollTop = scrollPosition.y; | |
} | |
}; | |
module.exports = ViewportMetrics; | |
}); | |
var ViewportMetrics$1 = interopDefault(ViewportMetrics); | |
var require$$2$24 = Object.freeze({ | |
default: ViewportMetrics$1 | |
}); | |
var getEventModifierState = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule getEventModifierState | |
*/ | |
'use strict'; | |
/** | |
* Translation from modifier key to the associated property in the event. | |
* @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers | |
*/ | |
var modifierKeyToProp = { | |
'Alt': 'altKey', | |
'Control': 'ctrlKey', | |
'Meta': 'metaKey', | |
'Shift': 'shiftKey' | |
}; | |
// IE8 does not implement getModifierState so we simply map it to the only | |
// modifier keys exposed by the event itself, does not support Lock-keys. | |
// Currently, all major browsers except Chrome seems to support Lock-keys. | |
function modifierStateGetter(keyArg) { | |
var syntheticEvent = this; | |
var nativeEvent = syntheticEvent.nativeEvent; | |
if (nativeEvent.getModifierState) { | |
return nativeEvent.getModifierState(keyArg); | |
} | |
var keyProp = modifierKeyToProp[keyArg]; | |
return keyProp ? !!nativeEvent[keyProp] : false; | |
} | |
function getEventModifierState(nativeEvent) { | |
return modifierStateGetter; | |
} | |
module.exports = getEventModifierState; | |
}); | |
var getEventModifierState$1 = interopDefault(getEventModifierState); | |
var require$$0$48 = Object.freeze({ | |
default: getEventModifierState$1 | |
}); | |
var SyntheticMouseEvent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule SyntheticMouseEvent | |
*/ | |
'use strict'; | |
var SyntheticUIEvent = interopDefault(require$$1$25); | |
var ViewportMetrics = interopDefault(require$$2$24); | |
var getEventModifierState = interopDefault(require$$0$48); | |
/** | |
* @interface MouseEvent | |
* @see http://www.w3.org/TR/DOM-Level-3-Events/ | |
*/ | |
var MouseEventInterface = { | |
screenX: null, | |
screenY: null, | |
clientX: null, | |
clientY: null, | |
ctrlKey: null, | |
shiftKey: null, | |
altKey: null, | |
metaKey: null, | |
getModifierState: getEventModifierState, | |
button: function (event) { | |
// Webkit, Firefox, IE9+ | |
// which: 1 2 3 | |
// button: 0 1 2 (standard) | |
var button = event.button; | |
if ('which' in event) { | |
return button; | |
} | |
// IE<9 | |
// which: undefined | |
// button: 0 0 0 | |
// button: 1 4 2 (onmouseup) | |
return button === 2 ? 2 : button === 4 ? 1 : 0; | |
}, | |
buttons: null, | |
relatedTarget: function (event) { | |
return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement); | |
}, | |
// "Proprietary" Interface. | |
pageX: function (event) { | |
return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft; | |
}, | |
pageY: function (event) { | |
return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop; | |
} | |
}; | |
/** | |
* @param {object} dispatchConfig Configuration used to dispatch this event. | |
* @param {string} dispatchMarker Marker identifying the event target. | |
* @param {object} nativeEvent Native browser event. | |
* @extends {SyntheticUIEvent} | |
*/ | |
function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { | |
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); | |
} | |
SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); | |
module.exports = SyntheticMouseEvent; | |
}); | |
var SyntheticMouseEvent$1 = interopDefault(SyntheticMouseEvent); | |
var require$$0$47 = Object.freeze({ | |
default: SyntheticMouseEvent$1 | |
}); | |
var EnterLeaveEventPlugin = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule EnterLeaveEventPlugin | |
*/ | |
'use strict'; | |
var EventConstants = interopDefault(require$$18); | |
var EventPropagators = interopDefault(require$$16$1); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var SyntheticMouseEvent = interopDefault(require$$0$47); | |
var keyOf = interopDefault(require$$0$37); | |
var topLevelTypes = EventConstants.topLevelTypes; | |
var eventTypes = { | |
mouseEnter: { | |
registrationName: keyOf({ onMouseEnter: null }), | |
dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver] | |
}, | |
mouseLeave: { | |
registrationName: keyOf({ onMouseLeave: null }), | |
dependencies: [topLevelTypes.topMouseOut, topLevelTypes.topMouseOver] | |
} | |
}; | |
var EnterLeaveEventPlugin = { | |
eventTypes: eventTypes, | |
/** | |
* For almost every interaction we care about, there will be both a top-level | |
* `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that | |
* we do not extract duplicate events. However, moving the mouse into the | |
* browser from outside will not fire a `mouseout` event. In this case, we use | |
* the `mouseover` top-level event. | |
*/ | |
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { | |
return null; | |
} | |
if (topLevelType !== topLevelTypes.topMouseOut && topLevelType !== topLevelTypes.topMouseOver) { | |
// Must not be a mouse in or mouse out - ignoring. | |
return null; | |
} | |
var win; | |
if (nativeEventTarget.window === nativeEventTarget) { | |
// `nativeEventTarget` is probably a window object. | |
win = nativeEventTarget; | |
} else { | |
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. | |
var doc = nativeEventTarget.ownerDocument; | |
if (doc) { | |
win = doc.defaultView || doc.parentWindow; | |
} else { | |
win = window; | |
} | |
} | |
var from; | |
var to; | |
if (topLevelType === topLevelTypes.topMouseOut) { | |
from = targetInst; | |
var related = nativeEvent.relatedTarget || nativeEvent.toElement; | |
to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null; | |
} else { | |
// Moving to a node from outside the window. | |
from = null; | |
to = targetInst; | |
} | |
if (from === to) { | |
// Nothing pertains to our managed components. | |
return null; | |
} | |
var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from); | |
var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to); | |
var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget); | |
leave.type = 'mouseleave'; | |
leave.target = fromNode; | |
leave.relatedTarget = toNode; | |
var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget); | |
enter.type = 'mouseenter'; | |
enter.target = toNode; | |
enter.relatedTarget = fromNode; | |
EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to); | |
return [leave, enter]; | |
} | |
}; | |
module.exports = EnterLeaveEventPlugin; | |
}); | |
var EnterLeaveEventPlugin$1 = interopDefault(EnterLeaveEventPlugin); | |
var require$$14 = Object.freeze({ | |
default: EnterLeaveEventPlugin$1 | |
}); | |
var HTMLDOMPropertyConfig = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule HTMLDOMPropertyConfig | |
*/ | |
'use strict'; | |
var DOMProperty = interopDefault(require$$19); | |
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; | |
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; | |
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; | |
var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; | |
var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; | |
var HTMLDOMPropertyConfig = { | |
isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')), | |
Properties: { | |
/** | |
* Standard Properties | |
*/ | |
accept: 0, | |
acceptCharset: 0, | |
accessKey: 0, | |
action: 0, | |
allowFullScreen: HAS_BOOLEAN_VALUE, | |
allowTransparency: 0, | |
alt: 0, | |
async: HAS_BOOLEAN_VALUE, | |
autoComplete: 0, | |
// autoFocus is polyfilled/normalized by AutoFocusUtils | |
// autoFocus: HAS_BOOLEAN_VALUE, | |
autoPlay: HAS_BOOLEAN_VALUE, | |
capture: HAS_BOOLEAN_VALUE, | |
cellPadding: 0, | |
cellSpacing: 0, | |
charSet: 0, | |
challenge: 0, | |
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | |
cite: 0, | |
classID: 0, | |
className: 0, | |
cols: HAS_POSITIVE_NUMERIC_VALUE, | |
colSpan: 0, | |
content: 0, | |
contentEditable: 0, | |
contextMenu: 0, | |
controls: HAS_BOOLEAN_VALUE, | |
coords: 0, | |
crossOrigin: 0, | |
data: 0, // For `<object />` acts as `src`. | |
dateTime: 0, | |
'default': HAS_BOOLEAN_VALUE, | |
defer: HAS_BOOLEAN_VALUE, | |
dir: 0, | |
disabled: HAS_BOOLEAN_VALUE, | |
download: HAS_OVERLOADED_BOOLEAN_VALUE, | |
draggable: 0, | |
encType: 0, | |
form: 0, | |
formAction: 0, | |
formEncType: 0, | |
formMethod: 0, | |
formNoValidate: HAS_BOOLEAN_VALUE, | |
formTarget: 0, | |
frameBorder: 0, | |
headers: 0, | |
height: 0, | |
hidden: HAS_BOOLEAN_VALUE, | |
high: 0, | |
href: 0, | |
hrefLang: 0, | |
htmlFor: 0, | |
httpEquiv: 0, | |
icon: 0, | |
id: 0, | |
inputMode: 0, | |
integrity: 0, | |
is: 0, | |
keyParams: 0, | |
keyType: 0, | |
kind: 0, | |
label: 0, | |
lang: 0, | |
list: 0, | |
loop: HAS_BOOLEAN_VALUE, | |
low: 0, | |
manifest: 0, | |
marginHeight: 0, | |
marginWidth: 0, | |
max: 0, | |
maxLength: 0, | |
media: 0, | |
mediaGroup: 0, | |
method: 0, | |
min: 0, | |
minLength: 0, | |
// Caution; `option.selected` is not updated if `select.multiple` is | |
// disabled with `removeAttribute`. | |
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | |
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | |
name: 0, | |
nonce: 0, | |
noValidate: HAS_BOOLEAN_VALUE, | |
open: HAS_BOOLEAN_VALUE, | |
optimum: 0, | |
pattern: 0, | |
placeholder: 0, | |
poster: 0, | |
preload: 0, | |
profile: 0, | |
radioGroup: 0, | |
readOnly: HAS_BOOLEAN_VALUE, | |
rel: 0, | |
required: HAS_BOOLEAN_VALUE, | |
reversed: HAS_BOOLEAN_VALUE, | |
role: 0, | |
rows: HAS_POSITIVE_NUMERIC_VALUE, | |
rowSpan: HAS_NUMERIC_VALUE, | |
sandbox: 0, | |
scope: 0, | |
scoped: HAS_BOOLEAN_VALUE, | |
scrolling: 0, | |
seamless: HAS_BOOLEAN_VALUE, | |
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, | |
shape: 0, | |
size: HAS_POSITIVE_NUMERIC_VALUE, | |
sizes: 0, | |
span: HAS_POSITIVE_NUMERIC_VALUE, | |
spellCheck: 0, | |
src: 0, | |
srcDoc: 0, | |
srcLang: 0, | |
srcSet: 0, | |
start: HAS_NUMERIC_VALUE, | |
step: 0, | |
style: 0, | |
summary: 0, | |
tabIndex: 0, | |
target: 0, | |
title: 0, | |
// Setting .type throws on non-<input> tags | |
type: 0, | |
useMap: 0, | |
value: 0, | |
width: 0, | |
wmode: 0, | |
wrap: 0, | |
/** | |
* RDFa Properties | |
*/ | |
about: 0, | |
datatype: 0, | |
inlist: 0, | |
prefix: 0, | |
// property is also supported for OpenGraph in meta tags. | |
property: 0, | |
resource: 0, | |
'typeof': 0, | |
vocab: 0, | |
/** | |
* Non-standard Properties | |
*/ | |
// autoCapitalize and autoCorrect are supported in Mobile Safari for | |
// keyboard hints. | |
autoCapitalize: 0, | |
autoCorrect: 0, | |
// autoSave allows WebKit/Blink to persist values of input fields on page reloads | |
autoSave: 0, | |
// color is for Safari mask-icon link | |
color: 0, | |
// itemProp, itemScope, itemType are for | |
// Microdata support. See http://schema.org/docs/gs.html | |
itemProp: 0, | |
itemScope: HAS_BOOLEAN_VALUE, | |
itemType: 0, | |
// itemID and itemRef are for Microdata support as well but | |
// only specified in the WHATWG spec document. See | |
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api | |
itemID: 0, | |
itemRef: 0, | |
// results show looking glass icon and recent searches on input | |
// search fields in WebKit/Blink | |
results: 0, | |
// IE-only attribute that specifies security restrictions on an iframe | |
// as an alternative to the sandbox attribute on IE<10 | |
security: 0, | |
// IE-only attribute that controls focus behavior | |
unselectable: 0 | |
}, | |
DOMAttributeNames: { | |
acceptCharset: 'accept-charset', | |
className: 'class', | |
htmlFor: 'for', | |
httpEquiv: 'http-equiv' | |
}, | |
DOMPropertyNames: {} | |
}; | |
module.exports = HTMLDOMPropertyConfig; | |
}); | |
var HTMLDOMPropertyConfig$1 = interopDefault(HTMLDOMPropertyConfig); | |
var require$$13 = Object.freeze({ | |
default: HTMLDOMPropertyConfig$1 | |
}); | |
var DOMNamespaces = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DOMNamespaces | |
*/ | |
'use strict'; | |
var DOMNamespaces = { | |
html: 'http://www.w3.org/1999/xhtml', | |
mathml: 'http://www.w3.org/1998/Math/MathML', | |
svg: 'http://www.w3.org/2000/svg' | |
}; | |
module.exports = DOMNamespaces; | |
}); | |
var DOMNamespaces$1 = interopDefault(DOMNamespaces); | |
var require$$25 = Object.freeze({ | |
default: DOMNamespaces$1 | |
}); | |
var createMicrosoftUnsafeLocalFunction = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule createMicrosoftUnsafeLocalFunction | |
*/ | |
/* globals MSApp */ | |
'use strict'; | |
/** | |
* Create a function which has 'unsafe' privileges (required by windows8 apps) | |
*/ | |
var createMicrosoftUnsafeLocalFunction = function (func) { | |
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { | |
return function (arg0, arg1, arg2, arg3) { | |
MSApp.execUnsafeLocalFunction(function () { | |
return func(arg0, arg1, arg2, arg3); | |
}); | |
}; | |
} else { | |
return func; | |
} | |
}; | |
module.exports = createMicrosoftUnsafeLocalFunction; | |
}); | |
var createMicrosoftUnsafeLocalFunction$1 = interopDefault(createMicrosoftUnsafeLocalFunction); | |
var require$$0$49 = Object.freeze({ | |
default: createMicrosoftUnsafeLocalFunction$1 | |
}); | |
var setInnerHTML = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule setInnerHTML | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var DOMNamespaces = interopDefault(require$$25); | |
var WHITESPACE_TEST = /^[ \r\n\t\f]/; | |
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; | |
var createMicrosoftUnsafeLocalFunction = interopDefault(require$$0$49); | |
// SVG temp container for IE lacking innerHTML | |
var reusableSVGContainer; | |
/** | |
* Set the innerHTML property of a node, ensuring that whitespace is preserved | |
* even in IE8. | |
* | |
* @param {DOMElement} node | |
* @param {string} html | |
* @internal | |
*/ | |
var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { | |
// IE does not have innerHTML for SVG nodes, so instead we inject the | |
// new markup in a temp node and then move the child nodes across into | |
// the target node | |
if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) { | |
reusableSVGContainer = reusableSVGContainer || document.createElement('div'); | |
reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; | |
var newNodes = reusableSVGContainer.firstChild.childNodes; | |
for (var i = 0; i < newNodes.length; i++) { | |
node.appendChild(newNodes[i]); | |
} | |
} else { | |
node.innerHTML = html; | |
} | |
}); | |
if (ExecutionEnvironment.canUseDOM) { | |
// IE8: When updating a just created node with innerHTML only leading | |
// whitespace is removed. When updating an existing node with innerHTML | |
// whitespace in root TextNodes is also collapsed. | |
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html | |
// Feature detection; only IE8 is known to behave improperly like this. | |
var testElement = document.createElement('div'); | |
testElement.innerHTML = ' '; | |
if (testElement.innerHTML === '') { | |
setInnerHTML = function (node, html) { | |
// Magic theory: IE8 supposedly differentiates between added and updated | |
// nodes when processing innerHTML, innerHTML on updated nodes suffers | |
// from worse whitespace behavior. Re-adding a node like this triggers | |
// the initial and more favorable whitespace behavior. | |
// TODO: What to do on a detached node? | |
if (node.parentNode) { | |
node.parentNode.replaceChild(node, node); | |
} | |
// We also implement a workaround for non-visible tags disappearing into | |
// thin air on IE8, this only happens if there is no visible text | |
// in-front of the non-visible tags. Piggyback on the whitespace fix | |
// and simply check if any non-visible tags appear in the source. | |
if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) { | |
// Recover leading whitespace by temporarily prepending any character. | |
// \uFEFF has the potential advantage of being zero-width/invisible. | |
// UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode | |
// in hopes that this is preserved even if "\uFEFF" is transformed to | |
// the actual Unicode character (by Babel, for example). | |
// https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216 | |
node.innerHTML = String.fromCharCode(0xFEFF) + html; | |
// deleteData leaves an empty `TextNode` which offsets the index of all | |
// children. Definitely want to avoid this. | |
var textNode = node.firstChild; | |
if (textNode.data.length === 1) { | |
node.removeChild(textNode); | |
} else { | |
textNode.deleteData(0, 1); | |
} | |
} else { | |
node.innerHTML = html; | |
} | |
}; | |
} | |
testElement = null; | |
} | |
module.exports = setInnerHTML; | |
}); | |
var setInnerHTML$1 = interopDefault(setInnerHTML); | |
var require$$2$25 = Object.freeze({ | |
default: setInnerHTML$1 | |
}); | |
var escapeTextContentForBrowser = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2016-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* Based on the escape-html library, which is used under the MIT License below: | |
* | |
* Copyright (c) 2012-2013 TJ Holowaychuk | |
* Copyright (c) 2015 Andreas Lubbe | |
* Copyright (c) 2015 Tiancheng "Timothy" Gu | |
* | |
* 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. | |
* | |
* @providesModule escapeTextContentForBrowser | |
*/ | |
'use strict'; | |
// code copied and modified from escape-html | |
/** | |
* Module variables. | |
* @private | |
*/ | |
var matchHtmlRegExp = /["'&<>]/; | |
/** | |
* Escape special characters in the given string of html. | |
* | |
* @param {string} string The string to escape for inserting into HTML | |
* @return {string} | |
* @public | |
*/ | |
function escapeHtml(string) { | |
var str = '' + string; | |
var match = matchHtmlRegExp.exec(str); | |
if (!match) { | |
return str; | |
} | |
var escape; | |
var html = ''; | |
var index = 0; | |
var lastIndex = 0; | |
for (index = match.index; index < str.length; index++) { | |
switch (str.charCodeAt(index)) { | |
case 34: | |
// " | |
escape = '"'; | |
break; | |
case 38: | |
// & | |
escape = '&'; | |
break; | |
case 39: | |
// ' | |
escape = '''; // modified from escape-html; used to be ''' | |
break; | |
case 60: | |
// < | |
escape = '<'; | |
break; | |
case 62: | |
// > | |
escape = '>'; | |
break; | |
default: | |
continue; | |
} | |
if (lastIndex !== index) { | |
html += str.substring(lastIndex, index); | |
} | |
lastIndex = index + 1; | |
html += escape; | |
} | |
return lastIndex !== index ? html + str.substring(lastIndex, index) : html; | |
} | |
// end code copied and modified from escape-html | |
/** | |
* Escapes text to prevent scripting attacks. | |
* | |
* @param {*} text Text value to escape. | |
* @return {string} An escaped string. | |
*/ | |
function escapeTextContentForBrowser(text) { | |
if (typeof text === 'boolean' || typeof text === 'number') { | |
// this shortcircuit helps perf for types that we know will never have | |
// special characters, especially given that this function is used often | |
// for numeric dom ids. | |
return '' + text; | |
} | |
return escapeHtml(text); | |
} | |
module.exports = escapeTextContentForBrowser; | |
}); | |
var escapeTextContentForBrowser$1 = interopDefault(escapeTextContentForBrowser); | |
var require$$2$26 = Object.freeze({ | |
default: escapeTextContentForBrowser$1 | |
}); | |
var setTextContent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule setTextContent | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var escapeTextContentForBrowser = interopDefault(require$$2$26); | |
var setInnerHTML = interopDefault(require$$2$25); | |
/** | |
* Set the textContent property of a node, ensuring that whitespace is preserved | |
* even in IE8. innerText is a poor substitute for textContent and, among many | |
* issues, inserts <br> instead of the literal newline chars. innerHTML behaves | |
* as it should. | |
* | |
* @param {DOMElement} node | |
* @param {string} text | |
* @internal | |
*/ | |
var setTextContent = function (node, text) { | |
if (text) { | |
var firstChild = node.firstChild; | |
if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) { | |
firstChild.nodeValue = text; | |
return; | |
} | |
} | |
node.textContent = text; | |
}; | |
if (ExecutionEnvironment.canUseDOM) { | |
if (!('textContent' in document.documentElement)) { | |
setTextContent = function (node, text) { | |
setInnerHTML(node, escapeTextContentForBrowser(text)); | |
}; | |
} | |
} | |
module.exports = setTextContent; | |
}); | |
var setTextContent$1 = interopDefault(setTextContent); | |
var require$$0$50 = Object.freeze({ | |
default: setTextContent$1 | |
}); | |
var DOMLazyTree = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2015-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DOMLazyTree | |
*/ | |
'use strict'; | |
var DOMNamespaces = interopDefault(require$$25); | |
var setInnerHTML = interopDefault(require$$2$25); | |
var createMicrosoftUnsafeLocalFunction = interopDefault(require$$0$49); | |
var setTextContent = interopDefault(require$$0$50); | |
var ELEMENT_NODE_TYPE = 1; | |
var DOCUMENT_FRAGMENT_NODE_TYPE = 11; | |
/** | |
* In IE (8-11) and Edge, appending nodes with no children is dramatically | |
* faster than appending a full subtree, so we essentially queue up the | |
* .appendChild calls here and apply them so each node is added to its parent | |
* before any children are added. | |
* | |
* In other browsers, doing so is slower or neutral compared to the other order | |
* (in Firefox, twice as slow) so we only do this inversion in IE. | |
* | |
* See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode. | |
*/ | |
var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent); | |
function insertTreeChildren(tree) { | |
if (!enableLazy) { | |
return; | |
} | |
var node = tree.node; | |
var children = tree.children; | |
if (children.length) { | |
for (var i = 0; i < children.length; i++) { | |
insertTreeBefore(node, children[i], null); | |
} | |
} else if (tree.html != null) { | |
setInnerHTML(node, tree.html); | |
} else if (tree.text != null) { | |
setTextContent(node, tree.text); | |
} | |
} | |
var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) { | |
// DocumentFragments aren't actually part of the DOM after insertion so | |
// appending children won't update the DOM. We need to ensure the fragment | |
// is properly populated first, breaking out of our lazy approach for just | |
// this level. Also, some <object> plugins (like Flash Player) will read | |
// <param> nodes immediately upon insertion into the DOM, so <object> | |
// must also be populated prior to insertion into the DOM. | |
if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) { | |
insertTreeChildren(tree); | |
parentNode.insertBefore(tree.node, referenceNode); | |
} else { | |
parentNode.insertBefore(tree.node, referenceNode); | |
insertTreeChildren(tree); | |
} | |
}); | |
function replaceChildWithTree(oldNode, newTree) { | |
oldNode.parentNode.replaceChild(newTree.node, oldNode); | |
insertTreeChildren(newTree); | |
} | |
function queueChild(parentTree, childTree) { | |
if (enableLazy) { | |
parentTree.children.push(childTree); | |
} else { | |
parentTree.node.appendChild(childTree.node); | |
} | |
} | |
function queueHTML(tree, html) { | |
if (enableLazy) { | |
tree.html = html; | |
} else { | |
setInnerHTML(tree.node, html); | |
} | |
} | |
function queueText(tree, text) { | |
if (enableLazy) { | |
tree.text = text; | |
} else { | |
setTextContent(tree.node, text); | |
} | |
} | |
function toString() { | |
return this.node.nodeName; | |
} | |
function DOMLazyTree(node) { | |
return { | |
node: node, | |
children: [], | |
html: null, | |
text: null, | |
toString: toString | |
}; | |
} | |
DOMLazyTree.insertTreeBefore = insertTreeBefore; | |
DOMLazyTree.replaceChildWithTree = replaceChildWithTree; | |
DOMLazyTree.queueChild = queueChild; | |
DOMLazyTree.queueHTML = queueHTML; | |
DOMLazyTree.queueText = queueText; | |
module.exports = DOMLazyTree; | |
}); | |
var DOMLazyTree$1 = interopDefault(DOMLazyTree); | |
var require$$20 = Object.freeze({ | |
default: DOMLazyTree$1 | |
}); | |
var createArrayFromMixed = createCommonjsModule(function (module) { | |
'use strict'; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Convert array-like objects to arrays. | |
* | |
* This API assumes the caller knows the contents of the data type. For less | |
* well defined inputs use createArrayFromMixed. | |
* | |
* @param {object|function|filelist} obj | |
* @return {array} | |
*/ | |
function toArray(obj) { | |
var length = obj.length; | |
// Some browsers builtin objects can report typeof 'function' (e.g. NodeList | |
// in old versions of Safari). | |
!(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? invariant(false, 'toArray: Array-like object expected') : void 0; | |
!(typeof length === 'number') ? invariant(false, 'toArray: Object needs a length property') : void 0; | |
!(length === 0 || length - 1 in obj) ? invariant(false, 'toArray: Object should have keys for indices') : void 0; | |
!(typeof obj.callee !== 'function') ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : void 0; | |
// Old IE doesn't give collections access to hasOwnProperty. Assume inputs | |
// without method will throw during the slice call and skip straight to the | |
// fallback. | |
if (obj.hasOwnProperty) { | |
try { | |
return Array.prototype.slice.call(obj); | |
} catch (e) { | |
// IE < 9 does not support Array#slice on collections objects | |
} | |
} | |
// Fall back to copying key by key. This assumes all keys have a value, | |
// so will not preserve sparsely populated inputs. | |
var ret = Array(length); | |
for (var ii = 0; ii < length; ii++) { | |
ret[ii] = obj[ii]; | |
} | |
return ret; | |
} | |
/** | |
* Perform a heuristic test to determine if an object is "array-like". | |
* | |
* A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" | |
* Joshu replied: "Mu." | |
* | |
* This function determines if its argument has "array nature": it returns | |
* true if the argument is an actual array, an `arguments' object, or an | |
* HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). | |
* | |
* It will return false for other array-like objects like Filelist. | |
* | |
* @param {*} obj | |
* @return {boolean} | |
*/ | |
function hasArrayNature(obj) { | |
return( | |
// not null/false | |
!!obj && ( | |
// arrays are objects, NodeLists are functions in Safari | |
typeof obj == 'object' || typeof obj == 'function') && | |
// quacks like an array | |
'length' in obj && | |
// not window | |
!('setInterval' in obj) && | |
// no DOM node should be considered an array-like | |
// a 'select' element has 'length' and 'item' properties on IE8 | |
typeof obj.nodeType != 'number' && ( | |
// a real array | |
Array.isArray(obj) || | |
// arguments | |
'callee' in obj || | |
// HTMLCollection/NodeList | |
'item' in obj) | |
); | |
} | |
/** | |
* Ensure that the argument is an array by wrapping it in an array if it is not. | |
* Creates a copy of the argument if it is already an array. | |
* | |
* This is mostly useful idiomatically: | |
* | |
* var createArrayFromMixed = require('createArrayFromMixed'); | |
* | |
* function takesOneOrMoreThings(things) { | |
* things = createArrayFromMixed(things); | |
* ... | |
* } | |
* | |
* This allows you to treat `things' as an array, but accept scalars in the API. | |
* | |
* If you need to convert an array-like object, like `arguments`, into an array | |
* use toArray instead. | |
* | |
* @param {*} obj | |
* @return {array} | |
*/ | |
function createArrayFromMixed(obj) { | |
if (!hasArrayNature(obj)) { | |
return [obj]; | |
} else if (Array.isArray(obj)) { | |
return obj.slice(); | |
} else { | |
return toArray(obj); | |
} | |
} | |
module.exports = createArrayFromMixed; | |
}); | |
var createArrayFromMixed$1 = interopDefault(createArrayFromMixed); | |
var require$$2$28 = Object.freeze({ | |
default: createArrayFromMixed$1 | |
}); | |
var getMarkupWrap = createCommonjsModule(function (module) { | |
'use strict'; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
/*eslint-disable fb-www/unsafe-html */ | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Dummy container used to detect which wraps are necessary. | |
*/ | |
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; | |
/** | |
* Some browsers cannot use `innerHTML` to render certain elements standalone, | |
* so we wrap them, render the wrapped nodes, then extract the desired node. | |
* | |
* In IE8, certain elements cannot render alone, so wrap all elements ('*'). | |
*/ | |
var shouldWrap = {}; | |
var selectWrap = [1, '<select multiple="true">', '</select>']; | |
var tableWrap = [1, '<table>', '</table>']; | |
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; | |
var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; | |
var markupWrap = { | |
'*': [1, '?<div>', '</div>'], | |
'area': [1, '<map>', '</map>'], | |
'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], | |
'legend': [1, '<fieldset>', '</fieldset>'], | |
'param': [1, '<object>', '</object>'], | |
'tr': [2, '<table><tbody>', '</tbody></table>'], | |
'optgroup': selectWrap, | |
'option': selectWrap, | |
'caption': tableWrap, | |
'colgroup': tableWrap, | |
'tbody': tableWrap, | |
'tfoot': tableWrap, | |
'thead': tableWrap, | |
'td': trWrap, | |
'th': trWrap | |
}; | |
// Initialize the SVG elements since we know they'll always need to be wrapped | |
// consistently. If they are created inside a <div> they will be initialized in | |
// the wrong namespace (and will not display). | |
var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; | |
svgElements.forEach(function (nodeName) { | |
markupWrap[nodeName] = svgWrap; | |
shouldWrap[nodeName] = true; | |
}); | |
/** | |
* Gets the markup wrap configuration for the supplied `nodeName`. | |
* | |
* NOTE: This lazily detects which wraps are necessary for the current browser. | |
* | |
* @param {string} nodeName Lowercase `nodeName`. | |
* @return {?array} Markup wrap configuration, if applicable. | |
*/ | |
function getMarkupWrap(nodeName) { | |
!!!dummyNode ? invariant(false, 'Markup wrapping node not initialized') : void 0; | |
if (!markupWrap.hasOwnProperty(nodeName)) { | |
nodeName = '*'; | |
} | |
if (!shouldWrap.hasOwnProperty(nodeName)) { | |
if (nodeName === '*') { | |
dummyNode.innerHTML = '<link />'; | |
} else { | |
dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; | |
} | |
shouldWrap[nodeName] = !dummyNode.firstChild; | |
} | |
return shouldWrap[nodeName] ? markupWrap[nodeName] : null; | |
} | |
module.exports = getMarkupWrap; | |
}); | |
var getMarkupWrap$1 = interopDefault(getMarkupWrap); | |
var require$$1$26 = Object.freeze({ | |
default: getMarkupWrap$1 | |
}); | |
var createNodesFromMarkup = createCommonjsModule(function (module) { | |
'use strict'; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
/*eslint-disable fb-www/unsafe-html*/ | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var createArrayFromMixed = interopDefault(require$$2$28); | |
var getMarkupWrap = interopDefault(require$$1$26); | |
var invariant = interopDefault(require$$0$33); | |
/** | |
* Dummy container used to render all markup. | |
*/ | |
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; | |
/** | |
* Pattern used by `getNodeName`. | |
*/ | |
var nodeNamePattern = /^\s*<(\w+)/; | |
/** | |
* Extracts the `nodeName` of the first element in a string of markup. | |
* | |
* @param {string} markup String of markup. | |
* @return {?string} Node name of the supplied markup. | |
*/ | |
function getNodeName(markup) { | |
var nodeNameMatch = markup.match(nodeNamePattern); | |
return nodeNameMatch && nodeNameMatch[1].toLowerCase(); | |
} | |
/** | |
* Creates an array containing the nodes rendered from the supplied markup. The | |
* optionally supplied `handleScript` function will be invoked once for each | |
* <script> element that is rendered. If no `handleScript` function is supplied, | |
* an exception is thrown if any <script> elements are rendered. | |
* | |
* @param {string} markup A string of valid HTML markup. | |
* @param {?function} handleScript Invoked once for each rendered <script>. | |
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. | |
*/ | |
function createNodesFromMarkup(markup, handleScript) { | |
var node = dummyNode; | |
!!!dummyNode ? invariant(false, 'createNodesFromMarkup dummy not initialized') : void 0; | |
var nodeName = getNodeName(markup); | |
var wrap = nodeName && getMarkupWrap(nodeName); | |
if (wrap) { | |
node.innerHTML = wrap[1] + markup + wrap[2]; | |
var wrapDepth = wrap[0]; | |
while (wrapDepth--) { | |
node = node.lastChild; | |
} | |
} else { | |
node.innerHTML = markup; | |
} | |
var scripts = node.getElementsByTagName('script'); | |
if (scripts.length) { | |
!handleScript ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : void 0; | |
createArrayFromMixed(scripts).forEach(handleScript); | |
} | |
var nodes = Array.from(node.childNodes); | |
while (node.lastChild) { | |
node.removeChild(node.lastChild); | |
} | |
return nodes; | |
} | |
module.exports = createNodesFromMarkup; | |
}); | |
var createNodesFromMarkup$1 = interopDefault(createNodesFromMarkup); | |
var require$$2$27 = Object.freeze({ | |
default: createNodesFromMarkup$1 | |
}); | |
var Danger = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule Danger | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var DOMLazyTree = interopDefault(require$$20); | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var createNodesFromMarkup = interopDefault(require$$2$27); | |
var emptyFunction = interopDefault(require$$3$10); | |
var invariant = interopDefault(require$$0$33); | |
var Danger = { | |
/** | |
* Replaces a node with a string of markup at its current position within its | |
* parent. The markup must render into a single root node. | |
* | |
* @param {DOMElement} oldChild Child node to replace. | |
* @param {string} markup Markup to render in place of the child node. | |
* @internal | |
*/ | |
dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) { | |
!ExecutionEnvironment.canUseDOM ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.') : void 0; | |
!markup ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : void 0; | |
!(oldChild.nodeName !== 'HTML') ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the <html> node. This is because browser quirks make this unreliable and/or slow. If you want to render to the root you must use server rendering. See ReactDOMServer.renderToString().') : void 0; | |
if (typeof markup === 'string') { | |
var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; | |
oldChild.parentNode.replaceChild(newChild, oldChild); | |
} else { | |
DOMLazyTree.replaceChildWithTree(oldChild, markup); | |
} | |
} | |
}; | |
module.exports = Danger; | |
}); | |
var Danger$1 = interopDefault(Danger); | |
var require$$6$6 = Object.freeze({ | |
default: Danger$1 | |
}); | |
var ReactMultiChildUpdateTypes = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactMultiChildUpdateTypes | |
*/ | |
'use strict'; | |
var keyMirror = interopDefault(require$$0$36); | |
/** | |
* When a component's children are updated, a series of update configuration | |
* objects are created in order to batch and serialize the required changes. | |
* | |
* Enumerates all the possible types of update configurations. | |
* | |
* @internal | |
*/ | |
var ReactMultiChildUpdateTypes = keyMirror({ | |
INSERT_MARKUP: null, | |
MOVE_EXISTING: null, | |
REMOVE_NODE: null, | |
SET_MARKUP: null, | |
TEXT_CONTENT: null | |
}); | |
module.exports = ReactMultiChildUpdateTypes; | |
}); | |
var ReactMultiChildUpdateTypes$1 = interopDefault(ReactMultiChildUpdateTypes); | |
var require$$6$7 = Object.freeze({ | |
default: ReactMultiChildUpdateTypes$1 | |
}); | |
var DOMChildrenOperations = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DOMChildrenOperations | |
*/ | |
'use strict'; | |
var DOMLazyTree = interopDefault(require$$20); | |
var Danger = interopDefault(require$$6$6); | |
var ReactMultiChildUpdateTypes = interopDefault(require$$6$7); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactInstrumentation = interopDefault(require$$8); | |
var createMicrosoftUnsafeLocalFunction = interopDefault(require$$0$49); | |
var setInnerHTML = interopDefault(require$$2$25); | |
var setTextContent = interopDefault(require$$0$50); | |
function getNodeAfter(parentNode, node) { | |
// Special case for text components, which return [open, close] comments | |
// from getHostNode. | |
if (Array.isArray(node)) { | |
node = node[1]; | |
} | |
return node ? node.nextSibling : parentNode.firstChild; | |
} | |
/** | |
* Inserts `childNode` as a child of `parentNode` at the `index`. | |
* | |
* @param {DOMElement} parentNode Parent node in which to insert. | |
* @param {DOMElement} childNode Child node to insert. | |
* @param {number} index Index at which to insert the child. | |
* @internal | |
*/ | |
var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) { | |
// We rely exclusively on `insertBefore(node, null)` instead of also using | |
// `appendChild(node)`. (Using `undefined` is not allowed by all browsers so | |
// we are careful to use `null`.) | |
parentNode.insertBefore(childNode, referenceNode); | |
}); | |
function insertLazyTreeChildAt(parentNode, childTree, referenceNode) { | |
DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode); | |
} | |
function moveChild(parentNode, childNode, referenceNode) { | |
if (Array.isArray(childNode)) { | |
moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode); | |
} else { | |
insertChildAt(parentNode, childNode, referenceNode); | |
} | |
} | |
function removeChild(parentNode, childNode) { | |
if (Array.isArray(childNode)) { | |
var closingComment = childNode[1]; | |
childNode = childNode[0]; | |
removeDelimitedText(parentNode, childNode, closingComment); | |
parentNode.removeChild(closingComment); | |
} | |
parentNode.removeChild(childNode); | |
} | |
function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) { | |
var node = openingComment; | |
while (true) { | |
var nextNode = node.nextSibling; | |
insertChildAt(parentNode, node, referenceNode); | |
if (node === closingComment) { | |
break; | |
} | |
node = nextNode; | |
} | |
} | |
function removeDelimitedText(parentNode, startNode, closingComment) { | |
while (true) { | |
var node = startNode.nextSibling; | |
if (node === closingComment) { | |
// The closing comment is removed by ReactMultiChild. | |
break; | |
} else { | |
parentNode.removeChild(node); | |
} | |
} | |
} | |
function replaceDelimitedText(openingComment, closingComment, stringText) { | |
var parentNode = openingComment.parentNode; | |
var nodeAfterComment = openingComment.nextSibling; | |
if (nodeAfterComment === closingComment) { | |
// There are no text nodes between the opening and closing comments; insert | |
// a new one if stringText isn't empty. | |
if (stringText) { | |
insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment); | |
} | |
} else { | |
if (stringText) { | |
// Set the text content of the first node after the opening comment, and | |
// remove all following nodes up until the closing comment. | |
setTextContent(nodeAfterComment, stringText); | |
removeDelimitedText(parentNode, nodeAfterComment, closingComment); | |
} else { | |
removeDelimitedText(parentNode, openingComment, closingComment); | |
} | |
} | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID, 'replace text', stringText); | |
} | |
} | |
var dangerouslyReplaceNodeWithMarkup = Danger.dangerouslyReplaceNodeWithMarkup; | |
if ("development" !== 'production') { | |
dangerouslyReplaceNodeWithMarkup = function (oldChild, markup, prevInstance) { | |
Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup); | |
if (prevInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onHostOperation(prevInstance._debugID, 'replace with', markup.toString()); | |
} else { | |
var nextInstance = ReactDOMComponentTree.getInstanceFromNode(markup.node); | |
if (nextInstance._debugID !== 0) { | |
ReactInstrumentation.debugTool.onHostOperation(nextInstance._debugID, 'mount', markup.toString()); | |
} | |
} | |
}; | |
} | |
/** | |
* Operations for updating with DOM children. | |
*/ | |
var DOMChildrenOperations = { | |
dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup, | |
replaceDelimitedText: replaceDelimitedText, | |
/** | |
* Updates a component's children by processing a series of updates. The | |
* update configurations are each expected to have a `parentNode` property. | |
* | |
* @param {array<object>} updates List of update configurations. | |
* @internal | |
*/ | |
processUpdates: function (parentNode, updates) { | |
if ("development" !== 'production') { | |
var parentNodeDebugID = ReactDOMComponentTree.getInstanceFromNode(parentNode)._debugID; | |
} | |
for (var k = 0; k < updates.length; k++) { | |
var update = updates[k]; | |
switch (update.type) { | |
case ReactMultiChildUpdateTypes.INSERT_MARKUP: | |
insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode)); | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(parentNodeDebugID, 'insert child', { toIndex: update.toIndex, content: update.content.toString() }); | |
} | |
break; | |
case ReactMultiChildUpdateTypes.MOVE_EXISTING: | |
moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode)); | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(parentNodeDebugID, 'move child', { fromIndex: update.fromIndex, toIndex: update.toIndex }); | |
} | |
break; | |
case ReactMultiChildUpdateTypes.SET_MARKUP: | |
setInnerHTML(parentNode, update.content); | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(parentNodeDebugID, 'replace children', update.content.toString()); | |
} | |
break; | |
case ReactMultiChildUpdateTypes.TEXT_CONTENT: | |
setTextContent(parentNode, update.content); | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(parentNodeDebugID, 'replace text', update.content.toString()); | |
} | |
break; | |
case ReactMultiChildUpdateTypes.REMOVE_NODE: | |
removeChild(parentNode, update.fromNode); | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(parentNodeDebugID, 'remove child', { fromIndex: update.fromIndex }); | |
} | |
break; | |
} | |
} | |
} | |
}; | |
module.exports = DOMChildrenOperations; | |
}); | |
var DOMChildrenOperations$1 = interopDefault(DOMChildrenOperations); | |
var require$$6$5 = Object.freeze({ | |
default: DOMChildrenOperations$1 | |
}); | |
var ReactDOMIDOperations = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMIDOperations | |
*/ | |
'use strict'; | |
var DOMChildrenOperations = interopDefault(require$$6$5); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
/** | |
* Operations used to process updates to DOM nodes. | |
*/ | |
var ReactDOMIDOperations = { | |
/** | |
* Updates a component's children by processing a series of updates. | |
* | |
* @param {array<object>} updates List of update configurations. | |
* @internal | |
*/ | |
dangerouslyProcessChildrenUpdates: function (parentInst, updates) { | |
var node = ReactDOMComponentTree.getNodeFromInstance(parentInst); | |
DOMChildrenOperations.processUpdates(node, updates); | |
} | |
}; | |
module.exports = ReactDOMIDOperations; | |
}); | |
var ReactDOMIDOperations$1 = interopDefault(ReactDOMIDOperations); | |
var require$$0$51 = Object.freeze({ | |
default: ReactDOMIDOperations$1 | |
}); | |
var ReactComponentBrowserEnvironment = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactComponentBrowserEnvironment | |
*/ | |
'use strict'; | |
var DOMChildrenOperations = interopDefault(require$$6$5); | |
var ReactDOMIDOperations = interopDefault(require$$0$51); | |
/** | |
* Abstracts away all functionality of the reconciler that requires knowledge of | |
* the browser context. TODO: These callers should be refactored to avoid the | |
* need for this injection. | |
*/ | |
var ReactComponentBrowserEnvironment = { | |
processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, | |
replaceNodeWithMarkup: DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup, | |
/** | |
* If a particular environment requires that some resources be cleaned up, | |
* specify this in the injected Mixin. In the DOM, we would likely want to | |
* purge any cached node ID lookups. | |
* | |
* @private | |
*/ | |
unmountIDFromEnvironment: function (rootNodeID) {} | |
}; | |
module.exports = ReactComponentBrowserEnvironment; | |
}); | |
var ReactComponentBrowserEnvironment$1 = interopDefault(ReactComponentBrowserEnvironment); | |
var require$$18$1 = Object.freeze({ | |
default: ReactComponentBrowserEnvironment$1 | |
}); | |
var focusNode = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
*/ | |
'use strict'; | |
/** | |
* @param {DOMElement} node input/textarea to focus | |
*/ | |
function focusNode(node) { | |
// IE8 can throw "Can't move focus to the control because it is invisible, | |
// not enabled, or of a type that does not accept the focus." for all kinds of | |
// reasons that are too expensive and fragile to test. | |
try { | |
node.focus(); | |
} catch (e) {} | |
} | |
module.exports = focusNode; | |
}); | |
var focusNode$1 = interopDefault(focusNode); | |
var require$$1$27 = Object.freeze({ | |
default: focusNode$1 | |
}); | |
var AutoFocusUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule AutoFocusUtils | |
*/ | |
'use strict'; | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var focusNode = interopDefault(require$$1$27); | |
var AutoFocusUtils = { | |
focusDOMComponent: function () { | |
focusNode(ReactDOMComponentTree.getNodeFromInstance(this)); | |
} | |
}; | |
module.exports = AutoFocusUtils; | |
}); | |
var AutoFocusUtils$1 = interopDefault(AutoFocusUtils); | |
var require$$28 = Object.freeze({ | |
default: AutoFocusUtils$1 | |
}); | |
var CSSProperty = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule CSSProperty | |
*/ | |
'use strict'; | |
/** | |
* CSS properties which accept numbers but are not in units of "px". | |
*/ | |
var isUnitlessNumber = { | |
animationIterationCount: true, | |
borderImageOutset: true, | |
borderImageSlice: true, | |
borderImageWidth: true, | |
boxFlex: true, | |
boxFlexGroup: true, | |
boxOrdinalGroup: true, | |
columnCount: true, | |
flex: true, | |
flexGrow: true, | |
flexPositive: true, | |
flexShrink: true, | |
flexNegative: true, | |
flexOrder: true, | |
gridRow: true, | |
gridColumn: true, | |
fontWeight: true, | |
lineClamp: true, | |
lineHeight: true, | |
opacity: true, | |
order: true, | |
orphans: true, | |
tabSize: true, | |
widows: true, | |
zIndex: true, | |
zoom: true, | |
// SVG-related properties | |
fillOpacity: true, | |
floodOpacity: true, | |
stopOpacity: true, | |
strokeDasharray: true, | |
strokeDashoffset: true, | |
strokeMiterlimit: true, | |
strokeOpacity: true, | |
strokeWidth: true | |
}; | |
/** | |
* @param {string} prefix vendor-specific prefix, eg: Webkit | |
* @param {string} key style name, eg: transitionDuration | |
* @return {string} style name prefixed with `prefix`, properly camelCased, eg: | |
* WebkitTransitionDuration | |
*/ | |
function prefixKey(prefix, key) { | |
return prefix + key.charAt(0).toUpperCase() + key.substring(1); | |
} | |
/** | |
* Support style names that may come passed in prefixed by adding permutations | |
* of vendor prefixes. | |
*/ | |
var prefixes = ['Webkit', 'ms', 'Moz', 'O']; | |
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an | |
// infinite loop, because it iterates over the newly added props too. | |
Object.keys(isUnitlessNumber).forEach(function (prop) { | |
prefixes.forEach(function (prefix) { | |
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; | |
}); | |
}); | |
/** | |
* Most style properties can be unset by doing .style[prop] = '' but IE8 | |
* doesn't like doing that with shorthand properties so for the properties that | |
* IE8 breaks on, which are listed here, we instead unset each of the | |
* individual properties. See http://bugs.jquery.com/ticket/12385. | |
* The 4-value 'clock' properties like margin, padding, border-width seem to | |
* behave without any problems. Curiously, list-style works too without any | |
* special prodding. | |
*/ | |
var shorthandPropertyExpansions = { | |
background: { | |
backgroundAttachment: true, | |
backgroundColor: true, | |
backgroundImage: true, | |
backgroundPositionX: true, | |
backgroundPositionY: true, | |
backgroundRepeat: true | |
}, | |
backgroundPosition: { | |
backgroundPositionX: true, | |
backgroundPositionY: true | |
}, | |
border: { | |
borderWidth: true, | |
borderStyle: true, | |
borderColor: true | |
}, | |
borderBottom: { | |
borderBottomWidth: true, | |
borderBottomStyle: true, | |
borderBottomColor: true | |
}, | |
borderLeft: { | |
borderLeftWidth: true, | |
borderLeftStyle: true, | |
borderLeftColor: true | |
}, | |
borderRight: { | |
borderRightWidth: true, | |
borderRightStyle: true, | |
borderRightColor: true | |
}, | |
borderTop: { | |
borderTopWidth: true, | |
borderTopStyle: true, | |
borderTopColor: true | |
}, | |
font: { | |
fontStyle: true, | |
fontVariant: true, | |
fontWeight: true, | |
fontSize: true, | |
lineHeight: true, | |
fontFamily: true | |
}, | |
outline: { | |
outlineWidth: true, | |
outlineStyle: true, | |
outlineColor: true | |
} | |
}; | |
var CSSProperty = { | |
isUnitlessNumber: isUnitlessNumber, | |
shorthandPropertyExpansions: shorthandPropertyExpansions | |
}; | |
module.exports = CSSProperty; | |
}); | |
var CSSProperty$1 = interopDefault(CSSProperty); | |
var require$$1$29 = Object.freeze({ | |
default: CSSProperty$1 | |
}); | |
var camelize = createCommonjsModule(function (module) { | |
"use strict"; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
var _hyphenPattern = /-(.)/g; | |
/** | |
* Camelcases a hyphenated string, for example: | |
* | |
* > camelize('background-color') | |
* < "backgroundColor" | |
* | |
* @param {string} string | |
* @return {string} | |
*/ | |
function camelize(string) { | |
return string.replace(_hyphenPattern, function (_, character) { | |
return character.toUpperCase(); | |
}); | |
} | |
module.exports = camelize; | |
}); | |
var camelize$1 = interopDefault(camelize); | |
var require$$0$52 = Object.freeze({ | |
default: camelize$1 | |
}); | |
var camelizeStyleName = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
'use strict'; | |
var camelize = interopDefault(require$$0$52); | |
var msPattern = /^-ms-/; | |
/** | |
* Camelcases a hyphenated CSS property name, for example: | |
* | |
* > camelizeStyleName('background-color') | |
* < "backgroundColor" | |
* > camelizeStyleName('-moz-transition') | |
* < "MozTransition" | |
* > camelizeStyleName('-ms-transition') | |
* < "msTransition" | |
* | |
* As Andi Smith suggests | |
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix | |
* is converted to lowercase `ms`. | |
* | |
* @param {string} string | |
* @return {string} | |
*/ | |
function camelizeStyleName(string) { | |
return camelize(string.replace(msPattern, 'ms-')); | |
} | |
module.exports = camelizeStyleName; | |
}); | |
var camelizeStyleName$1 = interopDefault(camelizeStyleName); | |
var require$$4$12 = Object.freeze({ | |
default: camelizeStyleName$1 | |
}); | |
var dangerousStyleValue = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule dangerousStyleValue | |
*/ | |
'use strict'; | |
var CSSProperty = interopDefault(require$$1$29); | |
var warning = interopDefault(require$$0$34); | |
var isUnitlessNumber = CSSProperty.isUnitlessNumber; | |
var styleWarnings = {}; | |
/** | |
* Convert a value into the proper css writable value. The style name `name` | |
* should be logical (no hyphens), as specified | |
* in `CSSProperty.isUnitlessNumber`. | |
* | |
* @param {string} name CSS property name such as `topMargin`. | |
* @param {*} value CSS property value such as `10px`. | |
* @param {ReactDOMComponent} component | |
* @return {string} Normalized style value with dimensions applied. | |
*/ | |
function dangerousStyleValue(name, value, component) { | |
// Note that we've removed escapeTextForBrowser() calls here since the | |
// whole string will be escaped when the attribute is injected into | |
// the markup. If you provide unsafe user data here they can inject | |
// arbitrary CSS which may be problematic (I couldn't repro this): | |
// https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet | |
// http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ | |
// This is not an XSS hole but instead a potential CSS injection issue | |
// which has lead to a greater discussion about how we're going to | |
// trust URLs moving forward. See #2115901 | |
var isEmpty = value == null || typeof value === 'boolean' || value === ''; | |
if (isEmpty) { | |
return ''; | |
} | |
var isNonNumeric = isNaN(value); | |
if (isNonNumeric || value === 0 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { | |
return '' + value; // cast to string | |
} | |
if (typeof value === 'string') { | |
if ("development" !== 'production') { | |
// Allow '0' to pass through without warning. 0 is already special and | |
// doesn't require units, so we don't need to warn about it. | |
if (component && value !== '0') { | |
var owner = component._currentElement._owner; | |
var ownerName = owner ? owner.getName() : null; | |
if (ownerName && !styleWarnings[ownerName]) { | |
styleWarnings[ownerName] = {}; | |
} | |
var warned = false; | |
if (ownerName) { | |
var warnings = styleWarnings[ownerName]; | |
warned = warnings[name]; | |
if (!warned) { | |
warnings[name] = true; | |
} | |
} | |
if (!warned) { | |
warning(false, 'a `%s` tag (owner: `%s`) was passed a numeric string value ' + 'for CSS property `%s` (value: `%s`) which will be treated ' + 'as a unitless number in a future version of React.', component._currentElement.type, ownerName || 'unknown', name, value); | |
} | |
} | |
} | |
value = value.trim(); | |
} | |
return value + 'px'; | |
} | |
module.exports = dangerousStyleValue; | |
}); | |
var dangerousStyleValue$1 = interopDefault(dangerousStyleValue); | |
var require$$3$15 = Object.freeze({ | |
default: dangerousStyleValue$1 | |
}); | |
var hyphenate = createCommonjsModule(function (module) { | |
'use strict'; | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
var _uppercasePattern = /([A-Z])/g; | |
/** | |
* Hyphenates a camelcased string, for example: | |
* | |
* > hyphenate('backgroundColor') | |
* < "background-color" | |
* | |
* For CSS style names, use `hyphenateStyleName` instead which works properly | |
* with all vendor prefixes, including `ms`. | |
* | |
* @param {string} string | |
* @return {string} | |
*/ | |
function hyphenate(string) { | |
return string.replace(_uppercasePattern, '-$1').toLowerCase(); | |
} | |
module.exports = hyphenate; | |
}); | |
var hyphenate$1 = interopDefault(hyphenate); | |
var require$$0$53 = Object.freeze({ | |
default: hyphenate$1 | |
}); | |
var hyphenateStyleName = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @typechecks | |
*/ | |
'use strict'; | |
var hyphenate = interopDefault(require$$0$53); | |
var msPattern = /^ms-/; | |
/** | |
* Hyphenates a camelcased CSS property name, for example: | |
* | |
* > hyphenateStyleName('backgroundColor') | |
* < "background-color" | |
* > hyphenateStyleName('MozTransition') | |
* < "-moz-transition" | |
* > hyphenateStyleName('msTransition') | |
* < "-ms-transition" | |
* | |
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix | |
* is converted to `-ms-`. | |
* | |
* @param {string} string | |
* @return {string} | |
*/ | |
function hyphenateStyleName(string) { | |
return hyphenate(string).replace(msPattern, '-ms-'); | |
} | |
module.exports = hyphenateStyleName; | |
}); | |
var hyphenateStyleName$1 = interopDefault(hyphenateStyleName); | |
var require$$2$29 = Object.freeze({ | |
default: hyphenateStyleName$1 | |
}); | |
var memoizeStringOnly = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* | |
* @typechecks static-only | |
*/ | |
'use strict'; | |
/** | |
* Memoizes the return value of a function that accepts one string argument. | |
*/ | |
function memoizeStringOnly(callback) { | |
var cache = {}; | |
return function (string) { | |
if (!cache.hasOwnProperty(string)) { | |
cache[string] = callback.call(this, string); | |
} | |
return cache[string]; | |
}; | |
} | |
module.exports = memoizeStringOnly; | |
}); | |
var memoizeStringOnly$1 = interopDefault(memoizeStringOnly); | |
var require$$1$30 = Object.freeze({ | |
default: memoizeStringOnly$1 | |
}); | |
var CSSPropertyOperations = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule CSSPropertyOperations | |
*/ | |
'use strict'; | |
var CSSProperty = interopDefault(require$$1$29); | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
var ReactInstrumentation = interopDefault(require$$8); | |
var camelizeStyleName = interopDefault(require$$4$12); | |
var dangerousStyleValue = interopDefault(require$$3$15); | |
var hyphenateStyleName = interopDefault(require$$2$29); | |
var memoizeStringOnly = interopDefault(require$$1$30); | |
var warning = interopDefault(require$$0$34); | |
var processStyleName = memoizeStringOnly(function (styleName) { | |
return hyphenateStyleName(styleName); | |
}); | |
var hasShorthandPropertyBug = false; | |
var styleFloatAccessor = 'cssFloat'; | |
if (ExecutionEnvironment.canUseDOM) { | |
var tempStyle = document.createElement('div').style; | |
try { | |
// IE8 throws "Invalid argument." if resetting shorthand style properties. | |
tempStyle.font = ''; | |
} catch (e) { | |
hasShorthandPropertyBug = true; | |
} | |
// IE8 only supports accessing cssFloat (standard) as styleFloat | |
if (document.documentElement.style.cssFloat === undefined) { | |
styleFloatAccessor = 'styleFloat'; | |
} | |
} | |
if ("development" !== 'production') { | |
// 'msTransform' is correct, but the other prefixes should be capitalized | |
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; | |
// style values shouldn't contain a semicolon | |
var badStyleValueWithSemicolonPattern = /;\s*$/; | |
var warnedStyleNames = {}; | |
var warnedStyleValues = {}; | |
var warnedForNaNValue = false; | |
var warnHyphenatedStyleName = function (name, owner) { | |
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { | |
return; | |
} | |
warnedStyleNames[name] = true; | |
warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), checkRenderMessage(owner)); | |
}; | |
var warnBadVendoredStyleName = function (name, owner) { | |
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { | |
return; | |
} | |
warnedStyleNames[name] = true; | |
warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)); | |
}; | |
var warnStyleValueWithSemicolon = function (name, value, owner) { | |
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { | |
return; | |
} | |
warnedStyleValues[value] = true; | |
warning(false, 'Style property values shouldn\'t contain a semicolon.%s ' + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')); | |
}; | |
var warnStyleValueIsNaN = function (name, value, owner) { | |
if (warnedForNaNValue) { | |
return; | |
} | |
warnedForNaNValue = true; | |
warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)); | |
}; | |
var checkRenderMessage = function (owner) { | |
if (owner) { | |
var name = owner.getName(); | |
if (name) { | |
return ' Check the render method of `' + name + '`.'; | |
} | |
} | |
return ''; | |
}; | |
/** | |
* @param {string} name | |
* @param {*} value | |
* @param {ReactDOMComponent} component | |
*/ | |
var warnValidStyle = function (name, value, component) { | |
var owner; | |
if (component) { | |
owner = component._currentElement._owner; | |
} | |
if (name.indexOf('-') > -1) { | |
warnHyphenatedStyleName(name, owner); | |
} else if (badVendoredStyleNamePattern.test(name)) { | |
warnBadVendoredStyleName(name, owner); | |
} else if (badStyleValueWithSemicolonPattern.test(value)) { | |
warnStyleValueWithSemicolon(name, value, owner); | |
} | |
if (typeof value === 'number' && isNaN(value)) { | |
warnStyleValueIsNaN(name, value, owner); | |
} | |
}; | |
} | |
/** | |
* Operations for dealing with CSS properties. | |
*/ | |
var CSSPropertyOperations = { | |
/** | |
* Serializes a mapping of style properties for use as inline styles: | |
* | |
* > createMarkupForStyles({width: '200px', height: 0}) | |
* "width:200px;height:0;" | |
* | |
* Undefined values are ignored so that declarative programming is easier. | |
* The result should be HTML-escaped before insertion into the DOM. | |
* | |
* @param {object} styles | |
* @param {ReactDOMComponent} component | |
* @return {?string} | |
*/ | |
createMarkupForStyles: function (styles, component) { | |
var serialized = ''; | |
for (var styleName in styles) { | |
if (!styles.hasOwnProperty(styleName)) { | |
continue; | |
} | |
var styleValue = styles[styleName]; | |
if ("development" !== 'production') { | |
warnValidStyle(styleName, styleValue, component); | |
} | |
if (styleValue != null) { | |
serialized += processStyleName(styleName) + ':'; | |
serialized += dangerousStyleValue(styleName, styleValue, component) + ';'; | |
} | |
} | |
return serialized || null; | |
}, | |
/** | |
* Sets the value for multiple styles on a node. If a value is specified as | |
* '' (empty string), the corresponding style property will be unset. | |
* | |
* @param {DOMElement} node | |
* @param {object} styles | |
* @param {ReactDOMComponent} component | |
*/ | |
setValueForStyles: function (node, styles, component) { | |
if ("development" !== 'production') { | |
ReactInstrumentation.debugTool.onHostOperation(component._debugID, 'update styles', styles); | |
} | |
var style = node.style; | |
for (var styleName in styles) { | |
if (!styles.hasOwnProperty(styleName)) { | |
continue; | |
} | |
if ("development" !== 'production') { | |
warnValidStyle(styleName, styles[styleName], component); | |
} | |
var styleValue = dangerousStyleValue(styleName, styles[styleName], component); | |
if (styleName === 'float' || styleName === 'cssFloat') { | |
styleName = styleFloatAccessor; | |
} | |
if (styleValue) { | |
style[styleName] = styleValue; | |
} else { | |
var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName]; | |
if (expansion) { | |
// Shorthand property that IE8 won't like unsetting, so unset each | |
// component to placate it | |
for (var individualStyleName in expansion) { | |
style[individualStyleName] = ''; | |
} | |
} else { | |
style[styleName] = ''; | |
} | |
} | |
} | |
} | |
}; | |
module.exports = CSSPropertyOperations; | |
}); | |
var CSSPropertyOperations$1 = interopDefault(CSSPropertyOperations); | |
var require$$1$28 = Object.freeze({ | |
default: CSSPropertyOperations$1 | |
}); | |
var ReactDOMNullInputValuePropDevtool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMNullInputValuePropDevtool | |
*/ | |
'use strict'; | |
var ReactComponentTreeDevtool = interopDefault(require$$0$39); | |
var warning = interopDefault(require$$0$34); | |
var didWarnValueNull = false; | |
function handleElement(debugID, element) { | |
if (element == null) { | |
return; | |
} | |
if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') { | |
return; | |
} | |
if (element.props != null && element.props.value === null && !didWarnValueNull) { | |
warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)); | |
didWarnValueNull = true; | |
} | |
} | |
var ReactDOMUnknownPropertyDevtool = { | |
onBeforeMountComponent: function (debugID, element) { | |
handleElement(debugID, element); | |
}, | |
onBeforeUpdateComponent: function (debugID, element) { | |
handleElement(debugID, element); | |
} | |
}; | |
module.exports = ReactDOMUnknownPropertyDevtool; | |
}); | |
var ReactDOMNullInputValuePropDevtool$1 = interopDefault(ReactDOMNullInputValuePropDevtool); | |
var require$$3$17 = Object.freeze({ | |
default: ReactDOMNullInputValuePropDevtool$1 | |
}); | |
var ReactDOMUnknownPropertyDevtool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMUnknownPropertyDevtool | |
*/ | |
'use strict'; | |
var DOMProperty = interopDefault(require$$19); | |
var EventPluginRegistry = interopDefault(require$$4$10); | |
var ReactComponentTreeDevtool = interopDefault(require$$0$39); | |
var warning = interopDefault(require$$0$34); | |
if ("development" !== 'production') { | |
var reactProps = { | |
children: true, | |
dangerouslySetInnerHTML: true, | |
key: true, | |
ref: true, | |
autoFocus: true, | |
defaultValue: true, | |
valueLink: true, | |
defaultChecked: true, | |
checkedLink: true, | |
innerHTML: true, | |
suppressContentEditableWarning: true, | |
onFocusIn: true, | |
onFocusOut: true | |
}; | |
var warnedProperties = {}; | |
var validateProperty = function (tagName, name, debugID) { | |
if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { | |
return true; | |
} | |
if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { | |
return true; | |
} | |
if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { | |
return true; | |
} | |
warnedProperties[name] = true; | |
var lowerCasedName = name.toLowerCase(); | |
// data-* attributes should be lowercase; suggest the lowercase version | |
var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; | |
var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; | |
if (standardName != null) { | |
warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)); | |
return true; | |
} else if (registrationName != null) { | |
warning(registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)); | |
return true; | |
} else { | |
// We were unable to guess which prop the user intended. | |
// It is likely that the user was just blindly spreading/forwarding props | |
// Components should be careful to only render valid props/attributes. | |
// Warning will be invoked in warnUnknownProperties to allow grouping. | |
return false; | |
} | |
}; | |
} | |
var warnUnknownProperties = function (debugID, element) { | |
var unknownProps = []; | |
for (var key in element.props) { | |
var isValid = validateProperty(element.type, key, debugID); | |
if (!isValid) { | |
unknownProps.push(key); | |
} | |
} | |
var unknownPropString = unknownProps.map(function (prop) { | |
return '`' + prop + '`'; | |
}).join(', '); | |
if (unknownProps.length === 1) { | |
warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)); | |
} else if (unknownProps.length > 1) { | |
warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)); | |
} | |
}; | |
function handleElement(debugID, element) { | |
if (element == null || typeof element.type !== 'string') { | |
return; | |
} | |
if (element.type.indexOf('-') >= 0 || element.props.is) { | |
return; | |
} | |
warnUnknownProperties(debugID, element); | |
} | |
var ReactDOMUnknownPropertyDevtool = { | |
onBeforeMountComponent: function (debugID, element) { | |
handleElement(debugID, element); | |
}, | |
onBeforeUpdateComponent: function (debugID, element) { | |
handleElement(debugID, element); | |
} | |
}; | |
module.exports = ReactDOMUnknownPropertyDevtool; | |
}); | |
var ReactDOMUnknownPropertyDevtool$1 = interopDefault(ReactDOMUnknownPropertyDevtool); | |
var require$$2$30 = Object.freeze({ | |
default: ReactDOMUnknownPropertyDevtool$1 | |
}); | |
var ReactDOMDebugTool = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMDebugTool | |
*/ | |
'use strict'; | |
var ReactDOMNullInputValuePropDevtool = interopDefault(require$$3$17); | |
var ReactDOMUnknownPropertyDevtool = interopDefault(require$$2$30); | |
var ReactDebugTool = interopDefault(require$$1$21); | |
var warning = interopDefault(require$$0$34); | |
var eventHandlers = []; | |
var handlerDoesThrowForEvent = {}; | |
function emitEvent(handlerFunctionName, arg1, arg2, arg3, arg4, arg5) { | |
eventHandlers.forEach(function (handler) { | |
try { | |
if (handler[handlerFunctionName]) { | |
handler[handlerFunctionName](arg1, arg2, arg3, arg4, arg5); | |
} | |
} catch (e) { | |
warning(handlerDoesThrowForEvent[handlerFunctionName], 'exception thrown by devtool while handling %s: %s', handlerFunctionName, e + '\n' + e.stack); | |
handlerDoesThrowForEvent[handlerFunctionName] = true; | |
} | |
}); | |
} | |
var ReactDOMDebugTool = { | |
addDevtool: function (devtool) { | |
ReactDebugTool.addDevtool(devtool); | |
eventHandlers.push(devtool); | |
}, | |
removeDevtool: function (devtool) { | |
ReactDebugTool.removeDevtool(devtool); | |
for (var i = 0; i < eventHandlers.length; i++) { | |
if (eventHandlers[i] === devtool) { | |
eventHandlers.splice(i, 1); | |
i--; | |
} | |
} | |
}, | |
onCreateMarkupForProperty: function (name, value) { | |
emitEvent('onCreateMarkupForProperty', name, value); | |
}, | |
onSetValueForProperty: function (node, name, value) { | |
emitEvent('onSetValueForProperty', node, name, value); | |
}, | |
onDeleteValueForProperty: function (node, name) { | |
emitEvent('onDeleteValueForProperty', node, name); | |
}, | |
onTestEvent: function () { | |
emitEvent('onTestEvent'); | |
} | |
}; | |
ReactDOMDebugTool.addDevtool(ReactDOMUnknownPropertyDevtool); | |
ReactDOMDebugTool.addDevtool(ReactDOMNullInputValuePropDevtool); | |
module.exports = ReactDOMDebugTool; | |
}); | |
var ReactDOMDebugTool$1 = interopDefault(ReactDOMDebugTool); | |
var require$$0$54 = Object.freeze({ | |
default: ReactDOMDebugTool$1 | |
}); | |
var ReactDOMInstrumentation = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMInstrumentation | |
*/ | |
'use strict'; | |
var debugTool = null; | |
if ("development" !== 'production') { | |
var ReactDOMDebugTool = interopDefault(require$$0$54); | |
debugTool = ReactDOMDebugTool; | |
} | |
module.exports = { debugTool: debugTool }; | |
}); | |
var ReactDOMInstrumentation$1 = interopDefault(ReactDOMInstrumentation); | |
var debugTool$1 = ReactDOMInstrumentation.debugTool; | |
var require$$3$16 = Object.freeze({ | |
default: ReactDOMInstrumentation$1, | |
debugTool: debugTool$1 | |
}); | |
var quoteAttributeValueForBrowser = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule quoteAttributeValueForBrowser | |
*/ | |
'use strict'; | |
var escapeTextContentForBrowser = interopDefault(require$$2$26); | |
/** | |
* Escapes attribute value to prevent scripting attacks. | |
* | |
* @param {*} value Value to escape. | |
* @return {string} An escaped string. | |
*/ | |
function quoteAttributeValueForBrowser(value) { | |
return '"' + escapeTextContentForBrowser(value) + '"'; | |
} | |
module.exports = quoteAttributeValueForBrowser; | |
}); | |
var quoteAttributeValueForBrowser$1 = interopDefault(quoteAttributeValueForBrowser); | |
var require$$1$31 = Object.freeze({ | |
default: quoteAttributeValueForBrowser$1 | |
}); | |
var DOMPropertyOperations = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DOMPropertyOperations | |
*/ | |
'use strict'; | |
var DOMProperty = interopDefault(require$$19); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactDOMInstrumentation = interopDefault(require$$3$16); | |
var ReactInstrumentation = interopDefault(require$$8); | |
var quoteAttributeValueForBrowser = interopDefault(require$$1$31); | |
var warning = interopDefault(require$$0$34); | |
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); | |
var illegalAttributeNameCache = {}; | |
var validatedAttributeNameCache = {}; | |
function isAttributeNameSafe(attributeName) { | |
if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { | |
return true; | |
} | |
if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { | |
return false; | |
} | |
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { | |
validatedAttributeNameCache[attributeName] = true; | |
return true; | |
} | |
illegalAttributeNameCache[attributeName] = true; | |
warning(false, 'Invalid attribute name: `%s`', attributeName); | |
return false; | |
} | |
function shouldIgnoreValue(propertyInfo, value) { | |
return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; | |
} | |
/** | |
* Operations for dealing with DOM properties. | |
*/ | |
var DOMPropertyOperations = { | |
/** | |
* Creates markup for the ID property. | |
* | |
* @param {string} id Unescaped ID. | |
* @return {string} Markup string. | |
*/ | |
createMarkupForID: function (id) { | |
return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); | |
}, | |
setAttributeForID: function (node, id) { | |
node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); | |
}, | |
createMarkupForRoot: function () { | |
return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; | |
}, | |
setAttributeForRoot: function (node) { | |
node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, ''); | |
}, | |
/** | |
* Creates markup for a property. | |
* | |
* @param {string} name | |
* @param {*} value | |
* @return {?string} Markup string, or null if the property was invalid. | |
*/ | |
createMarkupForProperty: function (name, value) { | |
if ("development" !== 'production') { | |
ReactDOMInstrumentation.debugTool.onCreateMarkupForProperty(name, value); | |
} | |
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; | |
if (propertyInfo) { | |
if (shouldIgnoreValue(propertyInfo, value)) { | |
return ''; | |
} | |
var attributeName = propertyInfo.attributeName; | |
if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { | |
return attributeName + '=""'; | |
} | |
return attributeName + '=' + quoteAttributeValueForBrowser(value); | |
} else if (DOMProperty.isCustomAttribute(name)) { | |
if (value == null) { | |
return ''; | |
} | |
return name + '=' + quoteAttributeValueForBrowser(value); | |
} | |
return null; | |
}, | |
/** | |
* Creates markup for a custom property. | |
* | |
* @param {string} name | |
* @param {*} value | |
* @return {string} Markup string, or empty string if the property was invalid. | |
*/ | |
createMarkupForCustomAttribute: function (name, value) { | |
if (!isAttributeNameSafe(name) || value == null) { | |
return ''; | |
} | |
return name + '=' + quoteAttributeValueForBrowser(value); | |
}, | |
/** | |
* Sets the value for a property on a node. | |
* | |
* @param {DOMElement} node | |
* @param {string} name | |
* @param {*} value | |
*/ | |
setValueForProperty: function (node, name, value) { | |
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; | |
if (propertyInfo) { | |
var mutationMethod = propertyInfo.mutationMethod; | |
if (mutationMethod) { | |
mutationMethod(node, value); | |
} else if (shouldIgnoreValue(propertyInfo, value)) { | |
this.deleteValueForProperty(node, name); | |
return; | |
} else if (propertyInfo.mustUseProperty) { | |
// Contrary to `setAttribute`, object properties are properly | |
// `toString`ed by IE8/9. | |
node[propertyInfo.propertyName] = value; | |
} else { | |
var attributeName = propertyInfo.attributeName; | |
var namespace = propertyInfo.attributeNamespace; | |
// `setAttribute` with objects becomes only `[object]` in IE8/9, | |
// ('' + value) makes it output the correct toString()-value. | |
if (namespace) { | |
node.setAttributeNS(namespace, attributeName, '' + value); | |
} else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { | |
node.setAttribute(attributeName, ''); | |
} else { | |
node.setAttribute(attributeName, '' + value); | |
} | |
} | |
} else if (DOMProperty.isCustomAttribute(name)) { | |
DOMPropertyOperations.setValueForAttribute(node, name, value); | |
return; | |
} | |
if ("development" !== 'production') { | |
ReactDOMInstrumentation.debugTool.onSetValueForProperty(node, name, value); | |
var payload = {}; | |
payload[name] = value; | |
ReactInstrumentation.debugTool.onHostOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'update attribute', payload); | |
} | |
}, | |
setValueForAttribute: function (node, name, value) { | |
if (!isAttributeNameSafe(name)) { | |
return; | |
} | |
if (value == null) { | |
node.removeAttribute(name); | |
} else { | |
node.setAttribute(name, '' + value); | |
} | |
if ("development" !== 'production') { | |
var payload = {}; | |
payload[name] = value; | |
ReactInstrumentation.debugTool.onHostOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'update attribute', payload); | |
} | |
}, | |
/** | |
* Deletes an attributes from a node. | |
* | |
* @param {DOMElement} node | |
* @param {string} name | |
*/ | |
deleteValueForAttribute: function (node, name) { | |
node.removeAttribute(name); | |
if ("development" !== 'production') { | |
ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name); | |
ReactInstrumentation.debugTool.onHostOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'remove attribute', name); | |
} | |
}, | |
/** | |
* Deletes the value for a property on a node. | |
* | |
* @param {DOMElement} node | |
* @param {string} name | |
*/ | |
deleteValueForProperty: function (node, name) { | |
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; | |
if (propertyInfo) { | |
var mutationMethod = propertyInfo.mutationMethod; | |
if (mutationMethod) { | |
mutationMethod(node, undefined); | |
} else if (propertyInfo.mustUseProperty) { | |
var propName = propertyInfo.propertyName; | |
if (propertyInfo.hasBooleanValue) { | |
node[propName] = false; | |
} else { | |
node[propName] = ''; | |
} | |
} else { | |
node.removeAttribute(propertyInfo.attributeName); | |
} | |
} else if (DOMProperty.isCustomAttribute(name)) { | |
node.removeAttribute(name); | |
} | |
if ("development" !== 'production') { | |
ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name); | |
ReactInstrumentation.debugTool.onHostOperation(ReactDOMComponentTree.getInstanceFromNode(node)._debugID, 'remove attribute', name); | |
} | |
} | |
}; | |
module.exports = DOMPropertyOperations; | |
}); | |
var DOMPropertyOperations$1 = interopDefault(DOMPropertyOperations); | |
var require$$5$6 = Object.freeze({ | |
default: DOMPropertyOperations$1 | |
}); | |
var ReactEventEmitterMixin = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactEventEmitterMixin | |
*/ | |
'use strict'; | |
var EventPluginHub = interopDefault(require$$7$1); | |
function runEventQueueInBatch(events) { | |
EventPluginHub.enqueueEvents(events); | |
EventPluginHub.processEventQueue(false); | |
} | |
var ReactEventEmitterMixin = { | |
/** | |
* Streams a fired top-level event to `EventPluginHub` where plugins have the | |
* opportunity to create `ReactEvent`s to be dispatched. | |
*/ | |
handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { | |
var events = EventPluginHub.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); | |
runEventQueueInBatch(events); | |
} | |
}; | |
module.exports = ReactEventEmitterMixin; | |
}); | |
var ReactEventEmitterMixin$1 = interopDefault(ReactEventEmitterMixin); | |
var require$$3$18 = Object.freeze({ | |
default: ReactEventEmitterMixin$1 | |
}); | |
var getVendorPrefixedEventName = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule getVendorPrefixedEventName | |
*/ | |
'use strict'; | |
var ExecutionEnvironment = interopDefault(require$$7$2); | |
/** | |
* Generate a mapping of standard vendor prefixes using the defined style property and event name. | |
* | |
* @param {string} styleProp | |
* @param {string} eventName | |
* @returns {object} | |
*/ | |
function makePrefixMap(styleProp, eventName) { | |
var prefixes = {}; | |
prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); | |
prefixes['Webkit' + styleProp] = 'webkit' + eventName; | |
prefixes['Moz' + styleProp] = 'moz' + eventName; | |
prefixes['ms' + styleProp] = 'MS' + eventName; | |
prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); | |
return prefixes; | |
} | |
/** | |
* A list of event names to a configurable list of vendor prefixes. | |
*/ | |
var vendorPrefixes = { | |
animationend: makePrefixMap('Animation', 'AnimationEnd'), | |
animationiteration: makePrefixMap('Animation', 'AnimationIteration'), | |
animationstart: makePrefixMap('Animation', 'AnimationStart'), | |
transitionend: makePrefixMap('Transition', 'TransitionEnd') | |
}; | |
/** | |
* Event names that have already been detected and prefixed (if applicable). | |
*/ | |
var prefixedEventNames = {}; | |
/** | |
* Element to check for prefixes on. | |
*/ | |
var style = {}; | |
/** | |
* Bootstrap if a DOM exists. | |
*/ | |
if (ExecutionEnvironment.canUseDOM) { | |
style = document.createElement('div').style; | |
// On some platforms, in particular some releases of Android 4.x, | |
// the un-prefixed "animation" and "transition" properties are defined on the | |
// style object but the events that fire will still be prefixed, so we need | |
// to check if the un-prefixed events are usable, and if not remove them from the map. | |
if (!('AnimationEvent' in window)) { | |
delete vendorPrefixes.animationend.animation; | |
delete vendorPrefixes.animationiteration.animation; | |
delete vendorPrefixes.animationstart.animation; | |
} | |
// Same as above | |
if (!('TransitionEvent' in window)) { | |
delete vendorPrefixes.transitionend.transition; | |
} | |
} | |
/** | |
* Attempts to determine the correct vendor prefixed event name. | |
* | |
* @param {string} eventName | |
* @returns {string} | |
*/ | |
function getVendorPrefixedEventName(eventName) { | |
if (prefixedEventNames[eventName]) { | |
return prefixedEventNames[eventName]; | |
} else if (!vendorPrefixes[eventName]) { | |
return eventName; | |
} | |
var prefixMap = vendorPrefixes[eventName]; | |
for (var styleProp in prefixMap) { | |
if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { | |
return prefixedEventNames[eventName] = prefixMap[styleProp]; | |
} | |
} | |
return ''; | |
} | |
module.exports = getVendorPrefixedEventName; | |
}); | |
var getVendorPrefixedEventName$1 = interopDefault(getVendorPrefixedEventName); | |
var require$$1$32 = Object.freeze({ | |
default: getVendorPrefixedEventName$1 | |
}); | |
var ReactBrowserEventEmitter = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactBrowserEventEmitter | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var EventConstants = interopDefault(require$$18); | |
var EventPluginRegistry = interopDefault(require$$4$10); | |
var ReactEventEmitterMixin = interopDefault(require$$3$18); | |
var ViewportMetrics = interopDefault(require$$2$24); | |
var getVendorPrefixedEventName = interopDefault(require$$1$32); | |
var isEventSupported = interopDefault(require$$0$46); | |
/** | |
* Summary of `ReactBrowserEventEmitter` event handling: | |
* | |
* - Top-level delegation is used to trap most native browser events. This | |
* may only occur in the main thread and is the responsibility of | |
* ReactEventListener, which is injected and can therefore support pluggable | |
* event sources. This is the only work that occurs in the main thread. | |
* | |
* - We normalize and de-duplicate events to account for browser quirks. This | |
* may be done in the worker thread. | |
* | |
* - Forward these native events (with the associated top-level type used to | |
* trap it) to `EventPluginHub`, which in turn will ask plugins if they want | |
* to extract any synthetic events. | |
* | |
* - The `EventPluginHub` will then process each event by annotating them with | |
* "dispatches", a sequence of listeners and IDs that care about that event. | |
* | |
* - The `EventPluginHub` then dispatches the events. | |
* | |
* Overview of React and the event system: | |
* | |
* +------------+ . | |
* | DOM | . | |
* +------------+ . | |
* | . | |
* v . | |
* +------------+ . | |
* | ReactEvent | . | |
* | Listener | . | |
* +------------+ . +-----------+ | |
* | . +--------+|SimpleEvent| | |
* | . | |Plugin | | |
* +-----|------+ . v +-----------+ | |
* | | | . +--------------+ +------------+ | |
* | +-----------.--->|EventPluginHub| | Event | | |
* | | . | | +-----------+ | Propagators| | |
* | ReactEvent | . | | |TapEvent | |------------| | |
* | Emitter | . | |<---+|Plugin | |other plugin| | |
* | | . | | +-----------+ | utilities | | |
* | +-----------.--->| | +------------+ | |
* | | | . +--------------+ | |
* +-----|------+ . ^ +-----------+ | |
* | . | |Enter/Leave| | |
* + . +-------+|Plugin | | |
* +-------------+ . +-----------+ | |
* | application | . | |
* |-------------| . | |
* | | . | |
* | | . | |
* +-------------+ . | |
* . | |
* React Core . General Purpose Event Plugin System | |
*/ | |
var hasEventPageXY; | |
var alreadyListeningTo = {}; | |
var isMonitoringScrollValue = false; | |
var reactTopListenersCounter = 0; | |
// For events like 'submit' which don't consistently bubble (which we trap at a | |
// lower node than `document`), binding at `document` would cause duplicate | |
// events so we don't include them here | |
var topEventMapping = { | |
topAbort: 'abort', | |
topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend', | |
topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration', | |
topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart', | |
topBlur: 'blur', | |
topCanPlay: 'canplay', | |
topCanPlayThrough: 'canplaythrough', | |
topChange: 'change', | |
topClick: 'click', | |
topCompositionEnd: 'compositionend', | |
topCompositionStart: 'compositionstart', | |
topCompositionUpdate: 'compositionupdate', | |
topContextMenu: 'contextmenu', | |
topCopy: 'copy', | |
topCut: 'cut', | |
topDoubleClick: 'dblclick', | |
topDrag: 'drag', | |
topDragEnd: 'dragend', | |
topDragEnter: 'dragenter', | |
topDragExit: 'dragexit', | |
topDragLeave: 'dragleave', | |
topDragOver: 'dragover', | |
topDragStart: 'dragstart', | |
topDrop: 'drop', | |
topDurationChange: 'durationchange', | |
topEmptied: 'emptied', | |
topEncrypted: 'encrypted', | |
topEnded: 'ended', | |
topError: 'error', | |
topFocus: 'focus', | |
topInput: 'input', | |
topKeyDown: 'keydown', | |
topKeyPress: 'keypress', | |
topKeyUp: 'keyup', | |
topLoadedData: 'loadeddata', | |
topLoadedMetadata: 'loadedmetadata', | |
topLoadStart: 'loadstart', | |
topMouseDown: 'mousedown', | |
topMouseMove: 'mousemove', | |
topMouseOut: 'mouseout', | |
topMouseOver: 'mouseover', | |
topMouseUp: 'mouseup', | |
topPaste: 'paste', | |
topPause: 'pause', | |
topPlay: 'play', | |
topPlaying: 'playing', | |
topProgress: 'progress', | |
topRateChange: 'ratechange', | |
topScroll: 'scroll', | |
topSeeked: 'seeked', | |
topSeeking: 'seeking', | |
topSelectionChange: 'selectionchange', | |
topStalled: 'stalled', | |
topSuspend: 'suspend', | |
topTextInput: 'textInput', | |
topTimeUpdate: 'timeupdate', | |
topTouchCancel: 'touchcancel', | |
topTouchEnd: 'touchend', | |
topTouchMove: 'touchmove', | |
topTouchStart: 'touchstart', | |
topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend', | |
topVolumeChange: 'volumechange', | |
topWaiting: 'waiting', | |
topWheel: 'wheel' | |
}; | |
/** | |
* To ensure no conflicts with other potential React instances on the page | |
*/ | |
var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); | |
function getListeningForDocument(mountAt) { | |
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` | |
// directly. | |
if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { | |
mountAt[topListenersIDKey] = reactTopListenersCounter++; | |
alreadyListeningTo[mountAt[topListenersIDKey]] = {}; | |
} | |
return alreadyListeningTo[mountAt[topListenersIDKey]]; | |
} | |
/** | |
* `ReactBrowserEventEmitter` is used to attach top-level event listeners. For | |
* example: | |
* | |
* EventPluginHub.putListener('myID', 'onClick', myFunction); | |
* | |
* This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. | |
* | |
* @internal | |
*/ | |
var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { | |
/** | |
* Injectable event backend | |
*/ | |
ReactEventListener: null, | |
injection: { | |
/** | |
* @param {object} ReactEventListener | |
*/ | |
injectReactEventListener: function (ReactEventListener) { | |
ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel); | |
ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; | |
} | |
}, | |
/** | |
* Sets whether or not any created callbacks should be enabled. | |
* | |
* @param {boolean} enabled True if callbacks should be enabled. | |
*/ | |
setEnabled: function (enabled) { | |
if (ReactBrowserEventEmitter.ReactEventListener) { | |
ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); | |
} | |
}, | |
/** | |
* @return {boolean} True if callbacks are enabled. | |
*/ | |
isEnabled: function () { | |
return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled()); | |
}, | |
/** | |
* We listen for bubbled touch events on the document object. | |
* | |
* Firefox v8.01 (and possibly others) exhibited strange behavior when | |
* mounting `onmousemove` events at some node that was not the document | |
* element. The symptoms were that if your mouse is not moving over something | |
* contained within that mount point (for example on the background) the | |
* top-level listeners for `onmousemove` won't be called. However, if you | |
* register the `mousemove` on the document object, then it will of course | |
* catch all `mousemove`s. This along with iOS quirks, justifies restricting | |
* top-level listeners to the document object only, at least for these | |
* movement types of events and possibly all events. | |
* | |
* @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html | |
* | |
* Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but | |
* they bubble to document. | |
* | |
* @param {string} registrationName Name of listener (e.g. `onClick`). | |
* @param {object} contentDocumentHandle Document which owns the container | |
*/ | |
listenTo: function (registrationName, contentDocumentHandle) { | |
var mountAt = contentDocumentHandle; | |
var isListening = getListeningForDocument(mountAt); | |
var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; | |
var topLevelTypes = EventConstants.topLevelTypes; | |
for (var i = 0; i < dependencies.length; i++) { | |
var dependency = dependencies[i]; | |
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { | |
if (dependency === topLevelTypes.topWheel) { | |
if (isEventSupported('wheel')) { | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt); | |
} else if (isEventSupported('mousewheel')) { | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt); | |
} else { | |
// Firefox needs to capture a different mouse scroll event. | |
// @see http://www.quirksmode.org/dom/events/tests/scroll.html | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel, 'DOMMouseScroll', mountAt); | |
} | |
} else if (dependency === topLevelTypes.topScroll) { | |
if (isEventSupported('scroll', true)) { | |
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt); | |
} else { | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topScroll, 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE); | |
} | |
} else if (dependency === topLevelTypes.topFocus || dependency === topLevelTypes.topBlur) { | |
if (isEventSupported('focus', true)) { | |
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt); | |
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt); | |
} else if (isEventSupported('focusin')) { | |
// IE has `focusin` and `focusout` events which bubble. | |
// @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt); | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt); | |
} | |
// to make sure blur and focus event listeners are only attached once | |
isListening[topLevelTypes.topBlur] = true; | |
isListening[topLevelTypes.topFocus] = true; | |
} else if (topEventMapping.hasOwnProperty(dependency)) { | |
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt); | |
} | |
isListening[dependency] = true; | |
} | |
} | |
}, | |
trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { | |
return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle); | |
}, | |
trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { | |
return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle); | |
}, | |
/** | |
* Listens to window scroll and resize events. We cache scroll values so that | |
* application code can access them without triggering reflows. | |
* | |
* ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when | |
* pageX/pageY isn't supported (legacy browsers). | |
* | |
* NOTE: Scroll events do not bubble. | |
* | |
* @see http://www.quirksmode.org/dom/events/scroll.html | |
*/ | |
ensureScrollValueMonitoring: function () { | |
if (hasEventPageXY === undefined) { | |
hasEventPageXY = document.createEvent && 'pageX' in document.createEvent('MouseEvent'); | |
} | |
if (!hasEventPageXY && !isMonitoringScrollValue) { | |
var refresh = ViewportMetrics.refreshScrollValues; | |
ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); | |
isMonitoringScrollValue = true; | |
} | |
} | |
}); | |
module.exports = ReactBrowserEventEmitter; | |
}); | |
var ReactBrowserEventEmitter$1 = interopDefault(ReactBrowserEventEmitter); | |
var require$$18$2 = Object.freeze({ | |
default: ReactBrowserEventEmitter$1 | |
}); | |
var DisabledInputUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule DisabledInputUtils | |
*/ | |
'use strict'; | |
var disableableMouseListenerNames = { | |
onClick: true, | |
onDoubleClick: true, | |
onMouseDown: true, | |
onMouseMove: true, | |
onMouseUp: true, | |
onClickCapture: true, | |
onDoubleClickCapture: true, | |
onMouseDownCapture: true, | |
onMouseMoveCapture: true, | |
onMouseUpCapture: true | |
}; | |
/** | |
* Implements a host component that does not receive mouse events | |
* when `disabled` is set. | |
*/ | |
var DisabledInputUtils = { | |
getHostProps: function (inst, props) { | |
if (!props.disabled) { | |
return props; | |
} | |
// Copy the props, except the mouse listeners | |
var hostProps = {}; | |
for (var key in props) { | |
if (!disableableMouseListenerNames[key] && props.hasOwnProperty(key)) { | |
hostProps[key] = props[key]; | |
} | |
} | |
return hostProps; | |
} | |
}; | |
module.exports = DisabledInputUtils; | |
}); | |
var DisabledInputUtils$1 = interopDefault(DisabledInputUtils); | |
var require$$5$7 = Object.freeze({ | |
default: DisabledInputUtils$1 | |
}); | |
var ReactDOMButton = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMButton | |
*/ | |
'use strict'; | |
var DisabledInputUtils = interopDefault(require$$5$7); | |
/** | |
* Implements a <button> host component that does not receive mouse events | |
* when `disabled` is set. | |
*/ | |
var ReactDOMButton = { | |
getHostProps: DisabledInputUtils.getHostProps | |
}; | |
module.exports = ReactDOMButton; | |
}); | |
var ReactDOMButton$1 = interopDefault(ReactDOMButton); | |
var require$$17$1 = Object.freeze({ | |
default: ReactDOMButton$1 | |
}); | |
var LinkedValueUtils = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule LinkedValueUtils | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactPropTypes = interopDefault(require$$3$12); | |
var ReactPropTypeLocations = interopDefault(require$$6); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
var hasReadOnlyValue = { | |
'button': true, | |
'checkbox': true, | |
'image': true, | |
'hidden': true, | |
'radio': true, | |
'reset': true, | |
'submit': true | |
}; | |
function _assertSingleLink(inputProps) { | |
!(inputProps.checkedLink == null || inputProps.valueLink == null) ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : void 0; | |
} | |
function _assertValueLink(inputProps) { | |
_assertSingleLink(inputProps); | |
!(inputProps.value == null && inputProps.onChange == null) ? invariant(false, 'Cannot provide a valueLink and a value or onChange event. If you want to use value or onChange, you probably don\'t want to use valueLink.') : void 0; | |
} | |
function _assertCheckedLink(inputProps) { | |
_assertSingleLink(inputProps); | |
!(inputProps.checked == null && inputProps.onChange == null) ? invariant(false, 'Cannot provide a checkedLink and a checked property or onChange event. If you want to use checked or onChange, you probably don\'t want to use checkedLink') : void 0; | |
} | |
var propTypes = { | |
value: function (props, propName, componentName) { | |
if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { | |
return null; | |
} | |
return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); | |
}, | |
checked: function (props, propName, componentName) { | |
if (!props[propName] || props.onChange || props.readOnly || props.disabled) { | |
return null; | |
} | |
return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); | |
}, | |
onChange: ReactPropTypes.func | |
}; | |
var loggedTypeFailures = {}; | |
function getDeclarationErrorAddendum(owner) { | |
if (owner) { | |
var name = owner.getName(); | |
if (name) { | |
return ' Check the render method of `' + name + '`.'; | |
} | |
} | |
return ''; | |
} | |
/** | |
* Provide a linked `value` attribute for controlled forms. You should not use | |
* this outside of the ReactDOM controlled form components. | |
*/ | |
var LinkedValueUtils = { | |
checkPropTypes: function (tagName, props, owner) { | |
for (var propName in propTypes) { | |
if (propTypes.hasOwnProperty(propName)) { | |
var error = propTypes[propName](props, propName, tagName, ReactPropTypeLocations.prop); | |
} | |
if (error instanceof Error && !(error.message in loggedTypeFailures)) { | |
// Only monitor this failure once because there tends to be a lot of the | |
// same error. | |
loggedTypeFailures[error.message] = true; | |
var addendum = getDeclarationErrorAddendum(owner); | |
warning(false, 'Failed form propType: %s%s', error.message, addendum); | |
} | |
} | |
}, | |
/** | |
* @param {object} inputProps Props for form component | |
* @return {*} current value of the input either from value prop or link. | |
*/ | |
getValue: function (inputProps) { | |
if (inputProps.valueLink) { | |
_assertValueLink(inputProps); | |
return inputProps.valueLink.value; | |
} | |
return inputProps.value; | |
}, | |
/** | |
* @param {object} inputProps Props for form component | |
* @return {*} current checked status of the input either from checked prop | |
* or link. | |
*/ | |
getChecked: function (inputProps) { | |
if (inputProps.checkedLink) { | |
_assertCheckedLink(inputProps); | |
return inputProps.checkedLink.value; | |
} | |
return inputProps.checked; | |
}, | |
/** | |
* @param {object} inputProps Props for form component | |
* @param {SyntheticEvent} event change event to handle | |
*/ | |
executeOnChange: function (inputProps, event) { | |
if (inputProps.valueLink) { | |
_assertValueLink(inputProps); | |
return inputProps.valueLink.requestChange(event.target.value); | |
} else if (inputProps.checkedLink) { | |
_assertCheckedLink(inputProps); | |
return inputProps.checkedLink.requestChange(event.target.checked); | |
} else if (inputProps.onChange) { | |
return inputProps.onChange.call(undefined, event); | |
} | |
} | |
}; | |
module.exports = LinkedValueUtils; | |
}); | |
var LinkedValueUtils$1 = interopDefault(LinkedValueUtils); | |
var require$$4$13 = Object.freeze({ | |
default: LinkedValueUtils$1 | |
}); | |
var ReactDOMInput = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMInput | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12), | |
_assign = interopDefault(require$$7); | |
var DisabledInputUtils = interopDefault(require$$5$7); | |
var DOMPropertyOperations = interopDefault(require$$5$6); | |
var LinkedValueUtils = interopDefault(require$$4$13); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactUpdates = interopDefault(require$$3$14); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
var didWarnValueLink = false; | |
var didWarnCheckedLink = false; | |
var didWarnValueDefaultValue = false; | |
var didWarnCheckedDefaultChecked = false; | |
var didWarnControlledToUncontrolled = false; | |
var didWarnUncontrolledToControlled = false; | |
function forceUpdateIfMounted() { | |
if (this._rootNodeID) { | |
// DOM component is still mounted; update | |
ReactDOMInput.updateWrapper(this); | |
} | |
} | |
function isControlled(props) { | |
var usesChecked = props.type === 'checkbox' || props.type === 'radio'; | |
return usesChecked ? props.checked !== undefined : props.value !== undefined; | |
} | |
/** | |
* Implements an <input> host component that allows setting these optional | |
* props: `checked`, `value`, `defaultChecked`, and `defaultValue`. | |
* | |
* If `checked` or `value` are not supplied (or null/undefined), user actions | |
* that affect the checked state or value will trigger updates to the element. | |
* | |
* If they are supplied (and not null/undefined), the rendered element will not | |
* trigger updates to the element. Instead, the props must change in order for | |
* the rendered element to be updated. | |
* | |
* The rendered element will be initialized as unchecked (or `defaultChecked`) | |
* with an empty value (or `defaultValue`). | |
* | |
* @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html | |
*/ | |
var ReactDOMInput = { | |
getHostProps: function (inst, props) { | |
var value = LinkedValueUtils.getValue(props); | |
var checked = LinkedValueUtils.getChecked(props); | |
var hostProps = _assign({ | |
// Make sure we set .type before any other properties (setting .value | |
// before .type means .value is lost in IE11 and below) | |
type: undefined | |
}, DisabledInputUtils.getHostProps(inst, props), { | |
defaultChecked: undefined, | |
defaultValue: undefined, | |
value: value != null ? value : inst._wrapperState.initialValue, | |
checked: checked != null ? checked : inst._wrapperState.initialChecked, | |
onChange: inst._wrapperState.onChange | |
}); | |
return hostProps; | |
}, | |
mountWrapper: function (inst, props) { | |
if ("development" !== 'production') { | |
LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); | |
var owner = inst._currentElement._owner; | |
if (props.valueLink !== undefined && !didWarnValueLink) { | |
warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.'); | |
didWarnValueLink = true; | |
} | |
if (props.checkedLink !== undefined && !didWarnCheckedLink) { | |
warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.'); | |
didWarnCheckedLink = true; | |
} | |
if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { | |
warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type); | |
didWarnCheckedDefaultChecked = true; | |
} | |
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { | |
warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type); | |
didWarnValueDefaultValue = true; | |
} | |
} | |
var defaultValue = props.defaultValue; | |
inst._wrapperState = { | |
initialChecked: props.checked != null ? props.checked : props.defaultChecked, | |
initialValue: props.value != null ? props.value : defaultValue, | |
listeners: null, | |
onChange: _handleChange.bind(inst) | |
}; | |
if ("development" !== 'production') { | |
inst._wrapperState.controlled = isControlled(props); | |
} | |
}, | |
updateWrapper: function (inst) { | |
var props = inst._currentElement.props; | |
if ("development" !== 'production') { | |
var controlled = isControlled(props); | |
var owner = inst._currentElement._owner; | |
if (!inst._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { | |
warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type); | |
didWarnUncontrolledToControlled = true; | |
} | |
if (inst._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { | |
warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type); | |
didWarnControlledToUncontrolled = true; | |
} | |
} | |
// TODO: Shouldn't this be getChecked(props)? | |
var checked = props.checked; | |
if (checked != null) { | |
DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false); | |
} | |
var node = ReactDOMComponentTree.getNodeFromInstance(inst); | |
var value = LinkedValueUtils.getValue(props); | |
if (value != null) { | |
// Cast `value` to a string to ensure the value is set correctly. While | |
// browsers typically do this as necessary, jsdom doesn't. | |
var newValue = '' + value; | |
// To avoid side effects (such as losing text selection), only set value if changed | |
if (newValue !== node.value) { | |
node.value = newValue; | |
} | |
} else { | |
if (props.value == null && props.defaultValue != null) { | |
node.defaultValue = '' + props.defaultValue; | |
} | |
if (props.checked == null && props.defaultChecked != null) { | |
node.defaultChecked = !!props.defaultChecked; | |
} | |
} | |
}, | |
postMountWrapper: function (inst) { | |
var props = inst._currentElement.props; | |
// This is in postMount because we need access to the DOM node, which is not | |
// available until after the component has mounted. | |
var node = ReactDOMComponentTree.getNodeFromInstance(inst); | |
// Detach value from defaultValue. We won't do anything if we're working on | |
// submit or reset inputs as those values & defaultValues are linked. They | |
// are not resetable nodes so this operation doesn't matter and actually | |
// removes browser-default values (eg "Submit Query") when no value is | |
// provided. | |
if (props.type !== 'submit' && props.type !== 'reset') { | |
node.value = node.value; | |
} | |
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug | |
// this is needed to work around a chrome bug where setting defaultChecked | |
// will sometimes influence the value of checked (even after detachment). | |
// Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 | |
// We need to temporarily unset name to avoid disrupting radio button groups. | |
var name = node.name; | |
if (name !== '') { | |
node.name = ''; | |
} | |
node.defaultChecked = !node.defaultChecked; | |
node.defaultChecked = !node.defaultChecked; | |
if (name !== '') { | |
node.name = name; | |
} | |
} | |
}; | |
function _handleChange(event) { | |
var props = this._currentElement.props; | |
var returnValue = LinkedValueUtils.executeOnChange(props, event); | |
// Here we use asap to wait until all updates have propagated, which | |
// is important when using controlled components within layers: | |
// https://github.com/facebook/react/issues/1698 | |
ReactUpdates.asap(forceUpdateIfMounted, this); | |
var name = props.name; | |
if (props.type === 'radio' && name != null) { | |
var rootNode = ReactDOMComponentTree.getNodeFromInstance(this); | |
var queryRoot = rootNode; | |
while (queryRoot.parentNode) { | |
queryRoot = queryRoot.parentNode; | |
} | |
// If `rootNode.form` was non-null, then we could try `form.elements`, | |
// but that sometimes behaves strangely in IE8. We could also try using | |
// `form.getElementsByName`, but that will only return direct children | |
// and won't include inputs that use the HTML5 `form=` attribute. Since | |
// the input might not even be in a form, let's just use the global | |
// `querySelectorAll` to ensure we don't miss anything. | |
var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]'); | |
for (var i = 0; i < group.length; i++) { | |
var otherNode = group[i]; | |
if (otherNode === rootNode || otherNode.form !== rootNode.form) { | |
continue; | |
} | |
// This will throw if radio buttons rendered by different copies of React | |
// and the same name are rendered into the same form (same as #1939). | |
// That's probably okay; we don't support it just as we don't support | |
// mixing React radio buttons with non-React ones. | |
var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode); | |
!otherInstance ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0; | |
// If this is a controlled radio button group, forcing the input that | |
// was previously checked to update will cause it to be come re-checked | |
// as appropriate. | |
ReactUpdates.asap(forceUpdateIfMounted, otherInstance); | |
} | |
} | |
return returnValue; | |
} | |
module.exports = ReactDOMInput; | |
}); | |
var ReactDOMInput$1 = interopDefault(ReactDOMInput); | |
var require$$14$1 = Object.freeze({ | |
default: ReactDOMInput$1 | |
}); | |
var ReactDOMSelect = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMSelect | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var DisabledInputUtils = interopDefault(require$$5$7); | |
var LinkedValueUtils = interopDefault(require$$4$13); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactUpdates = interopDefault(require$$3$14); | |
var warning = interopDefault(require$$0$34); | |
var didWarnValueLink = false; | |
var didWarnValueDefaultValue = false; | |
function updateOptionsIfPendingUpdateAndMounted() { | |
if (this._rootNodeID && this._wrapperState.pendingUpdate) { | |
this._wrapperState.pendingUpdate = false; | |
var props = this._currentElement.props; | |
var value = LinkedValueUtils.getValue(props); | |
if (value != null) { | |
updateOptions(this, Boolean(props.multiple), value); | |
} | |
} | |
} | |
function getDeclarationErrorAddendum(owner) { | |
if (owner) { | |
var name = owner.getName(); | |
if (name) { | |
return ' Check the render method of `' + name + '`.'; | |
} | |
} | |
return ''; | |
} | |
var valuePropNames = ['value', 'defaultValue']; | |
/** | |
* Validation function for `value` and `defaultValue`. | |
* @private | |
*/ | |
function checkSelectPropTypes(inst, props) { | |
var owner = inst._currentElement._owner; | |
LinkedValueUtils.checkPropTypes('select', props, owner); | |
if (props.valueLink !== undefined && !didWarnValueLink) { | |
warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.'); | |
didWarnValueLink = true; | |
} | |
for (var i = 0; i < valuePropNames.length; i++) { | |
var propName = valuePropNames[i]; | |
if (props[propName] == null) { | |
continue; | |
} | |
if (props.multiple) { | |
warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)); | |
} else { | |
warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)); | |
} | |
} | |
} | |
/** | |
* @param {ReactDOMComponent} inst | |
* @param {boolean} multiple | |
* @param {*} propValue A stringable (with `multiple`, a list of stringables). | |
* @private | |
*/ | |
function updateOptions(inst, multiple, propValue) { | |
var selectedValue, i; | |
var options = ReactDOMComponentTree.getNodeFromInstance(inst).options; | |
if (multiple) { | |
selectedValue = {}; | |
for (i = 0; i < propValue.length; i++) { | |
selectedValue['' + propValue[i]] = true; | |
} | |
for (i = 0; i < options.length; i++) { | |
var selected = selectedValue.hasOwnProperty(options[i].value); | |
if (options[i].selected !== selected) { | |
options[i].selected = selected; | |
} | |
} | |
} else { | |
// Do not set `select.value` as exact behavior isn't consistent across all | |
// browsers for all cases. | |
selectedValue = '' + propValue; | |
for (i = 0; i < options.length; i++) { | |
if (options[i].value === selectedValue) { | |
options[i].selected = true; | |
return; | |
} | |
} | |
if (options.length) { | |
options[0].selected = true; | |
} | |
} | |
} | |
/** | |
* Implements a <select> host component that allows optionally setting the | |
* props `value` and `defaultValue`. If `multiple` is false, the prop must be a | |
* stringable. If `multiple` is true, the prop must be an array of stringables. | |
* | |
* If `value` is not supplied (or null/undefined), user actions that change the | |
* selected option will trigger updates to the rendered options. | |
* | |
* If it is supplied (and not null/undefined), the rendered options will not | |
* update in response to user actions. Instead, the `value` prop must change in | |
* order for the rendered options to update. | |
* | |
* If `defaultValue` is provided, any options with the supplied values will be | |
* selected. | |
*/ | |
var ReactDOMSelect = { | |
getHostProps: function (inst, props) { | |
return _assign({}, DisabledInputUtils.getHostProps(inst, props), { | |
onChange: inst._wrapperState.onChange, | |
value: undefined | |
}); | |
}, | |
mountWrapper: function (inst, props) { | |
if ("development" !== 'production') { | |
checkSelectPropTypes(inst, props); | |
} | |
var value = LinkedValueUtils.getValue(props); | |
inst._wrapperState = { | |
pendingUpdate: false, | |
initialValue: value != null ? value : props.defaultValue, | |
listeners: null, | |
onChange: _handleChange.bind(inst), | |
wasMultiple: Boolean(props.multiple) | |
}; | |
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { | |
warning(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components'); | |
didWarnValueDefaultValue = true; | |
} | |
}, | |
getSelectValueContext: function (inst) { | |
// ReactDOMOption looks at this initial value so the initial generated | |
// markup has correct `selected` attributes | |
return inst._wrapperState.initialValue; | |
}, | |
postUpdateWrapper: function (inst) { | |
var props = inst._currentElement.props; | |
// After the initial mount, we control selected-ness manually so don't pass | |
// this value down | |
inst._wrapperState.initialValue = undefined; | |
var wasMultiple = inst._wrapperState.wasMultiple; | |
inst._wrapperState.wasMultiple = Boolean(props.multiple); | |
var value = LinkedValueUtils.getValue(props); | |
if (value != null) { | |
inst._wrapperState.pendingUpdate = false; | |
updateOptions(inst, Boolean(props.multiple), value); | |
} else if (wasMultiple !== Boolean(props.multiple)) { | |
// For simplicity, reapply `defaultValue` if `multiple` is toggled. | |
if (props.defaultValue != null) { | |
updateOptions(inst, Boolean(props.multiple), props.defaultValue); | |
} else { | |
// Revert the select back to its default unselected state. | |
updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : ''); | |
} | |
} | |
} | |
}; | |
function _handleChange(event) { | |
var props = this._currentElement.props; | |
var returnValue = LinkedValueUtils.executeOnChange(props, event); | |
if (this._rootNodeID) { | |
this._wrapperState.pendingUpdate = true; | |
} | |
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); | |
return returnValue; | |
} | |
module.exports = ReactDOMSelect; | |
}); | |
var ReactDOMSelect$1 = interopDefault(ReactDOMSelect); | |
var require$$1$33 = Object.freeze({ | |
default: ReactDOMSelect$1 | |
}); | |
var ReactDOMOption = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMOption | |
*/ | |
'use strict'; | |
var _assign = interopDefault(require$$7); | |
var ReactChildren = interopDefault(require$$3$9); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactDOMSelect = interopDefault(require$$1$33); | |
var warning = interopDefault(require$$0$34); | |
var didWarnInvalidOptionChildren = false; | |
function flattenChildren(children) { | |
var content = ''; | |
// Flatten children and warn if they aren't strings or numbers; | |
// invalid types are ignored. | |
ReactChildren.forEach(children, function (child) { | |
if (child == null) { | |
return; | |
} | |
if (typeof child === 'string' || typeof child === 'number') { | |
content += child; | |
} else if (!didWarnInvalidOptionChildren) { | |
didWarnInvalidOptionChildren = true; | |
warning(false, 'Only strings and numbers are supported as <option> children.'); | |
} | |
}); | |
return content; | |
} | |
/** | |
* Implements an <option> host component that warns when `selected` is set. | |
*/ | |
var ReactDOMOption = { | |
mountWrapper: function (inst, props, hostParent) { | |
// TODO (yungsters): Remove support for `selected` in <option>. | |
if ("development" !== 'production') { | |
warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.'); | |
} | |
// Look up whether this option is 'selected' | |
var selectValue = null; | |
if (hostParent != null) { | |
var selectParent = hostParent; | |
if (selectParent._tag === 'optgroup') { | |
selectParent = selectParent._hostParent; | |
} | |
if (selectParent != null && selectParent._tag === 'select') { | |
selectValue = ReactDOMSelect.getSelectValueContext(selectParent); | |
} | |
} | |
// If the value is null (e.g., no specified value or after initial mount) | |
// or missing (e.g., for <datalist>), we don't change props.selected | |
var selected = null; | |
if (selectValue != null) { | |
var value; | |
if (props.value != null) { | |
value = props.value + ''; | |
} else { | |
value = flattenChildren(props.children); | |
} | |
selected = false; | |
if (Array.isArray(selectValue)) { | |
// multiple | |
for (var i = 0; i < selectValue.length; i++) { | |
if ('' + selectValue[i] === value) { | |
selected = true; | |
break; | |
} | |
} | |
} else { | |
selected = '' + selectValue === value; | |
} | |
} | |
inst._wrapperState = { selected: selected }; | |
}, | |
postMountWrapper: function (inst) { | |
// value="" should make a value attribute (#6219) | |
var props = inst._currentElement.props; | |
if (props.value != null) { | |
var node = ReactDOMComponentTree.getNodeFromInstance(inst); | |
node.setAttribute('value', props.value); | |
} | |
}, | |
getHostProps: function (inst, props) { | |
var hostProps = _assign({ selected: undefined, children: undefined }, props); | |
// Read state only from initial mount because <select> updates value | |
// manually; we need the initial state only for server rendering | |
if (inst._wrapperState.selected != null) { | |
hostProps.selected = inst._wrapperState.selected; | |
} | |
var content = flattenChildren(props.children); | |
if (content) { | |
hostProps.children = content; | |
} | |
return hostProps; | |
} | |
}; | |
module.exports = ReactDOMOption; | |
}); | |
var ReactDOMOption$1 = interopDefault(ReactDOMOption); | |
var require$$13$1 = Object.freeze({ | |
default: ReactDOMOption$1 | |
}); | |
var ReactDOMTextarea = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactDOMTextarea | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12), | |
_assign = interopDefault(require$$7); | |
var DisabledInputUtils = interopDefault(require$$5$7); | |
var LinkedValueUtils = interopDefault(require$$4$13); | |
var ReactDOMComponentTree = interopDefault(require$$4$9); | |
var ReactUpdates = interopDefault(require$$3$14); | |
var invariant = interopDefault(require$$0$33); | |
var warning = interopDefault(require$$0$34); | |
var didWarnValueLink = false; | |
var didWarnValDefaultVal = false; | |
function forceUpdateIfMounted() { | |
if (this._rootNodeID) { | |
// DOM component is still mounted; update | |
ReactDOMTextarea.updateWrapper(this); | |
} | |
} | |
/** | |
* Implements a <textarea> host component that allows setting `value`, and | |
* `defaultValue`. This differs from the traditional DOM API because value is | |
* usually set as PCDATA children. | |
* | |
* If `value` is not supplied (or null/undefined), user actions that affect the | |
* value will trigger updates to the element. | |
* | |
* If `value` is supplied (and not null/undefined), the rendered element will | |
* not trigger updates to the element. Instead, the `value` prop must change in | |
* order for the rendered element to be updated. | |
* | |
* The rendered element will be initialized with an empty value, the prop | |
* `defaultValue` if specified, or the children content (deprecated). | |
*/ | |
var ReactDOMTextarea = { | |
getHostProps: function (inst, props) { | |
!(props.dangerouslySetInnerHTML == null) ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : void 0; | |
// Always set children to the same thing. In IE9, the selection range will | |
// get reset if `textContent` is mutated. We could add a check in setTextContent | |
// to only set the value if/when the value differs from the node value (which would | |
// completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution. | |
// The value can be a boolean or object so that's why it's forced to be a string. | |
var hostProps = _assign({}, DisabledInputUtils.getHostProps(inst, props), { | |
value: undefined, | |
defaultValue: undefined, | |
children: '' + inst._wrapperState.initialValue, | |
onChange: inst._wrapperState.onChange | |
}); | |
return hostProps; | |
}, | |
mountWrapper: function (inst, props) { | |
if ("development" !== 'production') { | |
LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner); | |
if (props.valueLink !== undefined && !didWarnValueLink) { | |
warning(false, '`valueLink` prop on `textarea` is deprecated; set `value` and `onChange` instead.'); | |
didWarnValueLink = true; | |
} | |
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { | |
warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components'); | |
didWarnValDefaultVal = true; | |
} | |
} | |
var value = LinkedValueUtils.getValue(props); | |
var initialValue = value; | |
// Only bother fetching default value if we're going to use it | |
if (value == null) { | |
var defaultValue = props.defaultValue; | |
// TODO (yungsters): Remove support for children content in <textarea>. | |
var children = props.children; | |
if (children != null) { | |
if ("development" !== 'production') { | |
warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.'); | |
} | |
!(defaultValue == null) ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : void 0; | |
if (Array.isArray(children)) { | |
!(children.length <= 1) ? invariant(false, '<textarea> can only have at most one child.') : void 0; | |
children = children[0]; | |
} | |
defaultValue = '' + children; | |
} | |
if (defaultValue == null) { | |
defaultValue = ''; | |
} | |
initialValue = defaultValue; | |
} | |
inst._wrapperState = { | |
initialValue: '' + initialValue, | |
listeners: null, | |
onChange: _handleChange.bind(inst) | |
}; | |
}, | |
updateWrapper: function (inst) { | |
var props = inst._currentElement.props; | |
var node = ReactDOMComponentTree.getNodeFromInstance(inst); | |
var value = LinkedValueUtils.getValue(props); | |
if (value != null) { | |
// Cast `value` to a string to ensure the value is set correctly. While | |
// browsers typically do this as necessary, jsdom doesn't. | |
var newValue = '' + value; | |
// To avoid side effects (such as losing text selection), only set value if changed | |
if (newValue !== node.value) { | |
node.value = newValue; | |
} | |
if (props.defaultValue == null) { | |
node.defaultValue = newValue; | |
} | |
} | |
if (props.defaultValue != null) { | |
node.defaultValue = props.defaultValue; | |
} | |
}, | |
postMountWrapper: function (inst) { | |
// This is in postMount because we need access to the DOM node, which is not | |
// available until after the component has mounted. | |
var node = ReactDOMComponentTree.getNodeFromInstance(inst); | |
// Warning: node.value may be the empty string at this point (IE11) if placeholder is set. | |
node.value = node.textContent; // Detach value from defaultValue | |
} | |
}; | |
function _handleChange(event) { | |
var props = this._currentElement.props; | |
var returnValue = LinkedValueUtils.executeOnChange(props, event); | |
ReactUpdates.asap(forceUpdateIfMounted, this); | |
return returnValue; | |
} | |
module.exports = ReactDOMTextarea; | |
}); | |
var ReactDOMTextarea$1 = interopDefault(ReactDOMTextarea); | |
var require$$11$1 = Object.freeze({ | |
default: ReactDOMTextarea$1 | |
}); | |
var ReactComponentEnvironment = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2014-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactComponentEnvironment | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var invariant = interopDefault(require$$0$33); | |
var injected = false; | |
var ReactComponentEnvironment = { | |
/** | |
* Optionally injectable environment dependent cleanup hook. (server vs. | |
* browser etc). Example: A browser system caches DOM nodes based on component | |
* ID and must remove that cache entry when this instance is unmounted. | |
*/ | |
unmountIDFromEnvironment: null, | |
/** | |
* Optionally injectable hook for swapping out mount images in the middle of | |
* the tree. | |
*/ | |
replaceNodeWithMarkup: null, | |
/** | |
* Optionally injectable hook for processing a queue of child updates. Will | |
* later move into MultiChildComponents. | |
*/ | |
processChildrenUpdates: null, | |
injection: { | |
injectEnvironment: function (environment) { | |
!!injected ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : void 0; | |
ReactComponentEnvironment.unmountIDFromEnvironment = environment.unmountIDFromEnvironment; | |
ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup; | |
ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates; | |
injected = true; | |
} | |
} | |
}; | |
module.exports = ReactComponentEnvironment; | |
}); | |
var ReactComponentEnvironment$1 = interopDefault(ReactComponentEnvironment); | |
var require$$5$8 = Object.freeze({ | |
default: ReactComponentEnvironment$1 | |
}); | |
var ReactInstanceMap = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactInstanceMap | |
*/ | |
'use strict'; | |
/** | |
* `ReactInstanceMap` maintains a mapping from a public facing stateful | |
* instance (key) and the internal representation (value). This allows public | |
* methods to accept the user facing instance as an argument and map them back | |
* to internal methods. | |
*/ | |
// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); | |
var ReactInstanceMap = { | |
/** | |
* This API should be called `delete` but we'd have to make sure to always | |
* transform these to strings for IE support. When this transform is fully | |
* supported we can rename it. | |
*/ | |
remove: function (key) { | |
key._reactInternalInstance = undefined; | |
}, | |
get: function (key) { | |
return key._reactInternalInstance; | |
}, | |
has: function (key) { | |
return key._reactInternalInstance !== undefined; | |
}, | |
set: function (key, value) { | |
key._reactInternalInstance = value; | |
} | |
}; | |
module.exports = ReactInstanceMap; | |
}); | |
var ReactInstanceMap$1 = interopDefault(ReactInstanceMap); | |
var require$$3$19 = Object.freeze({ | |
default: ReactInstanceMap$1 | |
}); | |
var ReactNodeTypes = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule ReactNodeTypes | |
* | |
*/ | |
'use strict'; | |
var _prodInvariant = interopDefault(require$$12); | |
var ReactElement = interopDefault(require$$9); | |
var invariant = interopDefault(require$$0$33); | |
var ReactNodeTypes = { | |
HOST: 0, | |
COMPOSITE: 1, | |
EMPTY: 2, | |
getType: function (node) { | |
if (node === null || node === false) { | |
return ReactNodeTypes.EMPTY; | |
} else if (ReactElement.isValidElement(node)) { | |
if (typeof node.type === 'function') { | |
return ReactNodeTypes.COMPOSITE; | |
} else { | |
return ReactNodeTypes.HOST; | |
} | |
} | |
invariant(false, 'Unexpected node: %s', node); | |
} | |
}; | |
module.exports = ReactNodeTypes; | |
}); | |
var ReactNodeTypes$1 = interopDefault(ReactNodeTypes); | |
var require$$0$55 = Object.freeze({ | |
default: ReactNodeTypes$1 | |
}); | |
var shouldUpdateReactComponent = createCommonjsModule(function (module) { | |
/** | |
* Copyright 2013-present, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* @providesModule shouldUpdateReactComponent | |
*/ | |
'use strict'; | |
/** | |
* Given a `prevElement` and `nextElement`, determines if the existing | |
* instance should be updated as opposed to being destroyed or replaced by a new | |
* instance. Both arguments are elements. This ensures that this logic can | |
* operate on stateless trees without any backing instance. | |
* | |
* @param {?object} prevElement | |
* @param {?object} nextElement | |
* @return {boolean} True if the existing instance should be updated. | |
* @protected | |
*/ | |
function shouldUpdateReactComponent(prevElement, nextElement) { | |
var prevEmpty = prevElement === null || prevElement === false; | |
var nextEmpty = nextElement === null || nextElement === false; | |
if (prevEmpty || nextEmpty) { | |
return prevEmpty === nextEmpty; | |
} | |
var prevType = typeof prevElement; | |
var nextType = typeof nextElement; | |
if (prevType === 'string' || prevType === 'number') { | |
return nextType === 'string' || nextType === 'number |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment