- Commentboxes work (marginals) + mouseover

- Basic Briefe Controller
- Generic XML reader
This commit is contained in:
schnulller
2022-05-19 01:09:49 +02:00
parent f1743fcf39
commit 2ed7265869
23 changed files with 1179 additions and 193 deletions

View File

@@ -1,20 +1,81 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using HaWeb.Models;
using HaDocument.Interfaces;
using HaXMLReader.Interfaces;
using HaDocument.Models;
namespace HaWeb.Controllers;
public class Briefecontroller : Controller
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
[BindProperty(SupportsGet = true)]
public string? id { get; set; }
// DI
private ILibrary _lib;
private IReaderService _readerService;
public Briefecontroller(ILibrary lib, IReaderService readerService)
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
_lib = lib;
_readerService = readerService;
}
[Route("Briefe")]
[Route("Briefe/{id?}")]
public IActionResult Index(int? id) {
return View();
public IActionResult Index(string? id)
{
// Setup settings and variables
var url = "/Briefe/";
var defaultID = "1";
// Normalisation and Validation, (some) data aquisition
if (id == null) return Redirect(url + defaultID);
this.id = id.ToLower();
var preliminarymeta = _lib.Metas.Where(x => x.Value.Autopsic == this.id);
if (preliminarymeta == null || !preliminarymeta.Any()) return error404();
// Get all neccessary data
var index = preliminarymeta.First().Key;
var meta = preliminarymeta.First().Value;
var text = _lib.Letters.ContainsKey(index) ? _lib.Letters[index] : null;
var marginals = _lib.MarginalsByLetter.Contains(index) ? _lib.MarginalsByLetter[index] : null;
var tradition = _lib.Traditions.ContainsKey(index) ? _lib.Traditions[index] : null;
var editreasons = _lib.Editreasons.ContainsKey(index) ? _lib.EditreasonsByLetter[index] : null; // TODO: Order
var hands = _lib.Hands.ContainsKey(index) ? _lib.Hands[index] : null;
var nextmeta = meta != _lib.MetasByDate.Last() ? _lib.MetasByDate.ItemRef(_lib.MetasByDate.IndexOf(meta) + 1) : null;
var prevmeta = meta != _lib.MetasByDate.First() ? _lib.MetasByDate.ItemRef(_lib.MetasByDate.IndexOf(meta) - 1) : null;
// More Settings and variables
ViewData["Title"] = "Brief " + id.ToLower();
ViewData["SEODescription"] = "Johann Georg Hamann: Kommentierte Briefausgabe. Brief " + id.ToLower();
ViewData["Filename"] = "HKB_" + meta.Autopsic + ".pdf";
// Model creation
var model = new BriefeViewModel(this.id, index, generateMetaViewModel(meta));
if (nextmeta != null) model.Next = generateMetaViewModel(nextmeta);
if (prevmeta != null) model.Prev = generateMetaViewModel(prevmeta);
// Return
return View(model);
}
private IActionResult error404()
{
Response.StatusCode = 404;
return Redirect("/Error404");
}
private BriefeMetaViewModel generateMetaViewModel(Meta meta)
{
var senders = meta.Senders.Select(x => _lib.Persons[x].Name) ?? new List<string>();
var recivers = meta.Receivers.Select(x => _lib.Persons[x].Name) ?? new List<string>();
return new BriefeMetaViewModel(meta) {
ParsedSenders = HTMLHelpers.StringHelpers.GetEnumerationString(senders),
ParsedReceivers = HTMLHelpers.StringHelpers.GetEnumerationString(recivers)
};
}
}

View File

