Merge from Chromium at DEPS revision r212014

This commit was generated by merge_to_master.py.

Change-Id: If2154daca257345f4d342af94fc5afb859510e2d
diff --git a/grit/format/chrome_messages_json.py b/grit/format/chrome_messages_json.py
index 5609122..7b370d7 100644
--- a/grit/format/chrome_messages_json.py
+++ b/grit/format/chrome_messages_json.py
@@ -6,6 +6,7 @@
 """Formats as a .json file that can be used to localize Google Chrome
 extensions."""
 
+from json import JSONEncoder
 import re
 import types
 
@@ -16,20 +17,19 @@
   """Format the messages as JSON."""
   yield '{\n'
 
+  encoder = JSONEncoder();
   format = ('  "%s": {\n'
-            '    "message": "%s"\n'
+            '    "message": %s\n'
             '  }')
   first = True
   for child in root.ActiveDescendants():
     if isinstance(child, message.MessageNode):
-      loc_message = child.Translate(lang)
-      loc_message = re.sub(r'\\', r'\\\\', loc_message)
-      loc_message = re.sub(r'"', r'\"', loc_message)
-
       id = child.attrs['name']
       if id.startswith('IDR_'):
         id = id[4:]
 
+      loc_message = encoder.encode(child.Translate(lang))
+
       if not first:
         yield ',\n'
       first = False
diff --git a/grit/format/chrome_messages_json_unittest.py b/grit/format/chrome_messages_json_unittest.py
index 8cbd672..484230f 100644
--- a/grit/format/chrome_messages_json_unittest.py
+++ b/grit/format/chrome_messages_json_unittest.py
@@ -53,7 +53,7 @@
     "message": "Simple message."
   },
   "IDS_QUOTES": {
-    "message": "element\u2019s \u201c%s\u201d attribute"
+    "message": "element\\u2019s \\u201c%s\\u201d attribute"
   },
   "IDS_PLACEHOLDERS": {
     "message": "%1$d error, %2$d warning"
@@ -86,10 +86,10 @@
     test = u"""
 {
   "ID_HELLO": {
-    "message": "H\xe9P\xe9ll\xf4P\xf4!"
+    "message": "H\\u00e9P\\u00e9ll\\u00f4P\\u00f4!"
   },
   "ID_HELLO_USER": {
-    "message": "H\xe9P\xe9ll\xf4P\xf4 %s"
+    "message": "H\\u00e9P\\u00e9ll\\u00f4P\\u00f4 %s"
   }
 }
 """
diff --git a/grit/format/html_inline.py b/grit/format/html_inline.py
index b5e0b0f..589e49b 100755
--- a/grit/format/html_inline.py
+++ b/grit/format/html_inline.py
@@ -32,11 +32,11 @@
 
 # Used by DoInline to replace various links with inline content.
 _STYLESHEET_RE = lazy_re.compile(
-    '<link rel="stylesheet"[^>]+?href="(?P<filename>[^"]*)".*?>',
-    re.MULTILINE)
+    '<link rel="stylesheet"[^>]+?href="(?P<filename>[^"]*)".*?>(\s*</link>)?',
+    re.DOTALL)
 _INCLUDE_RE = lazy_re.compile(
-    '<include[^>]+?src="(?P<filename>[^"\']*)".*>',
-    re.MULTILINE)
+    '<include[^>]+?src="(?P<filename>[^"\']*)".*?>(\s*</include>)?',
+    re.DOTALL)
 _SRC_RE = lazy_re.compile(
     r'<(?!script)(?:[^>]+?\s)src=(?P<quote>")(?P<filename>[^"\']*)\1',
     re.MULTILINE)
diff --git a/grit/format/html_inline_unittest.py b/grit/format/html_inline_unittest.py
index 45840f2..96d8750 100755
--- a/grit/format/html_inline_unittest.py
+++ b/grit/format/html_inline_unittest.py
@@ -262,6 +262,67 @@
     resources.add(tmp_dir.GetPath('index.html'))
     self.failUnlessEqual(resources, source_resources)
 
+  def testWithCloseTags(self):
+    '''Tests that close tags are removed.'''
+
+    files = {
+      'index.html': '''
+      <html>
+      <head>
+      <link rel="stylesheet" href="style1.css"></link>
+      <link rel="stylesheet" href="style2.css">
+      </link>
+      <link rel="stylesheet" href="style2.css"
+      >
+      </link>
+      <script src="script1.js"></script>
+      </head>
+      <include src="tmpl1.html"></include>
+      <include src="tmpl2.html">
+      </include>
+      <include src="tmpl2.html"
+      >
+      </include>
+      <img src="img1.png">
+      </html>
+      ''',
+      'style1.css': '''h1 {}''',
+      'style2.css': '''h2 {}''',
+      'tmpl1.html': '''<h1></h1>''',
+      'tmpl2.html': '''<h2></h2>''',
+      'script1.js': '''console.log('hello');''',
+      'img1.png': '''abc''',
+    }
+
+    expected_inlined = '''
+      <html>
+      <head>
+      <style>h1 {}</style>
+      <style>h2 {}</style>
+      <style>h2 {}</style>
+      <script>console.log('hello');</script>
+      </head>
+      <h1></h1>
+      <h2></h2>
+      <h2></h2>
+      <img src="data:image/png;base64,YWJj">
+      </html>
+      '''
+
+    source_resources = set()
+    tmp_dir = util.TempDir(files)
+    for filename in files:
+      source_resources.add(tmp_dir.GetPath(filename))
+
+    # Test normal inlining.
+    result = html_inline.DoInline(
+        tmp_dir.GetPath('index.html'),
+        None)
+    resources = result.inlined_files
+    resources.add(tmp_dir.GetPath('index.html'))
+    self.failUnlessEqual(resources, source_resources)
+    self.failUnlessEqual(expected_inlined,
+                         util.FixLineEnd(result.inlined_data, '\n'))
 
 if __name__ == '__main__':
   unittest.main()