fix user keys layout, adjust @media breakpoints to bs4, fix more unused css, optimize script
This commit is contained in:
parent
18df2fd647
commit
4ebd52cd69
6 changed files with 162 additions and 108 deletions
|
@ -169,13 +169,13 @@
|
||||||
max-width: 1120px;
|
max-width: 1120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 767px) {
|
||||||
.content-dashboard {
|
.content-dashboard {
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 540px) {
|
@media (max-width: 576px) {
|
||||||
select {
|
select {
|
||||||
width: 280px;
|
width: 280px;
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@
|
||||||
margin: 15px auto;
|
margin: 15px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) and (max-width: 900px) {
|
@media (min-width: 768px) and (max-width: 991px) {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 320px) {
|
@media(min-width: 576px) {
|
||||||
.modal:before {
|
.modal:before {
|
||||||
content: '';
|
content: '';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -215,7 +215,7 @@ textarea {
|
||||||
|
|
||||||
/* Show the dropdown menu on hover */
|
/* Show the dropdown menu on hover */
|
||||||
|
|
||||||
@media (min-width: 769px) {
|
@media (min-width: 768px) {
|
||||||
.nav-language .dropdown:hover .dropdown-menu {
|
.nav-language .dropdown:hover .dropdown-menu {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -769,7 +769,7 @@ tech-sub-sec h2 {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 767px) {
|
||||||
.ssdimg img {
|
.ssdimg img {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
@ -884,7 +884,6 @@ tech-sub-sec h2 {
|
||||||
|
|
||||||
.price-calc-section .card .description span {
|
.price-calc-section .card .description span {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-left: 4px;
|
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -1002,7 +1001,7 @@ tech-sub-sec h2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 480px) and (max-width: 767px) {
|
@media (min-width: 576px) and (max-width: 767px) {
|
||||||
.logo-wrap, .logo-wrap-1 {
|
.logo-wrap, .logo-wrap-1 {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
padding: 15px 30px !important;
|
padding: 15px 30px !important;
|
||||||
|
@ -1010,7 +1009,7 @@ tech-sub-sec h2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width:990px) {
|
@media(max-width:991px) {
|
||||||
.pricing-section .text {
|
.pricing-section .text {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
|
@ -1174,7 +1173,7 @@ tech-sub-sec h2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width:540px) {
|
@media(max-width:575px) {
|
||||||
.logo-wrap {
|
.logo-wrap {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
}
|
}
|
||||||
|
@ -1201,7 +1200,6 @@ tech-sub-sec h2 {
|
||||||
}
|
}
|
||||||
.price-calc-section .card .description span {
|
.price-calc-section .card .description span {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
margin-left: 0px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
IndexView, BetaProgramView, LandingProgramView, BetaAccessView,
|
# BetaProgramView, SuccessView, LandingProgramView,
|
||||||
SuccessView, PaymentOrderView, OrderConfirmationView,
|
IndexView, BetaAccessView, PaymentOrderView, OrderConfirmationView,
|
||||||
WhyDataCenterLightView, ContactUsView
|
WhyDataCenterLightView, ContactUsView
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
{% trans "Generate" %}
|
{% trans "Generate" %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>{% trans "Using existing key" %}</h2>
|
<h2>{% trans "Using existing key" %}</h2>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="virtual-machine-container dashboard-container">
|
<div class="virtual-machine-container dashboard-container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9 col-md-offset-2">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<form method="POST" action="" novalidate class="form-ssh">
|
<form method="POST" action="" novalidate class="form-ssh">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import pprint
|
||||||
import re
|
import re
|
||||||
from collections import Counter, OrderedDict
|
from collections import Counter, OrderedDict
|
||||||
from itertools import zip_longest
|
from itertools import zip_longest
|
||||||
|
@ -17,8 +18,11 @@ RE_PATTERNS = {
|
||||||
'view_html': '[\'\"](.*\.html)',
|
'view_html': '[\'\"](.*\.html)',
|
||||||
'html_html': '{% (?:extends|include) [\'\"]?(.*\.html)',
|
'html_html': '{% (?:extends|include) [\'\"]?(.*\.html)',
|
||||||
'html_style': '{% static [\'\"]?(.*\.css)',
|
'html_style': '{% static [\'\"]?(.*\.css)',
|
||||||
|
'css_media': (
|
||||||
|
'^\s*\@media([^{]+)\{\s*([\s\S]*?})\s*}'
|
||||||
|
),
|
||||||
'css_selector': (
|
'css_selector': (
|
||||||
'^\s*([.#\[:_A-Za-z][.#\[\]\(\)=:+~\-_A-Za-z0-9\s>,]*)'
|
'^\s*([.#\[:_A-Za-z][^{]*)'
|
||||||
'{([\s\S]*?)}'
|
'{([\s\S]*?)}'
|
||||||
),
|
),
|
||||||
'html_class': 'class=[\'\"]([a-zA-Z0-9-_\s]*)',
|
'html_class': 'class=[\'\"]([a-zA-Z0-9-_\s]*)',
|
||||||
|
@ -54,32 +58,25 @@ class Command(BaseCommand):
|
||||||
for app in apps_list:
|
for app in apps_list:
|
||||||
if options['css']:
|
if options['css']:
|
||||||
self.optimize_css(app)
|
self.optimize_css(app)
|
||||||
else:
|
# else:
|
||||||
self.optimize_all(app)
|
# optimize_all(app)
|
||||||
|
|
||||||
def optimize_css(self, app_name):
|
def optimize_css(self, app_name):
|
||||||
# get html and css files used in the app
|
# get html and css files used in the app
|
||||||
files = self.get_files(app_name)
|
files = get_files(app_name)
|
||||||
# get_selectors_from_css
|
# get_selectors_from_css
|
||||||
css_selectors = self.get_selectors_css(files['style'])
|
css_selectors = get_selectors_css(files['style'])
|
||||||
# get_selectors_from_html
|
# get_selectors_from_html
|
||||||
html_selectors = self.get_selectors_html(files['html'])
|
html_selectors = get_selectors_html(files['html'])
|
||||||
|
# get duplication of css rules from css files
|
||||||
|
css_dup_report = get_css_duplication(css_selectors)
|
||||||
|
|
||||||
# duplicate css selectors in stylesheets
|
|
||||||
for file, selectors in css_selectors.items():
|
|
||||||
count = {}
|
|
||||||
for selector in selectors:
|
|
||||||
if selector[0] in count:
|
|
||||||
count[selector[0]] += 1
|
|
||||||
print(file, selector[0], count[selector[0]])
|
|
||||||
else:
|
|
||||||
count[selector[0]] = 1
|
|
||||||
|
|
||||||
def get_files(self, app_name):
|
def get_files(app_name):
|
||||||
# the view file for the app
|
# the view file for the app
|
||||||
app_view = os.path.join(settings.PROJECT_DIR, app_name, 'views.py')
|
app_view = os.path.join(settings.PROJECT_DIR, app_name, 'views.py')
|
||||||
# get template files called from the view
|
# get template files called from the view
|
||||||
all_html_list = file_match_pattern(app_view, ['view_html'])[0]
|
all_html_list = file_match_pattern(app_view, 'view_html')
|
||||||
# list of unique template files
|
# list of unique template files
|
||||||
uniq_html_list = list(OrderedDict.fromkeys(all_html_list).keys())
|
uniq_html_list = list(OrderedDict.fromkeys(all_html_list).keys())
|
||||||
# list of stylesheets
|
# list of stylesheets
|
||||||
|
@ -115,29 +112,111 @@ class Command(BaseCommand):
|
||||||
print(result)
|
print(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_selectors_css(self, files):
|
|
||||||
|
def get_selectors_css(files):
|
||||||
selectors = {}
|
selectors = {}
|
||||||
|
media_selectors = {}
|
||||||
for file in files:
|
for file in files:
|
||||||
if any(vendor in file for vendor in ['bootstrap', 'font-awesome']):
|
if any(vendor in file for vendor in ['bootstrap', 'font-awesome']):
|
||||||
continue
|
continue
|
||||||
result = finders.find(file)
|
result = finders.find(file)
|
||||||
if result:
|
if result:
|
||||||
selectors[file] = file_match_pattern(
|
with open(result) as f:
|
||||||
result, ['css_selector']
|
data = f.read()
|
||||||
)[0]
|
media_selectors[file] = string_match_pattern(
|
||||||
|
data, 'css_media'
|
||||||
|
)
|
||||||
|
new_data = string_replace_pattern(
|
||||||
|
data, 'css_media'
|
||||||
|
)
|
||||||
|
selectors[file] = {
|
||||||
|
'default': string_match_pattern(
|
||||||
|
new_data, 'css_selector'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
# pp = pprint.PrettyPrinter(compact=False, width=120)
|
||||||
|
# pp.pprint(media_selectors)
|
||||||
|
|
||||||
|
for file, match_list in media_selectors.items():
|
||||||
|
for match in match_list:
|
||||||
|
query = match[0]
|
||||||
|
block_text = ' '.join(match[1].split())
|
||||||
|
results = string_match_pattern(
|
||||||
|
block_text, 'css_selector'
|
||||||
|
)
|
||||||
|
f_query = ' '.join(query.replace(':', ': ').split())
|
||||||
|
if f_query in selectors[file]:
|
||||||
|
selectors[file][f_query].extend(results)
|
||||||
|
else:
|
||||||
|
selectors[file][f_query] = results
|
||||||
|
# pp.pprint(selectors)
|
||||||
return selectors
|
return selectors
|
||||||
|
|
||||||
def get_selectors_html(self, files):
|
|
||||||
|
def get_selectors_html(files):
|
||||||
selectors = {}
|
selectors = {}
|
||||||
for file in files:
|
for file in files:
|
||||||
results = templates_match_pattern(file, ['html_class', 'html_id'])
|
results = templates_match_pattern(file, ['html_class', 'html_id'])
|
||||||
selectors[file] = {
|
selectors[file] = {
|
||||||
'class': results[0],
|
'class': results[0],
|
||||||
'id': results[0],
|
'id': results[1],
|
||||||
}
|
}
|
||||||
return selectors
|
return selectors
|
||||||
|
|
||||||
def selectors_css(self, results, filename='frontend'):
|
|
||||||
|
def file_match_pattern(file, patterns):
|
||||||
|
with open(file) as f:
|
||||||
|
data = f.read()
|
||||||
|
results = string_match_pattern(data, patterns)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def string_match_pattern(data, patterns):
|
||||||
|
if not isinstance(patterns, str):
|
||||||
|
results = []
|
||||||
|
for p in patterns:
|
||||||
|
re_pattern = re.compile(RE_PATTERNS[p], re.MULTILINE)
|
||||||
|
results.append(re.findall(re_pattern, data))
|
||||||
|
else:
|
||||||
|
re_pattern = re.compile(RE_PATTERNS[patterns], re.MULTILINE)
|
||||||
|
results = re.findall(re_pattern, data)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def string_replace_pattern(data, patterns):
|
||||||
|
if not isinstance(patterns, str):
|
||||||
|
for p in patterns:
|
||||||
|
re_pattern = re.compile(RE_PATTERNS[p], re.MULTILINE)
|
||||||
|
data = re.sub(re_pattern, '', data)
|
||||||
|
else:
|
||||||
|
re_pattern = re.compile(RE_PATTERNS[patterns], re.MULTILINE)
|
||||||
|
data = re.sub(re_pattern, '', data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def templates_match_pattern(template_name, patterns):
|
||||||
|
t = template.loader.get_template(template_name)
|
||||||
|
data = t.template.source
|
||||||
|
results = string_match_pattern(data, patterns)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def get_css_duplication(css_selectors):
|
||||||
|
# duplicate css selectors in stylesheets
|
||||||
|
for file in css_selectors:
|
||||||
|
print(file)
|
||||||
|
for media in css_selectors[file]:
|
||||||
|
print(' '.join(media.replace(':', ': ').split()))
|
||||||
|
print(len(css_selectors[file][media]), 'rules')
|
||||||
|
# for selector in selectors:
|
||||||
|
# if selector[0] in count:
|
||||||
|
# count[selector[0]] += 1
|
||||||
|
# # print(file, selector[0], count[selector[0]])
|
||||||
|
# else:
|
||||||
|
# count[selector[0]] = 1
|
||||||
|
|
||||||
|
|
||||||
|
def write_report(results, filename='frontend'):
|
||||||
full_filename = '../optimize_' + filename + '.csv'
|
full_filename = '../optimize_' + filename + '.csv'
|
||||||
output_file = os.path.join(
|
output_file = os.path.join(
|
||||||
settings.PROJECT_DIR, full_filename
|
settings.PROJECT_DIR, full_filename
|
||||||
|
@ -149,28 +228,6 @@ class Command(BaseCommand):
|
||||||
w.writerow(r)
|
w.writerow(r)
|
||||||
|
|
||||||
|
|
||||||
def file_match_pattern(file, patterns):
|
|
||||||
results = []
|
|
||||||
with open(file) as f:
|
|
||||||
data = f.read()
|
|
||||||
for p in patterns:
|
|
||||||
results.append(
|
|
||||||
re.findall(re.compile(RE_PATTERNS[p], re.MULTILINE), data)
|
|
||||||
)
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def templates_match_pattern(template_name, patterns):
|
|
||||||
t = template.loader.get_template(template_name)
|
|
||||||
data = t.template.source
|
|
||||||
results = []
|
|
||||||
for p in patterns:
|
|
||||||
results.append(
|
|
||||||
re.findall(re.compile(RE_PATTERNS[p], re.MULTILINE), data)
|
|
||||||
)
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
html_tags = [
|
html_tags = [
|
||||||
"a",
|
"a",
|
||||||
"abbr",
|
"abbr",
|
||||||
|
@ -280,6 +337,6 @@ html_tags = [
|
||||||
"wbr"
|
"wbr"
|
||||||
]
|
]
|
||||||
|
|
||||||
exempt_classes = [
|
bootstrap_classes = [
|
||||||
"active",
|
"active",
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue