Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 72 additions & 3 deletions app/class/Optlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Optlist extends Optcode
protected bool $time = false;
protected bool $author = false;
protected bool $hidecurrent = false;
protected bool $tags = false;
protected bool $tagcheck = false;
protected string $style = self::LIST;

public const LIST = 'list';
Expand All @@ -27,6 +27,9 @@ class Optlist extends Optcode
self::CARD => self::CARD,
];

/** @var array<string, int> $usefulltags */
protected array $usefulltags = [];

/**
* @param array<string, mixed> $datas
*/
Expand All @@ -52,6 +55,9 @@ public function getcode(): string
*/
public function listhtml(array $pagelist, Page $currentpage): string
{
$pagecount = count($pagelist);
$html = '';

if ($this->hidecurrent && key_exists($currentpage->id(), $pagelist)) {
unset($pagelist[$currentpage->id()]);
}
Expand Down Expand Up @@ -137,16 +143,69 @@ public function listhtml(array $pagelist, Page $currentpage): string
$thumbnail->setAttribute('alt', htmlspecialchars($page->title()));
$parent->appendChild($thumbnail);
}
if ($this->tagcheck) {
$tags = $page->tag();
$this->addusefulltags($tags);
foreach ($tags as $tag) {
$parent->setAttribute("data-tag_$tag", '1');
}
}
}

$dom->appendChild($ul);

return $dom->saveHTML($dom->documentElement);
if ($this->tagcheck) {
$hash = crc32(serialize($this));
$domform = new DOMDocument('1.0', 'UTF-8');
$form = $domform->createElement('form');
$form->setAttribute('class', 'tagcheck');
$form->setAttribute('id', "tagcheck-$hash");
foreach ($this->usefulltags as $tag => $count) {
if ($count === $pagecount) {
continue; // skip this tag as it's used by all pages
}
$span = $domform->createElement('span');
$span->setAttribute('class', "tag_$tag");
$id = "tagcheck-$hash-tag_$tag";
$input = $domform->createElement('input');
$input->setAttribute('id', $id);
$input->setAttribute('value', $tag);
$input->setAttribute('type', 'checkbox');
$label = $domform->createElement('label', $tag);
$label->setAttribute('for', $id);
$span->appendChild($input);
$span->appendChild($label);
$form->appendChild($span);
}
$domform->appendChild($form);
$html .= $domform->saveHTML($domform->documentElement);
$html .= "\n";
}

$html .= $dom->saveHTML($dom->documentElement);

return $html;
} catch (DOMException $e) {
throw new LogicException('bad DOM node used', 0, $e);
}
}

/**
* merge list of tags within the list of usefull tags.
* Tag name is key and value count the time it's used.
*
* @param string[] $tags
*/
private function addusefulltags(array $tags): void
{
foreach ($tags as $tag) {
if (key_exists($tag, $this->usefulltags)) {
$this->usefulltags[$tag] ++;
} else {
$this->usefulltags[$tag] = 1;
}
}
}




Expand Down Expand Up @@ -188,6 +247,11 @@ public function hidecurrent(): bool
return $this->hidecurrent;
}

public function tagcheck(): bool
{
return $this->tagcheck;
}

public function style(): string
{
return $this->style;
Expand Down Expand Up @@ -231,6 +295,11 @@ public function sethidecurrent(bool $hidecurrent): void
$this->hidecurrent = $hidecurrent;
}

public function settagcheck(bool $tagcheck): void
{
$this->tagcheck = $tagcheck;
}

public function setstyle(string $style): void
{
if (key_exists($style, self::STYLES)) {
Expand Down
11 changes: 11 additions & 0 deletions app/class/Servicerender.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ abstract class Servicerender
/** @var bool True if the page need post process */
protected bool $postprocessaction = false;

/** @var bool True if the page need to join a JS checkbox file */
protected bool $checkboxjs = false;

/**
* @var Bookmark[] Associative array of Bookmarks using fullmatch as key
* */
Expand Down Expand Up @@ -260,6 +263,10 @@ protected function gethead(): string
} catch (RuntimeException $e) {
Logger::warningex($e);
}
if ($this->checkboxjs) {
$checkboxjs = Model::jspath() . 'pagecheckbox.bundle.js';
$head .= "<script type=\"module\" src=\"$checkboxjs\" async/></script>\n";
}
if (!empty($this->page->javascript())) {
$head .= "<script src=\"$renderpath$id.js\" async/></script>\n";
}
Expand Down Expand Up @@ -707,6 +714,10 @@ protected function pageoptlist(string $text): string

$optlist->hydrate($options);

if ($optlist->tagcheck()) {
$this->checkboxjs = true;
}

$pagetable = $this->pagemanager->pagetable($this->pagemanager->pagelist(), $optlist);
$content = $optlist->listhtml($pagetable, $this->page);
$text = str_replace($match->fullmatch(), $content, $text);
Expand Down
39 changes: 39 additions & 0 deletions src/pagecheckbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const formFilters = document.querySelectorAll('form');

function filterpagelist(id) {
let idSelector = '#' + id;
let tagCheckboxesChecked = document.querySelectorAll(
'form' + idSelector + ' input[type="checkbox"]:checked'
);

let pages = document.querySelectorAll(
'form' + idSelector + ' + .pagelist li'
);
let tagCount = tagCheckboxesChecked.length;

for (var li of pages) {
li.classList.remove('w_filter-or-out');
li.classList.remove('w_filter-and-out');
if (tagCount > 0) {
let counter = 0;
for (var tag of tagCheckboxesChecked) {
let dataAttr = 'data-tag_' + tag.value;
if (li.hasAttribute(dataAttr)) {
counter++;
}
}
if (counter < 1) {
li.classList.add('w_filter-or-out');
}
if (counter !== tagCount) {
li.classList.add('w_filter-and-out');
}
}
}
}

for (let formFilter of formFilters) {
formFilter.addEventListener('click', () => {
filterpagelist(formFilter.id);
});
}