@@ -0,0 +1,420 @@
namespace HaWeb.HTMLHelpers;
using HaDocument.Interfaces;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using HaDocument.Models;
using System.Text;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
// Type aliasses for incredible long types
using TagFuncList = List<(Func<HaXMLReader.EvArgs.Tag, BriefeHelper, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Tag, BriefeHelper>)>;
using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, BriefeHelper, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Text, BriefeHelper>)>;
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, BriefeHelper, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace, BriefeHelper>)>;
public class BriefeHelper
{
// Input
private protected ILibrary Lib;
private protected IReaderService ReaderService;
private protected Meta Meta;
private protected Letter? Letter;
private protected Tradition? Tradition;
private protected ImmutableList<Hand>? Hands;
private protected ImmutableList<Editreason>? EditReasons;
private protected ImmutableList<Marginal>? Marginals;
// State
private protected string currline = "-1";
private protected string currpage = "";
private protected string oldpage = "";
private protected int commid = 1;
private protected bool active_firstedit = true;
private protected bool active_trad = false;
private protected bool active_skipwhitespace = true;
private protected bool active_del = false;
private protected List<string> handstrings = new List<string>();
// Parsing-Combinations
private protected StringBuilder sb_lettertext = new StringBuilder(); // Hauptext
private protected StringBuilder sb_linecount = new StringBuilder(); // Linke Spalte (Zeilenzählung)
private protected StringBuilder sb_marginals = new StringBuilder(); // Rechte Spalte (Kommentare)
private protected StringBuilder sb_tradition = new StringBuilder(); // Überlieferung
private protected StringBuilder sb_trad_zhtext = new StringBuilder(); // Überlieferung, ZHText
private protected StringBuilder sb_trad_left = new StringBuilder(); // Überlieferung ZHText linke Spalte (zeilenzählung)
private protected StringBuilder sb_trad_right = new StringBuilder(); // Überlieferung ZHText rechte Spalte (Kommentare)
private protected StringBuilder sb_edits = new StringBuilder(); // Edits
private protected IReader? rd_lettertext;
private protected IReader? rd_tradition;
// Parsing Rules
// General rules (for the lettertext column, also for parsing the marginals, awa tradtions and editreasons)
private static readonly TagFuncList OTag_Funcs = new TagFuncList() {
( ( x, _) => x.Name == "align" && x["pos"] == "center", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "align center")) ),
( ( x, _) => x.Name == "align" && x["pos"] == "right", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "align right")) ),
( ( x, _) => x.Name == "added", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "added")) ),
( ( x, _) => x.Name == "sal", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "sal")) ),
( ( x, _) => x.Name == "aq", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "aq")) ),
( ( x, _) => x.Name == "super", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "super")) ),
( ( x, _) => x.Name == "del", (sb, tag, bh) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "del"));
bh.active_del = true;
} ),
( ( x, _) => x.Name == "nr", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "nr")) ),
( ( x, _) => x.Name == "note", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "note")) ),
( ( x, _) => x.Name == "ul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "ul")) ),
( ( x, _) => x.Name == "anchor" && !String.IsNullOrWhiteSpace(x["ref"]), (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "anchor")) ),
( ( x, _) => x.Name == "fn" && !String.IsNullOrWhiteSpace(x["index"]), (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "footnote")) ),
( ( x, _) => x.Name == "dul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "dul")) ),
( ( x, _) => x.Name == "ful", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "ful")) ),
( ( x, _) => x.Name == "up", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "up")) ),
( ( x, _) => x.Name == "sub", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("sub")) ),
( ( x, _) => x.Name == "tul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "tul")) ),
( ( x, _) => x.Name == "header", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "header")) ),
( ( x, _) => x.Name == "lemma", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "lemma")) ),
( ( x, _) => x.Name == "eintrag", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "entry")) ),
( ( x, _) => x.Name == "titel", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "title")) ),
( ( x, _) => x.Name == "bzg", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "bzg")) ),
( ( x, _) => x.Name == "zh", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "zh")) ),
( ( x, _) => x.Name == "emph", (sb, tag, _) => { sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("em")); } ),
( ( x, _) => x.Name == "app", (sb, tag, _) => { sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "app")); } ),
( ( x, _) => x.Name == "subsection", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "subcomment", tag["id"])) ),
( ( x, _) => x.Name == "kommentar", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "comment", tag["id"])) ),
( ( x, _) => x.Name == "editreason", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "editreason")) ),
( ( x, _) => x.Name == "subsection", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "letter")) ),
( ( x, _) => x.Name == "letterTradition", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "tradition")) ),
( ( x, _) => x.Name == "marginal", (sb, tag, bh) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "marginal"));
bh.active_skipwhitespace = !bh.active_skipwhitespace;
}),
( ( x, _) => x.Name == "hand", (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "hand"));
} ),
( ( x, _) => x.Name == "tabs", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "htable")) ),
( ( x, _) => x.Name == "tab" && !String.IsNullOrWhiteSpace(x["value"]), (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "htab htab-" + tag["value"])))
};
public BriefeHelper(ILibrary lib, IReaderService readerService, Meta meta, Letter? letter, Tradition? tradition, ImmutableList<Hand>? hands, ImmutableList<Editreason> editreasons, ImmutableList<Marginal> marginals)
{
Lib = lib;
ReaderService = readerService;
Letter = letter;
Meta = meta;
Tradition = tradition;
Hands = hands;
EditReasons = editreasons;
Marginals = marginals;
initState();
}
private void initState()
{
rd_lettertext = Letter != null && !String.IsNullOrWhiteSpace(Letter.Element) ? ReaderService.RequestStringReader(Letter.Element) : null;
rd_tradition = Tradition != null && !String.IsNullOrWhiteSpace(Tradition.Element) ? ReaderService.RequestStringReader(Tradition.Element) : null;
if (Meta.ZH != null)
{
currpage = Meta.ZH.Page;
}
if (Hands != null)
{
foreach (var hand in Hands.OrderBy(x => x.StartPage.Length).ThenBy(x => x.StartPage).ThenBy(x => x.StartLine.Length).ThenBy(x => x.StartLine))
{
var currstring = hand.StartPage + "/" + hand.StartLine;
if (hand.StartPage != hand.EndPage)
{
currstring += "" + hand.EndPage + "/" + hand.EndLine;
}
else
{
if (hand.StartLine != hand.EndLine)
{
currstring += "" + hand.EndLine;
}
}
if (Lib.HandPersons.Where(x => x.Key == hand.Person).Any())
{
currstring += " " + Lib.HandPersons.Where(x => x.Key == hand.Person).FirstOrDefault().Value.Name;
handstrings.Add(currstring);
}
}
}
}
public void CreateHTML()
{
var CTag_Funcs = new TagFuncList() {
( ( x, _) => x.Name == "align", (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
} ),
( ( x, _) => x.Name == "added", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "sal", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "aq", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "super", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "del", (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
active_del = false;
} ),
( ( x, _) => x.Name == "nr", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "note", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "ul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "anchor", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "fn", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "dul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "up", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "ful", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "sub", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("sub")) ),
( ( x, _) => x.Name == "tul", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "header", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "lemma", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "eintrag", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "titel", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "bzg", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "zh", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "emph", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("em")) ),
( ( x, _) => x.Name == "app", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span")) ),
( ( x, _) => x.Name == "subsection", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "kommentar", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "editreason", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "subsection", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "letterTradition", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "marginal", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "tabs", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "tab", (sb, tag, _) => sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div")) ),
( ( x, _) => x.Name == "hand", (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
} )
};
var Text_Funcs = new TextFuncList() {
( ( x, _) => true, ( sb, txt, _) => {
if (active_del)
sb.Append(txt.Value.Replace("", "<span class=\"diagdel\"></span>"));
else
sb.Append(txt.Value);
} )
};
var Text_Funcs_Tagging = new TextFuncList() {
( ( _, _) => true, ( sb, txt, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "ntext"));
sb.Append(txt.Value);
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
} )
};
var STag_Funcs = new TagFuncList() {
( ( x, _) => x.Name == "line", (sb, tag, _) => {
if(currline != "-1") sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "ZHBreak"));
if(tag["type"] == "line") sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("hr", "lineline"));
} ),
( ( x, _) => x.Name == "line" && !String.IsNullOrWhiteSpace(x["tab"]), (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "tab-" + tag["tab"]));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
} )
};
var Whitespace_Funcs = new WhitespaceFuncList() {
( ( _, _) => true, ( sb, txt, _) => {
if (active_skipwhitespace)
sb.Append(txt.Value);
else
active_skipwhitespace = !active_skipwhitespace;
})
};
// Rules for the left sidebar
var STag_Funcs_LEFT = new TagFuncList() {
( ( x, _) => x.Name == "line", (sb, tag, _) => {
if(currline != "-1") {
if (currpage == oldpage)
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "", currpage + "-" + currline));
else {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "", oldpage + "-" + currline));
oldpage = currpage;
}
}
else {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "zhpage firstpage", currpage + "-" + tag["index"]));
sb.Append("S." + "&nbsp;");
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
if (tag["index"] != "1")
sb.Append(currpage + "&thinsp;/&thinsp;" + tag["index"]);
else
sb.Append(currpage);
oldpage = currpage;
}
}),
( ( x, _) => x.Name == "line", (sb, tag, _) => { if(currline != "-1" && Int32.TryParse(tag["index"], out var _) && Int32.Parse(tag["index"]) % 5 == 0) { sb.Append(tag["index"]); } } ),
( ( x, _) => x.Name == "line" && x["index"] == "1" && currline != "-1", (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "zhpage", ""));
sb.Append("S. " + currpage);
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
}),
( ( x, _) => x.Name == "line", (sb, tag, _) => { currline = tag["index"]; } ),
( ( x, _) => x.Name == "page", (sb, tag, _) => { currpage = tag["index"]; } )
};
// Rules for the right sidebar
var STag_Funcs_RIGHT = new TagFuncList() {
( ( x, _) => x.Name == "line", (sb, tag, _) => {
if(currline != "-1" && Marginals != null) {
var margs = Marginals.Where(x => x.Page == currpage && x.Line == currline);
if (margs != null && margs.Any())
{
margs = margs.OrderBy(x => Int32.Parse(x.Index));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "commBox", commid.ToString()));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "commselector"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("button", "button"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("button"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "comment"));
foreach (var marginal in margs)
{
var rd = ReaderService.RequestStringReader(marginal.Element);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd, sb, OTag_Funcs, null, CTag_Funcs, Text_Funcs_Tagging, Whitespace_Funcs);
new HaWeb.HTMLHelpers.LinkHelper(Lib, rd, sb, false);
rd.Read();
}
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br"));
}
else
{
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "emptyline"));
}
}
commid++;
}
)};
// Rules for traditions
var OTag_Funcs_Trad = new TagFuncList() {
( ( x, _) => x.Name == "app", (sb, tag, _) => { if (!active_firstedit) { sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br")); } else { active_firstedit = false; } } ),
( ( x, _) => x.Name == "ZHText", (sb, tag, _) => {
sb_tradition.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "row zhtext"));
sb_tradition.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "trad-text col order-2 letterbox"));
sb_trad_left = new StringBuilder();
sb_trad_right = new StringBuilder();
currline = "-1";
currpage = "";
active_trad = true;
sb_trad_left.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "trad-linecount countbox nnumber d-none d-lg-block order-1"));
sb_trad_right.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "commentColumn trad-comm col-4 d-none d-lg-block order-3"));
sb_trad_right.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "emptyline"));
if (rd_tradition != null) {
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_tradition, sb_trad_left, null, STag_Funcs_LEFT);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_tradition, sb_trad_right, null, STag_Funcs_RIGHT);
}
} )
};
var CTag_Funcs_Trad = new TagFuncList() {
( ( x, _) => x.Name == "ZHText", (sb, tag, _) => {
sb_tradition.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb_trad_left.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb_trad_right.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
sb_tradition.Append(sb_trad_left.ToString());
sb_tradition.Append(sb_trad_right.ToString());
sb_tradition.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
active_trad = false;
} )
};
var STags_Funcs_TRAD = new TagFuncList() {
( ( x, _) => x.Name == "line", (sb, tag, _) => { if(currline != "-1" || !active_trad) sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("br", "ZHBreak")); } ),
( ( x, _) => x.Name == "line" && !String.IsNullOrWhiteSpace(x["tab"]), (sb, tag, _) => {
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "tab-" + tag["tab"]));
sb.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
} )
};
// Rules for Edits:
var STags_Funcs_EDIT = new TagFuncList() {
( ( x, _) => x.Name == "line", (sb, tag, _) => sb.Append("&emsp;") )
};
string HandleEdit(Editreason edit)
{
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("div", "edit"));
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "pageline"));
var currstring = edit.StartPage + "/" + edit.StartLine;
if (edit.StartPage != edit.EndPage)
{
currstring += "" + edit.EndPage + "/" + edit.EndLine;
}
else
{
if (edit.StartLine != edit.EndLine)
{
currstring += "" + edit.EndLine;
}
}
sb_edits.Append(currstring + "&emsp;");
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
if (!String.IsNullOrWhiteSpace(edit.Reference))
{
var sb2 = new StringBuilder();
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "reference"));
var rd = ReaderService.RequestStringReader(edit.Reference);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd, sb2, OTag_Funcs, null, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
rd.Read();
sb2.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
if ((edit.StartPage != edit.EndPage || edit.StartLine != edit.EndLine) && XElement.Parse(sb2.ToString()).Value.ToString().Length >= 60)
{
var text = XElement.Parse(sb2.ToString()).Value.ToString();
text = text.ToString().Split(' ').Take(1).First() + " [&#x2026;] " + text.ToString().Split(' ').TakeLast(1).First();
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "reference"));
sb_edits.Append(text);
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
}
else
sb_edits.Append(sb2);
}
if (!String.IsNullOrWhiteSpace(edit.Element))
{
sb_edits.Append("&emsp;");
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateElement("span", "corrections"));
var rd = ReaderService.RequestStringReader(edit.Element);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd, sb_edits, OTag_Funcs, STags_Funcs_EDIT, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
rd.Read();
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("span"));
}
sb_edits.Append(HaWeb.HTMLHelpers.TagHelpers.CreateEndElement("div"));
return sb_edits.ToString();
}
// Actual parsing
if (Letter != null && Letter.Element != null && !String.IsNullOrWhiteSpace(Letter.Element) && rd_lettertext != null)
{
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_lettertext, sb_lettertext, OTag_Funcs, STag_Funcs, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_lettertext, sb_linecount, null, STag_Funcs_LEFT);
if (Marginals != null && Marginals.Any())
{
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_lettertext, sb_marginals, null, STag_Funcs_RIGHT);
}
rd_lettertext.Read();
}
if (Tradition != null && !String.IsNullOrWhiteSpace(Tradition.Element) && rd_tradition != null)
{
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_tradition, sb_tradition, OTag_Funcs_Trad, null, CTag_Funcs_Trad, null, null);
new HaWeb.HTMLHelpers.GenericXMLHelper<BriefeHelper>(this, rd_tradition, sb_tradition, OTag_Funcs, STags_Funcs_TRAD, CTag_Funcs, Text_Funcs, Whitespace_Funcs);
new HaWeb.HTMLHelpers.LinkHelper(Lib, rd_tradition, sb_tradition);
rd_tradition.Read();
}
if (EditReasons != null && EditReasons.Any())
{
foreach (var edit in EditReasons)
{
HandleEdit(edit);
}
}
}
}

