webcode-tk 1.0.4__tar.gz → 1.0.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: webcode-tk
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary:
5
5
  Home-page: https://github.com/HundredVisionsGuy/webcode-tk
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "webcode-tk"
3
- version = "1.0.4"
3
+ version = "1.0.6"
4
4
  description = ""
5
5
  authors = ["hundredvisionsguy <cwinikka@gmail.com>"]
6
6
  keywords = ["html", "validation", "css", ]
@@ -18,4 +18,4 @@ Modules exported by this package:
18
18
  - `validator_tools`: sends HTML or CSS code to the W3C Validator to check
19
19
  for errors.
20
20
  """
21
- __version__ = "1.0.4"
21
+ __version__ = "1.0.6"
@@ -21,8 +21,8 @@ from webcode_tk import font_tools as fonts
21
21
  from webcode_tk import html_tools
22
22
 
23
23
 
24
- default_global_color = "#FFFFFF"
25
- default_global_background = None
24
+ default_global_color = "#000000"
25
+ default_global_background = "#ffffff"
26
26
  default_link_color = "#0000EE"
27
27
  default_link_visited = "#551A8B"
28
28
  root_font_size = 16
@@ -111,6 +111,13 @@ class Element(object):
111
111
  "specificity": "",
112
112
  "applied_by": "default",
113
113
  }
114
+ self.visited_background = {
115
+ "value": "",
116
+ "sheet": "",
117
+ "selector": "",
118
+ "specificity": "",
119
+ "applied_by": "default",
120
+ }
114
121
  self.hover_color = {
115
122
  "value": "",
116
123
  "sheet": "",
@@ -134,6 +141,13 @@ class Element(object):
134
141
  "large_aaa": True,
135
142
  "large_aa": True,
136
143
  }
144
+ self.hover_contrast_data = {
145
+ "ratio": 21.0,
146
+ "normal_aaa": True,
147
+ "normal_aa": True,
148
+ "large_aaa": True,
149
+ "large_aa": True,
150
+ }
137
151
  self.visited_contrast_data = {
138
152
  "ratio": 0.0,
139
153
  "normal_aaa": False,
@@ -156,6 +170,10 @@ class Element(object):
156
170
  self.visited_color["value"] = default_link_visited
157
171
  self.visited_color["sheet"] = "user-agent"
158
172
  self.visited_color["specificity"] = "000"
173
+ self.visited_background["value"] = default_global_background
174
+ self.visited_background["sheet"] = "user-agent"
175
+ self.visited_background["specificity"] = "000"
176
+ self.visited_background["applied_by"] = "context"
159
177
 
160
178
  def ammend_color_styles(self, new_styles: dict, filename: str) -> None:
161
179
  """adjust color styles based on specificity.
@@ -202,6 +220,25 @@ class Element(object):
202
220
  # get contrast for color & bg_color
203
221
  self.get_contrast_data("standard")
204
222
  else:
223
+ # be sure to change at least the background color for pseudo-states
224
+ if targets_bg_color:
225
+ # check hover background
226
+ hover_bg = self.hover_background.get("value")
227
+ hover_specificity = self.hover_background.get("specificity")
228
+ new_bg = new_styles.get("background-color")
229
+ if not hover_bg or new_specificity >= hover_specificity:
230
+ self.hover_background["value"] = new_bg
231
+ self.hover_background["specificity"] = new_specificity
232
+
233
+ # check visited background
234
+ visited_bg = self.visited_background.get("value")
235
+ visited_specificity = self.visited_background.get(
236
+ "specificity"
237
+ )
238
+ if not visited_bg or new_specificity >= visited_specificity:
239
+ self.visited_background["value"] = new_bg
240
+ self.visited_background["specificity"] = new_specificity
241
+
205
242
  # Do we have a link selector?
206
243
  is_link_selector = css.is_link_selector(selector)
207
244
  if is_link_selector:
@@ -247,6 +284,11 @@ class Element(object):
247
284
  # If it was not directly set, we can change it
248
285
  if not bg_was_directly_set:
249
286
  self.background_color["value"] = bg_color
287
+ if self.children:
288
+ for kid in self.children:
289
+ kid.ammend_bg_color(
290
+ bg_color, new_selector, new_specificity, filename
291
+ )
250
292
 
251
293
  def get_contrast_data(self, type="default") -> None:
