blob: e2b3689059c46d3ea3181617bd171631ec776e69 [file] [log] [blame]
# This script is used to update the CSS ranking. The CSS ranking will affect
# the grouping of CSS properties in Computed Style.
# Usage: Run `python update_css_ranking.py` to update the default
# CSS ranking file and API.
# Run `python update_css_ranking.py <ranking_file>` to update
# the ranking to another file with the default ranking API.
# Run `python update_css_ranking.py <ranking_file> <ranking_api_link>`
# to update the ranking from <ranking_api_link> API to <ranking_file>
import urllib2
import json
import sys
import cluster
import json5_generator
import math
CSS_RANKING_API = "http://www.chromestatus.com/data/csspopularity"
CSS_RANKING_FILE = "../../core/css/CSSPropertiesRanking.json5"
CSS_PROPERTIES = "../../core/css/CSSProperties.json5"
CONFIG_FILE = "../../core/css/CSSGroupConfig.json5"
def reformat_properties_name(css_properties):
for i in range(len(css_properties)):
if css_properties[i][:5] == "alias":
css_properties[i] = css_properties[i][5:]
if css_properties[i][:6] == "webkit":
css_properties[i] = "-" + css_properties[i]
def update_css_ranking(css_ranking_file, css_ranking_api):
"""Create the CSSPropertiesRanking.json5 for uses in Computed Style grouping
Args:
css_ranking_file: file directory to CSSPropertiesRanking.json5
css_ranking_api: url to CSS ranking api
"""
css_ranking = json.loads(urllib2.urlopen(css_ranking_api).read())
css_ranking_content = {"properties": {}, "data": []}
css_ranking_content["data"] = [property_["property_name"] for property_ in
sorted(css_ranking, key=lambda x: -float(x["day_percentage"]))]
reformat_properties_name(css_ranking_content["data"])
with open(css_ranking_file, "w") as fw:
fw.write("// The popularity ranking of all css properties the first properties is the most\n")
fw.write("// used property according to: https://www.chromestatus.com/metrics/css/popularity\n")
json.dump(css_ranking_content, fw, indent=4, sort_keys=False)
def find_partition_rule(css_property_set, all_properties, n_cluster, transform=lambda x: x):
"""Find partition rule for a set of CSS property based on its popularity
Args:
css_property_set: list of CSS properties and their popularity of form
[(css_property_name, popularity_score)..]
n_cluster: number of cluster to divide the set into
all_properties: all CSS properties and its score
transform: data transform function to transform the popularity score,
default value is the identity function
Returns:
partition rule for css_property_set
"""
_, cluster_alloc, _ = cluster.k_means([transform(p[1]) for p in css_property_set], n_cluster=n_cluster)
return [all_properties[css_property_set[i][0]] for i in range(len(cluster_alloc) - 1)
if cluster_alloc[i] != cluster_alloc[i + 1]] + [1.0]
def produce_partition_rule(config_file, css_ranking_api):
"""Find the partition rule for the groups and print them to config_file
Args:
config_file: the file to write the parameters to
css_ranking_api: url to CSS ranking api
"""
css_ranking = sorted(json.loads(urllib2.urlopen(css_ranking_api).read()),
key=lambda x: -x["day_percentage"])
total_css_properties = len(css_ranking)
css_ranking_dictionary = dict([(x["property_name"], x["day_percentage"] * 100) for x in css_ranking])
css_ranking_cdf = dict(zip([x["property_name"] for x in css_ranking],
[float(i) / total_css_properties for i in range(total_css_properties)]))
css_properties = json5_generator.Json5File.load_from_files([CSS_PROPERTIES]).name_dictionaries
rare_non_inherited_properties = sorted([(x["name"], css_ranking_dictionary[x["name"]])
for x in css_properties if not x["inherited"]
and x["field_group"] is not None
and "*" in x["field_group"]
and x["name"] in css_ranking_dictionary],
key=lambda x: -x[1])
rare_inherited_properties = sorted([(x["name"], css_ranking_dictionary[x["name"]])
for x in css_properties if x["inherited"]
and x["field_group"] is not None
and "*" in x["field_group"]
and x["name"] in css_ranking_dictionary],
key=lambda x: -x[1])
rni_properties_rule = find_partition_rule(rare_non_inherited_properties,
css_ranking_cdf, n_cluster=3)
ri_properties_rule = find_partition_rule(rare_inherited_properties,
css_ranking_cdf,
n_cluster=2, transform=lambda x: math.log(x + 10e-6))
with open(config_file, 'w') as fw:
fw.write("// The grouping parameter is a cumulative distribution over the whole set of ranked\n")
fw.write("// CSS properties.\n")
json.dump({
"parameters": {},
"data": [{"name": "rare_non_inherited_properties_rule", "cumulative_distribution": rni_properties_rule},
{"name": "rare_inherited_properties_rule", "cumulative_distribution": ri_properties_rule}]
}, fw, indent=4)
if __name__ == '__main__':
assert len(sys.argv) < 4, "Too many parameters"
if len(sys.argv) == 1:
update_css_ranking(CSS_RANKING_FILE, CSS_RANKING_API)
produce_partition_rule(CONFIG_FILE, CSS_RANKING_API)
elif len(sys.argv) == 2:
update_css_ranking(sys.argv[1], CSS_RANKING_API)
produce_partition_rule(CONFIG_FILE, CSS_RANKING_API)
elif len(sys.argv) == 3:
update_css_ranking(sys.argv[1], sys.argv[2])
produce_partition_rule(CONFIG_FILE, sys.argv[2])