Browse Source

Make use of getTargetToElementFixed for RTE

pull/2524/head
Artur Arseniev 7 years ago
parent
commit
c9981f1194
  1. 66
      src/canvas/index.js
  2. 2
      src/canvas/view/CanvasView.js
  3. 13
      src/canvas/view/FrameWrapView.js
  4. 27
      src/rich_text_editor/index.js

66
src/canvas/index.js

@ -402,6 +402,72 @@ export default () => {
return result;
},
canvasRectOffset(el, pos) {
const getFrameElFromDoc = doc => {
const { defaultView } = doc;
return defaultView && defaultView.frameElement;
};
const rectOff = (el, top = 1, pos) => {
const zoom = this.em.getZoomDecimal();
const side = top ? 'top' : 'left';
const doc = el.ownerDocument;
const { offsetTop = 0, offsetLeft = 0 } = getFrameElFromDoc(doc);
const { scrollTop = 0, scrollLeft = 0 } = doc.body || {};
const scroll = top ? scrollTop : scrollLeft;
const offset = top ? offsetTop : offsetLeft;
return pos[side] - (scroll - offset) * zoom;
};
return {
top: rectOff(el, 1, pos),
left: rectOff(el, 0, pos)
};
},
getTargetToElementFixed(el, elToMove, opts = {}) {
const pos = opts.pos || this.getElementPos(el);
const cvOff = opts.canvasOff || this.canvasRectOffset(el, pos);
const toolbarH = elToMove.offsetHeight || 0;
const toolbarW = elToMove.offsetWidth || 0;
const elRight = pos.left + pos.width;
const cv = this.getCanvasView();
const frCvOff = cv.getPosition();
const frameOffset = cv.getFrameOffset();
const { event } = opts;
let top = -toolbarH;
let left = pos.width - toolbarW;
left = pos.left < -left ? -pos.left : left;
left = elRight > frCvOff.width ? left - (elRight - frCvOff.width) : left;
// Scroll with the window if the top edge is reached and the
// element is bigger than the canvas
const fullHeight = pos.height + toolbarH;
const elIsShort = fullHeight < frameOffset.height;
if (cvOff.top < toolbarH) {
if (elIsShort) {
top = top + fullHeight;
} else {
top = -cvOff.top < pos.height ? -cvOff.top : pos.height;
}
}
const result = {
top,
left,
canvasOffsetTop: cvOff.top,
canvasOffsetLeft: cvOff.left
};
// In this way I can catch data and also change the position strategy
event && this.em.trigger(event, result);
return result;
},
/**
* Instead of simply returning e.clientX and e.clientY this function
* calculates also the offset based on the canvas. This is helpful when you

2
src/canvas/view/CanvasView.js

@ -38,7 +38,7 @@ export default Backbone.View.extend({
this.className = this.config.stylePrefix + 'canvas';
const { em } = this;
this.listenTo(em, 'change:canvasOffset', this.clearOff);
this.listenTo(em, 'frame:scroll', this.onFrameScroll);
// this.listenTo(em, 'frame:scroll', this.onFrameScroll);
this.listenTo(em, 'component:selected', this.checkSelected);
this.listenTo(model, 'change:zoom change:x change:y', this.updateFrames);
this.toggleListeners(1);

13
src/canvas/view/FrameWrapView.js

@ -17,21 +17,10 @@ export default Backbone.View.extend({
this.em = config.em;
this.ppfx = config.pStylePrefix || '';
this.frame = new FrameView({ model, config });
// this.listenTo(canvasView.model, 'change:zoom', this.canvasChange)
},
// canvasChange() {
// const zoom = this.config.module.getZoomMultiplier();
// this.elTools.style.transform = `scale(${zoom})`;
// },
onScroll() {
const { frame, em } = this;
// const unit = 'px';
// const { scrollTop, scrollLeft } = frame.getBody();
// const { style } = this.elTools;
// style.top = `-${scrollTop}${unit}`;
// style.left = `-${scrollLeft}${unit}`;
em.trigger('frame:scroll', {
frame,
body: frame.getBody(),
@ -87,7 +76,7 @@ export default Backbone.View.extend({
);
this.elTools = elTools;
cv.toolsWrapper.appendChild(elTools); // TODO remove on frame remove
frame.on('loaded', this.frameLoaded);
frame.model.on('loaded', this.frameLoaded);
return this;
}

27
src/rich_text_editor/index.js

@ -32,7 +32,7 @@ import defaults from './config/config';
export default () => {
let config = {};
let toolbar, actions, lastEl, globalRte;
let toolbar, actions, lastEl, lastElPos, globalRte;
const hideToolbar = () => {
const style = toolbar.style;
@ -234,26 +234,13 @@ export default () => {
updatePosition() {
const un = 'px';
const canvas = config.em.get('Canvas');
const pos = canvas.getTargetToElementDim(toolbar, lastEl, {
const { style } = toolbar;
const pos = canvas.getTargetToElementFixed(lastEl, toolbar, {
event: 'rteToolbarPosUpdate'
});
if (pos) {
if (config.adjustToolbar && 0) {
const frameOffset = canvas.getCanvasView().getFrameOffset();
// Move the toolbar down when the top canvas edge is reached
if (
pos.top <= pos.canvasTop &&
!(pos.elementHeight + pos.targetHeight >= frameOffset.height)
) {
pos.top = pos.elementTop + pos.elementHeight;
}
}
const toolbarStyle = toolbar.style;
toolbarStyle.top = -toolbar.offsetHeight + un;
toolbarStyle.left = 0 + un;
}
style.top = pos.top + un;
style.left = 0 + un;
},
/**
@ -264,16 +251,18 @@ export default () => {
* */
enable(view, rte) {
lastEl = view.el;
const canvas = config.em.get('Canvas');
const em = config.em;
const el = view.getChildrenContainer();
const customRte = this.customRte;
lastElPos = canvas.getElementPos(lastEl);
toolbar.style.display = '';
rte = customRte ? customRte.enable(el, rte) : this.initRte(el).enable();
if (em) {
setTimeout(this.updatePosition.bind(this), 0);
const event = 'change:canvasOffset canvasScroll';
const event = 'change:canvasOffset canvasScroll frame:scroll';
em.off(event, this.updatePosition, this);
em.on(event, this.updatePosition, this);
em.trigger('rte:enable', view, rte);

Loading…
Cancel
Save