Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 150268 Details for
Bug 107138
[content assist] Offer content assist and validation for custom tags in attribute values
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Fix Patch
107138_JSPContentAssistProcessor.txt (text/plain), 19.36 KB, created by
Ian Tewksbury
on 2009-10-22 11:57:30 EDT
(
hide
)
Description:
Fix Patch
Filename:
MIME Type:
Creator:
Ian Tewksbury
Created:
2009-10-22 11:57:30 EDT
Size:
19.36 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jst.jsp.ui >Index: src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java >=================================================================== >RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java,v >retrieving revision 1.63 >diff -u -r1.63 JSPContentAssistProcessor.java >--- src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java 13 Oct 2009 21:34:32 -0000 1.63 >+++ src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java 22 Oct 2009 15:57:30 -0000 >@@ -12,10 +12,11 @@ > > import java.util.ArrayList; > import java.util.Arrays; >-import java.util.Collections; > import java.util.HashMap; > import java.util.Iterator; > import java.util.List; >+import java.util.Set; >+import java.util.TreeSet; > import java.util.Vector; > > import org.eclipse.core.runtime.Path; >@@ -43,6 +44,7 @@ > import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper; > import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImages; > import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP; >+import org.eclipse.swt.graphics.Image; > import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor; > import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument; > import org.eclipse.wst.html.core.text.IHTMLPartitions; >@@ -72,6 +74,7 @@ > import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryRegistry; > import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument; > import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; >+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode; > import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; > import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; > import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser; >@@ -88,6 +91,9 @@ > import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor; > import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistUtilities; > import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants; >+import org.eclipse.wst.xml.ui.internal.editor.CMImageUtil; >+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper; >+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages; > import org.w3c.dom.Attr; > import org.w3c.dom.Document; > import org.w3c.dom.Element; >@@ -245,38 +251,69 @@ > ITextRegion nameRegion = null; > while (i >= 0) { > nameRegion = openRegions.get(i--); >- if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) >+ if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) { > break; >+ } > } > >- // on an empty value, add all the JSP and taglib tags > CMElementDeclaration elementDecl = getCMElementDeclaration(node); > if (nameRegion != null && elementDecl != null) { > String attributeName = open.getText(nameRegion); > if (attributeName != null) { >- String currentValue = node.getAttributes().getNamedItem(attributeName).getNodeValue(); >+ Node parent = contentAssistRequest.getParent(); > >- if(currentValue == null || currentValue.length() == 0) { //$NON-NLS-1$ >- List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, ModelQuery.INCLUDE_ATTRIBUTES); >- for (i = 0; i < additionalElements.size(); i++) { >- Object additionalElement = additionalElements.get(i); >- if(additionalElement instanceof CMElementDeclaration) { >- CMElementDeclaration ed = (CMElementDeclaration) additionalElement; >- >+ //ignore starte quote in match string >+ String matchString = contentAssistRequest.getMatchString().trim(); >+ if(matchString.startsWith("'") || matchString.startsWith("\"")) { >+ matchString = matchString.substring(1); >+ } >+ >+ //get all the proposals >+ List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, 0); >+ Iterator nodeIterator = additionalElements.iterator(); >+ >+ //check each suggestion >+ while (nodeIterator.hasNext()) { >+ CMNode additionalElementDecl = (CMNode) nodeIterator.next(); >+ if (additionalElementDecl != null && additionalElementDecl instanceof CMElementDeclaration) { >+ CMElementDeclaration ed = (CMElementDeclaration) additionalElementDecl; >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=89811 >+ StringBuffer sb = new StringBuffer(); >+ getContentGenerator().generateTag(parent, ed, sb); >+ >+ String proposedText = sb.toString(); >+ >+ //filter out any proposals that dont match matchString >+ if (beginsWith(proposedText, matchString)) { >+ //wrap with ' because JSP attributes are warped with " >+ proposedText = "'" + proposedText; >+ >+ //if its a container its possible the closing quote is already there >+ //don't want to risk injecting an extra >+ if(!(contentAssistRequest.getRegion() instanceof ITextRegionContainer)) { >+ proposedText += "'"; >+ } >+ >+ Image image = CMImageUtil.getImage(elementDecl); >+ if (image == null) { >+ image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC); >+ } >+ >+ //create the proposal >+ int cursorAdjustment = getCursorPositionForProposedText(proposedText); >+ String proposedInfo = getAdditionalInfo(getCMElementDeclaration(parent), elementDecl); > String tagname = getContentGenerator().getRequiredName(node, ed); >- StringBuffer contents = new StringBuffer("\""); //$NON-NLS-1$ >- getContentGenerator().generateTag(node, ed, contents); >- contents.append('"'); //$NON-NLS-1$ >- CustomCompletionProposal proposal = new CustomCompletionProposal(contents.toString(), contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), contents.length(), JSPEditorPluginImageHelper.getInstance().getImage(JSPEditorPluginImages.IMG_OBJ_TAG_GENERIC), tagname, null, null, XMLRelevanceConstants.R_JSP_ATTRIBUTE_VALUE); >+ CustomCompletionProposal proposal = new CustomCompletionProposal( >+ proposedText, contentAssistRequest.getReplacementBeginPosition(), >+ contentAssistRequest.getReplacementLength(), cursorAdjustment, image, tagname, null, proposedInfo, >+ XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE); > contentAssistRequest.addProposal(proposal); > } > } >- > } > } > } >- >- if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { >+ else if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { > try { > // Create a new model for Content Assist to operate on. This > // will simulate >@@ -400,8 +437,6 @@ > Logger.logException("Error in embedded JSP Content Assist", e); //$NON-NLS-1$ > } > } >- >- > } > > /** >@@ -668,35 +703,7 @@ > } > } > >- // check if it's in an attribute value, if so, don't add CDATA >- // proposal >- ITextRegion attrContainer = (fn != null) ? fn.getRegionAtCharacterOffset(documentPosition) : null; >- if (attrContainer != null && attrContainer instanceof ITextRegionContainer) { >- if (attrContainer.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { >- // test location of the cursor >- // return null if it's in the middle of an open/close >- // delimeter >- Iterator attrRegions = ((ITextRegionContainer) attrContainer).getRegions().iterator(); >- ITextRegion testRegion = null; >- while (attrRegions.hasNext()) { >- testRegion = (ITextRegion) attrRegions.next(); >- // need to check for other valid attribute regions >- if (XMLContentAssistUtilities.isJSPOpenDelimiter(testRegion.getType())) { >- if (!(((ITextRegionContainer) attrContainer).getEndOffset(testRegion) <= documentPosition)) >- return EMPTY_PROPOSAL_SET; >- } >- else if (XMLContentAssistUtilities.isJSPCloseDelimiter(testRegion.getType())) { >- if (!(((ITextRegionContainer) attrContainer).getStartOffset(testRegion) >= documentPosition)) >- return EMPTY_PROPOSAL_SET; >- } >- } >- // TODO: handle non-Java code such as nested tags >- if (testRegion.getType().equals(DOMJSPRegionContexts.JSP_CONTENT)) >- return getJSPJavaCompletionProposals(viewer, documentPosition); >- return EMPTY_PROPOSAL_SET; >- } >- } >- >+ //get the embedded results > IContentAssistProcessor p = (IContentAssistProcessor) fPartitionToProcessorMap.get(partitionType); > if (p != null) { > embeddedResults = p.computeCompletionProposals(viewer, documentPosition); >@@ -721,21 +728,10 @@ > fTemplateContexts.clear(); > jspResults = super.computeCompletionProposals(viewer, documentPosition); > } >- if (useEmbeddedResults) { >- if (embeddedResults != null && embeddedResults.length > 0) { >- List results = new ArrayList(); >- for (int i = 0; i < embeddedResults.length; i++) >- results.add(embeddedResults[i]); >- if (jspResults != null) { >- for (int i = 0; i < jspResults.length; i++) >- results.add(jspResults[i]); >- } >- jspResults = new ICompletionProposal[results.size()]; >- Collections.sort(results, new ProposalComparator()); >- for (int i = 0; i < results.size(); i++) >- jspResults[i] = (ICompletionProposal) results.get(i); >- >- } >+ >+ //merge the embedded results >+ if (useEmbeddedResults && embeddedResults != null && embeddedResults.length > 0) { >+ jspResults = merge(jspResults, embeddedResults); > } > if (jspResults == null) > jspResults = EMPTY_PROPOSAL_SET; >@@ -793,22 +789,23 @@ > } > > /** >- * Adds 2 arrays of ICompletionProposals and sorts them with a >- * ProposalComparator. >+ * Adds 2 arrays of {@link ICompletionProposal}s to a {@link TreeSet} >+ * eliminating duplicates and sorting with a {@link ProposalComparator} >+ * then returning the new merged, filtered, sorted, array of {@link ICompletionProposal}s. > * >- * @param jspResults >- * @param htmlResults >- * @return >+ * @param proposalsOne >+ * @param proposalsTwo >+ * @return a new merged, filtered, sorted array of {@link ICompletionProposal}s created from >+ * the two given arrays of {@link ICompletionProposal}s. > */ >- private ICompletionProposal[] merge(ICompletionProposal[] jspResults, ICompletionProposal[] htmlResults) { >- List results = new ArrayList(); >- List jsps = Arrays.asList(jspResults); >- List htmls = Arrays.asList(htmlResults); >+ private ICompletionProposal[] merge(ICompletionProposal[] proposalsOne, ICompletionProposal[] proposalsTwo) { >+ Set results = new TreeSet(new ProposalComparator()); >+ List proposalsOneList = Arrays.asList(proposalsOne); >+ List proposalsTwoList = Arrays.asList(proposalsTwo); > >- results.addAll(jsps); >- results.addAll(htmls); >+ results.addAll(proposalsOneList); >+ results.addAll(proposalsTwoList); > >- Collections.sort(results, new ProposalComparator()); > return (ICompletionProposal[]) results.toArray(new ICompletionProposal[results.size()]); > } > >@@ -1135,4 +1132,49 @@ > addTemplates(contentAssistRequest, TemplateContextTypeIdsJSP.TAG); > //don't need to call super here because otherwise we duplicate what the HTMLCOntentAssistProcessor that is running is already doing > } >+ >+ /** >+ * Different behavior if in {@link DOMRegionContext#XML_TAG_ATTRIBUTE_VALUE} region >+ * otherwise calls {@link AbstractContentAssistProcessor#getMatchString(IStructuredDocumentRegion, ITextRegion, int)} >+ * >+ * @see org.eclipse.wst.xml.ui.internal.contentassist.AbstractContentAssistProcessor#getMatchString(org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion, org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion, int) >+ */ >+ protected String getMatchString(IStructuredDocumentRegion parent, >+ ITextRegion aRegion, int offset) { >+ >+ String matchString = null; >+ >+ if ((aRegion == null) || isCloseRegion(aRegion)) { >+ matchString = ""; //$NON-NLS-1$ >+ } else { >+ String regionType = aRegion.getType(); >+ /* >+ * if attribute value then check to see if ' or " is in region and if so >+ * don't count it as part of match string >+ */ >+ if(regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) { >+ if(aRegion instanceof ITextRegionContainer) { >+ ITextRegionContainer attrValueContainer = (ITextRegionContainer)aRegion; >+ int matchStartIndex = 0; >+ if(attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE || >+ attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_SQUOTE) { >+ >+ matchStartIndex = attrValueContainer.getRegions().get(1).getStart(); >+ } >+ >+ matchString = parent.getText(aRegion).substring(matchStartIndex, offset - parent.getStartOffset(aRegion)); >+ } else { >+ matchString = parent.getText(aRegion).substring(0, offset - parent.getStartOffset(aRegion)); >+ if(matchString.charAt(0) == '\'' || matchString.charAt(0) == '\"') { >+ matchString = matchString.substring(1); >+ } >+ } >+ } >+ } >+ >+ if(matchString == null) { >+ matchString = super.getMatchString(parent, aRegion, offset); >+ } >+ return matchString; >+ } > } >#P org.eclipse.wst.xml.ui >Index: src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java >=================================================================== >RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java,v >retrieving revision 1.26 >diff -u -r1.26 AbstractContentAssistProcessor.java >--- src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java 20 Oct 2009 19:25:55 -0000 1.26 >+++ src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java 22 Oct 2009 15:57:30 -0000 >@@ -340,28 +340,24 @@ > } > boolean currentValid = false; > >- // d210858, if the region's a container, don't suggest the >- // enumerated values as they probably won't help >- boolean existingComplicatedValue = (contentAssistRequest.getRegion() != null) && (contentAssistRequest.getRegion() instanceof ITextRegionContainer); >- if (!existingComplicatedValue) { >- int rOffset = contentAssistRequest.getReplacementBeginPosition(); >- int rLength = contentAssistRequest.getReplacementLength(); >- for (Iterator j = possibleValues.iterator(); j.hasNext();) { >- String possibleValue = (String) j.next(); >- if(!possibleValue.equals(defaultValue)) { >- currentValid = currentValid || possibleValue.equals(currentValue); >- if ((matchString.length() == 0) || possibleValue.startsWith(matchString)) { >- String rString = "\"" + possibleValue + "\""; //$NON-NLS-2$//$NON-NLS-1$ >- CustomCompletionProposal proposal = new CustomCompletionProposal(rString, rOffset, rLength, possibleValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_ENUM), rString, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE); >- contentAssistRequest.addProposal(proposal); >- } >+ //create suggestions for enumerated values >+ int rOffset = contentAssistRequest.getReplacementBeginPosition(); >+ int rLength = contentAssistRequest.getReplacementLength(); >+ for (Iterator j = possibleValues.iterator(); j.hasNext();) { >+ String possibleValue = (String) j.next(); >+ if(!possibleValue.equals(defaultValue)) { >+ currentValid = currentValid || possibleValue.equals(currentValue); >+ if ((matchString.length() == 0) || possibleValue.startsWith(matchString)) { >+ String rString = "\"" + possibleValue + "\""; //$NON-NLS-2$//$NON-NLS-1$ >+ CustomCompletionProposal proposal = new CustomCompletionProposal(rString, rOffset, rLength, possibleValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_ENUM), rString, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE); >+ contentAssistRequest.addProposal(proposal); > } > } >- if(defaultValue != null && ((matchString.length() == 0) || defaultValue.startsWith(matchString))) { >- String rString = "\"" + defaultValue + "\""; //$NON-NLS-2$//$NON-NLS-1$ >- CustomCompletionProposal proposal = new CustomCompletionProposal(rString, rOffset, rLength, defaultValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_DEFAULT), rString, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE); >- contentAssistRequest.addProposal(proposal); >- } >+ } >+ if(defaultValue != null && ((matchString.length() == 0) || defaultValue.startsWith(matchString))) { >+ String rString = "\"" + defaultValue + "\""; //$NON-NLS-2$//$NON-NLS-1$ >+ CustomCompletionProposal proposal = new CustomCompletionProposal(rString, rOffset, rLength, defaultValue.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_DEFAULT), rString, null, proposedInfo, XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE); >+ contentAssistRequest.addProposal(proposal); > } > } > else if (((attrDecl.getUsage() == CMAttributeDeclaration.FIXED) || (attrDecl.getAttrType().getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)) && (attrDecl.getAttrType().getImpliedValue() != null)) { >@@ -1132,7 +1128,7 @@ > * @return the position the cursor should be in after the proposal is > * applied > */ >- private int getCursorPositionForProposedText(String proposedText) { >+ protected int getCursorPositionForProposedText(String proposedText) { > int cursorAdjustment; > cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$ > // otherwise, after the first tag >@@ -1262,7 +1258,34 @@ > addAttributeNameProposals(contentAssistRequest); > } > else { >- contentAssistRequest = newContentAssistRequest(nodeAtOffset, node, sdRegion, completionRegion, sdRegion.getStartOffset(completionRegion), completionRegion.getTextLength(), matchString); >+ int replaceLength = completionRegion.getTextLength(); >+ >+ //if container region, be sure replace length is only the attribute value region not the entire container >+ if(completionRegion instanceof ITextRegionContainer){ >+ ITextRegion openRegion = ((ITextRegionContainer) completionRegion).getFirstRegion(); >+ ITextRegion closeRegion = ((ITextRegionContainer) completionRegion).getLastRegion(); >+ >+ /* >+ * check to see if the container is opened the same way its closed. >+ * Such as: >+ * <img src=' ' >+ * But not: >+ * <img src=' >+ * >+ * </body> >+ * </html> >+ * In the latter case we only want to replace the opening text of the container >+ * Admittedly crude test, but effective. >+ */ >+ if(openRegion.getType() != closeRegion.getType()) { >+ replaceLength = openRegion.getTextLength(); >+ } >+ } >+ >+ contentAssistRequest = newContentAssistRequest(nodeAtOffset, node, sdRegion, >+ completionRegion, sdRegion.getStartOffset(completionRegion), >+ replaceLength, matchString); >+ > addAttributeValueProposals(contentAssistRequest); > } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 107138
:
150268
|
151343
|
153604
|
162108
|
162110