diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties
index 04ed0e5f9dbe..5bb5b5d3f3ba 100644
--- a/platform/platform-resources-en/src/messages/XmlBundle.properties
+++ b/platform/platform-resources-en/src/messages/XmlBundle.properties
@@ -241,10 +241,15 @@ label.text.path.to.profiles.ini=Path to \"profiles.ini\":
label.text.profile=&Profile:
button.text.settings=Settings...
display.name.firefox.settings=Firefox Settings
-zen.coding.title=XML Zen Coding
-zen.coding.enable.label=Enable Zen Coding
+
+zen.coding.title=Emmet (XML Zen Coding)
+emmet.configuration.title=Emmet (Zen Coding)
+emmet.auto.insert.vendor.prefixes=Auto insert css vendor prefixes
+zen.coding.enable.label=Enable Emmet
+emmet.enable.bem.filter=Enable BEM filter by default
zen.coding.enter.abbreviation.dialog.label=Please enter an abbreviation
zen.coding.incorrect.abbreviation.error=Incorrect abbreviation
+
title.cannot.create.html.file=Cannot create HTML file
new.html.file.action=HTML File
new.html.file.action.description=Creates new HTML file
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 6cd517927f37..e0eb126d1335 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -149,6 +149,12 @@
serviceImplementation="com.intellij.application.options.editor.WebEditorOptions"/>
+
+
+
+
+
diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptions.java b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptions.java
index 570014aba157..fa1f6491e172 100644
--- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptions.java
+++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptions.java
@@ -109,18 +109,22 @@ public class WebEditorOptions implements PersistentStateComponent
-
+
@@ -21,7 +21,7 @@
-
+
@@ -29,7 +29,7 @@
-
+
@@ -37,43 +37,16 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java
index eb1ff2ad95f6..da7f38ae0428 100644
--- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java
+++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java
@@ -15,15 +15,11 @@
*/
package com.intellij.application.options.editor;
-import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.xml.XmlBundle;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
/**
* @author spleaner
@@ -34,23 +30,7 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
private JCheckBox myAutomaticallyInsertRequiredAttributesCheckBox;
private JCheckBox myAutomaticallyInsertRequiredSubTagsCheckBox;
private JCheckBox myAutomaticallyStartAttributeAfterCheckBox;
- private JCheckBox myEnableZenCodingCheckBox;
- private JComboBox myZenCodingExpandShortcutCombo;
- private static final String SPACE = CodeInsightBundle.message("template.shortcut.space");
- private static final String TAB = CodeInsightBundle.message("template.shortcut.tab");
- private static final String ENTER = CodeInsightBundle.message("template.shortcut.enter");
-
- {
- myZenCodingExpandShortcutCombo.addItem(SPACE);
- myZenCodingExpandShortcutCombo.addItem(TAB);
- myZenCodingExpandShortcutCombo.addItem(ENTER);
- myEnableZenCodingCheckBox.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- myZenCodingExpandShortcutCombo.setEnabled(myEnableZenCodingCheckBox.isSelected());
- }
- });
- }
public String getDisplayName() {
return XmlBundle.message("web.editor.configuration.title");
@@ -64,24 +44,13 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
return myWholePanel;
}
- private char getSelectedZenCodingExpandShortcut() {
- Object selectedItem = myZenCodingExpandShortcutCombo.getSelectedItem();
- if (TAB.equals(selectedItem)) {
- return TemplateSettings.TAB_CHAR;
- }
- else if (ENTER.equals(selectedItem)) {
- return TemplateSettings.ENTER_CHAR;
- }
- return TemplateSettings.SPACE_CHAR;
- }
+
public boolean isModified() {
final WebEditorOptions xmlEditorOptions = WebEditorOptions.getInstance();
return xmlEditorOptions.isAutomaticallyInsertClosingTag() != myAutomaticallyInsertClosingTagCheckBox.isSelected() ||
xmlEditorOptions.isAutomaticallyInsertRequiredAttributes() != myAutomaticallyInsertRequiredAttributesCheckBox.isSelected() ||
xmlEditorOptions.isAutomaticallyStartAttribute() != myAutomaticallyStartAttributeAfterCheckBox.isSelected() ||
- xmlEditorOptions.isZenCodingEnabled() != myEnableZenCodingCheckBox.isSelected() ||
- xmlEditorOptions.getZenCodingExpandShortcut() != getSelectedZenCodingExpandShortcut() ||
xmlEditorOptions.isAutomaticallyInsertRequiredSubTags() != myAutomaticallyInsertRequiredSubTagsCheckBox.isSelected();
}
@@ -91,8 +60,6 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
xmlEditorOptions.setAutomaticallyInsertRequiredAttributes(myAutomaticallyInsertRequiredAttributesCheckBox.isSelected());
xmlEditorOptions.setAutomaticallyInsertRequiredSubTags(myAutomaticallyInsertRequiredSubTagsCheckBox.isSelected());
xmlEditorOptions.setAutomaticallyStartAttribute(myAutomaticallyStartAttributeAfterCheckBox.isSelected());
- xmlEditorOptions.setZenCodingEnabled(myEnableZenCodingCheckBox.isSelected());
- xmlEditorOptions.setZenCodingExpandShortcut(getSelectedZenCodingExpandShortcut());
}
public void reset() {
@@ -101,19 +68,6 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider {
myAutomaticallyInsertRequiredAttributesCheckBox.setSelected(xmlEditorOptions.isAutomaticallyInsertRequiredAttributes());
myAutomaticallyInsertRequiredSubTagsCheckBox.setSelected(xmlEditorOptions.isAutomaticallyInsertRequiredSubTags());
myAutomaticallyStartAttributeAfterCheckBox.setSelected(xmlEditorOptions.isAutomaticallyStartAttribute());
- myEnableZenCodingCheckBox.setSelected(xmlEditorOptions.isZenCodingEnabled());
- myZenCodingExpandShortcutCombo.setEnabled(xmlEditorOptions.isZenCodingEnabled());
-
- char shortcut = (char)WebEditorOptions.getInstance().getZenCodingExpandShortcut();
- if (shortcut == TemplateSettings.TAB_CHAR) {
- myZenCodingExpandShortcutCombo.setSelectedItem(TAB);
- }
- else if (shortcut == TemplateSettings.ENTER_CHAR) {
- myZenCodingExpandShortcutCombo.setSelectedItem(ENTER);
- }
- else {
- myZenCodingExpandShortcutCombo.setSelectedItem(SPACE);
- }
}
public void disposeUIResources() {
diff --git a/xml/impl/src/com/intellij/application/options/emmet/CssEditPrefixesListPanel.java b/xml/impl/src/com/intellij/application/options/emmet/CssEditPrefixesListPanel.java
new file mode 100644
index 000000000000..aa6d6ec5620d
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/CssEditPrefixesListPanel.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+import com.intellij.openapi.ui.Messages;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.ui.table.TableView;
+import com.intellij.util.ui.ColumnInfo;
+import com.intellij.util.ui.ListTableModel;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: zolotov
+ * Date: 2/20/13
+ */
+public class CssEditPrefixesListPanel {
+ private final ListTableModel myPrefixesModel;
+ private final TableView myPrefixesTableView;
+
+ public CssEditPrefixesListPanel() {
+ ColumnInfo[] columns = new ColumnInfo[CssPrefix.values().length + 1];
+ columns[0] = new PropertyColumn();
+ CssPrefix[] values = CssPrefix.values();
+ for (int i = 0; i < values.length; i++) {
+ columns[i + 1] = new PrefixColumnInfo(values[i]);
+ }
+
+ myPrefixesModel = new ListTableModel(columns, new ArrayList(), 0);
+ myPrefixesModel.setSortable(true);
+ myPrefixesTableView = new TableView(myPrefixesModel);
+ myPrefixesTableView.setAutoCreateRowSorter(true);
+ myPrefixesTableView.setBorder(null);
+ myPrefixesTableView.getRowSorter().toggleSortOrder(0);
+
+ new TableViewSpeedSearch(myPrefixesTableView) {
+ @Override
+ protected String getElementText(final Object element) {
+ CssPrefixInfo prefixInfo = (CssPrefixInfo)element;
+ return prefixInfo.getPropertyName();
+ }
+ };
+ }
+
+ public void setEnabled(boolean value) {
+ myPrefixesTableView.setEnabled(value);
+ }
+
+ public void setState(List prefixInfos) {
+ myPrefixesModel.setItems(prefixInfos);
+ }
+
+ public List getState() {
+ return myPrefixesModel.getItems();
+ }
+
+ public JPanel createMainComponent() {
+ final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myPrefixesTableView);
+ decorator.disableUpDownActions();
+ final JPanel panel = decorator.createPanel();
+ decorator.setAddAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ TableUtil.stopEditing(myPrefixesTableView);
+ String propertyName = Messages.showInputDialog(myPrefixesTableView, "Property name:", "New Css Property", null);
+ if (propertyName != null && !propertyName.isEmpty()) {
+ List items = myPrefixesModel.getItems();
+ for (CssPrefixInfo state : items) {
+ if (propertyName.equals(state.getPropertyName())) {
+ myPrefixesTableView.clearSelection();
+ myPrefixesTableView.addSelection(state);
+ scrollToSelection();
+ return;
+ }
+ }
+ CssPrefixInfo newPrefixInfo = new CssPrefixInfo(propertyName);
+ myPrefixesModel.addRow(newPrefixInfo);
+ myPrefixesTableView.clearSelection();
+ myPrefixesTableView.addSelection(newPrefixInfo);
+ scrollToSelection();
+ }
+ myPrefixesTableView.requestFocus();
+ }
+
+ private void scrollToSelection() {
+ int selectedRow = myPrefixesTableView.getSelectedRow();
+ if (selectedRow >= 0) {
+ myPrefixesTableView.scrollRectToVisible(myPrefixesTableView.getCellRect(selectedRow, 0, true));
+ }
+ }
+ }).setRemoveAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton button) {
+ TableUtil.stopEditing(myPrefixesTableView);
+ CssPrefixInfo selectedObject = myPrefixesTableView.getSelectedObject();
+ int selectedRow = myPrefixesTableView.getSelectedRow();
+ int index = myPrefixesModel.indexOf(selectedObject);
+ if (0 <= index && index < myPrefixesModel.getRowCount()) {
+ myPrefixesModel.removeRow(index);
+ if (selectedRow < myPrefixesTableView.getRowCount()) {
+ myPrefixesTableView.setRowSelectionInterval(selectedRow, selectedRow);
+ }
+ else {
+ if (selectedRow > 0) {
+ myPrefixesTableView.setRowSelectionInterval(selectedRow - 1, selectedRow - 1);
+ }
+ }
+ }
+ myPrefixesTableView.getParent().repaint();
+ myPrefixesTableView.requestFocus();
+ }
+ });
+ return panel;
+ }
+
+ private static class PropertyColumn extends ColumnInfo {
+ public PropertyColumn() {
+ super("Property");
+ }
+
+ @Nullable
+ @Override
+ public String valueOf(CssPrefixInfo prefixInfo) {
+ return prefixInfo.getPropertyName();
+ }
+ }
+
+ private class PrefixColumnInfo extends ColumnInfo {
+ private final CssPrefix myPrefix;
+ private final BooleanTableCellRenderer myCellRenderer = new BooleanTableCellRenderer();
+
+ @Nullable
+ @Override
+ public TableCellRenderer getRenderer(CssPrefixInfo state) {
+ return myCellRenderer;
+ }
+
+ public PrefixColumnInfo(CssPrefix prefix) {
+ super(prefix.getText());
+ myPrefix = prefix;
+ }
+
+ @Nullable
+ @Override
+ public TableCellEditor getEditor(CssPrefixInfo prefixInfo) {
+ JBCheckBox box = new JBCheckBox();
+ box.setHorizontalAlignment(SwingConstants.CENTER);
+ return new DefaultCellEditor(box);
+ }
+
+ @Override
+ public boolean isCellEditable(CssPrefixInfo prefixInfo) {
+ return myPrefixesTableView.isEnabled();
+ }
+
+ public final Class getColumnClass() {
+ return Boolean.class;
+ }
+
+ @Override
+ public final void setValue(final CssPrefixInfo prefixInfo, final Boolean aValue) {
+ prefixInfo.setValue(myPrefix, aValue);
+ }
+
+ @Nullable
+ @Override
+ public final Boolean valueOf(CssPrefixInfo state) {
+ return state.getValue(myPrefix);
+ }
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/CssPrefix.java b/xml/impl/src/com/intellij/application/options/emmet/CssPrefix.java
new file mode 100644
index 000000000000..da3bae3ab476
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/CssPrefix.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+/**
+* User: zolotov
+* Date: 2/21/13
+*/
+public enum CssPrefix {
+ WEBKIT(0x1), MOZ(0x2), MS(0x4), O(0x8);
+
+ final int myIntMask;
+
+ CssPrefix(int intMask) {
+ myIntMask = intMask;
+ }
+
+ public String getText() {
+ return "-" + toString().toLowerCase();
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/CssPrefixInfo.java b/xml/impl/src/com/intellij/application/options/emmet/CssPrefixInfo.java
new file mode 100644
index 000000000000..f31443ce9e4b
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/CssPrefixInfo.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Sets.newHashSet;
+
+/**
+ * User: zolotov
+ * Date: 2/20/13
+ */
+public class CssPrefixInfo {
+ @NotNull
+ private final String myPropertyName;
+ @NotNull
+ private final Collection myEnabledPrefixes;
+
+ public CssPrefixInfo(@NotNull String propertyName, CssPrefix... enabledPrefixes) {
+ myPropertyName = propertyName;
+ myEnabledPrefixes = newHashSet(enabledPrefixes);
+ for (CssPrefix prefix : enabledPrefixes) {
+ setValue(prefix, true);
+ }
+ }
+
+ public CssPrefixInfo(@NotNull String propertyName, Collection enabledPrefixes) {
+ myPropertyName = propertyName;
+ myEnabledPrefixes = newHashSet(enabledPrefixes);
+ for (CssPrefix prefix : enabledPrefixes) {
+ setValue(prefix, true);
+ }
+ }
+
+ @NotNull
+ public Collection getEnabledPrefixes() {
+ return myEnabledPrefixes;
+ }
+
+ public void setValue(CssPrefix prefix, boolean value) {
+ if (value) {
+ myEnabledPrefixes.add(prefix);
+ } else {
+ myEnabledPrefixes.remove(prefix);
+ }
+ }
+
+ public boolean getValue(CssPrefix prefix) {
+ return myEnabledPrefixes.contains(prefix);
+ }
+
+ @NotNull
+ public String getPropertyName() {
+ return myPropertyName;
+ }
+
+ public static CssPrefixInfo fromIntegerValue(String propertyName, Integer value) {
+ if (value == null) {
+ return new CssPrefixInfo(propertyName);
+ }
+ List enabledPrefixes = newArrayList();
+ for (CssPrefix prefix : CssPrefix.values()) {
+ if ((value & prefix.myIntMask) > 0) {
+ enabledPrefixes.add(prefix);
+ }
+ }
+ return new CssPrefixInfo(propertyName, enabledPrefixes);
+ }
+
+ public int toIntegerValue() {
+ int result = 0;
+ for (CssPrefix prefix : myEnabledPrefixes) {
+ if (getValue(prefix)) {
+ result |= prefix.myIntMask;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CssPrefixInfo that = (CssPrefixInfo)o;
+
+ if (!myEnabledPrefixes.equals(that.myEnabledPrefixes)) return false;
+ if (!myPropertyName.equals(that.myPropertyName)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myPropertyName.hashCode();
+ result = 31 * result + myEnabledPrefixes.hashCode();
+ return result;
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.form b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.form
new file mode 100644
index 000000000000..62127bcf42e3
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.form
@@ -0,0 +1,89 @@
+
+
diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.java b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.java
new file mode 100644
index 000000000000..5f69489785da
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurable.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.template.impl.TemplateSettings;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.ui.components.JBCheckBox;
+import com.intellij.xml.XmlBundle;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * User: zolotov
+ * Date: 2/20/13
+ */
+public class EmmetConfigurable implements SearchableConfigurable, Disposable, Configurable.NoScroll {
+ private JBCheckBox myEnableEmmetJBCheckBox;
+ private JComboBox myEmmetExpandShortcutCombo;
+ private JBCheckBox myEnableBEMFilterJBCheckBox;
+ private JBCheckBox myAutoInsertCssVendorJBCheckBox;
+ private JPanel myPanel;
+ private JPanel myPrefixesPanel;
+
+ private CssEditPrefixesListPanel myCssEditPrefixesListPanel;
+
+ private static final String SPACE = CodeInsightBundle.message("template.shortcut.space");
+ private static final String TAB = CodeInsightBundle.message("template.shortcut.tab");
+ private static final String ENTER = CodeInsightBundle.message("template.shortcut.enter");
+
+ public EmmetConfigurable() {
+ myEnableEmmetJBCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ boolean selected = myEnableEmmetJBCheckBox.isSelected();
+ myEmmetExpandShortcutCombo.setEnabled(selected);
+ //myInsertFallbackGradientColorJBCheckBox.setEnabled(selected);
+ myAutoInsertCssVendorJBCheckBox.setEnabled(selected);
+ myCssEditPrefixesListPanel.setEnabled(selected && myAutoInsertCssVendorJBCheckBox.isSelected());
+ myEnableBEMFilterJBCheckBox.setEnabled(selected);
+ }
+ });
+
+ myAutoInsertCssVendorJBCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ myCssEditPrefixesListPanel.setEnabled(myAutoInsertCssVendorJBCheckBox.isSelected());
+ }
+ });
+
+ myEmmetExpandShortcutCombo.addItem(SPACE);
+ myEmmetExpandShortcutCombo.addItem(TAB);
+ myEmmetExpandShortcutCombo.addItem(ENTER);
+ }
+
+ private char getSelectedEmmetExpandShortcut() {
+ Object selectedItem = myEmmetExpandShortcutCombo.getSelectedItem();
+ if (TAB.equals(selectedItem)) {
+ return TemplateSettings.TAB_CHAR;
+ }
+ else if (ENTER.equals(selectedItem)) {
+ return TemplateSettings.ENTER_CHAR;
+ }
+ return TemplateSettings.SPACE_CHAR;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return "reference.settingsdialog.emmet";
+ }
+
+ @Nullable
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
+ @Nls
+ @Override
+ public String getDisplayName() {
+ return XmlBundle.message("emmet.configuration.title");
+ }
+
+ @Nullable
+ @Override
+ public String getHelpTopic() {
+ return getId();
+ }
+
+ @Nullable
+ @Override
+ public JComponent createComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public boolean isModified() {
+ EmmetOptions emmetOptions = EmmetOptions.getInstance();
+ return emmetOptions.isEmmetEnabled() != myEnableEmmetJBCheckBox.isSelected() ||
+ emmetOptions.isBemFilterEnabledByDefault() != myEnableBEMFilterJBCheckBox.isSelected() ||
+ emmetOptions.isAutoInsertCssPrefixedEnabled() != myAutoInsertCssVendorJBCheckBox.isSelected() ||
+ !emmetOptions.getAllPrefixInfo().equals(myCssEditPrefixesListPanel.getState()) ||
+ emmetOptions.getEmmetExpandShortcut() != getSelectedEmmetExpandShortcut();
+ }
+
+
+ @Override
+ public void apply() throws ConfigurationException {
+ EmmetOptions emmetOptions = EmmetOptions.getInstance();
+ emmetOptions.setEmmetEnabled(myEnableEmmetJBCheckBox.isSelected());
+ emmetOptions.setEnableBemFilterByDefault(myEnableBEMFilterJBCheckBox.isSelected());
+ emmetOptions.setEmmetExpandShortcut(getSelectedEmmetExpandShortcut());
+ emmetOptions.setAutoInsertCssPrefixedEnabled(myAutoInsertCssVendorJBCheckBox.isSelected());
+ emmetOptions.setPrefixInfo(myCssEditPrefixesListPanel.getState());
+ }
+
+ @Override
+ public void reset() {
+ EmmetOptions emmetOptions = EmmetOptions.getInstance();
+ myEnableEmmetJBCheckBox.setSelected(emmetOptions.isEmmetEnabled());
+ myEnableBEMFilterJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
+ myEnableBEMFilterJBCheckBox.setSelected(emmetOptions.isBemFilterEnabledByDefault());
+ myEmmetExpandShortcutCombo.setEnabled(emmetOptions.isEmmetEnabled());
+ myAutoInsertCssVendorJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
+ myAutoInsertCssVendorJBCheckBox.setSelected(emmetOptions.isAutoInsertCssPrefixedEnabled());
+ //myInsertFallbackGradientColorJBCheckBox.setEnabled(emmetOptions.isEmmetEnabled());
+ //myInsertFallbackGradientColorJBCheckBox.setSelected(emmetOptions.isInsertFallbackGradientColorEnabled());
+
+ myCssEditPrefixesListPanel.setEnabled(emmetOptions.isEmmetEnabled() && emmetOptions.isAutoInsertCssPrefixedEnabled());
+ myCssEditPrefixesListPanel.setState(emmetOptions.getAllPrefixInfo());
+
+ char shortcut = (char)emmetOptions.getEmmetExpandShortcut();
+ if (shortcut == TemplateSettings.TAB_CHAR) {
+ myEmmetExpandShortcutCombo.setSelectedItem(TAB);
+ }
+ else if (shortcut == TemplateSettings.ENTER_CHAR) {
+ myEmmetExpandShortcutCombo.setSelectedItem(ENTER);
+ }
+ else {
+ myEmmetExpandShortcutCombo.setSelectedItem(SPACE);
+ }
+ }
+
+ @Override
+ public void disposeUIResources() {
+ myCssEditPrefixesListPanel = null;
+ myPrefixesPanel = null;
+ }
+
+ private void createUIComponents() {
+ myCssEditPrefixesListPanel = new CssEditPrefixesListPanel();
+ myPrefixesPanel = myCssEditPrefixesListPanel.createMainComponent();
+ myPrefixesPanel.setEnabled(true);
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurableProvider.java b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurableProvider.java
new file mode 100644
index 000000000000..2d13a7382516
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetConfigurableProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableProvider;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: zolotov
+ * Date: 2/20/13
+ */
+public class EmmetConfigurableProvider extends ConfigurableProvider {
+ @Nullable
+ @Override
+ public Configurable createConfigurable() {
+ return new EmmetConfigurable();
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java
new file mode 100644
index 000000000000..70ddaa453aae
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/EmmetOptions.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.emmet;
+
+import com.intellij.application.options.editor.WebEditorOptions;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import com.intellij.xml.XmlBundle;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import static com.google.common.collect.Lists.newLinkedList;
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.io.Resources.getResource;
+
+/**
+ * User: zolotov
+ * Date: 2/20/13
+ */
+@State(
+ name = "EmmetOptions",
+ storages = {
+ @Storage(
+ file = StoragePathMacros.APP_CONFIG + "/emmet.xml"
+ )}
+)
+public class EmmetOptions implements PersistentStateComponent, ExportableComponent {
+ private boolean myEnableBemFilterByDefault = false;
+ private boolean myEmmetEnabled = WebEditorOptions.getInstance().isZenCodingEnabled();
+ private int myEmmetExpandShortcut = WebEditorOptions.getInstance().getZenCodingExpandShortcut();
+ private boolean myAutoInsertCssPrefixedEnabled = true;
+ @Nullable
+ private Map prefixes = null;
+
+ public void setPrefixInfo(List prefixInfos) {
+ prefixes = newHashMap();
+ for (CssPrefixInfo state : prefixInfos) {
+ prefixes.put(state.getPropertyName(), state.toIntegerValue());
+ }
+ }
+
+ public CssPrefixInfo getPrefixStateForProperty(String propertyName) {
+ return CssPrefixInfo.fromIntegerValue(propertyName, getPrefixes().get(propertyName));
+ }
+
+ public List getAllPrefixInfo() {
+ List result = newLinkedList();
+ for (Map.Entry entry : getPrefixes().entrySet()) {
+ result.add(CssPrefixInfo.fromIntegerValue(entry.getKey(), entry.getValue()));
+ }
+ return result;
+ }
+
+ public boolean isBemFilterEnabledByDefault() {
+ return myEnableBemFilterByDefault;
+ }
+
+ public void setEnableBemFilterByDefault(boolean enableBemFilterByDefault) {
+ myEnableBemFilterByDefault = enableBemFilterByDefault;
+ }
+
+ public void setEmmetExpandShortcut(int emmetExpandShortcut) {
+ myEmmetExpandShortcut = emmetExpandShortcut;
+ }
+
+ public int getEmmetExpandShortcut() {
+ return myEmmetExpandShortcut;
+ }
+
+ public boolean isEmmetEnabled() {
+ return myEmmetEnabled;
+ }
+
+ public void setEmmetEnabled(boolean emmetEnabled) {
+ myEmmetEnabled = emmetEnabled;
+ }
+
+ public boolean isAutoInsertCssPrefixedEnabled() {
+ return myAutoInsertCssPrefixedEnabled;
+ }
+
+ public void setAutoInsertCssPrefixedEnabled(boolean autoInsertCssPrefixedEnabled) {
+ myAutoInsertCssPrefixedEnabled = autoInsertCssPrefixedEnabled;
+ }
+
+ @NotNull
+ @Override
+ public File[] getExportFiles() {
+ return new File[]{PathManager.getOptionsFile("emmet")};
+ }
+
+ @NotNull
+ @Override
+ public String getPresentableName() {
+ return XmlBundle.message("emmet.configuration.title");
+ }
+
+ @Nullable
+ @Override
+ public EmmetOptions getState() {
+ return this;
+ }
+
+ public void loadState(final EmmetOptions state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+
+ public static EmmetOptions getInstance() {
+ return ServiceManager.getService(EmmetOptions.class);
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ @NotNull
+ public Map getPrefixes() {
+ if (prefixes == null) {
+ prefixes = loadDefaultPrefixes();
+ }
+ return prefixes;
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ public void setPrefixes(@Nullable Map prefixes) {
+ this.prefixes = prefixes;
+ }
+
+ public static Map loadDefaultPrefixes() {
+ Map result = newHashMap();
+ try {
+ Document document = JDOMUtil.loadDocument(getResource(EmmetOptions.class, "emmet_default_options.xml"));
+ Element prefixesElement = document.getRootElement().getChild("prefixes");
+ if (prefixesElement != null) {
+ for (Object entry : prefixesElement.getChildren("entry")) {
+ Element entryElement = (Element)entry;
+ String propertyName = entryElement.getAttributeValue("key");
+ Integer value = StringUtil.parseInt(entryElement.getAttributeValue("value"), 0);
+ result.put(propertyName, value);
+ }
+ }
+ }
+ catch (Exception e) {
+ Logger.getInstance(EmmetOptions.class).warn(e);
+ return result;
+ }
+ return result;
+ }
+}
diff --git a/xml/impl/src/com/intellij/application/options/emmet/emmet_default_options.xml b/xml/impl/src/com/intellij/application/options/emmet/emmet_default_options.xml
new file mode 100644
index 000000000000..287ab5f703f3
--- /dev/null
+++ b/xml/impl/src/com/intellij/application/options/emmet/emmet_default_options.xml
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
index 6f4e29d58187..5d3ab8730412 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/ZenCodingTemplate.java
@@ -15,7 +15,7 @@
*/
package com.intellij.codeInsight.template.emmet;
-import com.intellij.application.options.editor.WebEditorOptions;
+import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.template.*;
import com.intellij.codeInsight.template.emmet.filters.SingleLineEmmetFilter;
@@ -276,8 +276,8 @@ public class ZenCodingTemplate implements CustomLiveTemplate {
}
public boolean isApplicable(PsiFile file, int offset, boolean wrapping) {
- WebEditorOptions webEditorOptions = WebEditorOptions.getInstance();
- if (!webEditorOptions.isZenCodingEnabled()) {
+ EmmetOptions emmetOptions = EmmetOptions.getInstance();
+ if (!emmetOptions.isEmmetEnabled()) {
return false;
}
if (file == null) {
@@ -320,7 +320,7 @@ public class ZenCodingTemplate implements CustomLiveTemplate {
}
public char getShortcut() {
- return (char)WebEditorOptions.getInstance().getZenCodingExpandShortcut();
+ return (char)EmmetOptions.getInstance().getEmmetExpandShortcut();
}
public String computeTemplateKey(@NotNull CustomTemplateCallback callback) {
diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
index f226864dd2c1..69b1adf67d8f 100644
--- a/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
+++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/filters/BemEmmetFilter.java
@@ -20,6 +20,7 @@ import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
+import com.intellij.application.options.emmet.EmmetOptions;
import com.intellij.codeInsight.template.emmet.nodes.GenerationNode;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.util.Key;
@@ -94,7 +95,7 @@ public class BemEmmetFilter extends ZenCodingFilter {
@Override
public boolean isAppliedByDefault(@NotNull PsiElement context) {
- return false; //todo: add setting for enabling this filter by default
+ return EmmetOptions.getInstance().isBemFilterEnabledByDefault();
}
@Override
diff --git a/xml/impl/src/com/intellij/xml/util/ColorIconCache.java b/xml/impl/src/com/intellij/xml/util/ColorIconCache.java
index 15b31716e5ca..c0f01ad354eb 100644
--- a/xml/impl/src/com/intellij/xml/util/ColorIconCache.java
+++ b/xml/impl/src/com/intellij/xml/util/ColorIconCache.java
@@ -17,7 +17,6 @@ package com.intellij.xml.util;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.SoftFactoryMap;
-import com.intellij.util.containers.WeakFactoryMap;
import com.intellij.util.ui.EmptyIcon;
import org.jetbrains.annotations.NotNull;
@@ -44,7 +43,6 @@ public class ColorIconCache {
return INSTANCE;
}
- @SuppressWarnings({"MethodMayBeStatic"})
public Icon getIcon(@NotNull final Color color, final int size) {
Icon icon = ourCache.get(color).get(size);
if (icon == null) {