added spec; rtl? -> direction_for
This commit is contained in:
parent
a7a8da2f75
commit
92bf8444a7
12 changed files with 152 additions and 61 deletions
|
|
@ -281,7 +281,7 @@ module ApplicationHelper
|
||||||
defaults
|
defaults
|
||||||
end
|
end
|
||||||
|
|
||||||
def rtl?(string)
|
def direction_for(string)
|
||||||
return (string.cleaned_is_rtl?) ? 'rtl' : ''
|
return (string.cleaned_is_rtl?) ? 'rtl' : ''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,5 @@
|
||||||
%time.timeago{:datetime => comment.created_at}
|
%time.timeago{:datetime => comment.created_at}
|
||||||
= comment.created_at ? timeago(comment.created_at) : timeago(Time.now)
|
= comment.created_at ? timeago(comment.created_at) : timeago(Time.now)
|
||||||
|
|
||||||
%p{ :class => rtl?(comment.text) }
|
%p{ :class => direction_for(comment.text) }
|
||||||
= markdownify(comment.text, :youtube_maps => comment.youtube_titles)
|
= markdownify(comment.text, :youtube_maps => comment.youtube_titles)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@
|
||||||
.content
|
.content
|
||||||
.from
|
.from
|
||||||
= person_link(comment.author)
|
= person_link(comment.author)
|
||||||
%p{ :class => rtl?(comment.text) }
|
%p{ :class => direction_for(comment.text) }
|
||||||
= markdownify(comment.text, :youtube_maps => comment[:youtube_titles])
|
= markdownify(comment.text, :youtube_maps => comment[:youtube_titles])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
.message_count
|
.message_count
|
||||||
= conversation.messages.size
|
= conversation.messages.size
|
||||||
|
|
||||||
%div{ :class => rtl?(conversation.subject) }
|
%div{ :class => direction_for(conversation.subject) }
|
||||||
= conversation.subject[0..30]
|
= conversation.subject[0..30]
|
||||||
|
|
||||||
.last_author
|
.last_author
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
.span-16.last
|
.span-16.last
|
||||||
.conversation_participants
|
.conversation_participants
|
||||||
.span-9
|
.span-9
|
||||||
%h3{ :class => rtl?(conversation.subject) }
|
%h3{ :class => direction_for(conversation.subject) }
|
||||||
= conversation.subject
|
= conversation.subject
|
||||||
|
|
||||||
.conversation_controls
|
.conversation_controls
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,6 @@
|
||||||
%time.timeago{:datetime => message.created_at}
|
%time.timeago{:datetime => message.created_at}
|
||||||
= how_long_ago(message)
|
= how_long_ago(message)
|
||||||
|
|
||||||
%p{ :class => rtl?(message.text) }
|
%p{ :class => direction_for(message.text) }
|
||||||
= markdownify(message.text)
|
= markdownify(message.text)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,13 @@
|
||||||
%li
|
%li
|
||||||
%h4
|
%h4
|
||||||
=t('.bio')
|
=t('.bio')
|
||||||
%div{ :class => rtl?(person.profile.bio) }
|
%div{ :class => direction_for(person.profile.bio) }
|
||||||
= markdownify(person.profile.bio, :newlines => true)
|
= markdownify(person.profile.bio, :newlines => true)
|
||||||
- unless person.profile.location.blank?
|
- unless person.profile.location.blank?
|
||||||
%li
|
%li
|
||||||
%h4
|
%h4
|
||||||
=t('.location')
|
=t('.location')
|
||||||
%div{ :class => rtl?(person.profile.location) }
|
%div{ :class => direction_for(person.profile.location) }
|
||||||
= markdownify(person.profile.location, :newlines => true)
|
= markdownify(person.profile.location, :newlines => true)
|
||||||
|
|
||||||
%li.span-8.last
|
%li.span-8.last
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,5 @@
|
||||||
- for photo in photos[1..photos.size]
|
- for photo in photos[1..photos.size]
|
||||||
= link_to (image_tag photo.url(:thumb_small), :class => 'thumb_small'), photo_path(photo)
|
= link_to (image_tag photo.url(:thumb_small), :class => 'thumb_small'), photo_path(photo)
|
||||||
|
|
||||||
%p{ :class => rtl?(post.text) }
|
%p{ :class => direction_for(post.text) }
|
||||||
= markdownify(post.text, :youtube_maps => post[:youtube_titles])
|
= markdownify(post.text, :youtube_maps => post[:youtube_titles])
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,5 @@
|
||||||
# Copyright (c) 2010, Diaspora Inc. This file is
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
# Deeply inspired by https://gitorious.org/statusnet/mainline/blobs/master/plugins/DirectionDetector/DirectionDetectorPlugin.php
|
|
||||||
|
|
||||||
class String
|
require File.join(Rails.root, 'lib/direction_detector')
|
||||||
|
|
||||||
def is_rtl?
|
|
||||||
count = 0
|
|
||||||
self.strip.split(" ").each do |word|
|
|
||||||
if starts_with_rtl_char?(word)
|
|
||||||
count += 1
|
|
||||||
else
|
|
||||||
count -= 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true if count > 0 # more than half of the words are rtl words
|
|
||||||
return starts_with_rtl_char?(self.strip) # otherwise let the first word decide
|
|
||||||
end
|
|
||||||
|
|
||||||
# Diaspora specific
|
|
||||||
def cleaned_is_rtl?
|
|
||||||
string = String.new(self)
|
|
||||||
[ /@[^ ]+|#[^ ]+/u, # mention, tag
|
|
||||||
/^RT[: ]{1}| RT | RT: |[♺♻:]/u, # retweet
|
|
||||||
/[ \r\t\n]+/ # whitespaces
|
|
||||||
].each do |cleaner|
|
|
||||||
string.gsub!(cleaner, '')
|
|
||||||
end
|
|
||||||
string.is_rtl?
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def starts_with_rtl_char?(string)
|
|
||||||
string = self.strip
|
|
||||||
return false if string.empty?
|
|
||||||
char = string.unpack('U*').first
|
|
||||||
limits = [
|
|
||||||
[1536, 1791], # arabic, persian, urdu, kurdish, ...
|
|
||||||
[65136, 65279], # arabic peresent 2
|
|
||||||
[64336, 65023], # arabic peresent 1
|
|
||||||
[1424, 1535], # hebrew
|
|
||||||
[64256, 64335], # hebrew peresent
|
|
||||||
[1792, 1871], # syriac
|
|
||||||
[1920, 1983], # thaana
|
|
||||||
[1984, 2047], # nko
|
|
||||||
[11568, 11647] # tifinagh
|
|
||||||
]
|
|
||||||
limits.each do |limit|
|
|
||||||
return true if char >= limit[0] && char <= limit[1]
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
||||||
52
lib/direction_detector.rb
Normal file
52
lib/direction_detector.rb
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
# Deeply inspired by https://gitorious.org/statusnet/mainline/blobs/master/plugins/DirectionDetector/DirectionDetectorPlugin.php
|
||||||
|
|
||||||
|
class String
|
||||||
|
|
||||||
|
def is_rtl?
|
||||||
|
return false if self.strip.empty?
|
||||||
|
count = 0
|
||||||
|
self.split(" ").each do |word|
|
||||||
|
if starts_with_rtl_char?(word)
|
||||||
|
count += 1
|
||||||
|
else
|
||||||
|
count -= 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true if count > 0 # more than half of the words are rtl words
|
||||||
|
return starts_with_rtl_char?(self) # otherwise let the first word decide
|
||||||
|
end
|
||||||
|
|
||||||
|
# Diaspora specific
|
||||||
|
def cleaned_is_rtl?
|
||||||
|
string = String.new(self)
|
||||||
|
[ /@[^ ]+|#[^ ]+/u, # mention, tag
|
||||||
|
/^RT[: ]{1}| RT | RT: |[♺♻:]/u # retweet
|
||||||
|
].each do |cleaner|
|
||||||
|
string.gsub!(cleaner, '')
|
||||||
|
end
|
||||||
|
string.is_rtl?
|
||||||
|
end
|
||||||
|
|
||||||
|
def starts_with_rtl_char?(string = self)
|
||||||
|
return false if string.strip.empty?
|
||||||
|
char = string.strip.unpack('U*').first
|
||||||
|
limits = [
|
||||||
|
[1536, 1791], # arabic, persian, urdu, kurdish, ...
|
||||||
|
[65136, 65279], # arabic peresent 2
|
||||||
|
[64336, 65023], # arabic peresent 1
|
||||||
|
[1424, 1535], # hebrew
|
||||||
|
[64256, 64335], # hebrew peresent
|
||||||
|
[1792, 1871], # syriac
|
||||||
|
[1920, 1983], # thaana
|
||||||
|
[1984, 2047], # nko
|
||||||
|
[11568, 11647] # tifinagh
|
||||||
|
]
|
||||||
|
limits.each do |limit|
|
||||||
|
return true if char >= limit[0] && char <= limit[1]
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -49,7 +49,7 @@ Diaspora.widgets.add("directionDetector", function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.bind = function() {
|
this.bind = function() {
|
||||||
$(this).one('keyup', Diaspora.widgets.directionDetector.updateDirection);
|
$(this).bind('keyup', Diaspora.widgets.directionDetector.updateDirection);
|
||||||
Diaspora.widgets.directionDetector.binds.push($(this));
|
Diaspora.widgets.directionDetector.binds.push($(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
89
spec/lib/direction_detector_spec.rb
Normal file
89
spec/lib/direction_detector_spec.rb
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe String do
|
||||||
|
let(:english) { "Hello World" }
|
||||||
|
let(:chinese) { "你好世界" }
|
||||||
|
let(:arabic) { "مرحبا العالم" }
|
||||||
|
let(:hebrew) { "שלום העולם" }
|
||||||
|
let(:english_chinese) { "#{english} #{chinese}" }
|
||||||
|
let(:english_arabic) { "#{english} #{chinese}" }
|
||||||
|
let(:english_hebrew) { "#{english} #{chinese}" }
|
||||||
|
let(:chinese_english) { "#{chinese} #{english}" }
|
||||||
|
let(:chinese_arabic) { "#{chinese} #{arabic}" }
|
||||||
|
let(:chinese_hebrew) { "#{chinese} #{hebrew}" }
|
||||||
|
let(:arabic_english) { "#{arabic} #{english}" }
|
||||||
|
let(:arabic_chinese) { "#{arabic} #{chinese}" }
|
||||||
|
let(:arabic_hebrew) { "#{arabic} #{hebrew}" }
|
||||||
|
let(:hebrew_english) { "#{hebrew} #{english}" }
|
||||||
|
let(:hebrew_chinese) { "#{hebrew} #{chinese}" }
|
||||||
|
let(:hebrew_arabic) { "#{hebrew} #{arabic}" }
|
||||||
|
|
||||||
|
|
||||||
|
describe "#stats_with_rtl_char?" do
|
||||||
|
it 'returns true or false correctly' do
|
||||||
|
english.starts_with_rtl_char?.should be_false
|
||||||
|
chinese.starts_with_rtl_char?.should be_false
|
||||||
|
arabic.starts_with_rtl_char?.should be_true
|
||||||
|
hebrew.starts_with_rtl_char?.should be_true
|
||||||
|
hebrew_arabic.starts_with_rtl_char?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'only looks at the first char' do
|
||||||
|
english_chinese.starts_with_rtl_char?.should be_false
|
||||||
|
chinese_english.starts_with_rtl_char?.should be_false
|
||||||
|
english_arabic.starts_with_rtl_char?.should be_false
|
||||||
|
hebrew_english.starts_with_rtl_char?.should be_true
|
||||||
|
arabic_chinese.starts_with_rtl_char?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ignores whitespaces' do
|
||||||
|
" \n \r \t".starts_with_rtl_char?.should be_false
|
||||||
|
" #{arabic} ".starts_with_rtl_char?.should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#is_rtl?" do
|
||||||
|
it 'returns true or false correctly' do
|
||||||
|
english.is_rtl?.should be_false
|
||||||
|
chinese.is_rtl?.should be_false
|
||||||
|
arabic.is_rtl?.should be_true
|
||||||
|
hebrew.is_rtl?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'respects all words' do
|
||||||
|
chinese_arabic.is_rtl?.should be_true
|
||||||
|
chinese_hebrew.is_rtl?.should be_true
|
||||||
|
english_hebrew.is_rtl?.should be_false
|
||||||
|
hebrew_arabic.is_rtl?.should be_true
|
||||||
|
"#{english} #{arabic} #{chinese}".is_rtl?.should be_false
|
||||||
|
"Translated to arabic, Hello World means: #{arabic}".is_rtl?.should be_false
|
||||||
|
"#{english} #{arabic} #{arabic}".is_rtl?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fallbacks to the first word if there's no majority" do
|
||||||
|
hebrew_english.is_rtl?.should be_true
|
||||||
|
english_hebrew.is_rtl?.should be_false
|
||||||
|
arabic_english.is_rtl?.should be_true
|
||||||
|
english_arabic.is_rtl?.should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'ignores whitespaces' do
|
||||||
|
" \n \r \t".is_rtl?.should be_false
|
||||||
|
" #{arabic} ".is_rtl?.should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#cleaned_is_rtl?' do
|
||||||
|
it 'should clean the string' do
|
||||||
|
"RT: #{arabic}".cleaned_is_rtl?.should be_true
|
||||||
|
"#{hebrew} RT: #{arabic}".cleaned_is_rtl?.should be_true
|
||||||
|
"@foo #{arabic}".cleaned_is_rtl?.should be_true
|
||||||
|
"#{hebrew} #example".cleaned_is_rtl?.should be_true
|
||||||
|
"♺: #{arabic} ♻: #{hebrew}".cleaned_is_rtl?.should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue