Example #1
0
def find_valid(node, file, target_alt):
    name = getattr(node.value, "name", None)
    is_img = (isinstance(node.value, ast.Element) and name
              and name.lower() == "img")

    if is_img:
        attributes = []
        if getattr(node.value, "opening_tag", None):
            attributes = {}
            for n in node.value.opening_tag.attributes.nodes:
                if not isinstance(n, JinjaElement):
                    attributes[str(n.name)] = str(n.value).strip("\"'")

        if len(attributes) == 0 or "alt" not in attributes:
            return [
                Issue.from_node(
                    file,
                    node,
                    "The `<img>` tag must have a `alt` attribute, either with meaningful text, or an empty string for decorative images",
                    "image_alt",
                )
            ]

    if not node.children:
        return []

    return sum(
        (find_valid(child, file, target_alt) for child in node.children), [])
Example #2
0
def find_valid(node, file, target_alt):
    name = getattr(node.value, "name", None)
    is_input = (isinstance(node.value, ast.Element) and name
                and name.lower() == "input")

    if is_input:
        attributes = []
        if getattr(node.value, "opening_tag", None):
            attributes = {}
            for n in node.value.opening_tag.attributes.nodes:
                attributes[str(n.name)] = str(n.value).strip("\"'")

        if "autofocus" in attributes:
            return [
                Issue.from_node(
                    file,
                    node,
                    "Do not use the `autofocus` attribute, which causes issues for screen reader users",
                    "no_autofocus",
                )
            ]

    if not node.children:
        return []

    return sum(
        (find_valid(child, file, target_alt) for child in node.children), [])
Example #3
0
def find_role_errors(node, file, target_roles):
    attributes = []
    if getattr(node.value, "opening_tag", None):
        attributes = {}
        for n in node.value.opening_tag.attributes.nodes:
            attributes[str(n.name)] = str(n.value).strip("\"'")

    target = VALID_ROLES if target_roles is True else target_roles

    if "role" in attributes:
        return (
            []
            if attributes["role"] in target
            else [
                Issue.from_node(
                    file,
                    node,
                    "The `role` attribute needs to have a valid value",
                    "aria_role",
                )
            ]
        )

    if not node.children:
        return []

    return sum(
        (
            find_role_errors(child, file, target_roles)
            for child in node.children
        ),
        [],
    )
Example #4
0
def check_tab_only_indent(file):
    issues = []
    for i, line in enumerate(file.lines):
        indent = WHITESPACE_INDENT_RE.match(line).group(0)
        if not contains_exclusively(indent, "\t"):
            loc = IssueLocation(file_path=file.path, line=i, column=0)
            issue = Issue(loc, "Should be indented with tabs", INDENT)
            issues.append(issue)
    return issues
Example #5
0
def find_valid(node, file):
    name = getattr(node.value, "name", None)
    is_meta = (
        isinstance(node.value, ast.Element) and name and name.lower() == "meta"
    )

    if is_meta:
        attributes = []
        if getattr(node.value, "opening_tag", None):
            attributes = {}
            for n in node.value.opening_tag.attributes.nodes:
                attributes[str(n.name)] = str(n.value).strip("\"'")

        if "name" in attributes and attributes["name"] == "viewport":
            if "user-scalable=no" in attributes["content"]:
                return [
                    Issue.from_node(
                        file,
                        node,
                        "Remove `user-scalable=no` from the viewport meta so users can zoom",
                        "meta_viewport",
                    )
                ]

            if (
                "maximum-scale=1" in attributes["content"]
                or "maximum-scale=0" in attributes["content"]
            ):
                return [
                    Issue.from_node(
                        file,
                        node,
                        "`maximum-scale` should not be less than 2",
                        "meta_viewport",
                    )
                ]

    if not node.children:
        return []

    return sum((find_valid(child, file) for child in node.children), [])
Example #6
0
def find_valid(node, file, target_lang):
    name = getattr(node.value, "name", None)
    is_html = (isinstance(node.value, ast.Element) and name
               and name.lower() == "html")

    if is_html:
        attributes = []
        if getattr(node.value, "opening_tag", None):
            attributes = {}
            for n in node.value.opening_tag.attributes.nodes:
                attributes[str(getattr(n, "name",
                                       ""))] = str(getattr(n, "value",
                                                           "")).strip("\"'")
        if len(attributes) == 0 or "lang" not in attributes:
            return [
                Issue.from_node(
                    file,
                    node,
                    "The `<html>` tag should have a `lang` attribute with a valid value, describing the main language of the page",
                    "html_has_lang",
                )
            ]

        if target_lang[0] is True or attributes["lang"] in target_lang:
            return []
        else:
            return [
                Issue.from_node(
                    file,
                    node,
                    f"The `<html>` tag should have a `lang` attribute with a valid value, describing the main language of the page. Allowed values: {', '.join(target_lang)}",
                    "html_has_lang",
                )
            ]

    if not node.children:
        return []

    return sum(
        (find_valid(child, file, target_lang) for child in node.children), [])
def find_valid(node, file, disallowed_variants):
    if isinstance(node.value, ast.JinjaVariable):
        matches = [v for v in disallowed_variants if v in node.value.content]
        if matches:
            return [
                Issue.from_node(
                    file,
                    node,
                    f"Avoid using `{matches[0]}` to render Django forms",
                    DJANGO_FORMS_RENDERING,
                )
            ]

    if not node.children:
        return []

    return sum(
        (
            find_valid(child, file, disallowed_variants)
            for child in node.children
        ),
        [],
    )
Example #8
0
def find_valid(node, file):
    is_elt = isinstance(node.value, ast.Element)

    if is_elt:
        attributes = []
        if getattr(node.value, "opening_tag", None):
            attributes = {}
            for n in node.value.opening_tag.attributes.nodes:
                attributes[str(n.name)] = str(n.value).strip("\"'")

        if "tabindex" in attributes and int(attributes["tabindex"]) > 0:
            return [
                Issue.from_node(
                    file,
                    node,
                    "Avoid positive `tabindex` values, change the order of elements on the page instead",
                    "tabindex_no_positive",
                )
            ]

    if not node.children:
        return []

    return sum((find_valid(child, file) for child in node.children), [])
Example #9
0
 def add_issue(location, msg):
     issues.append(
         Issue.from_ast(file, location.line, location.column, msg, INDENT))