Skip to content

Commit

Permalink
Tag <a> elements are auto-populated on use.
Browse files Browse the repository at this point in the history
Maybe someone is relying on the `href` attributes being real, we'll
see. This is nicer because (1) the HTML is smaller, (2) we can
decide from context what to link to -- for example, a tag on the
review preferences page can link back to the review preferences
page (#332), and a tag on a search page will incorporate any view
annotations on the search.
  • Loading branch information
kohler committed Feb 7, 2024
1 parent 040e0c4 commit 31a9764
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 31 deletions.
32 changes: 18 additions & 14 deletions lib/tagger.php
Original file line number Diff line number Diff line change
Expand Up @@ -1686,8 +1686,8 @@ function unparse_decoration_html($tags, $type = 0) {
}
$b = self::unparse_emoji_html($e, $count);
if ($type === self::DECOR_PAPER) {
$url = $this->conf->hoturl("search", ["q" => "emoji:{$e}"]);
$b = "<a class=\"q\" href=\"{$url}\">{$b}</a>";
$q = htmlspecialchars("emoji:{$e}");
$b = "<a href=\"\" class=\"q uic js-sq\" data-q=\"{$q}\">{$b}</a>";
}
if ($x === "") {
$x = " ";
Expand All @@ -1700,8 +1700,9 @@ function unparse_decoration_html($tags, $type = 0) {
TagMap::stash_ensure_pattern("badge-{$tb[1]}");
}
$tag = $this->unparse($tb[0]);
if ($type === self::DECOR_PAPER && ($link = $this->link($tag))) {
$b = "<a href=\"{$link}\"{$klass}>#{$tag}</a>";
if ($type === self::DECOR_PAPER && ($q = $this->js_sq($tag, false)) !== null) {
$dq = $q === "" ? "" : " data-q=\"" . htmlspecialchars($q) . "\"";
$b = "<a href=\"\" class=\"uic js-sq\"{$dq}{$klass}>#{$tag}</a>";
} else {
if ($type !== self::DECOR_USER) {
$tag = "#{$tag}";
Expand All @@ -1727,13 +1728,13 @@ function link_base($tv) {
}

/** @param string $tv
* @param int $flags
* @return string|false */
function link($tv, $flags = 0) {
* @param bool $always
* @return ?string */
private function js_sq($tv, $always) {
if (ctype_digit($tv[0])) {
$p = strlen((string) $this->_contactId);
if (substr($tv, 0, $p) != $this->_contactId || $tv[$p] !== "~") {
return false;
return null;
}
$tv = substr($tv, $p);
}
Expand All @@ -1742,13 +1743,14 @@ function link($tv, $flags = 0) {
if ($dt->has(TagInfo::TFM_VOTES)
&& ($dt->is_votish($base)
|| ($base[0] === "~" && $dt->is_allotment(substr($base, 1))))) {
$q = "#{$base} showsort:-#{$base}";
return "#{$base} showsort:-#{$base}";
} else if (!$always) {
return "";
} else if ($base === $tv) {
$q = "#{$base}";
} else {
$q = "order:#{$base}";
}
return $this->conf->hoturl("search", ["q" => $q], $flags);
}

/** @param list<string>|string $viewable
Expand All @@ -1766,11 +1768,13 @@ function unparse_link($viewable) {
if (!($base = Tagger::tv_tag($tv))) {
continue;
}
if (($link = $this->link($tv))) {
$tsuf = substr($tv, strlen($base));
$tx = "<a class=\"qo ibw\" href=\"{$link}\"><u class=\"x\">#{$base}</u>{$tsuf}</a>";
} else {
$q = $this->js_sq($tv, false);
if ($q === null) {
$tx = "#{$tv}";
} else {
$tsuf = substr($tv, strlen($base));
$dq = $q === "" ? "" : " data-q=\"" . htmlspecialchars($q) . "\"";
$tx = "<a href=\"\" class=\"qo ibw uic js-sq\"{$dq}><u class=\"x\">#{$base}</u>{$tsuf}</a>";
}
if (($cc = $dt->styles($base))) {
$ccs = join(" ", $cc);
Expand Down
46 changes: 36 additions & 10 deletions scripts/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -5313,12 +5313,12 @@ handle_ui.on(".js-autoassign-prepare", function () {
if (!this.elements.a || !(a = this.elements.a.value)) {
return;
}
this.action = hoturl_add(this.action, "a=" + encodeURIComponent(a));
this.action = hoturl_add(this.action, "a=" + urlencode(a));
for (k in this.elements) {
if (k.startsWith(a + ":")) {
v = this.elements[k].value;
if (v && typeof v === "string" && v.length < 100)
this.action = hoturl_add(this.action, encodeURIComponent(k) + "=" + encodeURIComponent(v));
this.action = hoturl_add(this.action, encodeURIComponent(k) + "=" + urlencode(v));
}
}
});
Expand Down Expand Up @@ -8675,6 +8675,9 @@ Hotlist.at = function (elt) {
Hotlist.prototype.ids = function () {
return this.obj && this.obj.ids ? decode_session_list_ids(this.obj.ids) : null;
};
Hotlist.prototype.urlbase = function () {
return this.obj && this.obj.urlbase;
};
Hotlist.prototype.resolve = function () {
var obj;
if (this.obj
Expand Down Expand Up @@ -8920,6 +8923,33 @@ function hotlist_search_params(x, ids) {
return q;
}

handle_ui.on("click.js-sq", function () {
removeClass(this, "js-sq");
let q;
if (this.hasAttribute("data-q")) {
q = this.getAttribute("data-q");
} else if (this.firstChild.nodeType === 3) {
q = this.firstChild.data;
} else if (this.lastChild === this.firstChild
|| (this.lastChild.nodeType === 3 && this.lastChild.data === "#0")) {
q = this.firstChild.firstChild.data;
} else {
q = "order:" + this.firstChild.firstChild.data;
}
const hle = this.closest(".has-hotlist");
if (hle && hle.nodeName !== "BODY") {
if (hle.hasAttribute("data-search-view")) {
q += " " + hle.getAttribute("data-search-view");
}
const urlbase = Hotlist.at(hle).urlbase();
if (urlbase) {
this.href = siteinfo.site_relative + hoturl_add(urlbase, "q=" + urlencode(q));
return;
}
}
this.href = siteinfo.site_relative + "search?q=" + urlencode(q);
});


// review preferences
(function () {
Expand Down Expand Up @@ -10571,16 +10601,12 @@ function render_tagset(plistui, tagstr, editable) {
tagx = tagmap ? tagmap[tbase.toLowerCase()] || 0 : 0;
tbase = tbase.substring(twiddle, hash);
if ((tagx & 2) || tindex != "0")
h = $e("a", "qo nw", $e("u", "x", "#" + tbase), "#" + tindex);
h = $e("a", "qo nw uic js-sq", $e("u", "x", "#" + tbase), "#" + tindex);
else
h = $e("a", "q nw", "#" + tbase);
h = $e("a", "q nw uic js-sq", "#" + tbase);
if (tagx & 2)
q = "#".concat(tbase, " showsort:-#", tbase);
else if (tindex != "0")
q = "order:#" + tbase;
else
q = "#" + tbase;
h.setAttribute("href", hoturl("search", {q: q}));
h.setAttribute("data-q", "#".concat(tbase, "showsort:-#", tbase));
h.href = "";
if (taghighlighter && taghighlighter.test(tbase))
h = $e("strong", null, h);
t.push([h, text.substring(twiddle, hash)]);
Expand Down
21 changes: 14 additions & 7 deletions src/paperlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class PaperList {
/** @var bool */
private $_sortable;
/** @var ?string */
private $_paper_linkto;
private $_view_linkto;
/** @var bool */
private $_view_facets = false;
/** @var int */
Expand Down Expand Up @@ -608,8 +608,11 @@ function set_view($k, $v, $origin, $decorations = null) {
assert($origin >= self::VIEWORIGIN_REPORT && $origin <= self::VIEWORIGIN_MAX);
if ($v === "show" || $v === "hide") {
$v = $v === "show";
} else if ($v === "edit") {
$v = true;
$decorations[] = "edit";
}
assert(is_bool($v) || $v === "edit");
assert(is_bool($v));

if ($k !== "" && $k[0] === "\"" && $k[strlen($k) - 1] === "\"") {
$k = substr($k, 1, -1);
Expand Down Expand Up @@ -650,9 +653,6 @@ function set_view($k, $v, $origin, $decorations = null) {
$flags = ($flags & ~(self::VIEW_ORIGINMASK | self::VIEW_SHOW))
| $origin
| ($v ? self::VIEW_SHOW : 0);
if ($v === "edit") {
$decorations[] = "edit";
}
if (!empty($decorations)) {
$this->_view_decorations[$k] = $decorations;
} else {
Expand All @@ -666,7 +666,7 @@ function set_view($k, $v, $origin, $decorations = null) {
} else if ($k === "linkto") {
if (!empty($decorations)
&& in_array($decorations[0], ["paper", "paperedit", "assign", "finishreview"])) {
$this->_paper_linkto = $decorations[0];
$this->_view_linkto = $decorations[0];
}
} else if (($k === "aufull" || $k === "anonau")
&& $origin >= self::VIEWORIGIN_SEARCH
Expand Down Expand Up @@ -1385,7 +1385,7 @@ function _contentDownload($row) {

/** @return string */
function _paperLink(PaperInfo $row) {
$pt = $this->_paper_linkto ?? "paper";
$pt = $this->_view_linkto ?? "paper";
$pm = "";
if ($pt === "finishreview") {
$ci = $row->contact_info($this->user);
Expand Down Expand Up @@ -2132,6 +2132,13 @@ private function _table_render() {
$this->table_attr["id"] = $this->_table_id;
}
$this->table_attr["data-search-params"] = $this->encoded_search_params();
$views = [];
foreach ($this->search->view_commands() as $svc) {
$views[] = $svc->command;
}
if (!empty($views)) {
$this->table_attr["data-search-view"] = join(" ", $views);
}
if ($this->_table_fold_session) {
$this->table_attr["data-fold-session-prefix"] = $this->_table_fold_session;
$this->table_attr["data-fold-session"] = json_encode_browser([
Expand Down

0 comments on commit 31a9764

Please sign in to comment.