/*******************************************************************************
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
*******************************************************************************/
package com.liferay.ide.alloy.core.jsp;
import java.util.Iterator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Position;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.jsdt.web.core.javascript.JsDataTypes;
import org.eclipse.wst.jsdt.web.core.javascript.JsTranslator;
import org.eclipse.wst.jsdt.web.core.javascript.NodeHelper;
import org.eclipse.wst.jsdt.web.core.javascript.Util;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
/**
* @author Gregory Amerson
*
* Most of this class is copied from JsTranslator
*/
@SuppressWarnings( "restriction" )
public class AlloyJsTranslator extends JsTranslator
{
private static final String EVENT_HANDLER_PRE = "(function(){";
private static final int EVENT_HANDLER_PRE_LENGTH = EVENT_HANDLER_PRE.length();
private static final String EVENT_HANDLER_POST = "})();";
private static final int EVENT_HANDLER_POST_LENGTH = EVENT_HANDLER_POST.length();
public static final String[] ALLOYATTREVENTS =
{
"onActiveStateChange",
"onBlurMethod",
"onBoundingBoxChange",
"onChange",
"onChangeMethod",
"onClassNamesChange",
"onClick",
"onContentBoxChange",
"onContentUpdate",
"onCssClassChange",
"onDefaultStateChange",
"onDepthChange",
"onDestroy",
"onDestroyedChange",
"onDisabledChange",
"onFocusedChange",
"onFocusMethod",
"onHandlerChange",
"onHeightChange",
"onHideClassChange",
"onHoverStateChange",
"onIconChange",
"onIconNodeChange",
"onIdChange",
"onIndexChange",
"onInit",
"onInitializedChange",
"onLabelChange",
"onLabelNodeChange",
"onlyActions",
"onParentChange",
"onRender",
"onRenderChange",
"onRenderedChange",
"onRootChange",
"onSelectedChange",
"onSrcNodeChange",
"onStringsChange",
"onSubmit",
"onTabIndexChange",
"onTitleChange",
"onTypeChange",
"onUseARIAChange",
"onVisibleChange",
"onWidthChange",
};
public AlloyJsTranslator( IStructuredDocument doc, String baseLocation, boolean listen )
{
super( doc, baseLocation, listen );
}
/*
* copied from org.eclipse.wst.jsdt.web.core.javascript.JsTranslator.translate()
* modified hardcoded section for "script" tags and added "aui:script"
*/
public void translate() {
//setCurrentNode(fStructuredDocument.getFirstStructuredDocumentRegion());
synchronized(finished) {
if(getCurrentNode() != null) {
NodeHelper nh = new NodeHelper(getCurrentNode());
while (getCurrentNode() != null && !isCanceled()) {
nh.setDocumentRegion(getCurrentNode());
// System.out.println("Translator Looking at Node
// type:"+getCurrentNode().getType()+"---------------------------------:");
// System.out.println(new NodeHelper(getCurrentNode()));
// i.println("/---------------------------------------------------");
if (getCurrentNode().getType() == DOMRegionContext.XML_TAG_NAME) {
if ((!nh.isEndTag() || nh.isSelfClosingTag()) && (nh.nameEquals("script") || nh.nameEquals("aui:script"))) { //$NON-NLS-1$
/*
* Handles the following cases: <script
* type="javascriptype"> <script language="javascriptype>
* <script src='' type=javascriptype> <script src=''
* language=javascripttype <script src=''> global js type.
* <script> (global js type)
*/
if (NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("type")) || NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("language")) || (nh.getAttributeValue("type")==null && nh.getAttributeValue("language")==null && isGlobalJs())) { //$NON-NLS-1$ //$NON-NLS-2$
if (nh.containsAttribute(new String[] { "src" })) { //$NON-NLS-1$
// Handle import
translateScriptImportNode(getCurrentNode());
}
// } else {
// handle script section
if (getCurrentNode().getNext() != null /*&& getCurrentNode().getNext().getType() == DOMRegionContext.BLOCK_TEXT*/) {
translateJSNode(getCurrentNode().getNext());
}
} // End search for <script> sections
} else if (nh.containsAttribute(JsDataTypes.HTMLATREVENTS) || nh.containsAttribute(ALLOYATTREVENTS)) {
/* Check for embedded JS events in any tags */
translateInlineJSNode(getCurrentNode());
} else if (nh.nameEquals("META") && nh.attrEquals("http-equiv", "Content-Script-Type") && nh.containsAttribute(new String[] { "content" })) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
// <META http-equiv="Content-Script-Type" content="type">
setIsGlobalJs( NodeHelper.isInArray(JsDataTypes.JSVALIDDATATYPES, nh.getAttributeValue("content"))); //$NON-NLS-1$
} // End big if of JS types
}
if (getCurrentNode() != null) {
advanceNextNode();
}
} // end while loop
if(getCompUnitBuffer()!=null) getCompUnitBuffer().setContents(fScriptText.toString());
}
finishedTranslation();
}
}
/*
* copied from org.eclipse.wst.jsdt.web.core.javascript.JsTranslator.translateInLineJSNode()
* modified hardcoded checks for htmlish scriptish attributes
*/
public void translateInlineJSNode(IStructuredDocumentRegion container) {
// System.out
// .println("JSPTranslator.translateInlineJSNode Entered
// w/ScriptOffset:"
// + scriptOffset);
//NodeHelper nh = new NodeHelper(container);
// System.out.println("inline js node looking at:\n" + nh);
/* start a function header.. will amend later */
ITextRegionList t = container.getRegions();
ITextRegion r;
Iterator regionIterator = t.iterator();
while (regionIterator.hasNext() && !isCanceled() ) {
r = (ITextRegion) regionIterator.next();
if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
int start = r.getStart();
int offset = r.getTextEnd();
String tagAttrname = container.getText(r);
/*
* Attribute values aren't case sensative, also make sure next
* region is attrib value
*/
if (NodeHelper.isInArray(JsDataTypes.HTMLATREVENTS, tagAttrname) || NodeHelper.isInArray( ALLOYATTREVENTS, tagAttrname )) {
if (regionIterator.hasNext()) {
regionIterator.next();
}
if (regionIterator.hasNext()) {
r = ((ITextRegion) regionIterator.next());
}
if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
int valStartOffset = container.getStartOffset(r);
// int valEndOffset = r.getTextEnd();
String rawText = container.getText(r);
if (rawText == null || rawText.length() == 0) {
continue;
}
/* Strip quotes */
switch (rawText.charAt(0)) {
case '\'':
case '"':
rawText = rawText.substring(1);
valStartOffset++;
}
if (rawText == null || rawText.length() == 0) {
continue;
}
switch (rawText.charAt(rawText.length() - 1)) {
case '\'':
case '"':
rawText = rawText.substring(0, rawText.length() - 1);
}
// Position inScript = new Position(scriptOffset,
// rawText.length());
/* Quoted text starts +1 and ends -1 char */
Position inHtml = new Position(valStartOffset, rawText.length());
/* need to pad the script text with spaces */
char[] spaces = Util.getPad(Math.max(0, valStartOffset - scriptOffset - EVENT_HANDLER_PRE_LENGTH));
for (int i = 0; i < spaces.length; i++) {
try {
char c = fStructuredDocument.getChar(scriptOffset + i);
if (c == '\n' || c == '\r' || c == '\t')
spaces[i] = c;
}
catch (BadLocationException e) {
Logger.logException(e);
}
}
fScriptText.append(spaces);
fScriptText.append(EVENT_HANDLER_PRE);
appendAndTrack(rawText, valStartOffset);
if(ADD_SEMICOLON_AT_INLINE) fScriptText.append(";"); //$NON-NLS-1$
if(r.getLength() > rawText.length()) {
fScriptText.append(EVENT_HANDLER_POST);
spaces = Util.getPad(Math.max(0, r.getLength() - rawText.length() - EVENT_HANDLER_POST_LENGTH));
fScriptText.append(spaces);
}
scriptOffset = container.getEndOffset(r);
}
}
}
}
}
}