252
294
  """get color contrast for the type specified
@@ -615,11 +657,17 @@ class Element(object):
615
657
  )
616
658
  self.background_color["gradient_colors"] = colors
617
659
  # set color, specificity, and directly applied
618
- self.background_color["value"] = val
619
- self.background_color["sheet"] = filename
620
- self.background_color["specificity"] = new_specificity
621
- self.background_color["applied_by"] = "directly"
622
- self.background_color["selector"] = selector
660
+ if ":hover" in selector:
661
+ background_color_dict = self.hover_background
662
+ elif ":visited" in selector:
663
+ background_color_dict = self.visited_background
664
+ else:
665
+ background_color_dict = self.background_color
666
+ background_color_dict["value"] = val
667
+ background_color_dict["sheet"] = filename
668
+ background_color_dict["specificity"] = new_specificity
669
+ background_color_dict["applied_by"] = "directly"
670
+ background_color_dict["selector"] = selector
623
671
  else:
624
672
  if not previously_set:
625
673
  self.background_color["value"] = val
@@ -808,7 +856,14 @@ class CSSAppliedTree:
808
856
  for ruleset in color_rules:
809
857
  # get filename
810
858
  filename = clerk.get_file_name(sheet.href)
811
- self.__adjust_colors(body, ruleset, filename)
859
+ selector_source = ""
860
+ if body.name == "body":
861
+ selector_source = "body"
862
+ else:
863
+ input("Wait, what?")
864
+ self.__adjust_colors(
865
+ body, ruleset, filename, selector_src=selector_source
866
+ )
812
867
 
813
868
  def targets_body(self, ruleset: dict) -> bool:
814
869
  """returns whether the ruleset is targetting the body or not.
@@ -873,7 +928,12 @@ class CSSAppliedTree:
873
928
  return
874
929
 
875
930
  def __adjust_colors(
876
- self, element: Element, ruleset: dict, filename: str
931
+ self,
932
+ element: Element,
933
+ ruleset: dict,
934
+ filename: str,
935
+ applied_by="default",
936
+ selector_src="",
877
937
  ) -> None:
878
938
  """recursively adjust color where necessary to all elements that
879
939
  apply.
@@ -924,6 +984,8 @@ class CSSAppliedTree:
924
984
  else:
925
985
  if ":hover" in selector:
926
986
  color = element.hover_color
987
+ elif ":visited" in selector:
988
+ color = element.visited_color
927
989
  else:
928
990
  color = element.color
929
991
  color["value"] = declaration.get("color")
@@ -932,8 +994,36 @@ class CSSAppliedTree:
932
994
  color["specificity"] = specificity
933
995
  color["applied_by"] = "directly"
934
996
  for child in element.children:
935
- self.__adjust_child_colors(child, ruleset, filename)
936
-
997
+ element_name = element.name
998
+ self.__adjust_child_colors(
999
+ child, ruleset, filename, element_name
1000
+ )
1001
+ elif is_background_prop:
1002
+ # background - if not set directly - apply by context
1003
+ value = declaration.get("background-color")
1004
+ if not value:
1005
+ value = declaration.get("background")
1006
+ if property == "background-image":
1007
+ value = declaration.get("background-image")
1008
+
1009
+ # adjust if value is not the same as current value
1010
+ applied_by = element.background_color.get("applied_by")
1011
+ current_value = element.background_color.get("value")
1012
+ time_to_adjust = (
1013
+ applied_by == "default"
1014
+ or applied_by == "context"
1015
+ and value != current_value
1016
+ )
1017
+ # But only if the value was applied to an ancestor
1018
+ # For example, a th is not a parent of a td
1019
+ applied_to_ancestor = False
1020
+ for ancestor in element.ancestors:
1021
+ ancestor_tag = ancestor[0]
1022
+ if ancestor_tag == selector_src:
1023
+ applied_to_ancestor = True
1024
+ time_to_adjust = time_to_adjust and applied_to_ancestor
1025
+ if time_to_adjust:
1026
+ print("Wait")
937
1027
  can_inherit = self.can_inherit_styles(element, selector, ruleset)
938
1028
  if can_inherit and applies:
939
1029
  declaration = ruleset.get(selector)
@@ -945,7 +1035,11 @@ class CSSAppliedTree:
945
1035
  self.__adjust_colors(child, ruleset, filename)
946
1036
 
947
1037
  def __adjust_child_colors(
948
- self, child: Element, ruleset: dict, filename: str
1038
+ self,
1039
+ child: Element,
1040
+ ruleset: dict,
1041
+ filename: str,
1042
+ applied_by="default",
949
1043
  ) -> None:
950
1044
  """adjusts colors for child of an element.
951
1045
 
@@ -953,10 +1047,16 @@ class CSSAppliedTree:
953
1047
  to see if the child element is a link or not (as well as the selector)
954
1048
  and check the specificity of the ruleset.
955
1049
 
1050
+ To help with background colors, we need to know where it was applied
1051
+ from (name of tag) - that way we can check if a declaration was applied
1052
+ by one of the tag's parents. If it was, then we apply that color by
1053
+ context taking the background from the nearest parent.
1054
+
956
1055
  Args:
957
1056
  child: the child element in question
958
1057
  ruleset: the CSS rule being applied
959
1058
  filename: name of the file where the styles came from
