npm package: @ruijie-sso/code-editor
Description: code-editor library for SSO Admin
Author: Ruijie Team
Latest version: 1.0.12-beta

# code-editor 代码编辑器

## get-started

### 1. 所需 app 的 project.json 或 angular.json 里

在 assets 里加上

```json

{
  "glob": "**/*",
  "input": "./node_modules/monaco-editor",
  "output": "monaco-editor/"
},
{
"glob": "**/*",
"input": "./node_modules/monaco-ace-tokenizer",
"output": "monaco-ace-tokenizer/"
}
```

例如:

```json
{
  "projectType": "application",
  "root": "apps/dev-code-editor",
  "sourceRoot": "apps/dev-code-editor/src",
  "prefix": "app",
  "targets": {
    "build": {
      "executor": "@angular-devkit/build-angular:browser",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/dev-code-editor",
        "index": "apps/dev-code-editor/src/index.html",
        "main": "apps/dev-code-editor/src/main.ts",
        "polyfills": "apps/dev-code-editor/src/polyfills.ts",
        "tsConfig": "apps/dev-code-editor/tsconfig.app.json",
        "inlineStyleLanguage": "scss",
        "assets": [
          "apps/dev-code-editor/src/favicon.ico",
          "apps/dev-code-editor/src/assets",
+          {
+            "glob": "**/*",
+            "input": "./node_modules/monaco-editor",
+            "output": "monaco-editor/"
+          },
+          {
+            "glob": "**/*",
+            "input": "./node_modules/monaco-ace-tokenizer",
+            "output": "monaco-ace-tokenizer/"
+          }
        ],
        "styles": ["apps/dev-code-editor/src/styles.scss"],
        "scripts": []
      },
      "configurations": {
        "production": {
          "budgets": [
            {
              "type": "initial",
              "maximumWarning": "500kb",
              "maximumError": "1mb"
            },
            {
              "type": "anyComponentStyle",
              "maximumWarning": "2kb",
              "maximumError": "4kb"
            }
          ],
          "fileReplacements": [
            {
              "replace": "apps/dev-code-editor/src/environments/environment.ts",
              "with": "apps/dev-code-editor/src/environments/environment.prod.ts"
            }
          ],
          "outputHashing": "all"
        },
        "development": {
          "buildOptimizer": false,
          "optimization": false,
          "vendorChunk": true,
          "extractLicenses": false,
          "sourceMap": true,
          "namedChunks": true
        }
      },
      "defaultConfiguration": "production"
    },
    "serve": {
      "executor": "@angular-devkit/build-angular:dev-server",
      "configurations": {
        "production": {
          "browserTarget": "dev-code-editor:build:production"
        },
        "development": {
          "browserTarget": "dev-code-editor:build:development"
        }
      },
      "defaultConfiguration": "development"
    },
    "extract-i18n": {
      "executor": "@angular-devkit/build-angular:extract-i18n",
      "options": {
        "browserTarget": "dev-code-editor:build"
      }
    },
    "lint": {
      "executor": "@nrwl/linter:eslint",
      "options": {
        "lintFilePatterns": ["apps/dev-code-editor/src/**/*.ts", "apps/dev-code-editor/src/**/*.html"]
      }
    },
    "test": {
      "executor": "@nrwl/jest:jest",
      "outputs": ["coverage/apps/dev-code-editor"],
      "options": {
        "jestConfig": "apps/dev-code-editor/jest.config.js",
        "passWithNoTests": true
      }
    }
  },
  "tags": ["angular-app"]
}
```

因为在加载模块的时候会用到这些变量。

### 2. 在所需模块里(module)引入

例子:

```typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { CodeEditorAppModule } from '@ruijie-sso/code-editor';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, +FormsModule, +CodeEditorAppModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

### 3. 在 html 里

例子:

```html
<rg-code-editor-app (contentChange)="contentChange($event)"></rg-code-editor-app>
```

### 4. 在 ts 里

例子:

```typescript
import { Component, OnInit, ViewChild } from '@angular/core';
import { CodeEditorAppComponent } from '@ruijie-sso/code-editor';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  @ViewChild(CodeEditorAppComponent) codeEditorApp?: CodeEditorAppComponent;

  constructor() {}

  /* 注意，这里一定要先去等待CodeEditorAppComponent组件里的初始化完成，不然会报错，在其初始化之前就使用它了。
  async ngOnInit() {
    await this.codeEditorApp?.ngOnInit();
  }

  /**
   * 获取当前框里的值
   */
  getValue() {
    console.log(this.codeEditorApp?.getValue());
  }

  /**
   * 监听内容变化值
   * @param res 内容
   */
  contentChange(res: string) {
    console.log(res);
  }
}
```

## 项目内容

### 核心与应用

#### 核心模块

> - code-editor/
>   > 该文件夹下为核心文件，仅仅渲染了代码内容区域，不涉及其他任何功能
>   >
>   > > 主要涉及功能
>   > >
>   > > 1. 自定义宽度(必须用固定值),默认 800px
>   > > 2. 自定义高度(必须用固定值),默认 600px
>   > > 3. 自定义默认提示（placeholder）----<i>暂未实现</b>
> - utils/
>   > 该文件夹下为核心算法文件
>   >
>   > > 主要包括内容
>   > >
>   > > 1. base-url => 获取默认 monaco 编辑器资源链接
>   > > 2. load-monaco-editor => moaco 加载器
>   > > 3. urlJoin => 字符串地址拼接

#### 应用模块

> code-editor-app/
>
> > 应用文件夹，对 code-editor 进行业务性封装
> >
> > > 目前主要实现的功能有
> > >
> > > 1. 自定义内容区域宽高
> > > 2. 自定义当前国际化语言
> > > 3. 自定义默认代码语言
> > > 4. 自定义默认主题
> > > 5. 监听当前内容变化
> > > 6. 获取当前内容的值
> > > 7. 切换当前代码语言
> > >
> > > - 目前支持代码语言的有(按项目需要排序)

```html
<option value="java">java</option>
<option value="javascript">javascript</option>
<option value="json">json</option>
<option value="sql">sql</option>
<option value="groovy">groovy</option>
<option value="plaintext">plaintext</option>
<option value="abap">abap</option>
<option value="apex">apex</option>
<option value="azcli">azcli</option>
<option value="bat">bat</option>
<option value="bicep">bicep</option>
<option value="cameligo">cameligo</option>
<option value="clojure">clojure</option>
<option value="coffeescript">coffeescript</option>
<option value="c">c</option>
<option value="cpp">cpp</option>
<option value="csharp">csharp</option>
<option value="csp">csp</option>
<option value="css">css</option>
<option value="dart">dart</option>
<option value="dockerfile">dockerfile</option>
<option value="ecl">ecl</option>
<option value="elixir">elixir</option>
<option value="flow9">flow9</option>
<option value="fsharp">fsharp</option>
<option value="go">go</option>
<option value="graphql">graphql</option>
<option value="handlebars">handlebars</option>
<option value="hcl">hcl</option>
<option value="html">html</option>
<option value="ini">ini</option>
<option value="julia">julia</option>
<option value="kotlin">kotlin</option>
<option value="less">less</option>
<option value="lexon">lexon</option>
<option value="liquid">liquid</option>
<option value="lua">lua</option>
<option value="m3">m3</option>
<option value="markdown">markdown</option>
<option value="mips">mips</option>
<option value="msdax">msdax</option>
<option value="mysql">mysql</option>
<option value="objective-c">objective-c</option>
<option value="pascal">pascal</option>
<option value="pascaligo">pascaligo</option>
<option value="perl">perl</option>
<option value="pgsql">pgsql</option>
<option value="php">php</option>
<option value="pla">pla</option>
<option value="postiats">postiats</option>
<option value="powerquery">powerquery</option>
<option value="powershell">powershell</option>
<option value="proto">proto</option>
<option value="pug">pug</option>
<option value="python">python</option>
<option value="qsharp">qsharp</option>
<option value="r">r</option>
<option value="razor">razor</option>
<option value="redis">redis</option>
<option value="redshift">redshift</option>
<option value="restructuredtext">restructuredtext</option>
<option value="ruby">ruby</option>
<option value="rust">rust</option>
<option value="sb">sb</option>
<option value="scala">scala</option>
<option value="scheme">scheme</option>
<option value="scss">scss</option>
<option value="shell">shell</option>
<option value="sol">sol</option>
<option value="aes">aes</option>
<option value="sparql">sparql</option>
<option value="st">st</option>
<option value="swift">swift</option>
<option value="systemverilog">systemverilog</option>
<option value="verilog">verilog</option>
<option value="tcl">tcl</option>
<option value="twig">twig</option>
<option value="typescript">typescript</option>
<option value="vb">vb</option>
<option value="xml">xml</option>
<option value="yaml">yaml</option>
<option value="ada">ada</option>
<option value="cobol">cobol</option>
<option value="d">d</option>
<option value="dart">dart</option>
<option value="elixir">elixir</option>
<option value="erlang">erlang</option>
<option value="fortran">fortran</option>
<option value="haskell">haskell</option>
<option value="julia">julia</option>
<option value="ocaml">ocaml</option>
<option value="racket">racket</option>
<option value="sbcl">sbcl</option>
<option value="scala">scala</option>
```

> > > 8. 切换当前内容框主题
> > >
> > > - 目前支持的内容框主题有(需要扩展支持的，去[demo](https://editor.bitwiser.in/) 上选)

```html
<option value="vs">VS</option>
<option value="vs-dark">VS Dark</option>
<option value="hc-black">High Contrast (Dark)</option>
```

## API

| 属性              | 类型     | 默认值 | 输出    | 描述                         |
| ----------------- | -------- | ------ | ------- | ---------------------------- |
| [baseUrl]         | string   | ""     | ----    | 默认路径 monaco 资源路径     |
| [localizeCode]    | string   | ""     | ----    | 显示语言，默认根据浏览器判断 |
| [language]        | string   | "java" | ----    | 默认语言                     |
| [theme]           | string   | "vs"   | ----    | 默认主题                     |
| [defaultValue]    | string   | ""     | ----    | 默认代码                     |
| [contentWidth]    | number   | 800    | ----    | 内容区域的宽度               |
| [contentHeight]   | number   | 600    | ----    | 内容区域的高度               |
| (contentChange)   | Function | ""     | string  | 内容改变事件                 |
| (syntaxDetection) | Function | ""     | boolean | 语法实时检测                 |

##### 更新记录(2022.03.02)

1. 新增@Output syntaxDetection，输出当前代码框中是否含有语法错误
2. 新增方法 getSyntaxError()，获取当前代码框中是否含有语法错误
3. 新增方法 listenSyntaxError().用户监听语法错误，并通过 syntaxDetection()，输出语法错误结果