Created
April 7, 2016 17:16
-
-
Save npfitz/df50a9dbce483613876add1dfefa2bbb to your computer and use it in GitHub Desktop.
My version of joint.ui.popup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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