Repository: oppia/oppia

Issue:
Add more rules for HTML lint checks
The following rules need to be added to the existing HTML lint checks:

1. For HTML attributes, the value should be enclosed in double quotes.  
2. For tags not ending on a single line, a line break should be inserted after the opening tag -- _Done in PR #5171_
    (Refer to [this](https://github.com/oppia/oppia/pull/5094#discussion_r195887845) for further details):
```html
   <tag>
      This tag extends to multiple lines.
   </tag>                            
 ```









(_More rules may be added to the list as and when required._)


Discussion:
@apb7 are you still working on this?
Hi @jacobdavis11, the second check has been already been put in place. I will pick up the first one in a couple of days.
Thanks!

Resolving patch:
diff --git a/scripts/pre_commit_linter.py b/scripts/pre_commit_linter.py
--- a/scripts/pre_commit_linter.py
+++ b/scripts/pre_commit_linter.py
@@ -1323,6 +1323,30 @@ def handle_starttag(self, tag, attrs):
             column_number + len(tag) + 2)
         starttag_text = self.get_starttag_text()
 
+        # Check whether the values of all attributes are placed
+        # in double quotes.
+        for attr, value in attrs:
+            # Not all attributes will have a value.
+            # Therefore the check should run only for those
+            # attributes which have a value.
+            if value:
+                expected_value = '"' + value + '"'
+
+                # &quot; is rendered as a double quote by the parser.
+                if '&quot;' in starttag_text:
+                    rendered_text = starttag_text.replace('&quot;', '"')
+                else:
+                    rendered_text = starttag_text
+
+                if not expected_value in rendered_text:
+                    self.failed = True
+                    print (
+                        '%s --> The value %s of attribute '
+                        '%s for the tag %s on line %s should '
+                        'be enclosed within double quotes.' % (
+                            self.filename, value, attr,
+                            tag, line_number))
+
         for line_num, line in enumerate(
                 str.splitlines(starttag_text)):
             if line_num == 0:
@@ -1392,10 +1416,10 @@ def handle_data(self, data):
                 self.indentation_level -= 1
 
 
-def _check_html_indent(all_files, debug=False):
+def _check_html_tags_and_attributes(all_files, debug=False):
     """This function checks the indentation of lines in HTML files."""
 
-    print 'Starting HTML indentation check'
+    print 'Starting HTML tag and attribute check'
     print '----------------------------------------'
 
     html_files_to_lint = [
@@ -1418,12 +1442,12 @@ def _check_html_indent(all_files, debug=False):
                 failed = True
 
     if failed:
-        summary_message = '%s   HTML indentation check failed' % (
+        summary_message = '%s   HTML tag and attribute check failed' % (
             _MESSAGE_TYPE_FAILED)
         print summary_message
         summary_messages.append(summary_message)
     else:
-        summary_message = '%s  HTML indentation check passed' % (
+        summary_message = '%s  HTML tag and attribute check passed' % (
             _MESSAGE_TYPE_SUCCESS)
         print summary_message
         summary_messages.append(summary_message)
@@ -1503,9 +1527,9 @@ def main():
     newline_messages = _check_newline_character(all_files)
     docstring_messages = _check_docstrings(all_files)
     comment_messages = _check_comments(all_files)
-    # The html indent check has an additional debug mode which
-    # when enabled prints the tag_stack for each file.
-    html_indent_messages = _check_html_indent(all_files)
+    # The html tags and attributes check check has an additional
+    # debug mode which when enabled prints the tag_stack for each file.
+    html_tag_and_attribute_messages = _check_html_tags_and_attributes(all_files)
     html_linter_messages = _lint_html_files(all_files)
     linter_messages = _pre_commit_linter(all_files)
     pattern_messages = _check_bad_patterns(all_files)
@@ -1514,7 +1538,7 @@ def main():
         directive_scope_messages + controller_dependency_messages +
         html_directive_name_messages + import_order_messages +
         newline_messages + docstring_messages + comment_messages +
-        html_indent_messages + html_linter_messages +
+        html_tag_and_attribute_messages + html_linter_messages +
         linter_messages + pattern_messages +
         copyright_notice_messages)
     if any([message.startswith(_MESSAGE_TYPE_FAILED) for message in


Test patch:
diff --git a/core/templates/dev/head/pages/exploration_editor/editor_tab/test_interaction_modal_directive.html b/core/templates/dev/head/pages/exploration_editor/editor_tab/test_interaction_modal_directive.html
--- a/core/templates/dev/head/pages/exploration_editor/editor_tab/test_interaction_modal_directive.html
+++ b/core/templates/dev/head/pages/exploration_editor/editor_tab/test_interaction_modal_directive.html
@@ -30,7 +30,7 @@
     </div>
   </div>
   <br>
-  <div class='submit-answer-btn'>
+  <div class="submit-answer-btn">
     <md-button class="oppia-learner-confirm-button protractor-test-submit-answer-button"
                ng-disabled="!interactionAnswerIsValid"
                ng-click="onSubmitAnswerFromButton()"