Skip to content

Commit

Permalink
- Slightly more helpful error message to console when Bind throws
Browse files Browse the repository at this point in the history
- Added `includeRule` for CSS style sheets. For example, `includeRule "wh100"` will look for and include CSS definitions for `rule ".wh100"` from the same style sheet
  • Loading branch information
davedawkins committed Jul 3, 2024
1 parent cba867e commit a6c9337
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 29 deletions.
12 changes: 6 additions & 6 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
"version": 1,
"isRoot": true,
"tools": {
"fable": {
"version": "3.7.20",
"commands": [
"fable"
]
},
"paket": {
"version": "5.257.0",
"commands": [
"paket"
]
},
"fable": {
"version": "4.19.3",
"commands": [
"fable"
]
}
}
}
5 changes: 4 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### 2.0.12
- Slightly more helpful error message to console when Bind throws
- Added `includeRule` for CSS style sheets. For example, `includeRule "wh100"` will look for and include CSS definitions for `rule ".wh100"` from the same style sheet

### 2.0.11
- New interface IReadOnlyStore, like an IObservable where you can query the current value
- Unprotect a few core functions and modules to enable development of new SutilElements (ContextHelpers, build, SutilEffect.MakeGroup, SutilGroup.RegisterUnsubscribe, SutilCore.ContextHelpers, SutilCore.build)
Expand All @@ -7,7 +11,6 @@
- Added more `c` helpers (ac, hrc, tbodyc, olc)
- Fix for Store.iter


### 2.0.9
- Remove cleanup diagnostics

Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.300",
"version": "8.0.100",
"rollForward": "latestFeature"
}
}
}
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Sutil/Bindings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ let bindElementCO<'T> (store : IObservable<'T>) (element: IObservable<'T> -> Su
node <- build (element(store)) (bindCtx |> ContextHelpers.withReplace (node,group.NextDomNode))
with
| x ->
JS.console.error(x)
JS.console.error("sutil.bindElementCO:parentNode: ", ctx.ParentNode, "exception:", x)
node <- build (elementFromException x) (bindCtx |> ContextHelpers.withReplace (node,group.NextDomNode))
)
group.RegisterUnsubscribe ( fun () ->
Expand Down
58 changes: 46 additions & 12 deletions src/Sutil/Styling.fs
Original file line number Diff line number Diff line change
Expand Up @@ -86,34 +86,69 @@ let private framesToText (frames : KeyFrames) =

let private isSutilRule (nm:string,v) = nm.StartsWith("sutil")

let private ruleToText (styleName : string) (rule:StyleRule) =
let private ruleToText (classMap : Map<string,StyleRule>) (styleName : string) (rule:StyleRule) =
//rule.SelectorSpec + (styleListToText rule.Style)
let styleText = String.Join ("\n", rule.Style |> Seq.filter (not << isSutilRule) |> Seq.map (fun (nm,v) -> $" {nm}: {v};"))

let rec styleText (r : StyleRule) =
r.Style
|> Seq.filter (not << isSutilRule)
|> Seq.map (fun (nm,v) ->
if (nm.EndsWith("()")) then
match classMap.TryFind nm[0..-3] with
| Some subrule ->
styleText subrule
| _ ->
Fable.Core.JS.console.warn("No class found for substitution: ", nm[0..-3])
""
else
$" {nm}: {v};")
|> String.concat "\n"

[
specifySelector styleName rule.SelectorSpec
" {\n"
styleText
styleText rule
"}\n"
] |> String.concat ""

let rec mediaRuleToText styleName rule =
sprintf "@media %s {\n%s\n}\n" (rule.Condition) (rule.Rules |> List.map (entryToText styleName) |> String.concat "\n")
let rec mediaRuleToText classMap styleName rule =
sprintf "@media %s {\n%s\n}\n" (rule.Condition) (rule.Rules |> List.map (entryToText classMap styleName) |> String.concat "\n")

and entryToText (styleName : string) = function
and entryToText classMap (styleName : string) = function
| Rule rule ->
ruleToText styleName rule
ruleToText classMap styleName rule
| KeyFrames frames ->
framesToText frames
| MediaRule rule ->
mediaRuleToText styleName rule
mediaRuleToText classMap styleName rule

let private isClassChar c = Char.IsLetterOrDigit(c) || c = '-' || c = '_'

let private isClassName (s : string) =
s.ToCharArray() |> Array.forall isClassChar

let private isClassOnly (s : string) =
s.Length >= 2 && s[0] = '.' && isClassName (s.Substring(1))


let getClassMap (styleSheet) =
styleSheet
|> List.choose (fun d -> match d with Rule r when isClassOnly r.SelectorSpec -> Some (r.SelectorSpec.Substring(1),r) | _ -> None)
|> (fun items -> Fable.Core.JS.console.log("Class map: ", items |> List.map fst |> String.concat ","); items)
|> Map


let includeRule (name : string) = (name + "()"), ("" :> obj)

let private styleSheetAsText (styleSheet : StyleSheetDefinitions) =
System.String.Join("\n", styleSheet |> List.map (entryToText ""))
let classMap : Map<string,StyleRule > = getClassMap styleSheet

System.String.Join("\n", styleSheet |> List.map (entryToText classMap ""))

let private addStyleSheet (doc:Document) styleName (styleSheet : StyleSheetDefinitions) =
let style = newStyleElement doc
for entry in styleSheet do
entryToText styleName entry |> doc.createTextNode |> style.appendChild |> ignore
entryToText (getClassMap styleSheet) styleName entry |> doc.createTextNode |> style.appendChild |> ignore
(fun () -> style.parentElement.removeChild(style) |> ignore)

let addGlobalStyleSheet (doc:Document) (styleSheet : StyleSheetDefinitions) =
Expand All @@ -125,10 +160,9 @@ let addGlobalStyleSheet (doc:Document) (styleSheet : StyleSheetDefinitions) =
let rule selector style =
let result = Rule {
SelectorSpec = selector
//Selector = parseSelector selector
Style = style
}
//log($"%s{selector} -> %A{result.Selector}")

result

/// <summary>
Expand Down

0 comments on commit a6c9337

Please sign in to comment.