Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 107138 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java (-22 / +45 lines)
Lines 340-367 Link Here
340
					}
340
					}
341
					boolean currentValid = false;
341
					boolean currentValid = false;
342
342
343
					// d210858, if the region's a container, don't suggest the
343
					//create suggestions for enumerated values
344
					// enumerated values as they probably won't help
344
					int rOffset = contentAssistRequest.getReplacementBeginPosition();
345
					boolean existingComplicatedValue = (contentAssistRequest.getRegion() != null) && (contentAssistRequest.getRegion() instanceof ITextRegionContainer);
345
					int rLength = contentAssistRequest.getReplacementLength();
346
					if (!existingComplicatedValue) {
346
					for (Iterator j = possibleValues.iterator(); j.hasNext();) {
347
						int rOffset = contentAssistRequest.getReplacementBeginPosition();
347
						String possibleValue = (String) j.next();
348
						int rLength = contentAssistRequest.getReplacementLength();
348
						if(!possibleValue.equals(defaultValue)) {
349
						for (Iterator j = possibleValues.iterator(); j.hasNext();) {
349
							currentValid = currentValid || possibleValue.equals(currentValue);
350
							String possibleValue = (String) j.next();
350
							if ((matchString.length() == 0) || possibleValue.startsWith(matchString)) {
351
							if(!possibleValue.equals(defaultValue)) {
351
								String rString = "\"" + possibleValue + "\""; //$NON-NLS-2$//$NON-NLS-1$
352
								currentValid = currentValid || possibleValue.equals(currentValue);
352
								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);
353
								if ((matchString.length() == 0) || possibleValue.startsWith(matchString)) {
353
								contentAssistRequest.addProposal(proposal);
354
									String rString = "\"" + possibleValue + "\""; //$NON-NLS-2$//$NON-NLS-1$
355
									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);
356
									contentAssistRequest.addProposal(proposal);
357
								}
358
							}
354
							}
359
						}
355
						}
360
						if(defaultValue != null && ((matchString.length() == 0) || defaultValue.startsWith(matchString))) {
356
					}
361
							String rString = "\"" + defaultValue + "\""; //$NON-NLS-2$//$NON-NLS-1$
357
					if(defaultValue != null && ((matchString.length() == 0) || defaultValue.startsWith(matchString))) {
362
							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);
358
						String rString = "\"" + defaultValue + "\""; //$NON-NLS-2$//$NON-NLS-1$
363
							contentAssistRequest.addProposal(proposal);
359
						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);
364
						}
360
						contentAssistRequest.addProposal(proposal);
365
					}
361
					}
366
				}
362
				}
