|
1 |
| -/*global angular,document*/ |
2 |
| -(function withAngular(angular, document) { |
| 1 | +/*global angular,window*/ |
| 2 | +(function withAngular(angular, window) { |
3 | 3 | 'use strict';
|
4 | 4 |
|
5 | 5 | var directiveName = 'tooltips'
|
6 | 6 | , marginLeftTooltipArrow = 8
|
7 | 7 | , 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 | + }()) |
8 | 53 | , getElementHTML = function getElementHTML(element) {
|
9 | 54 | var txt
|
10 |
| - , ax |
11 |
| - , el = document.createElement('div'); |
| 55 | + , el = window.document.createElement('div'); |
12 | 56 |
|
13 | 57 | element.removeAttr(directiveName);
|
14 | 58 | el.appendChild(element.clone()[0]);
|
15 | 59 | txt = el.innerHTML;
|
16 |
| - ax = txt.indexOf('>') + 1; |
17 |
| - txt = txt.substring(0, ax) + element.html() + txt.substring(ax); |
18 | 60 | el = null;
|
19 | 61 | return txt;
|
20 | 62 | }
|
21 |
| - , trasformTooltipContent = function trasformTooltipContent(tooltippedContent, tooltipContent, tooltipTemplate, side) { |
| 63 | + , trasformTooltipContent = function trasformTooltipContent(tooltippedContent, tooltipTemplate) { |
22 | 64 |
|
23 | 65 | var toReturn = [
|
24 |
| - '<a tooltips title="' + tooltipContent + '" class="' + side + ' tooltips">', |
| 66 | + '<tooltip tooltips class="tooltips">', |
25 | 67 | '<tip-cont>',
|
26 | 68 | tooltippedContent,
|
27 | 69 | '</tip-cont>'
|
|
35 | 77 | '</tip>'
|
36 | 78 | ]);
|
37 | 79 | }
|
38 |
| - toReturn.push('</a>'); |
| 80 | + toReturn.push('</tooltip>'); |
39 | 81 | return toReturn.join(' ');
|
40 | 82 | }
|
41 | 83 | , TooltipController = /*@ngInject*/ ["$log", function TooltipController($log) {
|
42 | 84 |
|
43 |
| - $log.info('controller called'); |
| 85 | + $log.debug('controller called'); |
44 | 86 | }]
|
45 | 87 | , tooltipDirective = /*@ngInject*/ function tooltipDirective() {
|
46 | 88 |
|
|
61 | 103 | 'controller': TooltipController,
|
62 | 104 | 'compile': function compiling(compileElement, compileAttributes) {
|
63 | 105 |
|
64 |
| - compileAttributes.tooltipTitle = compileAttributes.tooltipTitle || ''; |
65 | 106 | compileAttributes.tooltipTemplate = compileAttributes.tooltipTemplate || '';
|
66 | 107 | compileAttributes.tooltipSide = compileAttributes.tooltipSide || 'top';
|
67 | 108 | compileAttributes.tooltipShowTrigger = compileAttributes.tooltipShowTrigger || 'mousemove';
|
68 | 109 | compileAttributes.tooltipHideTrigger = compileAttributes.tooltipHideTrigger || 'mouseout';
|
69 | 110 | var initialElement = getElementHTML(compileElement)
|
70 | 111 | , startingTooltipContent = trasformTooltipContent(initialElement,
|
71 |
| - compileAttributes.tooltipTitle, |
72 |
| - compileAttributes.tooltipTemplate, |
73 |
| - compileAttributes.tooltipSide); |
| 112 | + compileAttributes.tooltipTemplate); |
74 | 113 |
|
75 | 114 | compileElement.replaceWith(startingTooltipContent);
|
76 | 115 | return function linkingFunction(scope, element, attrs) {
|
77 | 116 |
|
78 |
| - var onTooltipShow = function onTooltipShow() { |
| 117 | + var onTooltipShow = function onTooltipShow(event) { |
79 | 118 | var tipContElement = element.find('tip-cont')
|
80 | 119 | , tipElement = element.find('tip')
|
| 120 | + , theTipContElement |
| 121 | + , theTipElement |
| 122 | + , theTipContClientRects |
| 123 | + , theTipClientRects |
| 124 | + , clientRectIndex |
| 125 | + , aClientRect |
| 126 | + , contentMinLeft = Number.MAX_SAFE_INTEGER |
81 | 127 | , newLeft
|
82 | 128 | , newTop;
|
83 | 129 |
|
84 |
| - element.addClass('active'); |
| 130 | + if (event) { |
| 131 | + |
| 132 | + element.addClass('active'); |
| 133 | + } |
85 | 134 | if (tipContElement.length > 0 &&
|
86 | 135 | tipElement.length > 0) {
|
87 | 136 |
|
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*/ |
96 | 200 | }
|
97 | 201 |
|
98 | 202 | tipElement.css({
|
99 | 203 | 'left': newLeft + 'px',
|
100 | 204 | 'top': newTop + 'px'
|
101 | 205 | });
|
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 |
| - }*/ |
111 | 206 | }
|
112 | 207 | }
|
113 | 208 | , onTooltipHide = function onTooltipHide() {
|
114 | 209 |
|
115 | 210 | element.removeClass('active');
|
116 | 211 | }
|
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 |
| - } |
128 | 212 | , onTooltipTemplateChange = function onTooltipTemplateChange(newValue, oldValue) {
|
129 | 213 |
|
130 | 214 | if (newValue) {
|
|
142 | 226 |
|
143 | 227 | if (oldValue) {
|
144 | 228 |
|
145 |
| - element.removeAttr(oldValue); |
| 229 | + element.removeAttr('_' + oldValue); |
146 | 230 | }
|
147 |
| - element.addClass(newValue); |
| 231 | + element.addClass('_' + newValue); |
148 | 232 | scope.tooltipCtrl.tooltipSide = newValue;
|
149 | 233 | }
|
150 | 234 | }
|
|
170 | 254 | element.on(newValue, onTooltipHide);
|
171 | 255 | }
|
172 | 256 | }
|
173 |
| - , unregisterOnTooltipTitleChangeObserver = attrs.$observe('tooltipTitle', onTooltipTitleChange) |
174 | 257 | , unregisterOnTooltipTemplateChange = attrs.$observe('tooltipTemplate', onTooltipTemplateChange)
|
175 | 258 | , unregisterOnTooltipSideChangeObserver = attrs.$observe('tooltipSide', onTooltipSideChange)
|
176 | 259 | , unregisterOnTooltipShowTrigger = attrs.$observe('tooltipShowTrigger', onTooltipShowTrigger)
|
177 | 260 | , unregisterOnTooltipHideTrigger = attrs.$observe('tooltipHideTrigger', onTooltipHideTrigger);
|
178 | 261 |
|
| 262 | + resizeObserver.add(function registerResize() { |
| 263 | + |
| 264 | + onTooltipShow(undefined); |
| 265 | + }); |
179 | 266 | scope.$on('$destroy', function unregisterListeners() {
|
180 | 267 |
|
181 |
| - unregisterOnTooltipTitleChangeObserver(); |
182 | 268 | unregisterOnTooltipTemplateChange();
|
183 | 269 | unregisterOnTooltipSideChangeObserver();
|
184 | 270 | unregisterOnTooltipShowTrigger();
|
|
192 | 278 |
|
193 | 279 | angular.module('720kb.tooltips', [])
|
194 | 280 | .directive(directiveName, tooltipDirective);
|
195 |
| -}(angular, document)); |
| 281 | +}(angular, window)); |
0 commit comments