@qooxdoo/framework
Version:
The JS Framework for Coders
1,261 lines (1,215 loc) • 53.8 kB
JavaScript
/* ************************************************************************
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><<application name>></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><<initial theme name>></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