367
				else if (((attrDecl.getUsage() == CMAttributeDeclaration.FIXED) || (attrDecl.getAttrType().getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)) && (attrDecl.getAttrType().getImpliedValue() != null)) {
363
				else if (((attrDecl.getUsage() == CMAttributeDeclaration.FIXED) || (attrDecl.getAttrType().getImpliedValueKind() == CMDataType.IMPLIED_VALUE_FIXED)) && (attrDecl.getAttrType().getImpliedValue() != null)) {
Lines 1132-1138 Link Here
1132
	 * @return the position the cursor should be in after the proposal is
1128
	 * @return the position the cursor should be in after the proposal is
1133
	 *         applied
1129
	 *         applied
1134
	 */
1130
	 */
1135
	private int getCursorPositionForProposedText(String proposedText) {
1131
	protected int getCursorPositionForProposedText(String proposedText) {
1136
		int cursorAdjustment;
1132
		int cursorAdjustment;
1137
		cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$
1133
		cursorAdjustment = proposedText.indexOf("\"\"") + 1; //$NON-NLS-1$
1138
		// otherwise, after the first tag
1134
		// otherwise, after the first tag
Lines 1262-1268 Link Here
1262
				addAttributeNameProposals(contentAssistRequest);
1258
				addAttributeNameProposals(contentAssistRequest);
1263
			}
1259
			}
1264
			else {
1260
			else {
1265
				contentAssistRequest = newContentAssistRequest(nodeAtOffset, node, sdRegion, completionRegion, sdRegion.getStartOffset(completionRegion), completionRegion.getTextLength(), matchString);
1261
				int replaceLength = completionRegion.getTextLength();
1262
				
1263
				//if container region, be sure replace length is only the attribute value region not the entire container
1264
				if(completionRegion instanceof ITextRegionContainer){
1265
					ITextRegion openRegion = ((ITextRegionContainer) completionRegion).getFirstRegion();
1266
					ITextRegion closeRegion = ((ITextRegionContainer) completionRegion).getLastRegion();
1267
					
1268
					/*
1269
					 * check to see if the container is opened the same way its closed.
1270
					 * Such as:
1271
					 * <img src=' '
1272
					 * But not:
1273
					 * <img src='
1274
					 * 
1275
					 * </body>
1276
					 * </html>
1277
					 * In the latter case we only want to replace the opening text of the container
1278
					 * Admittedly crude test, but effective.
1279
					 */
1280
					if(openRegion.getType() != closeRegion.getType()) {
1281
						replaceLength = openRegion.getTextLength();
1282
					}
1283
				} 
1284
				
1285
				contentAssistRequest = newContentAssistRequest(nodeAtOffset, node, sdRegion,
1286
						completionRegion, sdRegion.getStartOffset(completionRegion),
1287
						replaceLength, matchString);
1288
				
1266
				addAttributeValueProposals(contentAssistRequest);
1289
				addAttributeValueProposals(contentAssistRequest);
1267
			}
1290
			}
1268
		}
1291
		}
(-)src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java (-46 / +98 lines)
Lines 43-48 Link Here
43
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper;
43
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper;
44
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImages;
44
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImages;
45
import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP;
45
import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP;
46
import org.eclipse.swt.graphics.Image;
46
import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor;
47
import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor;
47
import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument;
48
import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument;
48
import org.eclipse.wst.html.core.text.IHTMLPartitions;
49
import org.eclipse.wst.html.core.text.IHTMLPartitions;
Lines 72-77 Link Here
72
import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryRegistry;
73
import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryRegistry;
73
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
74
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
74
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
75
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
76
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
75
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
77
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
76
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
78
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
77
import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser;
79
import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser;
Lines 88-93 Link Here
88
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
90
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
89
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistUtilities;
91
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistUtilities;
90
import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
92
import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
93
import org.eclipse.wst.xml.ui.internal.editor.CMImageUtil;
94
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
95
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
91
import org.w3c.dom.Attr;
96
import org.w3c.dom.Attr;
92
import org.w3c.dom.Document;
97
import org.w3c.dom.Document;
93
import org.w3c.dom.Element;
98
import org.w3c.dom.Element;
Lines 245-277 Link Here
245
		ITextRegion nameRegion = null;
250
		ITextRegion nameRegion = null;
246
		while (i >= 0) {
251
		while (i >= 0) {
247
			nameRegion = openRegions.get(i--);
252
			nameRegion = openRegions.get(i--);
248
			if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME)
253
			if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
249
				break;
254
				break;
255
			}
250
		}
256
		}
251
		
257
		
252
		// on an empty value, add all the JSP and taglib tags
253
		CMElementDeclaration elementDecl = getCMElementDeclaration(node);
258
		CMElementDeclaration elementDecl = getCMElementDeclaration(node);
