tether.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /*! tether 0.6.5 */
  2. (function(root, factory) {
  3. if (typeof define === 'function' && define.amd) {
  4. define(factory);
  5. } else if (typeof exports === 'object') {
  6. module.exports = factory(require,exports,module);
  7. } else {
  8. root.Tether = factory();
  9. }
  10. }(this, function(require,exports,module) {
  11. (function() {
  12. var Evented, addClass, defer, deferred, extend, flush, getBounds, getOffsetParent, getOrigin, getScrollBarSize, getScrollParent, hasClass, node, removeClass, uniqueId, updateClasses, zeroPosCache,
  13. __hasProp = {}.hasOwnProperty,
  14. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
  15. __slice = [].slice;
  16. if (this.Tether == null) {
  17. this.Tether = {
  18. modules: []
  19. };
  20. }
  21. getScrollParent = function(el) {
  22. var parent, position, scrollParent, style, _ref;
  23. position = getComputedStyle(el).position;
  24. if (position === 'fixed') {
  25. return el;
  26. }
  27. scrollParent = void 0;
  28. parent = el;
  29. while (parent = parent.parentNode) {
  30. try {
  31. style = getComputedStyle(parent);
  32. } catch (_error) {}
  33. if (style == null) {
  34. return parent;
  35. }
  36. if (/(auto|scroll)/.test(style['overflow'] + style['overflow-y'] + style['overflow-x'])) {
  37. if (position !== 'absolute' || ((_ref = style['position']) === 'relative' || _ref === 'absolute' || _ref === 'fixed')) {
  38. return parent;
  39. }
  40. }
  41. }
  42. return document.body;
  43. };
  44. uniqueId = (function() {
  45. var id;
  46. id = 0;
  47. return function() {
  48. return id++;
  49. };
  50. })();
  51. zeroPosCache = {};
  52. getOrigin = function(doc) {
  53. var id, k, node, v, _ref;
  54. node = doc._tetherZeroElement;
  55. if (node == null) {
  56. node = doc.createElement('div');
  57. node.setAttribute('data-tether-id', uniqueId());
  58. extend(node.style, {
  59. top: 0,
  60. left: 0,
  61. position: 'absolute'
  62. });
  63. doc.body.appendChild(node);
  64. doc._tetherZeroElement = node;
  65. }
  66. id = node.getAttribute('data-tether-id');
  67. if (zeroPosCache[id] == null) {
  68. zeroPosCache[id] = {};
  69. _ref = node.getBoundingClientRect();
  70. for (k in _ref) {
  71. v = _ref[k];
  72. zeroPosCache[id][k] = v;
  73. }
  74. defer(function() {
  75. return zeroPosCache[id] = void 0;
  76. });
  77. }
  78. return zeroPosCache[id];
  79. };
  80. node = null;
  81. getBounds = function(el) {
  82. var box, doc, docEl, k, origin, v, _ref;
  83. if (el === document) {
  84. doc = document;
  85. el = document.documentElement;
  86. } else {
  87. doc = el.ownerDocument;
  88. }
  89. docEl = doc.documentElement;
  90. box = {};
  91. _ref = el.getBoundingClientRect();
  92. for (k in _ref) {
  93. v = _ref[k];
  94. box[k] = v;
  95. }
  96. origin = getOrigin(doc);
  97. box.top -= origin.top;
  98. box.left -= origin.left;
  99. if (box.width == null) {
  100. box.width = document.body.scrollWidth - box.left - box.right;
  101. }
  102. if (box.height == null) {
  103. box.height = document.body.scrollHeight - box.top - box.bottom;
  104. }
  105. box.top = box.top - docEl.clientTop;
  106. box.left = box.left - docEl.clientLeft;
  107. box.right = doc.body.clientWidth - box.width - box.left;
  108. box.bottom = doc.body.clientHeight - box.height - box.top;
  109. return box;
  110. };
  111. getOffsetParent = function(el) {
  112. return el.offsetParent || document.documentElement;
  113. };
  114. getScrollBarSize = function() {
  115. var inner, outer, width, widthContained, widthScroll;
  116. inner = document.createElement('div');
  117. inner.style.width = '100%';
  118. inner.style.height = '200px';
  119. outer = document.createElement('div');
  120. extend(outer.style, {
  121. position: 'absolute',
  122. top: 0,
  123. left: 0,
  124. pointerEvents: 'none',
  125. visibility: 'hidden',
  126. width: '200px',
  127. height: '150px',
  128. overflow: 'hidden'
  129. });
  130. outer.appendChild(inner);
  131. document.body.appendChild(outer);
  132. widthContained = inner.offsetWidth;
  133. outer.style.overflow = 'scroll';
  134. widthScroll = inner.offsetWidth;
  135. if (widthContained === widthScroll) {
  136. widthScroll = outer.clientWidth;
  137. }
  138. document.body.removeChild(outer);
  139. width = widthContained - widthScroll;
  140. return {
  141. width: width,
  142. height: width
  143. };
  144. };
  145. extend = function(out) {
  146. var args, key, obj, val, _i, _len, _ref;
  147. if (out == null) {
  148. out = {};
  149. }
  150. args = [];
  151. Array.prototype.push.apply(args, arguments);
  152. _ref = args.slice(1);
  153. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  154. obj = _ref[_i];
  155. if (obj) {
  156. for (key in obj) {
  157. if (!__hasProp.call(obj, key)) continue;
  158. val = obj[key];
  159. out[key] = val;
  160. }
  161. }
  162. }
  163. return out;
  164. };
  165. removeClass = function(el, name) {
  166. var cls, _i, _len, _ref, _results;
  167. if (el.classList != null) {
  168. _ref = name.split(' ');
  169. _results = [];
  170. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  171. cls = _ref[_i];
  172. if (cls.trim()) {
  173. _results.push(el.classList.remove(cls));
  174. }
  175. }
  176. return _results;
  177. } else {
  178. return el.className = el.className.replace(new RegExp("(^| )" + (name.split(' ').join('|')) + "( |$)", 'gi'), ' ');
  179. }
  180. };
  181. addClass = function(el, name) {
  182. var cls, _i, _len, _ref, _results;
  183. if (el.classList != null) {
  184. _ref = name.split(' ');
  185. _results = [];
  186. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  187. cls = _ref[_i];
  188. if (cls.trim()) {
  189. _results.push(el.classList.add(cls));
  190. }
  191. }
  192. return _results;
  193. } else {
  194. removeClass(el, name);
  195. return el.className += " " + name;
  196. }
  197. };
  198. hasClass = function(el, name) {
  199. if (el.classList != null) {
  200. return el.classList.contains(name);
  201. } else {
  202. return new RegExp("(^| )" + name + "( |$)", 'gi').test(el.className);
  203. }
  204. };
  205. updateClasses = function(el, add, all) {
  206. var cls, _i, _j, _len, _len1, _results;
  207. for (_i = 0, _len = all.length; _i < _len; _i++) {
  208. cls = all[_i];
  209. if (__indexOf.call(add, cls) < 0) {
  210. if (hasClass(el, cls)) {
  211. removeClass(el, cls);
  212. }
  213. }
  214. }
  215. _results = [];
  216. for (_j = 0, _len1 = add.length; _j < _len1; _j++) {
  217. cls = add[_j];
  218. if (!hasClass(el, cls)) {
  219. _results.push(addClass(el, cls));
  220. } else {
  221. _results.push(void 0);
  222. }
  223. }
  224. return _results;
  225. };
  226. deferred = [];
  227. defer = function(fn) {
  228. return deferred.push(fn);
  229. };
  230. flush = function() {
  231. var fn, _results;
  232. _results = [];
  233. while (fn = deferred.pop()) {
  234. _results.push(fn());
  235. }
  236. return _results;
  237. };
  238. Evented = (function() {
  239. function Evented() {}
  240. Evented.prototype.on = function(event, handler, ctx, once) {
  241. var _base;
  242. if (once == null) {
  243. once = false;
  244. }
  245. if (this.bindings == null) {
  246. this.bindings = {};
  247. }
  248. if ((_base = this.bindings)[event] == null) {
  249. _base[event] = [];
  250. }
  251. return this.bindings[event].push({
  252. handler: handler,
  253. ctx: ctx,
  254. once: once
  255. });
  256. };
  257. Evented.prototype.once = function(event, handler, ctx) {
  258. return this.on(event, handler, ctx, true);
  259. };
  260. Evented.prototype.off = function(event, handler) {
  261. var i, _ref, _results;
  262. if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) {
  263. return;
  264. }
  265. if (handler == null) {
  266. return delete this.bindings[event];
  267. } else {
  268. i = 0;
  269. _results = [];
  270. while (i < this.bindings[event].length) {
  271. if (this.bindings[event][i].handler === handler) {
  272. _results.push(this.bindings[event].splice(i, 1));
  273. } else {
  274. _results.push(i++);
  275. }
  276. }
  277. return _results;
  278. }
  279. };
  280. Evented.prototype.trigger = function() {
  281. var args, ctx, event, handler, i, once, _ref, _ref1, _results;
  282. event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  283. if ((_ref = this.bindings) != null ? _ref[event] : void 0) {
  284. i = 0;
  285. _results = [];
  286. while (i < this.bindings[event].length) {
  287. _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once;
  288. handler.apply(ctx != null ? ctx : this, args);
  289. if (once) {
  290. _results.push(this.bindings[event].splice(i, 1));
  291. } else {
  292. _results.push(i++);
  293. }
  294. }
  295. return _results;
  296. }
  297. };
  298. return Evented;
  299. })();
  300. this.Tether.Utils = {
  301. getScrollParent: getScrollParent,
  302. getBounds: getBounds,
  303. getOffsetParent: getOffsetParent,
  304. extend: extend,
  305. addClass: addClass,
  306. removeClass: removeClass,
  307. hasClass: hasClass,
  308. updateClasses: updateClasses,
  309. defer: defer,
  310. flush: flush,
  311. uniqueId: uniqueId,
  312. Evented: Evented,
  313. getScrollBarSize: getScrollBarSize
  314. };
  315. }).call(this);
  316. (function() {
  317. var MIRROR_LR, MIRROR_TB, OFFSET_MAP, Tether, addClass, addOffset, attachmentToOffset, autoToFixedAttachment, defer, extend, flush, getBounds, getOffsetParent, getOuterSize, getScrollBarSize, getScrollParent, getSize, now, offsetToPx, parseAttachment, parseOffset, position, removeClass, tethers, transformKey, updateClasses, within, _Tether, _ref,
  318. __slice = [].slice,
  319. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
  320. if (this.Tether == null) {
  321. throw new Error("You must include the utils.js file before tether.js");
  322. }
  323. Tether = this.Tether;
  324. _ref = Tether.Utils, getScrollParent = _ref.getScrollParent, getSize = _ref.getSize, getOuterSize = _ref.getOuterSize, getBounds = _ref.getBounds, getOffsetParent = _ref.getOffsetParent, extend = _ref.extend, addClass = _ref.addClass, removeClass = _ref.removeClass, updateClasses = _ref.updateClasses, defer = _ref.defer, flush = _ref.flush, getScrollBarSize = _ref.getScrollBarSize;
  325. within = function(a, b, diff) {
  326. if (diff == null) {
  327. diff = 1;
  328. }
  329. return (a + diff >= b && b >= a - diff);
  330. };
  331. transformKey = (function() {
  332. var el, key, _i, _len, _ref1;
  333. el = document.createElement('div');
  334. _ref1 = ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform'];
  335. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  336. key = _ref1[_i];
  337. if (el.style[key] !== void 0) {
  338. return key;
  339. }
  340. }
  341. })();
  342. tethers = [];
  343. position = function() {
  344. var tether, _i, _len;
  345. for (_i = 0, _len = tethers.length; _i < _len; _i++) {
  346. tether = tethers[_i];
  347. tether.position(false);
  348. }
  349. return flush();
  350. };
  351. now = function() {
  352. var _ref1;
  353. return (_ref1 = typeof performance !== "undefined" && performance !== null ? typeof performance.now === "function" ? performance.now() : void 0 : void 0) != null ? _ref1 : +(new Date);
  354. };
  355. (function() {
  356. var event, lastCall, lastDuration, pendingTimeout, tick, _i, _len, _ref1, _results;
  357. lastCall = null;
  358. lastDuration = null;
  359. pendingTimeout = null;
  360. tick = function() {
  361. if ((lastDuration != null) && lastDuration > 16) {
  362. lastDuration = Math.min(lastDuration - 16, 250);
  363. pendingTimeout = setTimeout(tick, 250);
  364. return;
  365. }
  366. if ((lastCall != null) && (now() - lastCall) < 10) {
  367. return;
  368. }
  369. if (pendingTimeout != null) {
  370. clearTimeout(pendingTimeout);
  371. pendingTimeout = null;
  372. }
  373. lastCall = now();
  374. position();
  375. return lastDuration = now() - lastCall;
  376. };
  377. _ref1 = ['resize', 'scroll', 'touchmove'];
  378. _results = [];
  379. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  380. event = _ref1[_i];
  381. _results.push(window.addEventListener(event, tick));
  382. }
  383. return _results;
  384. })();
  385. MIRROR_LR = {
  386. center: 'center',
  387. left: 'right',
  388. right: 'left'
  389. };
  390. MIRROR_TB = {
  391. middle: 'middle',
  392. top: 'bottom',
  393. bottom: 'top'
  394. };
  395. OFFSET_MAP = {
  396. top: 0,
  397. left: 0,
  398. middle: '50%',
  399. center: '50%',
  400. bottom: '100%',
  401. right: '100%'
  402. };
  403. autoToFixedAttachment = function(attachment, relativeToAttachment) {
  404. var left, top;
  405. left = attachment.left, top = attachment.top;
  406. if (left === 'auto') {
  407. left = MIRROR_LR[relativeToAttachment.left];
  408. }
  409. if (top === 'auto') {
  410. top = MIRROR_TB[relativeToAttachment.top];
  411. }
  412. return {
  413. left: left,
  414. top: top
  415. };
  416. };
  417. attachmentToOffset = function(attachment) {
  418. var _ref1, _ref2;
  419. return {
  420. left: (_ref1 = OFFSET_MAP[attachment.left]) != null ? _ref1 : attachment.left,
  421. top: (_ref2 = OFFSET_MAP[attachment.top]) != null ? _ref2 : attachment.top
  422. };
  423. };
  424. addOffset = function() {
  425. var left, offsets, out, top, _i, _len, _ref1;
  426. offsets = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  427. out = {
  428. top: 0,
  429. left: 0
  430. };
  431. for (_i = 0, _len = offsets.length; _i < _len; _i++) {
  432. _ref1 = offsets[_i], top = _ref1.top, left = _ref1.left;
  433. if (typeof top === 'string') {
  434. top = parseFloat(top, 10);
  435. }
  436. if (typeof left === 'string') {
  437. left = parseFloat(left, 10);
  438. }
  439. out.top += top;
  440. out.left += left;
  441. }
  442. return out;
  443. };
  444. offsetToPx = function(offset, size) {
  445. if (typeof offset.left === 'string' && offset.left.indexOf('%') !== -1) {
  446. offset.left = parseFloat(offset.left, 10) / 100 * size.width;
  447. }
  448. if (typeof offset.top === 'string' && offset.top.indexOf('%') !== -1) {
  449. offset.top = parseFloat(offset.top, 10) / 100 * size.height;
  450. }
  451. return offset;
  452. };
  453. parseAttachment = parseOffset = function(value) {
  454. var left, top, _ref1;
  455. _ref1 = value.split(' '), top = _ref1[0], left = _ref1[1];
  456. return {
  457. top: top,
  458. left: left
  459. };
  460. };
  461. _Tether = (function() {
  462. _Tether.modules = [];
  463. function _Tether(options) {
  464. this.position = __bind(this.position, this);
  465. var module, _i, _len, _ref1, _ref2;
  466. tethers.push(this);
  467. this.history = [];
  468. this.setOptions(options, false);
  469. _ref1 = Tether.modules;
  470. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  471. module = _ref1[_i];
  472. if ((_ref2 = module.initialize) != null) {
  473. _ref2.call(this);
  474. }
  475. }
  476. this.position();
  477. }
  478. _Tether.prototype.getClass = function(key) {
  479. var _ref1, _ref2;
  480. if ((_ref1 = this.options.classes) != null ? _ref1[key] : void 0) {
  481. return this.options.classes[key];
  482. } else if (((_ref2 = this.options.classes) != null ? _ref2[key] : void 0) !== false) {
  483. if (this.options.classPrefix) {
  484. return "" + this.options.classPrefix + "-" + key;
  485. } else {
  486. return key;
  487. }
  488. } else {
  489. return '';
  490. }
  491. };
  492. _Tether.prototype.setOptions = function(options, position) {
  493. var defaults, key, _i, _len, _ref1, _ref2;
  494. this.options = options;
  495. if (position == null) {
  496. position = true;
  497. }
  498. defaults = {
  499. offset: '0 0',
  500. targetOffset: '0 0',
  501. targetAttachment: 'auto auto',
  502. classPrefix: 'tether'
  503. };
  504. this.options = extend(defaults, this.options);
  505. _ref1 = this.options, this.element = _ref1.element, this.target = _ref1.target, this.targetModifier = _ref1.targetModifier;
  506. if (this.target === 'viewport') {
  507. this.target = document.body;
  508. this.targetModifier = 'visible';
  509. } else if (this.target === 'scroll-handle') {
  510. this.target = document.body;
  511. this.targetModifier = 'scroll-handle';
  512. }
  513. _ref2 = ['element', 'target'];
  514. for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  515. key = _ref2[_i];
  516. if (this[key] == null) {
  517. throw new Error("Tether Error: Both element and target must be defined");
  518. }
  519. if (this[key].jquery != null) {
  520. this[key] = this[key][0];
  521. } else if (typeof this[key] === 'string') {
  522. this[key] = document.querySelector(this[key]);
  523. }
  524. }
  525. addClass(this.element, this.getClass('element'));
  526. addClass(this.target, this.getClass('target'));
  527. if (!this.options.attachment) {
  528. throw new Error("Tether Error: You must provide an attachment");
  529. }
  530. this.targetAttachment = parseAttachment(this.options.targetAttachment);
  531. this.attachment = parseAttachment(this.options.attachment);
  532. this.offset = parseOffset(this.options.offset);
  533. this.targetOffset = parseOffset(this.options.targetOffset);
  534. if (this.scrollParent != null) {
  535. this.disable();
  536. }
  537. if (this.targetModifier === 'scroll-handle') {
  538. this.scrollParent = this.target;
  539. } else {
  540. this.scrollParent = getScrollParent(this.target);
  541. }
  542. if (this.options.enabled !== false) {
  543. return this.enable(position);
  544. }
  545. };
  546. _Tether.prototype.getTargetBounds = function() {
  547. var bounds, fitAdj, hasBottomScroll, height, out, scrollBottom, scrollPercentage, style, target;
  548. if (this.targetModifier != null) {
  549. switch (this.targetModifier) {
  550. case 'visible':
  551. if (this.target === document.body) {
  552. return {
  553. top: pageYOffset,
  554. left: pageXOffset,
  555. height: innerHeight,
  556. width: innerWidth
  557. };
  558. } else {
  559. bounds = getBounds(this.target);
  560. out = {
  561. height: bounds.height,
  562. width: bounds.width,
  563. top: bounds.top,
  564. left: bounds.left
  565. };
  566. out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top));
  567. out.height = Math.min(out.height, bounds.height - ((bounds.top + bounds.height) - (pageYOffset + innerHeight)));
  568. out.height = Math.min(innerHeight, out.height);
  569. out.height -= 2;
  570. out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left));
  571. out.width = Math.min(out.width, bounds.width - ((bounds.left + bounds.width) - (pageXOffset + innerWidth)));
  572. out.width = Math.min(innerWidth, out.width);
  573. out.width -= 2;
  574. if (out.top < pageYOffset) {
  575. out.top = pageYOffset;
  576. }
  577. if (out.left < pageXOffset) {
  578. out.left = pageXOffset;
  579. }
  580. return out;
  581. }
  582. break;
  583. case 'scroll-handle':
  584. target = this.target;
  585. if (target === document.body) {
  586. target = document.documentElement;
  587. bounds = {
  588. left: pageXOffset,
  589. top: pageYOffset,
  590. height: innerHeight,
  591. width: innerWidth
  592. };
  593. } else {
  594. bounds = getBounds(target);
  595. }
  596. style = getComputedStyle(target);
  597. hasBottomScroll = target.scrollWidth > target.clientWidth || 'scroll' === [style.overflow, style.overflowX] || this.target !== document.body;
  598. scrollBottom = 0;
  599. if (hasBottomScroll) {
  600. scrollBottom = 15;
  601. }
  602. height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom;
  603. out = {
  604. width: 15,
  605. height: height * 0.975 * (height / target.scrollHeight),
  606. left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15
  607. };
  608. fitAdj = 0;
  609. if (height < 408 && this.target === document.body) {
  610. fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58;
  611. }
  612. if (this.target !== document.body) {
  613. out.height = Math.max(out.height, 24);
  614. }
  615. scrollPercentage = this.target.scrollTop / (target.scrollHeight - height);
  616. out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth);
  617. if (this.target === document.body) {
  618. out.height = Math.max(out.height, 24);
  619. }
  620. return out;
  621. }
  622. } else {
  623. return getBounds(this.target);
  624. }
  625. };
  626. _Tether.prototype.clearCache = function() {
  627. return this._cache = {};
  628. };
  629. _Tether.prototype.cache = function(k, getter) {
  630. if (this._cache == null) {
  631. this._cache = {};
  632. }
  633. if (this._cache[k] == null) {
  634. this._cache[k] = getter.call(this);
  635. }
  636. return this._cache[k];
  637. };
  638. _Tether.prototype.enable = function(position) {
  639. if (position == null) {
  640. position = true;
  641. }
  642. addClass(this.target, this.getClass('enabled'));
  643. addClass(this.element, this.getClass('enabled'));
  644. this.enabled = true;
  645. if (this.scrollParent !== document) {
  646. this.scrollParent.addEventListener('scroll', this.position);
  647. }
  648. if (position) {
  649. return this.position();
  650. }
  651. };
  652. _Tether.prototype.disable = function() {
  653. removeClass(this.target, this.getClass('enabled'));
  654. removeClass(this.element, this.getClass('enabled'));
  655. this.enabled = false;
  656. if (this.scrollParent != null) {
  657. return this.scrollParent.removeEventListener('scroll', this.position);
  658. }
  659. };
  660. _Tether.prototype.destroy = function() {
  661. var i, tether, _i, _len, _results;
  662. this.disable();
  663. _results = [];
  664. for (i = _i = 0, _len = tethers.length; _i < _len; i = ++_i) {
  665. tether = tethers[i];
  666. if (tether === this) {
  667. tethers.splice(i, 1);
  668. break;
  669. } else {
  670. _results.push(void 0);
  671. }
  672. }
  673. return _results;
  674. };
  675. _Tether.prototype.updateAttachClasses = function(elementAttach, targetAttach) {
  676. var add, all, side, sides, _i, _j, _len, _len1, _ref1,
  677. _this = this;
  678. if (elementAttach == null) {
  679. elementAttach = this.attachment;
  680. }
  681. if (targetAttach == null) {
  682. targetAttach = this.targetAttachment;
  683. }
  684. sides = ['left', 'top', 'bottom', 'right', 'middle', 'center'];
  685. if ((_ref1 = this._addAttachClasses) != null ? _ref1.length : void 0) {
  686. this._addAttachClasses.splice(0, this._addAttachClasses.length);
  687. }
  688. add = this._addAttachClasses != null ? this._addAttachClasses : this._addAttachClasses = [];
  689. if (elementAttach.top) {
  690. add.push("" + (this.getClass('element-attached')) + "-" + elementAttach.top);
  691. }
  692. if (elementAttach.left) {
  693. add.push("" + (this.getClass('element-attached')) + "-" + elementAttach.left);
  694. }
  695. if (targetAttach.top) {
  696. add.push("" + (this.getClass('target-attached')) + "-" + targetAttach.top);
  697. }
  698. if (targetAttach.left) {
  699. add.push("" + (this.getClass('target-attached')) + "-" + targetAttach.left);
  700. }
  701. all = [];
  702. for (_i = 0, _len = sides.length; _i < _len; _i++) {
  703. side = sides[_i];
  704. all.push("" + (this.getClass('element-attached')) + "-" + side);
  705. }
  706. for (_j = 0, _len1 = sides.length; _j < _len1; _j++) {
  707. side = sides[_j];
  708. all.push("" + (this.getClass('target-attached')) + "-" + side);
  709. }
  710. return defer(function() {
  711. if (_this._addAttachClasses == null) {
  712. return;
  713. }
  714. updateClasses(_this.element, _this._addAttachClasses, all);
  715. updateClasses(_this.target, _this._addAttachClasses, all);
  716. return _this._addAttachClasses = void 0;
  717. });
  718. };
  719. _Tether.prototype.position = function(flushChanges) {
  720. var elementPos, elementStyle, height, left, manualOffset, manualTargetOffset, module, next, offset, offsetBorder, offsetParent, offsetParentSize, offsetParentStyle, offsetPosition, ret, scrollLeft, scrollTop, scrollbarSize, side, targetAttachment, targetOffset, targetPos, targetSize, top, width, _i, _j, _len, _len1, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6,
  721. _this = this;
  722. if (flushChanges == null) {
  723. flushChanges = true;
  724. }
  725. if (!this.enabled) {
  726. return;
  727. }
  728. this.clearCache();
  729. targetAttachment = autoToFixedAttachment(this.targetAttachment, this.attachment);
  730. this.updateAttachClasses(this.attachment, targetAttachment);
  731. elementPos = this.cache('element-bounds', function() {
  732. return getBounds(_this.element);
  733. });
  734. width = elementPos.width, height = elementPos.height;
  735. if (width === 0 && height === 0 && (this.lastSize != null)) {
  736. _ref1 = this.lastSize, width = _ref1.width, height = _ref1.height;
  737. } else {
  738. this.lastSize = {
  739. width: width,
  740. height: height
  741. };
  742. }
  743. targetSize = targetPos = this.cache('target-bounds', function() {
  744. return _this.getTargetBounds();
  745. });
  746. offset = offsetToPx(attachmentToOffset(this.attachment), {
  747. width: width,
  748. height: height
  749. });
  750. targetOffset = offsetToPx(attachmentToOffset(targetAttachment), targetSize);
  751. manualOffset = offsetToPx(this.offset, {
  752. width: width,
  753. height: height
  754. });
  755. manualTargetOffset = offsetToPx(this.targetOffset, targetSize);
  756. offset = addOffset(offset, manualOffset);
  757. targetOffset = addOffset(targetOffset, manualTargetOffset);
  758. left = targetPos.left + targetOffset.left - offset.left;
  759. top = targetPos.top + targetOffset.top - offset.top;
  760. _ref2 = Tether.modules;
  761. for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  762. module = _ref2[_i];
  763. ret = module.position.call(this, {
  764. left: left,
  765. top: top,
  766. targetAttachment: targetAttachment,
  767. targetPos: targetPos,
  768. attachment: this.attachment,
  769. elementPos: elementPos,
  770. offset: offset,
  771. targetOffset: targetOffset,
  772. manualOffset: manualOffset,
  773. manualTargetOffset: manualTargetOffset,
  774. scrollbarSize: scrollbarSize
  775. });
  776. if ((ret == null) || typeof ret !== 'object') {
  777. continue;
  778. } else if (ret === false) {
  779. return false;
  780. } else {
  781. top = ret.top, left = ret.left;
  782. }
  783. }
  784. next = {
  785. page: {
  786. top: top,
  787. left: left
  788. },
  789. viewport: {
  790. top: top - pageYOffset,
  791. bottom: pageYOffset - top - height + innerHeight,
  792. left: left - pageXOffset,
  793. right: pageXOffset - left - width + innerWidth
  794. }
  795. };
  796. if (document.body.scrollWidth > window.innerWidth) {
  797. scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
  798. next.viewport.bottom -= scrollbarSize.height;
  799. }
  800. if (document.body.scrollHeight > window.innerHeight) {
  801. scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
  802. next.viewport.right -= scrollbarSize.width;
  803. }
  804. if (((_ref3 = document.body.style.position) !== '' && _ref3 !== 'static') || ((_ref4 = document.body.parentElement.style.position) !== '' && _ref4 !== 'static')) {
  805. next.page.bottom = document.body.scrollHeight - top - height;
  806. next.page.right = document.body.scrollWidth - left - width;
  807. }
  808. if (((_ref5 = this.options.optimizations) != null ? _ref5.moveElement : void 0) !== false && (this.targetModifier == null)) {
  809. offsetParent = this.cache('target-offsetparent', function() {
  810. return getOffsetParent(_this.target);
  811. });
  812. offsetPosition = this.cache('target-offsetparent-bounds', function() {
  813. return getBounds(offsetParent);
  814. });
  815. offsetParentStyle = getComputedStyle(offsetParent);
  816. elementStyle = getComputedStyle(this.element);
  817. offsetParentSize = offsetPosition;
  818. offsetBorder = {};
  819. _ref6 = ['Top', 'Left', 'Bottom', 'Right'];
  820. for (_j = 0, _len1 = _ref6.length; _j < _len1; _j++) {
  821. side = _ref6[_j];
  822. offsetBorder[side.toLowerCase()] = parseFloat(offsetParentStyle["border" + side + "Width"]);
  823. }
  824. offsetPosition.right = document.body.scrollWidth - offsetPosition.left - offsetParentSize.width + offsetBorder.right;
  825. offsetPosition.bottom = document.body.scrollHeight - offsetPosition.top - offsetParentSize.height + offsetBorder.bottom;
  826. if (next.page.top >= (offsetPosition.top + offsetBorder.top) && next.page.bottom >= offsetPosition.bottom) {
  827. if (next.page.left >= (offsetPosition.left + offsetBorder.left) && next.page.right >= offsetPosition.right) {
  828. scrollTop = offsetParent.scrollTop;
  829. scrollLeft = offsetParent.scrollLeft;
  830. next.offset = {
  831. top: next.page.top - offsetPosition.top + scrollTop - offsetBorder.top,
  832. left: next.page.left - offsetPosition.left + scrollLeft - offsetBorder.left
  833. };
  834. }
  835. }
  836. }
  837. this.move(next);
  838. this.history.unshift(next);
  839. if (this.history.length > 3) {
  840. this.history.pop();
  841. }
  842. if (flushChanges) {
  843. flush();
  844. }
  845. return true;
  846. };
  847. _Tether.prototype.move = function(position) {
  848. var css, elVal, found, key, moved, offsetParent, point, same, transcribe, type, val, write, writeCSS, _i, _len, _ref1, _ref2,
  849. _this = this;
  850. if (this.element.parentNode == null) {
  851. return;
  852. }
  853. same = {};
  854. for (type in position) {
  855. same[type] = {};
  856. for (key in position[type]) {
  857. found = false;
  858. _ref1 = this.history;
  859. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  860. point = _ref1[_i];
  861. if (!within((_ref2 = point[type]) != null ? _ref2[key] : void 0, position[type][key])) {
  862. found = true;
  863. break;
  864. }
  865. }
  866. if (!found) {
  867. same[type][key] = true;
  868. }
  869. }
  870. }
  871. css = {
  872. top: '',
  873. left: '',
  874. right: '',
  875. bottom: ''
  876. };
  877. transcribe = function(same, pos) {
  878. var xPos, yPos, _ref3;
  879. if (((_ref3 = _this.options.optimizations) != null ? _ref3.gpu : void 0) !== false) {
  880. if (same.top) {
  881. css.top = 0;
  882. yPos = pos.top;
  883. } else {
  884. css.bottom = 0;
  885. yPos = -pos.bottom;
  886. }
  887. if (same.left) {
  888. css.left = 0;
  889. xPos = pos.left;
  890. } else {
  891. css.right = 0;
  892. xPos = -pos.right;
  893. }
  894. css[transformKey] = "translateX(" + (Math.round(xPos)) + "px) translateY(" + (Math.round(yPos)) + "px)";
  895. if (transformKey !== 'msTransform') {
  896. return css[transformKey] += " translateZ(0)";
  897. }
  898. } else {
  899. if (same.top) {
  900. css.top = "" + pos.top + "px";
  901. } else {
  902. css.bottom = "" + pos.bottom + "px";
  903. }
  904. if (same.left) {
  905. return css.left = "" + pos.left + "px";
  906. } else {
  907. return css.right = "" + pos.right + "px";
  908. }
  909. }
  910. };
  911. moved = false;
  912. if ((same.page.top || same.page.bottom) && (same.page.left || same.page.right)) {
  913. css.position = 'absolute';
  914. transcribe(same.page, position.page);
  915. } else if ((same.viewport.top || same.viewport.bottom) && (same.viewport.left || same.viewport.right)) {
  916. css.position = 'fixed';
  917. transcribe(same.viewport, position.viewport);
  918. } else if ((same.offset != null) && same.offset.top && same.offset.left) {
  919. css.position = 'absolute';
  920. offsetParent = this.cache('target-offsetparent', function() {
  921. return getOffsetParent(_this.target);
  922. });
  923. if (getOffsetParent(this.element) !== offsetParent) {
  924. defer(function() {
  925. _this.element.parentNode.removeChild(_this.element);
  926. return offsetParent.appendChild(_this.element);
  927. });
  928. }
  929. transcribe(same.offset, position.offset);
  930. moved = true;
  931. } else {
  932. css.position = 'absolute';
  933. transcribe({
  934. top: true,
  935. left: true
  936. }, position.page);
  937. }
  938. if (!moved && this.element.parentNode.tagName !== 'BODY') {
  939. this.element.parentNode.removeChild(this.element);
  940. document.body.appendChild(this.element);
  941. }
  942. writeCSS = {};
  943. write = false;
  944. for (key in css) {
  945. val = css[key];
  946. elVal = this.element.style[key];
  947. if (elVal !== '' && val !== '' && (key === 'top' || key === 'left' || key === 'bottom' || key === 'right')) {
  948. elVal = parseFloat(elVal);
  949. val = parseFloat(val);
  950. }
  951. if (elVal !== val) {
  952. write = true;
  953. writeCSS[key] = css[key];
  954. }
  955. }
  956. if (write) {
  957. return defer(function() {
  958. return extend(_this.element.style, writeCSS);
  959. });
  960. }
  961. };
  962. return _Tether;
  963. })();
  964. Tether.position = position;
  965. this.Tether = extend(_Tether, Tether);
  966. }).call(this);
  967. (function() {
  968. var BOUNDS_FORMAT, MIRROR_ATTACH, defer, extend, getBoundingRect, getBounds, getOuterSize, getSize, updateClasses, _ref,
  969. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  970. _ref = this.Tether.Utils, getOuterSize = _ref.getOuterSize, getBounds = _ref.getBounds, getSize = _ref.getSize, extend = _ref.extend, updateClasses = _ref.updateClasses, defer = _ref.defer;
  971. MIRROR_ATTACH = {
  972. left: 'right',
  973. right: 'left',
  974. top: 'bottom',
  975. bottom: 'top',
  976. middle: 'middle'
  977. };
  978. BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom'];
  979. getBoundingRect = function(tether, to) {
  980. var i, pos, side, size, style, _i, _len;
  981. if (to === 'scrollParent') {
  982. to = tether.scrollParent;
  983. } else if (to === 'window') {
  984. to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset];
  985. }
  986. if (to === document) {
  987. to = to.documentElement;
  988. }
  989. if (to.nodeType != null) {
  990. pos = size = getBounds(to);
  991. style = getComputedStyle(to);
  992. to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top];
  993. for (i = _i = 0, _len = BOUNDS_FORMAT.length; _i < _len; i = ++_i) {
  994. side = BOUNDS_FORMAT[i];
  995. side = side[0].toUpperCase() + side.substr(1);
  996. if (side === 'Top' || side === 'Left') {
  997. to[i] += parseFloat(style["border" + side + "Width"]);
  998. } else {
  999. to[i] -= parseFloat(style["border" + side + "Width"]);
  1000. }
  1001. }
  1002. }
  1003. return to;
  1004. };
  1005. this.Tether.modules.push({
  1006. position: function(_arg) {
  1007. var addClasses, allClasses, attachment, bounds, changeAttachX, changeAttachY, cls, constraint, eAttachment, height, left, oob, oobClass, p, pin, pinned, pinnedClass, removeClass, side, tAttachment, targetAttachment, targetHeight, targetSize, targetWidth, to, top, width, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8,
  1008. _this = this;
  1009. top = _arg.top, left = _arg.left, targetAttachment = _arg.targetAttachment;
  1010. if (!this.options.constraints) {
  1011. return true;
  1012. }
  1013. removeClass = function(prefix) {
  1014. var side, _i, _len, _results;
  1015. _this.removeClass(prefix);
  1016. _results = [];
  1017. for (_i = 0, _len = BOUNDS_FORMAT.length; _i < _len; _i++) {
  1018. side = BOUNDS_FORMAT[_i];
  1019. _results.push(_this.removeClass("" + prefix + "-" + side));
  1020. }
  1021. return _results;
  1022. };
  1023. _ref1 = this.cache('element-bounds', function() {
  1024. return getBounds(_this.element);
  1025. }), height = _ref1.height, width = _ref1.width;
  1026. if (width === 0 && height === 0 && (this.lastSize != null)) {
  1027. _ref2 = this.lastSize, width = _ref2.width, height = _ref2.height;
  1028. }
  1029. targetSize = this.cache('target-bounds', function() {
  1030. return _this.getTargetBounds();
  1031. });
  1032. targetHeight = targetSize.height;
  1033. targetWidth = targetSize.width;
  1034. tAttachment = {};
  1035. eAttachment = {};
  1036. allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')];
  1037. _ref3 = this.options.constraints;
  1038. for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
  1039. constraint = _ref3[_i];
  1040. if (constraint.outOfBoundsClass) {
  1041. allClasses.push(constraint.outOfBoundsClass);
  1042. }
  1043. if (constraint.pinnedClass) {
  1044. allClasses.push(constraint.pinnedClass);
  1045. }
  1046. }
  1047. for (_j = 0, _len1 = allClasses.length; _j < _len1; _j++) {
  1048. cls = allClasses[_j];
  1049. _ref4 = ['left', 'top', 'right', 'bottom'];
  1050. for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
  1051. side = _ref4[_k];
  1052. allClasses.push("" + cls + "-" + side);
  1053. }
  1054. }
  1055. addClasses = [];
  1056. tAttachment = extend({}, targetAttachment);
  1057. eAttachment = extend({}, this.attachment);
  1058. _ref5 = this.options.constraints;
  1059. for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
  1060. constraint = _ref5[_l];
  1061. to = constraint.to, attachment = constraint.attachment, pin = constraint.pin;
  1062. if (attachment == null) {
  1063. attachment = '';
  1064. }
  1065. if (__indexOf.call(attachment, ' ') >= 0) {
  1066. _ref6 = attachment.split(' '), changeAttachY = _ref6[0], changeAttachX = _ref6[1];
  1067. } else {
  1068. changeAttachX = changeAttachY = attachment;
  1069. }
  1070. bounds = getBoundingRect(this, to);
  1071. if (changeAttachY === 'target' || changeAttachY === 'both') {
  1072. if (top < bounds[1] && tAttachment.top === 'top') {
  1073. top += targetHeight;
  1074. tAttachment.top = 'bottom';
  1075. }
  1076. if (top + height > bounds[3] && tAttachment.top === 'bottom') {
  1077. top -= targetHeight;
  1078. tAttachment.top = 'top';
  1079. }
  1080. }
  1081. if (changeAttachY === 'together') {
  1082. if (top < bounds[1] && tAttachment.top === 'top') {
  1083. if (eAttachment.top === 'bottom') {
  1084. top += targetHeight;
  1085. tAttachment.top = 'bottom';
  1086. top += height;
  1087. eAttachment.top = 'top';
  1088. } else if (eAttachment.top === 'top') {
  1089. top += targetHeight;
  1090. tAttachment.top = 'bottom';
  1091. top -= height;
  1092. eAttachment.top = 'bottom';
  1093. }
  1094. }
  1095. if (top + height > bounds[3] && tAttachment.top === 'bottom') {
  1096. if (eAttachment.top === 'top') {
  1097. top -= targetHeight;
  1098. tAttachment.top = 'top';
  1099. top -= height;
  1100. eAttachment.top = 'bottom';
  1101. } else if (eAttachment.top === 'bottom') {
  1102. top -= targetHeight;
  1103. tAttachment.top = 'top';
  1104. top += height;
  1105. eAttachment.top = 'top';
  1106. }
  1107. }
  1108. if (tAttachment.top === 'middle') {
  1109. if (top + height > bounds[3] && eAttachment.top === 'top') {
  1110. top -= height;
  1111. eAttachment.top = 'bottom';
  1112. } else if (top < bounds[1] && eAttachment.top === 'bottom') {
  1113. top += height;
  1114. eAttachment.top = 'top';
  1115. }
  1116. }
  1117. }
  1118. if (changeAttachX === 'target' || changeAttachX === 'both') {
  1119. if (left < bounds[0] && tAttachment.left === 'left') {
  1120. left += targetWidth;
  1121. tAttachment.left = 'right';
  1122. }
  1123. if (left + width > bounds[2] && tAttachment.left === 'right') {
  1124. left -= targetWidth;
  1125. tAttachment.left = 'left';
  1126. }
  1127. }
  1128. if (changeAttachX === 'together') {
  1129. if (left < bounds[0] && tAttachment.left === 'left') {
  1130. if (eAttachment.left === 'right') {
  1131. left += targetWidth;
  1132. tAttachment.left = 'right';
  1133. left += width;
  1134. eAttachment.left = 'left';
  1135. } else if (eAttachment.left === 'left') {
  1136. left += targetWidth;
  1137. tAttachment.left = 'right';
  1138. left -= width;
  1139. eAttachment.left = 'right';
  1140. }
  1141. } else if (left + width > bounds[2] && tAttachment.left === 'right') {
  1142. if (eAttachment.left === 'left') {
  1143. left -= targetWidth;
  1144. tAttachment.left = 'left';
  1145. left -= width;
  1146. eAttachment.left = 'right';
  1147. } else if (eAttachment.left === 'right') {
  1148. left -= targetWidth;
  1149. tAttachment.left = 'left';
  1150. left += width;
  1151. eAttachment.left = 'left';
  1152. }
  1153. } else if (tAttachment.left === 'center') {
  1154. if (left + width > bounds[2] && eAttachment.left === 'left') {
  1155. left -= width;
  1156. eAttachment.left = 'right';
  1157. } else if (left < bounds[0] && eAttachment.left === 'right') {
  1158. left += width;
  1159. eAttachment.left = 'left';
  1160. }
  1161. }
  1162. }
  1163. if (changeAttachY === 'element' || changeAttachY === 'both') {
  1164. if (top < bounds[1] && eAttachment.top === 'bottom') {
  1165. top += height;
  1166. eAttachment.top = 'top';
  1167. }
  1168. if (top + height > bounds[3] && eAttachment.top === 'top') {
  1169. top -= height;
  1170. eAttachment.top = 'bottom';
  1171. }
  1172. }
  1173. if (changeAttachX === 'element' || changeAttachX === 'both') {
  1174. if (left < bounds[0] && eAttachment.left === 'right') {
  1175. left += width;
  1176. eAttachment.left = 'left';
  1177. }
  1178. if (left + width > bounds[2] && eAttachment.left === 'left') {
  1179. left -= width;
  1180. eAttachment.left = 'right';
  1181. }
  1182. }
  1183. if (typeof pin === 'string') {
  1184. pin = (function() {
  1185. var _len4, _m, _ref7, _results;
  1186. _ref7 = pin.split(',');
  1187. _results = [];
  1188. for (_m = 0, _len4 = _ref7.length; _m < _len4; _m++) {
  1189. p = _ref7[_m];
  1190. _results.push(p.trim());
  1191. }
  1192. return _results;
  1193. })();
  1194. } else if (pin === true) {
  1195. pin = ['top', 'left', 'right', 'bottom'];
  1196. }
  1197. pin || (pin = []);
  1198. pinned = [];
  1199. oob = [];
  1200. if (top < bounds[1]) {
  1201. if (__indexOf.call(pin, 'top') >= 0) {
  1202. top = bounds[1];
  1203. pinned.push('top');
  1204. } else {
  1205. oob.push('top');
  1206. }
  1207. }
  1208. if (top + height > bounds[3]) {
  1209. if (__indexOf.call(pin, 'bottom') >= 0) {
  1210. top = bounds[3] - height;
  1211. pinned.push('bottom');
  1212. } else {
  1213. oob.push('bottom');
  1214. }
  1215. }
  1216. if (left < bounds[0]) {
  1217. if (__indexOf.call(pin, 'left') >= 0) {
  1218. left = bounds[0];
  1219. pinned.push('left');
  1220. } else {
  1221. oob.push('left');
  1222. }
  1223. }
  1224. if (left + width > bounds[2]) {
  1225. if (__indexOf.call(pin, 'right') >= 0) {
  1226. left = bounds[2] - width;
  1227. pinned.push('right');
  1228. } else {
  1229. oob.push('right');
  1230. }
  1231. }
  1232. if (pinned.length) {
  1233. pinnedClass = (_ref7 = this.options.pinnedClass) != null ? _ref7 : this.getClass('pinned');
  1234. addClasses.push(pinnedClass);
  1235. for (_m = 0, _len4 = pinned.length; _m < _len4; _m++) {
  1236. side = pinned[_m];
  1237. addClasses.push("" + pinnedClass + "-" + side);
  1238. }
  1239. }
  1240. if (oob.length) {
  1241. oobClass = (_ref8 = this.options.outOfBoundsClass) != null ? _ref8 : this.getClass('out-of-bounds');
  1242. addClasses.push(oobClass);
  1243. for (_n = 0, _len5 = oob.length; _n < _len5; _n++) {
  1244. side = oob[_n];
  1245. addClasses.push("" + oobClass + "-" + side);
  1246. }
  1247. }
  1248. if (__indexOf.call(pinned, 'left') >= 0 || __indexOf.call(pinned, 'right') >= 0) {
  1249. eAttachment.left = tAttachment.left = false;
  1250. }
  1251. if (__indexOf.call(pinned, 'top') >= 0 || __indexOf.call(pinned, 'bottom') >= 0) {
  1252. eAttachment.top = tAttachment.top = false;
  1253. }
  1254. if (tAttachment.top !== targetAttachment.top || tAttachment.left !== targetAttachment.left || eAttachment.top !== this.attachment.top || eAttachment.left !== this.attachment.left) {
  1255. this.updateAttachClasses(eAttachment, tAttachment);
  1256. }
  1257. }
  1258. defer(function() {
  1259. updateClasses(_this.target, addClasses, allClasses);
  1260. return updateClasses(_this.element, addClasses, allClasses);
  1261. });
  1262. return {
  1263. top: top,
  1264. left: left
  1265. };
  1266. }
  1267. });
  1268. }).call(this);
  1269. (function() {
  1270. var defer, getBounds, updateClasses, _ref;
  1271. _ref = this.Tether.Utils, getBounds = _ref.getBounds, updateClasses = _ref.updateClasses, defer = _ref.defer;
  1272. this.Tether.modules.push({
  1273. position: function(_arg) {
  1274. var abutted, addClasses, allClasses, bottom, height, left, right, side, sides, targetPos, top, width, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref1, _ref2, _ref3, _ref4, _ref5,
  1275. _this = this;
  1276. top = _arg.top, left = _arg.left;
  1277. _ref1 = this.cache('element-bounds', function() {
  1278. return getBounds(_this.element);
  1279. }), height = _ref1.height, width = _ref1.width;
  1280. targetPos = this.getTargetBounds();
  1281. bottom = top + height;
  1282. right = left + width;
  1283. abutted = [];
  1284. if (top <= targetPos.bottom && bottom >= targetPos.top) {
  1285. _ref2 = ['left', 'right'];
  1286. for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  1287. side = _ref2[_i];
  1288. if ((_ref3 = targetPos[side]) === left || _ref3 === right) {
  1289. abutted.push(side);
  1290. }
  1291. }
  1292. }
  1293. if (left <= targetPos.right && right >= targetPos.left) {
  1294. _ref4 = ['top', 'bottom'];
  1295. for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
  1296. side = _ref4[_j];
  1297. if ((_ref5 = targetPos[side]) === top || _ref5 === bottom) {
  1298. abutted.push(side);
  1299. }
  1300. }
  1301. }
  1302. allClasses = [];
  1303. addClasses = [];
  1304. sides = ['left', 'top', 'right', 'bottom'];
  1305. allClasses.push(this.getClass('abutted'));
  1306. for (_k = 0, _len2 = sides.length; _k < _len2; _k++) {
  1307. side = sides[_k];
  1308. allClasses.push("" + (this.getClass('abutted')) + "-" + side);
  1309. }
  1310. if (abutted.length) {
  1311. addClasses.push(this.getClass('abutted'));
  1312. }
  1313. for (_l = 0, _len3 = abutted.length; _l < _len3; _l++) {
  1314. side = abutted[_l];
  1315. addClasses.push("" + (this.getClass('abutted')) + "-" + side);
  1316. }
  1317. defer(function() {
  1318. updateClasses(_this.target, addClasses, allClasses);
  1319. return updateClasses(_this.element, addClasses, allClasses);
  1320. });
  1321. return true;
  1322. }
  1323. });
  1324. }).call(this);
  1325. (function() {
  1326. this.Tether.modules.push({
  1327. position: function(_arg) {
  1328. var left, result, shift, shiftLeft, shiftTop, top, _ref;
  1329. top = _arg.top, left = _arg.left;
  1330. if (!this.options.shift) {
  1331. return;
  1332. }
  1333. result = function(val) {
  1334. if (typeof val === 'function') {
  1335. return val.call(this, {
  1336. top: top,
  1337. left: left
  1338. });
  1339. } else {
  1340. return val;
  1341. }
  1342. };
  1343. shift = result(this.options.shift);
  1344. if (typeof shift === 'string') {
  1345. shift = shift.split(' ');
  1346. shift[1] || (shift[1] = shift[0]);
  1347. shiftTop = shift[0], shiftLeft = shift[1];
  1348. shiftTop = parseFloat(shiftTop, 10);
  1349. shiftLeft = parseFloat(shiftLeft, 10);
  1350. } else {
  1351. _ref = [shift.top, shift.left], shiftTop = _ref[0], shiftLeft = _ref[1];
  1352. }
  1353. top += shiftTop;
  1354. left += shiftLeft;
  1355. return {
  1356. top: top,
  1357. left: left
  1358. };
  1359. }
  1360. });
  1361. }).call(this);
  1362. return this.Tether;
  1363. }));