1059
+ applied_from: the name of the element that was targetted
960
1060
  """
961
1061
  # Adjust colors if necessary - if there was a change,
962
1062
  # adjust colors for children
@@ -1504,7 +1604,8 @@ def get_color_contrast_details(tree: CSSAppliedTree, rating="AAA") -> list:
1504
1604
  rating: the rating of contrast we check for (AAA or AA). The default
1505
1605
  is AAA.
1506
1606
  Returns:
1507
- results"""
1607
+ results
1608
+ """
1508
1609
  results = []
1509
1610
  filename = tree.filename
1510
1611
  # Loop recursively through the tree
@@ -1547,6 +1648,7 @@ def get_color_contrast_details(tree: CSSAppliedTree, rating="AAA") -> list:
1547
1648
  passes = contrast_data.get("normal_aaa")
1548
1649
  else:
1549
1650
  passes = contrast_data.get("normal_aa")
1651
+
1550
1652
  # only add results if failure
1551
1653
  if not passes:
1552
1654
  if el.is_large:
@@ -1556,9 +1658,10 @@ def get_color_contrast_details(tree: CSSAppliedTree, rating="AAA") -> list:
1556
1658
  selector = el.background_color.get("selector")
1557
1659
  if not selector:
1558
1660
  selector = el.color.get("selector")
1559
- msg = f"{el.name} tag (selector: {selector}) fails color "
1560
- msg += f"contrast at {size} {rating}."
1661
+ msg = f"selector: {selector} fails color contrast {size}"
1662
+ msg += f"{rating}"
1561
1663
  results.append(msg)
1664
+
1562
1665
  if not children:
1563
1666
  return
1564
1667
  else:
@@ -1570,7 +1673,7 @@ def get_color_contrast_details(tree: CSSAppliedTree, rating="AAA") -> list:
1570
1673
  if results:
1571
1674
  adjusted = []
1572
1675
  for result in results:
1573
- adjusted.append("fail: " + result)
1676
+ adjusted.append(f"fail: ({filename}) " + result)
1574
1677
  results = adjusted
1575
1678
  else:
1576
1679
  # It's a success! Let's let them know
@@ -1580,6 +1683,32 @@ def get_color_contrast_details(tree: CSSAppliedTree, rating="AAA") -> list:
1580
1683
  return results
1581
1684
 
1582
1685
 
1686
+ def get_color_contrast_report(dir_path: str, rating="AAA") -> list:
1687
+ """returns a list of all failures or a pass based on rating
1688
+
1689
+ Args:
1690
+ dir_path: the path to the directory in question
1691
+ rating: the rating of contrast we check for (AAA or AA). The default
1692
+ is AAA.
1693
+ Returns:
1694
+ results: a list of pass or fail messages.
1695
+ """
1696
+ results = []
1697
+ files = css.get_styles_by_html_files(dir_path)
1698
+ for file in files:
1699
+ filepath = file.get("file")
1700
+ stylesheets = file.get("stylesheets")
1701
+ tree = CSSAppliedTree(filepath, stylesheets)
1702
+
1703
+ report = get_color_contrast_details(tree, rating)
1704
+ for item in report:
1705
+ if item not in results:
1706
+ results.append(item)
1707
+ # Do one more pass on hyperlinks and double check contrast
1708
+ print(results)
1709
+ return results
1710
+
1711
+
1583
1712
  if __name__ == "__main__":
1584
1713
  project_path = "tests/test_files/attribute_selector_file"
1585
1714
  project_path = "tests/test_files/large_project/"
@@ -2476,6 +2476,38 @@ def get_heading_color_report(project_dir: str) -> list:
2476
2476
  return report
2477
2477
 
2478
2478
 
2479
+ def get_project_color_contrast_report(project_dir: str, level="AAA") -> list:
2480
+ """returns a report of pass or fail for each element targetting color.
2481
+
2482
+ Args:
2483
+ project_dir: the project folder where the html and css files are found.
2484
+ level: the level for the report (AAA or AA)
2485
+ Returns:
2486
+ report: a report of every targetted color and whether it passes or
2487
+ fails.
2488
+ """
2489
+ report = []
2490
+ large = "Large " + level
2491
+ normal = "Normal " + level
2492
+ results = get_project_color_contrast(project_dir, normal, large)
2493
+ for result in results:
2494
+ filename = clerk.get_file_name(result[0])
2495
+ selector = result[1]
2496
+ level = result[2]
2497
+ color = result[3]
2498
+ bg_color = result[4]
2499
+ ratio = result[5]
2500
+ passes = result[6]
2501
+ if passes:
2502
+ msg = f"pass: {filename} selector: {selector} meets color contrast"
2503
+ else:
2504
+ msg = f"fail: {filename} selector: {selector} DOES NOT meet"
2505
+ msg += f" report (level {level} for colors ({color} & {bg_color})"
2506
+ msg += f" at a ratio of {ratio}."
2507
+ report.append(msg)
2508
+ return report
2509
+
2510
+
2479
2511
  if __name__ == "__main__":
2480
2512
  insane_gradient = """
2481
2513
  -moz-radial-gradient(0% 200%, ellipse cover,
File without changes
File without changes