254
		if (nameRegion != null && elementDecl != null) {
259
		if (nameRegion != null && elementDecl != null) {
255
			String attributeName = open.getText(nameRegion);
260
			String attributeName = open.getText(nameRegion);
256
			if (attributeName != null) {
261
			if (attributeName != null) {
257
				String currentValue = node.getAttributes().getNamedItem(attributeName).getNodeValue();
262
				Node parent = contentAssistRequest.getParent();
258
				
263
				
259
				if(currentValue == null || currentValue.length() == 0) { //$NON-NLS-1$
264
				//ignore starte quote in match string
260
					List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, ModelQuery.INCLUDE_ATTRIBUTES);
265
				String matchString = contentAssistRequest.getMatchString().trim();
261
					for (i = 0; i < additionalElements.size(); i++) {
266
				if(matchString.startsWith("'") || matchString.startsWith("\"")) {
262
						Object additionalElement = additionalElements.get(i);
267
					matchString = matchString.substring(1);
263
						if(additionalElement instanceof CMElementDeclaration) {
268
				}
264
							CMElementDeclaration ed = (CMElementDeclaration) additionalElement;
269
				
265
	
270
				//get all the proposals
271
				List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, 0);
272
				Iterator nodeIterator = additionalElements.iterator();
273
				
274
				//check each suggestion
275
				while (nodeIterator.hasNext()) {
276
					CMNode additionalElementDecl = (CMNode) nodeIterator.next();
277
					if (additionalElementDecl != null && additionalElementDecl instanceof CMElementDeclaration) {
278
						CMElementDeclaration ed = (CMElementDeclaration) additionalElementDecl;
279
						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=89811
280
						StringBuffer sb = new StringBuffer();
281
						getContentGenerator().generateTag(parent, ed, sb);
282
283
						String proposedText = sb.toString();
284
285
						//filter out any proposals that dont match matchString
286
						if (beginsWith(proposedText, matchString)) {
287
							//wrap with ' because JSP attributes are warped with "
288
							proposedText = "'" + proposedText;
289
							
290
							//if its a container its possible the closing quote is already there
291
							//don't want to risk injecting an extra
292
							if(!(contentAssistRequest.getRegion() instanceof ITextRegionContainer)) {
293
								proposedText += "'";
294
							}
295
							
296
							Image image = CMImageUtil.getImage(elementDecl);
297
							if (image == null) {
298
								image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC);
299
							}
300
							
301
							//create the proposal
302
							int cursorAdjustment = getCursorPositionForProposedText(proposedText);
303
							String proposedInfo = getAdditionalInfo(getCMElementDeclaration(parent), elementDecl);
266
							String tagname = getContentGenerator().getRequiredName(node, ed);
304
							String tagname = getContentGenerator().getRequiredName(node, ed);
267
							StringBuffer contents = new StringBuffer("\""); //$NON-NLS-1$
305
							CustomCompletionProposal proposal = new CustomCompletionProposal(
268
							getContentGenerator().generateTag(node, ed, contents);
306
									proposedText, contentAssistRequest.getReplacementBeginPosition(),
269
							contents.append('"'); //$NON-NLS-1$
307
									contentAssistRequest.getReplacementLength(), cursorAdjustment, image, tagname, null, proposedInfo,
270
							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);
308
									XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
271
							contentAssistRequest.addProposal(proposal);
309
							contentAssistRequest.addProposal(proposal);
272
						}
310
						}
273
					}
311
					}
274
				
275
				}
312
				}
276
			}
313
			}
277
		}
314
		}
Lines 400-407 Link Here
400
				Logger.logException("Error in embedded JSP Content Assist", e); //$NON-NLS-1$
437
				Logger.logException("Error in embedded JSP Content Assist", e); //$NON-NLS-1$
401
			}
438
			}
402
		}
439
		}
403
404
405
	}
440
	}
