@lynx-js/web-elements 0.11.3 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export declare const MarkdownIt: any;
2
+ export declare const createDOMPurify: any;
@@ -0,0 +1,11 @@
1
+ /*
2
+ // Copyright 2024 The Lynx Authors. All rights reserved.
3
+ // Licensed under the Apache License Version 2.0 that can be found in the
4
+ // LICENSE file in the root directory of this source tree.
5
+ */
6
+ // Keep runtime interop consistent with dynamic import usage in XMarkdownAttributes.
7
+ import * as mdModule from 'markdown-it';
8
+ import * as dpModule from 'dompurify';
9
+ export const MarkdownIt = (mdModule.default ?? mdModule);
10
+ export const createDOMPurify = (dpModule.default ?? dpModule);
11
+ //# sourceMappingURL=XMarkdownDeps.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @module elements/XMarkdown
3
+ *
4
+ * `x-markdown` renders markdown content with minimal styling.
5
+ * It supports the `content` and `markdown-style` attributes.
6
+ */
7
+ export { XMarkdown } from './XMarkdown.js';
@@ -0,0 +1,11 @@
1
+ // Copyright 2024 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ /**
5
+ * @module elements/XMarkdown
6
+ *
7
+ * `x-markdown` renders markdown content with minimal styling.
8
+ * It supports the `content` and `markdown-style` attributes.
9
+ */
10
+ export { XMarkdown } from './XMarkdown.js';
11
+ //# sourceMappingURL=index.js.map
@@ -21,7 +21,7 @@ let InlineTruncation = (() => {
21
21
  }
22
22
  static XEnableCustomTruncation = 'x-text-custom-overflow';
23
23
  connectedCallback() {
24
- if (!CSS.supports('selector(:has(inline-truncation))')) {
24
+ if (!CSS.supports('selector(:has(>inline-truncation))')) {
25
25
  if (this.parentElement?.tagName === 'X-TEXT'
26
26
  && !this.matches('inline-truncation ~ inline-truncation')) {
27
27
  this.parentElement.setAttribute(InlineTruncation.XEnableCustomTruncation, '');
@@ -45,16 +45,10 @@ let XTextTruncation = (() => {
45
45
  return !this.#hasInlineTruncation && !this.#tailColorConvert;
46
46
  }
47
47
  get #hasInlineTruncation() {
48
- if (CSS.supports('selector(:has(inline-truncation))')) {
49
- return this.#dom.matches(':has(inline-truncation)');
50
- }
51
- else {
52
- const candidateElement = this.#dom.querySelector('inline-truncation');
53
- if (candidateElement?.parentElement === this.#dom) {
54
- return true;
55
- }
56
- }
57
- return false;
48
+ return !!this.#findValidInlineTruncation();
49
+ }
50
+ #findValidInlineTruncation() {
51
+ return this.#dom.querySelector(':scope > inline-truncation');
58
52
  }
59
53
  get #doExpensiveLineLayoutCalculation() {
60
54
  return (!isNaN(this.#maxLine)
@@ -139,7 +133,7 @@ let XTextTruncation = (() => {
139
133
  const currentLineText = end - start;
140
134
  if (this.#hasInlineTruncation) {
141
135
  this.#dom.setAttribute(XTextTruncation.showInlineTruncation, '');
142
- const inlineTruncation = this.#dom.querySelector('inline-truncation');
136
+ const inlineTruncation = this.#findValidInlineTruncation();
143
137
  const inlineTruncationBoundingRect = inlineTruncation
144
138
  .getBoundingClientRect();
145
139
  const parentWidth = parentBondingRect.width;
@@ -5,6 +5,7 @@ export declare class XViewpagerNgEvents implements InstanceType<AttributeReactiv
5
5
  static observedAttributes: never[];
6
6
  constructor(dom: XViewpagerNg);
7
7
  _enableChangeEvent(status: boolean): void;
8
+ _enableWillChangeEvent(status: boolean): void;
8
9
  _enableOffsetChangeEvent(status: boolean): void;
9
10
  connectedCallback(): void;
10
11
  dispose(): void;
@@ -11,13 +11,16 @@ import { registerEventEnableStatusChangeHandler } from '../../element-reactive/i
11
11
  let XViewpagerNgEvents = (() => {
12
12
  let _instanceExtraInitializers = [];
13
13
  let __enableChangeEvent_decorators;
14
+ let __enableWillChangeEvent_decorators;
14
15
  let __enableOffsetChangeEvent_decorators;
15
16
  return class XViewpagerNgEvents {
16
17
  static {
17
18
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
18
19
  __enableChangeEvent_decorators = [registerEventEnableStatusChangeHandler('change')];
20
+ __enableWillChangeEvent_decorators = [registerEventEnableStatusChangeHandler('willchange')];
19
21
  __enableOffsetChangeEvent_decorators = [registerEventEnableStatusChangeHandler('offsetchange')];
20
22
  __esDecorate(this, null, __enableChangeEvent_decorators, { kind: "method", name: "_enableChangeEvent", static: false, private: false, access: { has: obj => "_enableChangeEvent" in obj, get: obj => obj._enableChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
23
+ __esDecorate(this, null, __enableWillChangeEvent_decorators, { kind: "method", name: "_enableWillChangeEvent", static: false, private: false, access: { has: obj => "_enableWillChangeEvent" in obj, get: obj => obj._enableWillChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
21
24
  __esDecorate(this, null, __enableOffsetChangeEvent_decorators, { kind: "method", name: "_enableOffsetChangeEvent", static: false, private: false, access: { has: obj => "_enableOffsetChangeEvent" in obj, get: obj => obj._enableOffsetChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
22
25
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
23
26
  }
@@ -70,12 +73,29 @@ let XViewpagerNgEvents = (() => {
70
73
  };
71
74
  #touchEndHandler = () => {
72
75
  this.#isDragging = false;
76
+ if (this.#enableWillChange) {
77
+ const scrollContainer = this.#getScrollContainer();
78
+ const oneItemWidth = this.#dom.clientWidth;
79
+ if (oneItemWidth > 0) {
80
+ const scrollLeft = scrollContainer.scrollLeft;
81
+ let targetIndex = Math.round(scrollLeft / oneItemWidth);
82
+ targetIndex = Math.max(0, Math.min(targetIndex, this.#dom.children.length - 1));
83
+ this.#dom.dispatchEvent(new CustomEvent('willchange', {
84
+ ...commonComponentEventSetting,
85
+ detail: { index: targetIndex },
86
+ }));
87
+ }
88
+ }
73
89
  };
74
90
  #enableChange = false;
75
91
  _enableChangeEvent(status) {
76
92
  this.#enableChange = status;
77
93
  this.#enableScrollEventListener();
78
94
  }
95
+ #enableWillChange = false;
96
+ _enableWillChangeEvent(status) {
97
+ this.#enableWillChange = status;
98
+ }
79
99
  #enableOffsetChange = false;
80
100
  _enableOffsetChangeEvent(status) {
81
101
  this.#enableOffsetChange = status;
@@ -16,3 +16,4 @@ import './XViewpagerNg/index.js';
16
16
  import './XList/index.js';
17
17
  import './XList/ListItem.js';
18
18
  import './XWebView/index.js';
19
+ import './XMarkdown/index.js';
@@ -16,4 +16,5 @@ import './XViewpagerNg/index.js';
16
16
  import './XList/index.js';
17
17
  import './XList/ListItem.js';
18
18
  import './XWebView/index.js';
19
+ import './XMarkdown/index.js';
19
20
  //# sourceMappingURL=all.js.map
@@ -7,11 +7,12 @@ export declare const templateFilterImage: (attributes: {
7
7
  src?: string;
8
8
  }) => string;
9
9
  export declare const templateXInput = "<style>\n #input:focus {\n outline: none;\n }\n #form {\n display: none;\n }\n</style>\n<form id=\"form\" part=\"form\" method=\"dialog\">\n <input\n id=\"input\"\n part=\"input\"\n step=\"any\"\n type=\"text\"\n inputmode=\"text\"\n spell-check=\"true\"\n />\n</form>";
10
- export declare const templateXList = "<style>\n .placeholder-dom {\n display: none;\n flex: 0 0 0;\n align-self: stretch;\n min-height: 0;\n min-width: 0;\n }\n .observer-container {\n flex-direction: inherit;\n overflow: visible;\n }\n .observer {\n display: flex;\n }\n</style>\n<div id=\"content\" part=\"content\">\n <div\n class=\"observer-container placeholder-dom\"\n part=\"upper-threshold-observer\"\n >\n <div\n class=\"observer placeholder-dom\"\n id=\"upper-threshold-observer\"\n ></div>\n </div>\n <slot part=\"slot\"></slot>\n <div\n class=\"observer-container placeholder-dom\"\n part=\"lower-threshold-observer\"\n >\n <div\n class=\"observer placeholder-dom\"\n id=\"lower-threshold-observer\"\n ></div>\n </div>\n</div>";
10
+ export declare const templateXList = "<style>\n .placeholder-dom {\n display: none;\n flex: 0 0 0;\n align-self: stretch;\n min-height: 0;\n min-width: 0;\n }\n .observer-container {\n flex-direction: inherit;\n overflow: visible;\n }\n .observer {\n display: flex;\n }\n</style>\n<div id=\"content\" part=\"content\">\n <div\n class=\"observer-container placeholder-dom\"\n part=\"upper-threshold-observer\"\n >\n <div\n class=\"observer placeholder-dom\"\n id=\"upper-threshold-observer\"\n part=\"upper-threshold-sentinel\"\n ></div>\n </div>\n <slot part=\"slot\"></slot>\n <div\n class=\"observer-container placeholder-dom\"\n part=\"lower-threshold-observer\"\n >\n <div\n class=\"observer placeholder-dom\"\n id=\"lower-threshold-observer\"\n part=\"lower-threshold-sentinel\"\n ></div>\n </div>\n</div>";
11
11
  export declare const templateXOverlayNg = "<style>\n #dialog[open] {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: fixed;\n overscroll-behavior: contain;\n scrollbar-width: none;\n }\n #dialog[open]::-webkit-scrollbar {\n display: none;\n }\n #dialog::backdrop {\n background-color: transparent;\n }\n .overlay-inner {\n position: sticky;\n top: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n }\n .overlay-inner > * {\n pointer-events: auto;\n }\n .overlay-placeholder {\n width: 100%;\n height: 1px;\n }\n</style>\n<dialog id=\"dialog\" part=\"dialog\">\n <div class=\"overlay-inner\">\n <slot></slot>\n </div>\n <div class=\"overlay-placeholder\"></div>\n</dialog>";
12
12
  export declare const templateXRefreshView = "<style>\n .bounce-container {\n overflow: scroll;\n overscroll-behavior: contain;\n scroll-snap-type: y mandatory;\n scroll-behavior: smooth;\n scrollbar-width: none;\n }\n .overflow-placeholder {\n min-height: 30%;\n min-width: 100%;\n flex-shrink: 0;\n scroll-snap-align: none;\n }\n .not-shrink {\n height: 100%;\n width: 100%;\n min-height: 100%;\n min-width: 100%;\n flex-shrink: 0;\n }\n .vertical {\n display: flex;\n flex-direction: column;\n }\n #content {\n scroll-snap-align: center;\n }\n</style>\n<div id=\"container\" part=\"container\" class=\"bounce-container not-shrink vertical\">\n <div\n id=\"placeholder-top\"\n class=\"overflow-placeholder bounce-item\"\n part=\"placeholder-top\"\n ></div>\n <slot name=\"header\"></slot>\n <div id=\"content\" part=\"content\" class=\"not-shrink vertical\">\n <slot part=\"slot\"></slot>\n </div>\n <slot name=\"footer\"></slot>\n <div\n id=\"placeholder-bot\"\n class=\"overflow-placeholder bounce-item\"\n part=\"placeholder-bot\"\n ></div>\n</div>";
13
13
  export declare const templateXSwiper = "<style>\n #bounce-padding {\n display: none;\n flex: 0 0 0;\n align-self: stretch;\n scroll-snap-align: none;\n flex-basis: 100%;\n }\n #content {\n position: relative;\n display: flex;\n flex: 0 0 100%;\n flex-direction: inherit;\n flex-wrap: inherit;\n align-self: stretch;\n justify-content: inherit;\n align-items: inherit;\n overflow: inherit;\n scrollbar-width: none;\n scroll-snap-align: start;\n scroll-snap-type: inherit;\n }\n div::-webkit-scrollbar {\n display: none;\n }\n #indicator-container {\n display: none;\n }\n #indicator-container > div {\n animation-name: indicator-dot;\n animation-duration: 100ms;\n }\n @keyframes indicator-dot {\n 30%,\n 70% {\n background-color: var(--indicator-color);\n }\n 31%,\n 69% {\n background-color: var(--indicator-active-color);\n }\n }\n</style>\n<style id=\"indicator-style\"></style>\n<div id=\"bounce-padding\" part=\"bounce-padding\"></div>\n<div id=\"indicator-container\" part=\"indicator-container\"></div>\n<div id=\"content\" part=\"content\">\n <slot part=\"slot-start\" name=\"circular-start\" id=\"circular-start\"></slot>\n <slot part=\"slot\"></slot>\n <slot part=\"slot-end\" name=\"circular-end\" id=\"circular-end\"></slot>\n</div>";
14
14
  export declare const templateXText = "<div id=\"inner-box\" part=\"inner-box\"><slot part=\"slot\"></slot><slot name=\"inline-truncation\"></slot></div>";
15
+ export declare const templateXMarkdown = "<style>\n :host {\n display: block;\n }\n .markdown-body {\n display: block;\n line-height: 1.4;\n color: inherit;\n word-break: break-word;\n position: relative;\n }\n .markdown-body p {\n margin: 0 0 0.75em 0;\n }\n .markdown-body h1,\n .markdown-body h2,\n .markdown-body h3,\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 {\n margin: 0.8em 0 0.4em 0;\n }\n .markdown-body ul,\n .markdown-body ol {\n margin: 0 0 0.75em 1.5em;\n }\n .markdown-body pre {\n margin: 0 0 0.75em 0;\n padding: 8px 12px;\n border-radius: 6px;\n background: #f6f8fa;\n overflow: auto;\n }\n .markdown-body code {\n font-family: ui-monospace, SFMono-Regular, SFMono, Menlo, Consolas,\n \"Liberation Mono\", monospace;\n }\n .markdown-body pre code {\n display: block;\n padding: 0;\n }\n .markdown-body img {\n max-width: 100%;\n height: auto;\n display: block;\n }\n .markdown-body .md-inline-view {\n display: inline-block;\n vertical-align: baseline;\n }\n .markdown-body .md-truncation {\n position: absolute;\n right: 0;\n bottom: 0;\n background-color: inherit;\n }\n .markdown-body .md-image-figure {\n margin: 0 0 0.75em 0;\n }\n .markdown-body .md-image-caption {\n margin-top: 4px;\n color: #666;\n font-size: 0.875em;\n }\n .markdown-body .md-text-mask-effect {\n position: relative;\n display: inline-block;\n }\n .markdown-body .md-text-mask-effect-overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n user-select: none;\n white-space: pre;\n color: transparent;\n -webkit-background-clip: text;\n background-clip: text;\n }\n .markdown-body a {\n color: #0366d6;\n text-decoration: underline;\n }\n</style>\n<style id=\"markdown-style\"></style>\n<div id=\"markdown-root\" part=\"root\" class=\"markdown-body\"></div>";
15
16
  export declare const templateInlineImage: (attributes: {
16
17
  src?: string;
17
18
  }) => string;
@@ -142,6 +142,7 @@ export const templateXList = `<style>
142
142
  <div
143
143
  class="observer placeholder-dom"
144
144
  id="upper-threshold-observer"
145
+ part="upper-threshold-sentinel"
145
146
  ></div>
146
147
  </div>
147
148
  <slot part="slot"></slot>
@@ -152,6 +153,7 @@ export const templateXList = `<style>
152
153
  <div
153
154
  class="observer placeholder-dom"
154
155
  id="lower-threshold-observer"
156
+ part="lower-threshold-sentinel"
155
157
  ></div>
156
158
  </div>
157
159
  </div>`;
@@ -294,6 +296,91 @@ export const templateXSwiper = `<style>
294
296
  <slot part="slot-end" name="circular-end" id="circular-end"></slot>
295
297
  </div>`;
296
298
  export const templateXText = `<div id="inner-box" part="inner-box"><slot part="slot"></slot><slot name="inline-truncation"></slot></div>`;
299
+ export const templateXMarkdown = `<style>
300
+ :host {
301
+ display: block;
302
+ }
303
+ .markdown-body {
304
+ display: block;
305
+ line-height: 1.4;
306
+ color: inherit;
307
+ word-break: break-word;
308
+ position: relative;
309
+ }
310
+ .markdown-body p {
311
+ margin: 0 0 0.75em 0;
312
+ }
313
+ .markdown-body h1,
314
+ .markdown-body h2,
315
+ .markdown-body h3,
316
+ .markdown-body h4,
317
+ .markdown-body h5,
318
+ .markdown-body h6 {
319
+ margin: 0.8em 0 0.4em 0;
320
+ }
321
+ .markdown-body ul,
322
+ .markdown-body ol {
323
+ margin: 0 0 0.75em 1.5em;
324
+ }
325
+ .markdown-body pre {
326
+ margin: 0 0 0.75em 0;
327
+ padding: 8px 12px;
328
+ border-radius: 6px;
329
+ background: #f6f8fa;
330
+ overflow: auto;
331
+ }
332
+ .markdown-body code {
333
+ font-family: ui-monospace, SFMono-Regular, SFMono, Menlo, Consolas,
334
+ "Liberation Mono", monospace;
335
+ }
336
+ .markdown-body pre code {
337
+ display: block;
338
+ padding: 0;
339
+ }
340
+ .markdown-body img {
341
+ max-width: 100%;
342
+ height: auto;
343
+ display: block;
344
+ }
345
+ .markdown-body .md-inline-view {
346
+ display: inline-block;
347
+ vertical-align: baseline;
348
+ }
349
+ .markdown-body .md-truncation {
350
+ position: absolute;
351
+ right: 0;
352
+ bottom: 0;
353
+ background-color: inherit;
354
+ }
355
+ .markdown-body .md-image-figure {
356
+ margin: 0 0 0.75em 0;
357
+ }
358
+ .markdown-body .md-image-caption {
359
+ margin-top: 4px;
360
+ color: #666;
361
+ font-size: 0.875em;
362
+ }
363
+ .markdown-body .md-text-mask-effect {
364
+ position: relative;
365
+ display: inline-block;
366
+ }
367
+ .markdown-body .md-text-mask-effect-overlay {
368
+ position: absolute;
369
+ inset: 0;
370
+ pointer-events: none;
371
+ user-select: none;
372
+ white-space: pre;
373
+ color: transparent;
374
+ -webkit-background-clip: text;
375
+ background-clip: text;
376
+ }
377
+ .markdown-body a {
378
+ color: #0366d6;
379
+ text-decoration: underline;
380
+ }
381
+ </style>
382
+ <style id="markdown-style"></style>
383
+ <div id="markdown-root" part="root" class="markdown-body"></div>`;
297
384
  export const templateInlineImage = templateXImage;
298
385
  export const templateXTextarea = `<style>
299
386
  #textarea:focus,
package/index.css CHANGED
@@ -13,6 +13,7 @@
13
13
  @import url("./src/elements/XSvg/x-svg.css");
14
14
  @import url("./src/elements/XImage/x-image.css");
15
15
  @import url("./src/elements/XInput/x-input.css");
16
+ @import url("./src/elements/XMarkdown/x-markdown.css");
16
17
  @import url("./src/elements/XOverlayNg/x-overlay-ng.css");
17
18
  @import url("./src/elements/XRefreshView/x-refresh-view.css");
18
19
  @import url("./src/elements/XSwiper/x-swiper.css");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-elements",
3
- "version": "0.11.3",
3
+ "version": "0.12.1",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,6 +12,7 @@
12
12
  "type": "module",
13
13
  "exports": {
14
14
  ".": {
15
+ "@lynx-js/source-field": "./src/elements/index.ts",
15
16
  "types": "./dist/elements/index.d.ts",
16
17
  "default": "./dist/elements/index.js"
17
18
  },
@@ -58,6 +59,11 @@
58
59
  "types": "./dist/elements/XInput/index.d.ts",
59
60
  "default": "./dist/elements/XInput/index.js"
60
61
  },
62
+ "./XMarkdown": {
63
+ "@lynx-js/source-field": "./src/elements/XMarkdown/index.ts",
64
+ "types": "./dist/elements/XMarkdown/index.d.ts",
65
+ "default": "./dist/elements/XMarkdown/index.js"
66
+ },
61
67
  "./XOverlayNg": {
62
68
  "@lynx-js/source-field": "./src/elements/XOverlayNg/index.ts",
63
69
  "types": "./dist/elements/XOverlayNg/index.d.ts",
@@ -112,7 +118,8 @@
112
118
  "@lynx-js/source-field": "./src/elements/htmlTemplates.ts",
113
119
  "types": "./dist/elements/htmlTemplates.d.ts",
114
120
  "default": "./dist/elements/htmlTemplates.js"
115
- }
121
+ },
122
+ "./package.json": "./package.json"
116
123
  },
117
124
  "main": "dist/index.js",
118
125
  "typings": "dist/index.d.ts",
@@ -126,10 +133,15 @@
126
133
  "index.css",
127
134
  "**/*.css"
128
135
  ],
136
+ "dependencies": {
137
+ "dompurify": "^3.3.1",
138
+ "markdown-it": "^14.1.0"
139
+ },
129
140
  "devDependencies": {
130
141
  "@playwright/test": "^1.58.2",
131
- "@rsbuild/core": "1.7.3",
142
+ "@rsbuild/core": "1.7.5",
132
143
  "@rsbuild/plugin-source-build": "1.0.4",
144
+ "@types/markdown-it": "^14.1.1",
133
145
  "nyc": "^17.1.0",
134
146
  "tslib": "^2.8.1",
135
147
  "@lynx-js/playwright-fixtures": "0.0.0"
@@ -26,7 +26,7 @@
26
26
  */
27
27
  @supports not
28
28
  ((content-visibility: auto) and (transition-behavior: allow-discrete) and
29
- (width: 1rex)) {
29
+ (-webkit-box-reflect: above)) {
30
30
  * {
31
31
  --lynx-display: linear;
32
32
  --lynx-linear-weight-sum: 1;
@@ -47,6 +47,7 @@
47
47
  --flex-wrap: nowrap;
48
48
  --align-self: auto;
49
49
  }
50
+
50
51
  [lynx-computed-display="linear"] {
51
52
  flex-wrap: nowrap !important;
52
53
  flex-direction: column;
@@ -61,11 +62,9 @@
61
62
 
62
63
  [lynx-computed-display="flex"] > *,
63
64
  [lynx-computed-display="flex"] > lynx-wrapper > * {
64
- flex: var(
65
- --flex,
66
- var(--flex-grow) var(--flex-shrink) var(--flex-basis)
67
- );
65
+ flex: var(--flex, var(--flex-grow) var(--flex-shrink) var(--flex-basis));
68
66
  }
67
+
69
68
  [lynx-computed-display="linear"] > *,
70
69
  [lynx-computed-display="linear"] > lynx-wrapper > * {
71
70
  flex-shrink: 0 !important;
@@ -111,6 +110,7 @@
111
110
  > * {
112
111
  align-self: var(--align-self-column);
113
112
  }
113
+
114
114
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal"] > *,
115
115
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal-reverse"],
116
116
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal"]
@@ -157,6 +157,37 @@ x-list[x-enable-scrolltoloweredge-event]::part(lower-threshold-observer) {
157
157
  display: flex;
158
158
  }
159
159
 
160
+ x-list[x-enable-scrolltoupper-event]::part(upper-threshold-sentinel),
161
+ x-list[x-enable-scrolltoupperedge-event]::part(upper-threshold-sentinel),
162
+ x-list[x-enable-scrolltolower-event]::part(lower-threshold-sentinel),
163
+ x-list[x-enable-scrolltoloweredge-event]::part(lower-threshold-sentinel) {
164
+ flex: 0 0 1px;
165
+ }
166
+
167
+ x-list[x-enable-scrolltoupper-event]::part(upper-threshold-sentinel),
168
+ x-list[x-enable-scrolltoupperedge-event]::part(upper-threshold-sentinel) {
169
+ margin-bottom: -1px;
170
+ }
171
+
172
+ x-list[x-enable-scrolltolower-event]::part(lower-threshold-sentinel),
173
+ x-list[x-enable-scrolltoloweredge-event]::part(lower-threshold-sentinel) {
174
+ margin-top: -1px;
175
+ transform: translateY(1px);
176
+ }
177
+
178
+ x-list[scroll-orientation="horizontal"][x-enable-scrolltoupper-event]::part(upper-threshold-sentinel),
179
+ x-list[scroll-orientation="horizontal"][x-enable-scrolltoupperedge-event]::part(upper-threshold-sentinel) {
180
+ margin-bottom: 0;
181
+ margin-right: -1px;
182
+ }
183
+
184
+ x-list[scroll-orientation="horizontal"][x-enable-scrolltolower-event]::part(lower-threshold-sentinel),
185
+ x-list[scroll-orientation="horizontal"][x-enable-scrolltoloweredge-event]::part(lower-threshold-sentinel) {
186
+ margin-top: 0;
187
+ margin-left: -1px;
188
+ transform: translateX(1px);
189
+ }
190
+
160
191
  x-list::part(lower-threshold-observer) {
161
192
  flex-direction: column-reverse;
162
193
  }
@@ -0,0 +1,15 @@
1
+ /*
2
+ // Copyright 2024 The Lynx Authors. All rights reserved.
3
+ // Licensed under the Apache License Version 2.0 that can be found in the
4
+ // LICENSE file in the root directory of this source tree.
5
+ */
6
+ x-markdown {
7
+ display: flex;
8
+ flex-direction: column;
9
+ align-items: stretch;
10
+ color: inherit;
11
+ }
12
+
13
+ x-markdown::part(root) {
14
+ width: 100%;
15
+ }
@@ -12,7 +12,8 @@ x-text {
12
12
  color: initial;
13
13
  }
14
14
 
15
- x-text > x-text, x-text > lynx-wrapper > x-text {
15
+ x-text > x-text,
16
+ x-text > lynx-wrapper > x-text {
16
17
  color: inherit;
17
18
  }
18
19
 
@@ -33,11 +34,17 @@ x-text > x-text::part(inner-box),
33
34
  x-text > lynx-wrapper > x-text::part(inner-box) {
34
35
  display: contents !important;
35
36
  }
36
- x-text::part(inner-box), inline-text, x-text::part(slot) {
37
+
38
+ x-text::part(inner-box),
39
+ inline-text,
40
+ x-text::part(slot) {
37
41
  background-clip: inherit;
38
42
  -webkit-background-clip: inherit;
39
43
  }
40
- inline-text, inline-image, inline-truncation {
44
+
45
+ inline-text,
46
+ inline-image,
47
+ inline-truncation {
41
48
  display: none;
42
49
  }
43
50
 
@@ -73,15 +80,19 @@ inline-text > lynx-wrapper > inline-image,
73
80
  inline-text > lynx-wrapper > x-image {
74
81
  display: contents !important;
75
82
  }
76
- x-text > x-view, x-text > lynx-wrapper > x-view {
83
+
84
+ x-text > x-view,
85
+ x-text > lynx-wrapper > x-view {
77
86
  display: inline-flex !important;
78
87
  }
88
+
79
89
  x-text > x-view,
80
90
  x-text[x-show-inline-truncation] > inline-truncation,
81
91
  x-text > lynx-wrapper > x-view,
82
92
  x-text[x-show-inline-truncation] > lynx-wrapper > inline-truncation {
83
93
  display: inline-flex;
84
94
  }
95
+
85
96
  x-text > inline-truncation:first-child,
86
97
  x-text > lynx-wrapper > inline-truncation:first-child {
87
98
  max-width: 100%;
@@ -125,7 +136,10 @@ inline-truncation > lynx-wrapper > x-image::part(img) {
125
136
 
126
137
  /* attribute text-selection */
127
138
 
128
- x-text, inline-text, inline-image, inline-truncation {
139
+ x-text,
140
+ inline-text,
141
+ inline-image,
142
+ inline-truncation {
129
143
  -webkit-user-select: none;
130
144
  user-select: none;
131
145
  }
@@ -154,6 +168,7 @@ x-text[text-selection] > lynx-wrapper > inline-truncation {
154
168
  -webkit-user-select: auto;
155
169
  user-select: auto;
156
170
  }
171
+
157
172
  x-text[x-text-clipped] > [x-text-clipped]:not(inline-truncation),
158
173
  x-text[x-text-clipped]
159
174
  > lynx-wrapper
@@ -166,9 +181,9 @@ x-text[x-text-clipped]:not([tail-color-convert="false"])::part(inner-box)::after
166
181
  content: "...";
167
182
  }
168
183
 
169
- x-text[x-text-clipped]:has(inline-truncation)::part(inner-box):after,
184
+ x-text[x-text-clipped]:has(> inline-truncation)::part(inner-box):after,
170
185
  x-text[x-text-clipped][x-text-custom-overflow]::part(inner-box):after,
171
- x-text[x-text-clipped]:has(inline-truncation)::part(inner-box)::after,
186
+ x-text[x-text-clipped]:has(> inline-truncation)::part(inner-box)::after,
172
187
  x-text[x-text-clipped][x-text-custom-overflow]::part(inner-box)::after {
173
188
  content: "" !important;
174
189
  }
@@ -198,41 +213,45 @@ x-text[text-maxline="0"] {
198
213
  display: none;
199
214
  }
200
215
 
201
- @supports not selector(:has(inline-truncation)) {
216
+ @supports not selector(:has(> inline-truncation)) {
202
217
  x-text[text-maxline="1"]:not([tail-color-convert="false"]):not([x-text-custom-overflow])::part(inner-box) {
203
218
  white-space: nowrap;
204
219
  text-overflow: ellipsis;
205
220
  }
206
221
  }
207
222
 
208
- @supports selector(:has(inline-truncation)) {
223
+ @supports selector(:has(> inline-truncation)) {
209
224
  /* text-wrap chrome 114, firefox 121, safari 17.4*/
210
- x-text[text-maxline="1"]:not([tail-color-convert="false"], :has(inline-truncation))::part(inner-box) {
225
+ x-text[text-maxline="1"]:not([tail-color-convert="false"], :has(> inline-truncation))::part(inner-box) {
211
226
  text-wrap: nowrap;
212
227
  white-space: nowrap;
213
228
  text-overflow: ellipsis;
214
229
  }
215
230
  }
231
+
216
232
  x-text[text-maxline="1"] {
217
233
  /* This is the stretch size */
218
234
  /* https://developer.mozilla.org/en-US/docs/Web/CSS/max-width */
219
235
  max-width: -moz-available;
220
236
  max-width: -webkit-fill-available;
221
237
  }
238
+
222
239
  x-text[text-maxline="1"]:not([tail-color-convert="false"])::part(inner-box) {
223
240
  display: block;
224
241
  }
225
242
 
226
243
  x-text[text-maxline][x-text-custom-overflow]::part(inner-box),
227
- x-text[text-maxline]:has(inline-truncation)::part(inner-box),
244
+ x-text[text-maxline]:has(> inline-truncation)::part(inner-box),
228
245
  x-text[text-maxline][tail-color-convert="false"]::part(inner-box) {
229
246
  display: block !important;
230
247
  }
231
248
 
232
249
  raw-text {
233
- display: none; /* raw-text only works in x-text */
250
+ display: none;
251
+ /* raw-text only works in x-text */
234
252
  white-space-collapse: preserve-breaks;
235
253
  }
254
+
236
255
  x-text > raw-text,
237
256
  inline-text > raw-text,
238
257
  x-text > lynx-wrapper > raw-text,