Remove CodeMirror stuff from database

This commit is contained in:
Konrad Borowski 2019-10-09 11:53:33 +02:00
parent 45a4ad16ea
commit 2384ec0213
7 changed files with 127 additions and 40 deletions

View File

@ -62,12 +62,12 @@ class Editor {
async updateLanguage() {
this.wrapperButtons.clear()
const identifier = this.getLanguageIdentifier()
this.setLanguage(identifier)
const isStillValid = () => identifier === this.getLanguageIdentifier()
const language = await getLanguage(identifier, isStillValid)
// This deals with user changing the language after asynchronous event
if (isStillValid()) {
this.wrapperButtons.update(language.implementations)
this.setLanguage(language)
}
}

View File

@ -1,18 +1,43 @@
import CodeMirror from 'codemirror'
const languagesMap = new Map([
['c', [() => import('codemirror/mode/clike/clike'), 'text/x-csrc']],
['c-plus-plus', [() => import('codemirror/mode/clike/clike'), 'text/x-c++src']],
['c-sharp', [() => import('codemirror/mode/clike/clike'), 'text/x-csharp']],
['haskell', [() => import('codemirror/mode/haskell/haskell'), 'text/x-haskell']],
['html', [() => import('codemirror/mode/htmlmixed/htmlmixed'), 'text/html']],
['java', [() => import('codemirror/mode/clike/clike'), 'text/x-java']],
['javascript', [() => import('codemirror/mode/javascript/javascript'), 'text/javascript']],
['jinja2', [() => import('codemirror/mode/jinja2/jinja2'), 'text/jinja2']],
['jsx', [() => import('codemirror/mode/jsx/jsx'), 'text/jsx']],
['markdown', [() => import('codemirror/mode/markdown/markdown'), 'text/x-markdown']],
['perl', [() => import('codemirror/mode/perl/perl'), 'text/x-perl']],
['perl6', [() => { }, 'text/x-perl6']],
['php', [() => import('codemirror/mode/php/php'), 'application/x-httpd-php']],
['plain-text', [() => { }, 'text/plain']],
['postgresql', [() => import('codemirror/mode/sql/sql'), 'text/x-pgsql']],
['python2', [() => import('codemirror/mode/python/python'), 'text/x-python']],
['python3', [() => import('codemirror/mode/python/python'), 'text/x-python']],
['rust', [() => import('codemirror/mode/rust/rust'), 'text/x-rustsrc']],
['sh', [() => import('codemirror/mode/shell/shell'), 'text/x-sh']],
['sql', [() => import('codemirror/mode/sql/sql'), 'text/x-sql']],
['sqlite', [() => import('codemirror/mode/sql/sql'), 'text/x-sqlite']],
['typescript', [() => import('codemirror/mode/javascript/javascript'), 'application/typescript']],
['typescript-jsx', [() => import('codemirror/mode/jsx/jsx'), 'text/typescript-jsx']],
])
class CodeMirrorEditor {
constructor(editor) {
this.editor = editor
}
async setLanguage({ mode, mime }) {
this.currentMime = mime
async setLanguage(identifier) {
this.currentIdentifier = identifier
const [importFn, mime] = await languagesMap.get(identifier)
this.editor.setOption('mode', mime)
if (mode) {
await import(`codemirror/mode/${mode}/${mode}.js`)
if (this.currentMime === mime) {
this.editor.setOption('mode', mime)
}
await importFn()
if (this.currentIdentifier === identifier) {
this.editor.setOption('mode', mime)
}
}

View File

@ -0,0 +1,54 @@
ALTER TABLE languages ADD COLUMN highlighter_mode text;
ALTER TABLE languages ADD COLUMN mime text;
UPDATE languages SET
highlighter_mode = CASE identifier
WHEN 'c' THEN 'clike'
WHEN 'c-plus-plus' THEN 'clike'
WHEN 'c-sharp' THEN 'clike'
WHEN 'haskell' THEN 'haskell'
WHEN 'html' THEN 'htmlmixed'
WHEN 'java' THEN 'clike'
WHEN 'javascript' THEN 'javascript'
WHEN 'jinja2' THEN 'jinja2'
WHEN 'jsx' THEN 'jsx'
WHEN 'markdown' THEN 'markdown'
WHEN 'perl' THEN 'perl'
WHEN 'php' THEN 'php'
WHEN 'postgresql' THEN 'sql'
WHEN 'python2' THEN 'python'
WHEN 'python3' THEN 'python'
WHEN 'rust' THEN 'rust'
WHEN 'sh' THEN 'shell'
WHEN 'sql' THEN 'sql'
WHEN 'sqlite' THEN 'sql'
WHEN 'typescript' THEN 'javascript'
WHEN 'typescript-jsx' THEN 'jsx'
END,
mime = CASE identifier
WHEN 'c' THEN 'text/x-csrc'
WHEN 'c-plus-plus' THEN 'text/x-c++src'
WHEN 'c-sharp' THEN 'text/x-csharp'
WHEN 'haskell' THEN 'text/x-haskell'
WHEN 'html' THEN 'text/html'
WHEN 'java' THEN 'text/x-java'
WHEN 'javascript' THEN 'text/javascript'
WHEN 'jinja2' THEN 'text/jinja2'
WHEN 'jsx' THEN 'text/jsx'
WHEN 'markdown' THEN 'text/x-markdown'
WHEN 'perl' THEN 'text/x-perl'
WHEN 'perl6' THEN 'text/x-perl6'
WHEN 'php' THEN 'application/x-httpd-php'
WHEN 'plain-text' THEN 'text/plain'
WHEN 'postgresql' THEN 'text/x-pgsql'
WHEN 'python2' THEN 'text/x-python'
WHEN 'python3' THEN 'text/x-python'
WHEN 'rust' THEN 'text/x-rustsrc'
WHEN 'sh' THEN 'text/x-sh'
WHEN 'sql' THEN 'text/x-sql'
WHEN 'sqlite' THEN 'text/x-sqlite'
WHEN 'typescript' THEN 'application/typescript'
WHEN 'typescript-jsx' THEN 'text/typescript-jsx'
END;
ALTER TABLE languages ALTER COLUMN mime SET NOT NULL;

View File

@ -0,0 +1,2 @@
ALTER TABLE languages DROP COLUMN highlighter_mode;
ALTER TABLE languages DROP COLUMN mime;

View File

@ -8,13 +8,6 @@ use tokio_executor::blocking;
use warp::http::header::CACHE_CONTROL;
use warp::{Rejection, Reply};
#[derive(Queryable)]
struct Language {
id: i32,
mode: Option<String>,
mime: String,
}
#[derive(Serialize, Queryable)]
#[serde(rename_all = "camelCase")]
struct Wrapper {
@ -45,8 +38,6 @@ struct ImplementationWrapper {
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct JsonLanguage {
mode: Option<String>,
mime: String,
implementations: Vec<JsonImplementation>,
}
@ -62,13 +53,9 @@ pub fn api_language(
identifier: String,
) -> impl Future<Item = impl Reply, Error = Rejection> {
blocking::run(move || {
let Language { id, mode, mime } = languages::table
let id: i32 = languages::table
.filter(languages::identifier.eq(identifier))
.select((
languages::language_id,
languages::highlighter_mode,
languages::mime,
))
.select(languages::language_id)
.get_result(&connection)
.optional()
.map_err(warp::reject::custom)?
@ -123,11 +110,7 @@ pub fn api_language(
})
.collect();
Ok(warp::reply::with_header(
warp::reply::json(&JsonLanguage {
mode,
mime,
implementations,
}),
warp::reply::json(&JsonLanguage { implementations }),
CACHE_CONTROL,
"max-age=14400",
))

View File

@ -198,13 +198,13 @@ mod test {
}
}
fn get_html_id() -> String {
fn get_sh_id() -> String {
let response = warp::test::request().reply(&*ROUTES);
let document = Html::parse_document(str::from_utf8(response.body()).unwrap());
document
.select(&Selector::parse("#language option").unwrap())
.find(|element| element.text().next() == Some("HTML"))
.expect("a language called HTML to exist")
.find(|element| element.text().next() == Some("Sh"))
.expect("a language called Sh to exist")
.value()
.attr("value")
.expect("an ID")
@ -214,26 +214,51 @@ mod test {
#[test]
fn test_language_api() {
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ApiLanguage<'a> {
mode: &'a str,
mime: &'a str,
#[serde(borrow)]
implementations: Vec<Implementation<'a>>,
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct Implementation<'a> {
identifier: &'a str,
label: &'a str,
#[serde(borrow)]
wrappers: Vec<Wrapper<'a>>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Wrapper<'a> {
identifier: &'a str,
label: &'a str,
is_asm: bool,
is_formatter: bool,
}
let response = warp::test::request()
.path(&format!("/api/v0/language/{}", get_html_id()))
.path(&format!("/api/v0/language/{}", get_sh_id()))
.reply(&*ROUTES);
assert_eq!(
serde_json::from_slice::<ApiLanguage>(response.body()).unwrap(),
ApiLanguage {
mode: "htmlmixed",
mime: "text/html"
implementations: vec![Implementation {
identifier: "sh",
label: "sh",
wrappers: vec![Wrapper {
identifier: "run",
label: "Run",
is_asm: false,
is_formatter: false,
}],
}],
},
);
}
#[test]
fn test_raw_pastes() {
let body = format!("language={}&code=abc", get_html_id());
let body = format!("language={}&code=abc", get_sh_id());
let reply = warp::test::request()
.method("POST")
.header(CONTENT_LENGTH, body.len())

View File

@ -25,8 +25,6 @@ table! {
language_id -> Int4,
priority -> Int4,
name -> Text,
highlighter_mode -> Nullable<Text>,
mime -> Text,
is_markdown -> Bool,
identifier -> Text,
}