diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
index ff1fedcc8542..85410a764d94 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/HtmlUtil.java
@@ -27,6 +27,7 @@ import com.intellij.lang.xhtml.XHTMLLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
@@ -65,7 +66,8 @@ public class HtmlUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.xml.util.HtmlUtil");
@NonNls private static final String JSFC = "jsfc";
- @NonNls private static final String CHARSET_PREFIX = "charset=";
+ @NonNls private static final String CHARSET = "charset";
+ @NonNls private static final String CHARSET_PREFIX = CHARSET+"=";
@NonNls private static final String HTML5_DATA_ATTR_PREFIX = "data-";
public static final String[] CONTENT_TYPES =
@@ -444,11 +446,23 @@ public class HtmlUtil {
}
public static Charset detectCharsetFromMetaHttpEquiv(@NotNull String content) {
+ // check for or and return Charset
+ // because we will lightly parse and explicit charset isn't used very often do quick check for applicability
+ int charPrefix = content.indexOf(CHARSET);
+ do {
+ if (charPrefix == -1) return null;
+ int charsetPrefixEnd = charPrefix + CHARSET.length();
+ while (charsetPrefixEnd < content.length() && Character.isWhitespace(content.charAt(charsetPrefixEnd))) ++charsetPrefixEnd;
+ if (charsetPrefixEnd < content.length() && content.charAt(charsetPrefixEnd) == '=') break;
+ charPrefix = content.indexOf(CHARSET, charsetPrefixEnd);
+ } while(true);
+
final Ref charsetNameRef = new Ref();
try {
new HtmlBuilderDriver(content).build(new XmlBuilder() {
@NonNls final Set inTag = new THashSet();
boolean metHttpEquiv = false;
+ boolean metHttml5Charset = false;
@Override
public void doctype(@Nullable final CharSequence publicId,
@@ -473,13 +487,18 @@ public class HtmlUtil {
@Override
public void endTag(final CharSequence localName, final String namespace, final int startoffset, final int endoffset) {
@NonNls final String name = localName.toString().toLowerCase();
- if ("meta".equals(name) && metHttpEquiv && contentAttributeValue != null) {
- int start = contentAttributeValue.indexOf(CHARSET_PREFIX);
- if (start == -1) return;
- start += CHARSET_PREFIX.length();
- int end = contentAttributeValue.indexOf(';', start);
- if (end == -1) end = contentAttributeValue.length();
- String charsetName = contentAttributeValue.substring(start, end);
+ if ("meta".equals(name) && (metHttpEquiv || metHttml5Charset) && contentAttributeValue != null) {
+ String charsetName = null;
+ if (metHttpEquiv) {
+ int start = contentAttributeValue.indexOf(CHARSET_PREFIX);
+ if (start == -1) return;
+ start += CHARSET_PREFIX.length();
+ int end = contentAttributeValue.indexOf(';', start);
+ if (end == -1) end = contentAttributeValue.length();
+ charsetName = contentAttributeValue.substring(start, end);
+ } else /*if (metHttml5Charset) */ {
+ charsetName = StringUtil.stripQuotesAroundValue(contentAttributeValue);
+ }
charsetNameRef.set(charsetName);
terminate();
}
@@ -488,6 +507,7 @@ public class HtmlUtil {
}
inTag.remove(name);
metHttpEquiv = false;
+ metHttml5Charset = false;
contentAttributeValue = null;
}
@@ -500,6 +520,9 @@ public class HtmlUtil {
@NonNls String value = v.toString().toLowerCase();
if (name.equals("http-equiv")) {
metHttpEquiv |= value.equals("content-type");
+ } else if (name.equals(CHARSET)) {
+ metHttml5Charset = true;
+ contentAttributeValue = value;
}
if (name.equals("content")) {
contentAttributeValue = value;