" as JSCompiler
64 | * option.
65 | *
66 | * Take into account that the locale code format is important. You should use
67 | * the canonical Unicode format with hyphen as a delimiter. Language must be
68 | * lowercase, Language Script - Capitalized, Region - UPPERCASE.
69 | * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.
70 | *
71 | * See more info about locale codes here:
72 | * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers
73 | *
74 | * For language codes you should use values defined by ISO 693-1. See it here
75 | * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from
76 | * this rule: the Hebrew language. For legacy reasons the old code (iw) should
77 | * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.
78 | */
79 | goog.LOCALE = 'en'; // default to en
80 |
81 |
82 | /**
83 | * Indicates whether or not we can call 'eval' directly to eval code in the
84 | * global scope. Set to a Boolean by the first call to goog.globalEval (which
85 | * empirically tests whether eval works for globals). @see goog.globalEval
86 | * @type {?boolean}
87 | * @private
88 | */
89 | goog.evalWorksForGlobals_ = null;
90 |
91 |
92 | /**
93 | * Creates object stubs for a namespace. When present in a file, goog.provide
94 | * also indicates that the file defines the indicated object. Calls to
95 | * goog.provide are resolved by the compiler if --closure_pass is set.
96 | * @param {string} name name of the object that this file defines.
97 | */
98 | goog.provide = function(name) {
99 | if (!COMPILED) {
100 | // Ensure that the same namespace isn't provided twice. This is intended
101 | // to teach new developers that 'goog.provide' is effectively a variable
102 | // declaration. And when JSCompiler transforms goog.provide into a real
103 | // variable declaration, the compiled JS should work the same as the raw
104 | // JS--even when the raw JS uses goog.provide incorrectly.
105 | if (goog.getObjectByName(name) && !goog.implicitNamespaces_[name]) {
106 | throw Error('Namespace "' + name + '" already declared.');
107 | }
108 |
109 | var namespace = name;
110 | while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {
111 | goog.implicitNamespaces_[namespace] = true;
112 | }
113 | }
114 |
115 | goog.exportPath_(name);
116 | };
117 |
118 |
119 | if (!COMPILED) {
120 | /**
121 | * Namespaces implicitly defined by goog.provide. For example,
122 | * goog.provide('goog.events.Event') implicitly declares
123 | * that 'goog' and 'goog.events' must be namespaces.
124 | *
125 | * @type {Object}
126 | * @private
127 | */
128 | goog.implicitNamespaces_ = {};
129 | }
130 |
131 |
132 | /**
133 | * Builds an object structure for the provided namespace path,
134 | * ensuring that names that already exist are not overwritten. For
135 | * example:
136 | * "a.b.c" -> a = {};a.b={};a.b.c={};
137 | * Used by goog.provide and goog.exportSymbol.
138 | * @param {string} name name of the object that this file defines.
139 | * @param {*=} opt_object the object to expose at the end of the path.
140 | * @param {Object=} opt_objectToExportTo The object to add the path to; default
141 | * is |goog.global|.
142 | * @private
143 | */
144 | goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
145 | var parts = name.split('.');
146 | var cur = opt_objectToExportTo || goog.global;
147 |
148 | // Internet Explorer exhibits strange behavior when throwing errors from
149 | // methods externed in this manner. See the testExportSymbolExceptions in
150 | // base_test.html for an example.
151 | if (!(parts[0] in cur) && cur.execScript) {
152 | cur.execScript('var ' + parts[0]);
153 | }
154 |
155 | // Certain browsers cannot parse code in the form for((a in b); c;);
156 | // This pattern is produced by the JSCompiler when it collapses the
157 | // statement above into the conditional loop below. To prevent this from
158 | // happening, use a for-loop and reserve the init logic as below.
159 |
160 | // Parentheses added to eliminate strict JS warning in Firefox.
161 | for (var part; parts.length && (part = parts.shift());) {
162 | if (!parts.length && goog.isDef(opt_object)) {
163 | // last part and we have an object; use it
164 | cur[part] = opt_object;
165 | } else if (cur[part]) {
166 | cur = cur[part];
167 | } else {
168 | cur = cur[part] = {};
169 | }
170 | }
171 | };
172 |
173 |
174 | /**
175 | * Returns an object based on its fully qualified external name. If you are
176 | * using a compilation pass that renames property names beware that using this
177 | * function will not find renamed properties.
178 | *
179 | * @param {string} name The fully qualified name.
180 | * @param {Object=} opt_obj The object within which to look; default is
181 | * |goog.global|.
182 | * @return {Object} The object or, if not found, null.
183 | */
184 | goog.getObjectByName = function(name, opt_obj) {
185 | var parts = name.split('.');
186 | var cur = opt_obj || goog.global;
187 | for (var part; part = parts.shift(); ) {
188 | if (cur[part]) {
189 | cur = cur[part];
190 | } else {
191 | return null;
192 | }
193 | }
194 | return cur;
195 | };
196 |
197 |
198 | /**
199 | * Globalizes a whole namespace, such as goog or goog.lang.
200 | *
201 | * @param {Object} obj The namespace to globalize.
202 | * @param {Object=} opt_global The object to add the properties to.
203 | * @deprecated Properties may be explicitly exported to the global scope, but
204 | * this should no longer be done in bulk.
205 | */
206 | goog.globalize = function(obj, opt_global) {
207 | var global = opt_global || goog.global;
208 | for (var x in obj) {
209 | global[x] = obj[x];
210 | }
211 | };
212 |
213 |
214 | /**
215 | * Adds a dependency from a file to the files it requires.
216 | * @param {string} relPath The path to the js file.
217 | * @param {Array} provides An array of strings with the names of the objects
218 | * this file provides.
219 | * @param {Array} requires An array of strings with the names of the objects
220 | * this file requires.
221 | */
222 | goog.addDependency = function(relPath, provides, requires) {
223 | if (!COMPILED) {
224 | var provide, require;
225 | var path = relPath.replace(/\\/g, '/');
226 | var deps = goog.dependencies_;
227 | for (var i = 0; provide = provides[i]; i++) {
228 | deps.nameToPath[provide] = path;
229 | if (!(path in deps.pathToNames)) {
230 | deps.pathToNames[path] = {};
231 | }
232 | deps.pathToNames[path][provide] = true;
233 | }
234 | for (var j = 0; require = requires[j]; j++) {
235 | if (!(path in deps.requires)) {
236 | deps.requires[path] = {};
237 | }
238 | deps.requires[path][require] = true;
239 | }
240 | }
241 | };
242 |
243 |
244 |
245 | /**
246 | * Implements a system for the dynamic resolution of dependencies
247 | * that works in parallel with the BUILD system. Note that all calls
248 | * to goog.require will be stripped by the JSCompiler when the
249 | * --closure_pass option is used.
250 | * @param {string} rule Rule to include, in the form goog.package.part.
251 | */
252 | goog.require = function(rule) {
253 |
254 | // if the object already exists we do not need do do anything
255 | // TODO(user): If we start to support require based on file name this has
256 | // to change
257 | // TODO(user): If we allow goog.foo.* this has to change
258 | // TODO(user): If we implement dynamic load after page load we should probably
259 | // not remove this code for the compiled output
260 | if (!COMPILED) {
261 | if (goog.getObjectByName(rule)) {
262 | return;
263 | }
264 | var path = goog.getPathFromDeps_(rule);
265 | if (path) {
266 | goog.included_[path] = true;
267 | goog.writeScripts_();
268 | } else {
269 | var errorMessage = 'goog.require could not find: ' + rule;
270 | if (goog.global.console) {
271 | goog.global.console['error'](errorMessage);
272 | }
273 |
274 |
275 | throw Error(errorMessage);
276 |
277 | }
278 | }
279 | };
280 |
281 |
282 | /**
283 | * Path for included scripts
284 | * @type {string}
285 | */
286 | goog.basePath = '';
287 |
288 |
289 | /**
290 | * A hook for overriding the base path.
291 | * @type {string|undefined}
292 | */
293 | goog.global.CLOSURE_BASE_PATH;
294 |
295 |
296 | /**
297 | * Whether to write out Closure's deps file. By default,
298 | * the deps are written.
299 | * @type {boolean|undefined}
300 | */
301 | goog.global.CLOSURE_NO_DEPS;
302 |
303 |
304 | /**
305 | * Null function used for default values of callbacks, etc.
306 | * @return {void} Nothing.
307 | */
308 | goog.nullFunction = function() {};
309 |
310 |
311 | /**
312 | * The identity function. Returns its first argument.
313 | *
314 | * @param {...*} var_args The arguments of the function.
315 | * @return {*} The first argument.
316 | * @deprecated Use goog.functions.identity instead.
317 | */
318 | goog.identityFunction = function(var_args) {
319 | return arguments[0];
320 | };
321 |
322 |
323 | /**
324 | * When defining a class Foo with an abstract method bar(), you can do:
325 | *
326 | * Foo.prototype.bar = goog.abstractMethod
327 | *
328 | * Now if a subclass of Foo fails to override bar(), an error
329 | * will be thrown when bar() is invoked.
330 | *
331 | * Note: This does not take the name of the function to override as
332 | * an argument because that would make it more difficult to obfuscate
333 | * our JavaScript code.
334 | *
335 | * @type {!Function}
336 | * @throws {Error} when invoked to indicate the method should be
337 | * overridden.
338 | */
339 | goog.abstractMethod = function() {
340 | throw Error('unimplemented abstract method');
341 | };
342 |
343 |
344 | /**
345 | * Adds a {@code getInstance} static method that always return the same instance
346 | * object.
347 | * @param {!Function} ctor The constructor for the class to add the static
348 | * method to.
349 | */
350 | goog.addSingletonGetter = function(ctor) {
351 | ctor.getInstance = function() {
352 | return ctor.instance_ || (ctor.instance_ = new ctor());
353 | };
354 | };
355 |
356 |
357 | if (!COMPILED) {
358 | /**
359 | * Object used to keep track of urls that have already been added. This
360 | * record allows the prevention of circular dependencies.
361 | * @type {Object}
362 | * @private
363 | */
364 | goog.included_ = {};
365 |
366 |
367 | /**
368 | * This object is used to keep track of dependencies and other data that is
369 | * used for loading scripts
370 | * @private
371 | * @type {Object}
372 | */
373 | goog.dependencies_ = {
374 | pathToNames: {}, // 1 to many
375 | nameToPath: {}, // 1 to 1
376 | requires: {}, // 1 to many
377 | // used when resolving dependencies to prevent us from
378 | // visiting the file twice
379 | visited: {},
380 | written: {} // used to keep track of script files we have written
381 | };
382 |
383 |
384 | /**
385 | * Tries to detect whether is in the context of an HTML document.
386 | * @return {boolean} True if it looks like HTML document.
387 | * @private
388 | */
389 | goog.inHtmlDocument_ = function() {
390 | var doc = goog.global.document;
391 | return typeof doc != 'undefined' &&
392 | 'write' in doc; // XULDocument misses write.
393 | };
394 |
395 |
396 | /**
397 | * Tries to detect the base path of the base.js script that bootstraps Closure
398 | * @private
399 | */
400 | goog.findBasePath_ = function() {
401 | if (!goog.inHtmlDocument_()) {
402 | return;
403 | }
404 | var doc = goog.global.document;
405 | if (goog.global.CLOSURE_BASE_PATH) {
406 | goog.basePath = goog.global.CLOSURE_BASE_PATH;
407 | return;
408 | }
409 | var scripts = doc.getElementsByTagName('script');
410 | // Search backwards since the current script is in almost all cases the one
411 | // that has base.js.
412 | for (var i = scripts.length - 1; i >= 0; --i) {
413 | var src = scripts[i].src;
414 | var l = src.length;
415 | if (src.substr(l - 7) == 'base.js') {
416 | goog.basePath = src.substr(0, l - 7);
417 | return;
418 | }
419 | }
420 | };
421 |
422 |
423 | /**
424 | * Writes a script tag if, and only if, that script hasn't already been added
425 | * to the document. (Must be called at execution time)
426 | * @param {string} src Script source.
427 | * @private
428 | */
429 | goog.writeScriptTag_ = function(src) {
430 | if (goog.inHtmlDocument_() &&
431 | !goog.dependencies_.written[src]) {
432 | goog.dependencies_.written[src] = true;
433 | var doc = goog.global.document;
434 | doc.write('
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 | Sniffer Tests
63 |
64 |
65 |
66 | Sniffer Tests
67 |
68 | Below is a list of all the tests that Sniffer currently runs. All tests should either return true
or a string result (numbers generally represent version numbers) below.
69 |
70 |
71 |
72 |
73 |
74 |
88 |
89 |
90 |
95 |
96 |
106 |
107 |
123 |
124 |
125 |
139 |
140 |
144 |
145 |
146 |
147 |
148 |
174 |
175 |
176 |