All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.themillhousegroup.scoup.traits.DocumentPositioning.scala Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.themillhousegroup.scoup.traits

import org.jsoup.nodes.{ Element, Node }
import scala.annotation.tailrec

trait DocumentPositioning extends ElementTarget {

  /**
   * Logic:
   * - Recurse up my parents, recording the sibling index of each as an integer
   * - Reverse the order of the integer sequence. These are my "co-ordinates"
   * These can be used for before/after document position queries
   */
  lazy val documentCoordinates = coordinatesOf(Seq(), Some(target)).reverse

  @tailrec
  private def coordinatesOf(accum: Seq[Int], maybeElement: Option[Element]): Seq[Int] = {
    if (maybeElement.isEmpty) {
      accum
    } else {
      val elem = maybeElement.get
      coordinatesOf(accum :+ elem.siblingIndex, Option(elem.parent))
    }
  }

  private def compareCoordinates(maybeOther: Option[DocumentPositioning])(f: (Int, Int) => Boolean): Boolean = {
    maybeOther.fold(false) { other =>
      val zip = documentCoordinates.zipAll(other.documentCoordinates, 0, 0)

      val maybeFirstDiff = zip.dropWhile(dc => dc._1 == dc._2).headOption

      // A None here means co-ords are exactly the same
      maybeFirstDiff.fold(false) { diff =>
        f(diff._1, diff._2)
      }
    }
  }

  def isBefore(other: DocumentPositioning): Boolean =
    compareCoordinates(Option(other))((a, b) => a < b)

  def isAfter(other: DocumentPositioning): Boolean =
    compareCoordinates(Option(other))((a, b) => a > b)

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy