From bfdfc7e1830a8291382bd35c680712e5d9c82f51 Mon Sep 17 00:00:00 2001 From: Jocs Date: Mon, 26 Feb 2018 18:36:27 +0800 Subject: [PATCH] opti: optimization the table tool bar style and float box style --- .eslintignore | 1 + LICENSE | 2 +- src/editor/assets/symbolIcon/index.css | 6 ++ src/editor/assets/symbolIcon/index.js | 1 + src/editor/contentState/tableBlockCtrl.js | 23 +++---- src/editor/floatBox/index.css | 63 ++++++++++++++++++ src/editor/floatBox/index.js | 6 +- src/editor/index.css | 81 +++-------------------- src/editor/index.js | 18 ++++- src/editor/parser/StateRender.js | 13 ++-- src/editor/tablePicker/index.js | 2 +- src/editor/themes/github.css | 8 +-- src/editor/utils/exportStyledHTML.js | 2 +- 13 files changed, 126 insertions(+), 100 deletions(-) create mode 100644 src/editor/assets/symbolIcon/index.css create mode 100644 src/editor/assets/symbolIcon/index.js create mode 100644 src/editor/floatBox/index.css diff --git a/.eslintignore b/.eslintignore index 083ddead..afc5e6bc 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,4 @@ test/unit/coverage/** test/unit/*.js test/e2e/*.js src/editor/parser/marked.js +src/editor/assets/symbolIcon/index.js diff --git a/LICENSE b/LICENSE index ea26fe64..a1b0da1d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 Jocs +Copyright (c) 2017-2018 Jocs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/editor/assets/symbolIcon/index.css b/src/editor/assets/symbolIcon/index.css new file mode 100644 index 00000000..f499a628 --- /dev/null +++ b/src/editor/assets/symbolIcon/index.css @@ -0,0 +1,6 @@ +.icon { + width: 1em; height: 1em; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; +} \ No newline at end of file diff --git a/src/editor/assets/symbolIcon/index.js b/src/editor/assets/symbolIcon/index.js new file mode 100644 index 00000000..bbe2817c --- /dev/null +++ b/src/editor/assets/symbolIcon/index.js @@ -0,0 +1 @@ +(function(window){var svgSprite='';var script=function(){var scripts=document.getElementsByTagName("script");return scripts[scripts.length-1]}();var shouldInjectCss=script.getAttribute("data-injectcss");var ready=function(fn){if(document.addEventListener){if(~["complete","loaded","interactive"].indexOf(document.readyState)){setTimeout(fn,0)}else{var loadFn=function(){document.removeEventListener("DOMContentLoaded",loadFn,false);fn()};document.addEventListener("DOMContentLoaded",loadFn,false)}}else if(document.attachEvent){IEContentLoaded(window,fn)}function IEContentLoaded(w,fn){var d=w.document,done=false,init=function(){if(!done){done=true;fn()}};var polling=function(){try{d.documentElement.doScroll("left")}catch(e){setTimeout(polling,50);return}init()};polling();d.onreadystatechange=function(){if(d.readyState=="complete"){d.onreadystatechange=null;init()}}}};var before=function(el,target){target.parentNode.insertBefore(el,target)};var prepend=function(el,target){if(target.firstChild){before(el,target.firstChild)}else{target.appendChild(el)}};function appendSvg(){var div,svg;div=document.createElement("div");div.innerHTML=svgSprite;svgSprite=null;svg=div.getElementsByTagName("svg")[0];if(svg){svg.setAttribute("aria-hidden","true");svg.style.position="absolute";svg.style.width=0;svg.style.height=0;svg.style.overflow="hidden";prepend(svg,document.body)}}if(shouldInjectCss&&!window.__iconfont__svg__cssinject__){window.__iconfont__svg__cssinject__=true;try{document.write("")}catch(e){console&&console.log(e)}}ready(appendSvg)})(window) diff --git a/src/editor/contentState/tableBlockCtrl.js b/src/editor/contentState/tableBlockCtrl.js index c4de3fbd..bcc1e566 100644 --- a/src/editor/contentState/tableBlockCtrl.js +++ b/src/editor/contentState/tableBlockCtrl.js @@ -1,9 +1,4 @@ import { isLengthEven } from '../utils' -import TableIcon from '../assets/icons/table.svg' -import LeftIcon from '../assets/icons/align-left.svg' -import CenterIcon from '../assets/icons/align-center.svg' -import RightIcon from '../assets/icons/align-right.svg' -import DeleteIcon from '../assets/icons/delete.svg' import tablePicker from '../tablePicker' // import selection from '../selection' @@ -16,27 +11,27 @@ const tableBlockCtrl = ContentState => { const ul = this.createBlock('ul') const tools = [{ label: 'table', - icon: TableIcon + icon: 'icon-table' }, { label: 'left', - icon: LeftIcon + icon: 'icon-alignleft' }, { label: 'center', - icon: CenterIcon + icon: 'icon-aligncenter' }, { label: 'right', - icon: RightIcon + icon: 'icon-alignright' }, { label: 'delete', - icon: DeleteIcon + icon: 'icon-del' }] tools.forEach(tool => { const toolBlock = this.createBlock('li') - const imgBlock = this.createBlock('img') - imgBlock.src = tool.icon + const svgBlock = this.createBlock('svg') + svgBlock.icon = tool.icon toolBlock.label = tool.label - this.appendChild(toolBlock, imgBlock) + this.appendChild(toolBlock, svgBlock) this.appendChild(ul, toolBlock) }) this.appendChild(toolBar, ul) @@ -228,7 +223,7 @@ const tableBlockCtrl = ContentState => { this.render() } - tablePicker.toogle({ row, column }, { left, top }, handler.bind(this)) + tablePicker.toggle({ row, column }, { left, top }, handler.bind(this)) // tablePicker.status ? tableLable.classList.add('active') : tableLable.classList.remove('active') } } diff --git a/src/editor/floatBox/index.css b/src/editor/floatBox/index.css new file mode 100644 index 00000000..4d81b014 --- /dev/null +++ b/src/editor/floatBox/index.css @@ -0,0 +1,63 @@ +.ag-float-box { + position: absolute; + display: none; + opacity: 0; + height: 168px; + min-width: 130px; + max-width: 150px; + margin: 0; + padding: 5px 0; + border: 1px solid #ebeef5; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1); + list-style: none; + transform: scale(0); + transition: transform, opacity .5s ease-out; + overflow: auto; + background: #fff; + z-index: 10000; +} + +.ag-show-float-box { + display: block; + opacity: 1; + transform: scale(1); +} + +.ag-float-item { + padding: 0 .5em; + height: 28px; + line-height: 28px; + box-sizing: border-box; + color: #606266; + cursor: pointer; + font-size: 12px; + display: flex; + font-weight: 400; +} + +.ag-float-item span:nth-of-type(2n) { + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap; +} + +.ag-float-box:hover .ag-float-item-active { + background: #fff; + color: #606266; +} +.ag-float-item-active, .ag-float-box .ag-float-item:hover { + background-color: #ecf5ff; + color: #66b1ff; +} + +.ag-float-item-icon { + font-size: 14px; + width: 28px; + height: 28px; + text-align: center; + display: inline-block; + vertical-align: middle; + flex-shrink: 0; + margin-right: .5em; +} diff --git a/src/editor/floatBox/index.js b/src/editor/floatBox/index.js index 7bb12eec..16fb53fb 100644 --- a/src/editor/floatBox/index.js +++ b/src/editor/floatBox/index.js @@ -3,7 +3,9 @@ import { } from '../config' import eventCenter from '../event' -const FLOAT_BOX_HEIGHT = 170 +import './index.css' + +const FLOAT_BOX_HEIGHT = 180 const ITEM_HEIGHT = 28 class FloatBox { @@ -83,7 +85,7 @@ class FloatBox { this.position = { left, top } const viewHeight = document.documentElement.offsetHeight if (viewHeight - top <= FLOAT_BOX_HEIGHT + 25) { - top = top - FLOAT_BOX_HEIGHT + top = top - (FLOAT_BOX_HEIGHT + 5) // left 5px between floatbox and input element } else { top = top + 25 } diff --git a/src/editor/index.css b/src/editor/index.css index 157ef828..2d844693 100644 --- a/src/editor/index.css +++ b/src/editor/index.css @@ -50,18 +50,23 @@ figure { margin-right: 3px; cursor: pointer; border-radius: 3px; + color: #606266; } -.ag-table-tool-bar ul li img { - width: 14px; - height: 14px; + +.ag-table-tool-bar ul li[data-label=delete] { + color: #E6A23C; } .ag-table-tool-bar ul li.active { - background: #aaa; + color: #409eff; } -.ag-table-tool-bar ul li:hover { - background: #bbb; +.ag-table-tool-bar ul li svg { + transition: transform .2s ease-in-out; +} + +.ag-table-tool-bar ul li:hover svg { + transform: scale(1.1); } figure.ag-active .ag-table-tool-bar { @@ -142,70 +147,6 @@ hr { cursor: default; } -.ag-float-box { - position: absolute; - display: none; - opacity: 0; - height: 168px; - min-width: 130px; - max-width: 150px; - margin: 0; - padding: 0; - border: 1px solid #dfe2e5; - border-radius: 3px; - box-shadow: 0 0 5px rgba(27,31,35,0.1); - list-style: none; - transform: scale(0); - transition: transform, opacity .5s ease-out; - overflow: auto; - background: #fff; - z-index: 10000; -} - -.ag-show-float-box { - display: block; - opacity: 1; - transform: scale(1); -} - -.ag-float-item { - padding: 0 .5em; - height: 28px; - line-height: 28px; - box-sizing: border-box; - border-bottom: 1px solid #dfe2e5; - color: #000; - cursor: pointer; - font-size: 12px; - display: flex; - font-weight: 400; -} - -.ag-float-item span:nth-of-type(2n) { - overflow: hidden; - text-overflow:ellipsis; - white-space: nowrap; -} - -.ag-float-box:hover .ag-float-item-active { - background: #fff; - color: #000; -} -.ag-float-item-active, .ag-float-box .ag-float-item:hover { - background: #0366d6; - color: #fff; -} - -.ag-float-item-icon { - font-size: 14px; - width: 28px; - height: 28px; - text-align: center; - display: inline-block; - vertical-align: middle; - flex-shrink: 0; - margin-right: .5em; -} span.ag-emoji-marked-text { position: relative; color: aqua; diff --git a/src/editor/index.js b/src/editor/index.js index 3c82bc30..393d41be 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -13,6 +13,9 @@ import ExportStyledHTML from './utils/exportStyledHTML' import exportHtml from './utils/exportUnstylishHtml' import tablePicker from './tablePicker' +import './assets/symbolIcon' // import symbol icons +import './assets/symbolIcon/index.css' + class Aganippe { constructor (container, options) { this.container = container @@ -278,13 +281,22 @@ class Aganippe { dispatchTableToolBar () { const { container, eventCenter } = this + const getToolItem = target => { + // poor implement, fix me + const parent = target.parentNode + const grandPa = parent && parent.parentNode + if (target.hasAttribute('data-label')) return target + if (parent && parent.hasAttribute('data-label')) return parent + if (grandPa && grandPa.hasAttribute('data-label')) return grandPa + return null + } const handler = event => { const target = event.target - const parent = target.parentNode - if (parent && parent.hasAttribute('data-label')) { + const toolItem = getToolItem(target) + if (toolItem) { event.preventDefault() event.stopPropagation() - const type = parent.getAttribute('data-label') + const type = toolItem.getAttribute('data-label') this.contentState.tableToolBarClick(type) } } diff --git a/src/editor/parser/StateRender.js b/src/editor/parser/StateRender.js index 641ec3f3..88c62061 100644 --- a/src/editor/parser/StateRender.js +++ b/src/editor/parser/StateRender.js @@ -129,10 +129,15 @@ class StateRender { } } - if (/img/.test(block.type)) { - const { src } = block - Object.assign(data.attrs, { src }) - children = '' + if (/svg/.test(block.type)) { + const { icon } = block + blockSelector += '.icon' + Object.assign(data.attrs, { 'aria-hidden': 'true' }) + children = [ + h('use', { + attrs: { 'xlink:href': `#${icon}` } + }) + ] } if (/^h\d$/.test(block.type)) { Object.assign(data.dataset, { head: block.type }) diff --git a/src/editor/tablePicker/index.js b/src/editor/tablePicker/index.js index eafb4994..dfbef702 100644 --- a/src/editor/tablePicker/index.js +++ b/src/editor/tablePicker/index.js @@ -60,7 +60,7 @@ class TablePicker { this.cb = noop } - toogle ({ row, column }, { left, top }, cb) { + toggle ({ row, column }, { left, top }, cb) { const { container, status, rowInput, columnInput } = this if (status) { this.hide() diff --git a/src/editor/themes/github.css b/src/editor/themes/github.css index 797edc88..30284286 100755 --- a/src/editor/themes/github.css +++ b/src/editor/themes/github.css @@ -255,25 +255,25 @@ table { } table tr { - border-top: 1px solid #cccccc; margin: 0; padding: 0; } +table thead tr, table tr:nth-child(2n) { - background-color: #f8f8f8; + background-color: #fafafa; } table tr th { font-weight: bold; - border: 1px solid #cccccc; + border: 1px solid #ebeef5; text-align: left; margin: 0; padding: 6px 13px; } table tr td { - border: 1px solid #cccccc; + border: 1px solid #ebeef5; text-align: left; margin: 0; padding: 6px 13px; diff --git a/src/editor/utils/exportStyledHTML.js b/src/editor/utils/exportStyledHTML.js index 0c5fe75b..63b87671 100644 --- a/src/editor/utils/exportStyledHTML.js +++ b/src/editor/utils/exportStyledHTML.js @@ -15,7 +15,7 @@ class ExportHTML { - Aganippe + Mark Text