406
441
407
	/**
442
	/**
Lines 668-702 Link Here
668
			}
703
			}
669
		}
704
		}
670
705
671
		// check if it's in an attribute value, if so, don't add CDATA
706
		//get the embedded results
672
		// proposal
673
		ITextRegion attrContainer = (fn != null) ? fn.getRegionAtCharacterOffset(documentPosition) : null;
674
		if (attrContainer != null && attrContainer instanceof ITextRegionContainer) {
675
			if (attrContainer.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
676
				// test location of the cursor
677
				// return null if it's in the middle of an open/close
678
				// delimeter
679
				Iterator attrRegions = ((ITextRegionContainer) attrContainer).getRegions().iterator();
680
				ITextRegion testRegion = null;
681
				while (attrRegions.hasNext()) {
682
					testRegion = (ITextRegion) attrRegions.next();
683
					// need to check for other valid attribute regions
684
					if (XMLContentAssistUtilities.isJSPOpenDelimiter(testRegion.getType())) {
685
						if (!(((ITextRegionContainer) attrContainer).getEndOffset(testRegion) <= documentPosition))
686
							return EMPTY_PROPOSAL_SET;
687
					}
688
					else if (XMLContentAssistUtilities.isJSPCloseDelimiter(testRegion.getType())) {
689
						if (!(((ITextRegionContainer) attrContainer).getStartOffset(testRegion) >= documentPosition))
690
							return EMPTY_PROPOSAL_SET;
691
					}
692
				}
693
				// TODO: handle non-Java code such as nested tags
694
				if (testRegion.getType().equals(DOMJSPRegionContexts.JSP_CONTENT))
695
					return getJSPJavaCompletionProposals(viewer, documentPosition);
696
				return EMPTY_PROPOSAL_SET;
697
			}
698
		}
699
700
		IContentAssistProcessor p = (IContentAssistProcessor) fPartitionToProcessorMap.get(partitionType);
707
		IContentAssistProcessor p = (IContentAssistProcessor) fPartitionToProcessorMap.get(partitionType);
701
		if (p != null) {
708
		if (p != null) {
702
			embeddedResults = p.computeCompletionProposals(viewer, documentPosition);
709
			embeddedResults = p.computeCompletionProposals(viewer, documentPosition);
Lines 1135-1138 Link Here
1135
		addTemplates(contentAssistRequest, TemplateContextTypeIdsJSP.TAG);
1142
		addTemplates(contentAssistRequest, TemplateContextTypeIdsJSP.TAG);
1136
		//don't need to call super here because otherwise we duplicate what the HTMLCOntentAssistProcessor that is running is already doing
1143
		//don't need to call super here because otherwise we duplicate what the HTMLCOntentAssistProcessor that is running is already doing
1137
	}
1144
	}
1145
	
1146
	/**
1147
	 * Different behavior if in {@link DOMRegionContext#XML_TAG_ATTRIBUTE_VALUE} region
1148
	 * otherwise calls {@link AbstractContentAssistProcessor#getMatchString(IStructuredDocumentRegion, ITextRegion, int)}
1149
	 * 
1150
	 * @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)
1151
	 */
1152
	protected String getMatchString(IStructuredDocumentRegion parent,
1153
			ITextRegion aRegion, int offset) {
1154
		
1155
		String matchString = null;
1156
		
1157
		if ((aRegion == null) || isCloseRegion(aRegion)) {
1158
			matchString = ""; //$NON-NLS-1$
1159
		} else {
1160
			String regionType = aRegion.getType();
1161
			/*
1162
			 * if attribute value then check to see if ' or " is in region and if so
1163
			 * don't count it as part of match string
1164
			 */
1165
			if(regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
1166
				if(aRegion instanceof ITextRegionContainer) {
1167
					ITextRegionContainer attrValueContainer = (ITextRegionContainer)aRegion;
1168
					int matchStartIndex = 0;
1169
					if(attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE ||
1170
							attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_SQUOTE) {
1171
						
1172
						matchStartIndex = attrValueContainer.getRegions().get(1).getStart();
1173
					}
1174
					
1175
					matchString = parent.getText(aRegion).substring(matchStartIndex, offset - parent.getStartOffset(aRegion));
1176
				} else {
1177
					matchString = parent.getText(aRegion).substring(0, offset - parent.getStartOffset(aRegion));
1178
					if(matchString.charAt(0) == '\'' || matchString.charAt(0) == '\"') {
1179
						matchString = matchString.substring(1);
1180
					}
1181
				}
1182
			}
1183
		}
1184
		
1185
		if(matchString == null) {
1186
			matchString = super.getMatchString(parent, aRegion, offset);
1187
		}
1188
		return matchString;
1189
	}
1138
}
1190
}

Return to bug 107138