3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
7 YUI.add('features', function (Y, NAME) {
9 var feature_tests = {};
12 Contains the core of YUI's feature test architecture.
22 Y.mix(Y.namespace('Features'), {
25 * Object hash of all registered feature tests
32 * Add a test to the system
35 * Y.Features.add("load", "1", {});
39 * @param {String} cat The category, right now only 'load' is supported
40 * @param {String} name The number sequence of the test, how it's reported in the URL or config: 1, 2, 3
41 * @param {Object} o Object containing test properties
42 * @param {String} o.name The name of the test
43 * @param {Function} o.test The test function to execute, the only argument to the function is the `Y` instance
44 * @param {String} o.trigger The module that triggers this test.
46 add: function(cat, name, o) {
47 feature_tests[cat] = feature_tests[cat] || {};
48 feature_tests[cat][name] = o;
51 * Execute all tests of a given category and return the serialized results
57 * @param {String} cat The category to execute
58 * @param {Array} args The arguments to pass to the test function
59 * @return {String} A semi-colon separated string of tests and their success/failure: 1:1;2:1;3:0
61 all: function(cat, args) {
62 var cat_o = feature_tests[cat],
66 Y.Object.each(cat_o, function(v, k) {
67 result.push(k + ':' + (Y.Features.test(cat, k, args) ? 1 : 0));
71 return (result.length) ? result.join(';') : '';
74 * Run a sepecific test and return a Boolean response.
77 * Y.Features.test("load", "1");
81 * @param {String} cat The category of the test to run
82 * @param {String} name The name of the test to run
83 * @param {Array} args The arguments to pass to the test function
84 * @return {Boolean} True or false if the test passed/failed.
86 test: function(cat, name, args) {
89 cat_o = feature_tests[cat],
90 feature = cat_o && cat_o[name];
95 result = feature.result;
97 if (Y.Lang.isUndefined(result)) {
105 if (test && ((!ua) || result)) {
106 result = test.apply(Y, args);
109 feature.result = result;
117 // Y.Features.add("load", "1", {});
118 // Y.Features.test("load", "1");
121 /* This file is auto-generated by src/loader/scripts/meta_join.js */
122 var add = Y.Features.add;
123 // app-transitions-native
125 "name": "app-transitions-native",
126 "test": function (Y) {
127 var doc = Y.config.doc,
128 node = doc ? doc.documentElement : null;
130 if (node && node.style) {
131 return ('MozTransition' in node.style || 'WebkitTransition' in node.style);
136 "trigger": "app-transitions"
138 // autocomplete-list-keys
140 "name": "autocomplete-list-keys",
141 "test": function (Y) {
142 // Only add keyboard support to autocomplete-list if this doesn't appear to
143 // be an iOS or Android-based mobile device.
145 // There's currently no feasible way to actually detect whether a device has
146 // a hardware keyboard, so this sniff will have to do. It can easily be
147 // overridden by manually loading the autocomplete-list-keys module.
149 // Worth noting: even though iOS supports bluetooth keyboards, Mobile Safari
150 // doesn't fire the keyboard events used by AutoCompleteList, so there's
151 // no point loading the -keys module even when a bluetooth keyboard may be
153 return !(Y.UA.ios || Y.UA.android);
155 "trigger": "autocomplete-list"
159 "name": "dd-gestures",
160 "test": function(Y) {
161 return ((Y.config.win && ("ontouchstart" in Y.config.win)) && !(Y.UA.chrome && Y.UA.chrome < 6));
167 "name": "dom-style-ie",
168 "test": function (Y) {
170 var testFeature = Y.Features.test,
171 addFeature = Y.Features.add,
172 WINDOW = Y.config.win,
173 DOCUMENT = Y.config.doc,
174 DOCUMENT_ELEMENT = 'documentElement',
177 addFeature('style', 'computedStyle', {
179 return WINDOW && 'getComputedStyle' in WINDOW;
183 addFeature('style', 'opacity', {
185 return DOCUMENT && 'opacity' in DOCUMENT[DOCUMENT_ELEMENT].style;
189 ret = (!testFeature('style', 'opacity') &&
190 !testFeature('style', 'computedStyle'));
194 "trigger": "dom-style"
198 "name": "editor-para-ie",
199 "trigger": "editor-para",
205 "name": "event-base-ie",
206 "test": function(Y) {
207 var imp = Y.config.doc && Y.config.doc.implementation;
208 return (imp && (!imp.hasFeature('Events', '2.0')));
210 "trigger": "node-base"
214 "name": "graphics-canvas",
215 "test": function(Y) {
216 var DOCUMENT = Y.config.doc,
217 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
218 canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
219 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
220 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
222 "trigger": "graphics"
224 // graphics-canvas-default
226 "name": "graphics-canvas-default",
227 "test": function(Y) {
228 var DOCUMENT = Y.config.doc,
229 useCanvas = Y.config.defaultGraphicEngine && Y.config.defaultGraphicEngine == "canvas",
230 canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
231 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
232 return (!svg || useCanvas) && (canvas && canvas.getContext && canvas.getContext("2d"));
234 "trigger": "graphics"
238 "name": "graphics-svg",
239 "test": function(Y) {
240 var DOCUMENT = Y.config.doc,
241 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
242 canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
243 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
245 return svg && (useSVG || !canvas);
247 "trigger": "graphics"
249 // graphics-svg-default
251 "name": "graphics-svg-default",
252 "test": function(Y) {
253 var DOCUMENT = Y.config.doc,
254 useSVG = !Y.config.defaultGraphicEngine || Y.config.defaultGraphicEngine != "canvas",
255 canvas = DOCUMENT && DOCUMENT.createElement("canvas"),
256 svg = (DOCUMENT && DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
258 return svg && (useSVG || !canvas);
260 "trigger": "graphics"
264 "name": "graphics-vml",
265 "test": function(Y) {
266 var DOCUMENT = Y.config.doc,
267 canvas = DOCUMENT && DOCUMENT.createElement("canvas");
268 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
270 "trigger": "graphics"
272 // graphics-vml-default
274 "name": "graphics-vml-default",
275 "test": function(Y) {
276 var DOCUMENT = Y.config.doc,
277 canvas = DOCUMENT && DOCUMENT.createElement("canvas");
278 return (DOCUMENT && !DOCUMENT.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") && (!canvas || !canvas.getContext || !canvas.getContext("2d")));
280 "trigger": "graphics"
284 "name": "history-hash-ie",
285 "test": function (Y) {
286 var docMode = Y.config.doc && Y.config.doc.documentMode;
288 return Y.UA.ie && (!('onhashchange' in Y.config.win) ||
289 !docMode || docMode < 8);
291 "trigger": "history-hash"
296 "trigger": "io-base",
299 // scrollview-base-ie
301 "name": "scrollview-base-ie",
302 "trigger": "scrollview-base",
307 "name": "selector-css2",
308 "test": function (Y) {
309 var DOCUMENT = Y.config.doc,
310 ret = DOCUMENT && !('querySelectorAll' in DOCUMENT);
314 "trigger": "selector"
318 "name": "transition-timer",
319 "test": function (Y) {
320 var DOCUMENT = Y.config.doc,
321 node = (DOCUMENT) ? DOCUMENT.documentElement: null,
324 if (node && node.style) {
325 ret = !('MozTransition' in node.style || 'WebkitTransition' in node.style);
330 "trigger": "transition"
334 "name": "widget-base-ie",
335 "trigger": "widget-base",
339 }, '3.7.1', {"requires": ["yui-base"]});