diff --git a/src-web/components/Editor/Editor.css b/src-web/components/Editor/Editor.css index 82a653de..2c48fedd 100644 --- a/src-web/components/Editor/Editor.css +++ b/src-web/components/Editor/Editor.css @@ -42,7 +42,7 @@ outline: none !important; } -.cm-multiline.cm-editor.cm-focused .cm-scroller { +.cm-multiline .cm-editor.cm-focused .cm-scroller { box-shadow: 0 0 0 1px hsl(var(--color-blue-400)/0.4); } @@ -66,6 +66,10 @@ color: hsl(var(--color-gray-200)); } +.cm-editor .cm-gutterElement { + transition: color var(--transition-duration); +} + .cm-editor .fold-gutter-icon { height: 1.5em; padding-top: 0.2em; diff --git a/src-web/components/Editor/extensions.ts b/src-web/components/Editor/extensions.ts index 4d88fcc2..21f76a02 100644 --- a/src-web/components/Editor/extensions.ts +++ b/src-web/components/Editor/extensions.ts @@ -48,13 +48,16 @@ export const myHighlightStyle = HighlightStyle.define([ color: '#757b93', fontStyle: 'italic', }, - { tag: [t.name, t.tagName, t.angleBracket, t.docString], color: 'hsl(var(--color-blue-500))' }, + { + tag: [t.name, t.tagName, t.angleBracket, t.docString, t.number], + color: 'hsl(var(--color-blue-500))', + }, { tag: [t.variableName], color: '#31c434' }, { tag: [t.bool], color: '#e864f6' }, { tag: [t.attributeName], color: 'hsl(var(--color-violet-500))' }, { tag: [t.attributeValue], color: 'hsl(var(--color-orange-500))' }, { tag: [t.string], color: 'hsl(var(--color-yellow-500))' }, - { tag: [t.keyword, t.meta], color: '#45e8a4' }, + { tag: [t.keyword, t.meta, t.operator], color: '#45e8a4' }, ]); // export const defaultHighlightStyle = HighlightStyle.define([ diff --git a/src-web/components/Editor/url/extension.ts b/src-web/components/Editor/url/extension.ts index 22a9e9dd..268d5426 100644 --- a/src-web/components/Editor/url/extension.ts +++ b/src-web/components/Editor/url/extension.ts @@ -7,16 +7,16 @@ import { completeFromList } from '@codemirror/autocomplete'; const parserWithMetadata = parser.configure({ props: [ styleTags({ - ProtocolName: t.comment, - Slashy: t.comment, + Protocol: t.comment, + Port: t.attributeName, Host: t.variableName, - Slash: t.comment, PathSegment: t.bool, - QueryName: t.variableName, - QueryValue: t.string, - Question: t.comment, - Equal: t.comment, + Slash: t.bool, + Question: t.attributeName, + QueryName: t.attributeName, + QueryValue: t.attributeName, Amp: t.comment, + Equal: t.comment, }), // indentNodeProp.add({ // Application: (context) => context.column(context.node.from) + context.unit, diff --git a/src-web/components/Editor/url/url.grammar b/src-web/components/Editor/url/url.grammar index ccb50b0f..432f9867 100644 --- a/src-web/components/Editor/url/url.grammar +++ b/src-web/components/Editor/url/url.grammar @@ -1,7 +1,7 @@ -@top url { Protocol Host Path Query } +@top url { Protocol Host Port? Path Query } Protocol { - ProtocolName Slashy + "http://" | "https://" } Path { @@ -17,12 +17,11 @@ QueryPair { } @tokens { - ProtocolName { "http" | "https" } + Port { ":" $[0-9]+ } Host { $[a-zA-Z0-9-_.]+ } QueryName { $[a-zA-Z0-9-_.]+ } - QueryValue { $[a-zA-Z0-9-_.]+ } + QueryValue { $[a-zA-Z0-9-_./]+ } PathSegment { $[a-zA-Z0-9-_.]+ } - Slashy { "://" } Slash { "/" } Question { "?" } Equal { "=" } diff --git a/src-web/components/Editor/url/url.terms.ts b/src-web/components/Editor/url/url.terms.ts index 6003bc8e..b7174166 100644 --- a/src-web/components/Editor/url/url.terms.ts +++ b/src-web/components/Editor/url/url.terms.ts @@ -2,16 +2,15 @@ export const url = 1, Protocol = 2, - ProtocolName = 3, - Slashy = 4, - Host = 5, - Path = 6, - Slash = 7, - PathSegment = 8, - Query = 9, - Question = 10, - QueryPair = 11, - Amp = 12, - QueryName = 13, - Equal = 14, - QueryValue = 15 + Host = 3, + Port = 4, + Path = 5, + Slash = 6, + PathSegment = 7, + Query = 8, + Question = 9, + QueryPair = 10, + Amp = 11, + QueryName = 12, + Equal = 13, + QueryValue = 14 diff --git a/src-web/components/Editor/url/url.ts b/src-web/components/Editor/url/url.ts index 99aada5d..16281422 100644 --- a/src-web/components/Editor/url/url.ts +++ b/src-web/components/Editor/url/url.ts @@ -2,14 +2,14 @@ import {LRParser} from "@lezer/lr" export const parser = LRParser.deserialize({ version: 14, - states: "#xOQOPOOOVOPO'#C^O[OQOOOOOO,58x,58xOaOPOOOiOSO'#ClOnOPO'#CbOvOPOOOOOO,59W,59WOOOO-E6j-E6jO{OWO'#CeQOOOOOO!WOPO'#CgO!]OWO'#CgOOOO'#Cm'#CmO!bOWO,59PO!mO`O,59RO!rOPO,59ROOOO-E6k-E6kOOOO1G.m1G.mO!wO`O1G.mOOOO7+$X7+$X", - stateData: "!|~ORPO~OSRO~OTSO~OVTOYUP~OWWO~OVTOYUX~OYYO~O[]O][ObXX~O^`O~O]aO~O[]O][ObXa~O_cO~O^dO~O_eO~O", - goto: "|bPPcPPPfPPiPlPPPPpvRQORVSRZVT^Y_QUSRXUQ_YRb_", - nodeNames: "⚠ url Protocol ProtocolName Slashy Host Path Slash PathSegment Query Question QueryPair Amp QueryName Equal QueryValue", - maxTerm: 18, + states: "#xOQOPOOOOOO'#C^'#C^OYOQOOO_OPOOOjOSO'#CkOoOPO'#CaOwOPOOObOPOOOOOO,59V,59VOOOO-E6i-E6iO|OWO'#CdQOOOOOO!XOPO'#CfO!^OWO'#CfOOOO'#Cl'#ClO!cOWO,59OO!nO`O,59QO!sOPO,59QOOOO-E6j-E6jOOOO1G.l1G.lO!xO`O1G.lOOOO7+$W7+$W", + stateData: "!}~ObPOcPO~ORRO~OSVOUSOXTP~OVWO~OUSOXTX~OXYO~OZ]O[[OaWX~O]`O~O[aO~OZ]O[[OaWa~O^cO~O]dO~O^eO~O", + goto: "}aPPbPPePPiPlPPPPpwRQOTURVRZUT^Y_STRVRXTQ_YRb_", + nodeNames: "⚠ url Protocol Host Port Path Slash PathSegment Query Question QueryPair Amp QueryName Equal QueryValue", + maxTerm: 19, skippedNodes: [0], repeatNodeCount: 2, - tokenData: "'T~R]vwz}!O!P!O!P!P!P!Q!n!Q![!P![!]!s!_!`#U!a!b#Z!c!}!P#R#S!P#T#[!P#[#]#`#]#o!P~!PO[~n![UTQWS]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#o!P~!sOV~~!vP!P!Q!y~!|P!P!Q#P~#UOS~~#ZO^~~#`OY~o#kWTQWS]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#h!P#h#i$T#i#o!Po$`WTQWS]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#h!P#h#i$x#i#o!Po%TWTQWS]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#d!P#d#e%m#e#o!Po%zWTQWSRP]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#g!P#g#h&d#h#o!Po&qUTQWSRP]W_`}!O!P!O!P!P!Q![!P!c!}!P#R#S!P#T#o!P", + tokenData: ")]~R]vwz}!O!P!O!P!P!P!Q#]!Q![!P![!]#y!_!`$X!a!b$^!c!}!P#R#S!P#T#[!P#[#]$c#]#o!P~!POZ~n![VRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P!c!}!P#R#S!P#T#o!P`!vV^`}!O!q!O!P!q!P!Q!q!Q![!q!c!}!q#R#S!q#T#o!qa#dV^`UP}!O!q!O!P!q!P!Q!q!Q![!q!c!}!q#R#S!q#T#o!q~#|P!Q![$P~$UPS~!Q![$P~$^O]~~$cOX~o$nXRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P!c!}!P#R#S!P#T#h!P#h#i%Z#i#o!Po%fXRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P!c!}!P#R#S!P#T#h!P#h#i&R#i#o!Po&^XRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P!c!}!P#R#S!P#T#d!P#d#e&y#e#o!Po'UYRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P![!]'t!c!}!P#R#S!P#T#g!P#g#h(V#h#o!PP'wP!P!Q'zP'}P!P!Q(QP(VObPo(bWRQVS[W^`}!O!P!O!P!P!P!Q!q!Q![!P![!](z!c!}!P#R#S!P#T#o!PP(}P!P!Q)QP)TP!P!Q)WP)]OcP", tokenizers: [0, 1, 2, 3, 4], topRules: {"url":[0,1]}, tokenPrec: 0 diff --git a/src-web/components/UrlBar.tsx b/src-web/components/UrlBar.tsx index c57737f1..33f95598 100644 --- a/src-web/components/UrlBar.tsx +++ b/src-web/components/UrlBar.tsx @@ -45,7 +45,13 @@ export function UrlBar({ sendRequest, loading, onMethodChange, method, onUrlChan { label: 'HEAD', value: 'HEAD' }, ]} > - @@ -56,7 +62,7 @@ export function UrlBar({ sendRequest, loading, onMethodChange, method, onUrlChan spin={loading} disabled={loading} size="sm" - className="mr-1" + className="mr-1 !px-2" /> } /> diff --git a/src-web/main.css b/src-web/main.css index 6efda673..600363a5 100644 --- a/src-web/main.css +++ b/src-web/main.css @@ -4,6 +4,7 @@ :root { color-scheme: light dark; + --transition-duration: 200ms ease-in-out; } :not(input):not(textarea), @@ -22,7 +23,7 @@ html, body, #root { } * { - transition: background-color 150ms ease, border-color 150ms ease; + transition: background-color var(--transition-duration), border-color var(--transition-duration); } @layer base {