not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
15 KiB

  1. /**
  2. * @license RequireJS text 2.0.10 Copyright (c) 2010-2012, 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.10',
  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.isBuild && !config.inlineText) {
  147. onLoad();
  148. return;
  149. }
  150. masterConfig.isBuild = 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 (false) {
  216. //Using special require.nodeRequire, something added by r.js.
  217. fs = require.nodeRequire('fs');
  218. text.get = function (url, callback, errback) {
  219. try {
  220. var file = fs.readFileSync(url, 'utf8');
  221. //Remove BOM (Byte Mark Order) from utf8 files if it is there.
  222. if (file.indexOf('\uFEFF') === 0) {
  223. file = file.substring(1);
  224. }
  225. callback(file);
  226. } catch (e) {
  227. errback(e);
  228. }
  229. };
  230. } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
  231. text.createXhr())) {
  232. text.get = function (url, callback, errback, headers) {
  233. var xhr = text.createXhr(), header;
  234. xhr.open('GET', url, true);
  235. //Allow plugins direct access to xhr headers
  236. if (headers) {
  237. for (header in headers) {
  238. if (headers.hasOwnProperty(header)) {
  239. xhr.setRequestHeader(header.toLowerCase(), headers[header]);
  240. }
  241. }
  242. }
  243. //Allow overrides specified in config
  244. if (masterConfig.onXhr) {
  245. masterConfig.onXhr(xhr, url);
  246. }
  247. xhr.onreadystatechange = function (evt) {
  248. var status, err;
  249. //Do not explicitly handle errors, those should be
  250. //visible via console output in the browser.
  251. if (xhr.readyState === 4) {
  252. status = xhr.status;
  253. if (status > 399 && status < 600) {
  254. //An http 4xx or 5xx error. Signal an error.
  255. err = new Error(url + ' HTTP status: ' + status);
  256. err.xhr = xhr;
  257. errback(err);
  258. } else {
  259. callback(xhr.responseText);
  260. }
  261. if (masterConfig.onXhrComplete) {
  262. masterConfig.onXhrComplete(xhr, url);
  263. }
  264. }
  265. };
  266. xhr.send(null);
  267. };
  268. } else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
  269. typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
  270. //Why Java, why is this so awkward?
  271. text.get = function (url, callback) {
  272. var stringBuffer, line,
  273. encoding = "utf-8",
  274. file = new java.io.File(url),
  275. lineSeparator = java.lang.System.getProperty("line.separator"),
  276. input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
  277. content = '';
  278. try {
  279. stringBuffer = new java.lang.StringBuffer();
  280. line = input.readLine();
  281. // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
  282. // http://www.unicode.org/faq/utf_bom.html
  283. // 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:
  284. // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
  285. if (line && line.length() && line.charAt(0) === 0xfeff) {
  286. // Eat the BOM, since we've already found the encoding on this file,
  287. // and we plan to concatenating this buffer with others; the BOM should
  288. // only appear at the top of a file.
  289. line = line.substring(1);
  290. }
  291. if (line !== null) {
  292. stringBuffer.append(line);
  293. }
  294. while ((line = input.readLine()) !== null) {
  295. stringBuffer.append(lineSeparator);
  296. stringBuffer.append(line);
  297. }
  298. //Make sure we return a JavaScript string and not a Java string.
  299. content = String(stringBuffer.toString()); //String
  300. } finally {
  301. input.close();
  302. }
  303. callback(content);
  304. };
  305. } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
  306. typeof Components !== 'undefined' && Components.classes &&
  307. Components.interfaces)) {
  308. //Avert your gaze!
  309. Cc = Components.classes,
  310. Ci = Components.interfaces;
  311. Components.utils['import']('resource://gre/modules/FileUtils.jsm');
  312. xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
  313. text.get = function (url, callback) {
  314. var inStream, convertStream, fileObj,
  315. readData = {};
  316. if (xpcIsWindows) {
  317. url = url.replace(/\//g, '\\');
  318. }
  319. fileObj = new FileUtils.File(url);
  320. //XPCOM, you so crazy
  321. try {
  322. inStream = Cc['@mozilla.org/network/file-input-stream;1']
  323. .createInstance(Ci.nsIFileInputStream);
  324. inStream.init(fileObj, 1, 0, false);
  325. convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
  326. .createInstance(Ci.nsIConverterInputStream);
  327. convertStream.init(inStream, "utf-8", inStream.available(),
  328. Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
  329. convertStream.readString(inStream.available(), readData);
  330. convertStream.close();
  331. inStream.close();
  332. callback(readData.value);
  333. } catch (e) {
  334. throw new Error((fileObj && fileObj.path || '') + ': ' + e);
  335. }
  336. };
  337. }
  338. return text;
  339. });