Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/2.x.x #64

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 59 additions & 52 deletions README.md

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions build/iife.rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import resolve from 'rollup-plugin-node-resolve'
import uglify from 'rollup-plugin-uglify'

export default {
input: 'src/index.js',
output: {
exports: 'named',
file: 'dist/easy-marker.dist.js',
format: 'iife',
name: 'EasyMarker',
},
plugins: [
uglify(),
resolve({
main: true,
jsnext: true,
}),
commonjs({
include: 'node_modules/**',
}),
babel({
runtimeHelpers: true,
presets: [
[
'env', {
targets: { browsers: ['android>=4', 'ios>=8'] },
modules: false,
},
],
],
plugins: [
['transform-runtime'],
],
exclude: 'node_modules/**',
}),
],
}
41 changes: 3 additions & 38 deletions build/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,4 @@
import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import resolve from 'rollup-plugin-node-resolve'
import uglify from 'rollup-plugin-uglify'
import iifeConfig from './iife.rollup.config'
import esmConfig from './esm.rollup.config'

export default {
input: 'src/index.js',
output: {
exports: 'named',
file: 'dist/easy-marker.dist.js',
format: 'iife',
name: 'EasyMarker',
},
plugins: [
uglify(),
resolve({
main: true,
jsnext: true,
}),
commonjs({
include: 'node_modules/**',
}),
babel({
runtimeHelpers: true,
presets: [
[
'env', {
targets: { browsers: ['android>=4', 'ios>=8'] },
modules: false,
},
],
],
plugins: [
['transform-runtime'],
],
exclude: 'node_modules/**',
}),
],
}
export default [iifeConfig, esmConfig]
45 changes: 41 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,26 @@ declare class EasyMarker {
): void;
public highlightLines(HighlightLines: HighlightLine[]): void;
public cancelHighlightLine(id: string | number): boolean;
public onHighlightLineClick(
public onHighlightLineClick(// 老
cb: (
id: string | number,
meta: unknown,
selection: SelectionContent,
) => void,
): void;
public onHighlightLineClick(// 新
cb: (
highClickPriorityLine: { id: string | number, line: HighlightLineInfo },
clickLines: { id: string | number, line: HighlightLineInfo }[],
e: Event
) => void,
): void;
public onSelectStatusChange(cb: (status: SelectStatus) => void): void;
public onMenuClick(
cb: (id: string | number, selection: SelectionContent) => void,
cb: (id: string | number, selection: SelectionContent, options: OldMenuOptions) => void,
): void;
public onMenuClick(
cb: (id: string | number, selection: SelectionContent, options: NewMenuOptions) => void,
): void;
public registerEventHook(cb: () => void): void;
public destroy(): void;
Expand All @@ -41,13 +51,19 @@ export enum SelectStatus {
FINISH = 'finish',
}

export enum NoteType {
UNDERLINE = 'underline',
HIGHLIGHT = 'highlight',
DASH = 'dash'
}

export interface InitOptions {
excludeElements?: HTMLElement[];
includeElements?: HTMLElement[];
}

export interface EasyMarkerOptions {
menuItems?: MenuItem[];
menuItems?: MenuItem[] | ((selection: SelectionIdentifier, type: MenuType) => MenuItem[]);
menuTopOffset?: number | string;
menuStyle?: MenuStyle;
disableTapHighlight?: boolean;
Expand Down Expand Up @@ -122,7 +138,28 @@ export interface MarkdownOptions {
export interface HighlightLine {
selection: SelectionIdentifier;
id?: string | number;
meta?: unknown;
meta?: HighlightLineMeta
}

/** clickAction 与 clickPriority 必须一起使用 */
export type HighlightLineMeta = {
[k: string]: any
clickPriority?: number, // >= 0
clickAction?: 'menuPop' | 'custom',
type?: NoteType,
};

export type HighlightLineInfo = Omit<HighlightLine, 'id'>

export type OldMenuOptions = {
e: Event,
id?: string | number,
meta?: unknown,
}
export type NewMenuOptions = {
highClickPriorityLine?: { id: string | number, line: HighlightLineInfo },
clickLines?: { id: string | number, line: HighlightLineInfo }[]
e: Event,
}

export default EasyMarker;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "Easy marker",
"main": "dist/easy-marker.esm.js",
"scripts": {
"build": "rollup -c build/esm.rollup.config.js && rollup -c build/rollup.config.js",
"build": "rollup -c build/rollup.config.js",
"watch": "rollup -w -c build/rollup.config.js",
"testRegion": "rollup -f iife -o test/regionDist.js -i test/testRegion.js -n test -w",
"testNode": "rollup -f iife -o test/nodeDist.js -i test/testNode.js -n test -w",
"doc": "jsdoc2md src/base_easy_marker.js > api.md",
Expand Down
27 changes: 17 additions & 10 deletions src/base_easy_marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,12 @@ class EasyMarker {
if (val === SelectStatus.FINISH) {
this.menu.setPosition(this.start, this.end)
this.menu.type = MenuType.SELECT
this.menu.show()
this.menu.show({
start: this.start,
end: this.end,
content: this.getSelectText(),
markdown: this.getSelectMarkdown(),
})
} else {
this.menu.hide()
}
Expand Down Expand Up @@ -443,14 +448,7 @@ class EasyMarker {
* };
* const meta = { someKey: 'someValue' };
* em.highlightLines([{selection, id, meta}]);
* @param {Object[]} lines
* @param {*} [lines[].id]
* @param {*} [lines[].meta]
* @param {Object} lines[].selection
* @param {Node} lines[].selection.anchorNode
* @param {number} lines[].selection.anchorOffset
* @param {Node} lines[].selection.focusNode
* @param {number} lines[].selection.focusOffset
* @param {import('../').HighlightLine[]} lines
* @memberof EasyMarker
*/
highlightLines(lines) {
Expand Down Expand Up @@ -748,11 +746,20 @@ class EasyMarker {
this.menu.setPosition(this.start, this.end)
this.menu.type = MenuType.HIGHLIGHT
this.menu.options = options
this.menu.show()
this.menu.show({
start: this.start,
end: this.end,
content: this.getSelectText(),
markdown: this.getSelectMarkdown(),
})
}

// eslint-disable-next-line class-methods-use-this
setSelection() {}
// eslint-disable-next-line class-methods-use-this
getSelectText() {}
// eslint-disable-next-line class-methods-use-this
getSelectMarkdown() {}

getTouchRelativePosition(e) {
const cursorOffset = this.deviceType === DeviceType.MOBILE ? this.movingCursor.height / 2 : 0
Expand Down
115 changes: 73 additions & 42 deletions src/element/highlight.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BaseElement from './base'
import TextNode from '../lib/text_node'
import { getTouchPosition, inRectangle, anyToPx, rectToPointArray } from '../lib/helpers'
import { getTouchPosition, inRectangle, anyToPx, rectToPointArray, getHighClickPriorityLine } from '../lib/helpers'
import { EasyMarkerMode, NoteType } from '../lib/types'

/**
Expand All @@ -21,6 +21,7 @@ export default class Highlight extends BaseElement {
tagColor: '#fff',
opacity: 1,
type: 'highlight',
strokeDasharray: '2, 2',
// margin: '0.1rem',
}
this.container = container
Expand Down Expand Up @@ -151,38 +152,44 @@ export default class Highlight extends BaseElement {
this.lineMap.forEach((line) => {
const type = line.meta.type || this.type
line.points.forEach((points, index) => {
if (type === NoteType.UNDERLINE) {
this.element.appendChild(this.createLine(points))
} else {
this.element.appendChild(this.createRectangle(points))
}
if (line.points.length - 1 === index && line.meta && line.meta.tag) {
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
text.setAttribute('x', points[2][0] - 5)
text.setAttribute('y', points[2][1] + 4)
text.setAttribute('dominant-baseline', 'hanging')
text.setAttribute('text-anchor', 'end')
text.setAttribute('font-size', '10')
text.setAttribute('fill', this.option.tagColor)
text.textContent = line.meta.tag
text.classList.add('em-highlight-tag-text')
this.element.appendChild(text)
// setTimeout(() => {
// 异步获取位置在某些情况无法正常渲染
// 同步执行在某些时候无法取到getBox
// const textRect = text.getBBox()
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
// rect.setAttribute('x', textRect.x - 5)
// rect.setAttribute('y', textRect.y - 1)
rect.setAttribute('x', points[2][0] - 25 - 5)
rect.setAttribute('y', points[2][1] - 0)
rect.setAttribute('rx', 2)
rect.setAttribute('ry', 2)
rect.setAttribute('width', 20 + 10)
rect.setAttribute('height', 14 + 2)
rect.setAttribute('fill', this.option.tagBackground)
this.element.insertBefore(rect, text)
// }, 10)
try {
if (type === NoteType.UNDERLINE) {
this.element.appendChild(this.createLine(points))
} else if (type === NoteType.DASH) {
this.element.appendChild(this.createDash(points))
} else {
this.element.appendChild(this.createRectangle(points))
}
if (line.points.length - 1 === index && line.meta && line.meta.tag) {
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
text.setAttribute('x', points[2][0] - 5)
text.setAttribute('y', points[2][1] + 4)
text.setAttribute('dominant-baseline', 'hanging')
text.setAttribute('text-anchor', 'end')
text.setAttribute('font-size', '10')
text.setAttribute('fill', this.option.tagColor)
text.textContent = line.meta.tag
text.classList.add('em-highlight-tag-text')
this.element.appendChild(text)
// setTimeout(() => {
// 异步获取位置在某些情况无法正常渲染
// 同步执行在某些时候无法取到getBox
// const textRect = text.getBBox()
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
// rect.setAttribute('x', textRect.x - 5)
// rect.setAttribute('y', textRect.y - 1)
rect.setAttribute('x', points[2][0] - 25 - 5)
rect.setAttribute('y', points[2][1] - 0)
rect.setAttribute('rx', 2)
rect.setAttribute('ry', 2)
rect.setAttribute('width', 20 + 10)
rect.setAttribute('height', 14 + 2)
rect.setAttribute('fill', this.option.tagBackground)
this.element.insertBefore(rect, text)
// }, 10)
}
} catch (error) {
console.error('easyMarker.render', error)
}
})
})
Expand All @@ -191,10 +198,7 @@ export default class Highlight extends BaseElement {
/**
*
*
* @param {Object[]} lines
* @param {Selection} lines[].selection
* @param {any} [lines[].id]
* @param {any} [lines[].meta]
* @param {import('../..').HighlightLine[]} lines
* @memberof Highlight
*/
highlightLines(lines) {
Expand Down Expand Up @@ -258,6 +262,22 @@ export default class Highlight extends BaseElement {
return line
}

createDash(pointList) {
const x1 = pointList[2][0]
const y1 = pointList[2][1] + 1
const x2 = pointList[3][0]
const y2 = pointList[3][1] + 1
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line.style.stroke = this.option.underlineColor
line.style.strokeWidth = this.option.underlineWidth
line.style.strokeDasharray = this.option.strokeDasharray
line.setAttribute('x1', x1)
line.setAttribute('y1', y1)
line.setAttribute('x2', x2)
line.setAttribute('y2', y2)
return line
}

createRectangle(pointList) {
const points = pointList.reduce((acc, [x, y]) => (acc === '' ? `${x},${y}` : `${acc} ${x},${y}`), '')
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')
Expand All @@ -272,21 +292,32 @@ export default class Highlight extends BaseElement {
handleTap(e) {
const { x, y } = getTouchPosition(e)
const { top, left } = this.container.getBoundingClientRect()
let clickLine
const clickLines = []
this.lineMap.forEach((line, id) => {
for (let i = 0; i < line.relativeRects.length; i++) {
const rect = line.relativeRects[i]
const margin = line.lineHeight ? (line.lineHeight - rect.height) / 2 : 0
if (inRectangle(x - left, y - top, rect, margin)) {
clickLine = { id, line }
break
clickLines.push({ id, line })
}
}
})
if (clickLine && this.easyMarker) {
if (this.easyMarker.highlightLineClick) {


if (clickLines.length > 0 && this.easyMarker) {
const highClickPriorityLine = getHighClickPriorityLine(clickLines)

if (highClickPriorityLine && highClickPriorityLine.line.meta.clickAction) { // !REMEMBER: clickAction 与 clickPriority 必须成对使用
if (highClickPriorityLine.line.meta.clickAction === 'custom') {
this.easyMarker.highlightLineClick(highClickPriorityLine, clickLines, e)
} else if (highClickPriorityLine.line.meta.clickAction === 'menuPop') {
this.easyMarker.showHighlightMenu(highClickPriorityLine.line.selection, { highClickPriorityLine, clickLines })
}
} else if (this.easyMarker.highlightLineClick) {
const [clickLine] = clickLines // TODO: 兼容老逻辑,确保没影响可以删除
this.easyMarker.highlightLineClick(clickLine.id, clickLine.line.meta, clickLine.line.selection, e)
} else {
const [clickLine] = clickLines // TODO: 兼容老逻辑,确保没影响可以删除
this.easyMarker.showHighlightMenu(clickLine.line.selection, { id: clickLine.id, meta: clickLine.line.meta })
}
return true
Expand Down
Loading