Skip to content

Commit

Permalink
style & doc refined
Browse files Browse the repository at this point in the history
fix a cursor style problem with alt Key
rewritten switchToHyperMD
  • Loading branch information
laobubu committed Jun 26, 2018
1 parent c1a10ff commit 7b5035f
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 58 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ Note: This feature could be **dangerous**. If you want to use this, enable it ma
## 0.3.7

* **Fix**
* Adjacent headers, the latter was not correctly styled
* **mode**
+ Adjacent headers, the latter was not correctly styled
+ Wrong behavoir at links whose text contains line break
* **addon/fold-html**: stop eating extra blank lines

* **Removed**
Expand All @@ -138,4 +140,5 @@ Note: This feature could be **dangerous**. If you want to use this, enable it ma

* **Other**
* English fundamental docs are now published within NPM package.
* PowerPack documentation is much more friendly.
* Documentation is much more friendly.
* Theme hypermd-light refined.
31 changes: 28 additions & 3 deletions docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ var cm = HyperMD.fromTextArea(myTextarea, {

Let's say you are using [parcel-bundler][], simpily run `parcel index.html` and voila!

[parcel-bundler]: https://parceljs.org/ Blazing fast, zero configuration web application bundler

> **You would need css-loader**
>
> HyperMD contains code like `require("xxx.css")`. Make sure you have [css-loader](https://github.com/webpack-contrib/css-loader) configured.
Expand Down Expand Up @@ -89,7 +87,7 @@ requirejs.config({
baseUrl: "/node_modules/",

// (Remove this section if you occur errors with CDN)
// RequireJS doesn't read package.json or detect entry file.
// RequireJS doesn't read package.json. Let's tell it the entries of modules.
packages: [
{ name: 'codemirror', main: 'lib/codemirror.js' },
{ name: 'mathjax', main: 'MathJax.js' },
Expand Down Expand Up @@ -141,7 +139,34 @@ Please read the source code of [this demo](./examples/ai1.html)



## convert existed CodeMirror markdown editor to HyperMD editor

If a markdown editor (based on CodeMirror ≥ 5.37.0) is already initialized and presented on page,
you can easily turn it into HyperMD markdown editor!

**Invoke `HyperMD.switchToHyperMD(editor);`** where `editor` is the CodeMirror editor instance.

> :warning: **Closure problem**, again...
>
> CodeMirror and HyperMD __must__ be loaded by the same method: either bundler, RequireJS or `<script>` tags.
> If not same, HyperMD might not work properly because it can't access the correct CodeMirror!
>
> Some components (eg. SimpleMDE, React-CodeMirror) use their __private__ CodeMirror build,
> which is __not supported__ by HyperMD. Further tweaking is required.
> [(example for react-codemirror)](https://github.com/laobubu/HyperMD/issues/26#issuecomment-391420190)
This will update editor options with `HyperMD.suggestedEditorConfig`.
If there are options you don't like, you may overwrite it, with the 2nd parameter of `switchToHyperMD`:

```js
// example: I want to keep "vim" keyMap
HyperMD.switchToHyperMD(editor, {
keyMap: "vim"
})
```



[parcel-bundler]: https://parceljs.org/
[options-for-addons]: ./options-for-addons.md
[PowerPacks]: ./powerpacks.md
32 changes: 31 additions & 1 deletion docs/zh-CN/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,16 @@ requirejs.config({
baseUrl: "/node_modules/",

// (如果你使用 CDN 遇到问题,删除这段)
// RequireJS doesn't read package.json or detect entry file.
// RequireJS 不会去解析 package.json ,需要手动设置各个模块的入口文件名
packages: [
{ name: 'codemirror', main: 'lib/codemirror.js' },
{ name: 'mathjax', main: 'MathJax.js' },
{ name: 'katex', main: 'dist/katex.min.js' },
{ name: 'marked', main: 'lib/marked.js' },
{ name: 'turndown', main: 'lib/turndown.browser.umd.js' },
{ name: 'turndown-plugin-gfm', main: 'dist/turndown-plugin-gfm.js' },
{ name: 'emojione', main: 'lib/js/emojione.min.js' },
{ name: 'twemoji', main: '2/twemoji.amd.js' },
],
waitSeconds: 15
})
Expand Down Expand Up @@ -152,5 +154,33 @@ require([
请参考 [这个文件](../examples/ai1.html) 的源代码


## 将已有的 CodeMirror markdown 编辑器转成 HyperMD 模式

如果你的页面上已经有一个基于 CodeMirror(版本 ≥ 5.37.0) 的 Markdown 编辑器了,
你可以很轻松地将它转换为 HyperMD 模式:

**调用 `HyperMD.switchToHyperMD(editor);` 即可**,其中 `editor` 是那个 CodeMirror 编辑器实例

> :warning: **还是闭包的问题**...
>
> CodeMirror 和 HyperMD __必须__ 用相同的方法载入:要么用打包器, 要么 RequireJS 或者 `<script>` 标签。
> 如果不一致,HyperMD 可能会无法正常工作,因为它无法访问正确的 CodeMirror!
>
> 有的组件 (例如 SimpleMDE, React-CodeMirror) 使用了其 __私有的__ CodeMirror 版本,
> HyperMD 是不支持的。如果要支持的话,可能得花一点功夫……
> [(例如 react-codemirror 得这样搞)](https://github.com/laobubu/HyperMD/issues/26#issuecomment-391420190)
此操作会把 `HyperMD.suggestedEditorConfig` 里面的配置逐个应用到你的编辑器上,
如果有不喜欢的配置项,你可以使用 `switchToHyperMD` 的第二个可选参数来覆盖之:

```js
// 举个栗子: 我就是想用 "vim" 按键绑定
HyperMD.switchToHyperMD(editor, {
keyMap: "vim"
})
```



[插件相关的编辑器选项]: ./options-for-addons.md
[PowerPack]: ../powerpacks.md
13 changes: 6 additions & 7 deletions mode/hypermd.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

%hidden-token {
display: inline;
opacity: 0;
font-size: 0 !important;
}

Expand All @@ -21,8 +20,8 @@
}

/* adding some CodeMirror-not-implemented styles' default style */
span.cm-inline-code,
span.cm-math {
.cm-inline-code,
.cm-math {
color: #900;
}

Expand All @@ -49,8 +48,8 @@
}

/* addon/fold */
span.hmd-link-icon:after { // Link Placeholder
content: "»";
.hmd-link-icon:after { // Link Placeholder
content: "🔗»";
color: #009;
text-shadow: 0 0 2px #69F;
}
Expand All @@ -68,13 +67,13 @@
.hmd-table-column-center { text-align: center }
.hmd-table-column-right { text-align: right }

span.cm-hmd-table-sep {
.cm-hmd-table-sep {
@extend %inline-block;
}
}

/* addon/fold-math */
span.hmd-fold-math {
.hmd-fold-math {
@extend %inline-block;
&.hmd-fold-math.math-2 { // aka. display mode
width: 100%;
Expand Down
46 changes: 28 additions & 18 deletions src/addon/click.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import * as CodeMirror from 'codemirror'
import { Addon, FlipFlop, expandRange, suggestedEditorConfig } from '../core'

import { addClass, rmClass } from '../core'
import { cm_t } from '../core/type'
import { splitLink } from './read-link'
import { HyperMDState } from '../mode/hypermd';
Expand Down Expand Up @@ -214,36 +213,42 @@ export class Click implements Addon.Addon, Options {
/* ON */() => {
this.lineDiv.addEventListener("mousedown", this._mouseDown, false)
el.addEventListener("keydown", this._keyDown, false)
el.addEventListener("keyup", this._keyUp, false)
},
/* OFF */() => {
this.lineDiv.removeEventListener("mousedown", this._mouseDown, false)
el.removeEventListener("keydown", this._keyDown, false)
el.removeEventListener("keyup", this._keyUp, false)
}
).bind(this, "enabled", true)
}

/** CodeMirror's <pre>s container */
private lineDiv: HTMLDivElement

/** Firefox */
private _hadAlt: boolean
/** It's not */
private _KeyDetectorActive: boolean

/** remove modifier className to editor DOM */
private _keyUp = (ev: KeyboardEvent) => {
var kc = ev.keyCode || ev.which
var className = ""
if (kc == 17) className = "HyperMD-with-ctrl"
if (kc == 18) className = "HyperMD-with-alt"
private _mouseMove_keyDetect = (ev: KeyboardEvent) => {
var el = this.el
var className = el.className, newClassName = className

const altClass = "HyperMD-with-alt"
const ctrlClass = "HyperMD-with-ctrl"

/** FireFox */
if (!className && this._hadAlt && !ev.altKey) {
this._hadAlt = false
className = "HyperMD-with-alt"
if (!ev.altKey && className.indexOf(altClass) >= 0) {
newClassName = className.replace(altClass, "");
}

if (className) rmClass(this.el, className)
if (!ev.ctrlKey && className.indexOf(ctrlClass) >= 0) {
newClassName = className.replace(ctrlClass, "");
}

if (!ev.altKey && !ev.ctrlKey) {
this._KeyDetectorActive = false;
el.removeEventListener('mousemove', this._mouseMove_keyDetect, false);
}

if (className != newClassName) el.className = newClassName.trim()
}

/** add modifier className to editor DOM */
Expand All @@ -253,10 +258,15 @@ export class Click implements Addon.Addon, Options {
if (kc == 17) className = "HyperMD-with-ctrl"
if (kc == 18) className = "HyperMD-with-alt"

/** FireFox */
if (kc == 18) this._hadAlt = true
var el = this.el
if (className && el.className.indexOf(className) == -1) {
el.className += " " + className;
}

if (className) addClass(this.el, className)
if (!this._KeyDetectorActive) {
this._KeyDetectorActive = true;
this.el.addEventListener('mousemove', this._mouseMove_keyDetect, false);
}
}

/** last click info */
Expand Down
47 changes: 31 additions & 16 deletions src/core/quick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export var suggestedEditorConfig: CodeMirror.EditorConfiguration = {
* @returns {cm_t}
*/
export function fromTextArea(textArea: HTMLTextAreaElement, config?: object): cm_t {
var final_config = Object.assign({}, suggestedEditorConfig, config)
var final_config = { ...suggestedEditorConfig, ...config }

var cm = CodeMirror.fromTextArea(textArea, final_config) as any as cm_t

Expand All @@ -64,26 +64,41 @@ export function fromTextArea(textArea: HTMLTextAreaElement, config?: object): cm
* Disable HyperMD visual effects.
* Interactive addons like click or paste are not affected.
*
* @param {cm_t} editor Created by **HyperMD.fromTextArea**
* @param {string} [theme]
* @param {cm_t} editor Any CodeMirror Editor! Created by HyperMD or CodeMirror
*/
export function switchToNormal(editor: cm_t, theme?: string) {
editor.setOption('theme', theme || "default")
editor.setOption('hmdFold', false) // unfold all folded parts
editor.setOption('hmdHideToken', false) // stop hiding tokens
editor.setOption('hmdTableAlign', false) // stop aligining table columns
export function switchToNormal(editor: cm_t);
export function switchToNormal(editor: cm_t, theme: string);
export function switchToNormal(editor: cm_t, options: CodeMirror.EditorConfiguration);
export function switchToNormal(editor: cm_t, options_or_theme?: CodeMirror.EditorConfiguration | string) {
var opt: CodeMirror.EditorConfiguration = {
theme: "default",
hmdFold: false, // unfold all folded parts
hmdHideToken: false, // stop hiding tokens
hmdTableAlign: false, // stop aligining table columns
}

if (typeof options_or_theme === 'string') options_or_theme = { theme: options_or_theme };
Object.assign(opt, options_or_theme)

for (const key in opt) {
editor.setOption(key, opt[key])
}
}

/**
* Revert what `HyperMD.switchToNormal` does
* Apply HyperMD suggestedEditorConfig to a CodeMirror Editor
*
* @param {cm_t} editor Created by **HyperMD.fromTextArea**
* @param {string} [theme]
* @param {cm_t} editor Any CodeMirror Editor! Created by HyperMD or CodeMirror
*/
export function switchToHyperMD(editor: cm_t, theme?: string) {
editor.setOption('theme', theme || 'hypermd-light')
editor.setOption('hmdFold', true)
editor.setOption('hmdHideToken', true)
editor.setOption('hmdTableAlign', true)
export function switchToHyperMD(editor: cm_t);
export function switchToHyperMD(editor: cm_t, theme: string);
export function switchToHyperMD(editor: cm_t, options: CodeMirror.EditorConfiguration);
export function switchToHyperMD(editor: cm_t, options_or_theme?: CodeMirror.EditorConfiguration | string) {
if (typeof options_or_theme === 'string') options_or_theme = { theme: options_or_theme };
var opt = { ...suggestedEditorConfig, ...options_or_theme }

for (const key in opt) {
editor.setOption(key, opt[key])
}
}

8 changes: 8 additions & 0 deletions src/core/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ declare module "codemirror" {
lookAhead(lineCount: number): string
}

interface LineWidget {
on(event: "redraw", fn: Function): void
off(event: "redraw", fn: Function): void
}

interface Editor extends CodeMirror.Doc, HyperMD.Editor {
display: any
options: any
Expand Down Expand Up @@ -201,6 +206,9 @@ declare module "codemirror" {
*/
on(eventName: 'clear', handler: (this: CodeMirror.Editor, from: CodeMirror.Position, to: CodeMirror.Position) => void): void;
off(eventName: 'clear', handler: (this: CodeMirror.Editor, from: CodeMirror.Position, to: CodeMirror.Position) => void): void;

on(eventName: 'hide' | 'unhide', handler: Function): void;
off(eventName: 'hide' | 'unhide', handler: Function): void;
}

interface LineHandle {
Expand Down
6 changes: 4 additions & 2 deletions src/mode/hypermd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,10 @@ CodeMirror.defineMode("hypermd", function (cmCfg, modeCfgUser) {
if (wasLinkText !== state.linkText) {
if (!wasLinkText) {
// entering a link
tmp = stream.match(/^([^\]]+)\](\(| ?\[|\:)?/, false) || ["](", "", "("] // make a fake link
if (!tmp[2]) { // barelink
tmp = stream.match(/^([^\]]+)\](\(| ?\[|\:)?/, false)
if (!tmp) { // maybe met a line-break in link text?
state.hmdLinkType = LinkType.BARELINK
} else if (!tmp[2]) { // barelink
if (tmp[1].charAt(0) === "^") {
state.hmdLinkType = LinkType.FOOTREF
} else {
Expand Down
Loading

0 comments on commit 7b5035f

Please sign in to comment.