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

Refactor sorter #6149

Merged
merged 93 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
8c6cbdb
Add canMove and getChildren to Sorter
mohamedsalem401 Sep 6, 2024
9d711e7
Make the canvas use Components.canMove function
mohamedsalem401 Sep 6, 2024
4c81586
Fix StyleManager issue
mohamedsalem401 Sep 6, 2024
21e4ca2
Make Sorter dependent on an abstract datastructure
mohamedsalem401 Sep 10, 2024
85c9dab
Remove unneeded properties
mohamedsalem401 Sep 10, 2024
185ef8d
Add drag direction enum
mohamedsalem401 Sep 10, 2024
19e7145
extract method
mohamedsalem401 Sep 10, 2024
67e2e71
Add default values for the sorter
mohamedsalem401 Sep 10, 2024
3638a8a
reverse avoidSelectOnEnd
mohamedsalem401 Sep 10, 2024
20c7990
Group related options for the Sorter
mohamedsalem401 Sep 10, 2024
f8088e5
Fix types, and fix canvas sorter
mohamedsalem401 Sep 10, 2024
c62ab28
Add method to clear source element freeze
mohamedsalem401 Sep 10, 2024
4f17832
Add DropLocationDeterminer class
mohamedsalem401 Sep 10, 2024
37cc27b
Refactor some methods in the sorter
mohamedsalem401 Sep 10, 2024
d27af86
Refactor endMove method
mohamedsalem401 Sep 10, 2024
332bec7
Refactor rollback method
mohamedsalem401 Sep 10, 2024
726dbdf
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into refac…
mohamedsalem401 Sep 11, 2024
1d0e52d
Add DropLocationDeterminer, refactor methods in Sorter class
mohamedsalem401 Sep 11, 2024
8c94152
Break the sorter into multiple classes
mohamedsalem401 Sep 13, 2024
99edd1e
Fix placeholder class jsdocs
mohamedsalem401 Sep 15, 2024
fb2b4c0
Fix bug while dropping items near the border
mohamedsalem401 Sep 15, 2024
69fc8ea
Refactor DropLocationDeterminer
mohamedsalem401 Sep 15, 2024
8fd7ed9
Add helping methods to the ComponentSorter
mohamedsalem401 Sep 15, 2024
f17d164
Remove unwanted fields in DropLocationDeterminer
mohamedsalem401 Sep 15, 2024
e3e16c0
Add componentSorter Class
mohamedsalem401 Sep 16, 2024
6729c33
Refactor DropLocationDeterminer Class
mohamedsalem401 Sep 16, 2024
0037371
Rename file
mohamedsalem401 Sep 16, 2024
c459498
Fix style manager class
mohamedsalem401 Sep 16, 2024
90cf6ea
Move files into a new folder
mohamedsalem401 Sep 16, 2024
ef40cea
Move types to a new file
mohamedsalem401 Sep 16, 2024
d289046
Add back the tree class paramater instead of abstract classes
mohamedsalem401 Sep 16, 2024
45da2af
Fix dropping on the same collection issue
mohamedsalem401 Sep 16, 2024
014da81
refactor isInFlow
mohamedsalem401 Sep 17, 2024
3ce4cef
Change methods to be accessor methods
mohamedsalem401 Sep 17, 2024
7e0becc
Make component sorter dependant on an abstract node
mohamedsalem401 Sep 17, 2024
8dab8a2
Fix bug with dropping into an element with no children
mohamedsalem401 Sep 17, 2024
34ea415
Fix component layers drag and drop
mohamedsalem401 Sep 17, 2024
2266283
Remove the ensure placeholder logic from the StyleManagerSorter
mohamedsalem401 Sep 17, 2024
ee78ed2
Refactor event handler types
mohamedsalem401 Sep 17, 2024
a81dbb8
export interface SorterEventHandlers
mohamedsalem401 Sep 17, 2024
de9cf1c
change to ensurePlaceholderElement method
mohamedsalem401 Sep 17, 2024
7281828
Make images droppable
mohamedsalem401 Sep 19, 2024
f2ed0b1
Add support for dragging and dropping textable components
mohamedsalem401 Sep 19, 2024
88d91c9
Remove container argument from startSort
mohamedsalem401 Sep 19, 2024
a5db2fe
Trigger events on starting and ending the dragging
mohamedsalem401 Sep 19, 2024
2b8b2bd
Add triggering old events and callback functions
mohamedsalem401 Sep 20, 2024
150a1e6
Fix drop issue with the style manager
mohamedsalem401 Sep 20, 2024
e6e9c2f
Add cancelling the dragging
mohamedsalem401 Sep 20, 2024
92302db
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into refac…
mohamedsalem401 Sep 22, 2024
782851b
Hide placeholder if no target
mohamedsalem401 Sep 22, 2024
2bd54b6
Refactor droplocationdeteminer and improve performance
mohamedsalem401 Sep 22, 2024
619d959
Fix some bugs
mohamedsalem401 Sep 22, 2024
e9f6bb8
Fix some callbacks
mohamedsalem401 Sep 22, 2024
879e58c
trigger 'sorter:drag:validation'
mohamedsalem401 Sep 22, 2024
b9e1a12
Disable editable text after dropping
mohamedsalem401 Sep 22, 2024
2c4a983
Remove unused functions
mohamedsalem401 Sep 22, 2024
5bddea2
Fix placeholder direction
mohamedsalem401 Sep 23, 2024
2587ba6
Refactor restnode state
mohamedsalem401 Sep 23, 2024
aa8c559
Run formatter
mohamedsalem401 Sep 23, 2024
2d58456
Remove unused code and redundent comments
mohamedsalem401 Sep 23, 2024
9c84530
Fix stack test
mohamedsalem401 Sep 23, 2024
ad9fca7
Merge branch 'dev' into refactor-sorter
artf Sep 24, 2024
2288078
Merge branch 'dev' of https://github.com/GrapesJS/grapesjs into refac…
mohamedsalem401 Sep 25, 2024
3fa0515
Avoid triggering the drop event twice
mohamedsalem401 Sep 25, 2024
98759c5
Fix styles being removed when dragging components
mohamedsalem401 Sep 25, 2024
9d1e629
change 'sorter:drag:start' event triggering
mohamedsalem401 Sep 25, 2024
c0be6bd
Fix legacyOnMove not being triggered
mohamedsalem401 Sep 25, 2024
f4c3512
Some refactor
mohamedsalem401 Sep 25, 2024
a907d1f
Fix selection after cancelling
mohamedsalem401 Sep 25, 2024
894c8e4
Fix triggering update event without moving any component
mohamedsalem401 Sep 25, 2024
57a0b09
fix the sort of dragged components
mohamedsalem401 Sep 25, 2024
ae5fe69
make style manager droppable even if the mouse is outside the continer
mohamedsalem401 Sep 25, 2024
1069558
Fix selecting blocks after being dropped
mohamedsalem401 Sep 25, 2024
59836e7
Merge branch 'dev' into refactor-sorter
artf Sep 26, 2024
d5cf3de
Fix placeholder for empty containers
mohamedsalem401 Sep 26, 2024
2712206
Fix blocks drag cancel issue
mohamedsalem401 Sep 26, 2024
115ccea
Fix style manager cancel
mohamedsalem401 Sep 26, 2024
eb84892
Fix autoscroll not stopping issue
mohamedsalem401 Sep 26, 2024
280d1bb
Fix comment components drag
mohamedsalem401 Sep 26, 2024
85847cb
Fix issue with hidden elements
mohamedsalem401 Sep 26, 2024
a64af92
Fix selection after dropping
mohamedsalem401 Sep 27, 2024
67fa7f7
Format
mohamedsalem401 Sep 27, 2024
fd6a6d2
Fix position on scroll
mohamedsalem401 Sep 27, 2024
fbf4c45
remove console.log
mohamedsalem401 Sep 27, 2024
da50ac8
Change target calculation with scroll
mohamedsalem401 Sep 27, 2024
057dce5
Fix blocks not activating issue
mohamedsalem401 Sep 27, 2024
f4f90ef
Fix block drop in wrapper issue
mohamedsalem401 Sep 27, 2024
846d4e9
Fix dropping multiple components in the same position
mohamedsalem401 Sep 27, 2024
897779e
Preserve target canvas spot
artf Sep 30, 2024
7673a81
Avoid updating non-text related component on drag/drop
artf Sep 30, 2024
20e32dc
Merge branch 'dev' into refactor-sorter
artf Sep 30, 2024
adaa367
skip sorter tests
artf Sep 30, 2024
1809c5a
Merge branch 'refactor-sorter' of https://github.com/artf/grapesjs in…
artf Sep 30, 2024
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
9 changes: 2 additions & 7 deletions packages/core/src/block_manager/view/BlockView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export default class BlockView extends View<Block> {
sorter.__currentBlock = model;
sorter.setDragHelper(this.el, e);
sorter.setDropContent(this.model.get('content'));
sorter.startSort(this.el);
sorter.startSort([this.el]);
on(document, 'mouseup', this.endDrag);
}

Expand All @@ -126,12 +126,7 @@ export default class BlockView extends View<Block> {
off(document, 'mouseup', this.endDrag);
const sorter = this.config.getSorter();

// After dropping the block in the canvas the mouseup event is not yet
// triggerd on 'this.doc' and so clicking outside, the sorter, tries to move
// things (throws false positives). As this method just need to drop away
// the block helper I use the trick of 'moved = 0' to void those errors.
sorter.moved = 0;
sorter.endMove();
sorter.cancelDrag();
}

render() {
Expand Down
8 changes: 5 additions & 3 deletions packages/core/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ export const getOnComponentDrag = (em: Editor) => (data: any) => em.trigger(even
export const getOnComponentDragEnd =
(em: Editor, targets: Component[], opts: { altMode?: boolean } = {}) =>
(a: any, b: any, data: any) => {
targets.forEach((trg) => trg.set('status', trg.get('selectable') ? 'selected' : ''));
em.setSelected(targets);
targets[0].emitUpdate();
setTimeout(() => {
targets.forEach((trg) => trg.set('status', trg.get('selectable') ? 'selected' : ''));
em.setSelected(targets);
targets[0].emitUpdate();
});
em.trigger(`${eventDrag}:end`, data);

// Defer selectComponent in order to prevent canvas "freeze" #2692
Expand Down
16 changes: 7 additions & 9 deletions packages/core/src/commands/view/MoveComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default extend({}, SelectPosition, SelectComponent, {
this.cacheEl = null;
this.startSelectPosition(e.target, this.frameEl.contentDocument);
this.sorter.draggable = drag;
this.sorter.onEndMove = this.onEndMove.bind(this);
this.sorter.eventHandlers.legacyOnEndMove = this.onEndMove.bind(this);
this.stopSelectComponent();
this.$wrapper.off('mousedown', this.initSorter);
on(this.getContentWindow(), 'keydown', this.rollback);
Expand All @@ -68,7 +68,7 @@ export default extend({}, SelectPosition, SelectComponent, {
var el = model.view.el;
this.startSelectPosition(el, this.frameEl.contentDocument);
this.sorter.draggable = drag;
this.sorter.onEndMove = this.onEndMoveFromModel.bind(this);
this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this);

/*
this.sorter.setDragHelper(el);
Expand All @@ -95,11 +95,10 @@ export default extend({}, SelectPosition, SelectComponent, {
const frameView = this.em.getCurrentFrame();
const el = lastModel.getEl(frameView?.model)!;
const doc = el.ownerDocument;
this.startSelectPosition(el, doc, { onStart: this.onStart });
this.sorter.draggable = lastModel.get('draggable');
this.sorter.toMove = models;
this.sorter.onMoveClb = this.onDrag;
this.sorter.onEndMove = this.onEndMoveFromModel.bind(this);
const elements = models.map((model) => model?.view?.el);
this.startSelectPosition(elements, doc, { onStart: this.onStart });
this.sorter.eventHandlers.legacyOnMoveClb = this.onDrag;
this.sorter.eventHandlers.legacyOnEndMove = this.onEndMoveFromModel.bind(this);
this.stopSelectComponent();
on(this.getContentWindow(), 'keydown', this.rollback);
},
Expand Down Expand Up @@ -134,8 +133,7 @@ export default extend({}, SelectPosition, SelectComponent, {
rollback(e: any, force: boolean) {
var key = e.which || e.keyCode;
if (key == 27 || force) {
this.sorter.moved = false;
this.sorter.endMove();
this.sorter.cancelDrag();
}
return;
},
Expand Down
56 changes: 35 additions & 21 deletions packages/core/src/commands/view/SelectPosition.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,51 @@
import { $ } from '../../common';
import CanvasComponentNode from '../../utils/sorter/CanvasComponentNode';
import { DragDirection } from '../../utils/sorter/types';
import { CommandObject } from './CommandAbstract';

export default {
/**
* Start select position event
* @param {HTMLElement} trg
* @param {HTMLElement[]} sourceElements
* @private
* */
startSelectPosition(trg: HTMLElement, doc: Document, opts: any = {}) {
startSelectPosition(sourceElements: HTMLElement[], doc: Document, opts: any = {}) {
this.isPointed = false;
const utils = this.em.Utils;
const container = trg.ownerDocument.body;
const container = sourceElements[0].ownerDocument.body;

if (utils && !this.sorter)
this.sorter = new utils.Sorter({
// @ts-ignore
container,
placer: this.canvas.getPlacerEl(),
containerSel: '*',
itemSel: '*',
pfx: this.ppfx,
direction: 'a',
document: doc,
wmargin: 1,
nested: 1,
this.sorter = new utils.ComponentSorter({
em: this.em,
canvasRelative: 1,
scale: () => this.em.getZoomDecimal(),
treeClass: CanvasComponentNode,
containerContext: {
container,
containerSel: '*',
itemSel: '*',
pfx: this.ppfx,
document: doc,
placeholderElement: this.canvas.getPlacerEl()!,
},
positionOptions: {
windowMargin: 1,
canvasRelative: true,
},
dragBehavior: {
dragDirection: DragDirection.BothDirections,
nested: true,
},
});

if (opts.onStart) this.sorter.onStart = opts.onStart;
trg && this.sorter.startSort(trg, { container });
if (opts.onStart) this.sorter.eventHandlers.legacyOnStartSort = opts.onStart;
this.em.on(
'frame:scroll',
((...agrs: any[]) => {
const canvasScroll = this.canvas.getCanvasView().frame === agrs[0].frame;
if (canvasScroll) this.sorter.recalculateTargetOnScroll();
}).bind(this),
);
sourceElements &&
sourceElements.length > 0 &&
this.sorter.startSort(sourceElements.map((element) => ({ element })));
},

/**
Expand All @@ -54,8 +69,7 @@ export default {
this.posTargetCollection = null;
this.posIndex = this.posMethod == 'after' && this.cDim.length !== 0 ? this.posIndex + 1 : this.posIndex; //Normalize
if (this.sorter) {
this.sorter.moved = 0;
this.sorter.endMove();
this.sorter.cancelDrag();
}
if (this.cDim) {
this.posIsLastEl = this.cDim.length !== 0 && this.posMethod == 'after' && this.posIndex == this.cDim.length;
Expand Down
17 changes: 11 additions & 6 deletions packages/core/src/navigator/view/ItemView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { isEnterKey, isEscKey } from '../../utils/dom';
import LayerManager from '../index';
import ItemsView from './ItemsView';
import { getOnComponentDrag, getOnComponentDragEnd, getOnComponentDragStart } from '../../commands';
import Sorter from '../../utils/sorter/Sorter';
import LayersComponentNode from '../../utils/sorter/LayersComponentNode';

export type ItemViewProps = ViewOptions & {
ItemView: ItemView;
Expand Down Expand Up @@ -99,7 +101,7 @@ export default class ItemView extends View {
opt: ItemViewProps;
module: LayerManager;
config: any;
sorter: any;
sorter: Sorter<Component, LayersComponentNode>;
/** @ts-ignore */
model!: Component;
parentView: ItemView;
Expand Down Expand Up @@ -323,11 +325,14 @@ export default class ItemView extends View {

if (sorter) {
const toMove = model.delegate?.move?.(model) || model;
sorter.onStart = getOnComponentDragStart(em);
sorter.onMoveClb = getOnComponentDrag(em);
sorter.onEndMove = getOnComponentDragEnd(em, [toMove]);
const itemEl = (toMove as any).viewLayer?.el || ev.target;
sorter.startSort(itemEl);
sorter.eventHandlers = {
legacyOnStartSort: getOnComponentDragStart(em),
legacyOnMoveClb: getOnComponentDrag(em),
legacyOnEndMove: getOnComponentDragEnd(em, [toMove]),
...sorter.eventHandlers,
};
const element = (toMove as any).viewLayer?.el || ev.target;
sorter.startSort([{ element }]);
}
}

Expand Down
51 changes: 40 additions & 11 deletions packages/core/src/navigator/view/ItemsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import EditorModel from '../../editor/model/Editor';
import ItemView from './ItemView';
import Components from '../../dom_components/model/Components';
import LayerManager from '..';
import { DragDirection } from '../../utils/sorter/types';
import LayersComponentNode from '../../utils/sorter/LayersComponentNode';
import ComponentSorter from '../../utils/sorter/ComponentSorter';

export default class ItemsView extends View {
items: ItemView[];
opt: any;
opt: {
sorter: ComponentSorter<LayersComponentNode>;
[k: string]: any;
};
config: any;
parentView: ItemView;
module: LayerManager;
Expand All @@ -34,17 +40,23 @@ export default class ItemsView extends View {

if (config.sortable && !this.opt.sorter) {
const utils = em.Utils;
this.opt.sorter = new utils.Sorter({
// @ts-ignore
container: config.sortContainer || this.el,
containerSel: `.${this.className}`,
itemSel: `.${pfx}layer`,
ignoreViewChildren: 1,
avoidSelectOnEnd: 1,
nested: 1,
ppfx,
pfx,
const container = config.sortContainer || this.el;
const placeholderElement = this.createPlaceholder(pfx);
this.opt.sorter = new utils.ComponentSorter({
em,
treeClass: LayersComponentNode,
containerContext: {
container: container,
containerSel: `.${this.className}`,
itemSel: `.${pfx}layer`,
pfx: config.pStylePrefix,
document: document,
placeholderElement: placeholderElement,
},
dragBehavior: {
dragDirection: DragDirection.Vertical,
nested: true,
},
});
}

Expand All @@ -53,6 +65,23 @@ export default class ItemsView extends View {
opt.parent && this.$el.data('model', opt.parent);
}

/**
* Create placeholder
* @return {HTMLElement}
*/
private createPlaceholder(pfx: string) {
const el = document.createElement('div');
const ins = document.createElement('div');
this.el.parentNode;
el.className = pfx + 'placeholder';
el.style.display = 'none';
el.style.pointerEvents = 'none';
ins.className = pfx + 'placeholder-int';
el.appendChild(ins);

return el;
}

removeChildren(removed: Component) {
const view = removed.viewLayer;
if (!view) return;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/style_manager/model/Layers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Collection } from '../../common';
import LayersView from '../view/LayersView';
import Layer from './Layer';

export default class Layers extends Collection<Layer> {
prop: any;
view?: LayersView;

initialize(p: any, opts: { prop?: any } = {}) {
this.prop = opts.prop;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/style_manager/view/LayerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class LayerView extends View<Layer> {
}

initSorter() {
this.sorter?.startSort(this.el);
this.sorter?.startSort([{ element: this.el }]);
}

removeItem(ev: Event) {
Expand Down
49 changes: 38 additions & 11 deletions packages/core/src/style_manager/view/LayersView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { View } from '../../common';
import EditorModel from '../../editor/model/Editor';
import StyleManagerSorter from '../../utils/sorter/StyleManagerSorter';
import { DragDirection } from '../../utils/sorter/types';
import Layer from '../model/Layer';
import Layers from '../model/Layers';
import LayerView from './LayerView';
import PropertyStackView from './PropertyStackView';

Expand All @@ -10,7 +13,7 @@ export default class LayersView extends View<Layer> {
config: any;
propertyView: PropertyStackView;
items: LayerView[];
sorter: any;
sorter?: StyleManagerSorter;

constructor(o: any) {
super(o);
Expand All @@ -27,20 +30,28 @@ export default class LayersView extends View<Layer> {
this.listenTo(coll, 'add', this.addTo);
this.listenTo(coll, 'reset', this.reset);
this.items = [];
const placeholderElement = this.createPlaceholder(config.pStylePrefix);
this.$el.append(placeholderElement);

// For the Sorter
const utils = em?.Utils;
this.sorter = utils
? new utils.Sorter({
// @ts-ignore
container: this.el,
ignoreViewChildren: 1,
containerSel: `.${pfx}layers`,
itemSel: `.${pfx}layer`,
pfx: config.pStylePrefix,
? new utils.StyleManagerSorter({
em,
containerContext: {
container: this.el,
containerSel: `.${pfx}layers`,
itemSel: `.${pfx}layer`,
pfx: config.pStylePrefix,
document: document,
placeholderElement: placeholderElement,
},
dragBehavior: {
dragDirection: DragDirection.Vertical,
nested: false,
},
})
: '';
: undefined;
// @ts-ignore
coll.view = this;
this.$el.data('model', coll);
Expand Down Expand Up @@ -107,14 +118,30 @@ export default class LayersView extends View<Layer> {
}

render() {
const { $el, sorter } = this;
const { $el } = this;
const frag = document.createDocumentFragment();
$el.empty();
this.collection.forEach((m) => this.addToCollection(m, frag));
$el.append(frag);
$el.attr('class', this.className!);
if (sorter) sorter.plh = null;

return this;
}

/**
* Create placeholder
* @return {HTMLElement}
*/
private createPlaceholder(pfx: string) {
const el = document.createElement('div');
const ins = document.createElement('div');
this.el.parentNode;
el.className = pfx + 'placeholder';
el.style.display = 'none';
el.style.pointerEvents = 'none';
ins.className = pfx + 'placeholder-int';
el.appendChild(ins);

return el;
}
}
Loading