[Glitch] Change RTL detection to rely on unicode-bidi paragraph by paragraph
Port 1f564051b6
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
pull/1476/head
parent
6205107229
commit
b0722fbc14
|
@ -4,7 +4,6 @@ import AutosuggestEmoji from './autosuggest_emoji';
|
||||||
import AutosuggestHashtag from './autosuggest_hashtag';
|
import AutosuggestHashtag from './autosuggest_hashtag';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isRtl } from 'flavours/glitch/util/rtl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
|
@ -189,11 +188,6 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props;
|
||||||
const { suggestionsHidden } = this.state;
|
const { suggestionsHidden } = this.state;
|
||||||
const style = { direction: 'ltr' };
|
|
||||||
|
|
||||||
if (isRtl(value)) {
|
|
||||||
style.direction = 'rtl';
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='autosuggest-input'>
|
<div className='autosuggest-input'>
|
||||||
|
@ -212,7 +206,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
onKeyUp={onKeyUp}
|
onKeyUp={onKeyUp}
|
||||||
onFocus={this.onFocus}
|
onFocus={this.onFocus}
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
style={style}
|
dir='auto'
|
||||||
aria-autocomplete='list'
|
aria-autocomplete='list'
|
||||||
id={id}
|
id={id}
|
||||||
className={className}
|
className={className}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import AutosuggestEmoji from './autosuggest_emoji';
|
||||||
import AutosuggestHashtag from './autosuggest_hashtag';
|
import AutosuggestHashtag from './autosuggest_hashtag';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isRtl } from 'flavours/glitch/util/rtl';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import Textarea from 'react-textarea-autosize';
|
import Textarea from 'react-textarea-autosize';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -195,11 +194,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
||||||
const { suggestionsHidden } = this.state;
|
const { suggestionsHidden } = this.state;
|
||||||
const style = { direction: 'ltr' };
|
|
||||||
|
|
||||||
if (isRtl(value)) {
|
|
||||||
style.direction = 'rtl';
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'>
|
<div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'>
|
||||||
|
@ -220,7 +214,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
onFocus={this.onFocus}
|
onFocus={this.onFocus}
|
||||||
onBlur={this.onBlur}
|
onBlur={this.onBlur}
|
||||||
onPaste={this.onPaste}
|
onPaste={this.onPaste}
|
||||||
style={style}
|
dir='auto'
|
||||||
aria-autocomplete='list'
|
aria-autocomplete='list'
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { isRtl } from 'flavours/glitch/util/rtl';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import Permalink from './permalink';
|
import Permalink from './permalink';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
@ -277,16 +276,11 @@ export default class StatusContent extends React.PureComponent {
|
||||||
|
|
||||||
const content = { __html: status.get('contentHtml') };
|
const content = { __html: status.get('contentHtml') };
|
||||||
const spoilerContent = { __html: status.get('spoilerHtml') };
|
const spoilerContent = { __html: status.get('spoilerHtml') };
|
||||||
const directionStyle = { direction: 'ltr' };
|
|
||||||
const classNames = classnames('status__content', {
|
const classNames = classnames('status__content', {
|
||||||
'status__content--with-action': parseClick && !disabled,
|
'status__content--with-action': parseClick && !disabled,
|
||||||
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
|
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isRtl(status.get('search_index'))) {
|
|
||||||
directionStyle.direction = 'rtl';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.get('spoiler_text').length > 0) {
|
if (status.get('spoiler_text').length > 0) {
|
||||||
let mentionsPlaceholder = '';
|
let mentionsPlaceholder = '';
|
||||||
|
|
||||||
|
@ -346,7 +340,6 @@ export default class StatusContent extends React.PureComponent {
|
||||||
<div
|
<div
|
||||||
ref={this.setContentsRef}
|
ref={this.setContentsRef}
|
||||||
key={`contents-${tagLinks}`}
|
key={`contents-${tagLinks}`}
|
||||||
style={directionStyle}
|
|
||||||
tabIndex={!hidden ? 0 : null}
|
tabIndex={!hidden ? 0 : null}
|
||||||
dangerouslySetInnerHTML={content}
|
dangerouslySetInnerHTML={content}
|
||||||
className='status__content__text'
|
className='status__content__text'
|
||||||
|
@ -360,7 +353,6 @@ export default class StatusContent extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames}
|
className={classNames}
|
||||||
style={directionStyle}
|
|
||||||
onMouseDown={this.handleMouseDown}
|
onMouseDown={this.handleMouseDown}
|
||||||
onMouseUp={this.handleMouseUp}
|
onMouseUp={this.handleMouseUp}
|
||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
|
@ -380,7 +372,6 @@ export default class StatusContent extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='status__content'
|
className='status__content'
|
||||||
style={directionStyle}
|
|
||||||
tabIndex='0'
|
tabIndex='0'
|
||||||
ref={this.setRef}
|
ref={this.setRef}
|
||||||
>
|
>
|
||||||
|
|
|
@ -10,9 +10,6 @@ import AccountContainer from 'flavours/glitch/containers/account_container';
|
||||||
import IconButton from 'flavours/glitch/components/icon_button';
|
import IconButton from 'flavours/glitch/components/icon_button';
|
||||||
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
import AttachmentList from 'flavours/glitch/components/attachment_list';
|
||||||
|
|
||||||
// Utils.
|
|
||||||
import { isRtl } from 'flavours/glitch/util/rtl';
|
|
||||||
|
|
||||||
// Messages.
|
// Messages.
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
cancel: {
|
cancel: {
|
||||||
|
@ -71,7 +68,6 @@ class ReplyIndicator extends ImmutablePureComponent {
|
||||||
<div
|
<div
|
||||||
className='content'
|
className='content'
|
||||||
dangerouslySetInnerHTML={{ __html: content || '' }}
|
dangerouslySetInnerHTML={{ __html: content || '' }}
|
||||||
style={{ direction: isRtl(content) ? 'rtl' : 'ltr' }}
|
|
||||||
/>
|
/>
|
||||||
{attachments.size > 0 && (
|
{attachments.size > 0 && (
|
||||||
<AttachmentList
|
<AttachmentList
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
p, pre, blockquote {
|
p, pre, blockquote {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
unicode-bidi: plaintext;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
@ -152,6 +153,7 @@
|
||||||
a {
|
a {
|
||||||
color: $secondary-text-color;
|
color: $secondary-text-color;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
unicode-bidi: isolate;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// U+0590 to U+05FF - Hebrew
|
|
||||||
// U+0600 to U+06FF - Arabic
|
|
||||||
// U+0700 to U+074F - Syriac
|
|
||||||
// U+0750 to U+077F - Arabic Supplement
|
|
||||||
// U+0780 to U+07BF - Thaana
|
|
||||||
// U+07C0 to U+07FF - N'Ko
|
|
||||||
// U+0800 to U+083F - Samaritan
|
|
||||||
// U+08A0 to U+08FF - Arabic Extended-A
|
|
||||||
// U+FB1D to U+FB4F - Hebrew presentation forms
|
|
||||||
// U+FB50 to U+FDFF - Arabic presentation forms A
|
|
||||||
// U+FE70 to U+FEFF - Arabic presentation forms B
|
|
||||||
|
|
||||||
const rtlChars = /[\u0590-\u083F]|[\u08A0-\u08FF]|[\uFB1D-\uFDFF]|[\uFE70-\uFEFF]/mg;
|
|
||||||
|
|
||||||
export function isRtl(text) {
|
|
||||||
if (text.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
text = text.replace(/(?:^|[^\/\w])@([a-z0-9_]+(@[a-z0-9\.\-]+)?)/ig, '');
|
|
||||||
text = text.replace(/(?:^|[^\/\w])#([\S]+)/ig, '');
|
|
||||||
text = text.replace(/\s+/g, '');
|
|
||||||
text = text.replace(/(\w\S+\.\w{2,}\S*)/g, '');
|
|
||||||
|
|
||||||
const matches = text.match(rtlChars);
|
|
||||||
|
|
||||||
if (!matches) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return matches.length / text.length > 0.3;
|
|
||||||
};
|
|
Loading…
Reference in New Issue