UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

1,261 lines (1,215 loc) 53.8 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2005-2011 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Martin Wittemann (martinwittemann) ************************************************************************ */ /** * This class is the single point to access all settings that may be different * in different environments. This contains e.g. the browser name, engine * version but also qooxdoo or application specific settings. * * Its public API can be found in its four main methods. One pair of methods * is used to check the synchronous values of the environment. The other pair * of methods is used for asynchronous checks. * * The most often used method should be {@link #get}, which returns the * current value for a given environment check. * * All qooxdoo settings can be changed at compile time. See the manual * for more details about the environment key in the config. As you can see * from the methods API, there is no way to override an existing key. So if you * need to change a qooxdoo setting, you have to use the compiler to do so. * * The compiler is also responsible for requiring the necessary implementation * classes for each check. When using a check of a new category, make sure to * rebuild you application and let the compiler include the necessary files. * * When you define a new environment check, the compiler needs to know which class * implements the check; to do this, you can either prefix the name of your check * with your class name (eg `my.package.MyClass.someEnvCheck`) or you can create * short names like the ones below and then add an entry to your library's * Manifest.json (under `provides.environmentChecks`). * * The following table shows the available checks. If you are * interested in more details, check the reference to the implementation of * each check. Please do not use those check implementations directly, as the * Environment class comes with a smart caching feature. * * <table border="0" cellspacing="10"> * <tbody> * <tr> * <td colspan="4"><h2>Synchronous checks</h2> * </td> * </tr> * <tr> * <th><h3>Key</h3></th> * <th><h3>Type</h3></th> * <th><h3>Example</h3></th> * <th><h3>Details</h3></th> * </tr> * <tr> * <td colspan="4"><b>browser</b></td> * </tr> * <tr> * <td>browser.documentmode</td><td><i>Integer</i></td><td><code>0</code></td> * <td>{@link qx.bom.client.Browser#getDocumentMode}</td> * </tr> * <tr> * <td>browser.name</td><td><i>String</i></td><td><code> chrome </code></td> * <td>{@link qx.bom.client.Browser#getName}</td> * </tr> * <tr> * <td>browser.quirksmode</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Browser#getQuirksMode}</td> * </tr> * <tr> * <td>browser.version</td><td><i>String</i></td><td><code>11.0</code></td> * <td>{@link qx.bom.client.Browser#getVersion}</td> * </tr> * <tr> * <td colspan="4"><b>runtime</b></td> * </tr> * <tr> * <td>runtime.name</td><td><i> String </i></td><td><code> node.js </code></td> * <td>{@link qx.bom.client.Runtime#getName}</td> * </tr> * <tr> * <td colspan="4"><b>css</b></td> * </tr> * <tr> * <td>css.borderradius</td><td><i>String</i> or <i>null</i></td><td><code>borderRadius</code></td> * <td>{@link qx.bom.client.Css#getBorderRadius}</td> * </tr> * <tr> * <td>css.borderimage</td><td><i>String</i> or <i>null</i></td><td><code>WebkitBorderImage</code></td> * <td>{@link qx.bom.client.Css#getBorderImage}</td> * </tr> * <tr> * <td>css.borderimage.standardsyntax</td><td><i>Boolean</i> or <i>null</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getBorderImageSyntax}</td> * </tr> * <tr> * <td>css.boxmodel</td><td><i>String</i></td><td><code>content</code></td> * <td>{@link qx.bom.client.Css#getBoxModel}</td> * </tr> * <tr> * <td>css.boxshadow</td><td><i>String</i> or <i>null</i></td><td><code>boxShadow</code></td> * <td>{@link qx.bom.client.Css#getBoxShadow}</td> * </tr> * <tr> * <td>css.gradient.linear</td><td><i>String</i> or <i>null</i></td><td><code>-moz-linear-gradient</code></td> * <td>{@link qx.bom.client.Css#getLinearGradient}</td> * </tr> * <tr> * <td>css.gradient.radial</td><td><i>String</i> or <i>null</i></td><td><code>-moz-radial-gradient</code></td> * <td>{@link qx.bom.client.Css#getRadialGradient}</td> * </tr> * <tr> * <td>css.gradient.legacywebkit</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Css#getLegacyWebkitGradient}</td> * </tr> * <tr> * <td>css.placeholder</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getPlaceholder}</td> * </tr> * <tr> * <td>css.textoverflow</td><td><i>String</i> or <i>null</i></td><td><code>textOverflow</code></td> * <td>{@link qx.bom.client.Css#getTextOverflow}</td> * </tr> * <tr> * <td>css.rgba</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getRgba}</td> * </tr> * <tr> * <td>css.usermodify</td><td><i>String</i> or <i>null</i></td><td><code>WebkitUserModify</code></td> * <td>{@link qx.bom.client.Css#getUserModify}</td> * </tr> * <tr> * <td>css.appearance</td><td><i>String</i> or <i>null</i></td><td><code>WebkitAppearance</code></td> * <td>{@link qx.bom.client.Css#getAppearance}</td> * </tr> * <tr> * <td>css.float</td><td><i>String</i> or <i>null</i></td><td><code>cssFloat</code></td> * <td>{@link qx.bom.client.Css#getFloat}</td> * </tr> * <tr> * <td>css.userselect</td><td><i>String</i> or <i>null</i></td><td><code>WebkitUserSelect</code></td> * <td>{@link qx.bom.client.Css#getUserSelect}</td> * </tr> * <tr> * <td>css.userselect.none</td><td><i>String</i> or <i>null</i></td><td><code>-moz-none</code></td> * <td>{@link qx.bom.client.Css#getUserSelectNone}</td> * </tr> * <tr> * <td>css.boxsizing</td><td><i>String</i> or <i>null</i></td><td><code>boxSizing</code></td> * <td>{@link qx.bom.client.Css#getBoxSizing}</td> * </tr> * <tr> * <td>css.animation</td><td><i>Object</i> or <i>null</i></td><td><code>{end-event: "webkitAnimationEnd", keyframes: "@-webkit-keyframes", play-state: null, name: "WebkitAnimation"}</code></td> * <td>{@link qx.bom.client.CssAnimation#getSupport}</td> * </tr> * <tr> * <td>css.animation.requestframe</td><td><i>String</i> or <i>null</i></td><td><code>mozRequestAnimationFrame</code></td> * <td>{@link qx.bom.client.CssAnimation#getRequestAnimationFrame}</td> * </tr> * <tr> * <td>css.transform</td><td><i>Object</i> or <i>null</i></td><td><code>{3d: true, origin: "WebkitTransformOrigin", name: "WebkitTransform", style: "WebkitTransformStyle", perspective: "WebkitPerspective", perspective-origin: "WebkitPerspectiveOrigin", backface-visibility: "WebkitBackfaceVisibility"}</code></td> * <td>{@link qx.bom.client.CssTransform#getSupport}</td> * </tr> * <tr> * <td>css.transform.3d</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.CssTransform#get3D}</td> * </tr> * <tr> * <td>css.transition</td><td><i>Object</i> or <i>null</i></td><td><code>{end-event: "webkitTransitionEnd", name: "WebkitTransition"}</code></td> * <td>{@link qx.bom.client.CssTransition#getSupport}</td> * </tr> * <tr> * <td>css.inlineblock</td><td><i>String</i> or <i>null</i></td><td><code>inline-block</code></td> * <td>{@link qx.bom.client.Css#getInlineBlock}</td> * </tr> * <tr> * <td>css.opacity</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getOpacity}</td> * </tr> * <tr> * <td>css.textShadow</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getTextShadow}</td> * </tr> * <tr> * <td>css.alphaimageloaderneeded</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Css#getAlphaImageLoaderNeeded}</td> * </tr> * <tr> * <td>css.pointerevents</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Css#getPointerEvents}</td> * </tr> * <tr> * <td>css.flexboxSyntax</td><td><i>String</i> or <i>null</i></td><td><code>"flex"</code></td> * <td>{@link qx.bom.client.Css#getFlexboxSyntax}</td> * </tr> * <tr> * <td colspan="4"><b>device</b></td> * </tr> * <tr> * <td>device.name</td><td><i>String</i></td><td><code>pc</code></td> * <td>{@link qx.bom.client.Device#getName}</td> * </tr> * <tr> * <td>device.type</td><td><i>String</i></td><td><code>mobile</code></td> * <td>{@link qx.bom.client.Device#getType}</td> * </tr> * <tr> * <td>device.pixelRatio</td><td><i>Number</i></td><td><code>2</code></td> * <td>{@link qx.bom.client.Device#getDevicePixelRatio}</td> * </tr> * <tr> * <td>device.touch</td><td><i>String</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Device#getTouch}</td> * </tr> * <tr> * <td colspan="4"><b>ecmascript</b></td> * </tr> * <tr> * <td>ecmascript.error.stacktrace</td><td><i>String</i> or <i>null</i></td><td><code>stack</code></td> * <td>{@link qx.bom.client.EcmaScript#getStackTrace}</td> * </tr> * <tr> * <td>ecmascript.mutationobserver</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getMutationObserver}</td> * </tr> * <tr> * <td>ecmascript.bigint</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getBigInt}</td> * </tr> * <tr> * <td>ecmascript.bigint.tolocalestring</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getBigIntToLocaleString}</td> * </tr> * <tr> * <td>ecmascript.array.indexof<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayIndexOf}</td> * </tr> * <tr> * <td>ecmascript.array.lastindexof<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayLastIndexOf}</td> * </tr> * <tr> * <td>ecmascript.array.foreach<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayForEach}</td> * </tr> * <tr> * <td>ecmascript.array.filter<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayFilter}</td> * </tr> * <tr> * <td>ecmascript.array.map<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayMap}</td> * </tr> * <tr> * <td>ecmascript.array.some<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArraySome}</td> * </tr> * <tr> * <td>ecmascript.array.find<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayFind}</td> * </tr> * <tr> * <td>ecmascript.array.findIndex<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayFindIndex}</td> * </tr> * <tr> * <td>ecmascript.array.every<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayEvery}</td> * </tr> * <tr> * <td>ecmascript.array.reduce<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayReduce}</td> * </tr> * <tr> * <td>ecmascript.array.reduceright<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getArrayReduceRight}</td> * </tr> * <tr> * <td>ecmascript.function.bind<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getFunctionBind}</td> * </tr> * <tr> * <td>ecmascript.object.keys<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getObjectKeys}</td> * </tr> * <tr> * <td>ecmascript.date.now<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getDateNow}</td> * </tr> * <tr> * <td>ecmascript.date.parse<td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getDateParse}</td> * </tr> * <tr> * <td>ecmascript.error.toString</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getErrorToString}</td> * </tr> * <tr> * <td>ecmascript.string.trim</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getStringTrim}</td> * </tr> * <tr> * <td>ecmascript.string.startsWith</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getStringStartsWith}</td> * </tr> * <tr> * <td>ecmascript.string.endsWith</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.EcmaScript#getStringEndsWith}</td> * </tr> * <tr> * <td colspan="4"><b>engine</b></td> * </tr> * <tr> * <td>engine.name</td><td><i>String</i></td><td><code>webkit</code></td> * <td>{@link qx.bom.client.Engine#getName}</td> * </tr> * <tr> * <td>engine.version</td><td><i>String</i></td><td><code>534.24</code></td> * <td>{@link qx.bom.client.Engine#getVersion}</td> * </tr> * <tr> * <td colspan="4"><b>event</b></td> * </tr> * <tr> * <td>event.mspointer</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getMsPointer}</td> * </tr> * <tr> * <td>event.touch</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Event#getTouch}</td> * </tr> * <tr> * <td>event.help</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Event#getHelp}</td> * </tr> * <tr> * <td>event.hashchange</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getHashChange}</td> * </tr> * <tr> * <td>event.dispatchevent</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getDispatchEvent}</td> * </tr> * <tr> * <td>event.customevent</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getCustomEvent}</td> * </tr> * <tr> * <td>event.mouseevent</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getMouseEvent}</td> * </tr> * <tr> * <td>event.mousecreateevent</td><td><i>String</i></td><td><code>UIEvents</code></td> * <td>{@link qx.bom.client.Event#getMouseCreateEvent}</td> * </tr> * <tr> * <td>event.mousewheel</td><td><i>Map</i></td><td><code>{type: "wheel", target: window}</code></td> * <td>{@link qx.bom.client.Event#getMouseWheel}</td> * </tr> * <tr> * <td>event.auxclick</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getAuxclickEvent}</td> * </tr> * <tr> * <td>event.passive</td><td><i>Map</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Event#getPassive}</td> * </tr> * * <tr> * <td colspan="4"><b>html</b></td> * </tr> * <tr> * <td>html.audio</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getAudio}</td> * </tr> * <tr> * <td>html.audio.mp3</td><td><i>String</i></td><td><code>""</code></td> * <td>{@link qx.bom.client.Html#getAudioMp3}</td> * </tr> * <tr> * <td>html.audio.ogg</td><td><i>String</i></td><td><code>"maybe"</code></td> * <td>{@link qx.bom.client.Html#getAudioOgg}</td> * </tr> * <tr> * <td>html.audio.wav</td><td><i>String</i></td><td><code>"probably"</code></td> * <td>{@link qx.bom.client.Html#getAudioWav}</td> * </tr> * <tr> * <td>html.audio.au</td><td><i>String</i></td><td><code>"maybe"</code></td> * <td>{@link qx.bom.client.Html#getAudioAu}</td> * </tr> * <tr> * <td>html.audio.aif</td><td><i>String</i></td><td><code>"probably"</code></td> * <td>{@link qx.bom.client.Html#getAudioAif}</td> * </tr> * <tr> * <td>html.canvas</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getCanvas}</td> * </tr> * <tr> * <td>html.classlist</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getClassList}</td> * </tr> * <tr> * <td>html.fullscreen</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getFullScreen}</td> * </tr> * <tr> * <td>html.geolocation</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getGeoLocation}</td> * </tr> * <tr> * <td>html.storage.local</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getLocalStorage}</td> * </tr> * <tr> * <td>html.storage.session</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getSessionStorage}</td> * </tr> * <tr> * <td>html.storage.userdata</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getUserDataStorage}</td> * </tr> * <tr> * <td>html.svg</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getSvg}</td> * </tr> * <tr> * <td>html.video</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getVideo}</td> * </tr> * <tr> * <td>html.video.h264</td><td><i>String</i></td><td><code>"probably"</code></td> * <td>{@link qx.bom.client.Html#getVideoH264}</td> * </tr> * <tr> * <td>html.video.ogg</td><td><i>String</i></td><td><code>""</code></td> * <td>{@link qx.bom.client.Html#getVideoOgg}</td> * </tr> * <tr> * <td>html.video.webm</td><td><i>String</i></td><td><code>"maybe"</code></td> * <td>{@link qx.bom.client.Html#getVideoWebm}</td> * </tr> * <tr> * <td>html.vml</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Html#getVml}</td> * </tr> * <tr> * <td>html.webworker</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getWebWorker}</td> * <tr> * <td>html.filereader</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getFileReader}</td> * </tr> * <tr> * <td>html.xpath</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getXPath}</td> * </tr> * <tr> * <td>html.xul</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getXul}</td> * </tr> * <tr> * <td>html.console</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getConsole}</td> * </tr> * <tr> * <td>html.element.contains</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getContains}</td> * </tr> * <tr> * <td>html.element.compareDocumentPosition</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getCompareDocumentPosition}</td> * </tr> * <tr> * <td>html.element.textContent</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getTextContent}</td> * </tr> * <tr> * <td>html.image.naturaldimensions</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getNaturalDimensions}</td> * </tr> * <tr> * <td>html.history.state</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getHistoryState}</td> * </tr> * <tr> * <td>html.selection</td><td><i>String</i></td><td><code>getSelection</code></td> * <td>{@link qx.bom.client.Html#getSelection}</td> * </tr> * <tr> * <td>html.node.isequalnode</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getIsEqualNode}</td> * </tr> * <tr> * <td colspan="4"><b>XML</b></td> * </tr> * <tr> * <td>xml.implementation</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Xml#getImplementation}</td> * </tr> * <tr> * <td>xml.domparser</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Xml#getDomParser}</td> * </tr> * <tr> * <td>xml.selectsinglenode</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Xml#getSelectSingleNode}</td> * </tr> * <tr> * <td>xml.selectnodes</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Xml#getSelectNodes}</td> * </tr> * <tr> * <td>xml.getelementsbytagnamens</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Xml#getElementsByTagNameNS}</td> * </tr> * <tr> * <td>xml.domproperties</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Xml#getDomProperties}</td> * </tr> * <tr> * <td>xml.attributens</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Xml#getAttributeNS}</td> * </tr> * <tr> * <td>xml.createelementns</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Xml#getCreateElementNS}</td> * </tr> * <tr> * <td>xml.createnode</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Xml#getCreateNode}</td> * </tr> * <tr> * <td>xml.getqualifieditem</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Xml#getQualifiedItem}</td> * </tr> * <tr> * <td colspan="4"><b>Stylesheets</b></td> * </tr> * <tr> * <td>html.stylesheet.createstylesheet</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Stylesheet#getCreateStyleSheet}</td> * </tr> * <tr> * <td>html.stylesheet.insertrule</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Stylesheet#getInsertRule}</td> * </tr> * <tr> * <td>html.stylesheet.deleterule</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Stylesheet#getDeleteRule}</td> * </tr> * <tr> * <td>html.stylesheet.addimport</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Stylesheet#getAddImport}</td> * </tr> * <tr> * <td>html.stylesheet.removeimport</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Stylesheet#getRemoveImport}</td> * </tr> * <tr> * <td colspan="4"><b>io</b></td> * </tr> * <tr> * <td>io.maxrequests</td><td><i>Integer</i></td><td><code>4</code></td> * <td>{@link qx.bom.client.Transport#getMaxConcurrentRequestCount}</td> * </tr> * <tr> * <td>io.ssl</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Transport#getSsl}</td> * </tr> * <tr> * <td>io.xhr</td><td><i>String</i></td><td><code>xhr</code></td> * <td>{@link qx.bom.client.Transport#getXmlHttpRequest}</td> * </tr> * <tr> * <td colspan="4"><b>locale</b></td> * </tr> * <tr> * <td>locale</td><td><i>String</i></td><td><code>de</code></td> * <td>{@link qx.bom.client.Locale#getLocale}</td> * </tr> * <tr> * <td>locale.variant</td><td><i>String</i></td><td><code>de</code></td> * <td>{@link qx.bom.client.Locale#getVariant}</td> * </tr> * <tr> * <td>locale.default</td><td><i>String</i></td><td><code>C</code></td> * <td>default locale C as in good tradition of unix {@link qx.bom.client.Locale}</td> * </tr> * <tr> * <td colspan="4"><b>os</b></td> * </tr> * <tr> * <td>os.name</td><td><i>String</i></td><td><code>osx</code></td> * <td>{@link qx.bom.client.OperatingSystem#getName}</td> * </tr> * <tr> * <td>os.version</td><td><i>String</i></td><td><code>10.6</code></td> * <td>{@link qx.bom.client.OperatingSystem#getVersion}</td> * </tr> * <tr> * <td>os.scrollBarOverlayed</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Scroll#scrollBarOverlayed}</td> * </tr> * <tr> * <td colspan="4"><b>phonegap</b></td> * </tr> * <tr> * <td>phonegap</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.PhoneGap#getPhoneGap}</td> * </tr> * <tr> * <td>phonegap.notification</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.PhoneGap#getNotification}</td> * </tr> * <tr> * <td colspan="4"><b>plugin</b></td> * </tr> * <tr> * <td>plugin.divx</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getDivX}</td> * </tr> * <tr> * <td>plugin.divx.version</td><td><i>String</i></td><td></td> * <td>{@link qx.bom.client.Plugin#getDivXVersion}</td> * </tr> * <tr> * <td>plugin.flash</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Flash#isAvailable}</td> * </tr> * <tr> * <td>plugin.flash.express</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Flash#getExpressInstall}</td> * </tr> * <tr> * <td>plugin.flash.strictsecurity</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Flash#getStrictSecurityModel}</td> * </tr> * <tr> * <td>plugin.flash.version</td><td><i>String</i></td><td><code>10.2.154</code></td> * <td>{@link qx.bom.client.Flash#getVersion}</td> * </tr> * <tr> * <td>plugin.gears</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getGears}</td> * </tr> * <tr> * <td>plugin.activex</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getActiveX}</td> * </tr> * <tr> * <td>plugin.skype</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getSkype}</td> * </tr> * <tr> * <td>plugin.pdf</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getPdf}</td> * </tr> * <tr> * <td>plugin.pdf.version</td><td><i>String</i></td><td></td> * <td>{@link qx.bom.client.Plugin#getPdfVersion}</td> * </tr> * <tr> * <td>plugin.quicktime</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Plugin#getQuicktime}</td> * </tr> * <tr> * <td>plugin.quicktime.version</td><td><i>String</i></td><td><code>7.6</code></td> * <td>{@link qx.bom.client.Plugin#getQuicktimeVersion}</td> * </tr> * <tr> * <td>plugin.silverlight</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getSilverlight}</td> * </tr> * <tr> * <td>plugin.silverlight.version</td><td><i>String</i></td><td></td> * <td>{@link qx.bom.client.Plugin#getSilverlightVersion}</td> * </tr> * <tr> * <td>plugin.windowsmedia</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Plugin#getWindowsMedia}</td> * </tr> * <tr> * <td>plugin.windowsmedia.version</td><td><i>String</i></td><td></td> * <td>{@link qx.bom.client.Plugin#getWindowsMediaVersion}</td> * </tr> * <tr> * <td colspan="4"><b>qx</b></td> * </tr> * <tr> * <td>qx.allowUrlSettings</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <td>qx.allowUrlVariants</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <td>qx.application</td><td><i>String</i></td><td><code>name.space</code></td> * <td><i>default:</i> <code>&lt;&lt;application name&gt;&gt;</code></td> * </tr> * <tr> * <td>qx.aspects</td><td><i>Boolean</i></td><td><code>false</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <td>qx.debug</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>qx.debug.databinding</td><td><i>Boolean</i></td><td><code>false</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <td>qx.debug.dispose</td><td><i>Boolean</i></td><td><code>false</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <td>qx.debug.dispose.level</td><td><i>Integer</i></td><td><code>0</code></td> * <td><i>default:</i> <code>0</code></td> * </tr> * <tr> * <td>qx.debug.io</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>false</code></td> * </tr> * <tr> * <tr> * <td>qx.debug.property.level</td><td><i>Integer</i></td><td><code>0</code></td> * <td><i>default:</i> <code>0</code></td> * </tr> * <tr> * <td>qx.debug.ui.queue</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>qx.dynlocale</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>qx.dyntheme</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>qx.globalErrorHandling</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code> {@link qx.event.GlobalError}</td> * </tr> * <tr> * <td>qx.headless</td><td><i>Boolean</i></td><td><code>false</code></td> * <td><i>default:</i> <code>false</code> Whether the environment is headless (ie rhino/nodejs); note that * headless will still have some kind of DOM emulation - normally that would be quite basic, unless * <a href="https://www.npmjs.com/package/jsdom">https://www.npmjs.com/package/jsdom</a> has been installed. * The <code>qx.headless</code> allows code to detect whether there is an user interface, most typically * whether to cater for input events. This is set automatically by the compiler but would have to be * manually configured if you use the generator.</td> * </tr> * <tr> * <td>qx.mobile.nativescroll</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Scroll#getNativeScroll}</td> * </tr> * <tr> * <td>qx.promise.warnings</td><td><i>Boolean</i></td><td>same as <code>qx.debug</code></td> * <td>true to enable runtime warnings in promises {@link qx.Promise}</td> * </tr> * <tr> * <td>qx.promise.longStackTraces</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>true to enable long stack traces in promises; this has a performance penalty but makes debugging asynchronous functions easier {@link qx.Promise}</td> * </tr> * <tr> * <td>qx.optimization.basecalls</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.optimization.comments</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.optimization.privates</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.optimization.strings</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.optimization.variables</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.optimization.variants</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>true if the corresponding <i>optimize</i> key is set in the config</td> * </tr> * <tr> * <td>qx.revision</td><td><i>String</i></td><td><code>27348</code></td> * </tr> * <tr> * <td>qx.theme</td><td><i>String</i></td><td><code>qx.theme.Modern</code></td> * <td><i>default:</i> <code>&lt;&lt;initial theme name&gt;&gt;</code></td> * </tr> * <tr> * <td>qx.version</td><td><i>String</i></td><td><code>${qxversion}</code></td> * </tr> * <tr> * <td>qx.blankpage</td><td><i>String</i></td><td><code>URI to blank.html page</code></td> * </tr> * <tr> * <td colspan="4"><b>module</b></td> * </tr> * <tr> * <td>module.databinding</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>module.logger</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>module.property</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>module.events</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td>module.objectid</td><td><i>Boolean</i></td><td><code>true</code></td> * <td><i>default:</i> <code>true</code></td> * </tr> * <tr> * <td colspan="4"><h3>Asynchronous checks</h3> * </td> * </tr> * <tr> * <td>html.dataurl</td><td><i>Boolean</i></td><td><code>true</code></td> * <td>{@link qx.bom.client.Html#getDataUrl}</td> * </tr> * <tr> * <td>plugin.pdfjs</td><td><i>Boolean</i></td><td><code>false</code></td> * <td>{@link qx.bom.client.Pdfjs#getPdfjs}</td> * </tr> * </tbody> * </table> * */ qx.Bootstrap.define("qx.core.Environment", { statics: { /** Map containing the synchronous check functions. */ _checks: {}, /** Map containing the asynchronous check functions. */ _asyncChecks: {}, /** Internal cache for all checks. */ __cache: {}, /** * Internal map for environment keys to check methods. * Gets populated dynamically at runtime. */ _checksMap: {}, _defaults: { // an always-true key (e.g. for use in qx.core.Environment.filter() calls) true: true, // old settings retTrue "qx.allowUrlSettings": false, "qx.allowUrlVariants": false, "qx.debug.property.level": 0, // old variants // make sure to reflect all changes to qx.debug here in the bootstrap class! "qx.debug": true, "qx.debug.ui.queue": true, "qx.debug.touchpad.detection": false, "qx.aspects": false, "qx.dynlocale": true, "qx.dyntheme": true, "qx.blankpage": "qx/static/blank.html", "qx.debug.databinding": false, "qx.debug.dispose": false, "qx.debug.startupTimings": false, // generator optimization vectors "qx.optimization.basecalls": false, "qx.optimization.comments": false, "qx.optimization.privates": false, "qx.optimization.strings": false, "qx.optimization.variables": false, "qx.optimization.variants": false, // qooxdoo modules "module.databinding": true, "module.logger": true, "module.property": true, "module.events": true, "module.objectid": true, "qx.nativeScrollBars": false, "qx.automaticMemoryManagement": true, "qx.promise": true, "qx.promise.warnings": true, "qx.promise.longStackTraces": true, "qx.command.bindEnabled": false, "qx.headless": false, "qx.environment.allowRuntimeMutations": false }, /** * The default accessor for the checks. It returns the value the current * environment has for the given key. The key could be something like * "qx.debug", "css.textoverflow" or "io.ssl". A complete list of * checks can be found in the class comment of this class. * * Please keep in mind that the result is cached. If you want to run the * check function again in case something could have been changed, take a * look at the {@link #invalidateCacheKey} function. * * @param key {String} The name of the check you want to query. * @return {var} The stored value depending on the given key. * (Details in the class doc) */ get(key) { // check the cache if (this.__cache[key] != undefined) { return this.__cache[key]; } // search for a matching check var check = this._checks[key]; if (check) { // execute the check and write the result in the cache var value = check(); this.__cache[key] = value; return value; } // try class lookup var classAndMethod = this._getClassNameFromEnvKey(key); if (classAndMethod[0] != undefined) { var clazz = classAndMethod[0]; var method = classAndMethod[1]; var value = clazz[method](); // call the check method this.__cache[key] = value; return value; } // debug flag if (qx.Bootstrap.DEBUG) { qx.Bootstrap.warn("The environment key '" + key + "' is undefined."); qx.Bootstrap.trace(this); } }, /** * Maps an environment key to a check class and method name. * * @param key {String} The name of the check you want to query. * @return {Array} [className, methodName] of * the corresponding implementation. */ _getClassNameFromEnvKey(key) { var envmappings = this._checksMap; if (envmappings[key] != undefined) { var implementation = envmappings[key]; // separate class from method var lastdot = implementation.lastIndexOf("."); if (lastdot > -1) { var classname = implementation.slice(0, lastdot); var methodname = implementation.slice(lastdot + 1); var clazz = qx.Bootstrap.getByName(classname); if (clazz != undefined) { return [clazz, methodname]; } } } return [undefined, undefined]; }, /** * Invokes the callback as soon as the check has been done. If no check * could be found, a warning will be printed. * * @param key {String} The key of the asynchronous check. * @param callback {Function} The function to call as soon as the check is * done. The function should have one argument which is the result of the * check. * @param self {var} The context to use when invoking the callback. */ getAsync(key, callback, self) { // check the cache var env = this; if (this.__cache[key] != undefined) { // force async behavior window.setTimeout(function () { callback.call(self, env.__cache[key]); }, 0); return; } var check = this._asyncChecks[key]; if (check) { check(function (result) { env.__cache[key] = result; callback.call(self, result); }); return; } // try class lookup var classAndMethod = this._getClassNameFromEnvKey(key); if (classAndMethod[0] != undefined) { var clazz = classAndMethod[0]; var method = classAndMethod[1]; clazz[method](function (result) { // call the check method env.__cache[key] = result; callback.call(self, result); }); return; } // debug flag if (qx.Bootstrap.DEBUG) { qx.Bootstrap.warn("The environment key '" + key + "' is undefined."); qx.Bootstrap.trace(this); } }, /** * Returns the proper value dependent on the check for the given key. * * @param key {String} The name of the check the select depends on. * @param values {Map} A map containing the values which should be returned * in any case. The "default" key could be used as a catch all statement. * @return {var} The value which is stored in the map for the given * check of the key. */ select(key, values) { return this.__pickFromValues(this.get(key), values); }, /** * Selects the proper function dependent on the asynchronous check. * * @param key {String} The key for the async check. * @param values {Map} A map containing functions. The map keys should * contain all possibilities which could be returned by the given check * key. The "default" key could be used as a catch all statement. * The called function will get one parameter, the result of the query. * @param self {var} The context which should be used when calling the * method in the values map. */ selectAsync(key, values, self) { this.getAsync( key, function (result) { var value = this.__pickFromValues(key, values); value.call(self, result); }, this ); }, /** * Internal helper which tries to pick the given key from the given values * map. If that key is not found, it tries to use a key named "default". * If there is also no default key, it prints out a warning and returns * undefined. * * @param key {String} The key to search for in the values. * @param values {Map} A map containing some keys. * @return {var} The value stored as values[key] usually. */ __pickFromValues(key, values) { var value = values[key]; if (values.hasOwnProperty(key)) { return value; } // check for piped values for (var id in values) { if (id.indexOf("|") != -1) { var ids = id.split("|"); for (var i = 0; i < ids.length; i++) { if (ids[i] == key) { return values[id]; } } } } if (values["default"] !== undefined) { return values["default"]; } if (qx.Bootstrap.DEBUG) { throw new Error( 'No match for variant "' + key + '" (' + typeof key + " type)" + " in variants [" + qx.Bootstrap.keys(values) + '] found, and no default ("default") given' ); } }, /** * Takes a given map containing the check names as keys and converts * the map to an array only containing the values for check evaluating * to <code>true</code>. This is especially handy for conditional * includes of mixins. * @param map {Map} A map containing check names as keys and values. * @return {Array} An array containing the values. */ filter(map) { var returnArray = []; for (var check in map) { if (this.get(check)) { returnArray.push(map[check]); } } return returnArray; }, /** * Invalidates the cache for the given key. * * @param key {String} The key of the check. */ invalidateCacheKey(key) { delete this.__cache[key]; }, /** * Add a check to the environment class. If there is already a check * added for the given key, the add will be ignored. * * @param key {String} The key for the check e.g. html.featurexyz. * @param check {var} It could be either a function or a simple value. * The function should be responsible for the check and should return the * result of the check. */ add(key, check) { // ignore already added checks. if (this._checks[key] == undefined) { // add functions directly if (check instanceof Function) { if (!this._checksMap[key] && check.displayName) { this._checksMap[key] = check.displayName.substr( 0, check.displayName.length - 2 ); } this._checks[key] = check; // otherwise, create a check function and use that } else { this._checks[key] = this.__createCheck(check); } } }, /** * Adds an asynchronous check to the environment. If there is already a check * added for the given key, the add will be ignored. * * @param key {String} The key of the check e.g. html.featureabc * @param check {Function} A function which should check for a specific * environment setting in an asynchronous way. The method should take two * arguments. First one is the callback and the second one is the context. */ addAsync(key, check) { if (this._checks[key] == undefined) { this._asyncChecks[key] = check; } }, /** * Returns all currently defined synchronous checks. * * @internal * @return {Map} The map of synchronous checks */ getChecks() { return this._checks; }, /** * Returns all currently defined asynchronous checks. * * @internal * @return {Map} The map of asynchronous checks */ getAsyncChecks() { return this._asyncChecks; }, // mutation of environment settings at runtime /** * Sets the environment setting for the given key to the given value. This deletes any check function * associated with this key. * * This method is only available if "qx.environment.allowRuntimeMutations" is set to true. * * @param key {String} The key of the environment setting to set. * @param value {var} The value to set the environment setting to. Must be a scalar value. */ set: qx.Bootstrap.getEnvironmentSetting("qx.environment.allowRuntimeMutations") ? function(key, value) { if (key === undefined) { throw new TypeError("Key must be provided to set an environment setting."); } if (this.__environmentBackup === undefined) { qx.Bootstrap.warn("Modifying environment settings at runtime is enabled. This is a security risk and should not be done in production code."); this.__environmentBackup = Object.assign({}, this.__cache); this.__checksBackup = Object.assign({}, this._checks); } this.__cache[key] = value; delete this._checks[key]; delete this._checksMap[key]; }: undefined, /** * Removes the environment setting for the given key, and any check function associated with it. * This method is only available if "qx.environment.allowRuntimeMutations" is set to true. * * @param key {String} The key of the environment setting to remove. */ remove: qx.Bootstrap.getEnvironmentSetting("qx.environment.allowRuntimeMutations") ? function(key) { if (key === undefined) { throw new TypeError("Key must be provided to remove an environment setting."); } if (this.__environmentBackup === undefined || this.__environmentBackup[key] === undefined) { throw new TypeError(`Environment setting "${key}" does not exist.`); } delete this.__cache[key]; delete this._checks[key]; delete this._checksMap[key]; }: undefined, /** * Resets the environment settings to their original values. If a key is provided, only that key is reset. * This method is only available if "qx.environment.allowRuntimeMutations" is set to true. * * @param key {String?} The key of the environment setting