@@ -4,13 +4,14 @@ import {
44 type Component ,
55 type Delegate ,
66} from "dreamland/core" ;
7- import iconShield from "@ktibow/iconset-ion/shield -outline" ;
7+ import iconOptions from "@ktibow/iconset-ion/options -outline" ;
88import iconStar from "@ktibow/iconset-ion/star-outline" ;
99import iconSearch from "@ktibow/iconset-ion/search" ;
1010import iconForwards from "@ktibow/iconset-ion/arrow-forward" ;
1111import { Icon } from "./Icon" ;
1212import { browser , scramjet } from "../main" ;
1313import { IconButton } from "./IconButton" ;
14+ import { parse } from "tldts" ;
1415
1516export const focusOmnibox = createDelegate < void > ( ) ;
1617export function trimUrl ( v : URL ) {
@@ -22,6 +23,24 @@ export function trimUrl(v: URL) {
2223 ) ;
2324}
2425
26+ // subdomain, domain+tld+port, path+search+query
27+ function splitUrl ( url : URL ) : [ string , string , string ] {
28+ let last = url . pathname + url . search + url . hash ;
29+ if ( last == "/" ) last = "" ;
30+
31+ let results = parse ( url . href ) ;
32+ let domain = results . domain ;
33+ if ( domain && url . port ) {
34+ domain += ":" + url . port ;
35+ }
36+ let subdomain = results . subdomain ;
37+ if ( subdomain ) {
38+ subdomain += "." ;
39+ }
40+
41+ return [ subdomain || "" , domain || "" , last ] ;
42+ }
43+
2544type OmniboxResult = {
2645 kind : "search" | "history" | "bookmark" | "direct" ;
2746 title ?: string | null ;
@@ -37,6 +56,7 @@ export const UrlInput: Component<
3756 {
3857 value : string ;
3958 active : boolean ;
59+ justselected : boolean ;
4060 input : HTMLInputElement ;
4161
4262 focusindex : number ;
@@ -151,6 +171,7 @@ export const UrlInput: Component<
151171 }
152172 this . input . focus ( ) ;
153173 this . input . select ( ) ;
174+ this . justselected = true ;
154175
155176 this . input . scrollLeft = 0 ;
156177 } ;
@@ -232,9 +253,27 @@ export const UrlInput: Component<
232253 ) ) }
233254 </ div >
234255 < div class = "realbar" >
235- < IconButton icon = { iconShield } > </ IconButton >
256+ < div class = "lefticon" >
257+ { use ( this . active , this . focusindex , this . overflowItems ) . map ( ( ) =>
258+ this . active ? (
259+ this . focusindex > 0 && this . overflowItems . length > 0 ? (
260+ < img
261+ src = {
262+ this . overflowItems [ this . focusindex - 1 ] . favicon ||
263+ "/vite.svg"
264+ }
265+ > </ img >
266+ ) : (
267+ < Icon icon = { iconSearch } > </ Icon >
268+ )
269+ ) : (
270+ < Icon icon = { iconOptions } > </ Icon >
271+ )
272+ ) }
273+ </ div >
236274 { use ( this . active ) . andThen (
237275 < input
276+ spellcheck = "false"
238277 this = { use ( this . input ) }
239278 value = { use ( this . value ) }
240279 on :keydown = { ( e : KeyboardEvent ) => {
@@ -260,6 +299,8 @@ export const UrlInput: Component<
260299 } }
261300 // keyup, we want this to happen after the input has been processed (so the user can delete the whole thing)
262301 on :keyup = { ( e : KeyboardEvent ) => {
302+ if ( ! this . justselected ) return ;
303+
263304 // if the user didn't modify anything
264305 if ( this . input . value == trimUrl ( this . tabUrl ) ) {
265306 // insert the untrimmed version
@@ -275,6 +316,8 @@ export const UrlInput: Component<
275316 this . input . setSelectionRange ( schemelen , schemelen ) ;
276317 }
277318 }
319+
320+ this . justselected = false ;
278321 } }
279322 on :input = { ( e : InputEvent ) => {
280323 this . value = this . input . value ;
@@ -285,7 +328,17 @@ export const UrlInput: Component<
285328 { use ( this . active , this . tabUrl )
286329 . map ( ( [ active , url ] ) => ! active && url . href != "puter://newtab" )
287330 . andThen (
288- < span class = "inactiveurl" > { use ( this . tabUrl ) . map ( trimUrl ) } </ span >
331+ < span class = "inactiveurl" >
332+ < span class = "subdomain" >
333+ { use ( this . tabUrl ) . map ( ( t ) => splitUrl ( t ) [ 0 ] ) }
334+ </ span >
335+ < span class = "domain" >
336+ { use ( this . tabUrl ) . map ( ( t ) => splitUrl ( t ) [ 1 ] ) }
337+ </ span >
338+ < span class = "rest" >
339+ { use ( this . tabUrl ) . map ( ( t ) => splitUrl ( t ) [ 2 ] ) }
340+ </ span >
341+ </ span >
289342 ) }
290343 { use ( this . active , this . tabUrl )
291344 . map ( ( [ active , url ] ) => ! active && url . href == "puter://newtab" )
@@ -318,6 +371,19 @@ UrlInput.style = css`
318371 height : 100% ;
319372 }
320373
374+ .lefticon {
375+ font-size : 1.25em ;
376+ color : grey;
377+ display : flex;
378+ margin : 0.25em ;
379+ align-self : stretch;
380+ align-items : center;
381+ }
382+ .lefticon img {
383+ width : 20px ;
384+ height : 20px ;
385+ }
386+
321387 .favicon {
322388 width : 16px ;
323389 height : 16px ;
@@ -356,7 +422,7 @@ UrlInput.style = css`
356422 color : grey;
357423 }
358424 .overflowitem .focused {
359- background : blue ;
425+ background : # fff ;
360426 }
361427
362428 .overflow .active {
@@ -390,6 +456,12 @@ UrlInput.style = css`
390456 display : flex;
391457 align-items : center;
392458 }
459+ .inactiveurl .subdomain ,
460+ .inactiveurl .rest {
461+ opacity : 0.7 ;
462+ color : grey;
463+ }
464+
393465 .placeholder {
394466 color : grey;
395467 display : flex;
0 commit comments