View File

@@ -5,38 +5,45 @@ using HaXMLReader.EvArgs;
using HaDocument.Models;
using System.Text;
// Type aliasses for incredible long types
using TagFuncList = List<(Func<HaXMLReader.EvArgs.Tag, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Tag>)>;
using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Text>)>;
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace>)>;
public static class CommentHelpers
{
private static readonly string DEFAULTELEMENT = HaWeb.Settings.ParsingSettings.DEFAULTELEMENT;
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
private static readonly string LEMMACLASS = HaWeb.Settings.CSSClasses.LEMMACLASS;
private static readonly string TITLECLASS = HaWeb.Settings.CSSClasses.TITLECLASS;
private static readonly string BACKLINKSCLASS = HaWeb.Settings.CSSClasses.BACKLINKSCLASS;
private static readonly string LETLINKCLASS = HaWeb.Settings.CSSClasses.LETLINKCLASS;
private static readonly string COMMENTHEADCLASS = HaWeb.Settings.CSSClasses.COMMENTHEADCLASS;
private static readonly string COMMENTBODYCLASS = HaWeb.Settings.CSSClasses.COMMENTBODYCLASS;
private static readonly string BACKLINKSHKBCLASS = HaWeb.Settings.CSSClasses.BACKLINKSHKBCLASS;
// Parsing Rules
private static readonly List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _OTagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
private static readonly TagFuncList _OTagFuncs = new TagFuncList() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, LEMMACLASS))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS)))
};
private static readonly List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _CTagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
private static readonly TagFuncList _CTagFuncs = new TagFuncList() {
( x => x.Name == "lemma", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT))),
( x => x.Name == "title", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT))),
( x => x.Name == "titel", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT)))
};
private static readonly List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> _STagFuncs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
private static readonly TagFuncList _STagFuncs = new TagFuncList() {
( x => x.Name == "line", (sb, tag) => sb.Append(HTMLHelpers.TagHelpers.CreateElement("br")) )
};
private static readonly List<(Func<Text, bool>, Action<StringBuilder, Text>)> _TextFuncs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
private static readonly TextFuncList _TextFuncs = new TextFuncList() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
private static readonly List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)> _WhitespaceFuncs = new List<(Func<Whitespace, bool>, Action<StringBuilder, Whitespace>)>() {
private static readonly WhitespaceFuncList _WhitespaceFuncs = new WhitespaceFuncList() {
( x => true, ( sb, txt ) => sb.Append(txt.Value) )
};
@@ -63,7 +70,9 @@ public static class CommentHelpers
{
if (!arrow)
{
sb.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, BACKLINKSHKBCLASS));
sb.Append("HKB&nbsp;");
sb.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT));
arrow = true;
}
sb.Append(HTMLHelpers.TagHelpers.CreateElement("a", LETLINKCLASS, "/Briefe/" + let.Autopsic + "#" + blk.Page + "-" + blk.Line));

