/******************************************************************************* * 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 org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP; import org.eclipse.wst.html.core.text.IHTMLPartitions; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; /** * @author Gregory Amerson */ @SuppressWarnings( "restriction" ) public class AlloyStructuredTextPartitionerForJSP extends StructuredTextPartitionerForJSP { private final String[] RESOURCE_BUNDLE_ATTRS = new String[] { "key", "message", "label", "helpMessage", "suffix", "title", "value", "placeholder", "errorMessage", "statusMessage", "confirmation" }; @Override public String getPartitionType( ITextRegion region, int offset ) { String retval = super.getPartitionType( region, offset ); final IStructuredDocumentRegion sdRegion = this.fStructuredDocument.getRegionAtCharacterOffset( offset ); if( isAUIScriptRegion( sdRegion ) ) { retval = IHTMLPartitions.SCRIPT; } else if( isAUIEventHandlerAttrValue( sdRegion, sdRegion.getRegionAtCharacterOffset( offset ), offset ) ) { retval = IHTMLPartitions.SCRIPT_EVENTHANDLER; } return retval; } @Override public String getPartitionTypeBetween( IStructuredDocumentRegion previousNode, IStructuredDocumentRegion nextNode ) { String retval = super.getPartitionTypeBetween( previousNode, nextNode ); if( isAUIScriptBetween(previousNode, nextNode ) ) { retval = "org.eclipse.wst.html.SCRIPT"; } return retval; } private boolean isAUIEventHandlerAttrValue( IStructuredDocumentRegion region, ITextRegion childRegion, int offset ) { if( region != null && childRegion != null && "XML_TAG_NAME".equals( region.getType() ) && "XML_TAG_ATTRIBUTE_VALUE".equals( childRegion.getType() ) && region.getText().toLowerCase().startsWith( "<aui:" ) ) { // we have found an attribute value in a AUI tag but now we need to check if the attribteName is a // javascript type attribute final ITextRegion[] regions = region.getRegions().toArray(); for( int i = 0; i < regions.length; i++ ) { if( regions[i].equals( childRegion ) ) { if( i >=2 && regions[i-2].getType().equals( "XML_TAG_ATTRIBUTE_NAME" ) ) { final ITextRegion attrNameRegion = regions[i-2]; final String attrName = region.getFullText( attrNameRegion ); for( String attrEvent : AlloyJsTranslator.ALLOYATTREVENTS ) { if( attrName.equals( attrEvent ) ) { return true; } } } } } } return false; } protected boolean isResourceBundleAttrValue( IStructuredDocumentRegion region, ITextRegion childRegion, int offset ) { if( region != null && childRegion != null && "XML_TAG_NAME".equals( region.getType() ) && "XML_TAG_ATTRIBUTE_VALUE".equals( childRegion.getType() ) && ( region.getText().toLowerCase().startsWith( "<aui:" ) || region.getText().toLowerCase().startsWith( "<liferay-ui:" ) ) ) { // we have found an attribute value in a liferay tag but now we need to check if the attribteName is a // resource bundle attribute final ITextRegion[] regions = region.getRegions().toArray(); for( int i = 0; i < regions.length; i++ ) { if( regions[i].equals( childRegion ) ) { if( i >=2 && regions[i-2].getType().equals( "XML_TAG_ATTRIBUTE_NAME" ) ) { final ITextRegion attrNameRegion = regions[i-2]; final String attrName = region.getFullText( attrNameRegion ); for( String attr : RESOURCE_BUNDLE_ATTRS ) { if( attrName.equals( attr ) ) { return true; } } } } } } return false; } private boolean isAUIScriptBetween( IStructuredDocumentRegion previousNode, IStructuredDocumentRegion nextNode ) { return previousNode.toString().contains( "aui:script" ); } private boolean isAUIScriptRegion( IStructuredDocumentRegion sdRegion ) { // TODO can this handle content with other regions like // <aui:script> function foo() {}; <portletTag/> function bar(){}</aui:script> return sdRegion != null && sdRegion.getPrevious() != null && sdRegion.getPrevious().toString().contains( "aui:script" ); } @Override protected boolean isDocumentRegionBasedPartition( IStructuredDocumentRegion sdRegion, ITextRegion containedChildRegion, int offset ) { if( isAUIEventHandlerAttrValue( sdRegion, containedChildRegion, offset ) ) { return false; } // only used if we need partitioner to not skip over liferay taglib message keys // if( isResourceBundleAttrValue( sdRegion, containedChildRegion, offset ) ) // { // return true; // } return super.isDocumentRegionBasedPartition( sdRegion, containedChildRegion, offset ); } }