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/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java (-76 / +118 lines)
Lines 12-21 Link Here
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Arrays;
14
import java.util.Arrays;
15
import java.util.Collections;
16
import java.util.HashMap;
15
import java.util.HashMap;
17
import java.util.Iterator;
16
import java.util.Iterator;
18
import java.util.List;
17
import java.util.List;
18
import java.util.Set;
19
import java.util.TreeSet;
19
import java.util.Vector;
20
import java.util.Vector;
20
21
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.core.runtime.Path;
Lines 43-48 Link Here
43
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper;
44
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImageHelper;
44
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImages;
45
import org.eclipse.jst.jsp.ui.internal.editor.JSPEditorPluginImages;
45
import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP;
46
import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP;
47
import org.eclipse.swt.graphics.Image;
46
import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor;
48
import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor;
47
import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument;
49
import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument;
48
import org.eclipse.wst.html.core.text.IHTMLPartitions;
50
import org.eclipse.wst.html.core.text.IHTMLPartitions;
Lines 72-77 Link Here
72
import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryRegistry;
74
import org.eclipse.wst.sse.ui.internal.provisional.registry.AdapterFactoryRegistry;
73
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
75
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
74
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
76
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
77
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
75
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
78
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
76
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
79
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
77
import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser;
80
import org.eclipse.wst.xml.core.internal.parser.XMLSourceParser;
Lines 88-93 Link Here
88
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
91
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
89
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistUtilities;
92
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistUtilities;
90
import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
93
import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
94
import org.eclipse.wst.xml.ui.internal.editor.CMImageUtil;
95
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
96
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
91
import org.w3c.dom.Attr;
97
import org.w3c.dom.Attr;
92
import org.w3c.dom.Document;
98
import org.w3c.dom.Document;
93
import org.w3c.dom.Element;
99
import org.w3c.dom.Element;
Lines 245-282 Link Here
245
		ITextRegion nameRegion = null;
251
		ITextRegion nameRegion = null;
246
		while (i >= 0) {
252
		while (i >= 0) {
247
			nameRegion = openRegions.get(i--);
253
			nameRegion = openRegions.get(i--);
248
			if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME)
254
			if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
249
				break;
255
				break;
256
			}
250
		}
257
		}
251
		
258
		
252
		// on an empty value, add all the JSP and taglib tags
253
		CMElementDeclaration elementDecl = getCMElementDeclaration(node);
259
		CMElementDeclaration elementDecl = getCMElementDeclaration(node);
