blob: 9df066dc0f1b02ffb30712b3e5427c404840ad5d [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// 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 net.codemirror.mode;
import static java.util.Comparator.comparing;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.safehtml.shared.SafeUri;
import java.util.HashMap;
import java.util.Map;
/** Description of a CodeMirror language mode. */
public class ModeInfo extends JavaScriptObject {
private static NativeMap<ModeInfo> byMime;
private static NativeMap<ModeInfo> byExt;
/** Map of names such as "clike" to URI for code download. */
private static final Map<String, SafeUri> modeUris = new HashMap<>();
static {
indexModes(
new DataResource[] {
Modes.I.apl(),
Modes.I.asciiarmor(),
Modes.I.asn_1(),
Modes.I.asterisk(),
Modes.I.brainfuck(),
Modes.I.clike(),
Modes.I.clojure(),
Modes.I.cmake(),
Modes.I.cobol(),
Modes.I.coffeescript(),
Modes.I.commonlisp(),
Modes.I.crystal(),
Modes.I.css(),
Modes.I.cypher(),
Modes.I.d(),
Modes.I.dart(),
Modes.I.diff(),
Modes.I.django(),
Modes.I.dockerfile(),
Modes.I.dtd(),
Modes.I.dylan(),
Modes.I.ebnf(),
Modes.I.ecl(),
Modes.I.eiffel(),
Modes.I.elm(),
Modes.I.erlang(),
Modes.I.factor(),
Modes.I.fcl(),
Modes.I.forth(),
Modes.I.fortran(),
Modes.I.gas(),
Modes.I.gerrit_commit(),
Modes.I.gfm(),
Modes.I.gherkin(),
Modes.I.go(),
Modes.I.groovy(),
Modes.I.haml(),
Modes.I.handlebars(),
Modes.I.haskell_literate(),
Modes.I.haskell(),
Modes.I.haxe(),
Modes.I.htmlembedded(),
Modes.I.htmlmixed(),
Modes.I.http(),
Modes.I.idl(),
Modes.I.javascript(),
Modes.I.jinja2(),
Modes.I.jsx(),
Modes.I.julia(),
Modes.I.livescript(),
Modes.I.lua(),
Modes.I.markdown(),
Modes.I.mathematica(),
Modes.I.mbox(),
Modes.I.mirc(),
Modes.I.mllike(),
Modes.I.modelica(),
Modes.I.mscgen(),
Modes.I.mumps(),
Modes.I.nginx(),
Modes.I.nsis(),
Modes.I.ntriples(),
Modes.I.octave(),
Modes.I.oz(),
Modes.I.pascal(),
Modes.I.pegjs(),
Modes.I.perl(),
Modes.I.php(),
Modes.I.pig(),
Modes.I.powershell(),
Modes.I.properties(),
Modes.I.protobuf(),
Modes.I.pug(),
Modes.I.puppet(),
Modes.I.python(),
Modes.I.q(),
Modes.I.r(),
Modes.I.rpm(),
Modes.I.rst(),
Modes.I.ruby(),
Modes.I.rust(),
Modes.I.sas(),
Modes.I.sass(),
Modes.I.scheme(),
Modes.I.shell(),
Modes.I.smalltalk(),
Modes.I.smarty(),
Modes.I.solr(),
Modes.I.soy(),
Modes.I.sparql(),
Modes.I.spreadsheet(),
Modes.I.sql(),
Modes.I.stex(),
Modes.I.stylus(),
Modes.I.swift(),
Modes.I.tcl(),
Modes.I.textile(),
Modes.I.tiddlywiki(),
Modes.I.tiki(),
Modes.I.toml(),
Modes.I.tornado(),
Modes.I.troff(),
Modes.I.ttcn_cfg(),
Modes.I.ttcn(),
Modes.I.turtle(),
Modes.I.twig(),
Modes.I.vb(),
Modes.I.vbscript(),
Modes.I.velocity(),
Modes.I.verilog(),
Modes.I.vhdl(),
Modes.I.vue(),
Modes.I.webidl(),
Modes.I.xml(),
Modes.I.xquery(),
Modes.I.yacas(),
Modes.I.yaml_frontmatter(),
Modes.I.yaml(),
Modes.I.z80(),
});
alias("application/x-httpd-php-open", "application/x-httpd-php");
alias("application/x-javascript", "application/javascript");
alias("application/x-shellscript", "text/x-sh");
alias("application/x-tcl", "text/x-tcl");
alias("text/typescript", "application/typescript");
alias("text/x-c", "text/x-csrc");
alias("text/x-c++hdr", "text/x-c++src");
alias("text/x-chdr", "text/x-csrc");
alias("text/x-h", "text/x-csrc");
alias("text/x-ini", "text/x-properties");
alias("text/x-java-source", "text/x-java");
alias("text/x-php", "application/x-httpd-php");
alias("text/x-scripttcl", "text/x-tcl");
}
/** All supported modes. */
public static native JsArray<ModeInfo> all() /*-{
return $wnd.CodeMirror.modeInfo
}-*/;
private static native void setAll(JsArray<ModeInfo> m) /*-{
$wnd.CodeMirror.modeInfo = m
}-*/;
/** Look up mode by primary or alternate MIME types. */
public static ModeInfo findModeByMIME(String mime) {
return byMime.get(mime);
}
public static SafeUri getModeScriptUri(String 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) {
ModeInfo mode = byMime.get(toMime);
if (mode != null) {
byMime.put(serverMime, mode);
}
}
private static void indexModes(DataResource[] all) {
for (DataResource r : all) {
modeUris.put(r.getName(), r.getSafeUri());
}
JsArray<ModeInfo> modeList = all();
modeList.push(gerrit_commit());
byMime = NativeMap.create();
JsArray<ModeInfo> filtered = JsArray.createArray().cast();
for (ModeInfo m : Natives.asList(modeList)) {
if (modeUris.containsKey(m.mode())) {
filtered.push(m);
for (String mimeType : Natives.asList(m.mimes())) {
byMime.put(mimeType, m);
}
byMime.put(m.mode(), m);
}
}
Natives.asList(filtered).sort(comparing(m -> m.name().toLowerCase()));
setAll(filtered);
}
/** Human readable name of the mode, such as "C++". */
public final native String name() /*-{ return this.name }-*/;
/** Internal CodeMirror name for {@code mode.js} file to load. */
public final native String mode() /*-{ return this.mode }-*/;
/** Primary MIME type to activate this mode. */
public final native String mime() /*-{ return this.mime }-*/;
/** Primary and additional MIME types that activate this mode. */
public final native JsArrayString mimes() /*-{ return this.mimes || [this.mime] }-*/;
private native JsArrayString ext() /*-{ return this.ext || [] }-*/;
protected ModeInfo() {}
private static native ModeInfo gerrit_commit() /*-{
return {name: "Git Commit Message",
mime: "text/x-gerrit-commit-message",
mode: "gerrit_commit"}
}-*/;
}