You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/09/03 02:17:49 UTC
[16/30] Radii8 code base as accepted by IP Clearance
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as b/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
new file mode 100644
index 0000000..c179e86
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/HTMLDocumentExporter.as
@@ -0,0 +1,1370 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.flexcapacitor.utils {
+ import com.flexcapacitor.model.IDocument;
+ import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+ import com.flexcapacitor.views.supportClasses.Styles;
+
+ import flash.display.BitmapData;
+ import flash.display.DisplayObject;
+ import flash.display.JPEGEncoderOptions;
+ import flash.display.PNGEncoderOptions;
+ import flash.geom.Rectangle;
+ import flash.utils.ByteArray;
+ import flash.utils.Dictionary;
+ import flash.utils.getTimer;
+
+ import mx.core.IUIComponent;
+ import mx.core.IVisualElement;
+ import mx.core.IVisualElementContainer;
+ import mx.graphics.codec.JPEGEncoder;
+ import mx.graphics.codec.PNGEncoder;
+ import mx.styles.IStyleClient;
+ import mx.utils.Base64Encoder;
+
+ import spark.components.BorderContainer;
+ import spark.components.HGroup;
+ import spark.components.supportClasses.GroupBase;
+ import spark.layouts.BasicLayout;
+ import spark.layouts.HorizontalLayout;
+ import spark.layouts.TileLayout;
+ import spark.layouts.VerticalLayout;
+ import spark.utils.BitmapUtil;
+
+ /**
+ * Exports a document to HTML
+ * */
+ public class HTMLDocumentExporter extends DocumentExporter {
+
+ public function HTMLDocumentExporter() {
+
+ }
+
+ /**
+ * Sets explicit size regardless if size is explicit
+ * */
+ public var setExplicitSize:Boolean = true;
+
+ /**
+ * Sets styles inline
+ * */
+ public var useInlineStyles:Boolean;
+
+ /**
+ * Name of token in the template that is replaced by the
+ * */
+ public var contentToken:String = "<!--template_content-->";
+
+ /**
+ * CSS to add to
+ * */
+ public var css:String;
+
+ /**
+ * Adds border box CSS
+ * */
+ public var borderBoxCSS:String;
+
+ /**
+ * Show outline
+ * */
+ public var showBordersCSS:String;
+
+ /**
+ * Zoom CSS
+ * */
+ public var zoomCSS:String;
+
+ /**
+ * Page zoom level
+ * */
+ public var scaleLevel:Number;
+
+ /**
+ * CSS for SVG button
+ * */
+ public var buttonCSS:String;
+
+ public var buttonCSS2:String;
+
+ public var stylesheets:String;
+
+ public var template:String;
+
+ /**
+ * Creates a snapshot of the application and sets it as the background image
+ * */
+ public var showScreenshotBackground:Boolean = false;
+
+ /**
+ * Alpha of the background image
+ * */
+ public var backgroundImageAlpha:Number = .5;
+
+ /**
+ * Used to create PNG images
+ * */
+ public var pngEncoder:PNGEncoder;
+
+ /**
+ * Used to create JPEG images
+ * */
+ public var jpegEncoder:JPEGEncoder;
+
+ /**
+ * Extension of the document when exporting to a file.
+ * */
+ public var extension:String;
+
+ /**
+ * Indicates when the user has typed in the text area
+ * */
+ [Bindable]
+ public var isCodeModifiedByUser:Boolean;
+
+ /**
+ * Show borders around HTML elements
+ * */
+ [Bindable]
+ public var showBorders:Boolean;
+
+ /**
+ * Use SVG button class
+ * */
+ [Bindable]
+ public var useSVGButtonClass:Boolean = true;
+
+ /**
+ * Show full HTML page source
+ * */
+ [Bindable]
+ public var showFullHTMLPageSource:Boolean = false;
+
+ /**
+ * Last source code
+ * */
+ [Bindable]
+ public var sourceCode:String;
+
+ public var includePreviewCode:Boolean;
+
+ public var horizontalPositions:Array = ["x","left","right","horizontalCenter"];
+ public var horizontalCenterPosition:String = "horizontalCenter";
+ public var verticalPositions:Array = ["y","top","bottom","verticalCenter"];
+ public var verticalCenterPosition:String = "verticalCenter";
+ public var sizesPositions:Array = ["width","height"];
+
+ public var addZoom:Boolean;
+ public var output:String = "";
+ public var cssOutput:String = "";
+ public var wrapInPreview:Boolean;
+
+ /**
+ *
+ * */
+ public var useWrapperDivs:Boolean;
+ public var showOnlyHTML:Boolean;
+ public var showOnlyCSS:Boolean;
+
+ /**
+ * @inheritDoc
+ * */
+ public function export(iDocument:IDocument, reference:Boolean = false, target:Object = null):String {
+ var XML1:XML;
+ var application:Object = iDocument ? iDocument.instance : null;
+ var targetDescription:ComponentDescription;
+ var componentTree:ComponentDescription;
+ var zoomOutput:String;
+ var xml:XML;
+
+ componentTree = iDocument.componentDescription;
+ cssOutput = "";
+
+ // find target in display list and get it's code
+ targetDescription = DisplayObjectUtils.getTargetInComponentDisplayList(target, componentTree);
+
+
+ if (targetDescription) {
+
+ // see the top of this document on how to generate source code
+ getAppliedPropertiesFromHistory(iDocument, targetDescription);
+
+ if (!reference) {
+ //output = getHTMLOutputString(iDocument, iDocument.componentDescription);
+
+ var includePreviewCode:Boolean = true;
+ var tabDepth:String = "";
+
+ if (showFullHTMLPageSource) {
+ tabDepth = ""; //"\t\t\t";
+ }
+
+ output = getHTMLOutputString(iDocument, targetDescription, true, tabDepth, includePreviewCode);
+ output += "\n";
+
+ var applicationContainerID:String = "applicationContainer";
+ var zoomInID:String = wrapInPreview ? application.name : applicationContainerID;
+
+ // not enabled at the moment - see code inspector
+ if (wrapInPreview) {
+ var wrapper:String = "<div id=\"" + applicationContainerID +"\" style=\"position:absolute;";
+ //output += "width:" + (component.instance.width + 40) + "px;";
+ wrapper += "width:100%;";
+ wrapper += "height:" + (targetDescription.instance.height + 40) + "px;";
+ wrapper += "background-color:#666666;\">\n" + output + "</div>";
+ output = wrapper;
+ }
+
+ if (stylesheets) {
+ output += "\n" + stylesheets;
+ }
+
+ var styles:String = "";
+
+ if (showOnlyCSS) {
+
+ // SPOT NUMBER 1
+ // you have to include css options in another spot as well below
+ // SEE SPOT NUMBER 2
+ // refactor
+ if (!useInlineStyles) {
+ styles = "\n" + cssOutput;
+ }
+
+ if (css) {
+ styles += "\n" + css;
+ }
+
+ if (useSVGButtonClass) {
+ styles += "\n" + buttonCSS2;
+ }
+
+ if (showBorders) {
+ styles += "\n" + showBordersCSS;
+ }
+
+ if (addZoom) {
+ //zoomOutput = zoomCSS.replace(/IFRAME_ID/g, "#" + application.name);
+ zoomOutput = zoomCSS.replace(/IFRAME_ID/g, "#" + zoomInID);
+ zoomOutput = zoomOutput.replace(/ZOOM_VALUE/g, iDocument.scale);
+ styles += "\n" + zoomOutput;
+ }
+
+ output = styles;
+ }
+ else if (showOnlyHTML) {
+
+ if (showFullHTMLPageSource) {
+ output = template.replace(contentToken, output);
+ }
+ }
+ else {
+ // THIS IS SPOT NUMBER 2
+ // You have to include CSS options in another place as well
+ // see spot number 1
+ if (!useInlineStyles) {
+ styles += "\n" + cssOutput;
+ }
+
+ if (css) {
+ styles += "\n" + css;
+ }
+
+ if (useSVGButtonClass) {
+ styles += "\n" + buttonCSS2;
+ }
+
+ if (showBorders) {
+ styles += "\n" + showBordersCSS;
+ }
+
+
+ if (addZoom) {
+ //zoomOutput = zoomCSS.replace(/IFRAME_ID/g, "#" + application.name);
+ zoomOutput = zoomCSS.replace(/IFRAME_ID/g, "#" + zoomInID);
+ zoomOutput = zoomOutput.replace(/ZOOM_VALUE/g, iDocument.scale);
+ styles += "\n" + zoomOutput;
+ }
+
+
+
+
+ // add styles in style tags and add to output
+ if (styles!="") {
+ output += "\n" + wrapInStyleTags(styles);
+ }
+
+
+
+ if (showFullHTMLPageSource) {
+ output = template.replace(contentToken, output);
+ }
+ }
+
+
+ isValid = XMLUtils.isValidXML(output);
+
+ if (!isValid) {
+ error = XMLUtils.validationError;
+ errorMessage = XMLUtils.validationErrorMessage;
+ }
+ else {
+ error = null;
+ errorMessage = null;
+ }
+
+ var checkValidXML:Boolean = false;
+ if (checkValidXML) {
+ try {
+ // don't use XML for HTML output because it converts this:
+ // <div ></div>
+ // to this:
+ // <div />
+ // and that breaks the html page
+
+ // we can still try it to make sure it's valid
+ // we could be saving CPU cycles here?
+ var time:int = getTimer();
+
+ // check if valid XML
+ // we could also use XMLUtils.isValid but this is also for formatting
+ xml = new XML(output);
+ time = getTimer() -time;
+ //trace("xml validation parsing time=" + time);
+ sourceCode = output;
+ }
+ catch (error:Error) {
+ // Error #1083: The prefix "s" for element "Group" is not bound.
+ // <s:Group x="93" y="128">
+ // <s:Button x="66" y="17"/>
+ //</s:Group>
+ time = getTimer() -time;
+ //trace("xml validation parsing time with error=" + time);
+ sourceCode = output;
+ }
+ }
+ else {
+ sourceCode = output;
+ }
+ }
+ else {// this should not be here - it should be in DocumentData
+ XML1 = <document />;
+ XML1.@host = iDocument.host;
+ XML1.@id = iDocument.id;
+ XML1.@name = iDocument.name;
+ XML1.@uid = iDocument.uid;
+ XML1.@uri = iDocument.uri;
+ output = XML1.toXMLString();
+ }
+ }
+
+ return output;
+ }
+
+
+
+ /**
+ * Gets the formatted output from a component.
+ * Yes, this is a mess. It needs refactoring.
+ * I wanted to see if I could quickly generate valid HTML
+ * from the component tree.
+ *
+ * There is partial work with CSS properties objects but those are not implemented yet.
+ * */
+ public function getHTMLOutputString(iDocument:IDocument, component:ComponentDescription, addLineBreak:Boolean = false, tabs:String = "", includePreview:Boolean = false):String {
+ var property:Object = component.properties;
+ var componentName:String = component.name ? component.name.toLowerCase() : "";
+ var htmlName:String = componentName ? componentName : "";
+ var componentChild:ComponentDescription;
+ var contentToken:String = "[child_content]";
+ var styleValue:String = "position:absolute;";
+ var styles:Styles = new Styles();
+ var wrapperStyles:Styles = new Styles();
+ var isHorizontalLayout:Boolean;
+ var isVerticalLayout:Boolean;
+ var isBasicLayout:Boolean;
+ var isTileLayout:Boolean;
+ var childContent:String = "";
+ var wrapperTag:String = "";
+ var centeredHorizontally:Boolean;
+ var wrapperTagStyles:String = "";
+ var properties:String = "";
+ var outlineStyle:String;
+ var output:String = "";
+ var type:String = "";
+ var instance:Object;
+ var numElements:int;
+ var index:int;
+ var value:*;
+ var gap:int;
+
+
+ // we are setting the styles in a string now
+ // the next refactor should use the object so we can output to CSS
+ styles.position = Styles.ABSOLUTE;
+ outlineStyle = "outline:1px solid red;"; // we should enable or disable outlines via code not markup on in the export
+
+ // get layout positioning
+ if (component.parent && component.parent.instance is IVisualElementContainer) {
+
+ if (component.parent.instance.layout is HorizontalLayout) {
+ isHorizontalLayout = true;
+ styleValue = styleValue.replace("absolute", "relative");
+ //styleValue += "vertical-align:middle;";
+ styles.position = Styles.RELATIVE;
+ index = GroupBase(component.parent.instance).getElementIndex(component.instance as IVisualElement);
+ numElements = GroupBase(component.parent.instance).numElements;
+ wrapperTagStyles += hasExplicitSizeSet(component.instance as IVisualElement) ? "display:inline-block;" : "display:inline;";
+ wrapperStyles.display = hasExplicitSizeSet(component.instance as IVisualElement) ? Styles.INLINE_BLOCK : Styles.INLINE;
+ gap = HorizontalLayout(component.parent.instance.layout).gap - 4;
+
+
+ if (index<numElements-1 && numElements>1) {
+ //wrapperTagStyles += "padding-right:" + gap + "px;";
+ wrapperTagStyles += Styles.MARGIN_RIGHT+":" + gap + "px;";
+ wrapperStyles.marginRight = gap + "px";
+
+ }
+
+ wrapperTag = "div";
+ }
+ else if (component.parent.instance.layout is TileLayout) {
+ //isHorizontalLayout = true;
+ isTileLayout = true;
+ styleValue = styleValue.replace("absolute", "relative");
+ styles.position = Styles.RELATIVE;
+ index = GroupBase(component.parent.instance).getElementIndex(component.instance as IVisualElement);
+ numElements = GroupBase(component.parent.instance).numElements;
+ wrapperTagStyles += hasExplicitSizeSet(component.instance as IVisualElement) ? "display:inline-block;" : "display:inline;";
+ wrapperStyles.display = hasExplicitSizeSet(component.instance as IVisualElement) ? Styles.INLINE_BLOCK : Styles.INLINE;
+ gap = TileLayout(component.parent.instance.layout).horizontalGap - 4;
+
+ if (index<numElements-1 && numElements>1) {
+ //wrapperTagStyles += "padding-right:" + gap + "px;";
+ // using "margin-right" because if you set a fixed width padding was not doing anything
+ wrapperTagStyles += Styles.MARGIN_RIGHT+":" + gap + "px;";
+ //wrapperStyles.paddingRight = gap + "px";
+ wrapperStyles.marginRight = gap + "px";
+ }
+
+ wrapperTag = "div";
+ }
+
+ else if (component.parent.instance.layout is VerticalLayout) {
+ isVerticalLayout = true;
+ styleValue = styleValue.replace("absolute", "relative");
+ styles.position = Styles.RELATIVE;
+ index = GroupBase(component.parent.instance).getElementIndex(component.instance as IVisualElement);
+ numElements = GroupBase(component.parent.instance).numElements;
+ gap = VerticalLayout(component.parent.instance.layout).gap;
+
+
+ if (index<numElements-1 && numElements>1) {
+ //wrapperTagStyles += "padding-bottom:" + gap + "px;";
+ wrapperTagStyles += Styles.MARGIN_BOTTOM+":" + gap + "px;";
+ //wrapperStyles.paddingBottom = gap + "px";
+ wrapperStyles.marginBottom = gap + "px";
+ }
+
+ wrapperTag = "div";
+ }
+
+ else if (component.parent.instance.layout is BasicLayout) {
+ isBasicLayout = true;
+
+
+
+ //styleValue = styleValue.replace("absolute", "relative");
+ //styles.position = Styles.RELATIVE;
+ /*index = GroupBase(component.parent.instance).getElementIndex(component.instance as IVisualElement);
+ numElements = GroupBase(component.parent.instance).numElements;
+ gap = BasicLayout(component.parent.instance.layout).gap;*/
+
+ /*if (index<numElements-1 && numElements>1) {
+ wrapperTagStyles += "padding-bottom:" + gap + "px";
+ }
+
+ wrapperTag = "div";*/
+ }
+ }
+
+ // constraints take higher authority
+ var isHorizontalSet:Boolean;
+ var isVerticalSet:Boolean;
+
+ // loop through assigned properties
+ for (var propertyName:String in property) {
+ value = property[propertyName];
+
+ if (value===undefined || value==null) {
+ continue;
+ }
+
+
+ if (verticalPositions.indexOf(propertyName)!=-1 && !isVerticalSet) {
+ styleValue = getVerticalPositionHTML(component.instance as IVisualElement, styles, styleValue, isBasicLayout);
+ isVerticalSet = true;
+ }
+ else if (horizontalPositions.indexOf(propertyName)!=-1 && !isHorizontalSet) {
+ styleValue = getHorizontalPositionHTML(component.instance as IVisualElement, styles, styleValue, isBasicLayout);
+ isHorizontalSet = true;
+ }
+
+ }
+
+
+ if (htmlName) {
+
+ // create code for element type
+ if (htmlName=="application") {
+ htmlName = "div";
+
+ // container div
+ if (includePreview) {
+ /*output = "<div style=\"position:absolute;";
+ //output += "width:" + (component.instance.width + 40) + "px;";
+ output += "width:100%;";
+ output += "height:" + (component.instance.height + 40) + "px;";
+ output += "background-color:#666666;\">";*/
+ output += "<div";
+ //output = getNameString(component.instance, output);
+ output += properties ? " " + properties : " ";
+ output = getIdentifierAttribute(component.instance, output);
+ styleValue = styleValue.replace("absolute", "relative");
+ styles.position = Styles.ABSOLUTE;
+ styleValue += "width:" + component.instance.width+ "px;";
+ styleValue += "height:" + component.instance.height+ "px;";
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ styleValue += "margin:0 auto;";
+ styleValue += "left:8px;top:14px;";
+ styleValue += "overflow:auto;";
+ styleValue += "background-color:" + DisplayObjectUtils.getColorInHex(component.instance.getStyle("backgroundColor"), true) + ";";
+ //output += properties ? " " : "";
+ output += setStyles(component.instance, styleValue);
+
+
+ if (showScreenshotBackground) {
+ var backgroundImageID:String = "backgroundComparisonImage";
+ var imageDataFormat:String = "png";//"jpeg";
+ var imageData:String = getDataURI(component.instance, imageDataFormat);
+ var backgroundSnapshot:String = "\n" + tabs + "\t" + "<img ";
+ backgroundSnapshot += "id=\"" + backgroundImageID +"\"";
+ backgroundSnapshot += " src=\"" + imageData + "\" ";
+
+ output += backgroundSnapshot;
+ output += setStyles("#"+backgroundImageID, "position:absolute;opacity:"+backgroundImageAlpha+";top:0px;left:0px;", true);
+ /* background-image didn't work in FF on mac. didn't test on other browsers
+ //trace(imageData);
+ var imageDataStyle:String = "#" + getIdentifierOrName(target) + " {\n";
+ //imageDataStyle = "\tbackground-image: url(data:image/jpeg;base64,"+imageData+");";
+ imageDataStyle += "\tbackground-repeat: no-repeat;\n";
+ imageDataStyle += "\tbackground-image: url(data:image/"+imageDataFormat+";base64,"+imageData+");\n}";
+ styles += "\n" + imageDataStyle;*/
+ }
+
+ output += contentToken;
+ //output += "\n </div>\n</div>";
+ output += "\n</div>";
+
+ }
+ else {
+ //output = "<div style=\"position: absolute;width:100%;height:100%;background-color:#666666;\">";
+ output = "<div";
+ output += properties ? " " + properties : " ";
+ output = getIdentifierAttribute(component.instance, output);
+ //output = getNameString(component.instance, output);
+ output += properties ? " " + properties : "";
+ styleValue += "width:" + component.instance.width+ "px;";
+ styleValue += "height:" + component.instance.height+ "px;";
+ styleValue += "border:1px solid black";
+ styleValue += "background-color:" + DisplayObjectUtils.getColorInHex(component.instance.getStyle("backgroundColor"), true) + ";";
+ //output += properties ? " " : "";
+ output += setStyles(component.instance, styleValue);
+ output += contentToken;
+ output += "\n</div>";
+ }
+ }
+
+ else if (htmlName=="group" || htmlName=="vgroup") {
+ htmlName = "div";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<div " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ output += properties ? " " : "";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ output += setStyles(component.instance, styleValue);
+ output += contentToken;
+ output += "\n" + tabs + "</div>";
+ output += getWrapperTag(wrapperTag, true);
+ }
+
+ else if (htmlName=="bordercontainer") {
+ htmlName = "div";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<div " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ output += properties ? " " : "";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += getBorderString(component.instance as BorderContainer);
+ //styleValue += getColorString(component.instance as BorderContainer);
+ //styles += component.instance as BorderContainer);
+
+ output += setStyles(component.instance, styleValue);
+ output += contentToken;
+ output += "\n" + tabs + "</div>";
+ output += getWrapperTag(wrapperTag, true);
+
+ }
+
+ else if (htmlName=="hgroup" || htmlName=="tilegroup") {
+ htmlName = "div";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<div " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+
+ //styleValue = getSizeString(component.instance as IVisualElement, styleValue);
+ if (component.name=="HGroup") {
+ styleValue += "width:" + Math.max(HGroup(component.instance).contentWidth, component.instance.width)+ "px;";
+ }
+ else {
+ styleValue += "width:" + component.instance.width+ "px;";
+ }
+
+ styleValue += "height:" + component.instance.height+ "px;";
+ //var verical:String = component.instance.getStyle("verticalAlign");
+ var vericalAlign:String = component.instance.verticalAlign;
+ if (componentName.toLowerCase()=="hgroup" && vericalAlign=="middle") {
+ styleValue += "line-height:" + component.instance.height + "px;";
+ }
+
+ output += properties ? " " : "";
+ output += setStyles(component.instance, styleValue);
+ output += contentToken;
+ output += "\n" + tabs + "</div>";
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="button" || htmlName=="togglebutton") {
+ htmlName = "button";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<input " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ output += " type=\"" + htmlName.toLowerCase() + "\"" ;
+ output += properties ? " " + properties : "";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ output += " value=\"" + component.instance.label + "\"";
+ output += " class=\"buttonSkin\"";
+ output += setStyles(component.instance, styleValue);
+
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="checkbox") {
+ if (component.instance.label!="") {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<label ";
+ output = getIdentifierAttribute(component.instance, output, "_Label");
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ //styleValue += "width:" + (component.instance.width + 6)+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ output += setStyles("#"+getIdentifierOrName(component.instance, true, "_Label"), styleValue);
+ output += "<input ";
+ output = getIdentifierAttribute(component.instance, output);
+ output += " type=\"" + htmlName.toLowerCase() + "\" ";
+ output += "/>" ;
+ }
+ else {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<input " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ output += " type=\"" + htmlName.toLowerCase() + "\" " + properties;
+ //styleValue = getSizeString(component.instance as IVisualElement, styleValue);
+ output += setStyles(component.instance, styleValue);
+ }
+
+ if (component.instance.label!="") {
+ output += " " + component.instance.label + "</label>";
+ }
+
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="radiobutton") {
+ htmlName = "radio";
+ if (component.instance.label!="") {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<label ";
+ output = getIdentifierAttribute(component.instance, output, "_Label");
+ //styleValue += "width:" + (component.instance.width + 8)+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ output += setStyles("#"+getIdentifierOrName(component.instance, true, "_Label"), styleValue);
+ output += "<input type=\"radio\" " ;
+ output = getIdentifierAttribute(component.instance, output);
+ //styleValue = getSizeString(component.instance as IVisualElement, styleValue);
+ output += "/>" ;
+ }
+ else {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<input type=\"" + htmlName.toLowerCase() + "\" " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ //styleValue = getSizeString(component.instance as IVisualElement, styleValue);
+ output += setStyles(component.instance, styleValue);
+ }
+
+ if (component.instance.label!="") {
+ output += " " + component.instance.label + "</label>";
+ }
+
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="textinput" || htmlName=="combobox") {
+ htmlName = "input";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<input ";
+ output = getIdentifierAttribute(component.instance, output);
+ output += " type=\"input\" " + properties;
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ styleValue += "padding:0;border:1px solid " + DisplayObjectUtils.getColorInHex(component.instance.getStyle("borderColor"), true) + ";";
+
+ if (htmlName=="combobox") {
+ output += " list=\"listdata\"";
+ //<datalist id="listData">
+ //<option value="value 1">
+ //<option value="value 2">
+ //<option value="value 3">
+ //</datalist>
+ }
+ output += setStyles(component.instance, styleValue);
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="dropdownlist") {
+ htmlName = "select";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<select ";
+ output = getIdentifierAttribute(component.instance, output);
+ output += " type=\"input\" " + properties;
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ styleValue += "padding:0;border:1px solid " + DisplayObjectUtils.getColorInHex(component.instance.getStyle("borderColor"), true) + ";";
+
+ output += setStyles(component.instance, styleValue);
+ output += "</select>";
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="linkbutton") {
+ htmlName = "a";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<a " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ //styles += getBorderString(component.instance as IStyleClient);
+
+ output += properties ? " " : "";
+ output += setStyles(component.instance, styleValue);
+ output += component.instance.label;
+ output += "</a>";
+ output += getWrapperTag(wrapperTag, true);
+ }
+ else if (htmlName=="label") {
+ htmlName = "label";
+ if (useWrapperDivs) {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ }
+ else {
+ output = tabs;
+ }
+ output += "<label " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet, isVerticalSet);
+ //styleValue += wrapperTagStyles;
+ styleValue += "color:" + DisplayObjectUtils.getColorInHex(component.instance.getStyle("color"), true) + ";";
+ styleValue += "font-weight:" + component.instance.getStyle("fontWeight") + ";";
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ styleValue += "line-height:" + "1;";
+ //styles += getBorderString(component.instance as IStyleClient);
+
+ output += properties ? " " : "";
+ // remove wrapperTagStyles since we are trying to not use wrapper tags
+ //output += setStyles(component.instance, styleValue+wrapperTagStyles);
+ output += setStyles(component.instance, wrapperTagStyles+styleValue);
+ output += component.instance.text;
+ output += "</label>";
+ if (useWrapperDivs) {
+ output += getWrapperTag(wrapperTag, true);
+ }
+ }
+ else if (htmlName=="image") {
+ htmlName = "img";
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<img " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ output += properties ? " " : "";
+
+ if (component.instance.source is BitmapData) {
+ output += " src=\"" + getDataURI(component.instance.source, "jpeg") + "\"";
+ }
+ else if (component.instance.source is String) {
+ output += " src=\"" + component.instance.source + "\"";
+ }
+ output += setStyles(component.instance, styleValue);
+ output += getWrapperTag(wrapperTag, true);
+ }
+
+ else {
+ // show placeholder NOT actual component
+ htmlName = "label";
+ if (useWrapperDivs) {
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ }
+ else {
+ output = tabs;
+ }
+ output += "<label " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ //styleValue += "width:" + component.instance.width+ "px;";
+ //styleValue += "height:" + component.instance.height+ "px;";
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet, isVerticalSet);
+ //styleValue += wrapperTagStyles;
+ styleValue += "color:" + DisplayObjectUtils.getColorInHex(component.instance.getStyle("color"), true) + ";";
+ styleValue += "font-weight:" + component.instance.getStyle("fontWeight") + ";";
+ styleValue += "font-family:" + component.instance.getStyle("fontFamily") + ";";
+ styleValue += "font-size:" + component.instance.getStyle("fontSize") + "px;";
+ styleValue += "line-height:" + "1;";
+ //styles += getBorderString(component.instance as IStyleClient);
+
+ output += properties ? " " : "";
+ // remove wrapperTagStyles since we are trying to not use wrapper tags
+ //output += setStyles(component.instance, styleValue+wrapperTagStyles);
+ output += setStyles(component.instance, wrapperTagStyles+styleValue);
+ output += getIdentifierOrName(component.instance);
+ output += "</label>";
+ if (useWrapperDivs) {
+ output += getWrapperTag(wrapperTag, true);
+ }
+ /*
+ output = tabs + getWrapperTag(wrapperTag, false, wrapperTagStyles);
+ output += "<" + htmlName.toLowerCase() + " " + properties;
+ output = getIdentifierAttribute(component.instance, output);
+ styleValue = getSizeString(component.instance as IVisualElement, styleValue, isHorizontalSet);
+ output += properties ? " " : "";
+ output += setStyles(component.instance, styleValue);
+ output += getWrapperTag(wrapperTag, true);*/
+ }
+
+
+ // add children
+ if (component.children && component.children.length>0) {
+ //output += ">\n";
+
+ for (var i:int;i<component.children.length;i++) {
+ componentChild = component.children[i];
+ getAppliedPropertiesFromHistory(iDocument, componentChild);
+ if (i>0) {
+ childContent += "\n";
+ }
+ childContent += getHTMLOutputString(iDocument, componentChild, false, tabs + "\t");
+ }
+
+ output = output.replace(contentToken, "\n" + childContent);
+
+ }
+ else {
+ output = output.replace(contentToken, "\n");
+ }
+ }
+ else {
+ output = "";
+ }
+
+ return output;
+ }
+
+ /**
+ * Get a tag with less than or greater than wrapped around it.
+ * */
+ private function getWrapperTag(wrapperTag:String = "", end:Boolean = false, styles:String = ""):String {
+ var output:String = "";
+
+ if (wrapperTag=="") return "";
+
+ if (end) {
+ output = "</" + wrapperTag + ">";
+ return output;
+ }
+
+ output += "<" + wrapperTag;
+
+ if (styles) {
+ output += " style=\"" + styles + "\"" ;
+ }
+
+ output += ">";
+
+ return output;
+ }
+
+ /**
+ * Get width and height styles
+ * If explicit width is set then we should use inline-block
+ * because inline does not respect width and height
+ * */
+ public function getSizeString(instance:IVisualElement, styleValue:String = "", isHorizontalAlignSet:Boolean = false, isVerticalSet:Boolean = false):String {
+ var hasExplicitSize:Boolean;
+ var hasBorder:Boolean;
+ var border:int;
+
+ if (instance is IStyleClient && IStyleClient(instance).getStyle("borderWeight")) {
+
+ }
+
+ if (!isNaN(instance.percentWidth)) {
+ styleValue += "width:" + instance.percentWidth + "%;";
+ }
+ else if ("explicitWidth" in instance) {
+ if (Object(instance).explicitWidth!=null && !isNaN(Object(instance).explicitWidth)
+ || setExplicitSize) {
+ styleValue += "width:" + instance.width + "px;";
+ hasExplicitSize = true;
+ }
+ }
+ else {
+ //styleValue += "width:" + instance.width + "px;";
+ }
+
+ if (!isNaN(instance.percentHeight)) {
+ styleValue += "height:" + instance.percentHeight + "%;";
+ }
+ else if ("explicitHeight" in instance) {
+ if (Object(instance).explicitHeight!=null && !isNaN(Object(instance).explicitHeight)
+ || setExplicitSize) {
+ styleValue += "height:" + instance.height + "px;";
+ hasExplicitSize = true;
+ }
+ }
+ else {
+ //styleValue += "height:" + instance.height + "px;";
+ }
+
+
+ // If explicit width is set then we should use inline-block
+ // because inline does not respect width and height
+ if (!isHorizontalAlignSet && hasExplicitSize) {
+ styleValue += "display:" + Styles.INLINE_BLOCK + ";";
+ }
+
+ return styleValue;
+
+ }
+
+ /**
+ * Checks if size is explicitly set
+ * If explicit width is set then we should use inline-block
+ * because inline does not respect width and height
+ * */
+ public function hasExplicitSizeSet(instance:IVisualElement):Boolean {
+
+ if ("explicitWidth" in instance && Object(instance).explicitWidth!=null) {
+ return true;
+ }
+ else if ("explicitHeight" in instance && Object(instance).explicitHeight!=null) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the horizontal position string for HTML
+ * */
+ public function getHorizontalPositionHTML(instance:IVisualElement, propertyModel:Styles, stylesValue:String = "", isBasicLayout:Boolean = true):String {
+
+ if (!isBasicLayout) return stylesValue;
+ // horizontal center trumps left and x properties
+ if (instance.horizontalCenter!=null) {
+ stylesValue += "display:block;margin:" + instance.horizontalCenter + " auto;left:0;right:0;";
+ //stylesValue = stylesValue.replace("absolute", "relative");
+
+ propertyModel.display = Styles.BLOCK;
+ //propertyModel.position = Styles.RELATIVE;
+ propertyModel.position = Styles.ABSOLUTE;
+ propertyModel.margin = instance.horizontalCenter + " auto;left:0;right:0;";
+
+ return stylesValue;
+ }
+ else if (instance.left!=null || instance.right!=null) {
+ stylesValue += instance.left!=null ? "left:" + instance.left + "px;" : "";
+ stylesValue += instance.right!=null ? "right:" + instance.right + "px;" : "";
+ if (instance.left!=null) propertyModel.left = instance.left + "px";
+ if (instance.right!=null) propertyModel.right = instance.right + "px";
+ return stylesValue;
+ }
+ else {
+ stylesValue += "left:" + instance.x + "px;";
+ propertyModel.left = instance.x + "px;";
+ }
+
+ return stylesValue;
+ }
+
+
+ /**
+ * Get the vertical position string for HTML
+ * */
+ public function getVerticalPositionHTML(instance:IVisualElement, propertyModel:Styles, stylesValue:String = "", isBasicLayout:Boolean = true):String {
+
+ if (!isBasicLayout) return stylesValue;
+
+ if (instance.verticalCenter!=null) {
+ stylesValue += "display:block;margin:" + instance.verticalCenter + " auto;";
+ stylesValue = stylesValue.replace("absolute", "relative");
+
+ propertyModel.display = Styles.BLOCK;
+ propertyModel.position = Styles.RELATIVE;
+ propertyModel.margin = instance.verticalCenter + " auto;";
+
+ return stylesValue;
+ }
+ else if (instance.top!=null || instance.bottom!=null) {
+ stylesValue += instance.top!=null ? "top:" + instance.top + "px;" : "";
+ stylesValue += instance.bottom!=null ? "bottom:" + instance.bottom + "px;" : "";
+ if (instance.top!=null) propertyModel.top = instance.top + "px";
+ if (instance.bottom!=null) propertyModel.bottom = instance.bottom + "px";
+ return stylesValue;
+ }
+ else {
+ stylesValue += "top:" + instance.y + "px;";
+ propertyModel.top = instance.y + "px;";
+ }
+
+ return stylesValue;
+ }
+
+ /**
+ * Get border and background styles of a border container
+ * */
+ public function getBorderString(element:IStyleClient):String {
+ var value:String = "";
+
+ if (element.getStyle("backgroundAlpha")!=0) {
+ value += "background-color:" + DisplayObjectUtils.getColorInHex(element.getStyle("backgroundColor"), true) + ";";
+ value += "background-alpha:" + element.getStyle("backgroundAlpha") + ";";
+ }
+
+ if (element.getStyle("borderVisible")) {
+ value += "border-width:" + element.getStyle("borderWeight") + "px;";
+ value += "border-style:solid;";
+
+ if (element.getStyle("borderColor")!==undefined) {
+ value += "border-color:" + DisplayObjectUtils.getColorInHex(element.getStyle("borderColor"), true) + ";";
+ }
+ }
+
+ if (element.getStyle("color")!==undefined) {
+ value += "color:" + DisplayObjectUtils.getColorInHex(element.getStyle("color"), true) + ";";
+ }
+
+ return value;
+ }
+
+ /**
+ * Set styles
+ * */
+ public function setStyles(component:Object, styles:String = "", singleton:Boolean = false):String {
+ var out:String = ">";
+
+ if (useInlineStyles) {
+ return " style=\"" + styles + "\"" + (singleton?"\>":">");
+ }
+ else {
+ var formatted:String= "\t" + styles.replace(/;/g, ";\n\t");
+
+ //styles += ";";
+ //cssOutput += "#" + getIdentifierOrName(component) + " {\n\n";
+ //cssOutput += "" + styles.replace(/;/g, ";\n") + "\n\n} ";
+
+ if (component is String) {
+ out = component + " {\n";
+ }
+ else {
+ out = "#" + getIdentifierOrName(component) + " {\n";
+ }
+ out += formatted;
+ out += "}\n\n";
+
+ out = out.replace(/\t}/g, "}");
+
+ cssOutput += out;
+ }
+
+ return (singleton?"\>":">");
+ }
+
+
+ /**
+ * Wrap in style tags
+ * */
+ public function wrapInStyleTags(value:String):String {
+ var out:String = "<style>\n" + value + "\n</style>";
+ return out;
+ }
+
+ /**
+ * Gets the ID of the target object
+ *
+ * @param name if id is not available then if the name parameter is true then use name
+ *
+ * returns id or name
+ * */
+ public function getIdentifierOrName(element:Object, name:Boolean = true, appendID:String = ""):String {
+
+ if (element && "id" in element && element.id) {
+ return element.id + appendID;
+ }
+ else if (element && name && "name" in element && element.name) {
+ return element.name + appendID;
+ }
+
+ return "";
+ }
+
+ /**
+ * Get ID from ID or else name attribute
+ * */
+ public function getIdentifierAttribute(instance:Object, value:String = "", appendID:String = ""):String {
+
+ if (instance && "id" in instance && instance.id) {
+ value += "id=\"" + instance.id + appendID + "\"";
+ }
+
+ else if (instance && "name" in instance && instance.name) {
+ value += "id=\"" + instance.name + appendID + "\"";
+ }
+
+ return value;
+ }
+
+ /**
+ * Get name and ID attribute
+ * */
+ public function getIdentifierOrNameAttribute(instance:Object, propertyValue:String = ""):String {
+
+ if (instance && "id" in instance && instance.id) {
+ propertyValue += "id=\"" + instance.id + "\"";
+ }
+
+ if (instance && "name" in instance && instance.name) {
+ propertyValue += "name=\"" + instance.name + "\"";
+ }
+
+ return propertyValue;
+ }
+
+ /**
+ * @inheritDoc
+ * */
+ public function exportXML(document:IDocument, reference:Boolean = false):XML {
+ return null;
+ }
+
+ /**
+ * @inheritDoc
+ * */
+ public function exportJSON(document:IDocument, reference:Boolean = false):JSON {
+ return null;
+ }
+
+ /**
+ * Get data URI from object.
+ *
+ * Encoding to JPG took 2000ms in some cases where PNG took 200ms.
+ * I have not extensively tested this but it seems to be 10x faster
+ * than JPG.
+ * */
+ public function getDataURI(target:Object, type:String = "png"):String {
+ var output:String;
+
+ if (type.toLowerCase()=="jpg") {
+ type = "jpeg";
+ }
+
+ output = "data:image/" + type + ";base64," + getBase64ImageData(target, type);
+
+ return output;
+ }
+
+ /**
+ * Returns base64 image string.
+ *
+ * Encoding to JPG took 2000ms in some cases where PNG took 200ms.
+ * I have not extensively tested this but it seems to be 10x faster
+ * than JPG.
+ *
+ * Performance:
+ * get snapshot. time=14
+ * encode to png. time=336 // encode to jpg. time=2000
+ * encode to base 64. time=35
+ *
+ * Don't trust these numbers. Test it yourself. First runs are always longer than previous.
+ *
+ * This function gets called multiple times sometimes. We may be encoding more than we have too.
+ * But is probably a bug somewhere.
+ * */
+ public function getBase64ImageData(target:Object, type:String = "png", checkCache:Boolean = false):String {
+ var component:IUIComponent = target as IUIComponent;
+ var bitmapData:BitmapData;
+ var byteArray:ByteArray;
+ var base64Encoder:Base64Encoder;
+ var base64Encoder2:Base64;
+ var useEncoder:Boolean;
+ var rectangle:Rectangle;
+ var jpegEncoderOptions:JPEGEncoderOptions;
+ var pngEncoderOptions:PNGEncoderOptions;
+ var quality:int = 80;
+ var fastCompression:Boolean = true;
+ var timeEvents:Boolean = false;
+ var altBase64:Boolean = true;
+ var results:String;
+
+
+ if (base64BitmapCache[target] && checkCache) {
+ return base64BitmapCache[target];
+ }
+
+ if (timeEvents) {
+ var time:int = getTimer();
+ }
+
+ if (component) {
+ bitmapData = BitmapUtil.getSnapshot(component);
+ }
+ else if (target is DisplayObject) {
+ bitmapData = DisplayObjectUtils.getBitmapDataSnapshot2(target as DisplayObject);
+ }
+ else if (target is BitmapData) {
+ bitmapData = target as BitmapData;
+ }
+ else {
+ return null;
+ }
+
+ rectangle = new Rectangle(0, 0, bitmapData.width, bitmapData.height);
+
+ if (timeEvents) {
+ trace ("get snapshot. time=" + (getTimer()-time));
+ time = getTimer();
+ }
+
+ if (type=="png") {
+
+ if (useEncoder) {
+ if (!pngEncoder) {
+ pngEncoder = new PNGEncoder();
+ }
+
+ byteArray = pngEncoder.encode(bitmapData);
+ }
+ else {
+ if (!pngEncoderOptions) {
+ pngEncoderOptions = new PNGEncoderOptions(fastCompression);
+ }
+
+ byteArray = bitmapData.encode(rectangle, pngEncoderOptions);
+ }
+ }
+ else if (type=="jpg" || type=="jpeg") {
+
+ if (useEncoder) {
+ if (!jpegEncoder) {
+ jpegEncoder = new JPEGEncoder();
+ }
+
+ byteArray = jpegEncoder.encode(bitmapData);
+ }
+ else {
+ if (!jpegEncoderOptions) {
+ jpegEncoderOptions = new JPEGEncoderOptions(quality);
+ }
+
+ byteArray = bitmapData.encode(rectangle, jpegEncoderOptions);
+ }
+ }
+ else {
+ // raw bitmap image data
+ byteArray = bitmapData.getPixels(new Rectangle(0, 0, bitmapData.width, bitmapData.height));
+ }
+
+ if (timeEvents) {
+ trace ("encode to " + type + ". time=" + (getTimer()-time));
+ time = getTimer();
+ }
+
+ if (!altBase64) {
+ if (!base64Encoder) {
+ base64Encoder = new Base64Encoder();
+ }
+
+ base64Encoder.encodeBytes(byteArray);
+
+ results = base64Encoder.toString();
+ }
+ else {
+ results = Base64.encode(byteArray);
+ }
+
+ //trace(base64.toString());
+
+ if (timeEvents) {
+ trace ("encode to base 64. time=" + (getTimer()-time));
+ }
+
+ base64BitmapCache[target] = results;
+
+ return results;
+ }
+
+ public var base64BitmapCache:Dictionary = new Dictionary(true)
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as b/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
new file mode 100644
index 0000000..ae388ec
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/InspectorUtils.as
@@ -0,0 +1,500 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+package com.flexcapacitor.utils {
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.events.InspectorEvent;
+ import com.flexcapacitor.graphics.LayoutLines;
+ import com.flexcapacitor.model.VisualElementVO;
+
+ import flash.desktop.Clipboard;
+ import flash.desktop.ClipboardFormats;
+ import flash.display.DisplayObject;
+ import flash.display.DisplayObjectContainer;
+ import flash.events.IEventDispatcher;
+ import flash.utils.describeType;
+ import flash.utils.getQualifiedClassName;
+ import flash.utils.getQualifiedSuperclassName;
+
+ import mx.collections.ArrayCollection;
+ import mx.core.IVisualElement;
+ import mx.core.IVisualElementContainer;
+ import mx.core.UIComponent;
+ import mx.managers.ISystemManager;
+ import mx.utils.NameUtil;
+ import mx.utils.ObjectUtil;
+
+ public class InspectorUtils {
+
+
+ public function InspectorUtils() {
+
+
+ }
+
+ /**
+ * Get unqualified class name of the target object
+ * */
+ public static function getClassName(element:Object):String {
+ var name:String = NameUtil.getUnqualifiedClassName(element);
+ return name;
+ }
+
+ /**
+ * Get unqualified class name of the document of the target object
+ * returns null if element is not a UIComponent
+ * */
+ public static function getDocumentName(element:Object):String {
+ var name:String;
+ if (element is UIComponent) {
+ name = NameUtil.getUnqualifiedClassName(UIComponent(element).document);
+ }
+ return name;
+ }
+
+ /**
+ * Get the type of the value passed in
+ * */
+ public static function getValueType(value:*):String {
+ var type:String = getQualifiedClassName(value);
+
+ if (type=="int") {
+ if (typeof value=="number") {
+ type = "Number";
+ }
+ }
+
+ return type;
+ }
+
+ /**
+ * Get package of the target object
+ * */
+ public static function getPackageName(element:Object):String {
+ var name:String = flash.utils.getQualifiedClassName(element);
+ if (name && name.indexOf("::")) {
+ name = name.split("::")[0];
+ }
+
+ return name;
+ }
+
+ /**
+ * Get super class name of the target object
+ * */
+ public static function getSuperClassName(element:Object):String {
+ var name:String = flash.utils.getQualifiedSuperclassName(element);
+ if (name && name.indexOf("::")) {
+ name = name.split("::")[name.split("::").length-1]; // i'm sure theres a better way to do this
+ }
+
+ return name;
+ }
+
+ /**
+ * Get the package of the super class name of the target
+ * */
+ public static function getSuperClassPackage(element:Object):String {
+ var name:String = flash.utils.getQualifiedSuperclassName(element);
+ if (name && name.indexOf("::")) {
+ name = name.split("::")[0];
+ }
+
+ return name;
+ }
+
+ /**
+ * Clears outline drawn around target display object
+ * */
+ public static function clearSelection(target:Object, systemManager:ISystemManager, remove:Boolean = false):void {
+ LayoutLines.getInstance().clear(target, systemManager, remove);
+ }
+
+ /**
+ * Draws outline around target display object
+ * */
+ public static function drawSelection(target:Object, systemManager:ISystemManager):void {
+ throw new Error("CANNOT USE DRAW SELECTION");
+ //Radiate.drawSelection(target);
+ /*if (target is DisplayObject) {
+ LayoutLines.getInstance().drawLines(target, systemManager);
+ }
+ else if (target!=null) {
+ trace("Is not displayObject", NameUtil.getUnqualifiedClassName(target));
+ }*/
+ }
+
+ /**
+ * Copy text to clipboard
+ * */
+ public static function copyToClipboard(text:String, format:String=ClipboardFormats.TEXT_FORMAT):void {
+ Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, text);
+ }
+
+ /**
+ * Returns an array of display objects of type VisualElementVO
+ * Optionally returns elements
+ * */
+ public static function getElementChildrenArray(displayObject:DisplayObject, getElements:Boolean = false, getSkins:Boolean = true):ArrayCollection {
+ var displayObject:DisplayObject = DisplayObject(displayObject);
+ var displayObjectContainer:DisplayObjectContainer;
+
+ var visualElementContainer:IVisualElementContainer;
+ var visualElement:IVisualElement;
+
+ var visualElementVO:VisualElementVO = new VisualElementVO();
+
+ var children:ArrayCollection = new ArrayCollection();
+
+
+ // attempt to cast to a specific type and assign in the process
+ displayObjectContainer = displayObject as DisplayObjectContainer;
+ visualElementContainer = displayObject as IVisualElementContainer;
+ visualElement = displayObject as IVisualElement;
+
+
+ // gather all the display objects on the current display object
+ if (displayObjectContainer) {
+
+ for (var bb:int = 0; bb < displayObjectContainer.numChildren; bb++) {
+
+ // visualElementVO = createDisplayObjectVO(displayObjectContainer.getChildAt(bb));
+ visualElementVO = VisualElementVO.unmarshall(displayObjectContainer.getChildAt(bb));
+ children.addItem(visualElementVO);
+ }
+ }
+
+ if (visualElementContainer && getElements) {
+
+ for (var cc:int = 0; cc < visualElementContainer.numElements; cc++) {
+ //visualElementVO = createDisplayObjectVO(displayObjectContainer.getChildAt(cc));
+ visualElementVO = VisualElementVO.unmarshall(DisplayObject(visualElementContainer.getElementAt(cc)));
+ children.addItem(visualElementVO);
+ }
+ }
+
+ return children;
+ }
+
+
+ /**
+ * Gets the ID of the target object
+ * returns null if no ID is specified or target is not a UIComponent
+ * */
+ public static function getIdentifier(element:Object):String {
+ var id:String;
+
+ if (element is UIComponent && UIComponent(element).id) {
+ id = UIComponent(element).id;
+ }
+ return id;
+ }
+
+ /**
+ * Get name of target object or null if not available
+ * */
+ public static function getName(element:Object):String {
+ var name:String;
+
+ if (element.hasOwnProperty("name") && element.name) {
+ name = element.name;
+ }
+
+ return name;
+ }
+
+ /**
+ * Get qualified class name of the target object
+ * */
+ public static function getQualifiedClassName(element:Object):String {
+ var name:String = flash.utils.getQualifiedClassName(element);
+ return name;
+ }
+
+ /**
+ * With the given target it returns a regexp pattern to find the exact instance in MXML
+ * If isScript is true it attempts to returns a pattern to find the exact instance in AS3
+ * The MXML pattern will find the instance with that ID. If the instance doesn't have an ID it no worky.
+ * NOTE: Press CMD+SHIFT+F to and check regular expression in the Find in Files dialog
+ * */
+ public static function getRegExpSearchPattern(target:DisplayObject, isScript:Boolean = false):String {
+ var id:String = getIdentifier(target);
+ var className:String = NameUtil.getUnqualifiedClassName(target);
+ var pattern:String;
+ var scriptPattern:String;
+
+ if (id == null) {
+ pattern = className + "(.*)";
+ }
+ else {
+ pattern = className + "(.*)id\\s?=\\s?[\"|']" + id + "[\"|']";
+ scriptPattern = id + ".addEventListener";
+ }
+
+
+ if (isScript) {
+ return scriptPattern;
+ }
+
+ return pattern;
+ }
+
+
+ /**
+ * Get ancestors of element
+ *
+ * @param target
+ * @param collection
+ * @param ancestors
+ * @return
+ */
+ public static function getVisualElementsArray(element:*, items:Array, ancestors:int = 0, topMostDisplayObject:Object = null):Array {
+ var vo:VisualElementVO;
+
+ // do the worm up the display list
+ while (element!= null && ancestors>-1)
+ {
+ // store display element information
+ vo = VisualElementVO.unmarshall(element);
+
+ // save reference to display element VO's for tree
+ if (!items) items = new Array();
+ items.push(vo);
+
+ if ("owner" in element) {
+ element = element.owner as IVisualElement;
+ }
+
+ ancestors--;
+
+ if (element==topMostDisplayObject) {
+ ancestors = 0; //bail after the next run through
+ }
+ }
+
+ return items;
+
+ }
+
+ /**
+ * Get the parent of the target that is also a UIComponent
+ *
+ * @return
+ */
+ public static function getParentUIComponent(target:DisplayObject):UIComponent {
+ var found:Boolean;
+
+ // run up the display list
+ while (target) {
+ target = target.parent;
+
+ // check if next parent exists
+ if (!target) {
+ break;
+ }
+
+ if (target is UIComponent) {
+ found = true;
+ break;
+ }
+
+ }
+
+ if (found) return UIComponent(target);
+ return null;
+ }
+
+ /**
+ * Get the name of the target parent that is also a UIComponent
+ *
+ * @return
+ */
+ public static function getParentUIComponentName(target:DisplayObject):String {
+ var parent:DisplayObject = getParentUIComponent(target);
+ var className:String = getClassName(parent);
+ return className;
+ }
+
+
+ /**
+ * Get parent document name
+ *
+ * @return null if target is not a UIComponent
+ */
+ public static function getParentDocumentName(target:Object):String {
+ var className:String;
+ if (target is UIComponent) {
+ className = getClassName(target.parentDocument);
+ }
+ return className;
+ }
+
+
+ /**
+ * Get parent document name
+ *
+ * @return
+ */
+ public static function getClassNameAndPackage(target:Object):Array {
+ var className:String;
+ var classPath:String;
+
+ className = getClassName(target);
+ classPath = getPackageName(target);
+
+ return [className, classPath];
+ }
+
+
+ /**
+ * Dispatch target change event
+ *
+ * @return
+ */
+ public static function dispatchTargetChangeEvent(target:Object, source:IEventDispatcher):void {
+
+ // let other inspectors know there is a new target selected
+ var selectionChangeEvent:InspectorEvent = new InspectorEvent(InspectorEvent.CHANGE);
+ selectionChangeEvent.targetItem = target;
+
+ // store previous targets in a dictionary
+
+ if (source) {
+ source.dispatchEvent(selectionChangeEvent);
+ }
+ }
+
+
+ /**
+ * Change target. Use this instead of dispatchTargetChangeEvent()
+ *
+ * TODO: Add a weak reference to the old target in a static array for history type navigation
+ *
+ * @return
+ */
+ public static function updateTarget(target:Object, source:IEventDispatcher):void {
+ // TODO: Add a weak reference to the old target in a static array for history type navigation
+
+ // let other inspectors know there is a new target selected
+ var selectionChangeEvent:InspectorEvent = new InspectorEvent(InspectorEvent.CHANGE);
+ selectionChangeEvent.targetItem = target;
+
+ if (source) {
+ source.dispatchEvent(selectionChangeEvent);
+ }
+ }
+
+ /**
+ * Converts an integer to hexidecimal.
+ * For example, 16117809 returns "#EEEEEE" or something
+ * @return
+ */
+ public static function convertIntToHex(item:Object):String {
+ var hex:String = Number(item).toString(16);
+ return ("00000" + hex.toUpperCase()).substr(-6);
+ }
+
+
+ /**
+ * Sets the property on the target. Supports styles.
+ * We should probably switch to the set property method
+ * @return
+ */
+ public static function setTargetProperty(target:Object, property:String, value:*, type:String = "String", isPropertyStyle:Object=null):void {
+ var newAssignedValue:* = TypeUtils.getTypedValue(value, type);
+ TypeUtils.applyProperty(target, property, newAssignedValue, type, isPropertyStyle);
+ }
+
+
+ /**
+ * @copy spark.components.gridClasses.GridItemEditor#save();
+ */
+ public static function setProperty(target:Object, field:String, value:*):Boolean {
+
+ var newData:Object = value;
+ var property:String = field;
+ var data:Object = target;
+ var typeInfo:String = "";
+
+ for each(var variable:XML in describeType((data).variable)) {
+ if (property == variable.@name.toString()) {
+ typeInfo = variable.@type.toString();
+ break;
+ }
+ }
+
+ if (typeInfo == "String") {
+ if (!(newData is String))
+ newData = newData.toString();
+ }
+ else if (typeInfo == "uint") {
+ if (!(newData is uint))
+ newData = uint(newData);
+ }
+ else if (typeInfo == "int") {
+ if (!(newData is int))
+ newData = int(newData);
+ }
+ else if (typeInfo == "Number") {
+ if (!(newData is Number))
+ newData = Number(newData);
+ }
+ else if (typeInfo == "Boolean") {
+ if (!(newData is Boolean)) {
+ var strNewData:String = newData.toString();
+
+ if (strNewData) {
+ newData = (strNewData.toLowerCase() == "true") ? true : false;
+ }
+ }
+ }
+
+ if (property && data[property] !== newData) {
+ data[property] = newData;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns <code>true</code> if the object reference specified
+ * is a simple data type. The simple data types include the following:
+ * <ul>
+ * <li><code>String</code></li>
+ * <li><code>Number</code></li>
+ * <li><code>uint</code></li>
+ * <li><code>int</code></li>
+ * <li><code>Boolean</code></li>
+ * <li><code>Date</code></li>
+ * <li><code>Array</code></li>
+ * </ul>
+ *
+ * @param value Object inspected.
+ *
+ * @return <code>true</code> if the object specified
+ * is one of the types above; <code>false</code> otherwise.
+ * */
+ public static function isSimple(value:*):Boolean {
+ return ObjectUtil.isSimple(value);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
new file mode 100644
index 0000000..ff3db5f
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentExporter.as
@@ -0,0 +1,170 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.flexcapacitor.utils {
+ import com.flexcapacitor.model.IDocument;
+ import com.flexcapacitor.model.IDocumentExporter;
+ import com.flexcapacitor.utils.supportClasses.ComponentDescription;
+
+ import spark.components.Application;
+
+ /**
+ * Exports a document to MXML
+ * */
+ public class MXMLDocumentExporter extends DocumentExporter implements IDocumentExporter {
+
+ public function MXMLDocumentExporter() {
+
+ }
+
+ /**
+ * @inheritDoc
+ * */
+ public function export(iDocument:IDocument, target:ComponentDescription = null, reference:Boolean = false):* {
+ var output:String;
+ var XML1:XML;
+
+ if (!target) {
+ target = iDocument.componentDescription;
+ }
+
+ if (!reference) {
+ output = getMXMLOutputString(iDocument, target);
+ }
+ else {
+ XML1 = <document />;
+ XML1.@host = iDocument.host;
+ XML1.@id = iDocument.id;
+ XML1.@name = iDocument.name;
+ XML1.@uid = iDocument.uid;
+ XML1.@uri = iDocument.uri;
+ output = XML1.toXMLString();
+ }
+
+ return output;
+ }
+
+ /**
+ * @inheritDoc
+ * */
+ public function exportXML(document:IDocument, reference:Boolean = false):XML {
+ return null;
+ }
+
+ /**
+ * @inheritDoc
+ * */
+ public function exportJSON(document:IDocument, reference:Boolean = false):JSON {
+ return null;
+ }
+
+
+ /**
+ * Gets the formatted MXML output from a component.
+ * TODO: This should be using XML and namespaces.
+ * */
+ public function getMXMLOutputString(iDocument:IDocument, component:ComponentDescription, addLineBreak:Boolean = false, tabs:String = ""):String {
+ if (component.instance is Application) {
+ getAppliedPropertiesFromHistory(iDocument, component);
+ }
+ var properties:Object = component.properties;
+ var styles:Object = component.styles;
+ var componentChild:ComponentDescription;
+ var name:String = component.name;
+ var output:String = "";
+ var outputValue:String = "";
+ var namespaces:String;
+ var value:*;
+
+
+ for (var propertyName:String in properties) {
+ value = properties[propertyName];
+ if (value===undefined || value==null) {
+ continue;
+ }
+ output += " ";
+
+ // we should be converting objects into tags
+ if (value is Object) {
+ outputValue = XMLUtils.getAttributeSafeString(Object(value).toString());
+ output += propertyName + "=\"" + outputValue + "\"";
+
+ }
+ else {
+ output += propertyName + "=\"" + XMLUtils.getAttributeSafeString(Object(value).toString()) + "\"";
+ }
+ }
+
+ for (var styleName:String in styles) {
+ value = styles[styleName];
+ if (value===undefined || value==null) {
+ continue;
+ }
+ output += " ";
+ output += styleName + "=\"" + XMLUtils.getAttributeSafeString(Object(styles[styleName]).toString()) + "\"";
+ }
+
+ if (name) {
+ if (component.instance is Application) {
+ name = "Application";
+ namespaces = " xmlns:fx=\"http://ns.adobe.com/mxml/2009\"";
+ namespaces += " xmlns:s=\"library://ns.adobe.com/flex/spark\"";
+ output = namespaces + output;
+ }
+ // we are not handling namespaces here - we could use component descriptor
+ output = tabs + "<s:" + name + output;
+
+ if (component.children && component.children.length>0) {
+ output += ">\n";
+
+ for (var i:int;i<component.children.length;i++) {
+ componentChild = component.children[i];
+ // we should get the properties and styles from the
+ // the component description
+ getAppliedPropertiesFromHistory(iDocument, componentChild);
+ output += getMXMLOutputString(iDocument, componentChild, false, tabs + "\t");
+ }
+
+ output += tabs + "</s:" + name + ">\n";
+ }
+ else {
+ output += "/>\n";
+ }
+ }
+ else {
+ output = "";
+ }
+
+ isValid = XMLUtils.isValidXML(output);
+
+ if (!isValid) {
+ error = XMLUtils.validationError;
+ errorMessage = XMLUtils.validationErrorMessage;
+ }
+ else {
+ error = null;
+ errorMessage = null;
+ }
+
+ return output;
+ }
+
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
new file mode 100644
index 0000000..c48992c
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLDocumentImporter.as
@@ -0,0 +1,143 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+package com.flexcapacitor.utils {
+
+ import com.flexcapacitor.controller.Radiate;
+ import com.flexcapacitor.model.IDocument;
+ import com.flexcapacitor.utils.supportClasses.ComponentDefinition;
+
+ import flash.events.EventDispatcher;
+ import flash.system.ApplicationDomain;
+ import flash.utils.getTimer;
+
+ import mx.core.IVisualElement;
+
+
+ /**
+ * Import MXML into a IDocument. Basic support of creating components and apply properties and styles.
+ * */
+ public class MXMLDocumentImporter extends EventDispatcher {
+
+ public var document:IDocument;
+
+ /**
+ * Import the MXML document into the IDocument.
+ * */
+ public function MXMLDocumentImporter(iDocument:IDocument, id:String, mxml:XML, container:IVisualElement) {
+ document = iDocument;
+
+ var elName:String = mxml.localName();
+ var timer:int = getTimer();
+
+ Radiate.importingDocument = true;
+
+ // TODO this is a special case we check for since
+ // we should have already created the application by now
+ // we should handle this case before we get here (pass in the children of the application xml not application itself)
+ if (elName=="Application") {
+ Radiate.setAttributesOnComponent(document.instance, mxml);
+ }
+ else {
+ createChildFromNode(mxml, container);
+ }
+
+
+ for each (var childNode:XML in mxml.children()) {
+ createChildFromNode(childNode, container);
+ }
+
+ Radiate.importingDocument = false;
+
+ // using importing document flag it goes down from 5 seconds to 1 second
+ //Radiate.log.info("Time to import: " + (getTimer()-timer));
+
+ }
+
+ /**
+ * Create child from node
+ * */
+ private function createChildFromNode(node:XML, parent:Object):IVisualElement {
+ var elementName:String = node.localName();
+ var domain:ApplicationDomain = ApplicationDomain.currentDomain;
+ var componentDefinition:ComponentDefinition = Radiate.getDynamicComponentType(elementName);
+ var className:String;
+ var classType:Class;
+ var includeChildren:Boolean = true;
+ var instance:Object;
+
+ if (componentDefinition==null) {
+
+ }
+
+ className =componentDefinition ? componentDefinition.className :null;
+ classType = componentDefinition ? componentDefinition.classType as Class :null;
+
+
+ if (componentDefinition==null && elementName!="RootWrapperNode") {
+ //message += " Add this class to Radii8LibrarySparkAssets.sparkManifestDefaults or add the library to the project that contains it.";
+ var message:String = "Could not find definition for " + elementName + ". The document will be missing elements.";
+ Radiate.log.error(message);
+ return null;
+ }
+
+ // classes to look into for decoding XML
+ // XMLDecoder, SchemaTypeRegistry, SchemaManager, SchemaProcesser
+
+
+ // special case for radio button group
+ /*var object:* = SchemaTypeRegistry.getInstance().getClass(classType);
+ var object2:* = SchemaTypeRegistry.getInstance().getClass(elementName);
+ var object3:* = SchemaTypeRegistry.getInstance().getClass(node);
+ var sm:mx.rpc.xml.SchemaManager = new mx.rpc.xml.SchemaManager();
+
+ sm.addNamespaces({s:new Namespace("s", "library://ns.adobe.com/flex/spark")});
+ var o:Object = sm.unmarshall(node);
+
+ var q:QName = new QName(null, elementName);*/
+ //var object2:* = SchemaTypeRegistry.getInstance().registerClass(;
+
+
+ if (componentDefinition!=null) {
+ instance = Radiate.createComponentForAdd(document, componentDefinition, true);
+ //Radiate.log.info("MXML Importer adding: " + elementName);
+
+ // calling add before setting properties because some
+ // properties such as borderVisible need to be set after
+ // the component is added (maybe)
+ Radiate.addElement(instance, parent);
+
+ Radiate.setAttributesOnComponent(instance, node);
+
+ }
+
+
+ if (includeChildren) {
+
+ for each (var childNode:XML in node.children()) {
+ createChildFromNode(childNode, instance);
+ }
+ }
+
+ return instance as IVisualElement;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-radii8/blob/f370bfcf/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
----------------------------------------------------------------------
diff --git a/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as b/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
new file mode 100644
index 0000000..e4cdc02
--- /dev/null
+++ b/Radii8Library/src/com/flexcapacitor/utils/MXMLImporterEvent.as
@@ -0,0 +1,37 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package com.flexcapacitor.utils
+{
+ import flash.events.Event;
+
+
+ public class MXMLImporterEvent extends Event
+ {
+
+ public static var INITIALIZE:String = "onInitialize";
+ public var idString : String;
+
+ public function MXMLImporterEvent(type : String, indata:String, bubbles : Boolean = false, cancelable : Boolean = false)
+ {
+ super( type, bubbles, cancelable );
+ idString = indata;
+ }
+ }
+
+}
\ No newline at end of file