View File

@@ -0,0 +1,116 @@
namespace HaWeb.HTMLHelpers;
using HaXMLReader.Interfaces;
using HaXMLReader.EvArgs;
using System.Text;
using System.Collections.Generic;
using System;
public class GenericXMLHelper<T>
{
private T _caller;
private IReader _in;
private StringBuilder _target;
private List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? _OTag_Funcs;
private List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? _STag_Funcs;
private List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? _CTag_Funcs;
private List<(Func<Text, T, bool>, Action<StringBuilder, Text, T>)>? _Text_Funcs;
private List<(Func<Whitespace, T, bool>, Action<StringBuilder, Whitespace, T>)>? _WS_Funcs;
private bool _deleteLeadingWS;
private bool _deleteTrailingWS;
public GenericXMLHelper(
T caller,
IReader input,
StringBuilder target,
List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? OTag_Funcs = null,
List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? STag_Funcs = null,
List<(Func<Tag, T, bool>, Action<StringBuilder, Tag, T>)>? CTag_Funcs = null,
List<(Func<Text, T, bool>, Action<StringBuilder, Text, T>)>? Text_Funcs = null,
List<(Func<Whitespace, T, bool>, Action<StringBuilder, Whitespace, T>)>? WS_Funcs = null,
bool deleteLeadingWS = false,
bool deleteTrailingWS = false
)
{
if (input == null || target == null || caller == null) throw new ArgumentNullException();
_caller = caller;
_in = input;
_target = target;
_deleteLeadingWS = deleteLeadingWS;
_deleteTrailingWS = deleteTrailingWS;
_OTag_Funcs = OTag_Funcs;
_STag_Funcs = STag_Funcs;
_CTag_Funcs = CTag_Funcs;
_Text_Funcs = Text_Funcs;
_WS_Funcs = WS_Funcs;
if (_OTag_Funcs != null)
_in.OpenTag += OnOTag;
if (_STag_Funcs != null)
_in.SingleTag += OnSTag;
if (_CTag_Funcs != null)
_in.CloseTag += OnCTag;
if (_Text_Funcs != null)
_in.Text += OnText;
if (_WS_Funcs != null)
_in.Whitespace += OnWS;
}
void OnOTag(object _, Tag tag)
{
if (_OTag_Funcs != null)
foreach (var entry in _OTag_Funcs)
if (entry.Item1(tag, _caller)) entry.Item2(_target, tag, _caller);
}
void OnText(object _, Text text)
{
if (_deleteLeadingWS) text.Value = text.Value.TrimStart();
if (_deleteTrailingWS) text.Value = text.Value.TrimEnd();
foreach (var entry in _Text_Funcs)
if (entry.Item1(text, _caller)) entry.Item2(_target, text, _caller);
}
void OnSTag(object _, Tag tag)
{
foreach (var entry in _STag_Funcs)
if (entry.Item1(tag, _caller)) entry.Item2(_target, tag, _caller);
}
void OnCTag(object _, Tag tag)
{
foreach (var entry in _CTag_Funcs)
if (entry.Item1(tag, _caller)) entry.Item2(_target, tag, _caller);
}
void OnWS(object _, Whitespace ws)
{
foreach (var entry in _WS_Funcs)
{
if (entry.Item1(ws, _caller)) entry.Item2(_target, ws, _caller);
}
}
internal void Dispose()
{
if (_in != null)
{
if (_OTag_Funcs != null)
_in.OpenTag -= OnOTag;
if (_STag_Funcs != null)
_in.SingleTag -= OnSTag;
if (_CTag_Funcs != null)
_in.CloseTag -= OnCTag;
if (_Text_Funcs != null)
_in.Text -= OnText;
if (_WS_Funcs != null)
_in.Whitespace -= OnWS;
}
}
~GenericXMLHelper()
{
Dispose();
}
}

View File

