update: phantoms rather than regions
This commit is contained in:
parent
2edda28695
commit
7ee91d7feb
185
PrettyJson.py
185
PrettyJson.py
|
@ -3,21 +3,21 @@ import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from xml.dom import minidom
|
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import sublime
|
import sublime
|
||||||
import sublime_plugin
|
import sublime_plugin
|
||||||
|
|
||||||
from . import simplejson as json
|
from .libs import simplejson as json
|
||||||
from .simplejson import OrderedDict
|
from .libs.simplejson import OrderedDict
|
||||||
|
|
||||||
SUBLIME_MAJOR_VERSION = int(sublime.version()) / 1000
|
SUBLIME_MAJOR_VERSION = int(sublime.version()) / 1000
|
||||||
|
|
||||||
|
s = sublime.load_settings("Pretty JSON.sublime-settings")
|
||||||
|
|
||||||
xml_syntax = "Packages/XML/XML.tmLanguage"
|
xml_syntax = "Packages/XML/XML.tmLanguage"
|
||||||
json_syntax = "Packages/JSON/JSON.tmLanguage"
|
json_syntax = "Packages/JSON/JSON.tmLanguage"
|
||||||
|
|
||||||
|
|
||||||
jq_exists = False
|
jq_exists = False
|
||||||
jq_init = False
|
jq_init = False
|
||||||
|
|
||||||
|
@ -51,10 +51,9 @@ def check_jq():
|
||||||
jq_exists = False
|
jq_exists = False
|
||||||
|
|
||||||
|
|
||||||
s = sublime.load_settings("Pretty JSON.sublime-settings")
|
|
||||||
|
|
||||||
class PrettyJsonBaseCommand:
|
class PrettyJsonBaseCommand:
|
||||||
json_error_matcher = re.compile(r"line (\d+)")
|
json_error_matcher = re.compile(r"line (\d+)")
|
||||||
|
json_char_matcher = re.compile(r"char (\d+)")
|
||||||
force_sorting = False
|
force_sorting = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -104,7 +103,7 @@ class PrettyJsonBaseCommand:
|
||||||
def json_dumps_minified(obj):
|
def json_dumps_minified(obj):
|
||||||
line_separator = s.get("line_separator", ",")
|
line_separator = s.get("line_separator", ",")
|
||||||
""":type : str"""
|
""":type : str"""
|
||||||
value_separator = s.get("value_separator", ": ")
|
value_separator = s.get("value_separator", ":")
|
||||||
""":type : str"""
|
""":type : str"""
|
||||||
|
|
||||||
sort_keys = s.get("sort_keys", False)
|
sort_keys = s.get("sort_keys", False)
|
||||||
|
@ -121,12 +120,11 @@ class PrettyJsonBaseCommand:
|
||||||
|
|
||||||
def reindent(self, text, selection):
|
def reindent(self, text, selection):
|
||||||
current_line = self.view.line(selection.begin())
|
current_line = self.view.line(selection.begin())
|
||||||
text_before_sel = sublime.Region(
|
text_before_sel = sublime.Region(current_line.begin(), selection.begin())
|
||||||
current_line.begin(), selection.begin())
|
|
||||||
|
|
||||||
reindent_mode = s.get('reindent_block', 'minimal')
|
reindent_mode = s.get("reindent_block", "minimal")
|
||||||
|
|
||||||
if reindent_mode == 'start':
|
if reindent_mode == "start":
|
||||||
# Reindent to the column where the selection starts
|
# Reindent to the column where the selection starts
|
||||||
space_number = text_before_sel.size()
|
space_number = text_before_sel.size()
|
||||||
indent_space = " " * space_number
|
indent_space = " " * space_number
|
||||||
|
@ -136,28 +134,39 @@ class PrettyJsonBaseCommand:
|
||||||
|
|
||||||
# Extracts the spaces at the start of the line to use them
|
# Extracts the spaces at the start of the line to use them
|
||||||
# as padding
|
# as padding
|
||||||
indent_space = re.search(
|
indent_space = re.search("^\s*", self.view.substr(text_before_sel)).group(0)
|
||||||
'^\s*', self.view.substr(text_before_sel)).group(0)
|
|
||||||
|
|
||||||
lines = text.split('\n')
|
lines = text.split("\n")
|
||||||
|
|
||||||
# Pad every line except the first one
|
# Pad every line except the first one
|
||||||
i = 1
|
i = 1
|
||||||
while (i < len(lines)):
|
while i < len(lines):
|
||||||
lines[i] = indent_space + lines[i]
|
lines[i] = indent_space + lines[i]
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def show_exception(self, region, msg):
|
||||||
|
sublime.status_message("[Error]: {}".format(msg))
|
||||||
|
if region is None:
|
||||||
|
return
|
||||||
|
self.highlight_error(region=region, message="{}".format(msg))
|
||||||
|
|
||||||
def highlight_error(self, message):
|
def highlight_error(self, region, message):
|
||||||
|
self.phantom_set = sublime.PhantomSet(self.view, "json_errors")
|
||||||
|
self.phantoms = list()
|
||||||
|
|
||||||
self.view.erase_regions("json_errors")
|
matches = self.json_error_matcher.search(message)
|
||||||
self.view.erase_status("json_errors")
|
char_match = self.json_char_matcher.search(message)
|
||||||
|
if char_match:
|
||||||
m = self.json_error_matcher.search(message)
|
if region.a > region.b:
|
||||||
if m:
|
region.b += int(char_match.group(1)) + 1
|
||||||
line = int(m.group(1)) - 1
|
region.a = region.b + 1
|
||||||
|
else:
|
||||||
|
region.a += int(char_match.group(1)) + 1
|
||||||
|
region.b = region.a + 1
|
||||||
|
if matches:
|
||||||
|
line = int(matches.group(1)) - 1
|
||||||
|
|
||||||
# sometime we need to highlight one line above
|
# sometime we need to highlight one line above
|
||||||
if "','" in message and "delimiter" in message:
|
if "','" in message and "delimiter" in message:
|
||||||
|
@ -165,7 +174,8 @@ class PrettyJsonBaseCommand:
|
||||||
self.view.full_line(self.view.text_point(line - 1, 0))
|
self.view.full_line(self.view.text_point(line - 1, 0))
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
line_content.strip()[-1] != ","
|
line_content.strip()
|
||||||
|
and line_content.strip()[-1] != ","
|
||||||
and line_content.strip() != "{"
|
and line_content.strip() != "{"
|
||||||
and line_content.strip() != "}"
|
and line_content.strip() != "}"
|
||||||
):
|
):
|
||||||
|
@ -179,19 +189,38 @@ class PrettyJsonBaseCommand:
|
||||||
if len(quotes) % 2 != 0 and len(quotes) != 0:
|
if len(quotes) % 2 != 0 and len(quotes) != 0:
|
||||||
line -= 1
|
line -= 1
|
||||||
|
|
||||||
regions = [
|
self.phantoms.append(
|
||||||
self.view.full_line(self.view.text_point(line, 0)),
|
sublime.Phantom(
|
||||||
]
|
region,
|
||||||
|
self.create_phantom_html(message, "error"),
|
||||||
self.view.add_regions(
|
sublime.LAYOUT_BELOW,
|
||||||
"json_errors", regions, "invalid", "dot", sublime.DRAW_OUTLINED
|
self.navigation,
|
||||||
)
|
)
|
||||||
self.view.show(regions[0])
|
)
|
||||||
|
self.phantom_set.update(self.phantoms)
|
||||||
self.view.set_status("json_errors", message)
|
self.view.set_status("json_errors", message)
|
||||||
|
|
||||||
def show_exception(self, msg):
|
# Description: Taken from https://github.com/sublimelsp/LSP/blob/master/plugin/diagnostics.py
|
||||||
sublime.status_message("[Error]: {}".format(msg))
|
# - Thanks to the LSP Team
|
||||||
self.highlight_error("{}".format(msg))
|
def create_phantom_html(self, content: str, severity: str) -> str:
|
||||||
|
stylesheet = sublime.load_resource("Packages/SublimePrettyJson/phantom.css")
|
||||||
|
return """<body id=inline-error>
|
||||||
|
<style>{}</style>
|
||||||
|
<div class="{}"></div>
|
||||||
|
<div class="{} container">
|
||||||
|
<div class="toolbar">
|
||||||
|
<a href="hide">×</a>
|
||||||
|
</div>
|
||||||
|
<div class="content">{}</div>
|
||||||
|
</div>
|
||||||
|
</body>""".format(
|
||||||
|
stylesheet, severity, severity, content
|
||||||
|
)
|
||||||
|
|
||||||
|
def navigation(self, href):
|
||||||
|
if href == "hide":
|
||||||
|
self.phantoms = list()
|
||||||
|
self.phantom_set.update(self.phantoms)
|
||||||
|
|
||||||
def syntax_to_json(self):
|
def syntax_to_json(self):
|
||||||
""" Changes syntax to JSON if its in plain text """
|
""" Changes syntax to JSON if its in plain text """
|
||||||
|
@ -208,6 +237,7 @@ class PrettyJsonValidate(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
continue
|
continue
|
||||||
elif region.empty() and s.get("use_entire_file_if_no_selection", True):
|
elif region.empty() and s.get("use_entire_file_if_no_selection", True):
|
||||||
selection = sublime.Region(0, self.view.size())
|
selection = sublime.Region(0, self.view.size())
|
||||||
|
region = sublime.Region(0, self.view.size())
|
||||||
else:
|
else:
|
||||||
selection = region
|
selection = region
|
||||||
|
|
||||||
|
@ -215,12 +245,13 @@ class PrettyJsonValidate(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
self.json_loads(self.view.substr(selection))
|
self.json_loads(self.view.substr(selection))
|
||||||
sublime.status_message("JSON is Valid")
|
sublime.status_message("JSON is Valid")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=region, msg=ex)
|
||||||
sublime.message_dialog("Invalid JSON")
|
|
||||||
|
|
||||||
|
|
||||||
class PrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
class PrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
""" Pretty Print JSON """
|
"""
|
||||||
|
Description: Pretty Print JSON
|
||||||
|
"""
|
||||||
|
|
||||||
def run(self, edit):
|
def run(self, edit):
|
||||||
self.view.erase_regions("json_errors")
|
self.view.erase_regions("json_errors")
|
||||||
|
@ -231,6 +262,7 @@ class PrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
continue
|
continue
|
||||||
elif region.empty() and s.get("use_entire_file_if_no_selection", True):
|
elif region.empty() and s.get("use_entire_file_if_no_selection", True):
|
||||||
selection = sublime.Region(0, self.view.size())
|
selection = sublime.Region(0, self.view.size())
|
||||||
|
region = sublime.Region(0, self.view.size())
|
||||||
selected_entire_file = True
|
selected_entire_file = True
|
||||||
else:
|
else:
|
||||||
selection = region
|
selection = region
|
||||||
|
@ -251,33 +283,36 @@ class PrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
try:
|
try:
|
||||||
amount_of_single_quotes = re.findall(r"(\'[^\']+\'?)", selection_text)
|
amount_of_single_quotes = re.findall(
|
||||||
amount_of_double_quotes = re.findall(r"(\"[^\"]+\"?)", selection_text)
|
r"(\'[^\']+\'?)", selection_text
|
||||||
|
)
|
||||||
|
amount_of_double_quotes = re.findall(
|
||||||
|
r"(\"[^\"]+\"?)", selection_text
|
||||||
|
)
|
||||||
|
|
||||||
if len(amount_of_single_quotes) >= len(amount_of_double_quotes):
|
if len(amount_of_single_quotes) >= len(amount_of_double_quotes):
|
||||||
selection_text_modified = re.sub(r"(?:\'([^\']+)\'?)", r'"\1"', selection_text)
|
selection_text_modified = re.sub(
|
||||||
|
r"(?:\'([^\']+)\'?)", r'"\1"', selection_text
|
||||||
|
)
|
||||||
obj = self.json_loads(selection_text_modified)
|
obj = self.json_loads(selection_text_modified)
|
||||||
|
|
||||||
json_text = self.json_dumps(obj)
|
json_text = self.json_dumps(obj)
|
||||||
|
|
||||||
if not selected_entire_file and s.get("reindent_block", False):
|
if not selected_entire_file and s.get("reindent_block", False):
|
||||||
json_text = self.reindent(json_text, selection)
|
json_text = self.reindent(json_text, selection)
|
||||||
|
|
||||||
self.view.replace(edit, selection, json_text)
|
self.view.replace(edit, selection, json_text)
|
||||||
|
|
||||||
|
|
||||||
if selected_entire_file:
|
if selected_entire_file:
|
||||||
self.syntax_to_json()
|
self.syntax_to_json()
|
||||||
else:
|
else:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=region, msg=ex)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=region, msg=ex)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PrettyJsonAndSortCommand(PrettyJsonCommand, sublime_plugin.TextCommand):
|
class PrettyJsonAndSortCommand(PrettyJsonCommand, sublime_plugin.TextCommand):
|
||||||
|
"""
|
||||||
""" Pretty print json with forced sorting """
|
Description: Pretty print json with forced sorting
|
||||||
|
"""
|
||||||
|
|
||||||
def run(self, edit):
|
def run(self, edit):
|
||||||
PrettyJsonBaseCommand.force_sorting = True
|
PrettyJsonBaseCommand.force_sorting = True
|
||||||
|
@ -286,18 +321,19 @@ class PrettyJsonAndSortCommand(PrettyJsonCommand, sublime_plugin.TextCommand):
|
||||||
|
|
||||||
|
|
||||||
class UnPrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
class UnPrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
|
"""
|
||||||
""" Compress/minify JSON - it makes json as one-liner """
|
Description: Compress/minify JSON - it makes json as one-liner
|
||||||
|
"""
|
||||||
|
|
||||||
def run(self, edit):
|
def run(self, edit):
|
||||||
self.view.erase_regions("json_errors")
|
self.view.erase_regions("json_errors")
|
||||||
for region in self.view.sel():
|
for region in self.view.sel():
|
||||||
|
|
||||||
selected_entire_file = False
|
selected_entire_file = False
|
||||||
|
|
||||||
# If no selection, use the entire file as the selection
|
# If no selection, use the entire file as the selection
|
||||||
if region.empty() and s.get("use_entire_file_if_no_selection", True):
|
if region.empty() and s.get("use_entire_file_if_no_selection", True):
|
||||||
selection = sublime.Region(0, self.view.size())
|
selection = sublime.Region(0, self.view.size())
|
||||||
|
region = sublime.Region(0, self.view.size())
|
||||||
selected_entire_file = True
|
selected_entire_file = True
|
||||||
else:
|
else:
|
||||||
selection = region
|
selection = region
|
||||||
|
@ -307,15 +343,15 @@ class UnPrettyJsonCommand(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
self.view.replace(edit, selection, self.json_dumps_minified(obj))
|
self.view.replace(edit, selection, self.json_dumps_minified(obj))
|
||||||
|
|
||||||
if selected_entire_file:
|
if selected_entire_file:
|
||||||
self.syntax_to_xml()
|
self.syntax_to_json()
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=region, msg=ex)
|
||||||
|
|
||||||
|
|
||||||
class JqPrettyJson(sublime_plugin.WindowCommand):
|
class JqPrettyJson(sublime_plugin.WindowCommand):
|
||||||
"""
|
"""
|
||||||
Allows work with ./jq
|
Description: Allows work with ./jq
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -351,13 +387,6 @@ class JqPrettyJson(sublime_plugin.WindowCommand):
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_json = self.get_content()
|
raw_json = self.get_content()
|
||||||
|
|
||||||
if SUBLIME_MAJOR_VERSION < 3:
|
|
||||||
if sys.platform != "win32":
|
|
||||||
out, err = p.communicate(bytes(raw_json))
|
|
||||||
else:
|
|
||||||
out, err = p.communicate(unicode(raw_json).encode("utf-8"))
|
|
||||||
else:
|
|
||||||
out, err = p.communicate(bytes(raw_json, "utf-8"))
|
out, err = p.communicate(bytes(raw_json, "utf-8"))
|
||||||
output = out.decode("UTF-8").replace(os.linesep, "\n").strip()
|
output = out.decode("UTF-8").replace(os.linesep, "\n").strip()
|
||||||
if output:
|
if output:
|
||||||
|
@ -372,7 +401,7 @@ class JqPrettyJson(sublime_plugin.WindowCommand):
|
||||||
|
|
||||||
class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
"""
|
"""
|
||||||
converts Json to XML
|
Description: converts Json to XML
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def run(self, edit):
|
def run(self, edit):
|
||||||
|
@ -396,9 +425,6 @@ class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
|
|
||||||
xml_string = "<?xml version='1.0' encoding='UTF-8' ?>\n"
|
xml_string = "<?xml version='1.0' encoding='UTF-8' ?>\n"
|
||||||
|
|
||||||
if SUBLIME_MAJOR_VERSION < 3:
|
|
||||||
self.indent_for_26(root)
|
|
||||||
|
|
||||||
rtn = ElementTree.tostring(root, "utf-8")
|
rtn = ElementTree.tostring(root, "utf-8")
|
||||||
|
|
||||||
if type(rtn) is bytes:
|
if type(rtn) is bytes:
|
||||||
|
@ -406,17 +432,9 @@ class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
|
|
||||||
xml_string += rtn
|
xml_string += rtn
|
||||||
|
|
||||||
# for some reason python 2.6 shipped with ST2
|
|
||||||
# does not have pyexpat
|
|
||||||
if SUBLIME_MAJOR_VERSION >= 3:
|
|
||||||
xml_string = minidom.parseString(xml_string).toprettyxml(
|
|
||||||
encoding="UTF-8"
|
|
||||||
)
|
|
||||||
|
|
||||||
if type(xml_string) is bytes:
|
if type(xml_string) is bytes:
|
||||||
xml_string = xml_string.decode("utf-8")
|
xml_string = xml_string.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
if not selected_entire_file and s.get("reindent_block", False):
|
if not selected_entire_file and s.get("reindent_block", False):
|
||||||
xml_string = self.reindent(xml_string, selection)
|
xml_string = self.reindent(xml_string, selection)
|
||||||
|
|
||||||
|
@ -426,23 +444,7 @@ class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
self.syntax_to_xml()
|
self.syntax_to_xml()
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=region, msg=ex)
|
||||||
|
|
||||||
def indent_for_26(self, elem, level=0):
|
|
||||||
""" intent of ElementTree in case it's py26 without minidom/pyexpat """
|
|
||||||
i = "\n" + level * " "
|
|
||||||
if len(elem):
|
|
||||||
if not elem.text or not elem.text.strip():
|
|
||||||
elem.text = i + " "
|
|
||||||
if not elem.tail or not elem.tail.strip():
|
|
||||||
elem.tail = i
|
|
||||||
for elem in elem:
|
|
||||||
self.indent_for_26(elem, level + 1)
|
|
||||||
if not elem.tail or not elem.tail.strip():
|
|
||||||
elem.tail = i
|
|
||||||
else:
|
|
||||||
if level and (not elem.tail or not elem.tail.strip()):
|
|
||||||
elem.tail = i
|
|
||||||
|
|
||||||
def traverse(self, element, json_dict):
|
def traverse(self, element, json_dict):
|
||||||
""" recursive traverse through dict and build xml tree """
|
""" recursive traverse through dict and build xml tree """
|
||||||
|
@ -466,7 +468,7 @@ class JsonToXml(PrettyJsonBaseCommand, sublime_plugin.TextCommand):
|
||||||
|
|
||||||
|
|
||||||
class JqPrettyJsonOut(sublime_plugin.TextCommand):
|
class JqPrettyJsonOut(sublime_plugin.TextCommand):
|
||||||
def run(self, edit, jq_output=""):
|
def run(self, edit, jq_output=str()):
|
||||||
self.view.insert(edit, 0, jq_output)
|
self.view.insert(edit, 0, jq_output)
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,13 +478,12 @@ class PrettyJsonGotoSymbolCommand(PrettyJsonBaseCommand, sublime_plugin.TextComm
|
||||||
self.goto_items = []
|
self.goto_items = []
|
||||||
|
|
||||||
content = self.view.substr(sublime.Region(0, self.view.size()))
|
content = self.view.substr(sublime.Region(0, self.view.size()))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
json_data = self.json_loads(content)
|
json_data = self.json_loads(content)
|
||||||
self.generate_items(json_data, "")
|
self.generate_items(json_data, "")
|
||||||
sublime.active_window().show_quick_panel(self.items, self.goto)
|
sublime.active_window().show_quick_panel(self.items, self.goto)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.show_exception(msg=ex)
|
self.show_exception(region=None, msg=ex)
|
||||||
|
|
||||||
def generate_items(self, json_data, root_key):
|
def generate_items(self, json_data, root_key):
|
||||||
if isinstance(json_data, OrderedDict):
|
if isinstance(json_data, OrderedDict):
|
||||||
|
|
|
@ -27,8 +27,8 @@ class PrettyJsonLintListener(sublime_plugin.EventListener, PrettyJsonBaseCommand
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.json_loads(json_content)
|
self.json_loads(json_content)
|
||||||
except Exception:
|
except Exception as ex:
|
||||||
self.show_exception()
|
self.show_exception(msg=ex)
|
||||||
|
|
||||||
|
|
||||||
class PrettyJsonAutoPrettyOnSaveListener(sublime_plugin.EventListener):
|
class PrettyJsonAutoPrettyOnSaveListener(sublime_plugin.EventListener):
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
div.error-arrow {
|
||||||
|
border-top: 0.4rem solid transparent;
|
||||||
|
border-left: 0.5rem solid color(var(--redish) blend(var(--background) 30%));
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
div.container {
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0 0.2rem 0.2rem 0.2rem;
|
||||||
|
}
|
||||||
|
div.content {
|
||||||
|
padding: 0.4rem 0.4rem 0.4rem 0.7rem;
|
||||||
|
}
|
||||||
|
div.content p {
|
||||||
|
margin: 0.2rem;
|
||||||
|
}
|
||||||
|
div.toolbar {
|
||||||
|
padding: 0.2rem 0.7rem 0.2rem 0.7rem;
|
||||||
|
}
|
||||||
|
div.toolbar a {
|
||||||
|
text-decoration: none
|
||||||
|
}
|
||||||
|
html.dark div.toolbar {
|
||||||
|
background-color: #00000018;
|
||||||
|
}
|
||||||
|
html.light div.toolbar {
|
||||||
|
background-color: #ffffff18;
|
||||||
|
}
|
Loading…
Reference in New Issue