forked from mirrors/treebird
Switch to PCRE2 and interaction animation
FossilOrigin-Name: 877f69fe0c99305ef15c7ab5a8db695986d7179f8d30e776a785347637d4f2a4
This commit is contained in:
parent
4a9500d0c0
commit
eaf3350511
5 changed files with 59 additions and 37 deletions
4
Makefile
4
Makefile
|
@ -2,8 +2,8 @@ CC ?= cc
|
|||
GIT ?= git
|
||||
MASTODONT_DIR = mastodont-c/
|
||||
MASTODONT = $(MASTODONT_DIR)libmastodont.a
|
||||
CFLAGS += -Wall -I $(MASTODONT_DIR)include/ -Wno-unused-variable -Wno-ignored-qualifiers -I/usr/include/ -I $(MASTODONT_DIR)/libs $(shell pkg-config --cflags libcurl libpcre)
|
||||
LDFLAGS = -L$(MASTODONT_DIR) -lmastodont $(shell pkg-config --libs libcurl libpcre) -lfcgi
|
||||
CFLAGS += -Wall -I $(MASTODONT_DIR)include/ -Wno-unused-variable -Wno-ignored-qualifiers -I/usr/include/ -I $(MASTODONT_DIR)/libs $(shell pkg-config --cflags libcurl libpcre2-8)
|
||||
LDFLAGS = -L$(MASTODONT_DIR) -lmastodont $(shell pkg-config --libs libcurl libpcre2-8) -lfcgi
|
||||
SRC = $(wildcard src/*.c)
|
||||
OBJ = $(patsubst %.c,%.o,$(SRC))
|
||||
HEADERS = $(wildcard src/*.h)
|
||||
|
|
14
dist/js/main.js
vendored
14
dist/js/main.js
vendored
|
@ -131,11 +131,19 @@ function interact_action(status, type)
|
|||
|
||||
that.classList.toggle("active");
|
||||
|
||||
// Flip itype value
|
||||
if (type.value.substr(0, 2) === "un")
|
||||
|
||||
if (is_active)
|
||||
{
|
||||
// Animation
|
||||
that.classList.remove("active-anim");
|
||||
|
||||
// Flip itype value
|
||||
type.value = type.value.replace("un", "");
|
||||
else
|
||||
}
|
||||
else {
|
||||
that.classList.add("active-anim");
|
||||
type.value = "un" + type.value;
|
||||
}
|
||||
|
||||
counter.innerHTML = change_count_text(counter.innerHTML, is_active ? -1 : 1);
|
||||
});
|
||||
|
|
21
dist/treebird20.css
vendored
21
dist/treebird20.css
vendored
|
@ -1179,17 +1179,6 @@ p}
|
|||
float: right;
|
||||
}
|
||||
|
||||
.statusbox-ani
|
||||
{
|
||||
animation: expand-reply .3s 1;
|
||||
}
|
||||
|
||||
@keyframes expand-reply
|
||||
{
|
||||
0% { padding-top: 0px; height: 0px; overflow: hidden; }
|
||||
100% { padding-top: 10px; height: 150px; overflow: hidden; }
|
||||
}
|
||||
|
||||
.status-interact .statbtn
|
||||
{
|
||||
display: block;
|
||||
|
@ -1202,6 +1191,16 @@ p}
|
|||
min-width: 25px !important;
|
||||
}
|
||||
|
||||
.active-anim
|
||||
{
|
||||
animation: interact .7s 1;
|
||||
}
|
||||
|
||||
@keyframes interact
|
||||
{
|
||||
0% { transform: rotateZ(0deg); }
|
||||
100% { transform: rotateZ(360deg); }
|
||||
}
|
||||
|
||||
.status-interact svg.repeat.active
|
||||
{
|
||||
|
|
31
src/reply.c
31
src/reply.c
|
@ -16,7 +16,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <pcre.h>
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
|
||||
#include <pcre2.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "reply.h"
|
||||
|
@ -55,7 +57,6 @@ char* construct_post_box(char* reply_id,
|
|||
* - Misskey/Mastodon adds an @ symbol in the href param, while pleroma adds /users
|
||||
*/
|
||||
#define REGEX_REPLY "<a .*?href=\"https?:\\/\\/(.*?)\\/(?:@|users/)?(.*?)?\".*?>@(?:<span>)?.*?(?:<\\/span>)?"
|
||||
#define REGEX_RESULTS_LEN 9
|
||||
|
||||
char* reply_status(char* id, struct mstdnt_status* status)
|
||||
{
|
||||
|
@ -63,11 +64,13 @@ char* reply_status(char* id, struct mstdnt_status* status)
|
|||
size_t content_len = strlen(status->content);
|
||||
char* stat_reply;
|
||||
// Regex
|
||||
pcre* re;
|
||||
int re_results[REGEX_RESULTS_LEN];
|
||||
pcre2_code* re;
|
||||
PCRE2_SIZE* re_results;
|
||||
pcre2_match_data* re_data;
|
||||
// Regex data
|
||||
int rc;
|
||||
const char* error;
|
||||
int erroffset;
|
||||
int error;
|
||||
PCRE2_SIZE erroffset;
|
||||
int url_off, url_len, name_off, name_len;
|
||||
// Replies
|
||||
size_t replies_size, replies_size_orig;
|
||||
|
@ -79,20 +82,24 @@ char* reply_status(char* id, struct mstdnt_status* status)
|
|||
replies[replies_size-1] = ' ';
|
||||
|
||||
// Compile regex
|
||||
re = pcre_compile(REGEX_REPLY, 0, &error, &erroffset, NULL);
|
||||
re = pcre2_compile((PCRE2_SPTR)REGEX_REPLY, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL);
|
||||
if (re == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't parse regex at offset %d: %s\n", erroffset, error);
|
||||
fprintf(stderr, "Couldn't parse regex at offset %ld: %d\n", erroffset, error);
|
||||
free(replies);
|
||||
pcre_free(re);
|
||||
pcre2_code_free(re);
|
||||
}
|
||||
|
||||
re_data = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
|
||||
for (int ind = 0;;)
|
||||
{
|
||||
rc = pcre_exec(re, NULL, content, content_len, ind, 0, re_results, REGEX_RESULTS_LEN);
|
||||
rc = pcre2_match(re, (PCRE2_SPTR)content, content_len, ind, 0, re_data, NULL);
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
re_results = pcre2_get_ovector_pointer(re_data);
|
||||
|
||||
// Store to last result
|
||||
ind = re_results[5];
|
||||
|
||||
|
@ -115,12 +122,14 @@ char* reply_status(char* id, struct mstdnt_status* status)
|
|||
replies[replies_size_orig+1+name_len] = '@';
|
||||
memcpy(replies + replies_size_orig + 1 + name_len + 1, content + url_off, url_len);
|
||||
replies[replies_size-1] = ' ';
|
||||
|
||||
pcre2_match_data_free(re_data);
|
||||
}
|
||||
|
||||
replies[replies_size-1] = '\0';
|
||||
|
||||
stat_reply = construct_post_box(id, replies, NULL);
|
||||
if (replies) free(replies);
|
||||
pcre_free(re);
|
||||
pcre2_code_free(re);
|
||||
return stat_reply;
|
||||
}
|
||||
|
|
26
src/status.c
26
src/status.c
|
@ -18,7 +18,8 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pcre.h>
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#include <pcre2.h>
|
||||
#include "http.h"
|
||||
#include "base_page.h"
|
||||
#include "status.h"
|
||||
|
@ -386,7 +387,6 @@ char* construct_in_reply_to(struct mstdnt_status* status,
|
|||
}
|
||||
|
||||
#define REGEX_GREENTEXT "((?:^|<br/?>|\\s)>.*?)(?:<br/?>|$)"
|
||||
#define REGEX_GREENTEXT_LEN 6
|
||||
|
||||
char* reformat_status(struct session* ssn,
|
||||
char* content,
|
||||
|
@ -414,8 +414,8 @@ char* greentextify(char* content)
|
|||
{
|
||||
if (!content) return NULL;
|
||||
|
||||
const char* error;
|
||||
int erroffset;
|
||||
int error;
|
||||
PCRE2_SIZE erroffset;
|
||||
int rc;
|
||||
int gt_off;
|
||||
int gt_len;
|
||||
|
@ -426,21 +426,26 @@ char* greentextify(char* content)
|
|||
char* gt_string;
|
||||
|
||||
char* oldres = NULL;
|
||||
int re_results[REGEX_GREENTEXT_LEN];
|
||||
pcre* re = pcre_compile(REGEX_GREENTEXT, 0, &error, &erroffset, NULL);
|
||||
PCRE2_SIZE* re_results;
|
||||
pcre2_code* re = pcre2_compile((PCRE2_SPTR)REGEX_GREENTEXT, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL);
|
||||
pcre2_match_data* re_data;
|
||||
if (re == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't parse regex at offset %d: %s\n", erroffset, error);
|
||||
pcre_free(re);
|
||||
fprintf(stderr, "Couldn't parse regex at offset %ld: %d\n", erroffset, error);
|
||||
pcre2_code_free(re);
|
||||
return res;
|
||||
}
|
||||
|
||||
re_data = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
|
||||
for (int ind = 0;;)
|
||||
{
|
||||
rc = pcre_exec(re, NULL, res, strlen(res), ind, 0, re_results, REGEX_GREENTEXT_LEN);
|
||||
rc = pcre2_match(re, (PCRE2_SPTR)res, strlen(res), ind, 0, re_data, NULL);
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
||||
re_results = pcre2_get_ovector_pointer(re_data);
|
||||
|
||||
// Store to last result
|
||||
gt_off = re_results[2];
|
||||
gt_len = re_results[3] - gt_off;
|
||||
|
@ -458,9 +463,10 @@ char* greentextify(char* content)
|
|||
ind = re_results[2] + strlen(gt_string);
|
||||
free(reg_string);
|
||||
free(gt_string);
|
||||
pcre2_match_data_free(re_data);
|
||||
}
|
||||
|
||||
pcre_free(re);
|
||||
pcre2_code_free(re);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue