Fallback language detection with meta.js extensions

CodeMirror ships meta.js with a map of file extensions.  Fallback to
this table if the server was unable to provide a valid MIME type.

Change-Id: I24930a8f79f8e1e2b919b81c8dab15c9c585d35e
This commit is contained in:
Shawn Pearce 2014-12-31 00:29:47 -05:00
parent 60a77b0562
commit b9b931af8b
4 changed files with 40 additions and 17 deletions

View File

@ -76,6 +76,7 @@ import net.codemirror.lib.CodeMirror.LineHandle;
import net.codemirror.lib.Configuration; import net.codemirror.lib.Configuration;
import net.codemirror.lib.KeyMap; import net.codemirror.lib.KeyMap;
import net.codemirror.lib.Pos; import net.codemirror.lib.Pos;
import net.codemirror.mode.ModeInfo;
import net.codemirror.mode.ModeInjector; import net.codemirror.mode.ModeInjector;
import java.util.ArrayList; import java.util.ArrayList;
@ -991,11 +992,12 @@ public class SideBySide2 extends Screen {
} }
private String getContentType(DiffInfo.FileMeta meta) { private String getContentType(DiffInfo.FileMeta meta) {
return prefs.syntaxHighlighting() if (prefs.syntaxHighlighting() && meta != null
&& meta != null && meta.content_type() != null) {
&& meta.content_type() != null ModeInfo m = ModeInfo.findMode(meta.content_type(), path);
? ModeInjector.getContentType(meta.content_type()) return m != null ? m.mime() : null;
: null; }
return null;
} }
private void injectMode(DiffInfo diffInfo, AsyncCallback<Void> cb) { private void injectMode(DiffInfo diffInfo, AsyncCallback<Void> cb) {

View File

@ -39,6 +39,7 @@ import com.google.gwtexpui.globalkey.client.GlobalKey;
import net.codemirror.lib.CodeMirror; import net.codemirror.lib.CodeMirror;
import net.codemirror.lib.Configuration; import net.codemirror.lib.Configuration;
import net.codemirror.mode.ModeInfo;
import net.codemirror.mode.ModeInjector; import net.codemirror.mode.ModeInjector;
public class EditScreen extends Screen { public class EditScreen extends Screen {
@ -86,7 +87,8 @@ public class EditScreen extends Screen {
cmGroup.addFinal(new GerritCallback<String>() { cmGroup.addFinal(new GerritCallback<String>() {
@Override @Override
public void onSuccess(String result) { public void onSuccess(String result) {
type = result; ModeInfo mode = ModeInfo.findMode(result, path);
type = mode != null ? mode.mime() : null;
injectMode(result, modeInjectorCb); injectMode(result, modeInjectorCb);
} }
})); }));
@ -148,7 +150,7 @@ public class EditScreen extends Screen {
.set("styleSelectedText", true) .set("styleSelectedText", true)
.set("showTrailingSpace", true) .set("showTrailingSpace", true)
.set("keyMap", "default") .set("keyMap", "default")
.set("mode", ModeInjector.getContentType(type)); .set("mode", type);
} }
private void initPath() { private void initPath() {

View File

@ -30,6 +30,7 @@ import java.util.Map;
/** Description of a CodeMirror language mode. */ /** Description of a CodeMirror language mode. */
public class ModeInfo extends JavaScriptObject { public class ModeInfo extends JavaScriptObject {
private static NativeMap<ModeInfo> byMime; private static NativeMap<ModeInfo> byMime;
private static NativeMap<ModeInfo> byExt;
/** Map of names such as "clike" to URI for code download. */ /** Map of names such as "clike" to URI for code download. */
private static final Map<String, SafeUri> modeUris = new HashMap<>(); private static final Map<String, SafeUri> modeUris = new HashMap<>();
@ -100,7 +101,7 @@ public class ModeInfo extends JavaScriptObject {
$wnd.CodeMirror.modeInfo = m $wnd.CodeMirror.modeInfo = m
}-*/; }-*/;
/** Lookup mode by primary or alternate MIME types. */ /** Look up mode by primary or alternate MIME types. */
public static ModeInfo findModeByMIME(String mime) { public static ModeInfo findModeByMIME(String mime) {
return byMime.get(mime); return byMime.get(mime);
} }
@ -109,6 +110,30 @@ public class ModeInfo extends JavaScriptObject {
return modeUris.get(mode); return modeUris.get(mode);
} }
/** Look up mode by MIME type or file extension from a path. */
public static ModeInfo findMode(String mime, String path) {
ModeInfo m = byMime.get(mime);
if (m != null) {
return m;
}
int s = path.lastIndexOf('/');
int d = path.lastIndexOf('.');
if (d == -1 || s > d) {
return null; // punt on "foo.src/bar" type paths.
}
if (byExt == null) {
byExt = NativeMap.create();
for (ModeInfo mode : Natives.asList(all())) {
for (String ext : Natives.asList(mode.ext())) {
byExt.put(ext, mode);
}
}
}
return byExt.get(path.substring(d + 1));
}
private static void alias(String serverMime, String toMime) { private static void alias(String serverMime, String toMime) {
ModeInfo mode = byMime.get(toMime); ModeInfo mode = byMime.get(toMime);
if (mode != null) { if (mode != null) {
@ -158,6 +183,9 @@ public class ModeInfo extends JavaScriptObject {
public final native JsArrayString mimes() public final native JsArrayString mimes()
/*-{ return this.mimes || [this.mime] }-*/; /*-{ return this.mimes || [this.mime] }-*/;
private final native JsArrayString ext()
/*-{ return this.ext || [] }-*/;
protected ModeInfo() { protected ModeInfo() {
} }

View File

@ -29,15 +29,6 @@ public class ModeInjector {
return ModeInfo.getModeScriptUri(mode) != null; return ModeInfo.getModeScriptUri(mode) != null;
} }
public static String getContentType(String mode) {
if (canLoad(mode)) {
return mode;
}
ModeInfo m = ModeInfo.findModeByMIME(mode);
return m != null ? m.mime() : mode;
}
private static native boolean isModeLoaded(String n) private static native boolean isModeLoaded(String n)
/*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/; /*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/;