254
		if (nameRegion != null && elementDecl != null) {
260
		if (nameRegion != null && elementDecl != null) {
255
			String attributeName = open.getText(nameRegion);
261
			String attributeName = open.getText(nameRegion);
256
			if (attributeName != null) {
262
			if (attributeName != null) {
257
				String currentValue = node.getAttributes().getNamedItem(attributeName).getNodeValue();
263
				Node parent = contentAssistRequest.getParent();
258
				
264
				
259
				if(currentValue == null || currentValue.length() == 0) { //$NON-NLS-1$
265
				//ignore starte quote in match string
260
					List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, ModelQuery.INCLUDE_ATTRIBUTES);
266
				String matchString = contentAssistRequest.getMatchString().trim();
261
					for (i = 0; i < additionalElements.size(); i++) {
267
				if(matchString.startsWith("'") || matchString.startsWith("\"")) {
262
						Object additionalElement = additionalElements.get(i);
268
					matchString = matchString.substring(1);
263
						if(additionalElement instanceof CMElementDeclaration) {
269
				}
264
							CMElementDeclaration ed = (CMElementDeclaration) additionalElement;
270
				
265
	
271
				//get all the proposals
272
				List additionalElements = ModelQueryUtil.getModelQuery(node.getOwnerDocument()).getAvailableContent((Element) node, elementDecl, 0);
273
				Iterator nodeIterator = additionalElements.iterator();
274
				
275
				//check each suggestion
276
				while (nodeIterator.hasNext()) {
277
					CMNode additionalElementDecl = (CMNode) nodeIterator.next();
278
					if (additionalElementDecl != null && additionalElementDecl instanceof CMElementDeclaration) {
279
						CMElementDeclaration ed = (CMElementDeclaration) additionalElementDecl;
280
						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=89811
281
						StringBuffer sb = new StringBuffer();
282
						getContentGenerator().generateTag(parent, ed, sb);
283
284
						String proposedText = sb.toString();
285
286
						//filter out any proposals that dont match matchString
287
						if (beginsWith(proposedText, matchString)) {
288
							//wrap with ' because JSP attributes are warped with "
289
							proposedText = "'" + proposedText;
290
							
291
							//if its a container its possible the closing quote is already there
292
							//don't want to risk injecting an extra
293
							if(!(contentAssistRequest.getRegion() instanceof ITextRegionContainer)) {
294
								proposedText += "'";
295
							}
296
							
297
							Image image = CMImageUtil.getImage(elementDecl);
298
							if (image == null) {
299
								image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC);
300
							}
301
							
302
							//create the proposal
303
							int cursorAdjustment = getCursorPositionForProposedText(proposedText);
304
							String proposedInfo = getAdditionalInfo(getCMElementDeclaration(parent), elementDecl);
266
							String tagname = getContentGenerator().getRequiredName(node, ed);
305
							String tagname = getContentGenerator().getRequiredName(node, ed);
267
							StringBuffer contents = new StringBuffer("\""); //$NON-NLS-1$
306
							CustomCompletionProposal proposal = new CustomCompletionProposal(
268
							getContentGenerator().generateTag(node, ed, contents);
307
									proposedText, contentAssistRequest.getReplacementBeginPosition(),
269
							contents.append('"'); //$NON-NLS-1$
308
									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);
309
									XMLRelevanceConstants.R_XML_ATTRIBUTE_VALUE);
271
							contentAssistRequest.addProposal(proposal);
310
							contentAssistRequest.addProposal(proposal);
272
						}
311
						}
273
					}
312
					}
274
				
275
				}
313
				}
276
			}
314
			}
277
		}
315
		}
278
		
316
		else if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
279
		if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
280
			try {
317
			try {
281
				// Create a new model for Content Assist to operate on. This
318
				// Create a new model for Content Assist to operate on. This
282
				// will simulate
319
				// will simulate
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 721-741 Link Here
721
			fTemplateContexts.clear();
728
			fTemplateContexts.clear();
722
			jspResults = super.computeCompletionProposals(viewer, documentPosition);
729
			jspResults = super.computeCompletionProposals(viewer, documentPosition);
723
		}
730
		}
724
		if (useEmbeddedResults) {
731
		
725
			if (embeddedResults != null && embeddedResults.length > 0) {
732
		//merge the embedded results
726
				List results = new ArrayList();
733
		if (useEmbeddedResults && embeddedResults != null && embeddedResults.length > 0) {
727
				for (int i = 0; i < embeddedResults.length; i++)
734
			jspResults = merge(jspResults, embeddedResults);
728
					results.add(embeddedResults[i]);
729
				if (jspResults != null) {
730
					for (int i = 0; i < jspResults.length; i++)
731
						results.add(jspResults[i]);
732
				}
733
				jspResults = new ICompletionProposal[results.size()];
734
				Collections.sort(results, new ProposalComparator());
735
				for (int i = 0; i < results.size(); i++)
736
					jspResults[i] = (ICompletionProposal) results.get(i);
737
738
			}
739
		}
735
		}
740
		if (jspResults == null)
736
		if (jspResults == null)
741
			jspResults = EMPTY_PROPOSAL_SET;
737
			jspResults = EMPTY_PROPOSAL_SET;
Lines 793-814 Link Here
793
	}
789
	}
