Skip to content

Instantly share code, notes, and snippets.

@npfitz
Created April 7, 2016 17:16
Show Gist options
  • Save npfitz/df50a9dbce483613876add1dfefa2bbb to your computer and use it in GitHub Desktop.
Save npfitz/df50a9dbce483613876add1dfefa2bbb to your computer and use it in GitHub Desktop.
My version of joint.ui.popup
'use strict';
var $ = require('jquery');
var joint = require('rappid');
var _ = require('lodash');
function popup(){
joint.ui.Popup2 = joint.ui.ContextToolbar.extend({
className: 'popup',
eventNamespace: 'popup',
events: {},
renderContent: function() {
var content = _.isFunction(this.options.content) ? this.options.content(this.el) : this.options.content;
if (content) {
this.$el.html(content);
this.$el.append('<div class="carretColor carret"></div>');
this.$el.append('<div class="carretWhite carret"></div>');
}
},
position: function() {
var self = this,
position = self.options.position,
bbox = joint.util.getElementBBox(self.options.target),
rootBbox = joint.util.getElementBBox(self.getRoot()),
width = self.$el.outerWidth(),
height = self.$el.outerHeight(),
left, top;
if(position === 'bottom'){
left = bbox.x + bbox.width / 2 - width / 2;
top = bbox.y + bbox.height + self.options.padding;
}
else if(position === 'right'){
left = bbox.x + bbox.width + self.options.padding;
top = bbox.y + bbox.height / 2 - height / 2;
}
else if(position === 'top'){
left = bbox.x + bbox.width / 2 - width / 2;
top = bbox.y - height - self.options.padding;
}
else if(position === 'left'){
left = bbox.x - width - self.options.padding;
top = bbox.y + bbox.height / 2 - height / 2;
}
left -= rootBbox.x;
top -= rootBbox.y;
self.$el.css({ left: left, top: top });
self.$el.removeClass('joint-theme-default');
self.$el.addClass(position);
// Probably want to replace this with something associated to the paper element
var $parent = $(self.options.target).parent();
while($parent.css('position') !== 'absolute'){
$parent = $parent.parent();
if($parent.prop('tagName') === 'BODY'){
break;
}
}
var visible = self.isVisible(joint.util.getElementBBox(self.$el), joint.util.getElementBBox($parent));
if(!visible.visible){
self.ensureVisible(visible, joint.util.getElementBBox($parent));
}
self.drawCarret(bbox);
},
drawCarret: function(targetBBox){
var self = this,
bbox = joint.util.getElementBBox(self.$el),
position = self.options.position,
$white = self.$el.find('.carretWhite'),
$color = self.$el.find('.carretColor');
if(position === 'bottom'){
$white.css({
top: -18,
left: (targetBBox.x - bbox.x) + targetBBox.width / 2 - 10
});
$color.css({
top: -21,
left: (targetBBox.x - bbox.x) + targetBBox.width / 2 - 10
});
}
if(position === 'top'){
$white.css({
top: bbox.height - 5,
left: (targetBBox.x - bbox.x) + targetBBox.width / 2 - 10
});
$color.css({
top: bbox.height - 3,
left: (targetBBox.x - bbox.x) + targetBBox.width / 2 - 10
});
}
if(position === 'right'){
$white.css({
top: (targetBBox.y - bbox.y) + targetBBox.height / 2 - 10,
left: -18
});
$color.css({
top: (targetBBox.y - bbox.y) + targetBBox.height / 2 - 10,
left: -21
});
}
if(position === 'left'){
$white.css({
top: (targetBBox.y - bbox.y) + targetBBox.height / 2 - 10,
left: bbox.width - 5
});
$color.css({
top: (targetBBox.y - bbox.y) + targetBBox.height / 2 - 10,
left: bbox.width - 3
});
}
$color.css('border-' + position + '-color', '#444');
$white.css('border-' + position + '-color', '#fff');
},
isVisible: function(elementBBox, parentBBox){
var retval = {
visible: true,
dir: []
};
//check top
if(elementBBox.y < parentBBox.y){
retval.visible = false;
retval.dir.push('top');
}
//check bottom
if(elementBBox.y + elementBBox.height > parentBBox.y + parentBBox.height){
retval.visible = false;
retval.dir.push('bottom');
}
//check right
if(elementBBox.x + elementBBox.width > parentBBox.x + parentBBox.width){
retval.visible = false;
retval.dir.push('right');
}
//check left
if(elementBBox.x < parentBBox.x){
retval.visible = false;
retval.dir.push('left');
}
return retval;
},
ensureVisible: function(visible, windowBBox){
var self = this,
elementBBox = joint.util.getElementBBox(self.$el),
opposites = {
left: 'right',
right: 'left',
top: 'bottom',
bottom: 'top'
};
if(visible.visible){
return;
}
//Is the direction that is off the direction that you originally wanted?
else if(visible.dir.indexOf(self.options.position) >= 0){
self.options.position = opposites[self.options.position];
self.position();
return;
}
//Otherwise, minor adjustments
_.each(visible.dir, function(direction){
if(direction === 'top'){
self.$el.css({top: windowBBox.y + self.options.padding});
}
else if (direction === 'bottom'){
self.$el.css({top: (windowBBox.y + windowBBox.height) - elementBBox.height - self.options.padding});
}
else if (direction === 'left'){
self.$el.css({left: windowBBox.x + self.options.padding});
}
else if (direction === 'right'){
self.$el.css({left: (windowBBox.x + windowBBox.width) - elementBBox.width - self.options.padding});
}
});
}
});
}
export default popup;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment