default.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { DOCUMENT_MODE } from '../common/html.js';
  2. export const defaultTreeAdapter = {
  3. //Node construction
  4. createDocument() {
  5. return {
  6. nodeName: '#document',
  7. mode: DOCUMENT_MODE.NO_QUIRKS,
  8. childNodes: [],
  9. };
  10. },
  11. createDocumentFragment() {
  12. return {
  13. nodeName: '#document-fragment',
  14. childNodes: [],
  15. };
  16. },
  17. createElement(tagName, namespaceURI, attrs) {
  18. return {
  19. nodeName: tagName,
  20. tagName,
  21. attrs,
  22. namespaceURI,
  23. childNodes: [],
  24. parentNode: null,
  25. };
  26. },
  27. createCommentNode(data) {
  28. return {
  29. nodeName: '#comment',
  30. data,
  31. parentNode: null,
  32. };
  33. },
  34. createTextNode(value) {
  35. return {
  36. nodeName: '#text',
  37. value,
  38. parentNode: null,
  39. };
  40. },
  41. //Tree mutation
  42. appendChild(parentNode, newNode) {
  43. parentNode.childNodes.push(newNode);
  44. newNode.parentNode = parentNode;
  45. },
  46. insertBefore(parentNode, newNode, referenceNode) {
  47. const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
  48. parentNode.childNodes.splice(insertionIdx, 0, newNode);
  49. newNode.parentNode = parentNode;
  50. },
  51. setTemplateContent(templateElement, contentElement) {
  52. templateElement.content = contentElement;
  53. },
  54. getTemplateContent(templateElement) {
  55. return templateElement.content;
  56. },
  57. setDocumentType(document, name, publicId, systemId) {
  58. const doctypeNode = document.childNodes.find((node) => node.nodeName === '#documentType');
  59. if (doctypeNode) {
  60. doctypeNode.name = name;
  61. doctypeNode.publicId = publicId;
  62. doctypeNode.systemId = systemId;
  63. }
  64. else {
  65. const node = {
  66. nodeName: '#documentType',
  67. name,
  68. publicId,
  69. systemId,
  70. parentNode: null,
  71. };
  72. defaultTreeAdapter.appendChild(document, node);
  73. }
  74. },
  75. setDocumentMode(document, mode) {
  76. document.mode = mode;
  77. },
  78. getDocumentMode(document) {
  79. return document.mode;
  80. },
  81. detachNode(node) {
  82. if (node.parentNode) {
  83. const idx = node.parentNode.childNodes.indexOf(node);
  84. node.parentNode.childNodes.splice(idx, 1);
  85. node.parentNode = null;
  86. }
  87. },
  88. insertText(parentNode, text) {
  89. if (parentNode.childNodes.length > 0) {
  90. const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
  91. if (defaultTreeAdapter.isTextNode(prevNode)) {
  92. prevNode.value += text;
  93. return;
  94. }
  95. }
  96. defaultTreeAdapter.appendChild(parentNode, defaultTreeAdapter.createTextNode(text));
  97. },
  98. insertTextBefore(parentNode, text, referenceNode) {
  99. const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
  100. if (prevNode && defaultTreeAdapter.isTextNode(prevNode)) {
  101. prevNode.value += text;
  102. }
  103. else {
  104. defaultTreeAdapter.insertBefore(parentNode, defaultTreeAdapter.createTextNode(text), referenceNode);
  105. }
  106. },
  107. adoptAttributes(recipient, attrs) {
  108. const recipientAttrsMap = new Set(recipient.attrs.map((attr) => attr.name));
  109. for (let j = 0; j < attrs.length; j++) {
  110. if (!recipientAttrsMap.has(attrs[j].name)) {
  111. recipient.attrs.push(attrs[j]);
  112. }
  113. }
  114. },
  115. //Tree traversing
  116. getFirstChild(node) {
  117. return node.childNodes[0];
  118. },
  119. getChildNodes(node) {
  120. return node.childNodes;
  121. },
  122. getParentNode(node) {
  123. return node.parentNode;
  124. },
  125. getAttrList(element) {
  126. return element.attrs;
  127. },
  128. //Node data
  129. getTagName(element) {
  130. return element.tagName;
  131. },
  132. getNamespaceURI(element) {
  133. return element.namespaceURI;
  134. },
  135. getTextNodeContent(textNode) {
  136. return textNode.value;
  137. },
  138. getCommentNodeContent(commentNode) {
  139. return commentNode.data;
  140. },
  141. getDocumentTypeNodeName(doctypeNode) {
  142. return doctypeNode.name;
  143. },
  144. getDocumentTypeNodePublicId(doctypeNode) {
  145. return doctypeNode.publicId;
  146. },
  147. getDocumentTypeNodeSystemId(doctypeNode) {
  148. return doctypeNode.systemId;
  149. },
  150. //Node types
  151. isTextNode(node) {
  152. return node.nodeName === '#text';
  153. },
  154. isCommentNode(node) {
  155. return node.nodeName === '#comment';
  156. },
  157. isDocumentTypeNode(node) {
  158. return node.nodeName === '#documentType';
  159. },
  160. isElementNode(node) {
  161. return Object.prototype.hasOwnProperty.call(node, 'tagName');
  162. },
  163. // Source code location
  164. setNodeSourceCodeLocation(node, location) {
  165. node.sourceCodeLocation = location;
  166. },
  167. getNodeSourceCodeLocation(node) {
  168. return node.sourceCodeLocation;
  169. },
  170. updateNodeSourceCodeLocation(node, endLocation) {
  171. node.sourceCodeLocation = { ...node.sourceCodeLocation, ...endLocation };
  172. },
  173. };