Long URLs are diluted with zero-width whitespaces

Zero-width spaces affect wrapping the same way as normal spaces but have no width.
Also added moved text formatting code into utils.

Closes bug 1229723

Change-Id: If6de83b6bf4125e8d48de203fe2d5cd935b20757
This commit is contained in:
Ilya Shakhat 2013-09-24 18:23:01 +04:00
parent f05b67954c
commit 2a7ee69fb8
5 changed files with 43 additions and 35 deletions

View File

@ -28,6 +28,11 @@
<div><span class="label">Registered By:</span> {{blueprint.author_name}} ({{ blueprint.company_name }})</div>
<div><span class="label">Registered On:</span> {{blueprint.date_str}}</div>
{% if blueprint.summary %}
<h2>Summary</h2>
<div class="message">{{ blueprint.summary }}</div>
{% endif %}
{% if blueprint.whiteboard %}
<h2>Whiteboard</h2>
<div class="message">{{ blueprint.whiteboard }}</div>

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import cgi
import datetime
import functools
import json
@ -664,6 +663,7 @@ def get_activity_json(records):
(record['record_type'] == 'bpc')):
blueprint = record.copy()
_extend_record(blueprint)
blueprint['summary'] = utils.format_text(record['summary'])
if 'mention_date' in record:
blueprint['mention_date_str'] = format_datetime(
record['mention_date'])
@ -976,28 +976,11 @@ def make_link(title, uri=None, options=None):
return '<a href="%(uri)s">%(title)s</a>' % {'uri': uri, 'title': title}
def unwrap_text(text):
res = ''
for line in text.splitlines():
s = line.rstrip()
if not s:
continue
res += line
if (not s[0].isalpha()) or (s[-1] in ['.', '!', '?', '>', ':', ';']):
res += '\n'
else:
res += ' '
return res.rstrip()
@app.template_filter('commit_message')
def make_commit_message(record):
s = record['message']
module = record['module']
# clear text
s = cgi.escape(re.sub(re.compile('\n{2,}', flags=re.MULTILINE), '\n', s))
s = re.sub(r'([/\/]+)', r'\1&#8203;', s)
s = utils.format_text(s)
# insert links
s = re.sub(re.compile('(blueprint\s+)([\w-]+)', flags=re.IGNORECASE),
@ -1010,7 +993,7 @@ def make_commit_message(record):
r' <a href="https://review.openstack.org/#q,\1,n,z" '
r'class="ext_link">\1</a>', s)
s = unwrap_text(s)
s = utils.unwrap_text(s)
return s

View File

@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import cgi
import datetime
import iso8601
import json
@ -87,3 +88,23 @@ def load_user(runtime_storage_inst, user_id):
def load_repos(runtime_storage_inst):
return runtime_storage_inst.get_by_key('repos') or []
def unwrap_text(text):
res = ''
for line in text.splitlines():
s = line.rstrip()
if not s:
continue
res += line
if (not s[0].isalpha()) or (s[-1] in ['.', '!', '?', '>', ':', ';']):
res += '\n'
else:
res += ' '
return res.rstrip()
def format_text(s):
s = cgi.escape(re.sub(re.compile('\n{2,}', flags=re.MULTILINE), '\n', s))
s = re.sub(r'([/\/]+)', r'\1&#8203;', s)
return s

View File

@ -50,3 +50,17 @@ class TestUtils(testtools.TestCase):
def test_email_invalid(self):
self.assertFalse(utils.check_email_validity('pupkin@localhost'))
self.assertFalse(utils.check_email_validity('222@some.(trash)'))
def test_unwrap(self):
original = 'Lorem ipsum. Dolor\nsit amet.\n Lorem\n ipsum.\ndolor!\n'
expected = 'Lorem ipsum. Dolor sit amet.\n Lorem\n ipsum.\ndolor!'
self.assertEqual(expected, utils.unwrap_text(original))
def test_format_text_split_long_link(self):
original = ('https://blueprints.launchpad.net/stackalytics/+spec/'
'stackalytics-core')
expected = ('https://&#8203;blueprints.launchpad.net/&#8203;'
'stackalytics/&#8203;+spec/&#8203;stackalytics-core')
self.assertEqual(expected, utils.format_text(original))

View File

@ -82,21 +82,6 @@ Implements Blueprint ''' + (
self.assertEqual(expected, observed,
'Commit message should be processed correctly')
def test_unwrap(self):
original = 'Lorem ipsum. Dolor\nsit amet.\n Lorem\n ipsum.\ndolor!\n'
expected = 'Lorem ipsum. Dolor sit amet.\n Lorem\n ipsum.\ndolor!'
self.assertEqual(expected, web.unwrap_text(original))
def test_unwrap_split_long_link(self):
original = ('https://blueprints.launchpad.net/stackalytics/+spec/'
'stackalytics-core')
expected = ('https://&#8203;blueprints.launchpad.net/&#8203;'
'stackalytics/&#8203;+spec/&#8203;stackalytics-core')
self.assertEqual(expected, web.make_commit_message(
{'message': original, 'module': 'none'}))
@mock.patch('dashboard.web.get_vault')
@mock.patch('dashboard.web.get_user_from_runtime_storage')
def test_make_page_title(self, user_patch, vault_patch):