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

Drag'n'drop support #445

Merged
merged 340 commits into from
Sep 27, 2018
Merged
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
340 commits
Select commit Hold shift + click to select a range
2e6b107
moving caret initial
khaydarov Dec 28, 2017
ef6f2d5
small improvements
khaydarov Dec 28, 2017
0ed9238
last changes, added docs
khaydarov Dec 28, 2017
c7a5be8
requested changes
khaydarov Dec 29, 2017
8adc54c
implement getters instead of functions in block cursors
khaydarov Dec 29, 2017
4575a24
last requested changes
khaydarov Dec 29, 2017
cf4a126
caret module docs and last improvements
khaydarov Dec 30, 2017
8f4b7e5
update docs
khaydarov Dec 30, 2017
6c75a45
upgrade request
khaydarov Jan 3, 2018
6d83636
update docs
khaydarov Jan 3, 2018
cdf2ca7
upd
khaydarov Jan 4, 2018
6db88c3
todo on delays
khaydarov Jan 4, 2018
6fd28f3
Merge pull request #242 from codex-team/module-caret
khaydarov Jan 4, 2018
d2d85ee
Sanitizer docs
khaydarov Jan 4, 2018
4f8d089
split func upd
Jan 5, 2018
1a9167f
split blocks update
Jan 5, 2018
ef24b23
Merge branch 'rewriting-version2.0' into Split-Merge-blocks
Jan 5, 2018
be575a1
up docs
khaydarov Jan 5, 2018
9dd05d2
Listeners Module: initial
khaydarov Jan 5, 2018
87c94d7
listener module updates
khaydarov Jan 5, 2018
342705b
split is ready
Jan 5, 2018
cbfcecd
Merge pull request #243 from codex-team/sanitizer-docs
khaydarov Jan 6, 2018
52ed658
update
khaydarov Jan 6, 2018
d46e823
start to make merge
Jan 7, 2018
97af4c8
upd
Jan 7, 2018
6a4de5f
split general upd
Jan 8, 2018
3ae2f9b
ups
khaydarov Jan 8, 2018
bbc1d0d
Merge pull request #244 from codex-team/module-listeners
khaydarov Jan 8, 2018
df75c79
keyboard module update
Jan 8, 2018
45dabb7
BlockManager removed keyboard handler
Jan 8, 2018
0869a64
commit before merging rewriting2.0
Jan 8, 2018
543b73a
Merge branch 'rewriting-version2.0' into Split-Merge-blocks
Jan 8, 2018
0c4c33e
general upd split
Jan 8, 2018
92a316e
Documentation upd
Jan 8, 2018
909080a
document + listener upd
Jan 8, 2018
b4d9485
upd doc
Jan 8, 2018
740349c
documentation upd
Jan 8, 2018
05b7663
doc upd
Jan 8, 2018
2cc8578
listener upd
Jan 8, 2018
fe5c99f
update algh extract fragm
Nikitos9I Jan 11, 2018
25f5b1d
upd extractRangeContent
Nikitos9I Jan 11, 2018
a4099ca
upd dom.js
Nikitos9I Jan 11, 2018
c73ce70
Merge pull request #246 from codex-team/Split-Merge-blocks
Nikitos9I Jan 11, 2018
17acac3
keyboard upd (shift + enter & enableLineBreaks)
Nikitos9I Jan 12, 2018
f1e95c3
upd enter pressed
Nikitos9I Jan 12, 2018
fb07764
keyboard.js upd
Nikitos9I Jan 12, 2018
2e5894a
enter pressed upd
Nikitos9I Jan 12, 2018
9347e44
documenation added
Nikitos9I Jan 12, 2018
feaf00a
documentation upd
Nikitos9I Jan 12, 2018
f9a7c0c
Merge pull request #250 from codex-team/Split-Merge-blocks
Nikitos9I Jan 12, 2018
c4bdc23
Toolbar: settings zone added. (#252)
neSpecc Mar 25, 2018
e6c3fc7
Making a Toolbar
neSpecc May 21, 2018
eded07b
delete block
khaydarov May 22, 2018
d29b3ae
dom improvements and merging blocks
khaydarov May 22, 2018
7c7f978
merge and split improvements
khaydarov May 22, 2018
d2470fe
fix merging
khaydarov May 22, 2018
0f0de88
do not remove block if block contains media
khaydarov May 22, 2018
e3be9ea
optimize code
khaydarov May 24, 2018
3ebf499
caret behaviour improved
khaydarov May 24, 2018
b61fac8
up
khaydarov May 24, 2018
550e3ce
up
khaydarov May 24, 2018
0d8257e
merging blocks. Now plugins handles this cases
khaydarov May 25, 2018
e2041c9
mergeable getter
khaydarov May 25, 2018
c92f3f9
save
khaydarov May 25, 2018
d969f7d
up
khaydarov May 25, 2018
01a1b96
dom getdeepestnode improvements
khaydarov May 25, 2018
fb3e6fd
improve getDeepest node method one more time
khaydarov May 25, 2018
b4220c8
upd
khaydarov May 25, 2018
58d640a
Deal with it
neSpecc May 25, 2018
12e1d37
improve isAtStart
neSpecc May 25, 2018
d5b0ebe
improve docs
neSpecc May 25, 2018
e1028fa
use smart isAtStart and isAtEnt method in navigateNext/navigatePrevious
neSpecc May 29, 2018
4636c7a
improve docs
neSpecc May 29, 2018
e85725f
fix bug in $.isEmpty, improve keydown
neSpecc May 29, 2018
768348f
fix isAtEnd
neSpecc May 29, 2018
fc44297
rollback setCaret code duplication
neSpecc May 29, 2018
24a7b9c
improve backspace
neSpecc May 29, 2018
beeecba
Debug tree walker
neSpecc May 29, 2018
5c08eda
fix tree walker
neSpecc May 29, 2018
f8043ff
small caret fix
neSpecc May 29, 2018
3ac9ee9
queue ordering
khaydarov May 29, 2018
1f30fa2
update bundle
neSpecc May 29, 2018
373579c
improve first letter checkup
neSpecc May 29, 2018
9c303ed
doc upd
neSpecc May 29, 2018
51a5ffe
update current block index setter
neSpecc May 29, 2018
d8747e5
Merge pull request #254 from codex-team/daily
khaydarov May 29, 2018
dbb4cd6
TypeScript support, Webpack 4, Inline Toolbar beginning (#257)
neSpecc Jun 11, 2018
cba999a
Inline Toolbar moving (#258)
neSpecc Jun 13, 2018
cd6edef
default settings initial
khaydarov Jun 19, 2018
7945bce
add move up button to default tunes area
khaydarov Jun 19, 2018
57ee838
need to figure out with assets
khaydarov Jun 20, 2018
36f505c
Inline Toolbar Tools base example (#260)
neSpecc Jun 21, 2018
0cddf41
save
khaydarov Jun 21, 2018
32aa383
Merge branch 'rewriting-version2.0' into default-editor-settings
khaydarov Jun 21, 2018
93ddb25
tunes with interface
khaydarov Jun 21, 2018
36bc3e4
add tool settings
khaydarov Jun 21, 2018
59347e3
initial api methods
khaydarov Jun 23, 2018
022023f
api is ready
khaydarov Jun 23, 2018
ca5beae
started writing docs
khaydarov Jun 23, 2018
543d35f
Create svg sprite (#261)
neSpecc Jun 23, 2018
2573fd6
API
neSpecc Jun 23, 2018
5526648
requested changes
khaydarov Jun 23, 2018
08a6549
Merge branch 'default-editor-settings' of https://github.com/codex-te…
khaydarov Jun 23, 2018
4413764
Merge branch 'rewriting-version2.0' into default-editor-settings
khaydarov Jun 23, 2018
cac6bac
fix conflicts
khaydarov Jun 23, 2018
84aa54b
add docs
khaydarov Jun 23, 2018
9d59e9c
doc fixes and interface improvements
khaydarov Jun 23, 2018
c85f9d0
update
khaydarov Jun 23, 2018
110603a
API scopes improved
neSpecc Jun 23, 2018
572f56f
Merge pull request #262 from codex-team/default-editor-settings
khaydarov Jun 23, 2018
295e425
Deleting block: Initial
khaydarov Jun 23, 2018
1b5260e
Delete block with confirmation
khaydarov Jun 24, 2018
4efaf0d
Event subscription&unsubscription
khaydarov Jun 24, 2018
242b9b5
deletion trigger improvements
khaydarov Jun 24, 2018
ad78d12
small improvements
khaydarov Jun 24, 2018
60eda57
Merge pull request #263 from codex-team/delete-block
khaydarov Jun 24, 2018
c665677
Link Inline Tool (#264)
neSpecc Jun 25, 2018
9c41fc4
Delete tune fixes
khaydarov Jun 27, 2018
972eb87
UI: Block Settings, show Plus after Enter keydown (#265)
neSpecc Jun 28, 2018
779bf5d
Merge branch 'delete-tune-fixes' into rewriting-version2.0
khaydarov Jun 28, 2018
d0126e0
Revert "Merge branch 'delete-tune-fixes' into rewriting-version2.0"
khaydarov Jun 28, 2018
088a537
Delete Tune improvements
khaydarov Jun 28, 2018
c4f49d0
upd
khaydarov Jun 28, 2018
65397b7
upd comments
khaydarov Jun 28, 2018
fa492e5
actualize API docs
khaydarov Jun 28, 2018
430277e
Merge pull request #267 from codex-team/delete-tune-improvements
khaydarov Jun 28, 2018
a8c5fea
Allow to connect external Inline Tools (#269)
neSpecc Jul 5, 2018
5ba9b80
Italic inline tool
talyguryn Jul 5, 2018
4ab74f3
update icon size
talyguryn Jul 5, 2018
f72626c
Merge pull request #270 from codex-team/italic-tool
talyguryn Jul 5, 2018
0197397
upgrade findParentTag function
talyguryn Jul 9, 2018
b3723d0
add interface selection
talyguryn Jul 9, 2018
8ef971a
fix cs
talyguryn Jul 9, 2018
773ef46
save marker
talyguryn Jul 9, 2018
ff74576
bundles
talyguryn Jul 9, 2018
97f04e6
add todo
talyguryn Jul 9, 2018
a95e236
removing wrapper
talyguryn Jul 10, 2018
e17ccbf
update styles
talyguryn Jul 10, 2018
319cabb
market -> term
talyguryn Jul 10, 2018
2428849
add comments
talyguryn Jul 11, 2018
f898492
improve code
neSpecc Jul 11, 2018
f1febf7
descrease margin
neSpecc Jul 11, 2018
0c918b5
add text block to example
talyguryn Jul 11, 2018
4f46afc
add line brakes
talyguryn Jul 11, 2018
8112e48
remove space
talyguryn Jul 11, 2018
d7d59bf
fix bugs
neSpecc Jul 11, 2018
4b61ea5
fix bug
neSpecc Jul 11, 2018
a5c682a
Merge pull request #271 from codex-team/marker
talyguryn Jul 11, 2018
1bbb136
umd as a library target
talyguryn Jul 11, 2018
69b70cc
Merge pull request #272 from codex-team/umd
talyguryn Jul 11, 2018
e21c645
background -> background-color
talyguryn Jul 11, 2018
73f5de3
Merge pull request #273 from codex-team/fix-css
talyguryn Jul 11, 2018
782a600
Clear API (#274)
talyguryn Jul 13, 2018
5222fe3
rename plugin name field in data object (#276)
talyguryn Jul 14, 2018
903093b
Text tool refactored (#277)
neSpecc Jul 14, 2018
72c2240
do not add block if tool is not exist (#278)
talyguryn Jul 14, 2018
832f0ca
Module Keyboard rewrited to BlockEvents (#279)
neSpecc Jul 14, 2018
640e44b
Move-up tune (#268)
khaydarov Jul 14, 2018
1853cfa
Eslint --fix for project files (#280)
gohabereg Jul 15, 2018
3d03461
Header plugin (#281)
talyguryn Jul 16, 2018
9c961bd
"MoveDown" tune (#283)
khaydarov Jul 16, 2018
ea64562
Fix merge function and rename Block's wrapper (#284)
khaydarov Jul 16, 2018
8696b9c
Merging blocks: Restore caret position 🤟🤟💪 (#286)
khaydarov Jul 16, 2018
f951ced
hide toolbar and selection on typing (#289)
talyguryn Jul 17, 2018
3398383
Editor Instance config Interface (#285)
talyguryn Jul 17, 2018
cbb4746
update editor interface (#293)
talyguryn Jul 17, 2018
dc7afd1
При перемещении по стрелочкам убирать выделение блока (#296)
talyguryn Jul 18, 2018
29d2bae
update toolbar design (#301)
talyguryn Jul 18, 2018
4b1d933
Set caret at the end if clicked outsite the block (#305)
khaydarov Jul 18, 2018
bc3f193
Insert new Block when enter pressed on editor area (#307)
khaydarov Jul 19, 2018
7a67d38
Add placeholder to contentEditable elements (#306)
talyguryn Jul 19, 2018
f2ef201
Close toolbar after block is removed (#314)
khaydarov Jul 19, 2018
835e698
makeSettings -> renderSettings (#315)
talyguryn Jul 19, 2018
f45521d
Term: new icon, new style. + margin between settings buttons (#316)
neSpecc Jul 19, 2018
83655d3
Tool's renderToolboxIcon function (#318)
talyguryn Jul 20, 2018
4346b4b
Paste (#259)
gohabereg Jul 21, 2018
9cc108e
Resolve conflict
gohabereg Jul 21, 2018
877e2de
Replace current block if it is empty (#320)
gohabereg Jul 21, 2018
c844b55
Improve Header line-height (#321)
neSpecc Jul 23, 2018
d3a7af9
Fix typo (#324)
gohabereg Jul 23, 2018
6571589
Installation docs (#325)
talyguryn Jul 23, 2018
2443672
Module Shortcuts (#317)
khaydarov Jul 23, 2018
9027974
Simple Image Tool (#326)
neSpecc Jul 23, 2018
11c9746
Fix toolbox appearance, tools boxed are clickable (#331)
talyguryn Jul 24, 2018
df3fd63
Remove toolsConfig from Editor's config (#327)
talyguryn Jul 25, 2018
07eb1b7
update dev dep packages (#333)
talyguryn Jul 25, 2018
dfb35da
Check is paste handler a function only if it exists (#328)
gohabereg Jul 25, 2018
1533af4
Toolbar with tab (#330)
khaydarov Jul 25, 2018
e190d67
Validate editor's config before initing (#341)
talyguryn Jul 25, 2018
c7549a9
Styles API (#343)
talyguryn Jul 25, 2018
1775e3c
List Tool [new] (#344)
neSpecc Jul 27, 2018
46bc5db
Example page improved (#347)
neSpecc Jul 28, 2018
3ba88fa
Header plugin (#348)
talyguryn Jul 28, 2018
b8db945
Improve paste behaviour (#346)
gohabereg Jul 28, 2018
ea881f0
Quote Tool (#329)
gohabereg Jul 28, 2018
9ca4e70
items -> blocks (#351)
talyguryn Jul 28, 2018
d9b0e5e
use SimpleImage from cdn (#355)
talyguryn Jul 30, 2018
1e3551a
Update text on the example.html (#356)
neSpecc Jul 30, 2018
3fca65f
use Paragraph Tool from CDN (#357)
talyguryn Jul 30, 2018
faac5ab
Remove _callbacks.js (#358)
neSpecc Jul 30, 2018
657fe98
Clear unused files (#359)
neSpecc Jul 30, 2018
d0f7e3e
TOOLBAR_ICON_CLASS -> TOOLBAR_ICON (#360)
talyguryn Jul 30, 2018
61adb11
Delimiter tool (#362)
talyguryn Jul 30, 2018
e854008
Enter on editor (#363)
khaydarov Jul 31, 2018
dbe862c
add Element.prepend() function (#365)
talyguryn Jul 31, 2018
545ce14
use List Tool from cdn (#366)
talyguryn Jul 31, 2018
7d30b04
Pass "config" from Tool's settings to Tool's constructor (#367)
talyguryn Jul 31, 2018
605154c
use string as a object's key 😔 (#368)
talyguryn Jul 31, 2018
ef2d25e
update placeholder's styles (#369)
talyguryn Jul 31, 2018
5206e03
Add shortcuts for internal tools (#370)
neSpecc Jul 31, 2018
43ffd4d
use quote from cdn (#371)
talyguryn Jul 31, 2018
c349c87
Add cache to the inline tools (#372)
neSpecc Aug 1, 2018
b593dc6
use Inline Code Tool from cdn (#375)
talyguryn Aug 1, 2018
6850019
Issue 354 inline tools filter (#376)
neSpecc Aug 1, 2018
9d1a33b
fix endless cycle (#378)
talyguryn Aug 2, 2018
e88d1d3
Destructured options for Inline Tools (#379)
talyguryn Aug 2, 2018
3a72af8
Fix toolbar moving after arrow navigation (#380)
neSpecc Aug 2, 2018
e1ad086
add example Tools as submodules (#381)
talyguryn Aug 3, 2018
672f7ae
Merge branch 'master' into rewriting-version2.0
neSpecc Aug 3, 2018
a58c8d2
Input navigation (#339)
gohabereg Aug 3, 2018
7b73a15
New readme 🦅 (#386)
neSpecc Aug 3, 2018
5f63cbd
Issue 374 (#385)
gohabereg Aug 3, 2018
7517620
Paragraph as a default Tool in editor; Zero-conf (#389)
talyguryn Aug 3, 2018
d7b9c47
enable minifying (#390)
talyguryn Aug 3, 2018
883ffd9
Drop current block index only if there is no selection at the Editor …
gohabereg Aug 4, 2018
a4ef357
Migrate to Yarn (#393)
gohabereg Aug 4, 2018
bfb6308
Rewrite helpers classes to TypeScript (#396)
gohabereg Aug 5, 2018
5dccbc9
Add docs and isReady promise (#394)
gohabereg Aug 5, 2018
570710d
set default holderId value (#404)
talyguryn Aug 5, 2018
b291625
Destroyer (#392)
gohabereg Aug 5, 2018
a5cf1bf
Add drag'n'drop support
gohabereg Sep 4, 2018
e00764d
Add docs
gohabereg Sep 4, 2018
1b86c8a
Merge branch 'master' of https://github.com/codex-team/codex.editor i…
gohabereg Sep 4, 2018
f03e8ec
Small fix
gohabereg Sep 4, 2018
6a58ac7
Continue merging master :|
gohabereg Sep 4, 2018
7e9283b
Fixes after merge
gohabereg Sep 4, 2018
ecfc5e9
Merge branch 'master' of https://github.com/codex-team/codex.editor i…
Sep 19, 2018
3a53db2
Merge branch 'master' of https://github.com/codex-team/codex.editor i…
Sep 21, 2018
b74045d
Add styles and improve behavior
Sep 21, 2018
dac1eb4
Close inline toolbar and remove dragged content
gohabereg Sep 21, 2018
2f9dbe8
Some improvements of paste data processing
Sep 25, 2018
b20a767
Delete selection content only if drag has been started at editor
gohabereg Sep 26, 2018
f7c066c
Add comments
gohabereg Sep 26, 2018
f83988e
Support of pasting from copy-buffer
gohabereg Sep 26, 2018
d83c18f
Change header level
gohabereg Sep 26, 2018
a9247b8
Improvements
Sep 27, 2018
bf6c30d
Use isDraNDrop flag
Sep 27, 2018
d0068ff
Update example
Sep 27, 2018
8ee5fff
Improve d'n'd behaviour
Sep 27, 2018
bf694e5
git pull for simple-image tool
talyguryn Sep 27, 2018
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
656 changes: 332 additions & 324 deletions build/codex-editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/codex-editor.js.map

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions docs/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,34 @@ static get onPaste() {

> Both `onPaste.handler` and `onPaste.patternHandler` can be `async` or return a `Promise`.

### Drag'n'drop handling

Your Tool can handle files drag'n'drop.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

files pasted by drag'n'drop


To handle dropped file you should provide `onDrop` static property with following fields

| Name | Type | Description |
| ---- | ---- | ----------- |
| `extensions` | `string[]` | _Optional_ Array of extensions your Tool can handle |
| `mimeTypes` | `sring[]` | _Optional_ Array of MIME types your Tool can handle |
| `handler` | `(file: File) => {data: any}` | Handler method should return the same object as `save` method |

Example

```javascript
static get onDrop() {
return {
mimeTypes: ['image/*'],
extensions: ['json'],
handler: (file) => {
/* do smth with the file */

return {
data // Some extracted content
}
}
}
}
```

### Sanitize
11 changes: 10 additions & 1 deletion src/components/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ export default class Block {
* CSS classes for the Block
* @return {{wrapper: string, content: string}}
*/
static get CSS(): {wrapper: string, wrapperStretched: string, content: string, selected: string} {
static get CSS(): {wrapper: string, wrapperStretched: string, content: string, selected: string, dropTarget: string} {
return {
wrapper: 'ce-block',
wrapperStretched: 'ce-block--stretched',
content: 'ce-block__content',
selected: 'ce-block--selected',
dropTarget: 'ce-block--drop-target',
};
}

Expand Down Expand Up @@ -363,6 +364,14 @@ export default class Block {
return tunesElement;
}

/**
* Toggle drop target state
* @param {boolean} state
*/
public set dropTarget(state) {
this.holder.classList.toggle(Block.CSS.dropTarget, state);
}

/**
* Make default Block wrappers and put Tool`s content there
* @returns {HTMLDivElement}
Expand Down
2 changes: 1 addition & 1 deletion src/components/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export default class Core {
* @return {Promise}
*/
async start() {
const modulesToPrepare = ['Tools', 'UI', 'BlockManager', 'Paste', 'ModificationsObserver'];
const modulesToPrepare = ['Tools', 'UI', 'BlockManager', 'Paste', 'DragNDrop', 'ModificationsObserver'];

await modulesToPrepare.reduce(
(promise, module) => promise.then(async () => {
Expand Down
22 changes: 22 additions & 0 deletions src/components/modules/block-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,28 @@ export default class BlockEvents extends Module {
}
}

/**
* Add drop target styles
*
* @param {DragEvent} e
*/
public dragOver(e: DragEvent) {
const block = this.Editor.BlockManager.getBlockByChildNode(e.target);

block.dropTarget = true;
}

/**
* Remove drop target style
*
* @param {DragEvent} e
*/
public dragLeave(e: DragEvent) {
const block = this.Editor.BlockManager.getBlockByChildNode(e.target);

block.dropTarget = false;
}

/**
* ENTER pressed on block
* @param {KeyboardEvent} event - keydown
Expand Down
28 changes: 25 additions & 3 deletions src/components/modules/blockManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export default class BlockManager extends Module {
this.Editor.Listeners.on(block.holder, 'keydown', (event) => this.Editor.BlockEvents.keydown(event), true);
this.Editor.Listeners.on(block.holder, 'mouseup', (event) => this.Editor.BlockEvents.mouseUp(event));
this.Editor.Listeners.on(block.holder, 'keyup', (event) => this.Editor.BlockEvents.keyup(event));
this.Editor.Listeners.on(block.holder, 'dragover', (event) => this.Editor.BlockEvents.dragOver(event));
this.Editor.Listeners.on(block.holder, 'dragleave', (event) => this.Editor.BlockEvents.dragLeave(event));
}

/**
Expand Down Expand Up @@ -362,17 +364,18 @@ export default class BlockManager extends Module {
* 2) Mark it as current
*
* @param {Element|Text} childNode - look ahead from this node.
* @param {string} caretPosition - position where to set caret
* @throws Error - when passed Node is not included at the Block
*/
setCurrentBlockByChildNode(childNode) {
setCurrentBlockByChildNode(childNode, caretPosition = 'default') {
/**
* If node is Text TextNode
*/
if (!$.isElement(childNode)) {
childNode = childNode.parentNode;
}

let parentFirstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);
const parentFirstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);

if (parentFirstLevelBlock) {
/**
Expand All @@ -381,12 +384,31 @@ export default class BlockManager extends Module {
*/
this.currentBlockIndex = this._blocks.nodes.indexOf(parentFirstLevelBlock);

this.Editor.Caret.setToInput(childNode);
this.Editor.Caret.setToInput(childNode, caretPosition);
} else {
throw new Error('Can not find a Block from this child Node');
}
}

/**
* Return block which contents passed node
*
* @param {Node} childNode
* @return {Block}
*/
getBlockByChildNode(childNode) {
/**
* If node is Text TextNode
*/
if (!$.isElement(childNode)) {
childNode = childNode.parentNode;
}

const firstLevelBlock = childNode.closest(`.${Block.CSS.wrapper}`);

return this.blocks.find(block => block.holder === firstLevelBlock);
}

/**
* Swap Blocks Position
* @param {Number} fromIndex
Expand Down
223 changes: 223 additions & 0 deletions src/components/modules/dragNDrop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import _ from '../utils';
import IBlockToolData from '../interfaces/tools/block-tool-data';
import SelectionUtils from '../selection';

declare var Module: any;

interface DropConfig {
extensions: string;
mimeTypes: string;
handler: (file: File) => IBlockToolData;
}

export default class DragNDrop extends Module {

/**
* If drag has been started at editor, we save it
*
* @type Boolean
* @private
*/
private isStartedAtEditor = false;

/**
* Cache for Tools onDrop configs
*
* @private
*/
private toolsDropConfigs: {[tool: string]: {
extensions: string[],
mimeTypes: string[],
handler: (file: File) => IBlockToolData,
}} = {};

/**
* Bind events and process tools configs
*
* @private
*/
public async prepare(): Promise<void> {
this.bindEvents();
await this.processTools();
}

/**
* Add drag events listeners to editor zone
* @private
*/
private bindEvents(): void {
this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'drop', this.processDrop, true);

this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'dragstart', () => {
this.isStartedAtEditor = true;
this.Editor.InlineToolbar.close();
});

/* Prevent default browser behavior to allow drop on non-contenteditable elements */
this.Editor.Listeners.on(this.Editor.UI.nodes.holder, 'dragover', (e) => e.preventDefault(), true);
}

/**
* Get and process tool`s drop configs
*
* @private
*/
private processTools(): void {
const tools = this.Editor.Tools.blockTools;

Object.entries(tools).forEach(this.processTool);
}

/**
* Check if onDrop config valid and save it to private property
*
* @param {string} name
* @param {Tool} tool
*/
private processTool = ([name, tool]): void => {
const toolDropConfig = tool.onDrop;

if (!toolDropConfig) {
return;
}

const {handler} = toolDropConfig;
let {extensions, mimeTypes} = toolDropConfig;

if (!handler || typeof handler !== 'function') {
_.log(`Drop handler for «${name}» Tool should be a function.`);
return;
}

if (extensions && !Array.isArray(extensions)) {
_.log(`«extensions» property of the onDrop config for «${name}» Tool should be an array`);
extensions = [];
}

if (mimeTypes && !Array.isArray(mimeTypes)) {
_.log(`«mimeTypes» property of the onDrop config for «${name}» Tool should be an array`);
mimeTypes = [];
}

if (mimeTypes) {
mimeTypes = mimeTypes.filter((type) => {
if (!_.isValidMimeType(type)) {
_.log(`MIME type value «${type}» for the «${name}» Tool is not a valid MIME type`, 'warn');
return false;
}

return true;
});
}

this.toolsDropConfigs[name] = {
extensions: extensions || [],
mimeTypes: mimeTypes || [],
handler,
};
}

/**
* Handle drop event
*
* @param {DragEvent} dropEvent
*/
private processDrop = async (dropEvent: DragEvent): Promise<void> => {
const {
BlockManager,
Paste,
} = this.Editor;

dropEvent.preventDefault();

BlockManager.blocks.forEach((block) => block.dropTarget = false);

if (SelectionUtils.isAtEditor && this.isStartedAtEditor) {
document.execCommand('delete');
}

this.isStartedAtEditor = false;

try {
neSpecc marked this conversation as resolved.
Show resolved Hide resolved
BlockManager.setCurrentBlockByChildNode(dropEvent.target, 'end');
} catch (e) {
BlockManager.setCurrentBlockByChildNode(BlockManager.lastBlock.holder, 'end');
}

if (!dropEvent.dataTransfer.files.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

надо оставить коммент

const isHTML = dropEvent.dataTransfer.types.includes('text/html');
let data;

if (isHTML) {
data = dropEvent.dataTransfer.getData('text/html');
data = '<p>' + data + '</p>';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

нужен коммент

} else {
data = dropEvent.dataTransfer.getData('Text');
}

Paste.processData(data, isHTML);

return;
}

let dataToInsert = [];

if (dropEvent.dataTransfer.files.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

разве тут не всегда будет true? выше обратная проверка с return;

dataToInsert = await Promise.all(
Array
.from(dropEvent.dataTransfer.items)
.map((item) => this.processDataTransferItem(item)),
);
dataToInsert = dataToInsert.filter((data) => !!data);
}

dataToInsert.forEach(
(data, i) => {
if (i === 0 && BlockManager.currentBlock && BlockManager.currentBlock.isEmpty) {
BlockManager.replace(data.type, data.data);
return;
}

BlockManager.insert(data.type, data.data);
},
);
}

/**
* Handle dropped files
* @param {DataTransferItem} item
*/
private processDataTransferItem = async (item: DataTransferItem) => {
if (item.kind === 'string') {
return;
}

const file = item.getAsFile();
const extension = _.getFileExtension(file);

const foundConfig = Object
.entries(this.toolsDropConfigs)
.find(([toolName, {mimeTypes, extensions}]) => {
const [fileType, fileSubtype] = file.type.split('/');

const foundExt = extensions.find((ext) => ext.toLowerCase() === extension.toLowerCase());
const foundMimeType = mimeTypes.find((mime) => {
const [type, subtype] = mime.split('/');

return type === fileType && (subtype === fileSubtype || subtype === '*');
});

return !!foundExt || !!foundMimeType;
});

if (!foundConfig) {
return;
}

const [tool, {handler}] = foundConfig;
return {
data: await handler(file),
type: tool,
};
}
}
Loading