twitter-text 1.4.16 → 1.4.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/autolink.rb +62 -7
- data/lib/regex.rb +50 -3
- data/spec/autolinking_spec.rb +17 -0
- data/twitter-text.gemspec +1 -1
- metadata +4 -4
data/lib/autolink.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
1
3
|
require 'set'
|
|
2
4
|
|
|
3
5
|
module Twitter
|
|
@@ -148,14 +150,11 @@ module Twitter
|
|
|
148
150
|
url_entities = {}
|
|
149
151
|
if options[:url_entities]
|
|
150
152
|
options[:url_entities].each do |entity|
|
|
151
|
-
entity = entity
|
|
152
|
-
url_entities[entity[:url]] = entity
|
|
153
|
+
url_entities[entity["url"]] = entity
|
|
153
154
|
end
|
|
154
155
|
options.delete(:url_entities)
|
|
155
156
|
end
|
|
156
157
|
|
|
157
|
-
html_attrs = html_attrs_for_options(options)
|
|
158
|
-
|
|
159
158
|
Twitter::Rewriter.rewrite_urls(text) do |url|
|
|
160
159
|
# In the case of t.co URLs, don't allow additional path characters
|
|
161
160
|
after = ""
|
|
@@ -171,11 +170,67 @@ module Twitter
|
|
|
171
170
|
end
|
|
172
171
|
|
|
173
172
|
display_url = url
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
link_text = html_escape(display_url)
|
|
174
|
+
if url_entities[url] && url_entities[url]["display_url"]
|
|
175
|
+
display_url = url_entities[url]["display_url"]
|
|
176
|
+
expanded_url = url_entities[url]["expanded_url"]
|
|
177
|
+
if !options[:title]
|
|
178
|
+
options[:title] = expanded_url
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
|
|
182
|
+
# should contain the full original URL (expanded_url), not the display URL.
|
|
183
|
+
#
|
|
184
|
+
# Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
|
|
185
|
+
# font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
|
|
186
|
+
# Elements with font-size:0 get copied even though they are not visible.
|
|
187
|
+
# Note that display:none doesn't work here. Elements with display:none don't get copied.
|
|
188
|
+
#
|
|
189
|
+
# Additionally, we want to *display* ellipses, but we don't want them copied. To make this happen we
|
|
190
|
+
# wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
|
|
191
|
+
# everything with the tco-ellipsis class.
|
|
192
|
+
#
|
|
193
|
+
# Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/#!/username/status/1234/photo/1
|
|
194
|
+
# For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
|
|
195
|
+
# For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.
|
|
196
|
+
display_url_sans_ellipses = display_url.sub("…", "")
|
|
197
|
+
if expanded_url.include?(display_url_sans_ellipses)
|
|
198
|
+
display_url_index = expanded_url.index(display_url_sans_ellipses)
|
|
199
|
+
before_display_url = expanded_url.slice(0, display_url_index)
|
|
200
|
+
# Portion of expanded_url that comes after display_url
|
|
201
|
+
after_display_url = expanded_url.slice(display_url_index + display_url_sans_ellipses.length, 999999)
|
|
202
|
+
preceding_ellipsis = display_url.match(/^…/) ? "…" : ""
|
|
203
|
+
following_ellipsis = display_url.match(/…$/) ? "…" : ""
|
|
204
|
+
# As an example: The user tweets "hi http://longdomainname.com/foo"
|
|
205
|
+
# This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
|
|
206
|
+
# This will get rendered as:
|
|
207
|
+
# <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
|
|
208
|
+
# …
|
|
209
|
+
# <!-- There's a chance the onCopy event handler might not fire. In case that happens,
|
|
210
|
+
# we include an here so that the … doesn't bump up against the URL and ruin it.
|
|
211
|
+
# The is inside the tco-ellipsis span so that when the onCopy handler *does*
|
|
212
|
+
# fire, it doesn't get copied. Otherwise the copied text would have two spaces in a row,
|
|
213
|
+
# e.g. "hi http://longdomainname.com/foo".
|
|
214
|
+
# <span style='font-size:0'> </span>
|
|
215
|
+
# </span>
|
|
216
|
+
# <span style='font-size:0'> <!-- This stuff should get copied but not displayed -->
|
|
217
|
+
# http://longdomai
|
|
218
|
+
# </span>
|
|
219
|
+
# <span class='js-display-url'> <!-- This stuff should get displayed *and* copied -->
|
|
220
|
+
# nname.com/foo
|
|
221
|
+
# </span>
|
|
222
|
+
# <span class='tco-ellipsis'> <!-- This stuff should get displayed but not copied -->
|
|
223
|
+
# <span style='font-size:0'> </span>
|
|
224
|
+
# …
|
|
225
|
+
# </span>
|
|
226
|
+
invisible = "style='font-size:0; line-height:0'"
|
|
227
|
+
link_text = "<span class='tco-ellipsis'>#{preceding_ellipsis}<span #{invisible}> </span></span><span #{invisible}>#{html_escape before_display_url}</span><span class='js-display-url'>#{html_escape display_url_sans_ellipses}</span><span #{invisible}>#{after_display_url}</span><span class='tco-ellipsis'><span #{invisible}> </span>#{following_ellipsis}</span>"
|
|
228
|
+
end
|
|
176
229
|
end
|
|
177
230
|
|
|
178
|
-
|
|
231
|
+
html_attrs = html_attrs_for_options(options)
|
|
232
|
+
|
|
233
|
+
%(<a href="#{href}"#{html_attrs}>#{link_text}</a>#{after})
|
|
179
234
|
end
|
|
180
235
|
end
|
|
181
236
|
|
data/lib/regex.rb
CHANGED
|
@@ -65,7 +65,19 @@ module Twitter
|
|
|
65
65
|
regex_range(0xc0, 0xd6),
|
|
66
66
|
regex_range(0xd8, 0xf6),
|
|
67
67
|
regex_range(0xf8, 0xff),
|
|
68
|
-
regex_range(
|
|
68
|
+
regex_range(0x0100, 0x024f),
|
|
69
|
+
regex_range(0x0253, 0x0254),
|
|
70
|
+
regex_range(0x0256, 0x0257),
|
|
71
|
+
regex_range(0x0259),
|
|
72
|
+
regex_range(0x025b),
|
|
73
|
+
regex_range(0x0263),
|
|
74
|
+
regex_range(0x0268),
|
|
75
|
+
regex_range(0x026f),
|
|
76
|
+
regex_range(0x0272),
|
|
77
|
+
regex_range(0x0289),
|
|
78
|
+
regex_range(0x028b),
|
|
79
|
+
regex_range(0x02bb),
|
|
80
|
+
regex_range(0x1e00, 0x1eff)
|
|
69
81
|
].join('').freeze
|
|
70
82
|
|
|
71
83
|
NON_LATIN_HASHTAG_CHARS = [
|
|
@@ -74,13 +86,48 @@ module Twitter
|
|
|
74
86
|
regex_range(0x0500, 0x0527), # Cyrillic Supplement
|
|
75
87
|
regex_range(0x2de0, 0x2dff), # Cyrillic Extended A
|
|
76
88
|
regex_range(0xa640, 0xa69f), # Cyrillic Extended B
|
|
77
|
-
#
|
|
89
|
+
regex_range(0x0591, 0x05bd), # Hebrew
|
|
90
|
+
regex_range(0x05bf),
|
|
91
|
+
regex_range(0x05c1, 0x05c2),
|
|
92
|
+
regex_range(0x05c4, 0x05c5),
|
|
93
|
+
regex_range(0x05c7),
|
|
94
|
+
regex_range(0x05d0, 0x05ea),
|
|
95
|
+
regex_range(0x05f0, 0x05f2),
|
|
96
|
+
regex_range(0xfb12, 0xfb28), # Hebrew Presentation Forms
|
|
97
|
+
regex_range(0xfb2a, 0xfb36),
|
|
98
|
+
regex_range(0xfb38, 0xfb3c),
|
|
99
|
+
regex_range(0xfb3e),
|
|
100
|
+
regex_range(0xfb40, 0xfb41),
|
|
101
|
+
regex_range(0xfb43, 0xfb44),
|
|
102
|
+
regex_range(0xfb46, 0xfb4f),
|
|
103
|
+
regex_range(0x0610, 0x061a), # Arabic
|
|
104
|
+
regex_range(0x0620, 0x065f),
|
|
105
|
+
regex_range(0x066e, 0x06d3),
|
|
106
|
+
regex_range(0x06d5, 0x06dc),
|
|
107
|
+
regex_range(0x06de, 0x06e8),
|
|
108
|
+
regex_range(0x06ea, 0x06ef),
|
|
109
|
+
regex_range(0x06fa, 0x06fc),
|
|
110
|
+
regex_range(0x06ff),
|
|
111
|
+
regex_range(0x0750, 0x077f), # Arabic Supplement
|
|
112
|
+
regex_range(0x08a0), # Arabic Extended A
|
|
113
|
+
regex_range(0x08a2, 0x08ac),
|
|
114
|
+
regex_range(0x08e4, 0x08fe),
|
|
115
|
+
regex_range(0xfb50, 0xfbb1), # Arabic Pres. Forms A
|
|
116
|
+
regex_range(0xfbd3, 0xfd3d),
|
|
117
|
+
regex_range(0xfd50, 0xfd8f),
|
|
118
|
+
regex_range(0xfd92, 0xfdc7),
|
|
119
|
+
regex_range(0xfdf0, 0xfdfb),
|
|
120
|
+
regex_range(0xfe70, 0xfe74), # Arabic Pres. Forms B
|
|
121
|
+
regex_range(0xfe76, 0xfefc),
|
|
122
|
+
regex_range(0x200c, 0x200c), # Zero-Width Non-Joiner
|
|
123
|
+
regex_range(0x0e01, 0x0e3a), # Thai
|
|
124
|
+
regex_range(0x0e40, 0x0e4e), # Hangul (Korean)
|
|
78
125
|
regex_range(0x1100, 0x11ff), # Hangul Jamo
|
|
79
126
|
regex_range(0x3130, 0x3185), # Hangul Compatibility Jamo
|
|
80
127
|
regex_range(0xA960, 0xA97F), # Hangul Jamo Extended-A
|
|
81
128
|
regex_range(0xAC00, 0xD7AF), # Hangul Syllables
|
|
82
129
|
regex_range(0xD7B0, 0xD7FF), # Hangul Jamo Extended-B
|
|
83
|
-
regex_range(0xFFA1, 0xFFDC)
|
|
130
|
+
regex_range(0xFFA1, 0xFFDC) # Half-width Hangul
|
|
84
131
|
].join('').freeze
|
|
85
132
|
REGEXEN[:latin_accents] = /[#{LATIN_ACCENTS}]+/o
|
|
86
133
|
|
data/spec/autolinking_spec.rb
CHANGED
|
@@ -546,6 +546,23 @@ describe Twitter::Autolink do
|
|
|
546
546
|
end
|
|
547
547
|
|
|
548
548
|
describe "autolinking options" do
|
|
549
|
+
it "should show display_url when :url_entities provided" do
|
|
550
|
+
linked = TestAutolink.new.auto_link("http://t.co/0JG5Mcq", :url_entities => [{
|
|
551
|
+
"url" => "http://t.co/0JG5Mcq",
|
|
552
|
+
"display_url" => "blog.twitter.com/2011/05/twitte…",
|
|
553
|
+
"expanded_url" => "http://blog.twitter.com/2011/05/twitter-for-mac-update.html",
|
|
554
|
+
"indices" => [
|
|
555
|
+
84,
|
|
556
|
+
103
|
|
557
|
+
]
|
|
558
|
+
}])
|
|
559
|
+
html = Nokogiri::HTML(linked)
|
|
560
|
+
html.search('a').should_not be_empty
|
|
561
|
+
html.search('a[@href="http://t.co/0JG5Mcq"]').should_not be_empty
|
|
562
|
+
html.search('span[@class=js-display-url]').inner_text.should == "blog.twitter.com/2011/05/twitte"
|
|
563
|
+
html.inner_text.should == " http://blog.twitter.com/2011/05/twitter-for-mac-update.html …"
|
|
564
|
+
end
|
|
565
|
+
|
|
549
566
|
it "should apply :url_class as a CSS class" do
|
|
550
567
|
linked = TestAutolink.new.auto_link("http://example.com/", :url_class => 'myclass')
|
|
551
568
|
linked.should have_autolinked_url('http://example.com/')
|
data/twitter-text.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = "twitter-text"
|
|
5
|
-
s.version = "1.4.
|
|
5
|
+
s.version = "1.4.17"
|
|
6
6
|
s.authors = ["Matt Sanford", "Patrick Ewing", "Ben Cherry", "Britt Selvitelle",
|
|
7
7
|
"Raffi Krikorian", "J.P. Cummins", "Yoshimasa Niwa", "Keita Fujii"]
|
|
8
8
|
s.email = ["matt@twitter.com", "patrick.henry.ewing@gmail.com", "bcherry@gmail.com", "bs@brittspace.com",
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: twitter-text
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 37
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
8
|
- 4
|
|
9
|
-
-
|
|
10
|
-
version: 1.4.
|
|
9
|
+
- 17
|
|
10
|
+
version: 1.4.17
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Matt Sanford
|
|
@@ -22,7 +22,7 @@ autorequire:
|
|
|
22
22
|
bindir: bin
|
|
23
23
|
cert_chain: []
|
|
24
24
|
|
|
25
|
-
date: 2012-02-
|
|
25
|
+
date: 2012-02-23 00:00:00 -08:00
|
|
26
26
|
default_executable:
|
|
27
27
|
dependencies:
|
|
28
28
|
- !ruby/object:Gem::Dependency
|