text.js 15 KB

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