|
|
@ -241,13 +241,16 @@ static inline void preprocess_link(const httplib::Request& req, const std::strin
|
|
|
|
const lxb_char_t* cls_c = lxb_dom_element_class(element, &cls_c_len);
|
|
|
|
const lxb_char_t* cls_c = lxb_dom_element_class(element, &cls_c_len);
|
|
|
|
std::string cls = cls_c ? std::string(reinterpret_cast<const char*>(cls_c), cls_c_len) : "";
|
|
|
|
std::string cls = cls_c ? std::string(reinterpret_cast<const char*>(cls_c), cls_c_len) : "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
CurlUrl href_url;
|
|
|
|
CurlUrl href_url;
|
|
|
|
href_url.set(CURLUPART_URL, get_origin(req));
|
|
|
|
href_url.set(CURLUPART_URL, get_origin(req));
|
|
|
|
href_url.set(CURLUPART_PATH, std::string(href_url.get(CURLUPART_PATH).get()) + req.path);
|
|
|
|
href_url.set(CURLUPART_PATH, std::string(href_url.get(CURLUPART_PATH).get()) + req.path);
|
|
|
|
href_url.set(CURLUPART_URL, href);
|
|
|
|
href_url.set(CURLUPART_URL, href);
|
|
|
|
|
|
|
|
|
|
|
|
CurlUrl instance_url_base;
|
|
|
|
CurlUrl instance_url_base;
|
|
|
|
instance_url_base.set(CURLUPART_SCHEME, "https");
|
|
|
|
instance_url_base.set(CURLUPART_SCHEME, "https");
|
|
|
|
instance_url_base.set(CURLUPART_HOST, domain_name);
|
|
|
|
instance_url_base.set(CURLUPART_HOST, domain_name);
|
|
|
|
|
|
|
|
|
|
|
|
// .mention is used in note and posts
|
|
|
|
// .mention is used in note and posts
|
|
|
|
// Instance base is used for link fields
|
|
|
|
// Instance base is used for link fields
|
|
|
|
if (std::regex_search(cls, mention_class_re) || starts_with(href_url, instance_url_base)) {
|
|
|
|
if (std::regex_search(cls, mention_class_re) || starts_with(href_url, instance_url_base)) {
|
|
|
@ -256,6 +259,12 @@ static inline void preprocess_link(const httplib::Request& req, const std::strin
|
|
|
|
|
|
|
|
|
|
|
|
lxb_dom_element_set_attribute(element, reinterpret_cast<const lxb_char_t*>("href"), 4, reinterpret_cast<const lxb_char_t*>(href.data()), href.size());
|
|
|
|
lxb_dom_element_set_attribute(element, reinterpret_cast<const lxb_char_t*>("href"), 4, reinterpret_cast<const lxb_char_t*>(href.data()), href.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (const CurlUrlException& e) {
|
|
|
|
|
|
|
|
// example: <a href=""></a> on eldritch.cafe/about
|
|
|
|
|
|
|
|
if (e.code != CURLUE_MALFORMED_INPUT) {
|
|
|
|
|
|
|
|
throw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (should_fix_link(element, cls)) {
|
|
|
|
if (should_fix_link(element, cls)) {
|
|
|
|
// Set the content of each <a> to its href
|
|
|
|
// Set the content of each <a> to its href
|
|
|
@ -274,7 +283,7 @@ static inline bool should_fix_link(lxb_dom_element_t* element, const std::string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto expected_element = [](lxb_dom_node_t* node, const char* expected_cls) {
|
|
|
|
auto expected_element = [](lxb_dom_node_t* node, const char* expected_cls) {
|
|
|
|
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
|
|
|
|
if (!node || node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lxb_dom_element_t* span = lxb_dom_interface_element(node);
|
|
|
|
lxb_dom_element_t* span = lxb_dom_interface_element(node);
|
|
|
@ -472,6 +481,8 @@ static inline Element serialize_media(const Media& media) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline Element serialize_poll(const httplib::Request& req, const Poll& poll) {
|
|
|
|
static inline Element serialize_poll(const httplib::Request& req, const Poll& poll) {
|
|
|
|
|
|
|
|
using namespace std::string_literals;
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t voters_count = poll.voters_count >= 0 ? static_cast<uint64_t>(poll.voters_count) : poll.votes_count;
|
|
|
|
uint64_t voters_count = poll.voters_count >= 0 ? static_cast<uint64_t>(poll.voters_count) : poll.votes_count;
|
|
|
|
Element div("div");
|
|
|
|
Element div("div");
|
|
|
|
|
|
|
|
|
|
|
@ -496,10 +507,13 @@ static inline Element serialize_poll(const httplib::Request& req, const Poll& po
|
|
|
|
: std::vector<Node>({std::to_string(poll.votes_count), " ", pick_form(poll.votes_count, "vote", "votes")})
|
|
|
|
: std::vector<Node>({std::to_string(poll.votes_count), " ", pick_form(poll.votes_count, "vote", "votes")})
|
|
|
|
);
|
|
|
|
);
|
|
|
|
if (poll.expired) {
|
|
|
|
if (poll.expired) {
|
|
|
|
p.nodes.push_back(" / Expired");
|
|
|
|
p.nodes.push_back(" / ");
|
|
|
|
|
|
|
|
p.nodes.push_back(Element("time", {{"datetime", to_rfc3339(poll.expires_at)}, {"title", "Expired on "s + full_time(poll.expires_at)}}, {"Expired"}));
|
|
|
|
} else if (poll.expires_at >= 0) {
|
|
|
|
} else if (poll.expires_at >= 0) {
|
|
|
|
p.nodes.push_back(" / Expires in ");
|
|
|
|
p.nodes.push_back(" / ");
|
|
|
|
p.nodes.push_back(relative_time(current_time(), poll.expires_at));
|
|
|
|
p.nodes.push_back(Element("time", {{"datetime", to_rfc3339(poll.expires_at)}, {"title", full_time(poll.expires_at)}}, {
|
|
|
|
|
|
|
|
"Expires in ", relative_time(current_time(), poll.expires_at),
|
|
|
|
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
div.nodes.push_back(std::move(p));
|
|
|
|
div.nodes.push_back(std::move(p));
|
|
|
|
|
|
|
|
|
|
|
|