794
790
795
	/**
791
	/**
796
	 * Adds 2 arrays of ICompletionProposals and sorts them with a
792
	 * Adds 2 arrays of {@link ICompletionProposal}s to a {@link TreeSet}
797
	 * ProposalComparator.
793
	 * eliminating duplicates and sorting with a {@link ProposalComparator}
794
	 * then returning the new merged, filtered, sorted, array of {@link ICompletionProposal}s.
798
	 * 
795
	 * 
799
	 * @param jspResults
796
	 * @param proposalsOne
800
	 * @param htmlResults
797
	 * @param proposalsTwo
801
	 * @return
798
	 * @return a new merged, filtered, sorted array of {@link ICompletionProposal}s created from
799
	 * the two given arrays of {@link ICompletionProposal}s.
802
	 */
800
	 */
803
	private ICompletionProposal[] merge(ICompletionProposal[] jspResults, ICompletionProposal[] htmlResults) {
801
	private ICompletionProposal[] merge(ICompletionProposal[] proposalsOne, ICompletionProposal[] proposalsTwo) {
804
		List results = new ArrayList();
802
		Set results = new TreeSet(new ProposalComparator());
805
		List jsps = Arrays.asList(jspResults);
803
		List proposalsOneList = Arrays.asList(proposalsOne);
806
		List htmls = Arrays.asList(htmlResults);
804
		List proposalsTwoList = Arrays.asList(proposalsTwo);
807
805
808
		results.addAll(jsps);
806
		results.addAll(proposalsOneList);
809
		results.addAll(htmls);
807
		results.addAll(proposalsTwoList);
810
808
811
		Collections.sort(results, new ProposalComparator());
812
		return (ICompletionProposal[]) results.toArray(new ICompletionProposal[results.size()]);
809
		return (ICompletionProposal[]) results.toArray(new ICompletionProposal[results.size()]);
813
	}
810
	}
814
811
Lines 1135-1138 Link Here
1135
		addTemplates(contentAssistRequest, TemplateContextTypeIdsJSP.TAG);
1132
		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
1133
		//don't need to call super here because otherwise we duplicate what the HTMLCOntentAssistProcessor that is running is already doing
1137
	}
1134
	}
1135
	
1136
	/**
1137
	 * Different behavior if in {@link DOMRegionContext#XML_TAG_ATTRIBUTE_VALUE} region
1138
	 * otherwise calls {@link AbstractContentAssistProcessor#getMatchString(IStructuredDocumentRegion, ITextRegion, int)}
1139
	 * 
1140
	 * @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)
1141
	 */
1142
	protected String getMatchString(IStructuredDocumentRegion parent,
1143
			ITextRegion aRegion, int offset) {
1144
		
1145
		String matchString = null;
1146
		
1147
		if ((aRegion == null) || isCloseRegion(aRegion)) {
1148
			matchString = ""; //$NON-NLS-1$
1149
		} else {
1150
			String regionType = aRegion.getType();
1151
			/*
1152
			 * if attribute value then check to see if ' or " is in region and if so
1153
			 * don't count it as part of match string
1154
			 */
1155
			if(regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
1156
				if(aRegion instanceof ITextRegionContainer) {
1157
					ITextRegionContainer attrValueContainer = (ITextRegionContainer)aRegion;
1158
					int matchStartIndex = 0;
1159
					if(attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE ||
1160
							attrValueContainer.getFirstRegion().getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_SQUOTE) {
1161
						
1162
						matchStartIndex = attrValueContainer.getRegions().get(1).getStart();
1163
					}
1164
					
1165
					matchString = parent.getText(aRegion).substring(matchStartIndex, offset - parent.getStartOffset(aRegion));
1166
				} else {
1167
					matchString = parent.getText(aRegion).substring(0, offset - parent.getStartOffset(aRegion));
1168
					if(matchString.charAt(0) == '\'' || matchString.charAt(0) == '\"') {
1169
						matchString = matchString.substring(1);
1170
					}
1171
				}
1172
			}
1173
		}
1174
		
1175
		if(matchString == null) {
1176
			matchString = super.getMatchString(parent, aRegion, offset);
1177
		}
1178
		return matchString;
1179
	}
1138
}
1180
}
(-)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
		}

Return to bug 107138