标记搜索关键词
This commit is contained in:
@@ -68,52 +68,7 @@ function normalize_url(url) {
|
|||||||
return /^https?:\/\//.test(url) ? url : 'http://' + url;
|
return /^https?:\/\//.test(url) ? url : 'http://' + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// props: text, show_pid, color_picker, search_param
|
||||||
export class HighlightedText extends PureComponent {
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<pre>
|
|
||||||
{this.props.parts.map((part, idx) => {
|
|
||||||
let [rule, p] = part;
|
|
||||||
return (
|
|
||||||
<span key={idx}>
|
|
||||||
{rule === 'url_pid' ? (
|
|
||||||
<span className="url-pid-link" title={p}>
|
|
||||||
/##
|
|
||||||
</span>
|
|
||||||
) : rule === 'url' ? (
|
|
||||||
<a href={normalize_url(p)} target="_blank" rel="noopener">
|
|
||||||
{p}
|
|
||||||
</a>
|
|
||||||
) : rule === 'pid' ? (
|
|
||||||
<a
|
|
||||||
href={'#' + p}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.show_pid(p.substring(1));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{p}
|
|
||||||
</a>
|
|
||||||
) : rule === 'nickname' ? (
|
|
||||||
<ColoredSpan colors={this.props.color_picker.get(p)}>
|
|
||||||
{p}
|
|
||||||
</ColoredSpan>
|
|
||||||
) : rule === 'search' ? (
|
|
||||||
<span className="search-query-highlight">{p}</span>
|
|
||||||
) : (
|
|
||||||
p
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</pre>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// props: text, show_pid, color_picker
|
|
||||||
export class HighlightedMarkdown extends Component {
|
export class HighlightedMarkdown extends Component {
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
@@ -169,13 +124,21 @@ export class HighlightedMarkdown extends Component {
|
|||||||
},
|
},
|
||||||
processNode(node, children, index) {
|
processNode(node, children, index) {
|
||||||
const originalText = node.data;
|
const originalText = node.data;
|
||||||
const splitted = split_text(originalText, [
|
let rules = [
|
||||||
['url_pid', URL_PID_RE],
|
['url_pid', URL_PID_RE],
|
||||||
['url', URL_RE],
|
['url', URL_RE],
|
||||||
['pid', PID_RE],
|
['pid', PID_RE],
|
||||||
['nickname', NICKNAME_RE],
|
['nickname', NICKNAME_RE],
|
||||||
['tag', TAG_RE],
|
['tag', TAG_RE]
|
||||||
|
];
|
||||||
|
if (props.search_param) {
|
||||||
|
let search_kws = props.search_param.split(' ').filter(s => !!s);
|
||||||
|
rules.push([
|
||||||
|
'search',
|
||||||
|
new RegExp(`(${search_kws.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join("|")})`, "g")
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
|
const splitted = split_text(originalText, rules);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={index}>
|
<React.Fragment key={index}>
|
||||||
|
|||||||
69
src/Flows.js
69
src/Flows.js
@@ -98,7 +98,7 @@ class Reply extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
info, color_picker, show_pid, do_filter_name, do_delete,
|
info, color_picker, show_pid, do_filter_name, do_delete,
|
||||||
do_report, do_block
|
do_report, do_block, search_param
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const author = info.name,
|
const author = info.name,
|
||||||
replyText = info.text;
|
replyText = info.text;
|
||||||
@@ -173,6 +173,7 @@ class Reply extends PureComponent {
|
|||||||
text={replyText}
|
text={replyText}
|
||||||
color_picker={color_picker}
|
color_picker={color_picker}
|
||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
|
search_param={search_param}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -227,7 +228,7 @@ class FlowItem extends PureComponent {
|
|||||||
const {
|
const {
|
||||||
info, is_quote, cached, attention, can_del, do_filter_name, do_delete,
|
info, is_quote, cached, attention, can_del, do_filter_name, do_delete,
|
||||||
do_edit_cw, do_edit_score, timestamp, img_clickable, color_picker,
|
do_edit_cw, do_edit_score, timestamp, img_clickable, color_picker,
|
||||||
show_pid, do_vote, do_block
|
show_pid, do_vote, do_block, search_param
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { cw, hot_score } = this.state;
|
const { cw, hot_score } = this.state;
|
||||||
return (
|
return (
|
||||||
@@ -358,39 +359,8 @@ class FlowItem extends PureComponent {
|
|||||||
text={info.text}
|
text={info.text}
|
||||||
color_picker={color_picker}
|
color_picker={color_picker}
|
||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
|
search_param={search_param}
|
||||||
/>
|
/>
|
||||||
{info.type === 'image' && (
|
|
||||||
<p className="img">
|
|
||||||
{img_clickable ? (
|
|
||||||
<a
|
|
||||||
className="no-underline"
|
|
||||||
href={IMAGE_BASE + info.url}
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={IMAGE_BASE + info.url}
|
|
||||||
onError={(e) => {
|
|
||||||
if (e.target.src === IMAGE_BASE + info.url) {
|
|
||||||
e.target.src = IMAGE_BAK_BASE + info.url;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
alt={IMAGE_BASE + info.url}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
<img
|
|
||||||
src={IMAGE_BASE + info.url}
|
|
||||||
onError={(e) => {
|
|
||||||
if (e.target.src === IMAGE_BASE + info.url) {
|
|
||||||
e.target.src = IMAGE_BAK_BASE + info.url;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
alt={IMAGE_BASE + info.url}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{/*{info.type==='audio' && <AudioWidget src={AUDIO_BASE+info.url} />}*/}
|
|
||||||
</div>
|
</div>
|
||||||
{ info.poll && (
|
{ info.poll && (
|
||||||
<div className={!do_vote ? "box-poll disabled" : "box-poll"}>
|
<div className={!do_vote ? "box-poll disabled" : "box-poll"}>
|
||||||
@@ -726,6 +696,7 @@ class FlowSidebar extends PureComponent {
|
|||||||
img_clickable={true}
|
img_clickable={true}
|
||||||
color_picker={this.color_picker}
|
color_picker={this.color_picker}
|
||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
|
search_param={this.props.search_param}
|
||||||
replies={this.state.replies}
|
replies={this.state.replies}
|
||||||
set_variant={(variant) => {
|
set_variant={(variant) => {
|
||||||
this.set_variant(null, variant);
|
this.set_variant(null, variant);
|
||||||
@@ -846,6 +817,7 @@ class FlowSidebar extends PureComponent {
|
|||||||
info={reply}
|
info={reply}
|
||||||
color_picker={this.color_picker}
|
color_picker={this.color_picker}
|
||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
|
search_param={this.props.search_param}
|
||||||
set_variant={(variant) => {
|
set_variant={(variant) => {
|
||||||
this.set_variant(reply.cid, variant);
|
this.set_variant(reply.cid, variant);
|
||||||
}}
|
}}
|
||||||
@@ -967,6 +939,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
<FlowSidebar
|
<FlowSidebar
|
||||||
key={+new Date()}
|
key={+new Date()}
|
||||||
info={this.state.info}
|
info={this.state.info}
|
||||||
|
search_param={this.props.search_param}
|
||||||
replies={this.state.replies}
|
replies={this.state.replies}
|
||||||
attention={this.state.attention}
|
attention={this.state.attention}
|
||||||
sync_state={this.setState.bind(this)}
|
sync_state={this.setState.bind(this)}
|
||||||
@@ -979,50 +952,41 @@ class FlowItemRow extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let show_pid = load_single_meta(this.props.show_sidebar, this.props.token, [
|
const {show_sidebar, token, search_param, is_quote } = this.props;
|
||||||
|
let show_pid = load_single_meta(show_sidebar, token, [
|
||||||
this.state.info.pid,
|
this.state.info.pid,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let hl_rules = [
|
let hl_rules = [
|
||||||
['url_pid', URL_PID_RE],
|
|
||||||
['url', URL_RE],
|
|
||||||
['pid', PID_RE],
|
['pid', PID_RE],
|
||||||
['nickname', NICKNAME_RE],
|
|
||||||
['tag', TAG_RE],
|
|
||||||
];
|
];
|
||||||
if (this.props.search_param) {
|
|
||||||
hl_rules.push([
|
|
||||||
'search',
|
|
||||||
!!this.props.search_param.match(/\/.+\//)
|
|
||||||
? build_highlight_re(this.props.search_param, ' ', 'gi', true) // Use regex
|
|
||||||
: build_highlight_re(this.props.search_param, ' ', 'gi'), // Don't use regex
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
let parts = split_text(this.state.info.text, hl_rules);
|
let parts = split_text(this.state.info.text, hl_rules);
|
||||||
|
|
||||||
//console.log('hl:', parts,this.state.info.pid);
|
//console.log('hl:', parts,this.state.info.pid);
|
||||||
|
|
||||||
let quote_id = null;
|
let quote_id = null;
|
||||||
if (!this.props.is_quote)
|
if (!is_quote)
|
||||||
for (let [mode, content] of parts) {
|
for (let [mode, content] of parts) {
|
||||||
content = content.length > 0 ? content.substring(1) : content;
|
content = content.length > 0 ? content.substring(1) : content;
|
||||||
if (
|
if (
|
||||||
mode === 'pid' &&
|
mode === 'pid' &&
|
||||||
QUOTE_BLACKLIST.indexOf(content) === -1 &&
|
QUOTE_BLACKLIST.indexOf(content) === -1 &&
|
||||||
parseInt(content) < parseInt(this.state.info.pid)
|
parseInt(content) < parseInt(this.state.info.pid)
|
||||||
)
|
) {
|
||||||
if (quote_id === null) quote_id = parseInt(content);
|
if (quote_id === null)
|
||||||
|
quote_id = parseInt(content);
|
||||||
else {
|
else {
|
||||||
quote_id = null;
|
quote_id = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let res = (
|
let res = (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
'flow-item-row flow-item-row-with-prompt' +
|
'flow-item-row flow-item-row-with-prompt' +
|
||||||
(this.props.is_quote ? ' flow-item-row-quote' : '')
|
(is_quote ? ' flow-item-row-quote' : '')
|
||||||
}
|
}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()])
|
if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()])
|
||||||
@@ -1030,7 +994,6 @@ class FlowItemRow extends PureComponent {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FlowItem
|
<FlowItem
|
||||||
parts={parts}
|
|
||||||
info={this.state.info}
|
info={this.state.info}
|
||||||
attention={this.state.attention}
|
attention={this.state.attention}
|
||||||
img_clickable={false}
|
img_clickable={false}
|
||||||
@@ -1039,6 +1002,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
replies={this.state.replies}
|
replies={this.state.replies}
|
||||||
cached={this.state.cached}
|
cached={this.state.cached}
|
||||||
|
search_param={search_param}
|
||||||
/>
|
/>
|
||||||
<div className="flow-reply-row">
|
<div className="flow-reply-row">
|
||||||
{this.state.reply_status === 'loading' && (
|
{this.state.reply_status === 'loading' && (
|
||||||
@@ -1064,6 +1028,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
info={reply}
|
info={reply}
|
||||||
color_picker={this.color_picker}
|
color_picker={this.color_picker}
|
||||||
show_pid={show_pid}
|
show_pid={show_pid}
|
||||||
|
search_param={search_param}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{this.state.replies.length > PREVIEW_REPLY_COUNT && (
|
{this.state.replies.length > PREVIEW_REPLY_COUNT && (
|
||||||
|
|||||||
Reference in New Issue
Block a user