Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if two text nodes are visually consecutive

I want to know if two text nodes are visually consecutive, regardless of html structure, i.e. that there isn't an empty line or any other element between both.

I'm using Ranges to get the rectangles (size and position) but there is a spacing between text nodes (the bottom of the first rect does not match the top of the second one).

I tried to calculate this spacing based on the line-height and font-size but I couldn't get the same value.

Here's a JsFiddle with my try: https://jsfiddle.net/3behsxxq/5/

Is there a way to calculate this spacing?

EDITED: In the first case of the jsFiddle code there are four lines ('first text', 'block', 'second', 'text block') that are visually consecutive, that is, visually the distance between them is the same, but the number that I get has a difference of 7 (in this first case). If I try to discard this space based on the difference between line-height/font-size and the values ​​of the range, they do not match, therefore I can not counteract it.

EDITED 2. Context: In the image below, the 6 lines have the same distance between them. I look for a way to determine that they are part of the same paragraph, regardless of the html structure (because the html could have a <p> element or any other element to represent the paragraph).

enter image description here

like image 945
jcbp Avatar asked Sep 01 '16 19:09

jcbp


1 Answers

var extractTextNodes = function(paragraph) {
  var nodes = [];
  function callback(node) {
    if (node.nodeType === Node.TEXT_NODE) {
      nodes.push(node);
    } else if (node.nodeType === Node.ELEMENT_NODE) {
      node.childNodes.forEach(callback);
    }
  }
  paragraph.childNodes.forEach(callback);
  return nodes;
};

var findParentParagraph = function(node) {
  var parent = node.parentElement;
  while (parent) {
    if (parent.tagName === "P") {
      return parent;
    }
    parent = parent.parentElement;
  }

  return null;
};

var areTextNodesSiblings = function(textNode1, textNode2) {
  var p = findParentParagraph(textNode1);
  if (!p) {
    return false;
  }

  var allTextNodes = extractTextNodes(p);
  var index1 = allTextNodes.indexOf(textNode1);
  var index2 = allTextNodes.indexOf(textNode2);
  if (index2 === -1) {
    return false;
  }
  return (index1 === index2 - 1) || (index1 === index2 + 1);
};

And just call areTextNodesSiblings by passing the nodes.

Fiddle: https://jsfiddle.net/krmnve37/1/


The title says "visually consecutive" but "EDITED 2. Context" says that nodes must be in the same paragraph. The following function will check if the two nodes are just in the same paragraph, not if they're next to each other:

var areTextNodesInTheSameParagraph = function(textNode1, textNode2) {
  var p = findParentParagraph(textNode1);
  if (!p) {
    return false;
  }

  var allTextNodes = extractTextNodes(p);
  var index1 = allTextNodes.indexOf(textNode1);
  var index2 = allTextNodes.indexOf(textNode2);
  return index1 > -1 || index2 > -1;
};
like image 193
Dimitar Nestorov Avatar answered Nov 05 '22 07:11

Dimitar Nestorov