webcode-tk 0.7.4__tar.gz → 0.7.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/PKG-INFO +1 -1
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/pyproject.toml +1 -1
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/__init__.py +1 -1
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/css_tools.py +229 -1
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/LICENSE.rst +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/README.rst +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/color_keywords.py +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/color_tools.py +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/html_tools.py +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/ux_tools.py +0 -0
- {webcode_tk-0.7.4 → webcode_tk-0.7.6}/webcode_tk/validator_tools.py +0 -0
|
@@ -25,6 +25,7 @@ regex_patterns: dict = {
|
|
|
25
25
|
"adjacent_sibling_combinator": r"\w+\s*\+\s*\w+",
|
|
26
26
|
"general_sibling_combinator": r"\w+\s*~\s*\w+",
|
|
27
27
|
"grouped_selector": r"\w+\s*,\s*\w+",
|
|
28
|
+
"advanced_link_selector": r"(a[:.#\[]\w+)",
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
# all relevant at-rules.
|
|
@@ -97,6 +98,7 @@ class Stylesheet:
|
|
|
97
98
|
self.repeated_selectors = []
|
|
98
99
|
self.__minify()
|
|
99
100
|
self.__replace_variables()
|
|
101
|
+
self.__replace_variables()
|
|
100
102
|
self.__remove_external_imports()
|
|
101
103
|
self.__extract_comments()
|
|
102
104
|
self.__extract_nested_at_rules()
|
|
@@ -1295,7 +1297,12 @@ def get_color_codes_of_type(color_type: str, gradient: str) -> list:
|
|
|
1295
1297
|
|
|
1296
1298
|
|
|
1297
1299
|
def is_required_selector(selector_type: str, selector: str) -> bool:
|
|
1298
|
-
"""checks selector to see if it's required type or not
|
|
1300
|
+
"""checks selector to see if it's required type or not.
|
|
1301
|
+
|
|
1302
|
+
Example: you may wish to loop through selectors and see which
|
|
1303
|
+
ones are class selectors, or id selectors, etc..
|
|
1304
|
+
|
|
1305
|
+
It makes use of the list of regex_patterns for selector type.
|
|
1299
1306
|
|
|
1300
1307
|
Args:
|
|
1301
1308
|
selector_type: the type of selector in question, such as
|
|
@@ -1817,6 +1824,227 @@ def get_project_color_contrast(
|
|
|
1817
1824
|
return results
|
|
1818
1825
|
|
|
1819
1826
|
|
|
1827
|
+
def file_applies_property_by_selector(
|
|
1828
|
+
file_path: str, selector: str, property: str
|
|
1829
|
+
) -> bool:
|
|
1830
|
+
"""determines whether a specific property is applied to selector or not.
|
|
1831
|
+
|
|
1832
|
+
Args:
|
|
1833
|
+
file_path: path to html doc in question.
|
|
1834
|
+
selector: CSS selector (or element) that the property is applied.
|
|
1835
|
+
property: the CSS property we are looking for.
|
|
1836
|
+
|
|
1837
|
+
Returns:
|
|
1838
|
+
applies_property: whether that selector applies the property or not.
|
|
1839
|
+
"""
|
|
1840
|
+
applies_property = False
|
|
1841
|
+
style_sheets = get_all_stylesheets_by_file(file_path)
|
|
1842
|
+
|
|
1843
|
+
# look for the selector get all declaration block
|
|
1844
|
+
declarations = []
|
|
1845
|
+
for sheet in style_sheets:
|
|
1846
|
+
declaration_block = get_declaration_block_from_selector(
|
|
1847
|
+
selector, sheet
|
|
1848
|
+
)
|
|
1849
|
+
if declaration_block:
|
|
1850
|
+
declarations.append(declaration_block)
|
|
1851
|
+
combined_declaration_block = "\n".join(declarations)
|
|
1852
|
+
if combined_declaration_block:
|
|
1853
|
+
# check for property in declaration_block
|
|
1854
|
+
declarations = combined_declaration_block.split(";")
|
|
1855
|
+
for declaration in declarations:
|
|
1856
|
+
try:
|
|
1857
|
+
prop, value = declaration.split(":")
|
|
1858
|
+
if property in prop:
|
|
1859
|
+
applies_property = True
|
|
1860
|
+
break
|
|
1861
|
+
except ValueError:
|
|
1862
|
+
print("Declaration is missing a colon!")
|
|
1863
|
+
return applies_property
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
def get_declaration_block_from_selector(
|
|
1867
|
+
selector: str, style_sheet: Stylesheet
|
|
1868
|
+
) -> str:
|
|
1869
|
+
declaration_block = ""
|
|
1870
|
+
for ruleset in style_sheet.rulesets:
|
|
1871
|
+
cur_selector = ruleset.selector
|
|
1872
|
+
if selector in cur_selector:
|
|
1873
|
+
# Check for grouped selectors
|
|
1874
|
+
grouped_selectors = cur_selector.split(",")
|
|
1875
|
+
if len(grouped_selectors) > 1:
|
|
1876
|
+
for item in grouped_selectors:
|
|
1877
|
+
if selector in item:
|
|
1878
|
+
if " " not in item:
|
|
1879
|
+
declaration_block += ruleset.declaration_block.text
|
|
1880
|
+
break
|
|
1881
|
+
elif is_selector_at_end_of_descendant(selector, item):
|
|
1882
|
+
declaration_block += ruleset.declaration_block.text
|
|
1883
|
+
break
|
|
1884
|
+
|
|
1885
|
+
# Check for descendant selectors
|
|
1886
|
+
if " " in cur_selector:
|
|
1887
|
+
# we have a descendant selector
|
|
1888
|
+
if is_selector_at_end_of_descendant(selector, cur_selector):
|
|
1889
|
+
declaration_block += ruleset.declaration_block.text
|
|
1890
|
+
continue
|
|
1891
|
+
declaration_block += ruleset.declaration_block.text + "\n"
|
|
1892
|
+
return declaration_block
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
def is_selector_at_end_of_descendant(selector: str, cur_selector: str) -> bool:
|
|
1896
|
+
"""returns whether a selector is at the end of a descendant selector"""
|
|
1897
|
+
selector_at_end_of_descendant = False
|
|
1898
|
+
selectors = cur_selector.split()
|
|
1899
|
+
if selector in selectors[-1]:
|
|
1900
|
+
# selector must be at the end of descendant selector
|
|
1901
|
+
# or it doesn't count
|
|
1902
|
+
selector_at_end_of_descendant = True
|
|
1903
|
+
return selector_at_end_of_descendant
|
|
1904
|
+
|
|
1905
|
+
|
|
1906
|
+
def get_declaration_value_by_property(
|
|
1907
|
+
block: Union[str, DeclarationBlock], property: str
|
|
1908
|
+
) -> str:
|
|
1909
|
+
"""returns the value of a property from a declaration block
|
|
1910
|
+
|
|
1911
|
+
Args:
|
|
1912
|
+
block: the declaration block in question (could be as a string
|
|
1913
|
+
or as a DeclarationBlock)
|
|
1914
|
+
property: the property we are looking for
|
|
1915
|
+
|
|
1916
|
+
Returns:
|
|
1917
|
+
value: the value of the property"""
|
|
1918
|
+
value = ""
|
|
1919
|
+
try:
|
|
1920
|
+
block = block.text
|
|
1921
|
+
except AttributeError:
|
|
1922
|
+
declarations = block.strip()
|
|
1923
|
+
declarations = block.split(";")
|
|
1924
|
+
for item in declarations:
|
|
1925
|
+
item = item.strip()
|
|
1926
|
+
try:
|
|
1927
|
+
# check for @media rules
|
|
1928
|
+
if "{" in item:
|
|
1929
|
+
item_split = item.split("{")
|
|
1930
|
+
item = item_split[1].strip()
|
|
1931
|
+
prop, val = item.split(":")
|
|
1932
|
+
if prop.lower().strip() == property.lower():
|
|
1933
|
+
value = val.strip()
|
|
1934
|
+
continue
|
|
1935
|
+
except ValueError:
|
|
1936
|
+
print("Doh! no colon")
|
|
1937
|
+
return value
|
|
1938
|
+
|
|
1939
|
+
|
|
1940
|
+
def has_link_selector(sheet: Stylesheet) -> bool:
|
|
1941
|
+
"""returns whether any style in a stylesheet targets a hyperlink
|
|
1942
|
+
|
|
1943
|
+
There could be one or more link selectors. This will check each possible
|
|
1944
|
+
link selector (or psuedoselector). It only has to target a link and not
|
|
1945
|
+
a descendant of a link.
|
|
1946
|
+
|
|
1947
|
+
Args:
|
|
1948
|
+
sheet: the stylesheet object.
|
|
1949
|
+
|
|
1950
|
+
Returns:
|
|
1951
|
+
has_selector: whether there is a selector that targets a link"""
|
|
1952
|
+
has_selector = False
|
|
1953
|
+
all_selectors = sheet.selectors
|
|
1954
|
+
for selector in all_selectors:
|
|
1955
|
+
selector_copy = selector
|
|
1956
|
+
if " " in selector:
|
|
1957
|
+
# we need to add a space at the end for the split to work
|
|
1958
|
+
selector = selector.strip() + " "
|
|
1959
|
+
selector_split = selector.split()
|
|
1960
|
+
selector_copy = selector_split[-1]
|
|
1961
|
+
if selector_copy == "a":
|
|
1962
|
+
has_selector = True
|
|
1963
|
+
break
|
|
1964
|
+
# Check selector_copy to see if it's an anchor
|
|
1965
|
+
regex_pattern = regex_patterns.get("advanced_link_selector")
|
|
1966
|
+
selector_match = re.search(regex_pattern, selector_copy)
|
|
1967
|
+
if selector_match:
|
|
1968
|
+
has_selector = True
|
|
1969
|
+
break
|
|
1970
|
+
return has_selector
|
|
1971
|
+
|
|
1972
|
+
|
|
1973
|
+
def get_all_link_selectors(sheet: Stylesheet) -> list:
|
|
1974
|
+
"""returns all selectors that target a link
|
|
1975
|
+
|
|
1976
|
+
Args:
|
|
1977
|
+
sheet: the stylesheet object.
|
|
1978
|
+
|
|
1979
|
+
Returns:
|
|
1980
|
+
selectors: a list of all selectors that target a link"""
|
|
1981
|
+
selectors = []
|
|
1982
|
+
all_selectors = sheet.selectors
|
|
1983
|
+
for selector in all_selectors:
|
|
1984
|
+
selector_match = is_link_selector(selector)
|
|
1985
|
+
if selector_match:
|
|
1986
|
+
selectors.append(selector.strip())
|
|
1987
|
+
return selectors
|
|
1988
|
+
|
|
1989
|
+
|
|
1990
|
+
def is_link_selector(selector):
|
|
1991
|
+
selector_copy = selector
|
|
1992
|
+
if " " in selector:
|
|
1993
|
+
# we need to add a space at the end for the split to work
|
|
1994
|
+
selector = selector.strip() + " "
|
|
1995
|
+
selector_split = selector.split()
|
|
1996
|
+
selector_copy = selector_split[-1]
|
|
1997
|
+
if selector_copy == "a":
|
|
1998
|
+
return True
|
|
1999
|
+
# Check selector_copy to see if it's an anchor
|
|
2000
|
+
regex_pattern = regex_patterns.get("advanced_link_selector")
|
|
2001
|
+
selector_match = re.search(regex_pattern, selector_copy)
|
|
2002
|
+
return selector_match
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
def get_all_link_rules(sheet: Stylesheet) -> list:
|
|
2006
|
+
"""returns all rules that target a hyperlink
|
|
2007
|
+
|
|
2008
|
+
returns all rules that target a link
|
|
2009
|
+
|
|
2010
|
+
Args:
|
|
2011
|
+
sheet: the stylesheet object.
|
|
2012
|
+
|
|
2013
|
+
Returns:
|
|
2014
|
+
rules: a list of all rules that target a link"""
|
|
2015
|
+
rules = []
|
|
2016
|
+
link_selectors = get_all_link_selectors(sheet)
|
|
2017
|
+
all_rulesets = sheet.rulesets
|
|
2018
|
+
for rule in all_rulesets:
|
|
2019
|
+
current_selector = rule.selector
|
|
2020
|
+
if current_selector in link_selectors:
|
|
2021
|
+
rules.append(rule)
|
|
2022
|
+
return rules
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
def get_link_color_data(project_path: str) -> list:
|
|
2026
|
+
"""returns all colors applied to links.
|
|
2027
|
+
|
|
2028
|
+
Identifies all selectors that target a link, and gets a
|
|
2029
|
+
list of dictionaries that identify colors.
|
|
2030
|
+
|
|
2031
|
+
Args:
|
|
2032
|
+
project_path: path to project folder
|
|
2033
|
+
|
|
2034
|
+
Returns:
|
|
2035
|
+
link_styles: a list of link color data applied to each
|
|
2036
|
+
file that includes a link color data"""
|
|
2037
|
+
link_styles = []
|
|
2038
|
+
color_contrast_data = get_project_color_contrast(project_path)
|
|
2039
|
+
for item in color_contrast_data:
|
|
2040
|
+
selector = item[1]
|
|
2041
|
+
if not is_link_selector(selector):
|
|
2042
|
+
continue
|
|
2043
|
+
# it must be a link selector, let's get our data
|
|
2044
|
+
link_styles.append(item)
|
|
2045
|
+
return link_styles
|
|
2046
|
+
|
|
2047
|
+
|
|
1820
2048
|
if __name__ == "__main__":
|
|
1821
2049
|
insane_gradient = """
|
|
1822
2050
|
-moz-radial-gradient(0% 200%, ellipse cover,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|