polyfills.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. (function() {
  2. 'use strict';
  3. // ChildNode (MDN)
  4. var buildDOM = function() {
  5. var nodes = Array.prototype.slice.call(arguments),
  6. frag = document.createDocumentFragment(),
  7. div, node;
  8. while (node = nodes.shift()) {
  9. if (typeof node == "string") {
  10. div = document.createElement("div");
  11. div.innerHTML = node;
  12. while (div.firstChild) {
  13. frag.appendChild(div.firstChild);
  14. }
  15. } else {
  16. frag.appendChild(node);
  17. }
  18. }
  19. return frag;
  20. };
  21. var proto = {
  22. before: function() {
  23. var frag = buildDOM.apply(this, arguments);
  24. this.parentNode.insertBefore(frag, this);
  25. },
  26. after: function() {
  27. var frag = buildDOM.apply(this, arguments);
  28. this.parentNode.insertBefore(frag, this.nextSibling);
  29. },
  30. replaceWith: function() {
  31. if (this.parentNode) {
  32. var frag = buildDOM.apply(this, arguments);
  33. this.parentNode.replaceChild(frag, this);
  34. }
  35. },
  36. remove: function() {
  37. if (this.parentNode) {
  38. this.parentNode.removeChild(this);
  39. }
  40. }
  41. };
  42. var a = ["Element", "DocumentType", "CharacterData"]; // interface
  43. var b = ["before", "after", "replaceWith", "remove"]; // methods
  44. a.forEach(function(v) {
  45. b.forEach(function(func) {
  46. if (window[v]) {
  47. if (window[v].prototype[func]) { return; }
  48. window[v].prototype[func] = proto[func];
  49. }
  50. });
  51. });
  52. // ParentNode.prepend()
  53. // Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/prepend()/prepend().md
  54. (function(arr) {
  55. arr.forEach(function(item) {
  56. if (item.hasOwnProperty('prepend')) {
  57. return;
  58. }
  59. Object.defineProperty(item, 'prepend', {
  60. configurable: true,
  61. enumerable: true,
  62. writable: true,
  63. value: function prepend() {
  64. var argArr = Array.prototype.slice.call(arguments),
  65. docFrag = document.createDocumentFragment();
  66. argArr.forEach(function(argItem) {
  67. var isNode = argItem instanceof Node;
  68. docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));
  69. });
  70. this.insertBefore(docFrag, this.firstChild);
  71. }
  72. });
  73. });
  74. })([Element.prototype, Document.prototype, DocumentFragment.prototype]);
  75. // Object.assign() (MDN)
  76. if (typeof Object.assign != 'function') {
  77. (function () {
  78. Object.assign = function (target) {
  79. // We must check against these specific cases.
  80. if (target === undefined || target === null) {
  81. throw new TypeError('Cannot convert undefined or null to object');
  82. }
  83. var output = Object(target);
  84. for (var index = 1; index < arguments.length; index++) {
  85. var source = arguments[index];
  86. if (source !== undefined && source !== null) {
  87. for (var nextKey in source) {
  88. if (source.hasOwnProperty(nextKey)) {
  89. output[nextKey] = source[nextKey];
  90. }
  91. }
  92. }
  93. }
  94. return output;
  95. };
  96. })();
  97. }
  98. // Element.prototype.matches (https://plainjs.com/javascript/traversing/get-closest-element-by-selector-39/)
  99. window.Element && function(ElementPrototype) {
  100. ElementPrototype.matches = ElementPrototype.matches ||
  101. ElementPrototype.matchesSelector ||
  102. ElementPrototype.webkitMatchesSelector ||
  103. ElementPrototype.msMatchesSelector ||
  104. function(selector) {
  105. var node = this, nodes = (node.parentNode || node.document).querySelectorAll(selector), i = -1;
  106. while (nodes[++i] && nodes[i] != node);
  107. return !!nodes[i];
  108. };
  109. }(Element.prototype);
  110. // Element.prototype.closest (https://plainjs.com/javascript/traversing/get-closest-element-by-selector-39/)
  111. window.Element && function(ElementPrototype) {
  112. ElementPrototype.closest = ElementPrototype.closest ||
  113. function(selector) {
  114. var el = this;
  115. while (el.matches && !el.matches(selector)) el = el.parentNode;
  116. return el.matches ? el : null;
  117. };
  118. }(Element.prototype);
  119. }());