Skip to content

Commit 99bdc9e

Browse files
committed
positioning support multiline for tooltipped content, now multiline tooltip is the step
1 parent 9de44bb commit 99bdc9e

7 files changed

+343
-155
lines changed

.jscsrc

-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
"requireOperatorBeforeLineBreak": [
4848
"?",
4949
"=",
50-
"+",
51-
"-",
5250
"/",
5351
"*",
5452
"==",

dist/angular-tooltips.css

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/angular-tooltips.css.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/angular-tooltips.js

+135-49
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,69 @@
1-
/*global angular,document*/
2-
(function withAngular(angular, document) {
1+
/*global angular,window*/
2+
(function withAngular(angular, window) {
33
'use strict';
44

55
var directiveName = 'tooltips'
66
, marginLeftTooltipArrow = 8
77
, deltaTooltipFromTooltipContent = 2
8+
, resizeObserver = (function optimizedResize() {
9+
10+
var callbacks = []
11+
, running = false
12+
, runCallbacks = function runCallbacks() {
13+
14+
callbacks.forEach(function iterator(callback) {
15+
16+
callback();
17+
});
18+
running = false;
19+
}
20+
, resize = function resize() {
21+
22+
if (!running) {
23+
24+
running = true;
25+
if (window.requestAnimationFrame) {
26+
27+
window.requestAnimationFrame(runCallbacks);
28+
} else {
29+
30+
window.setTimeout(runCallbacks, 66);
31+
}
32+
}
33+
}
34+
, addCallback = function addCallback(callback) {
35+
36+
if (callback) {
37+
38+
callbacks.push(callback);
39+
}
40+
};
41+
42+
return {
43+
'add': function add(callback) {
44+
45+
if (!callbacks.length) {
46+
47+
window.addEventListener('resize', resize);
48+
}
49+
addCallback(callback);
50+
}
51+
};
52+
}())
853
, getElementHTML = function getElementHTML(element) {
954
var txt
10-
, ax
11-
, el = document.createElement('div');
55+
, el = window.document.createElement('div');
1256

1357
element.removeAttr(directiveName);
1458
el.appendChild(element.clone()[0]);
1559
txt = el.innerHTML;
16-
ax = txt.indexOf('>') + 1;
17-
txt = txt.substring(0, ax) + element.html() + txt.substring(ax);
1860
el = null;
1961
return txt;
2062
}
21-
, trasformTooltipContent = function trasformTooltipContent(tooltippedContent, tooltipContent, tooltipTemplate, side) {
63+
, trasformTooltipContent = function trasformTooltipContent(tooltippedContent, tooltipTemplate) {
2264

2365
var toReturn = [
24-
'<a tooltips title="' + tooltipContent + '" class="' + side + ' tooltips">',
66+
'<tooltip tooltips class="tooltips">',
2567
'<tip-cont>',
2668
tooltippedContent,
2769
'</tip-cont>'
@@ -35,12 +77,12 @@
3577
'</tip>'
3678
]);
3779
}
38-
toReturn.push('</a>');
80+
toReturn.push('</tooltip>');
3981
return toReturn.join(' ');
4082
}
4183
, TooltipController = /*@ngInject*/ ["$log", function TooltipController($log) {
4284

43-
$log.info('controller called');
85+
$log.debug('controller called');
4486
}]
4587
, tooltipDirective = /*@ngInject*/ function tooltipDirective() {
4688

@@ -61,70 +103,112 @@
61103
'controller': TooltipController,
62104
'compile': function compiling(compileElement, compileAttributes) {
63105

64-
compileAttributes.tooltipTitle = compileAttributes.tooltipTitle || '';
65106
compileAttributes.tooltipTemplate = compileAttributes.tooltipTemplate || '';
66107
compileAttributes.tooltipSide = compileAttributes.tooltipSide || 'top';
67108
compileAttributes.tooltipShowTrigger = compileAttributes.tooltipShowTrigger || 'mousemove';
68109
compileAttributes.tooltipHideTrigger = compileAttributes.tooltipHideTrigger || 'mouseout';
69110
var initialElement = getElementHTML(compileElement)
70111
, startingTooltipContent = trasformTooltipContent(initialElement,
71-
compileAttributes.tooltipTitle,
72-
compileAttributes.tooltipTemplate,
73-
compileAttributes.tooltipSide);
112+
compileAttributes.tooltipTemplate);
74113

75114
compileElement.replaceWith(startingTooltipContent);
76115
return function linkingFunction(scope, element, attrs) {
77116

78-
var onTooltipShow = function onTooltipShow() {
117+
var onTooltipShow = function onTooltipShow(event) {
79118
var tipContElement = element.find('tip-cont')
80119
, tipElement = element.find('tip')
120+
, theTipContElement
121+
, theTipElement
122+
, theTipContClientRects
123+
, theTipClientRects
124+
, clientRectIndex
125+
, aClientRect
126+
, contentMinLeft = Number.MAX_SAFE_INTEGER
81127
, newLeft
82128
, newTop;
83129

84-
element.addClass('active');
130+
if (event) {
131+
132+
element.addClass('active');
133+
}
85134
if (tipContElement.length > 0 &&
86135
tipElement.length > 0) {
87136

88-
if (attrs.tooltipSide === 'top') {
89-
90-
newLeft = tipContElement[0].offsetLeft + tipContElement[0].offsetWidth / 2 - tipElement[0].offsetWidth / 2;
91-
newTop = tipContElement[0].offsetTop - marginLeftTooltipArrow - tipElement[0].offsetHeight - deltaTooltipFromTooltipContent;
92-
} else if (attrs.tooltipSide === 'left') {
93-
94-
newLeft = tipContElement[0].offsetLeft - tipElement[0].offsetWidth - marginLeftTooltipArrow - deltaTooltipFromTooltipContent;
95-
newTop = tipContElement[0].offsetTop + tipContElement[0].offsetHeight / 2 - tipElement[0].offsetHeight / 2;
137+
theTipContElement = tipContElement[0];
138+
theTipElement = tipElement[0];
139+
theTipContClientRects = theTipContElement.getClientRects();
140+
theTipClientRects = theTipElement.getClientRects();
141+
if (theTipClientRects.length > 0) {
142+
143+
/*jshint -W014*/
144+
if (attrs.tooltipSide === 'top') {
145+
146+
newLeft = theTipContElement.offsetLeft
147+
+ theTipContClientRects[0].width / 2
148+
- theTipClientRects[0].width / 2;
149+
newTop = theTipContElement.offsetTop
150+
- marginLeftTooltipArrow
151+
- theTipClientRects[0].height
152+
- deltaTooltipFromTooltipContent;
153+
} else if (attrs.tooltipSide === 'left') {
154+
155+
for (clientRectIndex = 0; clientRectIndex < theTipContClientRects.length; clientRectIndex += 1) {
156+
157+
aClientRect = theTipContClientRects.item(clientRectIndex);
158+
if (aClientRect &&
159+
aClientRect.left <= contentMinLeft) {
160+
161+
contentMinLeft = aClientRect.left;
162+
}
163+
}
164+
165+
newLeft = contentMinLeft
166+
- theTipElement.offsetWidth
167+
- marginLeftTooltipArrow
168+
- deltaTooltipFromTooltipContent;
169+
newTop = theTipContElement.offsetTop
170+
+ theTipContElement.offsetHeight / 2
171+
- theTipElement.offsetHeight / 2;
172+
} else if (attrs.tooltipSide === 'bottom') {
173+
174+
newLeft = theTipContClientRects[theTipContClientRects.length - 1].left
175+
+ theTipContClientRects[theTipContClientRects.length - 1].width / 2
176+
- theTipClientRects[0].width / 2;
177+
newTop = theTipContElement.offsetTop
178+
+ theTipContElement.offsetHeight
179+
+ marginLeftTooltipArrow;
180+
} else if (attrs.tooltipSide === 'right') {
181+
182+
for (clientRectIndex = 0; clientRectIndex < theTipContClientRects.length; clientRectIndex += 1) {
183+
184+
aClientRect = theTipContClientRects.item(clientRectIndex);
185+
if (aClientRect &&
186+
aClientRect.left <= contentMinLeft) {
187+
188+
contentMinLeft = aClientRect.left;
189+
}
190+
}
191+
192+
newLeft = contentMinLeft
193+
+ theTipContElement.offsetWidth
194+
+ marginLeftTooltipArrow;
195+
newTop = theTipContElement.offsetTop
196+
+ theTipContElement.offsetHeight / 2
197+
- theTipElement.offsetHeight / 2;
198+
}
199+
/*jshint +W014*/
96200
}
97201

98202
tipElement.css({
99203
'left': newLeft + 'px',
100204
'top': newTop + 'px'
101205
});
102-
/*if (attrs.tooltipSide === 'top' || attrs.tooltipSide === 'bottom') {
103-
104-
newLeft = -(actualWidth / 2 + actualPaddingLeft / 2);
105-
tipElement.css('left', newLeft + 'px');
106-
} else if (attrs.tooltipSide === 'left' || attrs.tooltipSide === 'right') {
107-
108-
newTop = -(actualHeight / 2 + actualPaddingTop / 2);
109-
tipElement.css('top', newTop + 'px');
110-
}*/
111206
}
112207
}
113208
, onTooltipHide = function onTooltipHide() {
114209

115210
element.removeClass('active');
116211
}
117-
, onTooltipTitleChange = function onTooltipTitleChange(newValue, oldValue) {
118-
119-
if (newValue) {
120-
121-
if (oldValue) {
122-
123-
element.find('tip').html(newValue);
124-
}
125-
scope.tooltipCtrl.tooltipTitle = newValue;
126-
}
127-
}
128212
, onTooltipTemplateChange = function onTooltipTemplateChange(newValue, oldValue) {
129213

130214
if (newValue) {
@@ -142,9 +226,9 @@
142226

143227
if (oldValue) {
144228

145-
element.removeAttr(oldValue);
229+
element.removeAttr('_' + oldValue);
146230
}
147-
element.addClass(newValue);
231+
element.addClass('_' + newValue);
148232
scope.tooltipCtrl.tooltipSide = newValue;
149233
}
150234
}
@@ -170,15 +254,17 @@
170254
element.on(newValue, onTooltipHide);
171255
}
172256
}
173-
, unregisterOnTooltipTitleChangeObserver = attrs.$observe('tooltipTitle', onTooltipTitleChange)
174257
, unregisterOnTooltipTemplateChange = attrs.$observe('tooltipTemplate', onTooltipTemplateChange)
175258
, unregisterOnTooltipSideChangeObserver = attrs.$observe('tooltipSide', onTooltipSideChange)
176259
, unregisterOnTooltipShowTrigger = attrs.$observe('tooltipShowTrigger', onTooltipShowTrigger)
177260
, unregisterOnTooltipHideTrigger = attrs.$observe('tooltipHideTrigger', onTooltipHideTrigger);
178261

262+
resizeObserver.add(function registerResize() {
263+
264+
onTooltipShow(undefined);
265+
});
179266
scope.$on('$destroy', function unregisterListeners() {
180267

181-
unregisterOnTooltipTitleChangeObserver();
182268
unregisterOnTooltipTemplateChange();
183269
unregisterOnTooltipSideChangeObserver();
184270
unregisterOnTooltipShowTrigger();
@@ -192,4 +278,4 @@
192278

193279
angular.module('720kb.tooltips', [])
194280
.directive(directiveName, tooltipDirective);
195-
}(angular, document));
281+
}(angular, window));

0 commit comments

Comments
 (0)