require-text.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /**
  2. * @license text 2.0.16 Copyright jQuery Foundation and other contributors.
  3. * Released under MIT license, http://github.com/requirejs/text/LICENSE
  4. */
  5. /*jslint regexp: true */
  6. /*global require, XMLHttpRequest, ActiveXObject,
  7. define, window, process, Packages,
  8. java, location, Components, FileUtils */
  9. define(['module'], function (module) {
  10. 'use strict';
  11. var text, fs, Cc, Ci, xpcIsWindows,
  12. progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
  13. xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
  14. bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
  15. hasLocation = typeof location !== 'undefined' && location.href,
  16. defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
  17. defaultHostName = hasLocation && location.hostname,
  18. defaultPort = hasLocation && (location.port || undefined),
  19. buildMap = {},
  20. masterConfig = (module.config && module.config()) || {};
  21. function useDefault(value, defaultValue) {
  22. return value === undefined || value === '' ? defaultValue : value;
  23. }
  24. //Allow for default ports for http and https.
  25. function isSamePort(protocol1, port1, protocol2, port2) {
  26. if (port1 === port2) {
  27. return true;
  28. } else if (protocol1 === protocol2) {
  29. if (protocol1 === 'http') {
  30. return useDefault(port1, '80') === useDefault(port2, '80');
  31. } else if (protocol1 === 'https') {
  32. return useDefault(port1, '443') === useDefault(port2, '443');
  33. }
  34. }
  35. return false;
  36. }
  37. text = {
  38. version: '2.0.16',
  39. strip: function (content) {
  40. //Strips <?xml ...?> declarations so that external SVG and XML
  41. //documents can be added to a document without worry. Also, if the string
  42. //is an HTML document, only the part inside the body tag is returned.
  43. if (content) {
  44. content = content.replace(xmlRegExp, "");
  45. var matches = content.match(bodyRegExp);
  46. if (matches) {
  47. content = matches[1];
  48. }
  49. } else {
  50. content = "";
  51. }
  52. return content;
  53. },
  54. jsEscape: function (content) {
  55. return content.replace(/(['\\])/g, '\\$1')
  56. .replace(/[\f]/g, "\\f")
  57. .replace(/[\b]/g, "\\b")
  58. .replace(/[\n]/g, "\\n")
  59. .replace(/[\t]/g, "\\t")
  60. .replace(/[\r]/g, "\\r")
  61. .replace(/[\u2028]/g, "\\u2028")
  62. .replace(/[\u2029]/g, "\\u2029");
  63. },
  64. createXhr: masterConfig.createXhr || function () {
  65. //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
  66. var xhr, i, progId;
  67. if (typeof XMLHttpRequest !== "undefined") {
  68. return new XMLHttpRequest();
  69. } else if (typeof ActiveXObject !== "undefined") {
  70. for (i = 0; i < 3; i += 1) {
  71. progId = progIds[i];
  72. try {
  73. xhr = new ActiveXObject(progId);
  74. } catch (e) {}
  75. if (xhr) {
  76. progIds = [progId]; // so faster next time
  77. break;
  78. }
  79. }
  80. }
  81. return xhr;
  82. },
  83. /**
  84. * Parses a resource name into its component parts. Resource names
  85. * look like: module/name.ext!strip, where the !strip part is
  86. * optional.
  87. * @param {String} name the resource name
  88. * @returns {Object} with properties "moduleName", "ext" and "strip"
  89. * where strip is a boolean.
  90. */
  91. parseName: function (name) {
  92. var modName, ext, temp,
  93. strip = false,
  94. index = name.lastIndexOf("."),
  95. isRelative = name.indexOf('./') === 0 ||
  96. name.indexOf('../') === 0;
  97. if (index !== -1 && (!isRelative || index > 1)) {
  98. modName = name.substring(0, index);
  99. ext = name.substring(index + 1);
  100. } else {
  101. modName = name;
  102. }
  103. temp = ext || modName;
  104. index = temp.indexOf("!");
  105. if (index !== -1) {
  106. //Pull off the strip arg.
  107. strip = temp.substring(index + 1) === "strip";
  108. temp = temp.substring(0, index);
  109. if (ext) {
  110. ext = temp;
  111. } else {
  112. modName = temp;
  113. }
  114. }
  115. return {
  116. moduleName: modName,
  117. ext: ext,
  118. strip: strip
  119. };
  120. },
  121. xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
  122. /**
  123. * Is an URL on another domain. Only works for browser use, returns
  124. * false in non-browser environments. Only used to know if an
  125. * optimized .js version of a text resource should be loaded
  126. * instead.
  127. * @param {String} url
  128. * @returns Boolean
  129. */
  130. useXhr: function (url, protocol, hostname, port) {
  131. var uProtocol, uHostName, uPort,
  132. match = text.xdRegExp.exec(url);
  133. if (!match) {
  134. return true;
  135. }
  136. uProtocol = match[2];
  137. uHostName = match[3];
  138. uHostName = uHostName.split(':');
  139. uPort = uHostName[1];
  140. uHostName = uHostName[0];
  141. return (!uProtocol || uProtocol === protocol) &&
  142. (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
  143. ((!uPort && !uHostName) || isSamePort(uProtocol, uPort, protocol, port));
  144. },
  145. finishLoad: function (name, strip, content, onLoad) {
  146. content = strip ? text.strip(content) : content;
  147. if (masterConfig.isBuild) {
  148. buildMap[name] = content;
  149. }
  150. onLoad(content);
  151. },
  152. load: function (name, req, onLoad, config) {
  153. //Name has format: some.module.filext!strip
  154. //The strip part is optional.
  155. //if strip is present, then that means only get the string contents
  156. //inside a body tag in an HTML string. For XML/SVG content it means
  157. //removing the <?xml ...?> declarations so the content can be inserted
  158. //into the current doc without problems.
  159. // Do not bother with the work if a build and text will
  160. // not be inlined.
  161. if (config && config.isBuild && !config.inlineText) {
  162. onLoad();
  163. return;
  164. }
  165. masterConfig.isBuild = config && config.isBuild;
  166. var parsed = text.parseName(name),
  167. nonStripName = parsed.moduleName +
  168. (parsed.ext ? '.' + parsed.ext : ''),
  169. url = req.toUrl(nonStripName),
  170. useXhr = (masterConfig.useXhr) ||
  171. text.useXhr;
  172. // Do not load if it is an empty: url
  173. if (url.indexOf('empty:') === 0) {
  174. onLoad();
  175. return;
  176. }
  177. //Load the text. Use XHR if possible and in a browser.
  178. if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
  179. text.get(url, function (content) {
  180. text.finishLoad(name, parsed.strip, content, onLoad);
  181. }, function (err) {
  182. if (onLoad.error) {
  183. onLoad.error(err);
  184. }
  185. });
  186. } else {
  187. //Need to fetch the resource across domains. Assume
  188. //the resource has been optimized into a JS module. Fetch
  189. //by the module name + extension, but do not include the
  190. //!strip part to avoid file system issues.
  191. req([nonStripName], function (content) {
  192. text.finishLoad(parsed.moduleName + '.' + parsed.ext,
  193. parsed.strip, content, onLoad);
  194. }, function (err) {
  195. if (onLoad.error) {
  196. onLoad.error(err);
  197. }
  198. });
  199. }
  200. },
  201. write: function (pluginName, moduleName, write, config) {
  202. if (buildMap.hasOwnProperty(moduleName)) {
  203. var content = text.jsEscape(buildMap[moduleName]);
  204. write.asModule(pluginName + "!" + moduleName,
  205. "define(function () { return '" +
  206. content +
  207. "';});\n");
  208. }
  209. },
  210. writeFile: function (pluginName, moduleName, req, write, config) {
  211. var parsed = text.parseName(moduleName),
  212. extPart = parsed.ext ? '.' + parsed.ext : '',
  213. nonStripName = parsed.moduleName + extPart,
  214. //Use a '.js' file name so that it indicates it is a
  215. //script that can be loaded across domains.
  216. fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
  217. //Leverage own load() method to load plugin value, but only
  218. //write out values that do not have the strip argument,
  219. //to avoid any potential issues with ! in file names.
  220. text.load(nonStripName, req, function (value) {
  221. //Use own write() method to construct full module value.
  222. //But need to create shell that translates writeFile's
  223. //write() to the right interface.
  224. var textWrite = function (contents) {
  225. return write(fileName, contents);
  226. };
  227. textWrite.asModule = function (moduleName, contents) {
  228. return write.asModule(moduleName, fileName, contents);
  229. };
  230. text.write(pluginName, nonStripName, textWrite, config);
  231. }, config);
  232. }
  233. };
  234. if (masterConfig.env === 'node' || (!masterConfig.env &&
  235. typeof process !== "undefined" &&
  236. process.versions &&
  237. !!process.versions.node &&
  238. !process.versions['node-webkit'] &&
  239. !process.versions['atom-shell'])) {
  240. //Using special require.nodeRequire, something added by r.js.
  241. fs = require.nodeRequire('fs');
  242. text.get = function (url, callback, errback) {
  243. try {
  244. var file = fs.readFileSync(url, 'utf8');
  245. //Remove BOM (Byte Mark Order) from utf8 files if it is there.
  246. if (file[0] === '\uFEFF') {
  247. file = file.substring(1);
  248. }
  249. callback(file);
  250. } catch (e) {
  251. if (errback) {
  252. errback(e);
  253. }
  254. }
  255. };
  256. } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
  257. text.createXhr())) {
  258. text.get = function (url, callback, errback, headers) {
  259. var xhr = text.createXhr(), header;
  260. xhr.open('GET', url, true);
  261. //Allow plugins direct access to xhr headers
  262. if (headers) {
  263. for (header in headers) {
  264. if (headers.hasOwnProperty(header)) {
  265. xhr.setRequestHeader(header.toLowerCase(), headers[header]);
  266. }
  267. }
  268. }
  269. //Allow overrides specified in config
  270. if (masterConfig.onXhr) {
  271. masterConfig.onXhr(xhr, url);
  272. }
  273. xhr.onreadystatechange = function (evt) {
  274. var status, err;
  275. //Do not explicitly handle errors, those should be
  276. //visible via console output in the browser.
  277. if (xhr.readyState === 4) {
  278. status = xhr.status || 0;
  279. if (status > 399 && status < 600) {
  280. //An http 4xx or 5xx error. Signal an error.
  281. err = new Error(url + ' HTTP status: ' + status);
  282. err.xhr = xhr;
  283. if (errback) {
  284. errback(err);
  285. }
  286. } else {
  287. callback(xhr.responseText);
  288. }
  289. if (masterConfig.onXhrComplete) {
  290. masterConfig.onXhrComplete(xhr, url);
  291. }
  292. }
  293. };
  294. xhr.send(null);
  295. };
  296. } else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
  297. typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
  298. //Why Java, why is this so awkward?
  299. text.get = function (url, callback) {
  300. var stringBuffer, line,
  301. encoding = "utf-8",
  302. file = new java.io.File(url),
  303. lineSeparator = java.lang.System.getProperty("line.separator"),
  304. input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
  305. content = '';
  306. try {
  307. stringBuffer = new java.lang.StringBuffer();
  308. line = input.readLine();
  309. // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
  310. // http://www.unicode.org/faq/utf_bom.html
  311. // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
  312. // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
  313. if (line && line.length() && line.charAt(0) === 0xfeff) {
  314. // Eat the BOM, since we've already found the encoding on this file,
  315. // and we plan to concatenating this buffer with others; the BOM should
  316. // only appear at the top of a file.
  317. line = line.substring(1);
  318. }
  319. if (line !== null) {
  320. stringBuffer.append(line);
  321. }
  322. while ((line = input.readLine()) !== null) {
  323. stringBuffer.append(lineSeparator);
  324. stringBuffer.append(line);
  325. }
  326. //Make sure we return a JavaScript string and not a Java string.
  327. content = String(stringBuffer.toString()); //String
  328. } finally {
  329. input.close();
  330. }
  331. callback(content);
  332. };
  333. } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
  334. typeof Components !== 'undefined' && Components.classes &&
  335. Components.interfaces)) {
  336. //Avert your gaze!
  337. Cc = Components.classes;
  338. Ci = Components.interfaces;
  339. Components.utils['import']('resource://gre/modules/FileUtils.jsm');
  340. xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
  341. text.get = function (url, callback) {
  342. var inStream, convertStream, fileObj,
  343. readData = {};
  344. if (xpcIsWindows) {
  345. url = url.replace(/\//g, '\\');
  346. }
  347. fileObj = new FileUtils.File(url);
  348. //XPCOM, you so crazy
  349. try {
  350. inStream = Cc['@mozilla.org/network/file-input-stream;1']
  351. .createInstance(Ci.nsIFileInputStream);
  352. inStream.init(fileObj, 1, 0, false);
  353. convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
  354. .createInstance(Ci.nsIConverterInputStream);
  355. convertStream.init(inStream, "utf-8", inStream.available(),
  356. Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  357. convertStream.readString(inStream.available(), readData);
  358. convertStream.close();
  359. inStream.close();
  360. callback(readData.value);
  361. } catch (e) {
  362. throw new Error((fileObj && fileObj.path || '') + ': ' + e);
  363. }
  364. };
  365. }
  366. return text;
  367. });