Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function isBlock(node) {
- if (node.nodeType !== Node.ELEMENT_NODE) return false;
- return /^(ADDRESS|ARTICLE|ASIDE|BLOCKQUOTE|CANVAS|DD|DIV|DL|DT|FIELDSET|FIGCAPTION|FIGURE|FOOTER|FORM|H1|H2|H3|H4|H5|H6|HEADER|HGROUP|HR|LI|MAIN|NAV|NOSCRIPT|OL|OUTPUT|P|PRE|SECTION|TABLE|TFOOT|UL|VIDEO)$/.test(node.nodeName);
- }
- function createPseudoParagraph(node) {
- return { nodeName: "PSEUDO_PARAGRAPH", childNodes: [node] };
- }
- function createBrBlock(nodes) {
- return { nodeName: "BR_BLOCK", childNodes: nodes };
- }
- function getBoundingRect(node) {
- const rect = node.getBoundingClientRect();
- return {
- left: rect.left + window.pageXOffset,
- top: rect.top + window.pageYOffset,
- width: rect.width,
- height: rect.height,
- };
- }
- function brbrTextToParagraphs(node) {
- // 空白、コメントを消す
- const nodes = [...node.childNodes || []].filter(n => {
- if (n.nodeType === Node.ELEMENT_NODE) return true;
- return n.nodeType === Node.TEXT_NODE && !!(n.nodeValue || "").trim();
- });
- // とりあえず普通のブロック要素と、PSEUDO_PARAGRAPH(text + インライン要素), BR_BLOCK(brが2個以上続いているやつ)に分割
- const paragraphs = [];
- let idx = 0;
- for (let i = 0; i < nodes.length; ++i) {
- const _node = nodes[i];
- if (_node.nodeName === "BR") {
- const ii = nodes.slice(i + 1).findIndex(n => n.nodeName !== "BR");
- if (ii === -1) {
- paragraphs.push(createBrBlock(nodes.slice(i)));
- break;
- } else if (ii > 0) {
- paragraphs.push(createBrBlock(nodes.slice(i, i + ii + 1)));
- idx += 2;
- i += ii;
- } else {
- if (!paragraphs[idx]) {
- paragraphs[idx] = createPseudoParagraph(_node);
- } else {
- paragraphs[idx].childNodes.push(_node);
- }
- }
- } else if (isBlock(_node)) {
- paragraphs.push(_node);
- idx += 2;
- } else {
- if (!paragraphs[idx]) {
- paragraphs[idx] = createPseudoParagraph(_node);
- } else {
- paragraphs[idx].childNodes.push(_node);
- }
- }
- }
- // 位置計算
- let rect = getBoundingRect(node);
- // まずは普通のブロック要素と、BR_BLOCKの箱を決定する
- for (let i = 0; i < paragraphs.length; ++i) {
- const _node = paragraphs[i];
- if (isBlock(_node)) {
- _node._rect = getBoundingRect(_node);
- } else if (_node.nodeName === "BR_BLOCK") {
- const first = getBoundingRect(_node.childNodes[0]);
- const last = getBoundingRect(_node.childNodes[_node.childNodes.length - 1]);
- const top = first.top + last.height;
- _node._rect = {
- left: first.left,
- top,
- width: 0,
- height: last.top + last.height - top,
- };
- }
- }
- // PSEUDO_PARAGRAPHの箱を前後関係から決定する
- for (let i = 0; i < paragraphs.length; ++i) {
- const _node = paragraphs[i];
- if (_node.nodeName !== "PSEUDO_PARAGRAPH" || _node.childNodes.every(x => x.nodeName === "BR")) continue;
- // top
- const first = _node.childNodes[0];
- let top = 0;
- if (first.nodeName === "BR") {
- _node.childNodes.shift();
- const r = getBoundingRect(first);
- top = r.top + r.height;
- } else if (first.nodeType !== Node.TEXT_NODE) {
- const r = getBoundingRect(first);
- top = r.top;
- } else {
- const prev = paragraphs[i - 1];
- top = prev ? prev._rect.top + prev._rect.height : rect.top;
- }
- // height
- const last = _node.childNodes[_node.childNodes.length - 1];
- let height = 0;
- if (last.nodeName === "BR") {
- _node.childNodes.pop();
- const r = getBoundingRect(last);
- height = r.top + r.height - top;
- } else if (last.nodeType !== Node.TEXT_NODE) {
- const r = getBoundingRect(last);
- height = r.top + r.height - top;
- } else {
- const next = paragraphs[i + 1];
- height = (next ? next._rect.top : rect.top + rect.height) - top;
- }
- _node._rect = {
- left: rect.left,
- width: rect.width,
- top,
- height,
- };
- }
- return paragraphs.filter(node => node.nodeType === Node.ELEMENT_NODE || !node.childNodes.every(x => x.nodeName === "BR"));
- }
Add Comment
Please, Sign In to add comment