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
6 /*jslint regexp: true */
7 /*global require, XMLHttpRequest, ActiveXObject,
8 define, window, process, Packages,
9 java, location, Components, FileUtils */
11 define(['module'], function (module
) {
14 var text
, fs
, Cc
, Ci
, xpcIsWindows
,
15 progIds
= ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
16 xmlRegExp
= /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
17 bodyRegExp
= /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
18 hasLocation
= typeof location
!== 'undefined' && location
.href
,
19 defaultProtocol
= hasLocation
&& location
.protocol
&& location
.protocol
.replace(/\:/, ''),
20 defaultHostName
= hasLocation
&& location
.hostname
,
21 defaultPort
= hasLocation
&& (location
.port
|| undefined),
23 masterConfig
= (module
.config
&& module
.config()) || {};
28 strip: function (content
) {
29 //Strips <?xml ...?> declarations so that external SVG and XML
30 //documents can be added to a document without worry. Also, if the string
31 //is an HTML document, only the part inside the body tag is returned.
33 content
= content
.replace(xmlRegExp
, "");
34 var matches
= content
.match(bodyRegExp
);
44 jsEscape: function (content
) {
45 return content
.replace(/(['\\])/g, '\\$1')
46 .replace(/[\f]/g, "\\f")
47 .replace(/[\b]/g, "\\b")
48 .replace(/[\n]/g, "\\n")
49 .replace(/[\t]/g, "\\t")
50 .replace(/[\r]/g, "\\r")
51 .replace(/[\u2028]/g, "\\u2028")
52 .replace(/[\u2029]/g, "\\u2029");
55 createXhr: masterConfig
.createXhr
|| function () {
56 //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
58 if (typeof XMLHttpRequest
!== "undefined") {
59 return new XMLHttpRequest();
60 } else if (typeof ActiveXObject
!== "undefined") {
61 for (i
= 0; i
< 3; i
+= 1) {
64 xhr
= new ActiveXObject(progId
);
68 progIds
= [progId
]; // so faster next time
78 * Parses a resource name into its component parts. Resource names
79 * look like: module/name.ext!strip, where the !strip part is
81 * @param {String} name the resource name
82 * @returns {Object} with properties "moduleName", "ext" and "strip"
83 * where strip is a boolean.
85 parseName: function (name
) {
86 var modName
, ext
, temp
,
88 index
= name
.indexOf("."),
89 isRelative
= name
.indexOf('./') === 0 ||
90 name
.indexOf('../') === 0;
92 if (index
!== -1 && (!isRelative
|| index
> 1)) {
93 modName
= name
.substring(0, index
);
94 ext
= name
.substring(index
+ 1, name
.length
);
99 temp
= ext
|| modName
;
100 index
= temp
.indexOf("!");
102 //Pull off the strip arg.
103 strip
= temp
.substring(index
+ 1) === "strip";
104 temp
= temp
.substring(0, index
);
119 xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
122 * Is an URL on another domain. Only works for browser use, returns
123 * false in non-browser environments. Only used to know if an
124 * optimized .js version of a text resource should be loaded
126 * @param {String} url
129 useXhr: function (url
, protocol
, hostname
, port
) {
130 var uProtocol
, uHostName
, uPort
,
131 match
= text
.xdRegExp
.exec(url
);
135 uProtocol
= match
[2];
136 uHostName
= match
[3];
138 uHostName
= uHostName
.split(':');
139 uPort
= uHostName
[1];
140 uHostName
= uHostName
[0];
142 return (!uProtocol
|| uProtocol
=== protocol
) &&
143 (!uHostName
|| uHostName
.toLowerCase() === hostname
.toLowerCase()) &&
144 ((!uPort
&& !uHostName
) || uPort
=== port
);
147 finishLoad: function (name
, strip
, content
, onLoad
) {
148 content
= strip
? text
.strip(content
) : content
;
149 if (masterConfig
.isBuild
) {
150 buildMap
[name
] = content
;
155 load: function (name
, req
, onLoad
, config
) {
156 //Name has format: some.module.filext!strip
157 //The strip part is optional.
158 //if strip is present, then that means only get the string contents
159 //inside a body tag in an HTML string. For XML/SVG content it means
160 //removing the <?xml ...?> declarations so the content can be inserted
161 //into the current doc without problems.
163 // Do not bother with the work if a build and text will
165 if (config
&& config
.isBuild
&& !config
.inlineText
) {
170 masterConfig
.isBuild
= config
&& config
.isBuild
;
172 var parsed
= text
.parseName(name
),
173 nonStripName
= parsed
.moduleName
+
174 (parsed
.ext
? '.' + parsed
.ext : ''),
175 url
= req
.toUrl(nonStripName
),
176 useXhr
= (masterConfig
.useXhr
) ||
179 // Do not load if it is an empty: url
180 if (url
.indexOf('empty:') === 0) {
185 //Load the text. Use XHR if possible and in a browser.
186 if (!hasLocation
|| useXhr(url
, defaultProtocol
, defaultHostName
, defaultPort
)) {
187 text
.get(url
, function (content
) {
188 text
.finishLoad(name
, parsed
.strip
, content
, onLoad
);
195 //Need to fetch the resource across domains. Assume
196 //the resource has been optimized into a JS module. Fetch
197 //by the module name + extension, but do not include the
198 //!strip part to avoid file system issues.
199 req([nonStripName
], function (content
) {
200 text
.finishLoad(parsed
.moduleName
+ '.' + parsed
.ext
,
201 parsed
.strip
, content
, onLoad
);
206 write: function (pluginName
, moduleName
, write
, config
) {
207 if (buildMap
.hasOwnProperty(moduleName
)) {
208 var content
= text
.jsEscape(buildMap
[moduleName
]);
209 write
.asModule(pluginName
+ "!" + moduleName
,
210 "define(function () { return '" +
216 writeFile: function (pluginName
, moduleName
, req
, write
, config
) {
217 var parsed
= text
.parseName(moduleName
),
218 extPart
= parsed
.ext
? '.' + parsed
.ext : '',
219 nonStripName
= parsed
.moduleName
+ extPart
,
220 //Use a '.js' file name so that it indicates it is a
221 //script that can be loaded across domains.
222 fileName
= req
.toUrl(parsed
.moduleName
+ extPart
) + '.js';
224 //Leverage own load() method to load plugin value, but only
225 //write out values that do not have the strip argument,
226 //to avoid any potential issues with ! in file names.
227 text
.load(nonStripName
, req
, function (value
) {
228 //Use own write() method to construct full module value.
229 //But need to create shell that translates writeFile's
230 //write() to the right interface.
231 var textWrite = function (contents
) {
232 return write(fileName
, contents
);
234 textWrite
.asModule = function (moduleName
, contents
) {
235 return write
.asModule(moduleName
, fileName
, contents
);
238 text
.write(pluginName
, nonStripName
, textWrite
, config
);
243 if (masterConfig
.env
=== 'node' || (!masterConfig
.env
&&
244 typeof process
!== "undefined" &&
246 !!process
.versions
.node
&&
247 !process
.versions
['node-webkit'])) {
248 //Using special require.nodeRequire, something added by r.js.
249 fs
= require
.nodeRequire('fs');
251 text
.get = function (url
, callback
, errback
) {
253 var file
= fs
.readFileSync(url
, 'utf8');
254 //Remove BOM (Byte Mark Order) from utf8 files if it is there.
255 if (file
.indexOf('\uFEFF') === 0) {
256 file
= file
.substring(1);
265 } else if (masterConfig
.env
=== 'xhr' || (!masterConfig
.env
&&
267 text
.get = function (url
, callback
, errback
, headers
) {
268 var xhr
= text
.createXhr(), header
;
269 xhr
.open('GET', url
, true);
271 //Allow plugins direct access to xhr headers
273 for (header
in headers
) {
274 if (headers
.hasOwnProperty(header
)) {
275 xhr
.setRequestHeader(header
.toLowerCase(), headers
[header
]);
280 //Allow overrides specified in config
281 if (masterConfig
.onXhr
) {
282 masterConfig
.onXhr(xhr
, url
);
285 xhr
.onreadystatechange = function (evt
) {
287 //Do not explicitly handle errors, those should be
288 //visible via console output in the browser.
289 if (xhr
.readyState
=== 4) {
290 status
= xhr
.status
|| 0;
291 if (status
> 399 && status
< 600) {
292 //An http 4xx or 5xx error. Signal an error.
293 err
= new Error(url
+ ' HTTP status: ' + status
);
299 callback(xhr
.responseText
);
302 if (masterConfig
.onXhrComplete
) {
303 masterConfig
.onXhrComplete(xhr
, url
);
309 } else if (masterConfig
.env
=== 'rhino' || (!masterConfig
.env
&&
310 typeof Packages
!== 'undefined' && typeof java
!== 'undefined')) {
311 //Why Java, why is this so awkward?
312 text
.get = function (url
, callback
) {
313 var stringBuffer
, line
,
315 file
= new java
.io
.File(url
),
316 lineSeparator
= java
.lang
.System
.getProperty("line.separator"),
317 input
= new java
.io
.BufferedReader(new java
.io
.InputStreamReader(new java
.io
.FileInputStream(file
), encoding
)),
320 stringBuffer
= new java
.lang
.StringBuffer();
321 line
= input
.readLine();
323 // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
324 // http://www.unicode.org/faq/utf_bom.html
326 // 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:
327 // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
328 if (line
&& line
.length() && line
.charAt(0) === 0xfeff) {
329 // Eat the BOM, since we've already found the encoding on this file,
330 // and we plan to concatenating this buffer with others; the BOM should
331 // only appear at the top of a file.
332 line
= line
.substring(1);
336 stringBuffer
.append(line
);
339 while ((line
= input
.readLine()) !== null) {
340 stringBuffer
.append(lineSeparator
);
341 stringBuffer
.append(line
);
343 //Make sure we return a JavaScript string and not a Java string.
344 content
= String(stringBuffer
.toString()); //String
350 } else if (masterConfig
.env
=== 'xpconnect' || (!masterConfig
.env
&&
351 typeof Components
!== 'undefined' && Components
.classes
&&
352 Components
.interfaces
)) {
354 Cc
= Components
.classes
;
355 Ci
= Components
.interfaces
;
356 Components
.utils
['import']('resource://gre/modules/FileUtils.jsm');
357 xpcIsWindows
= ('@mozilla.org/windows-registry-key;1' in Cc
);
359 text
.get = function (url
, callback
) {
360 var inStream
, convertStream
, fileObj
,
364 url
= url
.replace(/\//g, '\\');
367 fileObj
= new FileUtils
.File(url
);
369 //XPCOM, you so crazy
371 inStream
= Cc
['@mozilla.org/network/file-input-stream;1']
372 .createInstance(Ci
.nsIFileInputStream
);
373 inStream
.init(fileObj
, 1, 0, false);
375 convertStream
= Cc
['@mozilla.org/intl/converter-input-stream;1']
376 .createInstance(Ci
.nsIConverterInputStream
);
377 convertStream
.init(inStream
, "utf-8", inStream
.available(),
378 Ci
.nsIConverterInputStream
.DEFAULT_REPLACEMENT_CHARACTER
);
380 convertStream
.readString(inStream
.available(), readData
);
381 convertStream
.close();
383 callback(readData
.value
);
385 throw new Error((fileObj
&& fileObj
.path
|| '') + ': ' + e
);