diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj index e7bb3e709a..24c07171ed 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj @@ -31,7 +31,6 @@ - diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj index 8b21c9d076..30b863a642 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj @@ -29,7 +29,13 @@ - + + diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs index 96ac3692a5..259df816f9 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfRenderMode.cs @@ -15,7 +15,7 @@ public enum BitPdfRenderMode /// a display list produced by the C# engine (the pdf.js model). Far fewer DOM /// nodes; selection, search and links still work through the DOM text layer, /// and zoom changes re-rasterize the canvases so text stays crisp. Requires - /// JavaScript — a prerendered page shows a blank canvas until the client + /// JavaScript - a prerendered page shows a blank canvas until the client /// loads. /// Canvas, diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs index a2bb262bb9..fafdf634cd 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.razor.cs @@ -134,7 +134,7 @@ public partial class BitPdfViewer : BitComponentBase /// /// How painted text is emitted. merges - /// same-line, same-style runs into one span per visual line — far fewer DOM + /// same-line, same-style runs into one span per visual line - far fewer DOM /// nodes on per-glyph PDFs, with small intra-line position drift (explicit /// kerning between runs is approximated). Rotated text always stays exact. /// Default is . @@ -1555,7 +1555,7 @@ private async Task RunSearchAsync() // Search a per-page extracted-text index (built lazily) rather than the // rendered DOM, so we only render the pages that actually contain matches - // — a 500-page document with matches on 3 pages renders 3, not 500. + // - a 500-page document with matches on 3 pages renders 3, not 500. _pageText ??= new string?[_document.PageCount]; string needle = _searchQuery; int pageCount = _document.PageCount; // captured so the loop condition never reads a nulled _document diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss index cf2b6eac9f..44f5ea1324 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.scss @@ -374,7 +374,7 @@ pointer-events: auto; } -/* Selection spans (data-bit-pdv-sel) hold the real Unicode but paint nothing — keep +/* Selection spans (data-bit-pdv-sel) hold the real Unicode but paint nothing - keep them transparent even while selected so only the highlight box shows and the painted glyphs beneath stay visible through it. Without this the browser paints the selected substitute glyphs opaque, stacking a wrong-font copy over the diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts index 30e4afbbc8..c1a543311c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/BitPdfViewer.ts @@ -23,7 +23,7 @@ } } - // Scrolls `target` into view by scrolling ONLY `container` — unlike + // Scrolls `target` into view by scrolling ONLY `container` - unlike // scrollIntoView, which also scrolls every scrollable ancestor (including // the hosting page, yanking the whole document around when the viewer is // embedded mid-page). @@ -468,7 +468,7 @@ clone.style.transformOrigin = "top left"; // A cloned loses its pixels: substitute a snapshot image so // canvas-mode pages print their painted content. Pages with a cached - // display list re-rasterize at print resolution — the screen-resolution + // display list re-rasterize at print resolution - the screen-resolution // bitmap is sized for on-screen zoom and prints blurry. const srcCanvases = el.querySelectorAll("canvas[data-bit-pdv-canvas]"); const dstCanvases = clone.querySelectorAll("canvas[data-bit-pdv-canvas]"); @@ -615,7 +615,7 @@ return; } - // @font-face faces load lazily — only when DOM text uses them — and canvas + // @font-face faces load lazily - only when DOM text uses them - and canvas // fillText never waits for (or reliably triggers) a load: it draws with the // fallback immediately. In canvas mode no DOM references the embedded // families, so without an explicit load the FIRST paint renders tofu until @@ -827,7 +827,7 @@ const ranges: Range[] = []; container.querySelectorAll("[data-page]").forEach((page) => { - // Search only the coalesced selection layer ([data-bit-pdv-sel]) — it + // Search only the coalesced selection layer ([data-bit-pdv-sel]) - it // holds the real Unicode in reading order. The painted layer beneath is // presentational (real glyphs or Private-Use codepoints) and would // otherwise double-count. diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfDocument.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfDocument.cs index 0d464adac9..a02b81c003 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfDocument.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfDocument.cs @@ -209,7 +209,7 @@ private void Traverse(BitPdfDict node, in InheritedAttributes inherited, } // A node explicitly typed /Pages but with no usable /Kids is a damaged - // interior node — skip it rather than materializing a phantom page. + // interior node - skip it rather than materializing a phantom page. if (BitPdfPrimitives.IsName(typeObj, "Pages")) { _xref.Warnings.Add("Interior /Pages node has no valid /Kids; skipping."); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfStructTree.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfStructTree.cs index 3cc61077d8..2370971a62 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfStructTree.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfStructTree.cs @@ -42,7 +42,7 @@ private static List ReadKids(IBitPdfXRef xref, object? kids private static void AddNode(IBitPdfXRef xref, object? item, List result, HashSet visited, int depth) { - // Marked-content leaves are plain integers or MCR/OBJR dicts; skip them — + // Marked-content leaves are plain integers or MCR/OBJR dicts; skip them - // the structure tree API exposes the element hierarchy, not content refs. if (item is double) { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfUnsupportedEncryptionException.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfUnsupportedEncryptionException.cs index 1fd10e5f1c..8da2e07f47 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfUnsupportedEncryptionException.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfUnsupportedEncryptionException.cs @@ -2,7 +2,7 @@ /// /// Thrown when a document declares an /Encrypt dictionary that this -/// library cannot handle — an unsupported security handler or revision, or a +/// library cannot handle - an unsupported security handler or revision, or a /// cryptographic primitive that is unavailable on the current platform (for /// example MD5/AES in the browser WebAssembly sandbox). Distinct from /// so callers can surface a clear "this diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfXRef.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfXRef.cs index 10b5ec96f3..89e86e5751 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfXRef.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/BitPdfXRef.cs @@ -103,7 +103,7 @@ public void Parse() } // If the classic/stream path did not yield a usable catalog, brute-force - // scan the file for objects and rebuild — matching pdf.js recovery. + // scan the file for objects and rebuild - matching pdf.js recovery. if (Trailer is null || Root is null) { RebuildByScanning(); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Content/BitPdfTextExtractor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Content/BitPdfTextExtractor.cs index 8e8678d5b2..d4e4c31f70 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Content/BitPdfTextExtractor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Content/BitPdfTextExtractor.cs @@ -8,7 +8,7 @@ namespace Bit.BlazorUI; /// /// Extracts the visible text of a page by replaying its content stream and /// decoding show-text operators through each selected font. Positioning is -/// approximated with simple space/newline heuristics — enough for search and +/// approximated with simple space/newline heuristics - enough for search and /// copy, not a layout-faithful reconstruction. /// public static class BitPdfTextExtractor diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Filters/BitPdfJpegDecoder.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Filters/BitPdfJpegDecoder.cs index d63bb7f194..3e68084b38 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Filters/BitPdfJpegDecoder.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Filters/BitPdfJpegDecoder.cs @@ -101,7 +101,7 @@ private sealed class HuffTable switch (marker) { case 0xC0: // SOF0 baseline - case 0xC1: // SOF1 extended sequential (Huffman) — same layout + case 0xC1: // SOF1 extended sequential (Huffman) - same layout { precision = data[segStart]; frameHeight = (data[segStart + 1] << 8) | data[segStart + 2]; @@ -122,7 +122,7 @@ private sealed class HuffTable } break; } - case 0xC2: // SOF2 progressive — not supported here + case 0xC2: // SOF2 progressive - not supported here return null; case 0xC4: // DHT ReadHuffmanTables(data, segStart, segEnd, huffDc, huffAc); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfCffFontParser.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfCffFontParser.cs index 1dedb287e7..c5a12d22ec 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfCffFontParser.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfCffFontParser.cs @@ -25,7 +25,7 @@ internal sealed class BitPdfCffFontParser /// The raw CFF Encoding offset from the Top DICT (0/1 = predefined). public int EncodingOffset { get; private set; } - /// true for a CID-keyed CFF (ROS present) — unsupported here. + /// true for a CID-keyed CFF (ROS present) - unsupported here. public bool IsCid { get; private set; } public static BitPdfCffFontParser? Parse(byte[] cff) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfFont.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfFont.cs index b3196b2da9..c17c23e582 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfFont.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfFont.cs @@ -383,7 +383,7 @@ private static (byte[]?, string?) ExtractEmbedded(BitPdfDict? descriptor) : (data, "cff"); } // Type1 program (/FontFile): parse it and build an OpenType/CFF font the - // browser can load. On any failure fall through to a substitute font — + // browser can load. On any failure fall through to a substitute font - // a rejected @font-face simply falls back to the generic family. if (descriptor.Get("FontFile") is BitPdfStream t1Stream) { @@ -761,7 +761,7 @@ private double WidthFor(int code) int index = code - _firstChar; if (index >= 0 && index < _widths.Length) { - // An explicit width of 0 is valid (e.g. combining marks) — use it + // An explicit width of 0 is valid (e.g. combining marks) - use it // rather than falling through to a substitute metric. return _widths[index] * _glyphWidthScale; } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfSfntGlyphMapper.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfSfntGlyphMapper.cs index b960806710..0e79ed4162 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfSfntGlyphMapper.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfSfntGlyphMapper.cs @@ -32,7 +32,7 @@ internal static class BitPdfSfntGlyphMapper var names = ReadPost(font, dir); // glyph name → gid // Map each byte code to a unique Private-Use-Area codepoint (glyph - // painting is by exact glyph id — no shaping, no Unicode collisions). + // painting is by exact glyph id - no shaping, no Unicode collisions). var result = new Dictionary(); for (int code = 0; code < 256; code++) { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfTrueTypeSanitizer.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfTrueTypeSanitizer.cs index 8ea0926c25..b061d23dfe 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfTrueTypeSanitizer.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfTrueTypeSanitizer.cs @@ -1,6 +1,6 @@ // A conservative TrueType/OpenType (sfnt) sanitizer. Embedded PDF subset fonts // frequently ship with an unsorted table directory, wrong table checksums, a -// wrong head.checkSumAdjustment, or unpadded tables — all of which strict font +// wrong head.checkSumAdjustment, or unpadded tables - all of which strict font // parsers (including the browser's OTS) reject, so the @font-face silently fails // to load. This rebuilds a structurally valid sfnt: recognized tables are kept // verbatim, the directory is re-sorted, tables are 4-byte aligned, and all @@ -21,7 +21,7 @@ internal static class BitPdfTrueTypeSanitizer /// /// As , but replaces the font's cmap with - /// when supplied — used to inject a clean + /// when supplied - used to inject a clean /// synthetic Unicode cmap for subset fonts whose own cmap OTS rejects. /// public static byte[]? Sanitize(byte[] input, byte[]? replacementCmap) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfType1Font.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfType1Font.cs index fe41b25ed5..52abd29025 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfType1Font.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Fonts/BitPdfType1Font.cs @@ -413,7 +413,7 @@ private bool Escape(int op, InterpContext ctx) ? Pop(ctx.PostScriptStack) : 0); break; - case 6: // seac (accented char) — not composed; ignore base for now + case 6: // seac (accented char) - not composed; ignore base for now case 7: // sbw case 0: // dotsection case 1: // vstem3 diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfCanvasRenderResult.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfCanvasRenderResult.cs index 7c5553af97..4fd9f4c824 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfCanvasRenderResult.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfCanvasRenderResult.cs @@ -6,7 +6,7 @@ namespace Bit.BlazorUI; /// /// The page's DOM part: the positioned page div containing the /// <canvas> placeholder, the selectable text layer, and link/ -/// annotation overlays — everything except the painted content. +/// annotation overlays - everything except the painted content. /// /// /// The display list to replay onto the canvas (JSON array of drawing ops), diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfHtmlRenderer.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfHtmlRenderer.cs index f9719a1c0e..6719904d30 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfHtmlRenderer.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfHtmlRenderer.cs @@ -54,7 +54,7 @@ public sealed class BitPdfHtmlRenderer // Coalesced selection/text layer (the pdf.js model): text is accumulated here // separately from the painted glyph spans and emitted once, on top, at page end - // — decoupled from paint order. Adjacent runs on a baseline merge into a single + // - decoupled from paint order. Adjacent runs on a baseline merge into a single // transparent, selectable span per visual line (with spaces inserted for gaps), // so double-click words, triple-click lines, click-drag and copy behave like // normal text instead of fragmenting per glyph. @@ -65,8 +65,9 @@ public sealed class BitPdfHtmlRenderer /// /// How painted text runs are emitted. - /// merges same-line, same-style substitute-font runs into one span per visual - /// line (embedded-font runs always stay per-run exact). Default is + /// merges same-line, same-style runs - including embedded-font (PUA + /// glyph-mapped) ones - into one span per visual line; only non-upright + /// (rotated, mirrored, or skewed) text stays per-run exact. Default is /// . /// public BitPdfTextCoalescing TextCoalescing { get; set; } = BitPdfTextCoalescing.Exact; @@ -270,7 +271,7 @@ public string Render() // in, so dragging over text selects while empty areas stay clickable. // font-size:0 collapses the flow-level
separators (the spans set their // own size): the brs still put line breaks in copied text, but their empty - // line boxes — which stack at the container's top-left — become zero-sized, + // line boxes - which stack at the container's top-left - become zero-sized, // so a multi-line selection no longer paints stray highlight blocks along // the page's left edge. if (_selLayer.Length > 0) @@ -1336,7 +1337,7 @@ private static bool IsAllowedUri(string uri) int colon = uri.IndexOf(':'); if (colon <= 0) { - return false; // no scheme, or leading ':' — treat as unsafe + return false; // no scheme, or leading ':' - treat as unsafe } // A URI scheme is letters/digits/+/-/. and must precede any '/', '?' or '#'. for (int i = 0; i < colon; i++) @@ -1370,8 +1371,8 @@ private void SetFont(BitPdfOperation op) { return null; } - // Key the cache by the font's object identity — the indirect reference if - // present (value-equal), otherwise the dictionary instance — rather than + // Key the cache by the font's object identity - the indirect reference if + // present (value-equal), otherwise the dictionary instance - rather than // "depth:name". Different resource dictionaries can reuse a resource name // for different fonts, so a name-based key returned the wrong font. object? raw = fonts.GetRaw(name); @@ -1477,7 +1478,7 @@ private void ShowText(object? operand) private void ShowType3Text(List glyphs) { // Type3 glyphs paint graphics directly (below), reached via a whitelisted - // show-text operator — flush any pending coalesced line to keep paint order. + // show-text operator - flush any pending coalesced line to keep paint order. FlushPaintedLine(); BitPdfFont font = _state.Font!; @@ -1592,18 +1593,18 @@ private void EmitText(string renderText, string realText, double runAdvance) AccumulateSelectionText(realText, trm, left, top, fontHeight, targetWidth, linear); } - // Emit only the PAINTED layer. It is never selectable or searchable — all + // Emit only the PAINTED layer. It is never selectable or searchable - all // selection and find-in-page run against the coalesced layer above. if (invisible) { // Render modes 3/7 (e.g. an OCR text layer over a scanned image) paint // nothing, so there is no glyph layer and no embedded @font-face to - // inline — the coalesced selection span alone carries the text. + // inline - the coalesced selection span alone carries the text. return; } // Canvas mode: one fillText/strokeText op per run at its exact device - // matrix (no DOM cost, so no coalescing) — the selection layer above + // matrix (no DOM cost, so no coalescing) - the selection layer above // already carries the real Unicode. if (_ops is not null) { @@ -1612,13 +1613,14 @@ private void EmitText(string renderText, string realText, double runAdvance) } // Compact mode: coalesce painted runs into one span per visual line. - // Embedded fonts — including PUA glyph-mapped ones, which is how every - // embedded font in this engine paints — coalesce too: the browser lays the + // Embedded fonts - including PUA glyph-mapped ones, which is how every + // embedded font in this engine paints - coalesce too: the browser lays the // merged run out with the font's own advance widths, so only explicit TJ // kerning between runs is approximated while data-w pins the line's total // advance. (A gap-bridging space missing from a subset font falls through - // to the generic fallback in the font stack.) Only rotated/mirrored text - // is excluded — its geometry can't be reduced to a horizontal line. + // to the generic fallback in the font stack.) Only non-upright text + // (rotated/mirrored/skewed) is excluded - its geometry can't be reduced + // to a horizontal line. if (TextCoalescing == BitPdfTextCoalescing.Compact && a > 1e-3 && d > 1e-3 && Math.Abs(b) < 1e-3 && Math.Abs(c) < 1e-3) @@ -1639,8 +1641,8 @@ private void EmitText(string renderText, string realText, double runAdvance) /// /// Emits one canvas text op. The matrix's linear part maps the run's local em - /// space (x right, y down, baseline at the origin) to device space — identical - /// to the HTML span's transform — and (e, f) is the baseline origin, matching + /// space (x right, y down, baseline at the origin) to device space - identical + /// to the HTML span's transform - and (e, f) is the baseline origin, matching /// canvas's alphabetic textBaseline. The interpreter measures the drawn text /// and applies scaleX width-correction to , the /// run's PDF-computed advance (the data-w mechanism, done inline). @@ -1933,7 +1935,7 @@ private void AppendFontStyle(StringBuilder sb, BitPdfFont font) /// /// The CSS font-family list for , registering the /// embedded face's @font-face rule on first use. Canvas text uses the - /// same registered faces — document.fonts serves them to + /// same registered faces - document.fonts serves them to /// ctx.fillText once loaded. /// private string FontFamilyList(BitPdfFont font) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfImage.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfImage.cs index d77ccffb99..6b951bec9e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfImage.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/PdfViewer/Core/Render/BitPdfImage.cs @@ -50,7 +50,7 @@ internal static class BitPdfImage { // Browsers decode plain RGB/YCbCr JPEG correctly, so pass those through. // But CMYK JPEGs render wrong in browsers, and /SMask, /Mask and a - // non-default /Decode all need the pixels in hand — decode in C# then. + // non-default /Decode all need the pixels in hand - decode in C# then. BitPdfColorSpace jcs = BitPdfColorSpace.Create(dict.Get("ColorSpace", "CS"), xref, resources); bool needsCSharp = jcs.Components == 4 || dict.Get("SMask") is BitPdfStream @@ -407,7 +407,7 @@ private static void ApplySoftMask(BitPdfDict dict, IBitPdfXRef xref, BitPdfDict? // The SMask's own bytes need the same image decoding as a base image. We // don't yet decode DCT/JPX masks, so applying the raw compressed bytes as - // alpha would paint noise — leave the image fully opaque instead. + // alpha would paint noise - leave the image fully opaque instead. var maskFilters = GetFilterNames(smask.Dict); if (maskFilters.Contains("DCTDecode") || maskFilters.Contains("DCT") || maskFilters.Contains("JPXDecode") || maskFilters.Contains("JBIG2Decode")) diff --git a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj index fc4510a6ef..c1c43bb2bf 100644 --- a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj @@ -16,10 +16,6 @@ - - - - diff --git a/src/BlazorUI/Bit.BlazorUI.slnx b/src/BlazorUI/Bit.BlazorUI.slnx index 85e580ac17..c2fbf75417 100644 --- a/src/BlazorUI/Bit.BlazorUI.slnx +++ b/src/BlazorUI/Bit.BlazorUI.slnx @@ -25,6 +25,7 @@ + diff --git a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj index 61ef6e0f69..18dac2d8be 100644 --- a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj +++ b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj @@ -32,7 +32,13 @@ - + + diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj index b7e47c30a0..bb31ffc5c1 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj @@ -2,11 +2,24 @@ net10.0 + fcf350f4-eef5-430b-a5cb-144713a68932 + + + true + false + $(DefineConstants);INCLUDE_WASM + + + true true true - fcf350f4-eef5-430b-a5cb-144713a68932 @@ -45,7 +58,8 @@ - + + diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor index d385554583..4b0c25829e 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor @@ -1,9 +1,25 @@ @using Bit.BlazorUI.Demo.Client.Core.Shared -@using Bit.BlazorUI.Demo.Client.Web.Components +@using Bit.BlazorUI.Demo.Client.Web.Shared.Components @{ +#if INCLUDE_WASM + var includeWasm = true; +#else + var includeWasm = false; +#endif +#if DEBUG + // While debugging, boot from the framework-served blazor.web.js instead of the ES2019-transpiled + // bit.blazor.web.es2019.js variant, which is only needed to support legacy (non-ES2019+) browsers. + var blazorWebScript = "_framework/blazor.web.js"; +#else + var blazorWebScript = "_framework/bit.blazor.web.es2019.js"; +#endif var noPrerender = HttpContext.Request.Query["no-prerender"].Count > 0; - var renderMode = noPrerender ? AppRenderMode.NoPrerenderBlazorWebAssembly : AppRenderMode.Current; + // Without the WASM client in the build, WebAssembly render modes can't boot, so fall back to Blazor Server + // even where AppRenderMode.Current would pick WebAssembly (e.g. Release with IncludeWasm=false). + var renderMode = noPrerender + ? (includeWasm ? AppRenderMode.NoPrerenderBlazorWebAssembly : AppRenderMode.NoPrerenderBlazorServer) + : (includeWasm ? AppRenderMode.Current : AppRenderMode.BlazorServer); } @@ -71,9 +87,13 @@ - - - + @if (includeWasm) + { + @* These files live in the Client.Web project's wwwroot, so they only exist when the WASM client is part of the build. *@ + + + } + @@ -95,10 +115,19 @@ @if (HttpContext.Request.IsLightHouseRequest() is false) { - - - - + @if (includeWasm) + { + + + + + } + else + { + @* No WASM client in this build (Debug renders in Blazor Server mode), so boot blazor directly without Bswup/service-worker. + Uses the framework-served blazor.web.js (always available) rather than the ES2019 variant, which only ships in the WASM build. *@ + + } diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs index de2431e089..79f037c397 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Extensions/IServiceCollectionExtensions.cs @@ -23,9 +23,12 @@ public static void AddBlazor(this IServiceCollection services, IConfiguration co }; }); - services.AddRazorComponents() - .AddInteractiveServerComponents() - .AddInteractiveWebAssemblyComponents(); + var razorComponentsBuilder = services.AddRazorComponents() + .AddInteractiveServerComponents(); + +#if INCLUDE_WASM + razorComponentsBuilder.AddInteractiveWebAssemblyComponents(); +#endif services.AddClientWebServices(); } diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs index 6e567f2935..a9e82f87ee 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Program.cs @@ -21,4 +21,10 @@ Bit.BlazorUI.Demo.Server.Startup.Middlewares.Use(app, builder.Environment, builder.Configuration); -app.Run(); +// Start the host first so startup failures propagate immediately, then await the +// SCSS watcher alongside shutdown (the watcher ties its own lifetime to app shutdown). +await app.StartAsync(); + +await Task.WhenAll( + app.WaitForShutdownAsync(), + Bit.BlazorUI.Demo.Server.Services.ScssCompilerService.WatchScssFiles(app) /* Development-only, no-op otherwise */); diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json index a92c102458..6bc92281cc 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Properties/launchSettings.json @@ -10,17 +10,6 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } - }, - // This configuration allows debugging the Blazor Web Assembly - "Bit.BlazorUI.Demo.Server-BlazorWebAssembly": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "http://localhost:5000;https://localhost:5001", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } } } } diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs new file mode 100644 index 0000000000..e06de5db37 --- /dev/null +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Services/ScssCompilerService.cs @@ -0,0 +1,150 @@ +using System.Diagnostics; + +namespace Bit.BlazorUI.Demo.Server.Services; + +/// +/// Compiles SCSS files into CSS in real-time during development, no extensions required. +/// Combined with the Watch items of the client/library csproj files, this lets dotnet watch +/// hot-apply style changes to the browser without a rebuild. +/// (Mirrors the ScssCompilerService of the bit Boilerplate template.) +/// +public static class ScssCompilerService +{ + internal static async Task WatchScssFiles(WebApplication app) + { + if (app.Environment.IsDevelopment() is false) + return; + + // A static type can't be an ILogger category, so create the logger by name via the factory. + var logger = app.Services.GetRequiredService().CreateLogger(nameof(ScssCompilerService)); + + var clientCorePath = Path.GetFullPath(Path.Combine(app.Environment.ContentRootPath, "../Client/Bit.BlazorUI.Demo.Client.Core")); + + // The npm-installed dart-sass shim: sass.cmd on Windows, the sass shell script elsewhere. + var toolPath = Path.Combine(clientCorePath, OperatingSystem.IsWindows() ? "node_modules/.bin/sass.cmd" : "node_modules/.bin/sass"); + + if (File.Exists(toolPath) is false) + { + logger.LogWarning("{SassTool} not found. Run a build of Bit.BlazorUI.Demo.Client.Core once (npm install) to enable real-time scss compilation.", toolPath); + return; + } + + // The sass process operates from the Client.Core directory. Folder:Folder pairs compile the + // isolated .razor.scss files in place; file:file pairs compile the global style bundles. + // The BlazorUI library styles are included as well, so editing a component's scss + // (e.g. BitButton.scss) instantly refreshes _content/Bit.BlazorUI/styles/*.css. + var sassPathsToWatch = new List + { + "Pages:Pages", "Components:Components", "Shared:Shared", + "Styles/app.scss:wwwroot/styles/app.css", + "../../../Bit.BlazorUI/Styles/bit.blazorui.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.css", + "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent.css", + "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent-dark.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent-dark.css", + "../../../Bit.BlazorUI/Styles/Fluent/bit.blazorui.fluent-light.scss:../../../Bit.BlazorUI/wwwroot/styles/bit.blazorui.fluent-light.css", + "../../../Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss:../../../Bit.BlazorUI.Extras/wwwroot/styles/bit.blazorui.extras.css", + "../../../Bit.BlazorUI.Icons/Styles/bit.blazorui.icons.scss:../../../Bit.BlazorUI.Icons/wwwroot/styles/bit.blazorui.icons.css", + "../../../Bit.BlazorUI.Assets/Styles/bit.blazorui.assets.scss:../../../Bit.BlazorUI.Assets/wwwroot/styles/bit.blazorui.assets.css", + }; + + // dart-sass --watch only watches files that live under a watched root: the directory of each + // compiled entry point plus every --load-path directory. The library bundle entry points sit in + // each project's Styles/ folder, but their component partials are imported from a sibling + // Components/ tree (e.g. bit.blazorui.scss -> ... -> Styles/components.scss -> ../Components/Buttons/ + // ActionButton/BitActionButton.scss). Those partials are outside every watched root, so editing one + // would NOT retrigger a compile and the css would go stale on hot reload. Adding each Components/ + // folder as a load-path brings it under a watched root. Do not remove these: without them, editing a + // component's scss (BitButton.scss, etc.) silently stops hot-reloading its styles. + var loadPaths = new List + { + "--load-path=.", + "--load-path=../../../Bit.BlazorUI/Components", + "--load-path=../../../Bit.BlazorUI.Extras/Components", + }; + + // --no-source-map is required for style hot reload to work. dart-sass emits a *.css.map next to + // every *.css; dotnet watch watches those too and pushes each change to the browser. The injected + // aspnetcore-browser-refresh.js only does a live, in-place stylesheet swap for paths ending in + // ".css" - for any other static file (including ".css.map") it falls back to a full location.reload(). + // With source maps on, every scss edit therefore fires a burst of full-page reloads that race with + // (and clobber) the clean css swaps, so the page never reliably shows the change. Dropping the maps + // leaves only ".css" updates, which hot-swap cleanly without reloading the page. + var command = $"{string.Join(" ", sassPathsToWatch)} {string.Join(" ", loadPaths)} --style compressed --no-source-map --silence-deprecation=import --update --watch --color"; + + // Scss watching is best-effort development tooling: any failure below must not fault this task, + // which would otherwise surface as an unobserved error in Program.cs's Task.WhenAll at shutdown. + Process? watchScssFilesProcess = null; + try + { + watchScssFilesProcess = new Process + { + StartInfo = new ProcessStartInfo + { + WorkingDirectory = clientCorePath, + FileName = toolPath, + Arguments = command, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + + // Pass the sass output as a logging argument, not as the message template: scss snippets in + // sass's error output contain braces that ILogger would parse as format placeholders. + watchScssFilesProcess.OutputDataReceived += (_, e) => { if (string.IsNullOrEmpty(e.Data) is false) logger.LogInformation("{SassOutput}", e.Data); }; + watchScssFilesProcess.ErrorDataReceived += (_, e) => { if (string.IsNullOrEmpty(e.Data) is false) logger.LogError("{SassError}", e.Data); }; + + logger.LogInformation("Running {toolPath} for {ProjectDirectory}", toolPath, clientCorePath); + if (watchScssFilesProcess.Start() is false) + { + logger.LogError("Failed to start {toolPath} for {ProjectDirectory}", toolPath, clientCorePath); + return; + } + + watchScssFilesProcess.BeginOutputReadLine(); + watchScssFilesProcess.BeginErrorReadLine(); + + // dart-sass --watch runs until killed, so tie its lifetime to the server: park until the + // host begins shutting down (dotnet watch restart, Ctrl+C), then the finally kills the whole + // process tree so no orphaned sass watcher survives - Program.cs awaits this task, so the + // cleanup always completes before the process exits. Waiting on ApplicationStopping (instead + // of app.WaitForShutdownAsync, which itself calls host.StopAsync) keeps Program.cs's + // WaitForShutdownAsync as the single code path that drives host shutdown. + try + { + await Task.Delay(Timeout.Infinite, app.Lifetime.ApplicationStopping); + } + catch (OperationCanceledException) + { + // The normal shutdown signal, not a failure. + } + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to watch scss files with {toolPath}", toolPath); + } + finally + { + KillSassProcess(watchScssFilesProcess, logger); + watchScssFilesProcess?.Dispose(); + } + } + + private static void KillSassProcess(Process? process, ILogger logger) + { + try + { + if (process is not null && process.HasExited is false) + { + process.Kill(entireProcessTree: true); + } + } + catch (InvalidOperationException) + { + // The process never started or is already disposed - nothing to terminate. + } + catch (Exception ex) + { + logger.LogWarning(ex, "Failed to terminate the scss watch process."); + } + } +} diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs index 8f2d45d65a..8a5507a76b 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Startup/Middlewares.cs @@ -32,7 +32,9 @@ public static void Use(WebApplication app, IWebHostEnvironment env, IConfigurati if (env.IsDevelopment()) { +#if INCLUDE_WASM app.UseWebAssemblyDebugging(); +#endif } else { @@ -107,7 +109,9 @@ public static void Use(WebApplication app, IWebHostEnvironment env, IConfigurati // Handle the rest of requests with blazor app.MapRazorComponents() .AddInteractiveServerRenderMode() +#if INCLUDE_WASM .AddInteractiveWebAssemblyRenderMode() +#endif .AddAdditionalAssemblies(AssemblyLoadContext.Default.Assemblies.Where(asm => asm.GetName().Name?.Contains("Bit.BlazorUI.Demo") is true).Except([Assembly.GetExecutingAssembly()]).ToArray()); } diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj index aaa56e0924..81c1d91d22 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj @@ -39,7 +39,14 @@ - + + + @@ -90,7 +97,7 @@ - + diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs index 8f6ad26ba7..b85305a211 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Services/AppRenderMode.cs @@ -9,10 +9,11 @@ public static class AppRenderMode // .NET 10 resolves the earlier prerendering issues, so this is enabled to serve fully-formed HTML. public static readonly bool PrerenderEnabled = true; - private static IComponentRenderMode Auto => new InteractiveAutoRenderMode(PrerenderEnabled); - private static IComponentRenderMode BlazorWebAssembly => new InteractiveWebAssemblyRenderMode(PrerenderEnabled); - private static IComponentRenderMode BlazorServer => new InteractiveServerRenderMode(PrerenderEnabled); - public static IComponentRenderMode NoPrerenderBlazorWebAssembly => new InteractiveWebAssemblyRenderMode(prerender: false); + public static IComponentRenderMode Auto { get; } = new InteractiveAutoRenderMode(PrerenderEnabled); + public static IComponentRenderMode BlazorWebAssembly { get; } = new InteractiveWebAssemblyRenderMode(PrerenderEnabled); + public static IComponentRenderMode BlazorServer { get; } = new InteractiveServerRenderMode(PrerenderEnabled); + public static IComponentRenderMode NoPrerenderBlazorWebAssembly { get; } = new InteractiveWebAssemblyRenderMode(prerender: false); + public static IComponentRenderMode NoPrerenderBlazorServer { get; } = new InteractiveServerRenderMode(prerender: false); public static IComponentRenderMode Current => BuildConfiguration.IsDebug() ? BlazorServer /*For better development experience*/ diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj new file mode 100644 index 0000000000..6c3e038796 --- /dev/null +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Bit.BlazorUI.Demo.Client.Web.Shared.csproj @@ -0,0 +1,39 @@ + + + + + + net10.0 + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor similarity index 94% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor index 1b46bed028..ae9127dbae 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Components/AppBswupProgressBar.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Components/AppBswupProgressBar.razor @@ -63,8 +63,8 @@
- -
+ +
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Extensions/IServiceCollectionExtensions.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Extensions/ClientWebServiceCollectionExtensions.cs similarity index 74% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Extensions/IServiceCollectionExtensions.cs rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Extensions/ClientWebServiceCollectionExtensions.cs index fe358052fc..7244737f1d 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Extensions/IServiceCollectionExtensions.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Extensions/ClientWebServiceCollectionExtensions.cs @@ -1,12 +1,12 @@ -using Bit.BlazorUI.Demo.Client.Web.Services; +using Bit.BlazorUI.Demo.Client.Web.Shared.Services; namespace Microsoft.Extensions.DependencyInjection; -public static class IServiceCollectionExtensions +public static class ClientWebServiceCollectionExtensions { public static IServiceCollection AddClientWebServices(this IServiceCollection services) { - // Services being registered here can get injected in web (blazor web assembly & blazor server) + // Services being registered here can get injected in web (blazor web assembly & blazor server). services.AddTransient(); services.AddTransient(); diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebDeviceCoordinator.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebDeviceCoordinator.cs similarity index 51% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebDeviceCoordinator.cs rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebDeviceCoordinator.cs index ca9dae81f4..3e4f027a1a 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebDeviceCoordinator.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebDeviceCoordinator.cs @@ -1,4 +1,4 @@ -namespace Bit.BlazorUI.Demo.Client.Web.Services; +namespace Bit.BlazorUI.Demo.Client.Web.Shared.Services; public class WebDeviceCoordinator : IBitDeviceCoordinator { diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebExceptionHandler.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebExceptionHandler.cs similarity index 84% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebExceptionHandler.cs rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebExceptionHandler.cs index 3d9becc16b..6ae6860d9e 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Services/WebExceptionHandler.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web.Shared/Services/WebExceptionHandler.cs @@ -1,4 +1,4 @@ -namespace Bit.BlazorUI.Demo.Client.Web.Services; +namespace Bit.BlazorUI.Demo.Client.Web.Shared.Services; public partial class WebExceptionHandler : ExceptionHandlerBase { diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Bit.BlazorUI.Demo.Client.Web.csproj b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Bit.BlazorUI.Demo.Client.Web.csproj index ce6030f981..7d3caa1f7e 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Bit.BlazorUI.Demo.Client.Web.csproj +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Web/Bit.BlazorUI.Demo.Client.Web.csproj @@ -28,12 +28,6 @@ - - - - - - all @@ -47,6 +41,7 @@ + diff --git a/src/BlazorUI/Demo/README.md b/src/BlazorUI/Demo/README.md index c711f35408..c5293fbf2c 100644 --- a/src/BlazorUI/Demo/README.md +++ b/src/BlazorUI/Demo/README.md @@ -1,3 +1,11 @@ # Bit.BlazorUI.Demo -https://blazorui.bitplatform.dev/ \ No newline at end of file +https://blazorui.bitplatform.dev/ + +## Debugging Blazor Server vs. WebAssembly + +Debug builds render in Blazor Server mode; the WASM client is excluded by default +(see `IncludeWasm` in the csproj). To run/debug the Blazor WebAssembly client, +build with the WASM client included, e.g.: + + dotnet run --project Bit.BlazorUI.Demo.Server -p:IncludeWasm=true \ No newline at end of file