X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/docs/source/AIRIntrospector.html diff --git a/docs/source/AIRIntrospector.html b/docs/source/AIRIntrospector.html new file mode 100644 index 00000000..e5d7d214 --- /dev/null +++ b/docs/source/AIRIntrospector.html @@ -0,0 +1,1950 @@ + +
+/* AIRIntrospector.js - Revision: 0.15.88 */ + +// Copyright 2007-2008. Adobe Systems Incorporated. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Adobe Systems Incorporated nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +var air; + +(function(){ + +if(typeof air=='undefined') air = {}; +air.Introspector = {}; + + +// Check the runtime. +if(typeof window.runtime!='undefined' && typeof window.nativeWindow!='undefined') + var isAppSandbox = true; +else + var isAppSandbox = false; + +//======================================================================================================================================================= +//Introspector.js +//======================================================================================================================================================= + + + + +//---------------------------------------------------------------------------------------------------- +/** +* @API air.Introspector.Console +* @description Exposes log, warn, info, error, dump to the user +* THIS IS THE ONLY SUPPORTED APIs +*/ + +air.Introspector.Console = { + log: function(){ + air.Introspector.logArguments(arguments, + {htmlLoader:isAppSandbox?window.htmlLoader:null}); + }, + + warn : function(){ + air.Introspector.logArguments(arguments, + {htmlLoader:isAppSandbox?window.htmlLoader:null, type:'warn'}); + }, + + info : function(){ + air.Introspector.logArguments(arguments, + {htmlLoader:isAppSandbox?window.htmlLoader:null, type:'info'}); + }, + + error : function(){ + air.Introspector.logArguments(arguments, + {htmlLoader:isAppSandbox?window.htmlLoader:null, type:'error'}); + }, + dump : function(obj, level){ + air.Introspector.logArguments(air.Introspector.dump(obj, level), + {htmlLoader: isAppSandbox?window.htmlLoader:null, usePre:true}); + } +}; + +//---------------------------------------------------------------------------------------------------- + +air.Introspector.config = { + showTimestamp: true, //Make the console show time stamps before each line + showSender: true, //Make the console show time stamps + wrapColumns: 2000, //Source files are soft-wrapped at around 2000 columns by default + flashTabLabels: true, //Console and xhr columns can flash whenever something happend to them (eg. logged something). You can turn it off + //by setting this to false + closeIntrospectorOnExit: true, //Makes the inspector window close when the last window closed + debugRuntimeObjects: true, //Also expand ActionScript objects + introspectorKey:122, //Inspect key - by default it is F11 (122) + debuggerKey:123, //Toggle inspectors visibility - by default it is F12 (123) + useAirDebugHtml: false, //Internal only +}; + + +/** +* @module air.Introspector +*/ + +air.Introspector.extend = function(dst, src){ + //Take every property from src and put it in dst + for(var i in src){ + dst[i]=src[i]; + } +}; + +// Checking if the user has configured Introspector using global AIRIntrospectorConfig variable +if(typeof AIRIntrospectorConfig!='undefined'){ + air.Introspector.extend(air.Introspector.config, AIRIntrospectorConfig); +} + +var eventListeners = []; + +// Can not expand ActionScript objects from remote sandbox - we can not even access ActionScript from there +// just disabled this feature +if(!isAppSandbox) air.Introspector.config.debugRuntimeObjects = false; + +// Made this use g/setters in order to make it easy to send its value over the bridge +air.Introspector.__defineGetter__('inspect', function(){ + return air.Introspector._inspect; +}); + +air.Introspector.__defineSetter__('inspect', function(value){ + air.Introspector._inspect=value; + if(!isAppSandbox){ + setTimeout(function(){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_setInspect(value); + }); + }, 0); + }else{ + if(!value){ + air.Introspector.hideHighlight(); + } + } +}); + +air.Introspector.extend(air.Introspector, { + + /** + * Makes it easier to acces runtime packages + * it makes sense only in the application sandbox + */ + runtime: isAppSandbox?{ + HTMLLoader : window.runtime.flash.html.HTMLLoader, + Event : window.runtime.flash.events.Event, + IOErrorEvent: window.runtime.flash.events.IOErrorEvent, + NativeApplication: window.runtime.flash.desktop.NativeApplication, + URLLoader : window.runtime.flash.net.URLLoader, + URLRequest : window.runtime.flash.net.URLRequest, + NativeWindowInitOptions : window.runtime.flash.display.NativeWindowInitOptions, + Capabilities: window.runtime.flash.system.Capabilities, + trace : window.runtime.trace, + }:null, + + _inspect: false, + remoteInspect: false, + canClick: false, + + bridgeCallbacks: [], + + + /** + * Different coloring styles for tag names, by default 'default' is used + * Undocumented feature + * - you can change the color of elements while inspecting by tag name, check bellow the body: 0x00CC00 line, + * uncomment that line, duplicate and change it with your own colors + */ + highlightBgColors: { + 'default': 0xFFCC00, + //body: 0x00CC00, + + }, + + /** + * @function trimRegExp + * @description Trims spaces from a string + * @private + */ + trimRegExp: /^[\s\r\n]*([\s\S]*?)[\s\r\n]*$/g, + trim:function(str){ + return str.replace(air.Introspector.trimRegExp, '$1'); + }, + + /** + * @function blockWrap + * @description Wraps a string by air.Introspector.config.wrapColumns columns + */ + blockWrap: function(str){ + //used for spliting large lines in+ var cols = air.Introspector.config.wrapColumns; + var lines = str.split(/\n/); + var buffer = []; + var l = lines.length; + var lineNumbers = []; + for(var i=0;icols){ + buffer.push(line.substr(0, cols)); + line = line.substr(cols); + lineNumbers.push(''); + } + buffer.push(line); + } + lineNumbers.push('EOF'); + return [buffer.join('\n'), lineNumbers.join('\n')]; + }, + + /** + * @function getTextFormat + * @description Returns a new flash TextField + */ + createTextField: function(parentSprite, fontSize, fontBold) { + if(isAppSandbox){ + var tf = new runtime.flash.text.TextField(); + tf.embedFonts = false; + tf.autoSize = runtime.flash.text.TextFieldAutoSize.LEFT; + tf.antiAliasType = runtime.flash.text.AntiAliasType.ADVANCED; + tf.defaultTextFormat = air.Introspector.getTextFormat(fontSize, fontBold); + tf.selectable = false; + tf.mouseEnabled = true; + tf.x = 4; + tf.text = ""; + if(parentSprite.numChildren > 0) { + var sibling = parentSprite.getChildAt(parentSprite.numChildren - 1); + tf.y = sibling.y + sibling.height + 15; + } + parentSprite.addChild(tf); + return tf; + }else{ + //should not get here + return null; + } + }, + /** + * @function getTextFormat + * Returns a new flash TextFormat + * see createTextField + */ + getTextFormat: function(fontSize, fontBold){ + if(isAppSandbox){ + var format = new runtime.flash.text.TextFormat(); + format.size = fontSize; + format.font = "Tahoma"; + format.bold = fontBold; + format.color = 0x330066; + return format; + }else{ + //should not get here + return null; + } + }, + + /** + * @function extendRect + * @description Initializes the sprite with values from the rectangle + */ + extendRect: function(sprite, rect){ + sprite.x = rect.x; + sprite.y = rect.y; + sprite.width = rect.width; + sprite.height = rect.height; + sprite.scaleX = rect.scaleX; + sprite.scaleY = rect.scaleY; + }, + + + /** + * @function showHighlight + * @description Shows a highlighting flash sprite using coordinates from rectangle + */ + showHighlight: function(rect){ + if(isAppSandbox){ + //dehilight everyone else + var ownedWindows = air.Introspector.getHtmlWindows(); + for(var i=ownedWindows.length-1;i>=0;i--){ + try{ + ownedWindows[i].htmlLoader.window.air.Introspector.hideHighlight(); + }catch(e){ + //no air.Introspector + } + } + air.Introspector.extendRect(air.Introspector.highlightSprite, rect); + }else{ + setTimeout(function(){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_showHighlight(rect); + }); + + }, 0); + + + } + }, + + /** + * @function hideHighlight + * @description Make the higlight box go away + */ + hideHighlight: function(){ + if(isAppSandbox){ + air.Introspector.extendRect(air.Introspector.highlightSprite, {x:0, y:0, width:0, height:0, scaleX:0, scaleY:0}); + air.Introspector.highlightText.visible = false; + }else{ + setTimeout(function(){ + try{ + parentSandboxBridge.air_Introspector_hideHighlight(); + }catch(e){ + // no bridge yet + } + }, 0); + } + }, + + /** + * @function remoteClick + * @description Make the remote sandbox know that the inspection finished + */ + remoteClick: function(){ + air.Introspector.debugWindow.finishInspect(false); + air.Introspector.hideHighlight(); + }, + + + /** + * @function createHighlight + * @description Creates a flash sprite used to higlight elements + * By using this method we are sure that no dom manipulation is done and + * no style is changed in HTML. + */ + createHighlight: function(){ + if(isAppSandbox){ + var sprite = new runtime.flash.display.Sprite(); + sprite.mouseEnabled = false; + sprite.width = 0; + sprite.height = 0; + sprite.buttonMode = true; + var prevent = function(element, event, isClick){ + air.Introspector.addEventListener(element, event, function(e){ + if((air.Introspector.inspect||air.Introspector.remoteInspect) &&sprite.hitTestPoint(e.stageX, e.stageY)){ + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + if(isClick&&air.Introspector.canClick){ + if(air.Introspector.remoteInspect){ + try{ + air.Introspector.inspectFrame.contentWindow.childSandboxBridge.air_Introspector_remoteClick(); + }catch(e){ air.Introspector.noChildBridge(air.Introspector.inspectFrame); } + }else{ + air.Introspector.debugWindow.finishInspect(false); + air.Introspector.hideHighlight(); + } + } + } + + }, true, 2000000); + }; + var check = function(element, event){ + air.Introspector.addEventListener(element, event, function(e){ + if((air.Introspector.inspect||air.Introspector.remoteInspect)&&nativeWindow.active){ + setTimeout(function(){ + air.Introspector.canClick = true; + }, 100); + } + }, true, 200000); + } + + var labelMover = function(element, event){ + air.Introspector.addEventListener(element, event, function(e){ + if((air.Introspector.inspect||air.Introspector.remoteInspect)){ + air.Introspector.highlightText.x = e.stageX+15; + air.Introspector.highlightText.y = e.stageY+15; +// air.Introspector.highlightText.visible = true; + }else{ + + air.Introspector.highlightText.visible = false; + } + }, true, 200000); + } + prevent(htmlLoader.stage, runtime.flash.events.MouseEvent.CLICK, true); + prevent(htmlLoader.stage, runtime.flash.events.MouseEvent.MOUSE_DOWN); + prevent(htmlLoader.stage, runtime.flash.events.MouseEvent.MOUSE_UP); + prevent(htmlLoader.stage, runtime.flash.events.MouseEvent.DOUBLE_CLICK); + check(htmlLoader.stage, runtime.flash.events.MouseEvent.MOUSE_MOVE); + check(nativeWindow, runtime.flash.events.Event.ACTIVATE); + labelMover(htmlLoader.stage, runtime.flash.events.MouseEvent.MOUSE_MOVE); + window.htmlLoader.stage.addChild(sprite); + air.Introspector.highlightSprite = sprite; + + air.Introspector.highlightText = new runtime.flash.display.Sprite(); + window.htmlLoader.stage.addChild(air.Introspector.highlightText); + + air.Introspector.highlightText.graphics.beginFill(0xeeeeee, 0.8); + air.Introspector.highlightText.graphics.lineStyle(1, 0xeeeeee, 0.9, false); + air.Introspector.highlightText.graphics.drawRect(0, 0, 250, 40); + air.Introspector.highlightText.visible = false; + air.Introspector.highlightLine1 = air.Introspector.createTextField(air.Introspector.highlightText, 16, true); + air.Introspector.highlightLine2 = air.Introspector.createTextField(air.Introspector.highlightText, 10, false); + }else{ + //should not be here + } + }, + + /** + * @function addEventListener + * @description Add a listener and stores it for future cleanup + */ + addEventListener: function(obj, eventName, listener, capture, priority){ + eventListeners.push([obj, eventName, listener, capture]); + obj.addEventListener(eventName, listener, capture, priority); + }, + + /** + * @function removeEventListener + * @description Removes listener + */ + removeEventListener: function(obj, eventName, listener, capture){ + for(var i=eventListeners.length-1;i>=0;i--){ + var l = eventListeners[i]; + if(l[0]==obj && l[1]==eventName && l[2]==listener && l[3]==capture) + { + eventListeners.splice(i, 1); + break; + } + } + obj.removeEventListener(eventName, listener, capture); + }, + + /** + * @function drawRect + * @description Draw a rectangle using ActionScript, also use tagName to find out which color to use + * @see air.Introspector.highlightBgColors + */ + drawRect: function (rect, tagName){ + var htmlLoaderBounds = htmlLoader.getBounds(htmlLoader.stage); + rect.x += htmlLoaderBounds.x; + rect.y += htmlLoaderBounds.y; + rect.scaleX = 1; + rect.scaleY = 1; + air.Introspector.showHighlight(rect); + air.Introspector.highlightSprite.graphics.clear(); + var bgColor = air.Introspector.highlightBgColors[tagName.toLowerCase()]; + if(typeof bgColor=='undefined') + bgColor = air.Introspector.highlightBgColors['default']; + air.Introspector.highlightSprite.graphics.beginFill(bgColor, 0.2); + air.Introspector.highlightSprite.graphics.lineStyle(3, bgColor, 0.9, false); + air.Introspector.highlightSprite.graphics.drawRect(0, 0, rect.width, rect.height); + }, + + /** + * @function highlightElement + * @description Highlight element e. Get its bounding box and send it directly or over the bridge to air.Introspector.drawRect + * @also air.Introspector.drawRect + */ + highlightElement: function(e, callback){ + var rect = air.Introspector.getBorderBox(e); + if(rect==false) + return; + + if(isAppSandbox){ + air.Introspector.drawRect(rect, e.tagName); + }else{ + setTimeout(function(){ + try{ + if(!isNaN(rect.width)&&!isNaN(rect.x)){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_drawRect(rect, e.tagName); + }); + } + }catch(e){ + air.Introspector.Console.error(e); + } + if(typeof callback!='undefined') callback(); + }, 0); + } + }, + + /** + * @function addKeyboardEvents + * @description Registers events on every window that includes AIRDebug.js. + * + * By default F11 enables the inspect tool + * F12 pops up the debug tool + */ + addKeyboardEvents: function(sprite){ + air.Introspector.addEventListener(sprite, runtime.flash.events.KeyboardEvent.KEY_DOWN, function(e){ + if(e.keyCode==air.Introspector.config.introspectorKey){ //F11 key pressed + if(typeof air.Introspector.lastElement!='undefined'&&(air.Introspector.lastElement.nodeName=='IFRAME'||air.Introspector.lastElement.nodeName=='FRAME')){ + try{ + var contentWindow = air.Introspector.lastElement.contentWindow; + if(typeof contentWindow.childSandboxBridge!='undefined'&& + typeof contentWindow.childSandboxBridge.air_Introspector_isDebugOpen!='undefined'&& + typeof contentWindow.childSandboxBridge.air_Introspector_toggleInspect!='undefined') + { + if(contentWindow.childSandboxBridge.air_Introspector_isDebugOpen()){ + contentWindow.childSandboxBridge.air_Introspector_toggleInspect(); + e.preventDefault(); + e.stopPropagation(); + return; + } + } + }catch(e){ + //it looks like no debugger in that iframe. go ahead with app sandbox debugger + } + } + air.Introspector.init(false, true, function(){ + air.Introspector.debugWindow.toggleInspect(); + }); + + e.preventDefault(); + e.stopPropagation(); + }else if(e.keyCode==air.Introspector.config.debuggerKey){ //F12 key pressed + air.Introspector.toggleWindow(); + e.preventDefault(); + e.stopPropagation(); + }else if(e.keyCode==27&&air.Introspector.inspect){ + air.Introspector.debugWindow.finishInspect(); + air.Introspector.hideHighlight(); + e.preventDefault(); + e.stopPropagation(); + }else if(e.ctrlKey==true&&e.altKey==false){ + var tab = null; + switch(e.keyCode){ + case runtime.flash.ui.Keyboard.NUMBER_1: + tab = 0; + break; + case runtime.flash.ui.Keyboard.NUMBER_2: + tab = 1; + break; + case runtime.flash.ui.Keyboard.NUMBER_3: + tab = 2; + break; + case runtime.flash.ui.Keyboard.NUMBER_4: + tab = 3; + break; + case runtime.flash.ui.Keyboard.NUMBER_5: + tab = 4; + break; + case runtime.flash.ui.Keyboard.NUMBER_6: + tab = 5; + break; + } + if(tab!=null){ + air.Introspector.init(false, true, function(){ + air.Introspector.debugWindow.setTab(tab); + }); + e.preventDefault(); + e.stopPropagation(); + } + } + }, true, 1000000); + }, + + /** + * @function showHighlightLabels + * @description Make the tooltip labels near the highlighting box appear and tell the id/tag name/outer HTML + */ + showHighlightLabels: function(id, nodeName, outerHTML){ + if(typeof id!='undefined'&&id.length!=0){ + air.Introspector.highlightLine1.text = nodeName+' - '+id; + }else{ + air.Introspector.highlightLine1.text = nodeName; + } + if(air.Introspector.canClick){ + air.Introspector.highlightLine2.text = outerHTML.substr(0, 40).replace(/\n/g, '\\n')+'...'; + }else{ + air.Introspector.highlightLine2.text = 'Click to activate window'; + window.clearTimeout(air.Introspector.clickToActivateTimeout); + air.Introspector.clickToActivateTimeout = setTimeout(function(){ + air.Introspector.highlightLine2.text = outerHTML.substr(0, 40).replace(/\n/g, '\\n')+'...'; + }, 400) + } + air.Introspector.highlightText.visible = true; + }, + + + /** + * @function registerUncaughtExceptionListener + * @description Catches all uncaught exceptions from javascript and shows them in the console + */ + registerUncaughtExceptionListener: function(){ + + air.Introspector.addEventListener(window.htmlLoader, + runtime.flash.events.HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION , + function(e){ + if(e.exceptionValue && + e.exceptionValue.air_Introspector_setParentSandboxBridge == true && + e.exceptionValue.air_Introspector_version == air.Introspector.version) + { + air.Introspector.registerFramesParentSandboxBridge(); + e.preventDefault(); + return; + } + + air.Introspector.logError(e.exceptionValue, {htmlLoader:window.htmlLoader}); + // e.preventDefault(); + }); + + + }, + + + /** + * @function registerCloseEventListener + * @description + */ + registerCloseEventListener: function(){ + air.Introspector.addEventListener(window.nativeWindow, air.Introspector.runtime.Event.CLOSE, function(){ + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null){ + debugWindow.closedWindow(window.htmlLoader); + } + + }); + + + }, + + /** + * @function registerCompleteEventLisener + * @description Make the Introspector window knwo that we are complete. Register parentSandboxBridge on every frame + */ + registerCompleteEventListener: function(){ + air.Introspector.addEventListener(window.htmlLoader, air.Introspector.runtime.Event.COMPLETE, function(){ + air.Introspector.removeEventListener(window.htmlLoader, air.Introspector.runtime.Event.COMPLETE, arguments.callee); + try{ + //announce the debugWindow to refresh DOM and assets + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null){ + if(debugWindow.isLoaded){ + debugWindow.completeWindow(window.htmlLoader); + } + } + + air.Introspector.registerFramesParentSandboxBridge(); + }catch(e){ + runtime.trace(e); + runtime.trace(e.line); + air.Introspector.Console.log(e); + } + }); + }, + + /** + * @function registerFramesParentSandboxBridge + * @description All frames should know about us - registering parentSandboxBridge + */ + + registerFramesParentSandboxBridge: function(){ + //var modified = false; + var iframes = document.getElementsByTagName('iframe'); + for(var i=iframes.length-1;i>=0;i--){ + air.Introspector.registerFrame(iframes[i]); + } + + var frames = document.getElementsByTagName('frame'); + for(var i=frames.length-1;i>=0;i--){ + air.Introspector.registerFrame(frames[i]); + } + //return modified; + }, + + /** + * @function registerDeactivateEventLisener + * @description Hides the highlighting rectangle and deactivates inspect-clicking for this window + */ + registerDeactivateEventListener: function(){ + air.Introspector.addEventListener(window.nativeWindow, air.Introspector.runtime.Event.DEACTIVATE, function(){ air.Introspector.hideHighlight(); air.Introspector.canClick =false; }); + }, + + /** + * @function registerChildSandboxBridge + * @description Register childSandboxBridge for current iframe + */ + registerChildSandboxBridge: function(){ + + if(typeof childSandboxBridge=='undefined') + childSandboxBridge={}; + try{ + childSandboxBridge.air_Introspector_remoteClick = function (){ + try{ + air.Introspector.remoteClick(); + }catch(e){ alert(e+' '+e.line); } + } + + childSandboxBridge.air_Introspector_isDebugOpen = function(){ + return typeof air.Introspector.debugWindow!='undefined'; + } + + childSandboxBridge.air_Introspector_toggleInspect = function (){ + air.Introspector.init(false, true, function() + { + air.Introspector.debugWindow.toggleInspect(); + }); + } + + childSandboxBridge.air_Introspector_bridgeLoaded = function(){ + var l = air.Introspector.bridgeCallbacks; + for(var i=0;i /** + * @function createOpenConsoleButton + * @description Creates a button on the top-right corent of the iframe that will open the introspector + */ + createOpenConsoleButton: function(){ + var consoleButton = document.createElement('input'); + consoleButton.onclick = function(){ + air.Introspector.init(true, true, function(){ }); + } + consoleButton.style.zIndex = 1000000; + consoleButton.style.position = 'fixed'; + consoleButton.style.right = '10px'; + consoleButton.style.top = '10px'; + consoleButton.type = 'button'; + consoleButton.value = 'Open Introspector'; + document.body.appendChild(consoleButton); + }, + + /** + * @function registerDOMEventListeners + * @description Registers DOMSubtreeModified, DOMCharacterDataModified, mouseover + */ + registerDOMEventListeners: function(){ + var hoverTimeout = null; + //debugWindow should know about any dom change + document.addEventListener('DOMSubtreeModified', function(e){ + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null&&debugWindow.isLoaded){ + debugWindow.dom3Event(e); + } + }); + document.addEventListener('DOMCharacterDataModified', function(e){ + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null&&debugWindow.isLoaded){ + debugWindow.dom3Event(e); + } + }); + + + document.body.addEventListener('mouseover', function(e){ + if(air.Introspector.inspect){ + setTimeout(function(){ + if(isAppSandbox){ + if(!nativeWindow.active) + nativeWindow.activate(); + } + if(e.srcElement){ + if(isAppSandbox){ + air.Introspector.highlightElement(e.srcElement); + air.Introspector.showHighlightLabels(e.srcElement.id, e.srcElement.nodeName, e.srcElement.outerHTML); + }else{ + air.Introspector.highlightElement(e.srcElement, function(){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_showHighlightLabels(e.srcElement.id, e.srcElement.nodeName, e.srcElement.outerHTML); + }); + }); + } + if(hoverTimeout) clearTimeout(hoverTimeout); + hoverTimeout = setTimeout(function(){ + air.Introspector.init(false, true, function (){ + air.Introspector.debugWindow.setInspectElement(e.srcElement); + }); + }, 100); + }else{ + air.Introspector.hideHighlight(); + } + }, 0); + }else if(isAppSandbox){ + air.Introspector.lastElement = e.srcElement; + } + + }, true); + + //document.body.addEventListener('mouseout', function(e){ + // air.Introspector.hideHighlight(); + //}); + }, + + /** + * @function cleanup + * @description Cleans up the html loader + * + */ + cleanup: function(){ + for(var i=eventListeners.length-1;i>=0;i--){ + var l = eventListeners[i]; + try{ + l[0].removeEventListener(l[1], l[2], l[3]); + }catch(e){} + } + eventListeners = []; + try{ + window.htmlLoader.stage.removeChild(air.Introspector.highlightText); + }catch(e){} + }, + + /** + * @function register + * @description Registers current window in debugger + * + * Captures every XHR object created and any uncaught exception + * and sends it to the debugger + */ + register: function(){ + + if (window.XMLHttpRequest && window.XMLHttpRequest.prototype){ + window.XMLHttpRequest.prototype.debugopen = window.XMLHttpRequest.prototype.open; + window.XMLHttpRequest.prototype.debugsend = window.XMLHttpRequest.prototype.send; + window.XMLHttpRequest.prototype.open = function(method, url, asyncFlag, username, password){ + if(typeof this.doNotDebug=='undefined'){ + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null){ + debugWindow.logNet(this, method, url, asyncFlag); + } + } + return this.debugopen(method, url, asyncFlag, username, password); + }; + window.XMLHttpRequest.prototype.send = function(obj){ + if(typeof this.doNotDebug=='undefined'){ + var self = this; + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null){ + var a = this.onreadystatechange; + this.onreadystatechange = function(){ + if (typeof a == 'function')a.call(self); + debugWindow.logNet(self, 'unknown', '', false); + }; + if(typeof self.doNotDebug=='undefined') + debugWindow.logNetSend(this, obj); + } + var ret = this.debugsend(obj); + if(debugWindow!=null){ + debugWindow.logNetSend(this, obj); + } + return ret; + }else{ + return this.debugsend(obj); + } + + } + } + + if(isAppSandbox){ + air.Introspector.addKeyboardEvents(window.htmlLoader.stage); + air.Introspector.registerUncaughtExceptionListener(); + air.Introspector.registerCloseEventListener(); + air.Introspector.registerCompleteEventListener(); + air.Introspector.registerDeactivateEventListener(); + air.Introspector.createHighlight(); + }else{ + air.Introspector.registerChildSandboxBridge(); + } + air.Introspector.waitForBody(document, function(){ + try{ + if(!isAppSandbox){ air.Introspector.createOpenConsoleButton(); } + air.Introspector.registerDOMEventListeners(); + window.addEventListener('unload', function(){ + try{ + air.Introspector.cleanup(); + if(!isAppSandbox){ + //our debugger can NOT live without its parent + air.Introspector.debugWindow.window.close(); + } + }catch(e){ } + }); + }catch(e){ + if(isAppSandbox){ + runtime.trace(e); + runtime.trace(e.line); + } + air.Introspector.Console.log(e); + } + }); + + + }, + + + /** + * @function registerFrame + * @description Makes the parentSandboxBridge available to frame + */ + registerFrame: function(frame){ + if(typeof frame.contentWindow.parentSandboxBridge=='undefined') + frame.contentWindow.parentSandboxBridge = {}; + + /*frame.contentWindow.parentSandboxBridge.trace = function(a){ + runtime.trace(a); + };*/ + //checking that the bridge is not already there + /*var modified = typeof frame.contentWindow.parentSandboxBridge.air_Introspector_hideHighlight=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_showHighlight=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_drawRect=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_setInspect=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_getWindowTitle=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_checkNativeWindow=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_writeConsoleToClipboard=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_writeConsoleToFile=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_writeConfigFile=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_readConfigFile=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_showHighlightLabels=='undefined' + || typeof frame.contentWindow.parentSandboxBridge.air_Introspector_getFrameId=='undefined';*/ + + frame.contentWindow.parentSandboxBridge.air_Introspector_hideHighlight = function(){ + air.Introspector.hideHighlight(); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_showHighlight = function(rect){ + air.Introspector.showHighlight(rect); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_drawRect = function(rect, tagName){ + var frameRect = air.Introspector.getBorderBox(frame); + var blw = air.Introspector.getIntProp(frame, "border-left-width"); + var btw = air.Introspector.getIntProp(frame, "border-top-width"); + if(frameRect==null) return; + rect.x+=frameRect.x+2*blw; + rect.y+=frameRect.y+2*btw; + air.Introspector.drawRect(rect, tagName); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_setInspect = function(enabled){ + air.Introspector.inspectFrame = enabled?frame:null; + air.Introspector.remoteInspect = enabled; + if(!enabled){ + air.Introspector.hideHighlight(); + } + }; + frame.contentWindow.parentSandboxBridge.air_Introspector_getWindowTitle = function(){ + return document.title; + }; + frame.contentWindow.parentSandboxBridge.air_Introspector_checkNativeWindow = function(title){ + var htmlWindows = air.Introspector.runtime.NativeApplication.nativeApplication.openedWindows; + for(var i=htmlWindows.length-1;i>=0;i--){ + if(htmlWindows[i].title==title){ + return true; + } + } + return false; + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_writeConsoleToClipboard = function(str){ + air.Introspector.writeConsoleToClipboard(str); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_writeConsoleToFile = function(str){ + air.Introspector.writeConsoleToFile(str); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_writeConfigFile = function(config){ + return air.Introspector.writeConfigFile(config, true); + } + + frame.contentWindow.parentSandboxBridge.air_Introspector_readConfigFile = function(){ + return air.Introspector.readConfigFile(true); + } + + frame.contentWindow.parentSandboxBridge.air_Introspector_showHighlightLabels = function(id, nodeName, outerHTML){ + air.Introspector.showHighlightLabels(id, nodeName, outerHTML); + }; + + frame.contentWindow.parentSandboxBridge.air_Introspector_getFrameId = function(){ + return frame.id; + } + + if(typeof frame.contentWindow.childSandboxBridge!='undefined' + && typeof frame.contentWindow.childSandboxBridge.air_Introspector_bridgeLoaded!='undefined'){ + frame.contentWindow.childSandboxBridge.air_Introspector_bridgeLoaded(); + } + + + //return modified; + }, + + /** + * @function waitForBody + * @description Wait until document.body is available + */ + waitForBody: function(document, callback){ + if(document.body){ + callback(); + }else{ + setTimeout(air.Introspector.waitForBody, 10, document, callback); + } + }, + + /** + * @function toggleWindow + * @description Shows/Hides the debug tool + */ + toggleWindow:function(){ + air.Introspector.init(true, false, function(justCreated){ + if(!justCreated) + air.Introspector.debugWindow.nativeWindow.visible ^= true; + }); + + }, + + + /** + * @function init + * @description Makes sure the debug tool is enabled + */ + init: function(showLoader, toggle, callback){ + if(!air.Introspector.canInit()) + return; + + if(typeof showLoader=='undefined') showLoader = false; + if(typeof toggle=='undefined') toggle = true; + + if(isAppSandbox){ + + if(typeof air.Introspector.debugWindow=='undefined' || air.Introspector.debugWindow.nativeWindow.closed){ + delete air.Introspector.debugWindow; + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow!=null && !debugWindow.nativeWindow.closed){ + air.Introspector.debugWindow = debugWindow; + if(toggle){ + air.Introspector.debugWindow.nativeWindow.visible = true; + if(!showLoader){ + nativeWindow.activate(); + } + } + callback(false); + }else{ + air.Introspector.loadDebugger(function(debugWindow){ + air.Introspector.debugWindow = debugWindow; + callback(true); + }, showLoader); + } + }else{ + if(toggle){ + if(showLoader){ + air.Introspector.debugWindow.nativeWindow.activate(); + } + } + callback(false); + } + }else{ + if(typeof activeWindow=='undefined'){ + air.Introspector.registerChildSandboxBridge(); + } + + if(typeof air.Introspector.debugWindow=='undefined'|| + typeof air.Introspector.debugWindow.window.air=='undefined'){ +/* (air.Introspector.debugWindow.isWindowCreated + &&air.Introspector.debugWindow.isLoaded + &&air.Introspector.debugWindow.window + &&!parentSandboxBridge.air_Introspector_checkNativeWindow(air.Introspector.parentWindowTitle + ': '+air.Introspector.debugWindow.window.document.title))){*/ + delete air.Introspector.debugWindow; + + + air.Introspector.loadDebugger(function(debugWindow){ + air.Introspector.debugWindow = debugWindow; + callback(true); + }); +// air.Introspector.debugWindow = new air.Introspector.DebugWindow ({activateDebug: showLoader, activeWindow: window}); + }else if(!air.Introspector.debugWindow.isWindowCreated){ + return; + }else{ + callback(false); + } + } + }, + times:0, //make the window.open page name unique - this is the number of opened and closed introspector windows + /** + * @function tryCreateWindow + * @description window.Open in browser/remote sandbox is not allowed if the action is not iniated by the user (eg. user gesture, mouse click) + * We can only wait for that moment. Until that happends we record all the callbacks and run them when the Introspector is laoded + * @runs in remote sandbox only + */ + tryCreateWindow: function(callbacks){ +// try{ + var self = this; + var w; + var iframeId; + +/* if(typeof parentSandboxBridge=='undefined'){ + air.Introspector.noBridge(function(){ + air.Introspector.tryCreateWindow(callbacks); + }); + return; + }*/ + + air.Introspector.parentWindowTitle = parentSandboxBridge.air_Introspector_getWindowTitle(); + + if(typeof parentSandboxBridge!='undefined'&&typeof parentSandboxBridge.air_Introspector_getFrameId!='undefined') + iframeId = parentSandboxBridge.air_Introspector_getFrameId(); + + air.Introspector.times++; + + if(typeof air.Introspector.config.useAirDebugHtml=='undefined'||air.Introspector.config.useAirDebugHtml==false){ + w = window.open('about:blank', 'debugger'+air.Introspector.times, 'width=640,height=480,resizable=1'); + if(w&&w.document){ + w.isAppSandbox = isAppSandbox; + w.opener = window; + w.iframeId = iframeId; + w.initCallbacks = callbacks; + w.activeWindow = window; + w.isLoaded = false; + w.config = air.Introspector.config; + w.document.write(air.Introspector.contentString); + w.document.close(); + } + }else{ + w = window.open('DebugUI.html', 'debugger'+air.Introspector.times, 'width=640,height=480,resizable=1'); + + if(w&&w.document){ + w.opener = window; + w.iframeId = iframeId; + w.activeWindow = window; + w.config = air.Introspector.config; + w.initCallbacks = callbacks; + w.isLoaded = false; + w.isAppSandbox = isAppSandbox; + } + } + return w; +// }catch(e){ +// alert(e+' '+e.line); +// } + }, + + /** + * @function loadDebugger + * @description Loads the debugger window, register callbacks until it is ready + * @runs in application sandbox only + */ + loadDebugger: function(callback, activateDebug){ + var htmlLoader; + var loadDebugger = arguments.callee; + if(loadDebugger.htmlLoader && typeof loadDebugger.htmlLoader.window.isLoaded != 'undefined'){ + if(loadDebugger.htmlLoader.window.isLoaded){ + callback(loadDebugger.htmlLoader.window.debugWindow); + }else{ + if(loadDebugger.htmlLoader.window.initCallbacks){ + loadDebugger.htmlLoader.window.initCallbacks.push(callback); + }else{ + loadDebugger.initCallbacks.push(callback); + } + } + return; + } + if(typeof loadDebugger.initCallbacks=='undefined'){ + loadDebugger.initCallbacks = [function(){ + delete loadDebugger.initCallbacks; + }, callback]; + }else{ + loadDebugger.initCallbacks.push(callback); + } + if(isAppSandbox){ + htmlLoader = air.Introspector.runtime.HTMLLoader.createRootWindow(false); + air.Introspector.addEventListener(htmlLoader, air.Introspector.runtime.Event.HTML_DOM_INITIALIZE, function(){ + try{ + air.Introspector.removeEventListener(htmlLoader, air.Introspector.runtime.Event.HTML_DOM_INITIALIZE, arguments.callee); + htmlLoader.window.initCallbacks = loadDebugger.initCallbacks; + htmlLoader.window.isLoaded = false; + htmlLoader.window.config = air.Introspector.config; + htmlLoader.window.activateDebug = activateDebug; + htmlLoader.window.isAppSandbox = isAppSandbox; + }catch(e){ + air.Introspector.runtime.trace(e); + air.Introspector.runtime.trace(e.line); + } + }); + htmlLoader.window.isLoaded = false; + + var nativeWindow = htmlLoader.stage.nativeWindow; + nativeWindow.width = 640; + nativeWindow.height = 480; + air.Introspector.addEventListener(htmlLoader, runtime.flash.events.HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION, function(e){ + air.Introspector.logError(e.exceptionValue, {htmlLoader: self.htmlLoader}); + e.preventDefault(); + }); + if(typeof air.Introspector.config.useAirDebugHtml=='undefined'||air.Introspector.config.useAirDebugHtml==false){ + htmlLoader.loadString(air.Introspector.contentString); + }else{ + htmlLoader.load(new air.Introspector.runtime.URLRequest('app:/DebugUI.html')); + } + }else{ + air.Introspector.noBridge(function(){ + var w = air.Introspector.tryCreateWindow(loadDebugger.initCallbacks); + if(w){ + var htmlLoader = {window: w}; + loadDebugger.htmlLoader = htmlLoader; + } + }); + } + loadDebugger.htmlLoader = htmlLoader; + }, + + /** + * @function findDebugWindow + * @description Look up the Introspector in other windows. Maybe somebody else just opened it before us. + */ + findDebugWindow: function(){ + if(isAppSandbox){ + try{ + if(air.Introspector.debugWindow&&air.Introspector.debugWindow.nativeWindow.closed==false) + return air.Introspector.debugWindow; + }catch(e){ + } + try{ + var htmlWindows = air.Introspector.getHtmlWindows(true); + for(var i=htmlWindows.length-1;i>=0;i--){ + try{ + if(typeof htmlWindows[i].htmlLoader.window.air!='undefined' + && typeof htmlWindows[i].htmlLoader.window.air.Introspector!='undefined' + && typeof htmlWindows[i].htmlLoader.window.air.Introspector.debugWindow!='undefined' + && htmlWindows[i].htmlLoader.window.air.Introspector.debugWindow.nativeWindow.closed==false + && htmlWindows[i].htmlLoader.window.isAppSandbox ) + { + return htmlWindows[i].htmlLoader.window.air.Introspector.debugWindow; + } + }catch(e){ + //this window is not initialized yet + //just get next window + } + } + }catch(e){} + }else{ + return air.Introspector.debugWindow; + } + return null; + }, + + //application browser formats + // 0 - text + // 1 - images + // 2 - xml (you may want to add your own xml type here) + formats : { 'png':1, 'gif':1, 'zip':1, 'air':1, 'jpg':1, 'jpeg':1, + 'txt':0, 'html':0, 'js':0, 'xml':2, 'opml':2, 'css':0, 'htm':0, '':0 }, + + + /** + * @function canInit + * @description Check if we got parentSandboxBridge available + * @disabled + */ + canInit: function(){ +/* if(!isAppSandbox&&typeof parentSandboxBridge=='undefined'){ + alert('You need to include AIRIntrospector.js in application sandbox too!'); + return false; + }*/ + return true; + }, + + /** + * @function logArguments + * @description + */ + logArguments: function(args, config){ + if(!air.Introspector.canInit()) return; + config.timestamp = new Date(); + air.Introspector.init(config.type=='error', true, function(){ + air.Introspector.debugWindow.logArguments(args, config); + }); + + }, + /** + * @function logError + * @description + */ + logError: function(error, config){ + air.Introspector.init(false, true, function(){ + air.Introspector.debugWindow.logError(error, config); + }); + }, + + /** + * @function showCssElement + * @description + */ + showCssElement: function(element){ + var debugWindow = air.Introspector.findDebugWindow(); + if(debugWindow){ + debugWindow.showCssElement(element); + } + }, + + /** + * @function findLoader + * @description Finds the first HTMLLoader in flash display object list + */ + findLoader: function (stage){ + try{ + for(var i=stage.numChildren-1;i>=0;i--){ + var child = stage.getChildAt(i); + var str=child.toString(); + if(str=='[object HTMLLoader]'||child.name=="FlexHTMLLoader7"){ + return child; + } + } + for(var i=stage.numChildren-1;i>=0;i--){ + var child = stage.getChildAt(i); + var loader = air.Introspector.findLoader(child); + if(loader!=null) + return loader; + } + }catch(e){ + } + return null; + }, + + /** + * @function getHtmlWindows + * @description Returns an array of all HTML windows + */ + getHtmlWindows: function(includeInspectors){ + if(isAppSandbox){ + var windowNodes = []; + var windows = air.Introspector.runtime.NativeApplication.nativeApplication.openedWindows; + for(var i=windows.length-1;i>=0;i--){ + var loader = air.Introspector.findLoader(windows[i].stage); + if(loader!=null){ + if(typeof includeInspectors=='undefined' && typeof loader.window!='undefined' && typeof loader.window.air!='undefined' && typeof loader.window.air.Introspector!='undefined' && + typeof loader.window.air.Introspector.localIframeDebug != 'undefined' ) + continue; + windowNodes.push({ + nativeWindow: windows[i], + stage: windows[i].stage, + htmlLoader : loader + }); + } + } + return windowNodes; + }else{ + //should not be here + return []; + } + }, + + /** + * @function twoDigits + * @description int 2 string with two digits + */ + twoDigits: function(val){ + if(val<10) return '0'+val; + return val+''; + }, + + /** + * @function escapeHtml + * @description Escapes html in order to display it in html + */ + escapeHtml: function(html){ + return (html+'').replace(/&/g, '&').replace(/"/g, """).replace(//g, '>'); + }, + + tree: { }, + + + /** + * @function isNumberObject + * @description + */ + isNumberObject: function(obj){ + try{ + //can we catch isNaN only for NaN + return (obj+0==obj&&!isNaN(obj)); + }catch(e){ + } + return false; + }, + + /** + * @function isStringObject + * @description + */ + isStringObject: function(obj){ + try{ + return (typeof(obj.match) != "undefined" && obj.match.toString().indexOf("[native code]")>0); + }catch(e){ + } + return false; + }, + + /** + * @function isDateObject + * @description + */ + isDateObject: function(obj){ + try{ + return (typeof(obj.getDate) != "undefined" && obj.getDate.toString().indexOf("[native code]")>0); + }catch(e){ + } + return false; + }, + + /** + * @function isArgumentsObject + * @description + */ + isArgumentsObject: function(obj){ + try{ + return obj.toString()=='[object Arguments]'; + }catch(e){ + } + return false; + }, + + /** + * @function isXMLObject + * @description + */ + isXMLObject: function(obj){ + try{ + if(obj.xmlVersion&&obj.firstChild!=null) + return obj.xmlVersion!=''; + }catch(e){ + } + return false; + }, + + /** + * @function isArrayObject + * @description + */ + isArrayObject: function(obj){ + try{ + return (typeof(obj.push) != "undefined" && obj.push.toString().indexOf("[native code]")>0); + }catch(e){ + } + return false; + }, + + /** + * @function isItemNative + * @description + */ + isItemNative: function(obj){ + try{ + return (typeof(obj.item) != "undefined" && obj.item.toString().indexOf("[native code]")>0); + }catch(e){ + } + return false; + }, + + + /** + * @function dump + * @description + */ + + dump: function (obj, levels, level){ + if(air.Introspector.isArgumentsObject(obj)&&obj.length==1) + return air.Introspector.dump(obj[0]); + if(typeof levels=='undefined') { levels=1; } + if(typeof level=='undefined') { level=0; } + try{ + if(typeof obj=='undefined'){ return '[undefined]'; } + if(obj==null){ return '[null]'; } + var list = []; +// if(air.Introspector.isXMLObject(obj)){ +// disable for the moment +// return; +// } + if(air.Introspector.isStringObject(obj) + ||air.Introspector.isNumberObject(obj) + ||air.Introspector.isDateObject(obj)){ + if(level==0){ + try{ + return obj+''; + }catch(e){ + return e+''; + }; + } + return''; + } + var isItemNative = air.Introspector.isItemNative(obj); + var parseArray = air.Introspector.isArrayObject(obj)||air.Introspector.isArgumentsObject(obj)||isItemNative; + var parseHash = !parseArray || isItemNative; + if (parseArray){ + var l = obj.length; + for(var i=0;i 0;i--) prefix+=' '; + var l = list.length; + var strList = []; + if(parseArray) strList.push(prefix+'[\n'); + else strList.push(prefix+'{\n'); + for(var i=0;i /** + * --------------------------------------------------------------------------------------- + * @extracted This is extracted from spry framework and removed support for other browsers. + * @description Finds the precise position of the dom element node + */ + + /** + * @function camelize + * @description + */ + + camelize : function(stringToCamelize) + { + if (stringToCamelize.indexOf('-') == -1){ + return stringToCamelize; + } + var oStringList = stringToCamelize.split('-'); + var isFirstEntry = true; + var camelizedString = ''; + + for(var i=0; i < oStringList.length; i++) + { + if(oStringList[i].length>0) + { + if(isFirstEntry) + { + camelizedString = oStringList[i]; + isFirstEntry = false; + } + else + { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + } + } + + return camelizedString; + }, + + /** + * @function getStyleProp + * @description + */ + getStyleProp : function(element, prop) + { + var value; + try + { + if (element.style) + value = element.style[air.Introspector.camelize(prop)]; + + if (!value) + { + if (document.defaultView && document.defaultView.getComputedStyle) + { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(prop) : null; + } + else if (element.currentStyle) + { + value = element.currentStyle[air.Introspector.camelize(prop)]; + } + } + } + catch (e) {} + + return value == 'auto' ? null : value; + }, + + + /** + * @function getIntProp + * @description + */ + getIntProp : function(element, prop){ + var a = parseInt(air.Introspector.getStyleProp(element, prop),10); + if (isNaN(a)) + return 0; + return a; + }, + + + /** + * @function getBorderBox + * @description + */ + getBorderBox : function (el, doc) { + doc = doc || document; + if (typeof(el) == 'string') { + el = doc.getElementById(el); + } + + if (!el) { + return false; + } + + if (el.parentNode === null || air.Introspector.getStyleProp(el, 'display') == 'none') { + //element must be visible to have a box + return false; + } + + var ret = {x:0, y:0, width:0, height:0}; + var parent = null; + var box; + + var str = el.nodeName; + + ret.x = el.offsetLeft; + ret.y = el.offsetTop; + ret.width = el.offsetWidth; + ret.height = el.offsetHeight; + + parent = el.offsetParent; + + if (parent != el) { + while (parent) { + ret.x += parent.offsetLeft; + ret.y += parent.offsetTop; + str+=':'+parent.nodeName; + parent = parent.offsetParent; + } + } + + + var blw = air.Introspector.getIntProp(el, "border-left-width"); + var btw = air.Introspector.getIntProp(el, "border-top-width"); + ret.x -= blw; + ret.y -= btw; + // opera & (safari absolute) incorrectly account for body offsetTop + switch (air.Introspector.getStyleProp(el, 'position')){ + case 'absolute': + ret.y -= doc.body.offsetTop; + break; + case 'fixed': + ret.y += doc.body.scrollTop; + ret.x += doc.body.scrollLeft; + break; + }; + + if (el.parentNode) + parent = el.parentNode; + else + parent = null; + + if (parent!=null&&parent.nodeName){ + var cas = parent.nodeName.toUpperCase(); + while (parent && cas != 'HTML') { + cas = parent.nodeName.toUpperCase(); + ret.x -= parent.scrollLeft; + ret.y -= parent.scrollTop; + if (parent.parentNode) + parent = parent.parentNode; + else + parent = null; + } + } + +/* ret.y -= el.ownerDocument.body.scrollTop; + ret.x -= el.ownerDocument.body.scrollLeft; +*/ + // adjust the margin + var gi = air.Introspector.getIntProp; + var btw = gi(el, "margin-top"); + var blw = gi(el, "margin-left"); + var bbw = gi(el, "margin-bottom"); + var brw = gi(el, "margin-right"); + ret.x -= blw; + ret.y -= btw; + ret.height += btw + bbw; + ret.width += blw + brw; + + // air.Introspector.Console.log(ret); + return ret; + }, + + /** + * --------------------------------------------------------------------------------------- + */ + + /** + * @function writeConfigFile + * @description + */ + writeConfigFile: function(config, fromRemoteSandbox){ + if(isAppSandbox){ + var file = runtime.flash.filesystem.File.applicationStorageDirectory.resolvePath('AIRIntrospector'+(fromRemoteSandbox?'Remote':'')+'.cfg'); + var fs = new runtime.flash.filesystem.FileStream(); + fs.open(file, runtime.flash.filesystem.FileMode.WRITE); + fs.writeObject(config); + fs.close(); + }else{ + if(typeof activeWindow=='undefined'){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_writeConfigFile(config); + }); + }else{ + activeWindow.setTimeout(function(){ + activeWindow.air.Introspector.writeConfigFile(config); + }, 0); + } + } + }, + + + + /** + * @function readConfigFile + * @description + */ + readConfigFile: function (fromRemoteSandbox, callback){ + if(isAppSandbox){ + var file = runtime.flash.filesystem.File.applicationStorageDirectory.resolvePath('AIRIntrospector'+(fromRemoteSandbox?'Remote':'')+'.cfg'); + if(file.exists){ + var fs = new runtime.flash.filesystem.FileStream(); + fs.open(file, runtime.flash.filesystem.FileMode.READ); + var config = fs.readObject(); + fs.close(); + return config; + } + }else{ + if(typeof activeWindow=='undefined'){ + air.Introspector.noBridge(function(){ + var config = parentSandboxBridge.air_Introspector_readConfigFile(); + callback(config); + }); + }else{ + activeWindow.setTimeout(function(){ + if(typeof activeWindow!='undefined'){ + var config = activeWindow.air.Introspector.readConfigFile(true, function(config){ + setTimeout(function(){ callback(config); }); + }); + } + }); + } + } + return {}; + }, + + + + /** + * @function writeConsoleToClipboard + * @description + */ + + writeConsoleToClipboard: function(str){ + if(isAppSandbox){ + runtime.flash.desktop.Clipboard.generalClipboard.clear(); + runtime.flash.desktop.Clipboard.generalClipboard.setData(runtime.flash.desktop.ClipboardFormats.TEXT_FORMAT, + str, false); + }else{ + if(typeof activeWindow=='undefined'){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_writeConsoleToClipboard(str); + }); + }else{ + activeWindow.setTimeout(function(){ + activeWindow.air.Introspector.writeConsoleToClipboard(str); + }); + } + } + }, + + + /** + * @function writeConsoleToFile + * @description + */ + writeConsoleToFile: function(str){ + if(isAppSandbox){ + var file = runtime.flash.filesystem.File.desktopDirectory; + var self = this; + file.addEventListener(runtime.flash.events.Event.SELECT, function(evt){ + var newFile = evt.target; + var stream = new runtime.flash.filesystem.FileStream(); + stream.open(newFile, runtime.flash.filesystem.FileMode.WRITE); + stream.writeUTFBytes(str); + stream.close(); + }); + file.browseForSave('Console dump file...'); + }else{ + if(typeof activeWindow=='undefined'){ + air.Introspector.noBridge(function(){ + parentSandboxBridge.air_Introspector_writeConsoleToFile(str); + }); + }else{ + activeWindow.setTimeout(function(){ + activeWindow.air.Introspector.writeConsoleToFile(str); + }); + } + } + }, + + + + + /** + * @function noBridge + * @description Alerts the user that no parent sandbox bridge is installed + */ + noBridge: function(callback){ + try{ + callback(); + return; + }catch(e){ + air.Introspector.bridgeCallbacks.push(callback); + air.Introspector.registerChildSandboxBridge(); + setTimeout(function(){ + throw { air_Introspector_setParentSandboxBridge: true, air_Introspector_version: air.Introspector.version , toString: function(){ return 'You need to include AIRIntrospector.js in your application sandbox.'; } }; + }, 0); + } + + }, + + /** + * @function noChildBridge + * @description Alerts the user that no child sandbox bridge is installed + */ + noChildBridge: function(iframe){ + if(!air.Introspector.secondBridgeTry){ + var iframeStr = ''; + if(typeof iframe!='undefined'){ + iframeStr = " Check the following iframe [id: "+iframe.id+"]"; + } + alert('Child sandbox bridge is not defined or has been rewritten. You need to include AIRIntrospector.js in child sandbox.'+iframeStr); + air.Introspector.secondBridgeTry = true; + } + }, + + +});//------------------------------------------------------------------------------------------------------------------------------------------------------- +air.Introspector.version = '0.15.88'; +})(); + + + + +air.Introspector.contentString = '\n\n\n\n ADOBE AIR HTML\/JS Application Introspector<\/title>\n