Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

index.js 37 KiB

há 3 anos
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vendorPrefix;
  4. var jsCssMap = {
  5. Webkit: '-webkit-',
  6. Moz: '-moz-',
  7. // IE did it wrong again ...
  8. ms: '-ms-',
  9. O: '-o-'
  10. };
  11. function getVendorPrefix() {
  12. if (vendorPrefix !== undefined) {
  13. return vendorPrefix;
  14. }
  15. vendorPrefix = '';
  16. var style = document.createElement('p').style;
  17. var testProp = 'Transform';
  18. for (var key in jsCssMap) {
  19. if (key + testProp in style) {
  20. vendorPrefix = key;
  21. }
  22. }
  23. return vendorPrefix;
  24. }
  25. function getTransitionName() {
  26. return getVendorPrefix() ? "".concat(getVendorPrefix(), "TransitionProperty") : 'transitionProperty';
  27. }
  28. function getTransformName() {
  29. return getVendorPrefix() ? "".concat(getVendorPrefix(), "Transform") : 'transform';
  30. }
  31. function setTransitionProperty(node, value) {
  32. var name = getTransitionName();
  33. if (name) {
  34. node.style[name] = value;
  35. if (name !== 'transitionProperty') {
  36. node.style.transitionProperty = value;
  37. }
  38. }
  39. }
  40. function setTransform(node, value) {
  41. var name = getTransformName();
  42. if (name) {
  43. node.style[name] = value;
  44. if (name !== 'transform') {
  45. node.style.transform = value;
  46. }
  47. }
  48. }
  49. function getTransitionProperty(node) {
  50. return node.style.transitionProperty || node.style[getTransitionName()];
  51. }
  52. function getTransformXY(node) {
  53. var style = window.getComputedStyle(node, null);
  54. var transform = style.getPropertyValue('transform') || style.getPropertyValue(getTransformName());
  55. if (transform && transform !== 'none') {
  56. var matrix = transform.replace(/[^0-9\-.,]/g, '').split(',');
  57. return {
  58. x: parseFloat(matrix[12] || matrix[4], 0),
  59. y: parseFloat(matrix[13] || matrix[5], 0)
  60. };
  61. }
  62. return {
  63. x: 0,
  64. y: 0
  65. };
  66. }
  67. var matrix2d = /matrix\((.*)\)/;
  68. var matrix3d = /matrix3d\((.*)\)/;
  69. function setTransformXY(node, xy) {
  70. var style = window.getComputedStyle(node, null);
  71. var transform = style.getPropertyValue('transform') || style.getPropertyValue(getTransformName());
  72. if (transform && transform !== 'none') {
  73. var arr;
  74. var match2d = transform.match(matrix2d);
  75. if (match2d) {
  76. match2d = match2d[1];
  77. arr = match2d.split(',').map(function (item) {
  78. return parseFloat(item, 10);
  79. });
  80. arr[4] = xy.x;
  81. arr[5] = xy.y;
  82. setTransform(node, "matrix(".concat(arr.join(','), ")"));
  83. } else {
  84. var match3d = transform.match(matrix3d)[1];
  85. arr = match3d.split(',').map(function (item) {
  86. return parseFloat(item, 10);
  87. });
  88. arr[12] = xy.x;
  89. arr[13] = xy.y;
  90. setTransform(node, "matrix3d(".concat(arr.join(','), ")"));
  91. }
  92. } else {
  93. setTransform(node, "translateX(".concat(xy.x, "px) translateY(").concat(xy.y, "px) translateZ(0)"));
  94. }
  95. }
  96. function _typeof(obj) {
  97. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  98. _typeof = function _typeof(obj) {
  99. return typeof obj;
  100. };
  101. } else {
  102. _typeof = function _typeof(obj) {
  103. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  104. };
  105. }
  106. return _typeof(obj);
  107. }
  108. var RE_NUM = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source;
  109. var getComputedStyleX; // https://stackoverflow.com/a/3485654/3040605
  110. function forceRelayout(elem) {
  111. var originalStyle = elem.style.display;
  112. elem.style.display = 'none';
  113. elem.offsetHeight; // eslint-disable-line
  114. elem.style.display = originalStyle;
  115. }
  116. function css(el, name, v) {
  117. var value = v;
  118. if (_typeof(name) === 'object') {
  119. for (var i in name) {
  120. if (name.hasOwnProperty(i)) {
  121. css(el, i, name[i]);
  122. }
  123. }
  124. return undefined;
  125. }
  126. if (typeof value !== 'undefined') {
  127. if (typeof value === 'number') {
  128. value = "".concat(value, "px");
  129. }
  130. el.style[name] = value;
  131. return undefined;
  132. }
  133. return getComputedStyleX(el, name);
  134. }
  135. function getClientPosition(elem) {
  136. var box;
  137. var x;
  138. var y;
  139. var doc = elem.ownerDocument;
  140. var body = doc.body;
  141. var docElem = doc && doc.documentElement; // 根据 GBS 最新数据,A-Grade Browsers 都已支持 getBoundingClientRect 方法,不用再考虑传统的实现方式
  142. box = elem.getBoundingClientRect(); // 注:jQuery 还考虑减去 docElem.clientLeft/clientTop
  143. // 但测试发现,这样反而会导致当 html 和 body 有边距/边框样式时,获取的值不正确
  144. // 此外,ie6 会忽略 html 的 margin 值,幸运地是没有谁会去设置 html 的 margin
  145. x = box.left;
  146. y = box.top; // In IE, most of the time, 2 extra pixels are added to the top and left
  147. // due to the implicit 2-pixel inset border. In IE6/7 quirks mode and
  148. // IE6 standards mode, this border can be overridden by setting the
  149. // document element's border to zero -- thus, we cannot rely on the
  150. // offset always being 2 pixels.
  151. // In quirks mode, the offset can be determined by querying the body's
  152. // clientLeft/clientTop, but in standards mode, it is found by querying
  153. // the document element's clientLeft/clientTop. Since we already called
  154. // getClientBoundingRect we have already forced a reflow, so it is not
  155. // too expensive just to query them all.
  156. // ie 下应该减去窗口的边框吧,毕竟默认 absolute 都是相对窗口定位的
  157. // 窗口边框标准是设 documentElement ,quirks 时设置 body
  158. // 最好禁止在 body 和 html 上边框 ,但 ie < 9 html 默认有 2px ,减去
  159. // 但是非 ie 不可能设置窗口边框,body html 也不是窗口 ,ie 可以通过 html,body 设置
  160. // 标准 ie 下 docElem.clientTop 就是 border-top
  161. // ie7 html 即窗口边框改变不了。永远为 2
  162. // 但标准 firefox/chrome/ie9 下 docElem.clientTop 是窗口边框,即使设了 border-top 也为 0
  163. x -= docElem.clientLeft || body.clientLeft || 0;
  164. y -= docElem.clientTop || body.clientTop || 0;
  165. return {
  166. left: x,
  167. top: y
  168. };
  169. }
  170. function getScroll(w, top) {
  171. var ret = w["page".concat(top ? 'Y' : 'X', "Offset")];
  172. var method = "scroll".concat(top ? 'Top' : 'Left');
  173. if (typeof ret !== 'number') {
  174. var d = w.document; // ie6,7,8 standard mode
  175. ret = d.documentElement[method];
  176. if (typeof ret !== 'number') {
  177. // quirks mode
  178. ret = d.body[method];
  179. }
  180. }
  181. return ret;
  182. }
  183. function getScrollLeft(w) {
  184. return getScroll(w);
  185. }
  186. function getScrollTop(w) {
  187. return getScroll(w, true);
  188. }
  189. function getOffset(el) {
  190. var pos = getClientPosition(el);
  191. var doc = el.ownerDocument;
  192. var w = doc.defaultView || doc.parentWindow;
  193. pos.left += getScrollLeft(w);
  194. pos.top += getScrollTop(w);
  195. return pos;
  196. }
  197. /**
  198. * A crude way of determining if an object is a window
  199. * @member util
  200. */
  201. function isWindow(obj) {
  202. // must use == for ie8
  203. /* eslint eqeqeq:0 */
  204. return obj !== null && obj !== undefined && obj == obj.window;
  205. }
  206. function getDocument(node) {
  207. if (isWindow(node)) {
  208. return node.document;
  209. }
  210. if (node.nodeType === 9) {
  211. return node;
  212. }
  213. return node.ownerDocument;
  214. }
  215. function _getComputedStyle(elem, name, cs) {
  216. var computedStyle = cs;
  217. var val = '';
  218. var d = getDocument(elem);
  219. computedStyle = computedStyle || d.defaultView.getComputedStyle(elem, null); // https://github.com/kissyteam/kissy/issues/61
  220. if (computedStyle) {
  221. val = computedStyle.getPropertyValue(name) || computedStyle[name];
  222. }
  223. return val;
  224. }
  225. var _RE_NUM_NO_PX = new RegExp("^(".concat(RE_NUM, ")(?!px)[a-z%]+$"), 'i');
  226. var RE_POS = /^(top|right|bottom|left)$/;
  227. var CURRENT_STYLE = 'currentStyle';
  228. var RUNTIME_STYLE = 'runtimeStyle';
  229. var LEFT = 'left';
  230. var PX = 'px';
  231. function _getComputedStyleIE(elem, name) {
  232. // currentStyle maybe null
  233. // http://msdn.microsoft.com/en-us/library/ms535231.aspx
  234. var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name]; // 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值
  235. // 一开始就处理了! CUSTOM_STYLE.height,CUSTOM_STYLE.width ,cssHook 解决@2011-08-19
  236. // 在 ie 下不对,需要直接用 offset 方式
  237. // borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了
  238. // From the awesome hack by Dean Edwards
  239. // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  240. // If we're not dealing with a regular pixel number
  241. // but a number that has a weird ending, we need to convert it to pixels
  242. // exclude left right for relativity
  243. if (_RE_NUM_NO_PX.test(ret) && !RE_POS.test(name)) {
  244. // Remember the original values
  245. var style = elem.style;
  246. var left = style[LEFT];
  247. var rsLeft = elem[RUNTIME_STYLE][LEFT]; // prevent flashing of content
  248. elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT]; // Put in the new values to get a computed value out
  249. style[LEFT] = name === 'fontSize' ? '1em' : ret || 0;
  250. ret = style.pixelLeft + PX; // Revert the changed values
  251. style[LEFT] = left;
  252. elem[RUNTIME_STYLE][LEFT] = rsLeft;
  253. }
  254. return ret === '' ? 'auto' : ret;
  255. }
  256. if (typeof window !== 'undefined') {
  257. getComputedStyleX = window.getComputedStyle ? _getComputedStyle : _getComputedStyleIE;
  258. }
  259. function getOffsetDirection(dir, option) {
  260. if (dir === 'left') {
  261. return option.useCssRight ? 'right' : dir;
  262. }
  263. return option.useCssBottom ? 'bottom' : dir;
  264. }
  265. function oppositeOffsetDirection(dir) {
  266. if (dir === 'left') {
  267. return 'right';
  268. } else if (dir === 'right') {
  269. return 'left';
  270. } else if (dir === 'top') {
  271. return 'bottom';
  272. } else if (dir === 'bottom') {
  273. return 'top';
  274. }
  275. } // 设置 elem 相对 elem.ownerDocument 的坐标
  276. function setLeftTop(elem, offset, option) {
  277. // set position first, in-case top/left are set even on static elem
  278. if (css(elem, 'position') === 'static') {
  279. elem.style.position = 'relative';
  280. }
  281. var presetH = -999;
  282. var presetV = -999;
  283. var horizontalProperty = getOffsetDirection('left', option);
  284. var verticalProperty = getOffsetDirection('top', option);
  285. var oppositeHorizontalProperty = oppositeOffsetDirection(horizontalProperty);
  286. var oppositeVerticalProperty = oppositeOffsetDirection(verticalProperty);
  287. if (horizontalProperty !== 'left') {
  288. presetH = 999;
  289. }
  290. if (verticalProperty !== 'top') {
  291. presetV = 999;
  292. }
  293. var originalTransition = '';
  294. var originalOffset = getOffset(elem);
  295. if ('left' in offset || 'top' in offset) {
  296. originalTransition = getTransitionProperty(elem) || '';
  297. setTransitionProperty(elem, 'none');
  298. }
  299. if ('left' in offset) {
  300. elem.style[oppositeHorizontalProperty] = '';
  301. elem.style[horizontalProperty] = "".concat(presetH, "px");
  302. }
  303. if ('top' in offset) {
  304. elem.style[oppositeVerticalProperty] = '';
  305. elem.style[verticalProperty] = "".concat(presetV, "px");
  306. } // force relayout
  307. forceRelayout(elem);
  308. var old = getOffset(elem);
  309. var originalStyle = {};
  310. for (var key in offset) {
  311. if (offset.hasOwnProperty(key)) {
  312. var dir = getOffsetDirection(key, option);
  313. var preset = key === 'left' ? presetH : presetV;
  314. var off = originalOffset[key] - old[key];
  315. if (dir === key) {
  316. originalStyle[dir] = preset + off;
  317. } else {
  318. originalStyle[dir] = preset - off;
  319. }
  320. }
  321. }
  322. css(elem, originalStyle); // force relayout
  323. forceRelayout(elem);
  324. if ('left' in offset || 'top' in offset) {
  325. setTransitionProperty(elem, originalTransition);
  326. }
  327. var ret = {};
  328. for (var _key in offset) {
  329. if (offset.hasOwnProperty(_key)) {
  330. var _dir = getOffsetDirection(_key, option);
  331. var _off = offset[_key] - originalOffset[_key];
  332. if (_key === _dir) {
  333. ret[_dir] = originalStyle[_dir] + _off;
  334. } else {
  335. ret[_dir] = originalStyle[_dir] - _off;
  336. }
  337. }
  338. }
  339. css(elem, ret);
  340. }
  341. function setTransform$1(elem, offset) {
  342. var originalOffset = getOffset(elem);
  343. var originalXY = getTransformXY(elem);
  344. var resultXY = {
  345. x: originalXY.x,
  346. y: originalXY.y
  347. };
  348. if ('left' in offset) {
  349. resultXY.x = originalXY.x + offset.left - originalOffset.left;
  350. }
  351. if ('top' in offset) {
  352. resultXY.y = originalXY.y + offset.top - originalOffset.top;
  353. }
  354. setTransformXY(elem, resultXY);
  355. }
  356. function setOffset(elem, offset, option) {
  357. if (option.ignoreShake) {
  358. var oriOffset = getOffset(elem);
  359. var oLeft = oriOffset.left.toFixed(0);
  360. var oTop = oriOffset.top.toFixed(0);
  361. var tLeft = offset.left.toFixed(0);
  362. var tTop = offset.top.toFixed(0);
  363. if (oLeft === tLeft && oTop === tTop) {
  364. return;
  365. }
  366. }
  367. if (option.useCssRight || option.useCssBottom) {
  368. setLeftTop(elem, offset, option);
  369. } else if (option.useCssTransform && getTransformName() in document.body.style) {
  370. setTransform$1(elem, offset);
  371. } else {
  372. setLeftTop(elem, offset, option);
  373. }
  374. }
  375. function each(arr, fn) {
  376. for (var i = 0; i < arr.length; i++) {
  377. fn(arr[i]);
  378. }
  379. }
  380. function isBorderBoxFn(elem) {
  381. return getComputedStyleX(elem, 'boxSizing') === 'border-box';
  382. }
  383. var BOX_MODELS = ['margin', 'border', 'padding'];
  384. var CONTENT_INDEX = -1;
  385. var PADDING_INDEX = 2;
  386. var BORDER_INDEX = 1;
  387. var MARGIN_INDEX = 0;
  388. function swap(elem, options, callback) {
  389. var old = {};
  390. var style = elem.style;
  391. var name; // Remember the old values, and insert the new ones
  392. for (name in options) {
  393. if (options.hasOwnProperty(name)) {
  394. old[name] = style[name];
  395. style[name] = options[name];
  396. }
  397. }
  398. callback.call(elem); // Revert the old values
  399. for (name in options) {
  400. if (options.hasOwnProperty(name)) {
  401. style[name] = old[name];
  402. }
  403. }
  404. }
  405. function getPBMWidth(elem, props, which) {
  406. var value = 0;
  407. var prop;
  408. var j;
  409. var i;
  410. for (j = 0; j < props.length; j++) {
  411. prop = props[j];
  412. if (prop) {
  413. for (i = 0; i < which.length; i++) {
  414. var cssProp = void 0;
  415. if (prop === 'border') {
  416. cssProp = "".concat(prop).concat(which[i], "Width");
  417. } else {
  418. cssProp = prop + which[i];
  419. }
  420. value += parseFloat(getComputedStyleX(elem, cssProp)) || 0;
  421. }
  422. }
  423. }
  424. return value;
  425. }
  426. var domUtils = {
  427. getParent: function getParent(element) {
  428. var parent = element;
  429. do {
  430. if (parent.nodeType === 11 && parent.host) {
  431. parent = parent.host;
  432. } else {
  433. parent = parent.parentNode;
  434. }
  435. } while (parent && parent.nodeType !== 1 && parent.nodeType !== 9);
  436. return parent;
  437. }
  438. };
  439. each(['Width', 'Height'], function (name) {
  440. domUtils["doc".concat(name)] = function (refWin) {
  441. var d = refWin.document;
  442. return Math.max( // firefox chrome documentElement.scrollHeight< body.scrollHeight
  443. // ie standard mode : documentElement.scrollHeight> body.scrollHeight
  444. d.documentElement["scroll".concat(name)], // quirks : documentElement.scrollHeight 最大等于可视窗口多一点?
  445. d.body["scroll".concat(name)], domUtils["viewport".concat(name)](d));
  446. };
  447. domUtils["viewport".concat(name)] = function (win) {
  448. // pc browser includes scrollbar in window.innerWidth
  449. var prop = "client".concat(name);
  450. var doc = win.document;
  451. var body = doc.body;
  452. var documentElement = doc.documentElement;
  453. var documentElementProp = documentElement[prop]; // 标准模式取 documentElement
  454. // backcompat 取 body
  455. return doc.compatMode === 'CSS1Compat' && documentElementProp || body && body[prop] || documentElementProp;
  456. };
  457. });
  458. /*
  459. 得到元素的大小信息
  460. @param elem
  461. @param name
  462. @param {String} [extra] 'padding' : (css width) + padding
  463. 'border' : (css width) + padding + border
  464. 'margin' : (css width) + padding + border + margin
  465. */
  466. function getWH(elem, name, ex) {
  467. var extra = ex;
  468. if (isWindow(elem)) {
  469. return name === 'width' ? domUtils.viewportWidth(elem) : domUtils.viewportHeight(elem);
  470. } else if (elem.nodeType === 9) {
  471. return name === 'width' ? domUtils.docWidth(elem) : domUtils.docHeight(elem);
  472. }
  473. var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];
  474. var borderBoxValue = name === 'width' ? elem.getBoundingClientRect().width : elem.getBoundingClientRect().height;
  475. var computedStyle = getComputedStyleX(elem);
  476. var isBorderBox = isBorderBoxFn(elem);
  477. var cssBoxValue = 0;
  478. if (borderBoxValue === null || borderBoxValue === undefined || borderBoxValue <= 0) {
  479. borderBoxValue = undefined; // Fall back to computed then un computed css if necessary
  480. cssBoxValue = getComputedStyleX(elem, name);
  481. if (cssBoxValue === null || cssBoxValue === undefined || Number(cssBoxValue) < 0) {
  482. cssBoxValue = elem.style[name] || 0;
  483. } // Normalize '', auto, and prepare for extra
  484. cssBoxValue = parseFloat(cssBoxValue) || 0;
  485. }
  486. if (extra === undefined) {
  487. extra = isBorderBox ? BORDER_INDEX : CONTENT_INDEX;
  488. }
  489. var borderBoxValueOrIsBorderBox = borderBoxValue !== undefined || isBorderBox;
  490. var val = borderBoxValue || cssBoxValue;
  491. if (extra === CONTENT_INDEX) {
  492. if (borderBoxValueOrIsBorderBox) {
  493. return val - getPBMWidth(elem, ['border', 'padding'], which);
  494. }
  495. return cssBoxValue;
  496. } else if (borderBoxValueOrIsBorderBox) {
  497. if (extra === BORDER_INDEX) {
  498. return val;
  499. }
  500. return val + (extra === PADDING_INDEX ? -getPBMWidth(elem, ['border'], which) : getPBMWidth(elem, ['margin'], which));
  501. }
  502. return cssBoxValue + getPBMWidth(elem, BOX_MODELS.slice(extra), which);
  503. }
  504. var cssShow = {
  505. position: 'absolute',
  506. visibility: 'hidden',
  507. display: 'block'
  508. }; // fix #119 : https://github.com/kissyteam/kissy/issues/119
  509. function getWHIgnoreDisplay() {
  510. for (var _len = arguments.length, args = new Array(_len), _key2 = 0; _key2 < _len; _key2++) {
  511. args[_key2] = arguments[_key2];
  512. }
  513. var val;
  514. var elem = args[0]; // in case elem is window
  515. // elem.offsetWidth === undefined
  516. if (elem.offsetWidth !== 0) {
  517. val = getWH.apply(undefined, args);
  518. } else {
  519. swap(elem, cssShow, function () {
  520. val = getWH.apply(undefined, args);
  521. });
  522. }
  523. return val;
  524. }
  525. each(['width', 'height'], function (name) {
  526. var first = name.charAt(0).toUpperCase() + name.slice(1);
  527. domUtils["outer".concat(first)] = function (el, includeMargin) {
  528. return el && getWHIgnoreDisplay(el, name, includeMargin ? MARGIN_INDEX : BORDER_INDEX);
  529. };
  530. var which = name === 'width' ? ['Left', 'Right'] : ['Top', 'Bottom'];
  531. domUtils[name] = function (elem, v) {
  532. var val = v;
  533. if (val !== undefined) {
  534. if (elem) {
  535. var computedStyle = getComputedStyleX(elem);
  536. var isBorderBox = isBorderBoxFn(elem);
  537. if (isBorderBox) {
  538. val += getPBMWidth(elem, ['padding', 'border'], which);
  539. }
  540. return css(elem, name, val);
  541. }
  542. return undefined;
  543. }
  544. return elem && getWHIgnoreDisplay(elem, name, CONTENT_INDEX);
  545. };
  546. });
  547. function mix(to, from) {
  548. for (var i in from) {
  549. if (from.hasOwnProperty(i)) {
  550. to[i] = from[i];
  551. }
  552. }
  553. return to;
  554. }
  555. var utils = {
  556. getWindow: function getWindow(node) {
  557. if (node && node.document && node.setTimeout) {
  558. return node;
  559. }
  560. var doc = node.ownerDocument || node;
  561. return doc.defaultView || doc.parentWindow;
  562. },
  563. getDocument: getDocument,
  564. offset: function offset(el, value, option) {
  565. if (typeof value !== 'undefined') {
  566. setOffset(el, value, option || {});
  567. } else {
  568. return getOffset(el);
  569. }
  570. },
  571. isWindow: isWindow,
  572. each: each,
  573. css: css,
  574. clone: function clone(obj) {
  575. var i;
  576. var ret = {};
  577. for (i in obj) {
  578. if (obj.hasOwnProperty(i)) {
  579. ret[i] = obj[i];
  580. }
  581. }
  582. var overflow = obj.overflow;
  583. if (overflow) {
  584. for (i in obj) {
  585. if (obj.hasOwnProperty(i)) {
  586. ret.overflow[i] = obj.overflow[i];
  587. }
  588. }
  589. }
  590. return ret;
  591. },
  592. mix: mix,
  593. getWindowScrollLeft: function getWindowScrollLeft(w) {
  594. return getScrollLeft(w);
  595. },
  596. getWindowScrollTop: function getWindowScrollTop(w) {
  597. return getScrollTop(w);
  598. },
  599. merge: function merge() {
  600. var ret = {};
  601. for (var i = 0; i < arguments.length; i++) {
  602. utils.mix(ret, i < 0 || arguments.length <= i ? undefined : arguments[i]);
  603. }
  604. return ret;
  605. },
  606. viewportWidth: 0,
  607. viewportHeight: 0
  608. };
  609. mix(utils, domUtils);
  610. /**
  611. * 得到会导致元素显示不全的祖先元素
  612. */
  613. var getParent = utils.getParent;
  614. function getOffsetParent(element) {
  615. if (utils.isWindow(element) || element.nodeType === 9) {
  616. return null;
  617. } // ie 这个也不是完全可行
  618. /*
  619. <div style="width: 50px;height: 100px;overflow: hidden">
  620. <div style="width: 50px;height: 100px;position: relative;" id="d6">
  621. 元素 6 高 100px 宽 50px<br/>
  622. </div>
  623. </div>
  624. */
  625. // element.offsetParent does the right thing in ie7 and below. Return parent with layout!
  626. // In other browsers it only includes elements with position absolute, relative or
  627. // fixed, not elements with overflow set to auto or scroll.
  628. // if (UA.ie && ieMode < 8) {
  629. // return element.offsetParent;
  630. // }
  631. // 统一的 offsetParent 方法
  632. var doc = utils.getDocument(element);
  633. var body = doc.body;
  634. var parent;
  635. var positionStyle = utils.css(element, 'position');
  636. var skipStatic = positionStyle === 'fixed' || positionStyle === 'absolute';
  637. if (!skipStatic) {
  638. return element.nodeName.toLowerCase() === 'html' ? null : getParent(element);
  639. }
  640. for (parent = getParent(element); parent && parent !== body && parent.nodeType !== 9; parent = getParent(parent)) {
  641. positionStyle = utils.css(parent, 'position');
  642. if (positionStyle !== 'static') {
  643. return parent;
  644. }
  645. }
  646. return null;
  647. }
  648. var getParent$1 = utils.getParent;
  649. function isAncestorFixed(element) {
  650. if (utils.isWindow(element) || element.nodeType === 9) {
  651. return false;
  652. }
  653. var doc = utils.getDocument(element);
  654. var body = doc.body;
  655. var parent = null;
  656. for (parent = getParent$1(element); parent && parent !== body; parent = getParent$1(parent)) {
  657. var positionStyle = utils.css(parent, 'position');
  658. if (positionStyle === 'fixed') {
  659. return true;
  660. }
  661. }
  662. return false;
  663. }
  664. /**
  665. * 获得元素的显示部分的区域
  666. */
  667. function getVisibleRectForElement(element, alwaysByViewport) {
  668. var visibleRect = {
  669. left: 0,
  670. right: Infinity,
  671. top: 0,
  672. bottom: Infinity
  673. };
  674. var el = getOffsetParent(element);
  675. var doc = utils.getDocument(element);
  676. var win = doc.defaultView || doc.parentWindow;
  677. var body = doc.body;
  678. var documentElement = doc.documentElement; // Determine the size of the visible rect by climbing the dom accounting for
  679. // all scrollable containers.
  680. while (el) {
  681. // clientWidth is zero for inline block elements in ie.
  682. if ((navigator.userAgent.indexOf('MSIE') === -1 || el.clientWidth !== 0) && // body may have overflow set on it, yet we still get the entire
  683. // viewport. In some browsers, el.offsetParent may be
  684. // document.documentElement, so check for that too.
  685. el !== body && el !== documentElement && utils.css(el, 'overflow') !== 'visible') {
  686. var pos = utils.offset(el); // add border
  687. pos.left += el.clientLeft;
  688. pos.top += el.clientTop;
  689. visibleRect.top = Math.max(visibleRect.top, pos.top);
  690. visibleRect.right = Math.min(visibleRect.right, // consider area without scrollBar
  691. pos.left + el.clientWidth);
  692. visibleRect.bottom = Math.min(visibleRect.bottom, pos.top + el.clientHeight);
  693. visibleRect.left = Math.max(visibleRect.left, pos.left);
  694. } else if (el === body || el === documentElement) {
  695. break;
  696. }
  697. el = getOffsetParent(el);
  698. } // Set element position to fixed
  699. // make sure absolute element itself don't affect it's visible area
  700. // https://github.com/ant-design/ant-design/issues/7601
  701. var originalPosition = null;
  702. if (!utils.isWindow(element) && element.nodeType !== 9) {
  703. originalPosition = element.style.position;
  704. var position = utils.css(element, 'position');
  705. if (position === 'absolute') {
  706. element.style.position = 'fixed';
  707. }
  708. }
  709. var scrollX = utils.getWindowScrollLeft(win);
  710. var scrollY = utils.getWindowScrollTop(win);
  711. var viewportWidth = utils.viewportWidth(win);
  712. var viewportHeight = utils.viewportHeight(win);
  713. var documentWidth = documentElement.scrollWidth;
  714. var documentHeight = documentElement.scrollHeight; // scrollXXX on html is sync with body which means overflow: hidden on body gets wrong scrollXXX.
  715. // We should cut this ourself.
  716. var bodyStyle = window.getComputedStyle(body);
  717. if (bodyStyle.overflowX === 'hidden') {
  718. documentWidth = win.innerWidth;
  719. }
  720. if (bodyStyle.overflowY === 'hidden') {
  721. documentHeight = win.innerHeight;
  722. } // Reset element position after calculate the visible area
  723. if (element.style) {
  724. element.style.position = originalPosition;
  725. }
  726. if (alwaysByViewport || isAncestorFixed(element)) {
  727. // Clip by viewport's size.
  728. visibleRect.left = Math.max(visibleRect.left, scrollX);
  729. visibleRect.top = Math.max(visibleRect.top, scrollY);
  730. visibleRect.right = Math.min(visibleRect.right, scrollX + viewportWidth);
  731. visibleRect.bottom = Math.min(visibleRect.bottom, scrollY + viewportHeight);
  732. } else {
  733. // Clip by document's size.
  734. var maxVisibleWidth = Math.max(documentWidth, scrollX + viewportWidth);
  735. visibleRect.right = Math.min(visibleRect.right, maxVisibleWidth);
  736. var maxVisibleHeight = Math.max(documentHeight, scrollY + viewportHeight);
  737. visibleRect.bottom = Math.min(visibleRect.bottom, maxVisibleHeight);
  738. }
  739. return visibleRect.top >= 0 && visibleRect.left >= 0 && visibleRect.bottom > visibleRect.top && visibleRect.right > visibleRect.left ? visibleRect : null;
  740. }
  741. function adjustForViewport(elFuturePos, elRegion, visibleRect, overflow) {
  742. var pos = utils.clone(elFuturePos);
  743. var size = {
  744. width: elRegion.width,
  745. height: elRegion.height
  746. };
  747. if (overflow.adjustX && pos.left < visibleRect.left) {
  748. pos.left = visibleRect.left;
  749. } // Left edge inside and right edge outside viewport, try to resize it.
  750. if (overflow.resizeWidth && pos.left >= visibleRect.left && pos.left + size.width > visibleRect.right) {
  751. size.width -= pos.left + size.width - visibleRect.right;
  752. } // Right edge outside viewport, try to move it.
  753. if (overflow.adjustX && pos.left + size.width > visibleRect.right) {
  754. // 保证左边界和可视区域左边界对齐
  755. pos.left = Math.max(visibleRect.right - size.width, visibleRect.left);
  756. } // Top edge outside viewport, try to move it.
  757. if (overflow.adjustY && pos.top < visibleRect.top) {
  758. pos.top = visibleRect.top;
  759. } // Top edge inside and bottom edge outside viewport, try to resize it.
  760. if (overflow.resizeHeight && pos.top >= visibleRect.top && pos.top + size.height > visibleRect.bottom) {
  761. size.height -= pos.top + size.height - visibleRect.bottom;
  762. } // Bottom edge outside viewport, try to move it.
  763. if (overflow.adjustY && pos.top + size.height > visibleRect.bottom) {
  764. // 保证上边界和可视区域上边界对齐
  765. pos.top = Math.max(visibleRect.bottom - size.height, visibleRect.top);
  766. }
  767. return utils.mix(pos, size);
  768. }
  769. function getRegion(node) {
  770. var offset;
  771. var w;
  772. var h;
  773. if (!utils.isWindow(node) && node.nodeType !== 9) {
  774. offset = utils.offset(node);
  775. w = utils.outerWidth(node);
  776. h = utils.outerHeight(node);
  777. } else {
  778. var win = utils.getWindow(node);
  779. offset = {
  780. left: utils.getWindowScrollLeft(win),
  781. top: utils.getWindowScrollTop(win)
  782. };
  783. w = utils.viewportWidth(win);
  784. h = utils.viewportHeight(win);
  785. }
  786. offset.width = w;
  787. offset.height = h;
  788. return offset;
  789. }
  790. /**
  791. * 获取 node 上的 align 对齐点 相对于页面的坐标
  792. */
  793. function getAlignOffset(region, align) {
  794. var V = align.charAt(0);
  795. var H = align.charAt(1);
  796. var w = region.width;
  797. var h = region.height;
  798. var x = region.left;
  799. var y = region.top;
  800. if (V === 'c') {
  801. y += h / 2;
  802. } else if (V === 'b') {
  803. y += h;
  804. }
  805. if (H === 'c') {
  806. x += w / 2;
  807. } else if (H === 'r') {
  808. x += w;
  809. }
  810. return {
  811. left: x,
  812. top: y
  813. };
  814. }
  815. function getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset) {
  816. var p1 = getAlignOffset(refNodeRegion, points[1]);
  817. var p2 = getAlignOffset(elRegion, points[0]);
  818. var diff = [p2.left - p1.left, p2.top - p1.top];
  819. return {
  820. left: Math.round(elRegion.left - diff[0] + offset[0] - targetOffset[0]),
  821. top: Math.round(elRegion.top - diff[1] + offset[1] - targetOffset[1])
  822. };
  823. }
  824. /**
  825. * align dom node flexibly
  826. * @author yiminghe@gmail.com
  827. */
  828. function isFailX(elFuturePos, elRegion, visibleRect) {
  829. return elFuturePos.left < visibleRect.left || elFuturePos.left + elRegion.width > visibleRect.right;
  830. }
  831. function isFailY(elFuturePos, elRegion, visibleRect) {
  832. return elFuturePos.top < visibleRect.top || elFuturePos.top + elRegion.height > visibleRect.bottom;
  833. }
  834. function isCompleteFailX(elFuturePos, elRegion, visibleRect) {
  835. return elFuturePos.left > visibleRect.right || elFuturePos.left + elRegion.width < visibleRect.left;
  836. }
  837. function isCompleteFailY(elFuturePos, elRegion, visibleRect) {
  838. return elFuturePos.top > visibleRect.bottom || elFuturePos.top + elRegion.height < visibleRect.top;
  839. }
  840. function flip(points, reg, map) {
  841. var ret = [];
  842. utils.each(points, function (p) {
  843. ret.push(p.replace(reg, function (m) {
  844. return map[m];
  845. }));
  846. });
  847. return ret;
  848. }
  849. function flipOffset(offset, index) {
  850. offset[index] = -offset[index];
  851. return offset;
  852. }
  853. function convertOffset(str, offsetLen) {
  854. var n;
  855. if (/%$/.test(str)) {
  856. n = parseInt(str.substring(0, str.length - 1), 10) / 100 * offsetLen;
  857. } else {
  858. n = parseInt(str, 10);
  859. }
  860. return n || 0;
  861. }
  862. function normalizeOffset(offset, el) {
  863. offset[0] = convertOffset(offset[0], el.width);
  864. offset[1] = convertOffset(offset[1], el.height);
  865. }
  866. /**
  867. * @param el
  868. * @param tgtRegion 参照节点所占的区域: { left, top, width, height }
  869. * @param align
  870. */
  871. function doAlign(el, tgtRegion, align, isTgtRegionVisible) {
  872. var points = align.points;
  873. var offset = align.offset || [0, 0];
  874. var targetOffset = align.targetOffset || [0, 0];
  875. var overflow = align.overflow;
  876. var source = align.source || el;
  877. offset = [].concat(offset);
  878. targetOffset = [].concat(targetOffset);
  879. overflow = overflow || {};
  880. var newOverflowCfg = {};
  881. var fail = 0;
  882. var alwaysByViewport = !!(overflow && overflow.alwaysByViewport); // 当前节点可以被放置的显示区域
  883. var visibleRect = getVisibleRectForElement(source, alwaysByViewport); // 当前节点所占的区域, left/top/width/height
  884. var elRegion = getRegion(source); // 将 offset 转换成数值,支持百分比
  885. normalizeOffset(offset, elRegion);
  886. normalizeOffset(targetOffset, tgtRegion); // 当前节点将要被放置的位置
  887. var elFuturePos = getElFuturePos(elRegion, tgtRegion, points, offset, targetOffset); // 当前节点将要所处的区域
  888. var newElRegion = utils.merge(elRegion, elFuturePos); // 如果可视区域不能完全放置当前节点时允许调整
  889. if (visibleRect && (overflow.adjustX || overflow.adjustY) && isTgtRegionVisible) {
  890. if (overflow.adjustX) {
  891. // 如果横向不能放下
  892. if (isFailX(elFuturePos, elRegion, visibleRect)) {
  893. // 对齐位置反下
  894. var newPoints = flip(points, /[lr]/gi, {
  895. l: 'r',
  896. r: 'l'
  897. }); // 偏移量也反下
  898. var newOffset = flipOffset(offset, 0);
  899. var newTargetOffset = flipOffset(targetOffset, 0);
  900. var newElFuturePos = getElFuturePos(elRegion, tgtRegion, newPoints, newOffset, newTargetOffset);
  901. if (!isCompleteFailX(newElFuturePos, elRegion, visibleRect)) {
  902. fail = 1;
  903. points = newPoints;
  904. offset = newOffset;
  905. targetOffset = newTargetOffset;
  906. }
  907. }
  908. }
  909. if (overflow.adjustY) {
  910. // 如果纵向不能放下
  911. if (isFailY(elFuturePos, elRegion, visibleRect)) {
  912. // 对齐位置反下
  913. var _newPoints = flip(points, /[tb]/gi, {
  914. t: 'b',
  915. b: 't'
  916. }); // 偏移量也反下
  917. var _newOffset = flipOffset(offset, 1);
  918. var _newTargetOffset = flipOffset(targetOffset, 1);
  919. var _newElFuturePos = getElFuturePos(elRegion, tgtRegion, _newPoints, _newOffset, _newTargetOffset);
  920. if (!isCompleteFailY(_newElFuturePos, elRegion, visibleRect)) {
  921. fail = 1;
  922. points = _newPoints;
  923. offset = _newOffset;
  924. targetOffset = _newTargetOffset;
  925. }
  926. }
  927. } // 如果失败,重新计算当前节点将要被放置的位置
  928. if (fail) {
  929. elFuturePos = getElFuturePos(elRegion, tgtRegion, points, offset, targetOffset);
  930. utils.mix(newElRegion, elFuturePos);
  931. }
  932. var isStillFailX = isFailX(elFuturePos, elRegion, visibleRect);
  933. var isStillFailY = isFailY(elFuturePos, elRegion, visibleRect); // 检查反下后的位置是否可以放下了,如果仍然放不下:
  934. // 1. 复原修改过的定位参数
  935. if (isStillFailX || isStillFailY) {
  936. points = align.points;
  937. offset = align.offset || [0, 0];
  938. targetOffset = align.targetOffset || [0, 0];
  939. } // 2. 只有指定了可以调整当前方向才调整
  940. newOverflowCfg.adjustX = overflow.adjustX && isStillFailX;
  941. newOverflowCfg.adjustY = overflow.adjustY && isStillFailY; // 确实要调整,甚至可能会调整高度宽度
  942. if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) {
  943. newElRegion = adjustForViewport(elFuturePos, elRegion, visibleRect, newOverflowCfg);
  944. }
  945. } // need judge to in case set fixed with in css on height auto element
  946. if (newElRegion.width !== elRegion.width) {
  947. utils.css(source, 'width', utils.width(source) + newElRegion.width - elRegion.width);
  948. }
  949. if (newElRegion.height !== elRegion.height) {
  950. utils.css(source, 'height', utils.height(source) + newElRegion.height - elRegion.height);
  951. } // https://github.com/kissyteam/kissy/issues/190
  952. // 相对于屏幕位置没变,而 left/top 变了
  953. // 例如 <div 'relative'><el absolute></div>
  954. utils.offset(source, {
  955. left: newElRegion.left,
  956. top: newElRegion.top
  957. }, {
  958. useCssRight: align.useCssRight,
  959. useCssBottom: align.useCssBottom,
  960. useCssTransform: align.useCssTransform,
  961. ignoreShake: align.ignoreShake
  962. });
  963. return {
  964. points: points,
  965. offset: offset,
  966. targetOffset: targetOffset,
  967. overflow: newOverflowCfg
  968. };
  969. }
  970. /**
  971. * 2012-04-26 yiminghe@gmail.com
  972. * - 优化智能对齐算法
  973. * - 慎用 resizeXX
  974. *
  975. * 2011-07-13 yiminghe@gmail.com note:
  976. * - 增加智能对齐,以及大小调整选项
  977. **/
  978. function isOutOfVisibleRect(target, alwaysByViewport) {
  979. var visibleRect = getVisibleRectForElement(target, alwaysByViewport);
  980. var targetRegion = getRegion(target);
  981. return !visibleRect || targetRegion.left + targetRegion.width <= visibleRect.left || targetRegion.top + targetRegion.height <= visibleRect.top || targetRegion.left >= visibleRect.right || targetRegion.top >= visibleRect.bottom;
  982. }
  983. function alignElement(el, refNode, align) {
  984. var target = align.target || refNode;
  985. var refNodeRegion = getRegion(target);
  986. var isTargetNotOutOfVisible = !isOutOfVisibleRect(target, align.overflow && align.overflow.alwaysByViewport);
  987. return doAlign(el, refNodeRegion, align, isTargetNotOutOfVisible);
  988. }
  989. alignElement.__getOffsetParent = getOffsetParent;
  990. alignElement.__getVisibleRectForElement = getVisibleRectForElement;
  991. function ownKeys(object, enumerableOnly) {
  992. var keys = Object.keys(object);
  993. if (Object.getOwnPropertySymbols) {
  994. var symbols = Object.getOwnPropertySymbols(object);
  995. if (enumerableOnly) symbols = symbols.filter(function (sym) {
  996. return Object.getOwnPropertyDescriptor(object, sym).enumerable;
  997. });
  998. keys.push.apply(keys, symbols);
  999. }
  1000. return keys;
  1001. }
  1002. function _objectSpread(target) {
  1003. for (var i = 1; i < arguments.length; i++) {
  1004. var source = arguments[i] != null ? arguments[i] : {};
  1005. if (i % 2) {
  1006. ownKeys(source, true).forEach(function (key) {
  1007. _defineProperty(target, key, source[key]);
  1008. });
  1009. } else if (Object.getOwnPropertyDescriptors) {
  1010. Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
  1011. } else {
  1012. ownKeys(source).forEach(function (key) {
  1013. Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
  1014. });
  1015. }
  1016. }
  1017. return target;
  1018. }
  1019. function _defineProperty(obj, key, value) {
  1020. if (key in obj) {
  1021. Object.defineProperty(obj, key, {
  1022. value: value,
  1023. enumerable: true,
  1024. configurable: true,
  1025. writable: true
  1026. });
  1027. } else {
  1028. obj[key] = value;
  1029. }
  1030. return obj;
  1031. }
  1032. /**
  1033. * `tgtPoint`: { pageX, pageY } or { clientX, clientY }.
  1034. * If client position provided, will internal convert to page position.
  1035. */
  1036. function alignPoint(el, tgtPoint, align) {
  1037. var pageX;
  1038. var pageY;
  1039. var doc = utils.getDocument(el);
  1040. var win = doc.defaultView || doc.parentWindow;
  1041. var scrollX = utils.getWindowScrollLeft(win);
  1042. var scrollY = utils.getWindowScrollTop(win);
  1043. var viewportWidth = utils.viewportWidth(win);
  1044. var viewportHeight = utils.viewportHeight(win);
  1045. if ('pageX' in tgtPoint) {
  1046. pageX = tgtPoint.pageX;
  1047. } else {
  1048. pageX = scrollX + tgtPoint.clientX;
  1049. }
  1050. if ('pageY' in tgtPoint) {
  1051. pageY = tgtPoint.pageY;
  1052. } else {
  1053. pageY = scrollY + tgtPoint.clientY;
  1054. }
  1055. var tgtRegion = {
  1056. left: pageX,
  1057. top: pageY,
  1058. width: 0,
  1059. height: 0
  1060. };
  1061. var pointInView = pageX >= 0 && pageX <= scrollX + viewportWidth && pageY >= 0 && pageY <= scrollY + viewportHeight; // Provide default target point
  1062. var points = [align.points[0], 'cc'];
  1063. return doAlign(el, tgtRegion, _objectSpread({}, align, {
  1064. points: points
  1065. }), pointInView);
  1066. }
  1067. exports.alignElement = alignElement;
  1068. exports.alignPoint = alignPoint;
  1069. exports.default = alignElement;
  1070. //# sourceMappingURL=index.js.map