forked from dojo/dojo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
text.js
218 lines (203 loc) · 8.65 KB
/
text.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
define(["./_base/kernel", "require", "./has", "./has!host-browser?./request"], function(dojo, require, has, request){
// module:
// dojo/text
var getText;
if(has("host-browser")){
getText= function(url, sync, load){
request(url, {sync:!!sync, headers: { 'X-Requested-With': null } }).then(load);
};
}else{
// Path for node.js and rhino, to load from local file system.
// TODO: use node.js native methods rather than depending on a require.getText() method to exist.
if(require.getText){
getText= require.getText;
}else{
console.error("dojo/text plugin failed to load because loader does not support getText");
}
}
var
theCache = {},
strip= function(text){
//Strips <?xml ...?> declarations so that external SVG and XML
//documents can be added to a document without worry. Also, if the string
//is an HTML document, only the part inside the body tag is returned.
if(text){
text= text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
var matches= text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
if(matches){
text= matches[1];
}
}else{
text = "";
}
return text;
},
notFound = {},
pending = {};
dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
// summary:
// A getter and setter for storing the string content associated with the
// module and url arguments.
// description:
// If module is a string that contains slashes, then it is interpretted as a fully
// resolved path (typically a result returned by require.toUrl), and url should not be
// provided. This is the preferred signature. If module is a string that does not
// contain slashes, then url must also be provided and module and url are used to
// call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated.
// If value is specified, the cache value for the moduleUrl will be set to
// that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
// in its internal cache and return that cached value for the URL. To clear
// a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
// the URL contents, only modules on the same domain of the page can use this capability.
// The build system can inline the cache values though, to allow for xdomain hosting.
// module: String||Object
// If a String with slashes, a fully resolved path; if a String without slashes, the
// module name to use for the base part of the URL, similar to module argument
// to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
// generates a valid path for the cache item. For example, a dojo._Url object.
// url: String
// The rest of the path to append to the path derived from the module argument. If
// module is an object, then this second argument should be the "value" argument instead.
// value: String||Object?
// If a String, the value to use in the cache for the module/url combination.
// If an Object, it can have two properties: value and sanitize. The value property
// should be the value to use in the cache, and sanitize can be set to true or false,
// to indicate if XML declarations should be removed from the value and if the HTML
// inside a body tag in the value should be extracted as the real value. The value argument
// or the value property on the value argument are usually only used by the build system
// as it inlines cache content.
// example:
// To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
// of call is used to avoid an issue with the build system erroneously trying to intern
// this example. To get the build system to intern your dojo.cache calls, use the
// "dojo.cache" style of call):
// | //If template.html contains "<h1>Hello</h1>" that will be
// | //the value for the text variable.
// | //Note: This is pre-AMD, deprecated syntax
// | var text = dojo["cache"]("my.module", "template.html");
// example:
// To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
// (the dojo["cache"] style of call is used to avoid an issue with the build system
// erroneously trying to intern this example. To get the build system to intern your
// dojo.cache calls, use the "dojo.cache" style of call):
// | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
// | //text variable will contain just "<h1>Hello</h1>".
// | //Note: This is pre-AMD, deprecated syntax
// | var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
// example:
// Same example as previous, but demonstrates how an object can be passed in as
// the first argument, then the value argument can then be the second argument.
// | //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
// | //text variable will contain just "<h1>Hello</h1>".
// | //Note: This is pre-AMD, deprecated syntax
// | var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
// * (string string [value]) => (module, url, value)
// * (object [value]) => (module, value), url defaults to ""
//
// * if module is an object, then it must be convertable to a string
// * (module, url) module + (url ? ("/" + url) : "") must be a legal argument to require.toUrl
// * value may be a string or an object; if an object then may have the properties "value" and/or "sanitize"
var key;
if(typeof module=="string"){
if(/\//.test(module)){
// module is a version 1.7+ resolved path
key = module;
value = url;
}else{
// module is a version 1.6- argument to dojo.moduleUrl
key = require.toUrl(module.replace(/\./g, "/") + (url ? ("/" + url) : ""));
}
}else{
key = module + "";
value = url;
}
var
val = (value != undefined && typeof value != "string") ? value.value : value,
sanitize = value && value.sanitize;
if(typeof val == "string"){
//We have a string, set cache value
theCache[key] = val;
return sanitize ? strip(val) : val;
}else if(val === null){
//Remove cached value
delete theCache[key];
return null;
}else{
//Allow cache values to be empty strings. If key property does
//not exist, fetch it.
if(!(key in theCache)){
getText(key, true, function(text){
theCache[key]= text;
});
}
return sanitize ? strip(theCache[key]) : theCache[key];
}
};
return {
// summary:
// This module implements the dojo/text! plugin and the dojo.cache API.
// description:
// We choose to include our own plugin to leverage functionality already contained in dojo
// and thereby reduce the size of the plugin compared to various foreign loader implementations.
// Also, this allows foreign AMD loaders to be used without their plugins.
//
// CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous
// loader. This feature is outside the scope of the CommonJS plugins specification.
// the dojo/text caches it's own resources because of dojo.cache
dynamic: true,
normalize: function(id, toAbsMid){
// id is something like (path may be relative):
//
// "path/to/text.html"
// "path/to/text.html!strip"
var parts= id.split("!"),
url= parts[0];
return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : "");
},
load: function(id, require, load){
// id: String
// Path to the resource.
// require: Function
// Object that include the function toUrl with given id returns a valid URL from which to load the text.
// load: Function
// Callback function which will be called, when the loading finished.
// id is something like (path is always absolute):
//
// "path/to/text.html"
// "path/to/text.html!strip"
var
parts= id.split("!"),
stripFlag= parts.length>1,
absMid= parts[0],
url = require.toUrl(parts[0]),
requireCacheUrl = "url:" + url,
text = notFound,
finish = function(text){
load(stripFlag ? strip(text) : text);
};
if(absMid in theCache){
text = theCache[absMid];
}else if(require.cache && requireCacheUrl in require.cache){
text = require.cache[requireCacheUrl];
}else if(url in theCache){
text = theCache[url];
}
if(text===notFound){
if(pending[url]){
pending[url].push(finish);
}else{
var pendingList = pending[url] = [finish];
getText(url, !require.async, function(text){
theCache[absMid]= theCache[url]= text;
for(var i = 0; i<pendingList.length;){
pendingList[i++](text);
}
delete pending[url];
});
}
}else{
finish(text);
}
}
};
});