diff --git a/onpoint.js b/onpoint.js index 2935247..ce834ed 100644 --- a/onpoint.js +++ b/onpoint.js @@ -35,12 +35,15 @@ function goToSlide(index) { currentSlide = index; window.location.href = window.location.href.split('#')[0] + `#slide${index}`; - let oldActiveTopicLink = topicList.querySelector(`.${activeTopicLinkClass}`); - if (oldActiveTopicLink != null) { - oldActiveTopicLink.classList.remove(activeTopicLinkClass); - } - let newActiveTopicLink = topicList.querySelector(`[data-slide="slide${index}"]`); - newActiveTopicLink.classList.add(activeTopicLinkClass); + let oldActiveTopicLinks = topicList.querySelectorAll(`.${activeTopicLinkClass}`); + [...oldActiveTopicLinks].forEach(link => { + link.classList.remove(activeTopicLinkClass); + }); + + let newActiveTopicLinks = topicList.querySelectorAll(`[data-slide*=";slide${index};"]`); + [...newActiveTopicLinks].forEach(link => { + link.classList.add(activeTopicLinkClass); + }) } } @@ -114,36 +117,184 @@ function showPreviousFragment() { } } +/** + * Store for the headline nodes of each chapter. + */ +class HeadlineStore { + constructor() { + this.topLevelChildren = []; + } + + /** + * Add a new root node, i.e. the headline of a new chapter. + * @param {Node} node the level-1 headline node + */ + add(node) { + this.topLevelChildren.push(node); + } + + /** + * Generate a HTML list of all headline nodes stored in this structure. + */ + getHTML() { + let resultHTML = '' + } +} + +/** + * Data structure storing all headlines for the topic list. + * Each node knows its parents and children. + */ +class Node { + constructor(title, level, father, slide) { + this.children = []; + this.slidesWithSameTitle = []; + this.title = title; + this.level = level; + this.father = father; + this.slide = slide; + } + + /** + * Return the child that was added last among all childen. + */ + getLastChild() { + return this.children[this.children.length - 1]; + } + + /** + * Add a child node to this headline if the title of the new child node is + * different from the title of the node that was added last. + * This way, headlines are not added twice if they appear consecutively. + * @param {Node} node a subtitle node + * @return true, if the node was added, false otherwise + */ + addChildNode(node) { + if (!this.lastChildHasTitle(node.title)) { + this.children.push(node); + return true; + } else { + return false; + } + } + + /** + * Each headline can have more than one slide related to it. + * Consecutive headlines appear only ones in a dictionary, but they are still + * related to all slides. If there are three slides with title »Example« in a + * row, the node will have slide1 as its child and slide2 and slide3 as + * entries to the slidesWithSameTitle array. + * The goal of this is to ultimately highlight the node in the topic list not + * only when slide1 is active, but also for slide2 and slide3. + * @param {Integer} slide the ID of a related slide + */ + addSlideWithSameTitle(slide) { + this.slidesWithSameTitle.push(slide); + } + + /** + * Whether or not this node's last child has the given title. + * @param {String} title the slide's title + */ + lastChildHasTitle(title) { + let len = this.children.length; + return len > 0 && this.children[len - 1].title == title; + } + + /** + * Generate the HTML anchor content for this node (without any children). + */ + getLinkHTML() { + return `${this.title}` + } + + /** + * Generate a list item for the topic list with a sublist of all child nodes. + */ + getHTML() { + let resultHTML = `
  • ${this.getLinkHTML()}`; + + if (this.children.length > 0) { + resultHTML += + `` + } + + return resultHTML + '
  • '; + } +} + function getTopicListContent() { let results = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')]; - let resultHtml = `'; + currentLevel = level; + }); + + return resultHTML + headlineStore.getHTML(); } function createTopicList() {