diff --git a/conformance/validate.yml b/conformance/validate.yml index f78b56e00..05328d2ec 100644 --- a/conformance/validate.yml +++ b/conformance/validate.yml @@ -33,6 +33,10 @@ tests: text: "A lie gets halfway around the world before the truth has a chance to get its pants on. \n-- Winston Churchill (1874-1965) http://bit.ly/dJpywL" expected: false + - description: "Valid Tweet: 140 characters (counting 2 character end-of-line as 1 character)" + text: "Lorem ipsum dolor sit amet consectetur adipiscing elit.\r\nCum sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus mus." + expected: true + usernames: - description: "Valid username: a-z < 20 characters" text: "@username" diff --git a/js/twitter-text.js b/js/twitter-text.js index eb4132b8c..1b8c04994 100644 --- a/js/twitter-text.js +++ b/js/twitter-text.js @@ -1067,6 +1067,10 @@ return text.replace(twttr.txt.regexen.non_bmp_code_pairs, ' ').length; }; + twttr.txt.cleanTweetText = function(text) { + return text.replace("\r\n", "\n") + }; + twttr.txt.convertUnicodeIndices = function(text, entities, indicesInUTF16) { if (entities.length == 0) { return; @@ -1249,9 +1253,10 @@ short_url_length_https: 23 }; } - var textLength = twttr.txt.getUnicodeTextLength(text), - urlsWithIndices = twttr.txt.extractUrlsWithIndices(text); - twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices); + var cleanText = twttr.txt.cleanTweetText(text), + textLength = twttr.txt.getUnicodeTextLength(cleanText), + urlsWithIndices = twttr.txt.extractUrlsWithIndices(cleanText); + twttr.txt.modifyIndicesFromUTF16ToUnicode(cleanText, urlsWithIndices); for (var i = 0; i < urlsWithIndices.length; i++) { // Subtract the length of the original URL diff --git a/rb/lib/twitter-text/validation.rb b/rb/lib/twitter-text/validation.rb index 659da88b5..ada2cbdee 100644 --- a/rb/lib/twitter-text/validation.rb +++ b/rb/lib/twitter-text/validation.rb @@ -25,9 +25,11 @@ module Validation extend self def tweet_length(text, options = {}) options = DEFAULT_TCO_URL_LENGTHS.merge(options) - length = text.to_nfc.unpack("U*").length + clean_text = clean_tweet_text(text) - Twitter::Extractor.extract_urls_with_indices(text) do |url, start_position, end_position| + length = clean_text.unpack("U*").length + + Twitter::Extractor.extract_urls_with_indices(clean_text) do |url, start_position, end_position| length += start_position - end_position length += url.downcase =~ /^https:\/\// ? options[:short_url_length_https] : options[:short_url_length] end @@ -109,5 +111,9 @@ def valid_match?(string, regex, optional=false) !(string && (!string.match(regex) || $~.to_s != string)) end + + def clean_tweet_text(text) + text.dup.to_nfc.gsub("\r\n", "\n") + end end end