Skip to content

Commit

Permalink
Make tether-to-selection use fixed positioning relative to selection
Browse files Browse the repository at this point in the history
Changes `{{tether-to-selection}}` to:
  * use "position: fixed". Avoids issues when the editor is in an
    absolutely-positioned div
  * (bugfix) Do not position relative to ".mobiledoc-editor". This was
    error-prone when there was more than one editor on the page, and also
    unnecessary.
  * Add 'mobiledoc-selection-tether' class (escape hatch for styling by
    consumers)
  * (bugfix) Read the window's selection metrics before element insertion. When
    the yielded link-prompt component focuses its input field, that
    changes the window selection. Reading before insertion fixes this
    problem.
  • Loading branch information
bantic committed Apr 12, 2016
1 parent d440171 commit 3fa3fe1
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions addon/components/tether-to-selection/component.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
import jQuery from 'jquery';
import Ember from 'ember';
import layout from './template';

let { Component } = Ember;

const LEFT_PADDING = 0;
const TOP_PADDING = 10;

export default Component.extend({
layout,
classNames: ['mobiledoc-selection-tether'],
left: 0,
top: 0,

willInsertElement() {
let selection = window.getSelection();
let range = selection && selection.rangeCount && selection.getRangeAt(0);

Ember.assert('Should not render {{#tether-to-selection}} when there is no selection', !!range);

if (range) {
let rect = range.getBoundingClientRect();
this.set('left', rect.left);
this.set('top', rect.top);
}
},

didInsertElement() {
Ember.run.schedule('afterRender', () => {
var selection = window.getSelection();
var range = selection && selection.rangeCount && selection.getRangeAt(0);

if (range) {
var rect = range.getBoundingClientRect();
let wrapperOffset = jQuery('.mobiledoc-editor').offset();
let myHeight = this.$().height();
this.$().css({
position: 'absolute',
left: `${rect.left - wrapperOffset.left}px`,
top: `${rect.top - wrapperOffset.top - myHeight - 10}px`
});
}
let myHeight = this.$().height();
let left = this.get('left') - LEFT_PADDING;
let top = this.get('top') - TOP_PADDING - myHeight;

this.$().css({
position: 'fixed',
left: `${left}px`,
top: `${top}px`
});
});
}
});

0 comments on commit 3fa3fe1

Please sign in to comment.