diff options
author | vrubezhny | 2014-10-22 00:48:32 +0000 |
---|---|---|
committer | Nick Sandonato | 2015-03-06 16:19:40 +0000 |
commit | 238bcaeb30bdeee6645dd5eef7e1cca4b0f6572d (patch) | |
tree | 050608c0299dea4bcb79e9959ab8fb2f31f86c1a | |
parent | 20579b8a789144d304a63a86af06be73bf19b7d6 (diff) | |
download | webtools.sourceediting-238bcaeb30bdeee6645dd5eef7e1cca4b0f6572d.tar.gz webtools.sourceediting-238bcaeb30bdeee6645dd5eef7e1cca4b0f6572d.tar.xz webtools.sourceediting-238bcaeb30bdeee6645dd5eef7e1cca4b0f6572d.zip |
Bug 448152 - [validation] Ability to ignore custom html tag (UI part that adds Validation Pref. page changes and new QuickFix)
Now it's able to ignore html element names from validation using comma-separated name patterns, that can be
specified on Validation Preference page, or set by a quick fix.
This is the UI Part that adds the possibility to set the new preference value on Validation Preference page as well as
adds the new QuickFix that allows a user to add new tag names to be ignored in validation.
Signed-off-by: vrubezhny <vrubezhny@exadel.com>
7 files changed, 630 insertions, 29 deletions
diff --git a/bundles/org.eclipse.wst.html.ui/plugin.xml b/bundles/org.eclipse.wst.html.ui/plugin.xml index 2f5a0348e1..b99c5f0b87 100644 --- a/bundles/org.eclipse.wst.html.ui/plugin.xml +++ b/bundles/org.eclipse.wst.html.ui/plugin.xml @@ -54,6 +54,10 @@ class="org.eclipse.wst.html.ui.internal.text.correction.HTMLAttributeValidationQuickFixProcessor" target="org.eclipse.wst.html.HTML_DEFAULT" /> <provisionalConfiguration + type="org.eclipse.jface.text.quickassist.IQuickAssistProcessor" + class="org.eclipse.wst.html.ui.internal.text.correction.HTMLSyntaxValidationQuickFixProcessor" + target="org.eclipse.wst.html.HTML_DEFAULT" /> + <provisionalConfiguration type="autoeditstrategy" class="org.eclipse.wst.html.ui.internal.autoedit.StructuredAutoEditStrategyHTML" target="org.eclipse.wst.html.HTML_DEFAULT, org.eclipse.wst.html.HTML_DECLARATION" /> diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIMessages.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIMessages.java index 153850622a..275cdfbe7a 100644 --- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIMessages.java +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIMessages.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2005, 2013 IBM Corporation and others. All rights reserved. This + * Copyright (c) 2005, 2014 IBM Corporation and others. All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html @@ -210,6 +210,15 @@ public class HTMLUIMessages extends NLS { public static String Hyperlink_line; public static String Open; + // Ignore Element Name Patterns + public static String IgnoreElementNames; + public static String IgnoreElementNamesPattern; + public static String BadIgnoreElementNamesPattern; + public static String DoNotValidateElement; + public static String DoNotValidateAllElements; + public static String DoNotValidateElementAddInfo; + public static String DoNotValidateAllElementsAddInfo; + // Ignore Attribute Name Patterns public static String IgnoreAttributeNames; public static String IgnoreAttributeNamesPattern; diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIPluginResources.properties b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIPluginResources.properties index b1e3b7899d..bdf842b955 100644 --- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIPluginResources.properties +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/HTMLUIPluginResources.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2004, 2013 IBM Corporation and others. +# Copyright (c) 2004, 2014 IBM Corporation and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -182,6 +182,14 @@ HTMLValidationPreferencePage_37=Missing attribute equals sign character: Hyperlink_line={0}={1} : line {2} Open=Open ''{0}'' +IgnoreElementNames=Ignore specified element names in validation +IgnoreElementNamesPattern=Specify comma-separated patterns for element names to be ignored: +BadIgnoreElementNamesPattern=''{0}'' is not a valid element names pattern +DoNotValidateElement=Ignore ''{0}'' element in validation +DoNotValidateAllElements=Ignore all ''{0}'' elements in validation +DoNotValidateElementAddInfo=Adds the name of element to the list of ignored elements for HTML Syntax Validator<br>You may edit the list of ignored elements at <b>Web→HTML Files→Validation</b> Preference Page +DoNotValidateAllElementsAddInfo=Adds the pattern based on the element name to the list of ignored elements for HTML Syntax Validator<br>You may edit the list of ignored elements at <b>Web→HTML Files→Validation</b> Preference Page + IgnoreAttributeNames=Ignore specified attribute names in validation IgnoreAttributeNamesPattern=Specify comma-separated patterns for attribute names to be ignored: BadIgnoreAttributeNamesPattern=''{0}'' is not a valid attribute names pattern diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/preferences/ui/HTMLValidationPreferencePage.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/preferences/ui/HTMLValidationPreferencePage.java index b707d1d30f..1b92fc27a9 100644 --- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/preferences/ui/HTMLValidationPreferencePage.java +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/preferences/ui/HTMLValidationPreferencePage.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; @@ -39,8 +40,10 @@ import org.eclipse.wst.html.ui.internal.HTMLUIMessages; import org.eclipse.wst.html.ui.internal.HTMLUIPlugin; import org.eclipse.wst.html.ui.internal.Logger; import org.eclipse.wst.sse.core.internal.validate.ValidationMessage; +import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; import org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractValidationSettingsPage; import org.eclipse.wst.sse.ui.internal.preferences.ui.ScrolledPageContent; +import org.eclipse.wst.sse.ui.internal.provisional.preferences.CommonEditorPreferenceNames; import org.osgi.service.prefs.BackingStoreException; public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage { @@ -131,19 +134,55 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage } private PixelConverter fPixelConverter; + private Button fIgnoreElementNames; + private Label fIgnoredElementNamesLabel; + private Text fIgnoredElementNames; private Button fIgnoreAttributeNames; private Label fIgnoredAttributeNamesLabel; private Text fIgnoredAttributeNames; private IPreferencesService fPreferencesService = null; - private boolean fUseOriginOverrides = false; + private boolean fUseElementsOriginOverrides = false; + private boolean fIgnoreElementNamesOriginOverride = HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES_DEFAULT; + private String fIgnoredElementNamesOriginOverride = HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE_DEFAULT; + + private boolean fUseAttributesOriginOverrides = false; private boolean fIgnoreAttributeNamesOriginOverride = HTMLCorePreferenceNames.IGNORE_ATTRIBUTE_NAMES_DEFAULT; private String fIgnoredAttributeNamesOriginOverride = HTMLCorePreferenceNames.ATTRIBUTE_NAMES_TO_IGNORE_DEFAULT; + public void overrideIgnoredElementsOriginValues(boolean enableIgnore, String elementNames) { + fIgnoreElementNamesOriginOverride = enableIgnore; + fIgnoredElementNamesOriginOverride = elementNames; + fUseElementsOriginOverrides = true; + + if (fIgnoreElementNames != null) { + BooleanData data = (BooleanData)fIgnoreElementNames.getData(); + if (data != null) + data.originalValue = fIgnoreElementNamesOriginOverride; + } + if (fIgnoredElementNames != null) { + TextData data = (TextData)fIgnoredElementNames.getData(); + if (data != null) + data.originalValue = fIgnoredElementNamesOriginOverride; + } + } + + /** + * Overrides the origin values for Ignored Attribute Names + * + * @deprecated Use overrideIgnoredAttributesOriginValues(boolean, String) + * + * @param enableIgnore + * @param attributeNames + */ public void overrideOriginValues(boolean enableIgnore, String attributeNames) { + this.overrideIgnoredAttributesOriginValues(enableIgnore, attributeNames); + } + + public void overrideIgnoredAttributesOriginValues(boolean enableIgnore, String attributeNames) { fIgnoreAttributeNamesOriginOverride = enableIgnore; fIgnoredAttributeNamesOriginOverride = attributeNames; - fUseOriginOverrides = true; + fUseAttributesOriginOverrides = true; if (fIgnoreAttributeNames != null) { BooleanData data = (BooleanData)fIgnoreAttributeNames.getData(); @@ -156,7 +195,7 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage data.originalValue = fIgnoredAttributeNamesOriginOverride; } } - + protected Control createCommonContents(Composite parent) { final Composite page = new Composite(parent, SWT.NULL); @@ -188,8 +227,61 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage layout.marginWidth= 0; composite.setLayout(layout); + // Ignored Element Names Pattern + BooleanData ignoreData = new BooleanData(HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES); + fIgnoreElementNames = new Button(composite, SWT.CHECK); + fIgnoreElementNames.setData(ignoreData); + fIgnoreElementNames.setFont(page.getFont()); + fIgnoreElementNames.setText(HTMLUIMessages.IgnoreElementNames); + fIgnoreElementNames.setEnabled(true); + + boolean ignoreElementNamesIsSelected = fPreferencesService.getBoolean(getPreferenceNodeQualifier(), + ignoreData.getKey(), HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES_DEFAULT, createPreferenceScopes()); + ignoreData.setValue(ignoreElementNamesIsSelected); + ignoreData.originalValue = fUseElementsOriginOverrides ? fIgnoreElementNamesOriginOverride : ignoreElementNamesIsSelected; + + fIgnoreElementNames.setSelection(ignoreData.getValue()); + fIgnoreElementNames.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + controlChanged(e.widget); + } + public void widgetSelected(SelectionEvent e) { + controlChanged(e.widget); + } + }); + fIgnoreElementNames.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); + + fIgnoredElementNamesLabel = new Label(composite, SWT.LEFT | SWT.WRAP); + fIgnoredElementNamesLabel.setFont(composite.getFont()); + fIgnoredElementNamesLabel.setEnabled(ignoreData.getValue()); + fIgnoredElementNamesLabel.setText(HTMLUIMessages.IgnoreElementNamesPattern); + fIgnoredElementNamesLabel.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false, 3, 1)); + setHorizontalIndent(fIgnoredElementNamesLabel, 20); + + TextData data = new TextData(HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE); + fIgnoredElementNames = new Text(composite, SWT.SINGLE | SWT.BORDER); + fIgnoredElementNames.setData(data); + fIgnoredElementNames.setTextLimit(500); + fIgnoredElementNames.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1)); + setHorizontalIndent(fIgnoredElementNames, 20); + setWidthHint(fIgnoredElementNames, convertWidthInCharsToPixels(65)); + String ignoredElementNames = fPreferencesService.getString(getPreferenceNodeQualifier(), data.getKey(), HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE_DEFAULT, createPreferenceScopes()); + data.setValue(ignoredElementNames); + data.originalValue = fUseElementsOriginOverrides ? fIgnoredElementNamesOriginOverride : ignoredElementNames; + fIgnoredElementNames.setText(data.getValue()); + + fIgnoredElementNames.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent e) { + if (verifyIgnoredNames(fIgnoredElementNames.getText().trim())) { + controlChanged(e.widget); + } + } + }); + controlChanged(fIgnoreElementNames); + // Ignored Attribute Names Pattern - BooleanData ignoreData = new BooleanData(HTMLCorePreferenceNames.IGNORE_ATTRIBUTE_NAMES); + ignoreData = new BooleanData(HTMLCorePreferenceNames.IGNORE_ATTRIBUTE_NAMES); fIgnoreAttributeNames = new Button(composite, SWT.CHECK); fIgnoreAttributeNames.setData(ignoreData); fIgnoreAttributeNames.setFont(page.getFont()); @@ -199,7 +291,7 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage boolean ignoreAttributeNamesIsSelected = fPreferencesService.getBoolean(getPreferenceNodeQualifier(), ignoreData.getKey(), HTMLCorePreferenceNames.IGNORE_ATTRIBUTE_NAMES_DEFAULT, createPreferenceScopes()); ignoreData.setValue(ignoreAttributeNamesIsSelected); - ignoreData.originalValue = fUseOriginOverrides ? fIgnoreAttributeNamesOriginOverride : ignoreAttributeNamesIsSelected; + ignoreData.originalValue = fUseAttributesOriginOverrides ? fIgnoreAttributeNamesOriginOverride : ignoreAttributeNamesIsSelected; fIgnoreAttributeNames.setSelection(ignoreData.getValue()); fIgnoreAttributeNames.addSelectionListener(new SelectionListener() { @@ -219,7 +311,7 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage fIgnoredAttributeNamesLabel.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false, 3, 1)); setHorizontalIndent(fIgnoredAttributeNamesLabel, 20); - TextData data = new TextData(HTMLCorePreferenceNames.ATTRIBUTE_NAMES_TO_IGNORE); + data = new TextData(HTMLCorePreferenceNames.ATTRIBUTE_NAMES_TO_IGNORE); fIgnoredAttributeNames = new Text(composite, SWT.SINGLE | SWT.BORDER); fIgnoredAttributeNames.setData(data); fIgnoredAttributeNames.setTextLimit(500); @@ -228,13 +320,13 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage setWidthHint(fIgnoredAttributeNames, convertWidthInCharsToPixels(65)); String ignoredAttributeNames = fPreferencesService.getString(getPreferenceNodeQualifier(), data.getKey(), HTMLCorePreferenceNames.ATTRIBUTE_NAMES_TO_IGNORE_DEFAULT, createPreferenceScopes()); data.setValue(ignoredAttributeNames); - data.originalValue = fUseOriginOverrides ? fIgnoredAttributeNamesOriginOverride : ignoredAttributeNames; + data.originalValue = fUseAttributesOriginOverrides ? fIgnoredAttributeNamesOriginOverride : ignoredAttributeNames; fIgnoredAttributeNames.setText(data.getValue()); fIgnoredAttributeNames.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { - if (verifyIgnoredAttributeNames()) { + if (verifyIgnoredNames(fIgnoredAttributeNames.getText().trim())) { controlChanged(e.widget); } } @@ -470,14 +562,13 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage } } - private boolean verifyIgnoredAttributeNames() { - final String text = fIgnoredAttributeNames.getText().trim(); - if (text.length() == 0) + private boolean verifyIgnoredNames(String value) { + if (value.length() == 0) return true; - String[] names = text.split(","); //$NON-NLS-1$ + String[] names = value.split(","); //$NON-NLS-1$ boolean valid = true; - for (int i = 0; names != null && i < names.length; i++) { + for (int i = 0; valid && names != null && i < names.length; i++) { String name = names[i] == null ? null : names[i].trim(); if (name != null && name.length() > 0) { for (int j = 0; valid && j < name.length(); j++) { @@ -490,7 +581,7 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage } if (!valid) { - setErrorMessage(NLS.bind(HTMLUIMessages.BadIgnoreAttributeNamesPattern, text)); + setErrorMessage(NLS.bind(HTMLUIMessages.BadIgnoreAttributeNamesPattern, value)); setValid(false); } else { setErrorMessage(null); @@ -508,10 +599,18 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage BooleanData data = (BooleanData) widget.getData(); if (data != null) { data.setValue(((Button)widget).getSelection()); - fIgnoredAttributeNamesLabel.setEnabled(data.getValue()); - fIgnoredAttributeNames.setEnabled(data.getValue()); - if (data.getValue()) { - fIgnoredAttributeNames.setFocus(); + if (fIgnoreElementNames == widget) { + fIgnoredElementNamesLabel.setEnabled(data.getValue()); + fIgnoredElementNames.setEnabled(data.getValue()); + if (data.getValue()) { + fIgnoredElementNames.setFocus(); + } + } else if (fIgnoreAttributeNames == widget) { + fIgnoredAttributeNamesLabel.setEnabled(data.getValue()); + fIgnoredAttributeNames.setEnabled(data.getValue()); + if (data.getValue()) { + fIgnoredAttributeNames.setFocus(); + } } } } else { @@ -524,11 +623,19 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage * causing the full validation to be requested. */ protected boolean shouldRevalidateOnSettingsChange() { - TextData data = (TextData)fIgnoredAttributeNames.getData(); + TextData data = (TextData)fIgnoredElementNames.getData(); + if (data.isChanged()) + return true; + + BooleanData ignoreData = (BooleanData)fIgnoreElementNames.getData(); + if (ignoreData.isChanged()) + return true; + + data = (TextData)fIgnoredAttributeNames.getData(); if (data.isChanged()) return true; - BooleanData ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); + ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); if (ignoreData.isChanged()) return true; @@ -542,11 +649,19 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage protected void storeValues() { IScopeContext[] contexts = createPreferenceScopes(); - BooleanData ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); + BooleanData ignoreData = (BooleanData)fIgnoreElementNames.getData(); contexts[0].getNode(getPreferenceNodeQualifier()).putBoolean(ignoreData.getKey(), ignoreData.getValue()); ignoreData.originalValue = ignoreData.getValue(); - TextData data = (TextData)fIgnoredAttributeNames.getData(); + TextData data = (TextData)fIgnoredElementNames.getData(); + contexts[0].getNode(getPreferenceNodeQualifier()).put(data.getKey(), data.getValue()); + data.originalValue = data.getValue(); + + ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); + contexts[0].getNode(getPreferenceNodeQualifier()).putBoolean(ignoreData.getKey(), ignoreData.getValue()); + ignoreData.originalValue = ignoreData.getValue(); + + data = (TextData)fIgnoredAttributeNames.getData(); contexts[0].getNode(getPreferenceNodeQualifier()).put(data.getKey(), data.getValue()); data.originalValue = data.getValue(); @@ -559,6 +674,15 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage } super.storeValues(); + + forceReconciling(); + } + + private void forceReconciling() { + IPreferenceStore store = SSEUIPlugin.getDefault().getPreferenceStore(); + boolean value = store.getBoolean(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS); + store.setValue(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS, !value); + store.setValue(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS, value); } /* @@ -566,19 +690,30 @@ public class HTMLValidationPreferencePage extends AbstractValidationSettingsPage * @see org.eclipse.jface.preference.PreferencePage#performDefaults() */ protected void performDefaults() { - resetIgnoreAttributeNamesPattern(); + resetIgnoreNamesPatterns(); resetSeverities(); super.performDefaults(); } - protected void resetIgnoreAttributeNamesPattern() { + protected void resetIgnoreNamesPatterns() { IEclipsePreferences defaultContext = new DefaultScope().getNode(getPreferenceNodeQualifier()); - BooleanData ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); + + BooleanData ignoreData = (BooleanData)fIgnoreElementNames.getData(); + boolean ignoreElementNames = defaultContext.getBoolean(ignoreData.getKey(), HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES_DEFAULT); + ignoreData.setValue(ignoreElementNames); + fIgnoreElementNames.setSelection(ignoreData.getValue()); + + TextData data = (TextData)fIgnoredElementNames.getData(); + String ignoredElementNames = defaultContext.get(data.getKey(), HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE_DEFAULT); + data.setValue(ignoredElementNames); + fIgnoredElementNames.setText(data.getValue()); + + ignoreData = (BooleanData)fIgnoreAttributeNames.getData(); boolean ignoreAttributeNames = defaultContext.getBoolean(ignoreData.getKey(), HTMLCorePreferenceNames.IGNORE_ATTRIBUTE_NAMES_DEFAULT); ignoreData.setValue(ignoreAttributeNames); fIgnoreAttributeNames.setSelection(ignoreData.getValue()); - TextData data = (TextData)fIgnoredAttributeNames.getData(); + data = (TextData)fIgnoredAttributeNames.getData(); String ignoredAttributeNames = defaultContext.get(data.getKey(), HTMLCorePreferenceNames.ATTRIBUTE_NAMES_TO_IGNORE_DEFAULT); data.setValue(ignoredAttributeNames); fIgnoredAttributeNames.setText(data.getValue()); diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/HTMLSyntaxValidationQuickFixProcessor.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/HTMLSyntaxValidationQuickFixProcessor.java new file mode 100644 index 0000000000..8519da1ec8 --- /dev/null +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/HTMLSyntaxValidationQuickFixProcessor.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.text.correction; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext; +import org.eclipse.jface.text.quickassist.IQuickAssistProcessor; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelExtension2; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.texteditor.MarkerAnnotation; +import org.eclipse.wst.html.core.internal.HTMLCoreMessages; +import org.eclipse.wst.html.core.internal.HTMLCorePlugin; +import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames; +import org.eclipse.wst.html.core.internal.validate.StringMatcher; +import org.eclipse.wst.html.ui.internal.HTMLUIMessages; +import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils; +import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation; +import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; +import org.w3c.dom.Element; + +public class HTMLSyntaxValidationQuickFixProcessor implements IQuickAssistProcessor { + + private StringMatcher UNKNOWN_ELEMENT_NAME_MATCHER; + private IPreferencesService fPreferenceService; + + public HTMLSyntaxValidationQuickFixProcessor() { + UNKNOWN_ELEMENT_NAME_MATCHER = new StringMatcher(NLS.bind(HTMLCoreMessages.Unknown_tag___0____ERROR_, "*")); //$NON-NLS-1$ + fPreferenceService = Platform.getPreferencesService(); + } + + /* + * @see org.eclipse.jface.text.quickassist.IQuickAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* + * @see org.eclipse.jface.text.quickassist.IQuickAssistProcessor#canFix(org.eclipse.jface.text.source.Annotation) + */ + public boolean canFix(Annotation annotation) { + boolean result = false; + + String text = null; + if (annotation instanceof TemporaryAnnotation) { + TemporaryAnnotation tempAnnotation = (TemporaryAnnotation) annotation; + int problemID = tempAnnotation.getProblemID(); + text = tempAnnotation.getText(); + + if (problemID == 0 && text != null) + result = true; + } else if (annotation instanceof MarkerAnnotation) { + MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation; + text = markerAnnotation.getText(); + IMarker marker = markerAnnotation.getMarker(); + IResource resource = marker == null ? null : marker.getResource(); + if (resource != null && resource.exists() && resource.isAccessible() && text != null) { + result = true; + } + } + + result = (result && UNKNOWN_ELEMENT_NAME_MATCHER.match(text)); + + return result; + } + + /* + * @see org.eclipse.jface.text.quickassist.IQuickAssistProcessor#canAssist(org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext) + */ + public boolean canAssist(IQuickAssistInvocationContext invocationContext) { + return true; + } + + /* + * @see org.eclipse.jface.text.quickassist.IQuickAssistProcessor#computeQuickAssistProposals(org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext) + */ + public ICompletionProposal[] computeQuickAssistProposals( + IQuickAssistInvocationContext invocationContext) { + ISourceViewer viewer = invocationContext.getSourceViewer(); + int documentOffset = invocationContext.getOffset(); + int length = viewer != null ? viewer.getSelectedRange().y : 0; + + IAnnotationModel model = viewer.getAnnotationModel(); + if (model == null) + return null; + + List proposals = new ArrayList(); + if (model instanceof IAnnotationModelExtension2) { + Iterator iter = ((IAnnotationModelExtension2) model).getAnnotationIterator(documentOffset, length, true, true); + while (iter.hasNext()) { + Annotation anno = (Annotation) iter.next(); + if (canFix(anno)) { + int offset = -1; + + if (anno instanceof TemporaryAnnotation) { + offset = ((TemporaryAnnotation)anno).getPosition().getOffset(); + } else if (anno instanceof MarkerAnnotation) { + offset = ((MarkerAnnotation)anno).getMarker().getAttribute(IMarker.CHAR_START, -1); + } + if (offset == -1) + continue; + + IDOMNode node = (IDOMNode) ContentAssistUtils.getNodeAt(viewer, offset); + if (!(node instanceof Element)) + continue; + + Object adapter = (node instanceof IAdaptable ? ((IAdaptable)node).getAdapter(IResource.class) : null); + IProject project = (adapter instanceof IResource ? ((IResource)adapter).getProject() : null); + + IScopeContext[] fLookupOrder = new IScopeContext[] {new InstanceScope(), new DefaultScope()}; + if (project != null) { + ProjectScope projectScope = new ProjectScope(project); + if(projectScope.getNode(getPreferenceNodeQualifier()) + .getBoolean(getProjectSettingsKey(), false)) + fLookupOrder = new IScopeContext[] {projectScope, new InstanceScope(), new DefaultScope()}; + } + + boolean ignore = fPreferenceService.getBoolean( + getPreferenceNodeQualifier(), HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES, + HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES_DEFAULT, fLookupOrder); + + String ignoreList = fPreferenceService.getString( + getPreferenceNodeQualifier(), HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE, + HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE_DEFAULT, fLookupOrder); + + Set result = new HashSet(); + if (ignoreList.trim().length() > 0) { + String[] names = ignoreList.split(","); //$NON-NLS-1$ + for (int i = 0; names != null && i < names.length; i++) { + String name = names[i] == null ? null : names[i].trim(); + if (name != null && name.length() > 0) + result.add(name.toLowerCase()); + } + } + + String name = getElementName(node, offset); + if (name == null) continue; + + // If ignore == false. then show a quick fix anyway (due to allow to turn 'ignore' option on) + if (!ignore || shouldShowQuickFix(result, name.toLowerCase())) { + IgnoreElementNameCompletionProposal p = new IgnoreElementNameCompletionProposal( + name.toLowerCase(), offset, NLS.bind(HTMLUIMessages.DoNotValidateElement, name), + HTMLUIMessages.DoNotValidateElementAddInfo, node); + if (!proposals.contains(p)) + proposals.add(p); + } + + int dashIndex = name.indexOf('-'); + while (dashIndex != -1) { + StringBuffer namePattern = new StringBuffer(name.substring(0, dashIndex + 1)).append('*'); + + // Do not continue creating proposals for the rest of patterns if + // a more common pattern is already created + if (ignore && result.contains(namePattern.toString().toLowerCase())) + break; + + IgnoreElementNameCompletionProposal p = new IgnoreElementNameCompletionProposal( + namePattern.toString().toLowerCase(), offset, NLS.bind(HTMLUIMessages.DoNotValidateAllElements, namePattern.toString()), + HTMLUIMessages.DoNotValidateAllElementsAddInfo, node); + if (!proposals.contains(p)) + proposals.add(p); + + dashIndex = name.indexOf('-', dashIndex + 1); + } + } + } + } + + if (proposals.isEmpty()) + return null; + + return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]); + + } + + private String getElementName(IDOMNode node, int offset) { + return node.getNodeName(); + } + + private boolean shouldShowQuickFix(Set lcIgnoredPatterns, String attrName) { + // Check the attribute name absence in ignore list + String [] lcPatterns = (String[])lcIgnoredPatterns.toArray(new String[0]); + for (int i = 0; i < lcPatterns.length; i++) { + StringMatcher strMatcher = new StringMatcher(lcPatterns[i]); + if (strMatcher.match(attrName.toLowerCase())) { + return false; // The attribute name is already ignored, no need to show a quickfix + } + } + + // The attribute name is not ignored yet, need to show a quickfix + return true; + } + + private String getPreferenceNodeQualifier() { + return HTMLCorePlugin.getDefault().getBundle().getSymbolicName(); + } + + private String getProjectSettingsKey() { + return HTMLCorePreferenceNames.USE_PROJECT_SETTINGS; + } +} diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreAttributeNameCompletionProposal.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreAttributeNameCompletionProposal.java index f43e9fef44..605d509355 100644 --- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreAttributeNameCompletionProposal.java +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreAttributeNameCompletionProposal.java @@ -117,7 +117,7 @@ public class IgnoreAttributeNameCompletionProposal implements ICompletionProposa if (dialog != null) { Object page = dialog.getSelectedPage(); if (page instanceof HTMLValidationPreferencePage) { - ((HTMLValidationPreferencePage)page).overrideOriginValues(originalEnableIgnore, originalAttributeNames); + ((HTMLValidationPreferencePage)page).overrideIgnoredAttributesOriginValues(originalEnableIgnore, originalAttributeNames); } result = dialog.open(); } diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreElementNameCompletionProposal.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreElementNameCompletionProposal.java new file mode 100644 index 0000000000..0b19420b3a --- /dev/null +++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/text/correction/IgnoreElementNameCompletionProposal.java @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2014 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.html.ui.internal.text.correction; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.dialogs.PreferencesUtil; +import org.eclipse.wst.html.core.internal.HTMLCorePlugin; +import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames; +import org.eclipse.wst.html.ui.internal.HTMLUIPlugin; +import org.eclipse.wst.html.ui.internal.Logger; +import org.eclipse.wst.html.ui.internal.editor.HTMLEditorPluginImageHelper; +import org.eclipse.wst.html.ui.internal.editor.HTMLEditorPluginImages; +import org.eclipse.wst.html.ui.internal.preferences.ui.HTMLValidationPreferencePage; +import org.osgi.service.prefs.BackingStoreException; +import org.w3c.dom.Node; + +public class IgnoreElementNameCompletionProposal implements ICompletionProposal { + /** The string to be added to the Ignored HTML Elements list. */ + private String fPattern; + /** The target node */ + private Node fTarget; + /** The string to be displayed in the completion proposal popup. */ + private String fDisplayString; + /** The replacement offset. */ + private int fReplacementOffset; + /** The context information of this proposal. */ + private IContextInformation fContextInformation; + /** The additional info of this proposal. */ + private String fAdditionalProposalInfo; + + private IPreferencesService fPreferenceService; + + public IgnoreElementNameCompletionProposal(String pattern, int offset, String displayString, String additionalProposalInfo, Node target) { + fReplacementOffset= offset; + fPattern = pattern; + fDisplayString= displayString; + fAdditionalProposalInfo= additionalProposalInfo; + fTarget = target; + fPreferenceService = Platform.getPreferencesService(); + } + + /* + * @see ICompletionProposal#apply(IDocument) + */ + public void apply(IDocument document) { + Object adapter = (fTarget instanceof IAdaptable ? ((IAdaptable)fTarget).getAdapter(IResource.class) : null); + IProject project = (adapter instanceof IResource ? ((IResource)adapter).getProject() : null); + + IScopeContext[] fLookupOrder = new IScopeContext[] {new InstanceScope(), new DefaultScope()}; + boolean hasProjectSettings = false; + if (project != null) { + ProjectScope projectScope = new ProjectScope(project); + if(projectScope.getNode(getPreferenceNodeQualifier()) + .getBoolean(getProjectSettingsKey(), false)) { + hasProjectSettings = true; + fLookupOrder = new IScopeContext[] {projectScope, new InstanceScope(), new DefaultScope()}; + } + } + + boolean originalEnableIgnore = fPreferenceService.getBoolean( + getPreferenceNodeQualifier(), HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES, + HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES_DEFAULT, fLookupOrder); + + String originalElementNames = fPreferenceService.getString( + getPreferenceNodeQualifier(), HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE, + HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE_DEFAULT, fLookupOrder); + + StringBuffer ignoreList = new StringBuffer(originalElementNames); + + if (!containsPattern(originalElementNames, fPattern)) { + if (ignoreList.length() > 0) + ignoreList.append(','); + + ignoreList.append(fPattern.toLowerCase()); + } + + fLookupOrder[0].getNode(getPreferenceNodeQualifier()) + .putBoolean(HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES, true); + + fLookupOrder[0].getNode(getPreferenceNodeQualifier()) + .put(HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE, ignoreList.toString()); + + PreferenceDialog dialog = hasProjectSettings ? + PreferencesUtil.createPropertyDialogOn(getShell(), project, HTMLValidationPreferencePage.PROPERTY_PAGE_ID, null, null) : + PreferencesUtil.createPreferenceDialogOn(getShell(), HTMLValidationPreferencePage.PREFERENCE_PAGE_ID, null, null); + + int result = Window.CANCEL; + if (dialog != null) { + Object page = dialog.getSelectedPage(); + if (page instanceof HTMLValidationPreferencePage) { + ((HTMLValidationPreferencePage)page).overrideIgnoredElementsOriginValues(originalEnableIgnore, originalElementNames); + } + result = dialog.open(); + } + + if (Window.CANCEL == result) { + fLookupOrder[0].getNode(getPreferenceNodeQualifier()) + .putBoolean(HTMLCorePreferenceNames.IGNORE_ELEMENT_NAMES, originalEnableIgnore); + + fLookupOrder[0].getNode(getPreferenceNodeQualifier()) + .put(HTMLCorePreferenceNames.ELEMENT_NAMES_TO_IGNORE, originalElementNames); + + for(int i = 0; i < fLookupOrder.length; i++) { + try { + fLookupOrder[i].getNode(getPreferenceNodeQualifier()).flush(); + } catch (BackingStoreException e) { + Logger.logException(e); + } + } + } + } + + private boolean containsPattern(String ignoreList, String pattern) { + Set result = new HashSet(); + if (ignoreList.trim().length() > 0) { + String[] names = ignoreList.split(","); //$NON-NLS-1$ + for (int i = 0; names != null && i < names.length; i++) { + String name = names[i] == null ? null : names[i].trim(); + if (name != null && name.length() > 0) + result.add(name.toLowerCase()); + } + } + return result.contains(pattern.toLowerCase()); + } + + + /* + * @see ICompletionProposal#getDisplayString() + */ + public String getDisplayString() { + if (fDisplayString != null) + return fDisplayString; + return ""; //$NON-NLS-1$ + } + + /* + * @see ICompletionProposal#getAdditionalProposalInfo() + */ + public String getAdditionalProposalInfo() { + return fAdditionalProposalInfo; + } + + /* + * @see ICompletionProposal#getImage() + */ + public Image getImage() { + return HTMLEditorPluginImageHelper.getInstance().getImage(HTMLEditorPluginImages.IMG_DTOOL_DO_NOT_VALIDATE); + } + + /* + * @see ICompletionProposal#getSelection(IDocument) + */ + public Point getSelection(IDocument document) { + return new Point(fReplacementOffset /*+ fCursorPosition*/, 0); + } + + /* + * @see ICompletionProposal#getContextInformation() + */ + public IContextInformation getContextInformation() { + return fContextInformation; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (obj instanceof IgnoreElementNameCompletionProposal) { + IgnoreElementNameCompletionProposal p = (IgnoreElementNameCompletionProposal)obj; + return (this.fPattern.equals(p.fPattern) && this.fTarget == p.fTarget && this.fReplacementOffset == p.fReplacementOffset); + } + return false; + } + + private String getPreferenceNodeQualifier() { + return HTMLCorePlugin.getDefault().getBundle().getSymbolicName(); + } + + private String getProjectSettingsKey() { + return HTMLCorePreferenceNames.USE_PROJECT_SETTINGS; + } + + private Shell getShell() { + IWorkbench workBench = HTMLUIPlugin.getDefault().getWorkbench(); + IWorkbenchWindow workBenchWindow = workBench == null ? null : workBench.getActiveWorkbenchWindow(); + return workBenchWindow == null ? null : workBenchWindow.getShell(); + } +} |