blob: 934569b89cd6ee705bfba32a497201536ffcf019 [file] [log] [blame]
/*
*
* 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 org.apache.royale.compiler.internal.codegen.js.royale;
import org.apache.royale.compiler.codegen.ISubEmitter;
import org.apache.royale.compiler.codegen.mxml.js.IMXMLJSEmitter;
import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
import org.apache.royale.compiler.internal.codegen.mxml.MXMLSubEmitter;
import org.apache.royale.compiler.internal.codegen.mxml.royale.MXMLDescriptorSpecifier;
import org.apache.royale.compiler.internal.codegen.mxml.royale.MXMLEventSpecifier;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
public class JSRoyaleBasicMXMLDescriptorEmitter extends MXMLSubEmitter implements ISubEmitter<MXMLDescriptorSpecifier>
{
private boolean useGoogReflectObjectProperty = false;
public JSRoyaleBasicMXMLDescriptorEmitter(IMXMLJSEmitter emitter)
{
super(emitter);
}
@Override
public void emit(MXMLDescriptorSpecifier root)
{
RoyaleJSProject project = (RoyaleJSProject) getMXMLWalker().getProject();
useGoogReflectObjectProperty = project.config != null && project.config.getMxmlReflectObjectProperty();
outputDescriptorSpecifier(root, true);
}
//---------------------------------
// writeSimpleDescriptor
//---------------------------------
protected void writeSimpleDescriptor(String name, String type, String value,
boolean writeNewline)
{
write(ASEmitterTokens.SINGLE_QUOTE);
write(name);
write(ASEmitterTokens.SINGLE_QUOTE);
writeDelimiter(writeNewline);
if (type != null)
{
write(type);
writeDelimiter(writeNewline);
}
write(value);
}
//---------------------------------
// writeDelimiter
//---------------------------------
protected void writeDelimiter(boolean writeNewline)
{
if (writeNewline)
writeNewline(ASEmitterTokens.COMMA);
else
writeToken(ASEmitterTokens.COMMA);
}
//---------------------------------
// outputDescriptorSpecifier
//---------------------------------
private void outputDescriptorSpecifier(MXMLDescriptorSpecifier root, boolean writeNewline)
{
if (root.isTopNode)
{
int count = 0;
for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
{
if (md.name != null)
count++;
}
write(count + "");
writeNewline(ASEmitterTokens.COMMA);
}
outputPropertySpecifiers(root, writeNewline);
if (!root.isProperty)
{
outputStyleSpecifiers(root, writeNewline);
// TODO (erikdebruin) not yet implemented in Royale
//outputEffectSpecifiers(writeNewline);
outputEventSpecifiers(root, writeNewline);
if (!root.isTopNode)
{
writeDelimiter(writeNewline);
if (root.childrenSpecifier == null)
write(ASEmitterTokens.NULL);
else
outputChildren(root.childrenSpecifier, writeNewline);
}
boolean isLastChild = root.parent != null
&& root.parent.propertySpecifiers.indexOf(root) == root.parent.propertySpecifiers
.size() - 1;
if (!isLastChild && !root.isTopNode)
writeDelimiter(writeNewline);
}
}
//---------------------------------
// outputPropertySpecifiers
//---------------------------------
private void outputPropertySpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
{
MXMLDescriptorSpecifier model = null; // model goes first
MXMLDescriptorSpecifier beads = null; // beads go last
for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
{
if (md.name != null && md.name.equals("model"))
{
model = md;
break;
}
}
if (model != null)
{
outputPropertySpecifier(model, writeNewline);
}
for (MXMLDescriptorSpecifier md : root.propertySpecifiers)
{
if (md.name != null)
{
if (!md.name.equals("model") && !md.name.equals("beads"))
outputPropertySpecifier(md, writeNewline);
else if (md.name.equals("beads"))
beads = md;
}
}
if (beads != null)
{
outputPropertySpecifier(beads, writeNewline);
}
}
//---------------------------------
// outputEventSpecifiers
//---------------------------------
private void outputEventSpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
{
// number of events
int count = 0;
for (MXMLEventSpecifier me : root.eventSpecifiers)
{
if (me.name != null)
count++;
}
write(count + "");
for (MXMLEventSpecifier me : root.eventSpecifiers)
{
writeDelimiter(writeNewline);
outputEventSpecifier(me, writeNewline);
}
}
//---------------------------------
// outputStyleSpecifiers
//---------------------------------
private void outputStyleSpecifiers(MXMLDescriptorSpecifier root, boolean writeNewline)
{
// TODO (erikdebruin) not yet implemented in Royale
write("0");
writeDelimiter(writeNewline);
}
//---------------------------------
// outputPropertySpecifier
//---------------------------------
private void outputPropertySpecifier(MXMLDescriptorSpecifier specifier, boolean writeNewline)
{
if(specifier.isProperty)
{
if(useGoogReflectObjectProperty)
{
write(JSGoogEmitterTokens.GOOG_REFLECT_OBJECTPROPERTY);
write(ASEmitterTokens.PAREN_OPEN);
}
write(ASEmitterTokens.SINGLE_QUOTE);
write(specifier.name);
write(ASEmitterTokens.SINGLE_QUOTE);
if(useGoogReflectObjectProperty)
{
MXMLDescriptorSpecifier parentSpecifier = specifier.parent;
String id = (parentSpecifier.id != null) ? parentSpecifier.id : parentSpecifier.effectiveId;
write(ASEmitterTokens.COMMA);
write(ASEmitterTokens.SPACE);
write(ASEmitterTokens.THIS);
if (id != null)
{
write(ASEmitterTokens.MEMBER_ACCESS);
write(id);
}
write(ASEmitterTokens.PAREN_CLOSE);
}
}
else
{
write(specifier.name);
}
writeDelimiter(writeNewline);
if (specifier.isProperty)
{
if (specifier.value != null)
{
write(ASEmitterTokens.TRUE);
writeDelimiter(writeNewline);
// need to do other escaping here?
// restrict="0-9.\"
if (specifier.value.endsWith("\\'") && !specifier.value.endsWith("\\\\'"))
{
specifier.value = specifier.value.substring(0, specifier.value.length() - 1) + "\\'";
}
write(specifier.value);
}
else
{
write((specifier.hasArray) ? ASEmitterTokens.NULL : ASEmitterTokens.FALSE);
writeDelimiter(writeNewline);
write(ASEmitterTokens.SQUARE_OPEN);
indentPush();
writeNewline();
outputDescriptorSpecifier(specifier, writeNewline);
indentPop();
writeNewline();
write(ASEmitterTokens.SQUARE_CLOSE);
}
if (specifier.parent != null)
writeDelimiter(writeNewline);
}
else
{
for (MXMLDescriptorSpecifier md : specifier.propertySpecifiers)
{
if (md.name != null && md.name.equals("mxmlContent"))
{
specifier.childrenSpecifier = md;
specifier.propertySpecifiers.remove(md);
break;
}
}
if (specifier.id != null || specifier.effectiveId != null)
{
write(specifier.propertySpecifiers.size() + 1 + "");
writeDelimiter(writeNewline);
String idPropName = (specifier.effectiveId != null) ? "_id" : "id";
String id = (specifier.id != null) ? specifier.id : specifier.effectiveId;
write(ASEmitterTokens.SINGLE_QUOTE);
write(idPropName);
write(ASEmitterTokens.SINGLE_QUOTE);
writeDelimiter(writeNewline);
write(ASEmitterTokens.TRUE);
writeDelimiter(writeNewline);
write(ASEmitterTokens.SINGLE_QUOTE);
write(id);
write(ASEmitterTokens.SINGLE_QUOTE);
writeDelimiter(writeNewline);
}
else
{
write(specifier.propertySpecifiers.size() + "");
writeDelimiter(writeNewline);
}
outputDescriptorSpecifier(specifier, writeNewline);
}
}
//---------------------------------
// outputEventSpecifier
//---------------------------------
public void outputEventSpecifier(MXMLEventSpecifier specifier, boolean writeNewline)
{
String handler = ASEmitterTokens.THIS.getToken()
+ ASEmitterTokens.MEMBER_ACCESS.getToken() + specifier.eventHandler;
if (MXMLEventSpecifier.nameMap.contains(specifier.name))
specifier.name = specifier.name.toLowerCase();
else if (specifier.name.equals("doubleClick"))
specifier.name = "dblclick";
else if (specifier.name.equals("mouseWheel"))
specifier.name = "wheel";
writeSimpleDescriptor(specifier.name, null, handler, writeNewline);
}
//---------------------------------
// outputChildren
//---------------------------------
private void outputChildren(MXMLDescriptorSpecifier children, boolean writeNewline)
{
write(ASEmitterTokens.SQUARE_OPEN.getToken());
if(writeNewline)
{
indentPush();
writeNewline();
}
outputDescriptorSpecifier(children, writeNewline);
if(writeNewline)
{
indentPop();
writeNewline();
}
write(ASEmitterTokens.SQUARE_CLOSE.getToken());
}
}