@@ -8,6 +8,12 @@ using HaXMLReader.EvArgs;
using HaXMLReader;
using System.Collections.Generic;
// Type aliasses for incredible long types
using TagFuncList = List<(Func<HaXMLReader.EvArgs.Tag, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Tag>)>;
using TextFuncList = List<(Func<HaXMLReader.EvArgs.Text, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Text>)>;
using WhitespaceFuncList = List<(Func<HaXMLReader.EvArgs.Whitespace, bool>, Action<System.Text.StringBuilder, HaXMLReader.EvArgs.Whitespace>)>;
public class LinkHelper {
private ILibrary _lib;
private IReader _reader;
@@ -16,7 +22,7 @@ public class LinkHelper {
private bool _followlinksinchildren;
private bool _followlinksinthis;
private static readonly string DEFAULTELEMENT = HaWeb.Settings.ParsingSettings.DEFAULTELEMENT;
private static readonly string DEFAULTELEMENT = HaWeb.Settings.HTML.DEFAULTELEMENT;
private static readonly string LETLINKCLASS = HaWeb.Settings.CSSClasses.LETLINKCLASS;
private static readonly string REFLINKCLASS = HaWeb.Settings.CSSClasses.REFLINKCLASS;
private static readonly string WWWLINKCLASS = HaWeb.Settings.CSSClasses.WWWLINKCLASS;
@@ -24,19 +30,19 @@ public class LinkHelper {
private static readonly string TITLECLASS = HaWeb.Settings.CSSClasses.TITLECLASS;
// Parsing Rules for inserting lemmas
private static readonly List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> OTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, INSERTEDLEMMACLASS)) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS)) ),
( x => x.Name == "title", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS)) )
private static readonly TagFuncList OTag_Funcs = new TagFuncList() {
( x => x.Name == "lemma", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, INSERTEDLEMMACLASS)) ),
( x => x.Name == "titel", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS)) ),
( x => x.Name == "title", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT, TITLECLASS)) )
};
private static readonly List<(Func<Tag, bool>, Action<StringBuilder, Tag>)> CTag_Funcs = new List<(Func<Tag, bool>, Action<StringBuilder, Tag>)>() {
( x => x.Name == "lemma", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT)) ),
( x => x.Name == "titel", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT)) ),
( x => x.Name == "title", (strbd, x) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT)) )
private static readonly TagFuncList CTag_Funcs = new TagFuncList() {
( x => x.Name == "lemma", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT)) ),
( x => x.Name == "titel", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateEndElement(DEFAULTELEMENT)) ),
( x => x.Name == "title", (strbd, _) => strbd.Append(HTMLHelpers.TagHelpers.CreateElement(DEFAULTELEMENT)) )
};
private static readonly List<(Func<Text, bool>, Action<StringBuilder, Text>)> Text_Funcs = new List<(Func<Text, bool>, Action<StringBuilder, Text>)>() {
private static readonly TextFuncList Text_Funcs = new TextFuncList() {
( x => true, (strbd, txt) => strbd.Append(txt.Value))
};

View File

@@ -1,6 +1,6 @@
namespace HaWeb.HTMLHelpers;
public static class StringHelpers {
public static string GetEnumerationString(List<string> strlist)
public static string GetEnumerationString(IEnumerable<string> strlist)
{
var res = "";
foreach (var str in strlist)

View File

@@ -29,7 +29,7 @@ public class XMLHelper
bool deleteTrailingWS = false
)
{
if (input == null || target == null) throw new ArgumentNullException();
if (input == null || target == null ) throw new ArgumentNullException();
_in = input;
_target = target;

View File

@@ -0,0 +1,15 @@
namespace HaWeb.Models;
using HaDocument.Models;
public class BriefeMetaViewModel
{
public Meta Meta { get; private set; }
public string? ParsedSenders { get; set; }
public string? ParsedReceivers { get; set; }
public BriefeMetaViewModel(Meta meta)
{
Meta = meta;
}
}

View File

@@ -0,0 +1,24 @@
namespace HaWeb.Models;
public class BriefeViewModel
{
public string Id { get; private set; }
public string Index { get; private set; }
public BriefeMetaViewModel Meta { get; private set; }
public string? ParsedText { get; set; }
public string? ParsedLineCount { get; set; }
public string? ParsedMarginals { get; set; }
public string? ParsedTradition { get; set; }
public string? ParsedEdits { get; set; }
public BriefeMetaViewModel? Next { get; set; }
public BriefeMetaViewModel? Prev { get; set; }
public BriefeViewModel(string id, string index, BriefeMetaViewModel meta)
{
Id = id;
Index = index;
Meta = meta;
}
}

View File

@@ -1,5 +1,4 @@
namespace HaWeb.Models;
using HaDocument.Models;
public class RegisterViewModel {
public string Category { get; private set; }
@@ -8,7 +7,6 @@ public class RegisterViewModel {
public string? Search { get; set; } = null;
public bool? MaxSearch { get; set; } = null;
// TODO: no null-checks in the Page Logic
public List<CommentModel> ParsedComments { get; private set; }
public List<(string, string)>? AvailableCategories { get; set; } = null;
public List<(string, string)>? AvailableSideCategories { get; set; } = null;

View File

@@ -31,8 +31,8 @@ app.MapControllers();
app.Run();
class Options : IHaDocumentOptions {
public string HamannXMLFilePath { get; set; } = @"Hamann.xml";
public string[] AvailableVolumes { get; set; } = { };
public bool NormalizeWhitespace { get; set; } = true;
public (int, int) AvailableYearRange {get; set; } = (1751, 1788);
public string HamannXMLFilePath { get; set; } = HaWeb.Settings.General.XMLFILEPATH;
public string[] AvailableVolumes { get; set; } = HaWeb.Settings.General.AVAILABLEVOLUMES;
public bool NormalizeWhitespace { get; set; } = HaWeb.Settings.General.NORMALIZEWHITESPACE;
public (int, int) AvailableYearRange {get; set; } = HaWeb.Settings.General.AVAILABLEYEARRANGE;
}

View File

@@ -1,9 +1,11 @@
namespace HaWeb.Settings;
public static class CSSClasses {
// Classes generated by parsing the XML:
public const string LEMMACLASS = "ha-lemma"; // XML: <lemma>
public const string TITLECLASS = "ha-title"; // XML: <title>
public const string BACKLINKSCLASS = "ha-letlinks"; // Collection containing links to references in letters
public const string BACKLINKSHKBCLASS = "ha-hkb"; // HKB-Text infront of l;ink collection
public const string COMMENTHEADCLASS = "ha-commenthead"; // Head of a comment, containing lemma and backlinks
public const string COMMENTBODYCLASS = "ha-commentbody"; // Body of a comment, contasining the text
@@ -13,4 +15,11 @@ public static class CSSClasses {
public const string INSERTEDLEMMACLASS = "ha-insertedlemma"; // XML <link linktext="true"></link>
// TODO Classes used in Razor Pages:
// TODO Classes used in Javascript:
// TODO IDs used by JavaScript:
}

View File

@@ -0,0 +1,9 @@
namespace HaWeb.Settings;
public static class General {
// Classes generated by parsing the XML:
public const string XMLFILEPATH = @"Hamann.xml";
public const bool NORMALIZEWHITESPACE = true;
public static (int, int) AVAILABLEYEARRANGE = (1751, 1788);
public static string[] AVAILABLEVOLUMES = { };
}

View File

@@ -1,5 +1,5 @@
namespace HaWeb.Settings;
public static class ParsingSettings {
public static class HTML {
public const string DEFAULTELEMENT = "div"; // Every tag gets replaced by a div, except fpr link or wwwlink
}

View File

@@ -0,0 +1,2 @@
@model BriefeViewModel;

View File

@@ -11,12 +11,12 @@
Dr. Gregor Babelotzky (seit 2019)<br/>
Konrad Bucher (seit 2019)<br/>
Christian Großmann (20182019)<br/>
Carl Friedrich Haak (20132018)<br/>
Carl Friedrich Haak (20142018)<br/>
Leonard Keidel (seit 2018)<br/>
Luca Klopfer (seit 2016)<br/>
Johannes Knüchel (20162020)<br/>
Isabel Langkabel (20132019)<br/>
Simon Martens (20132018)<br/>
Isabel Langkabel (20142019)<br/>
Simon Martens (20142018)<br/>
Dr. Janina Reibold (Leitung seit 2013)
<h3>Technische Umsetzung</h3>

View File

@@ -1,5 +1,4 @@
@model RegisterViewModel;
@using System.Diagnostics;
@* Generated classes by CommentHelper.cs:
- .ha-letlink .ha-wwwlink .ha-reflink: Links to letters, the web, the reference
@@ -9,7 +8,14 @@
- .ha-commenthead: Class containing the head of a comment, lemma and backlinks
- .ha-commentbody: Body of a comment, containing the comments text
- .ha-letlinks: Collection of references in the comment within the marginals
- .ha-hkb: HKB that is in front of those links
- .ha-insertedlemma: automatically generated and inserted lemma
Generated classes by JavaScript:
- .ha-collapsed-box, .ha-expanded-box: for an expanded or collapsed comment box
- .ha-open-btn-collapsed-box, ha-close-btn-collapsed-box: for open- & close buttons for the boxes
- .ha-btn-collapsed-box: for the button itself
- .ha-collapsed-box-manually-toggled: for a manually (not on mousehover) toggled button
*@
@{

View File

@@ -0,0 +1,101 @@
@* Javascript gets inlined because it ain't much (but it's honest work) *@
@* Only put PRODUCTION JavaScript here *@
<script>
const openmenu = function () {
var x = document.getElementById("ha-topnav");
if (x !== null) x.className += " ha-topnav-collapsed";
let oldbutton = document.getElementById("openmenubutton");
if (oldbutton !== null) oldbutton.setAttribute('class', 'hidden');
let newbutton = document.getElementById("closemenubutton");
if (newbutton !== null) newbutton.setAttribute('class', '');
}
const closemenu = function () {
var x = document.getElementById("ha-topnav");
if (x !== null) x.className = "ha-topnav";
let oldbutton = document.getElementById("closemenubutton");
if (oldbutton !== null) oldbutton.setAttribute('class', 'hidden');
let newbutton = document.getElementById("openmenubutton");
if (newbutton !== null) newbutton.setAttribute('class', '');
}
const markactive_startswith = function (element) {
// Marks links as active which target URL starts with the current URL
var all_links = element.getElementsByTagName("a"),
i = 0, len = all_links.length,
full_path = location.href.split('#')[0].toLowerCase(); //Ignore hashes
for (; i < len; i++) {
if (full_path.startsWith(all_links[i].href.toLowerCase())) {
all_links[i].className += " active";
}
}
}
const markactive_exact = function (element) {
var all_links = element.getElementsByTagName("a"),
i = 0, len = all_links.length,
full_path = location.href.split('#')[0].toLowerCase(); //Ignore hashes
for (; i < len; i++) {
if (full_path == all_links[i].href.toLowerCase()) {
all_links[i].className += " active";
}
}
}
const getLineHeight = function (element) {
var temp = document.createElement(element.nodeName), ret;
temp.setAttribute("class", element.className);
temp.innerHTML = "A";
element.parentNode.appendChild(temp);
ret = temp.clientHeight;
temp.parentNode.removeChild(temp);
return ret;
}
/* TODO: need a resize watcher to undo and reapply the effect on breakpoint */
const overlappingboxcollapse = function (selector) {
let boxes = document.querySelectorAll(selector);
let clientrects = [];
let lineheight = 1;
if (boxes.length >= 1) {
lineheight = getLineHeight(boxes[0]);
}
for (element of boxes) {
clientrects.push([element, element.getBoundingClientRect()]);
}
for (var i = 0; i < clientrects.length; i++) {
if (i < clientrects.length-1) {
if (clientrects[i][1].bottom >= clientrects[i+1][1].top) {
let overlap = clientrects[i][1].bottom - clientrects[i+1][1].top;
let newlength = clientrects[i][1].height - overlap;
let remainder = newlength % lineheight;
newlength = newlength - remainder;
clientrects[i][0].style.height = newlength + 'px';
clientrects[i][0].style.overflowX = "hidden";
clientrects[i][0].style.overflowY = "scroll";
}
}
}
}
window.addEventListener('load', function() {
document.getElementById("openmenubutton").addEventListener('click', openmenu);
document.getElementById("closemenubutton").addEventListener('click', closemenu);
markactive_startswith(document.getElementById("ha-topnav"));
markactive_exact(document.getElementById("ha-register-nav"));
overlappingboxcollapse(".ha-neuzeit .ha-letlinks");
overlappingboxcollapse(".ha-forschung .ha-letlinks");
})
</script>

View File

@@ -9,12 +9,22 @@
<title>HKB: @ViewData["Title"]</title>
<!-- crossorigin is a workaround to prevent double downloading bugs in chrome -->
<link rel="preload" href="/css/output.css" as="style" />
<link rel="preload" href="/img/subtlenet2.png" as="image" />
<link rel="preload" href="/fonts/LinBiolinum_R_G.ttf" as="font" crossorigin/>
<!-- also, the graphite versions of the font are available for use:
<link rel="preload" href="/fonts/LinLibertine_R_G.ttf" as="font" crossorigin/>
<link rel="preload" href="/fonts/LinBiolinum_R_G.ttf" as="font" crossorigin/>
-->
<link rel="preload" href="/css/output.css" as="style" asp-append-version="true"/>
<link rel="preload" href="/img/subtlenet2.png" as="image" />
<link rel="preload" href="/fonts/LinBiolinum_R.woff" as="font" crossorigin/>
<link rel="preload" href="/fonts/LinLibertine_R.woff" as="font" crossorigin/>
<link rel="preload" href="/fonts/LinLibertine_RI.woff" as="font" crossorigin/>
<link rel="preload" href="/fonts/LinLibertine_RB.woff" as="font" crossorigin/>
<link rel="stylesheet" href="/css/output.css" />
<link rel="stylesheet" href="/css/output.css" asp-append-version="true" />
<environment include="Development">
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
</head>
@@ -25,10 +35,11 @@
@RenderBody()
</main>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
@await Html.PartialAsync("/Views/Shared/_Footer.cshtml")
<environment exclude="Development">
@await Html.PartialAsync("/Views/Shared/_Javascript.cshtml")
</environment>
</body>
</html>

View File

@@ -1,3 +1,4 @@
@using HaWeb
@using HaWeb.Models
@using HaWeb.Settings
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@@ -468,6 +468,8 @@ Ensure the default browser behavior of the `hidden` attribute.
--tw-backdrop-sepia: ;
}
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
body {
height: 100%;
width: 100%;
@@ -808,6 +810,8 @@ body {
.ha-register .ha-register-head {
border-bottom-width: 2px;
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.ha-register .ha-register-head h1 {
@@ -855,6 +859,8 @@ body {
.ha-register .ha-register-head .ha-register-nav a.active {
border-bottom-width: 2px;
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.ha-register .ha-register-head .ha-register-nav .ha-register-left-nav {
@@ -967,30 +973,29 @@ body {
}
}
.ha-register .ha-neuzeit .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
padding-left: 0.5rem;
.ha-register .ha-register-body .ha-comment .ha-commenthead .ha-letlinks .ha-hkb {
display: inline;
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
@media (min-width: 1190px) {
.ha-register .ha-neuzeit .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
position: absolute;
left: 48rem;
top: 0px;
display: block;
width: 20rem;
border-left-width: 2px;
text-indent: 0px;
}
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks {
left: 46rem;
}
}
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-letlinks {
padding-left: 0.5rem;
}
@media (min-width: 1190px) {
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-letlinks, .ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-letlinks {
position: absolute;
left: 46rem;
top: 0px;
display: block;
width: 20rem;
@@ -1190,12 +1195,55 @@ body {
}
}
.pointer-events-none {
pointer-events: none;
.ha-register .ha-headcomment .ha-btn-collapsed-box {
left: 47.6rem;
}
.static {
position: static;
.ha-register .ha-subcomment .ha-btn-collapsed-box {
left: 45.6rem;
}
.ha-register .ha-btn-collapsed-box {
position: absolute;
top: -0.25rem;
display: none;
cursor: pointer;
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
.ha-register .ha-btn-collapsed-box:hover {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
@media (min-width: 1190px) {
.ha-register .ha-btn-collapsed-box {
display: block;
}
}
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-collapsed-box, .ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-collapsed-box {
z-index: 0;
overflow: hidden;
}
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-expanded-box, .ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-expanded-box {
z-index: 1000;
height: auto !important;
max-height: 100vh !important;
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
/* .ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-collapsed-box:hover,
.ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-collapsed-box:hover {
@apply shadow-md z-[1000] !h-auto
} */
.pointer-events-none {
pointer-events: none;
}
.sticky {
@@ -1286,6 +1334,10 @@ body {
cursor: default;
}
.resize {
resize: both;
}
.list-disc {
list-style-type: disc;
}
@@ -1391,12 +1443,12 @@ body {
color: rgb(0 0 0 / var(--tw-text-opacity));
}
/* Regular woff-files for regular font variants
Instead we use the Graphite versions of the font currently
/* Regular woff-files for regular font variants curerently
Instead we can use the Graphite versions of the font
@font-face {
font-family: 'Biolinum';
src: url('../fonts/LinBiolinum_R.woff') format('woff');
src: url('/fonts/LinBiolinum_R_G.ttf') format('truetype');
font-display: swap;
font-weight: normal;
font-style: normal;
@@ -1404,7 +1456,7 @@ body {
@font-face {
font-family: 'Libertine';
src: url('../fonts/LinLibertine_R.woff') format('woff');
src: url('/fonts/LinLibertine_R_G.ttf') format('truetype');
font-display: swap;
font-weight: normal;
font-style: normal;
@@ -1415,7 +1467,7 @@ body {
@font-face {
font-family: 'Biolinum';
src: url('/fonts/LinBiolinum_R_G.ttf') format('truetype');
src: url('../fonts/LinBiolinum_R.woff') format('woff');
font-display: swap;
@@ -1427,7 +1479,7 @@ body {
@font-face {
font-family: 'Libertine';
src: url('/fonts/LinLibertine_R_G.ttf') format('truetype');
src: url('../fonts/LinLibertine_R.woff') format('woff');
font-display: swap;
@@ -1510,6 +1562,10 @@ body {
list-style-type:circle;
} */
.downshadow-sm {
box-shadow: 5px 6px 5px -7px rgba(0,0,0,0.79);
}
.hyphenate {
-webkit-hyphens: auto;
-ms-hyphens: auto;
@@ -1570,14 +1626,24 @@ body {
color:#000000;
}
.ha-open-btn-collapsed-box::before {
content: '\200E+';
font-weight: 900;
}
.ha-close-btn-collapsed-box::before {
content: '\200E\00D7';
font-weight: 900;
}
/* Not possible otherwise, overwrites javascript set style values, which cant be defined before render */
@media (max-width: 1190px) {
/* @media (max-width: 1190px) {
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks {
height: auto !important;
overflow: unset !important;
}
}
} */
.hover\:text-black:hover {
--tw-text-opacity: 1;

View File

@@ -2,26 +2,8 @@
@tailwind components;
@tailwind utilities;
/* Regular woff-files for regular font variants
Instead we use the Graphite versions of the font currently
@font-face {
font-family: 'Biolinum';
src: url('../fonts/LinBiolinum_R.woff') format('woff');
font-display: swap;
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Libertine';
src: url('../fonts/LinLibertine_R.woff') format('woff');
font-display: swap;
font-weight: normal;
font-style: normal;
}
*/
/* Regular woff-files for regular font variants curerently
Instead we can use the Graphite versions of the font
@font-face {
font-family: 'Biolinum';
@@ -39,6 +21,24 @@
font-style: normal;
}
*/
@font-face {
font-family: 'Biolinum';
src: url('../fonts/LinBiolinum_R.woff') format('woff');
font-display: swap;
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Libertine';
src: url('../fonts/LinLibertine_R.woff') format('woff');
font-display: swap;
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Biolinum';
src: url('../fonts/LinBiolinum_RI.woff') format('woff');
@@ -80,6 +80,7 @@
}
@layer components {
/* TODO: check what can be inlined (eg. used once in the code, has no double paths etc...) */
body {
@apply text-base desktop:text-lg w-full h-full
}
@@ -202,7 +203,7 @@
}
.ha-register .ha-register-head {
@apply border-b-2
@apply border-b-2 border-slate-200
}
.ha-register .ha-register-head h1 {
@@ -222,7 +223,7 @@
}
.ha-register .ha-register-head .ha-register-nav a.active {
@apply border-b-2
@apply border-b-2 border-slate-200
}
.ha-register .ha-register-head .ha-register-nav .ha-register-left-nav {
@@ -273,14 +274,23 @@
@apply inline-block font-normal text-xs md:text-sm leading-snug font-sans text-gray-600 caps-small ml-2
}
.ha-register .ha-register-body .ha-comment .ha-commenthead .ha-letlinks .ha-hkb {
@apply inline text-gray-900
}
.ha-register .ha-neuzeit .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks,
.ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
@apply desktop:indent-0 desktop:left-[48rem] desktop:top-0 desktop:w-80 desktop:block desktop:absolute desktop:border-l-2 pl-2
@apply desktop:left-[48rem]
}
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks,
.ha-register .ha-forschung .ha-register-body .ha-headcomment .ha-commenthead .ha-letlinks {
@apply desktop:indent-0 desktop:block desktop:absolute desktop:border-l-2 pl-2 desktop:bg-slate-50 desktop:left-[46rem] desktop:top-0 desktop:w-80
.ha-register .ha-forschung .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks {
@apply desktop:left-[46rem]
}
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-letlinks,
.ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-letlinks {
@apply desktop:indent-0 desktop:top-0 desktop:w-80 desktop:block desktop:bg-slate-50 desktop:absolute desktop:border-l-2 pl-2
}
.ha-register .ha-register-body .ha-comment .ha-commenthead .ha-letlinks a {
@@ -365,6 +375,33 @@
.ha-topnav.ha-topnav-collapsed .ha-topnav-dropdown .ha-topnav-dropdown-content a {
@apply py-1 desktop:py-2
}
.ha-register .ha-headcomment .ha-btn-collapsed-box {
@apply left-[47.6rem]
}
.ha-register .ha-subcomment .ha-btn-collapsed-box {
@apply left-[45.6rem]
}
.ha-register .ha-btn-collapsed-box {
@apply hidden desktop:block absolute -top-1 text-gray-600 hover:text-gray-900 cursor-pointer
}
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-collapsed-box,
.ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-collapsed-box {
@apply z-0 overflow-hidden
}
.ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-expanded-box,
.ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-expanded-box {
@apply shadow-md z-[1000] !h-auto !max-h-screen
}
/* .ha-register .ha-neuzeit .ha-register-body .ha-commenthead .ha-collapsed-box:hover,
.ha-register .ha-forschung .ha-register-body .ha-commenthead .ha-collapsed-box:hover {
@apply shadow-md z-[1000] !h-auto
} */
}
* {
@@ -380,6 +417,11 @@ body {
list-style-type:circle;
} */
.downshadow-sm {
-webkit-box-shadow: 5px 6px 5px -7px rgba(0,0,0,0.79);
box-shadow: 5px 6px 5px -7px rgba(0,0,0,0.79);
}
.hyphenate {
hyphens: auto;
}
@@ -435,10 +477,20 @@ body {
color:#000000;
}
.ha-open-btn-collapsed-box::before {
content: '\200E+';
font-weight: 900;
}
.ha-close-btn-collapsed-box::before {
content: '\200E\00D7';
font-weight: 900;
}
/* Not possible otherwise, overwrites javascript set style values, which cant be defined before render */
@media (max-width: 1190px) {
/* @media (max-width: 1190px) {
.ha-register .ha-neuzeit .ha-register-body .ha-subcomment .ha-commenthead .ha-letlinks {
height: auto !important;
overflow: unset !important;
}
}
} */

View File

@@ -1,49 +1,51 @@
const openmenu = function () {
const openmenu = function () {
var x = document.getElementById("ha-topnav");
if (x !== null) x.className += " ha-topnav-collapsed";
let oldbutton = document.getElementById("openmenubutton");
if (oldbutton !== null) oldbutton.setAttribute('class', 'hidden');
if (oldbutton !== null) oldbutton.setAttribute("class", "hidden");
let newbutton = document.getElementById("closemenubutton");
if (newbutton !== null) newbutton.setAttribute('class', '');
}
if (newbutton !== null) newbutton.setAttribute("class", "");
};
const closemenu = function () {
var x = document.getElementById("ha-topnav");
if (x !== null) x.className = "ha-topnav";
let oldbutton = document.getElementById("closemenubutton");
if (oldbutton !== null) oldbutton.setAttribute('class', 'hidden');
if (oldbutton !== null) oldbutton.setAttribute("class", "hidden");
let newbutton = document.getElementById("openmenubutton");
if (newbutton !== null) newbutton.setAttribute('class', '');
}
if (newbutton !== null) newbutton.setAttribute("class", "");
};
const markactive_startswith = function (element) {
// Marks links as active which target URL starts with the current URL
var all_links = element.getElementsByTagName("a"),
i = 0, len = all_links.length,
full_path = location.href.split('#')[0].toLowerCase(); //Ignore hashes
i = 0,
len = all_links.length,
full_path = location.href.split("#")[0].toLowerCase(); //Ignore hashes
for (; i < len; i++) {
if (full_path.startsWith(all_links[i].href.toLowerCase())) {
all_links[i].className += " active";
}
}
}
};
const markactive_exact = function (element) {
var all_links = element.getElementsByTagName("a"),
i = 0, len = all_links.length,
full_path = location.href.split('#')[0].toLowerCase(); //Ignore hashes
i = 0,
len = all_links.length,
full_path = location.href.split("#")[0].toLowerCase(); //Ignore hashes
for (; i < len; i++) {
if (full_path == all_links[i].href.toLowerCase()) {
all_links[i].className += " active";
}
}
}
};
const getLineHeight = function (element) {
var temp = document.createElement(element.nodeName), ret;
var temp = document.createElement(element.nodeName),
ret;
temp.setAttribute("class", element.className);
temp.innerHTML = "A";
@@ -52,45 +54,123 @@ const getLineHeight = function (element) {
temp.parentNode.removeChild(temp);
return ret;
}
};
const sidebarcollapse = function (selector) {
let backlinkboxes = document.querySelectorAll(selector);
const collapsebox = function (element, height) {
element.style.maxHeight = height + "px";
element.classList.add("ha-collapsed-box");
element.classList.remove("ha-expanded-box");
};
const uncollapsebox = function (element) {
element.classList.remove("ha-collapsed-box");
element.classList.add("ha-expanded-box");
};
const addbuttoncaollapsebox = function (element, height, hoverfunction) {
const btn = document.createElement("div");
btn.classList.add("ha-btn-collapsed-box");
if (element.classList.contains("ha-collapsed-box")) {
btn.classList.add("ha-open-btn-collapsed-box");
} else {
btn.classList.add("ha-close-btn-collapsed-box");
}
btn.addEventListener("click", function (ev) {
ev.stopPropagation();
if (element.classList.contains("ha-collapsed-box")) {
uncollapsebox(element);
btn.classList.remove("ha-open-btn-collapsed-box");
btn.classList.add("ha-close-btn-collapsed-box");
btn.classList.add("ha-collapsed-box-manually-toggled");
} else {
collapsebox(element, height);
btn.classList.remove("ha-close-btn-collapsed-box");
btn.classList.remove("ha-collapsed-box-manually-toggled");
btn.classList.add("ha-open-btn-collapsed-box");
}
});
if (hoverfunction) {
let timer = null;
element.addEventListener("mouseenter", function (ev) {
ev.stopPropagation();
timer = setTimeout(function () {
if (element.classList.contains("ha-collapsed-box")) {
uncollapsebox(element);
btn.classList.remove("ha-open-btn-collapsed-box");
btn.classList.add("ha-close-btn-collapsed-box");
}
}, 200);
});
element.addEventListener("mouseleave", function (ev) {
ev.stopPropagation();
if (timer != null) {
clearTimeout(timer);
}
if (
element.classList.contains("ha-expanded-box") &&
!btn.classList.contains("ha-collapsed-box-manually-toggled")
) {
collapsebox(element, height);
btn.classList.remove("ha-close-btn-collapsed-box");
btn.classList.add("ha-open-btn-collapsed-box");
}
});
}
//element.appendChild(btn);
//element.insertBefore(btn, element.firstChild);
element.parentNode.insertBefore(btn, element);
};
/* TODO: need a resize watcher to undo and reapply the effect on breakpoint */
const overlappingcollapsebox = function (selector, hoverfunction) {
let boxes = document.querySelectorAll(selector);
let clientrects = [];
let lineheight = 1;
for (element of backlinkboxes) {
if (boxes.length >= 1) {
lineheight = getLineHeight(boxes[0]);
}
for (element of boxes) {
clientrects.push([element, element.getBoundingClientRect()]);
}
let lineheight = 1;
if (backlinkboxes.length >= 1) {
lineheight = getLineHeight(backlinkboxes[0]);
}
for (var i = 0; i < clientrects.length; i++) {
if (i < clientrects.length-1) {
if (clientrects[i][1].bottom >= clientrects[i+1][1].top) {
let overlap = clientrects[i][1].bottom - clientrects[i+1][1].top;
if (i < clientrects.length - 1) {
let overlap = clientrects[i][1].bottom - clientrects[i + 1][1].top;
if (overlap >= 0) {
let newlength = clientrects[i][1].height - overlap;
let remainder = newlength % lineheight;
newlength = newlength - remainder;
clientrects[i][0].style.height = newlength + 'px';
clientrects[i][0].style.overflowX = "hidden";
clientrects[i][0].style.overflowY = "scroll";
collapsebox(clientrects[i][0], newlength);
addbuttoncaollapsebox(clientrects[i][0], newlength, hoverfunction);
}
}
}
}
};
window.addEventListener('load', function() {
document.getElementById("openmenubutton").addEventListener('click', openmenu);
document.getElementById("closemenubutton").addEventListener('click', closemenu);
window.addEventListener("load", function () {
if (
document.getElementById("openmenubutton") != null &&
document.getElementById("closemenubutton") != null
) {
document
.getElementById("openmenubutton")
.addEventListener("click", openmenu);
document
.getElementById("closemenubutton")
.addEventListener("click", closemenu);
}
if (document.getElementById("ha-topnav") != null)
markactive_startswith(document.getElementById("ha-topnav"));
if (document.getElementById("ha-register-nav") != null)
markactive_exact(document.getElementById("ha-register-nav"));
sidebarcollapse(".ha-neuzeit .ha-letlinks");
sidebarcollapse(".ha-forschung .ha-letlinks");
})
overlappingcollapsebox(".ha-neuzeit .ha-letlinks", true);
overlappingcollapsebox(".ha-forschung .ha-letlinks", true);
});