diff --git a/app/assets/javascripts/components/annotations/annotation_marker.ts b/app/assets/javascripts/components/annotations/annotation_marker.ts index 8032b97f68..460f4e06f5 100644 --- a/app/assets/javascripts/components/annotations/annotation_marker.ts +++ b/app/assets/javascripts/components/annotations/annotation_marker.ts @@ -1,5 +1,5 @@ import { customElement, property } from "lit/decorators.js"; -import { html, LitElement, TemplateResult } from "lit"; +import { css, html, LitElement, TemplateResult, CSSResultGroup } from "lit"; import { Annotation, compareAnnotationOrders, @@ -19,37 +19,46 @@ import { StateController } from "state/state_system/StateController"; export class AnnotationMarker extends LitElement { @property({ type: Array }) annotations: Annotation[]; + @property({ type: Boolean, attribute: "full-width" }) + fullWidth = false; state = new StateController(this); + static get styles(): CSSResultGroup { + // order matters here, the last defined class determines the color if multiple apply + return css` + .info, .warning, .error, + .info-intense, .warning-intense, .error-intense { + background-position: left bottom; + background-repeat: repeat-x; + } + .info { background-image: var(--d-annotation-info-background) } + .warning { background-image: var(--d-annotation-warning-background) } + .error { background-image: var(--d-annotation-error-background) } + .info-intense { background-image: var(--d-annotation-info-background-intense) } + .warning-intense { background-image: var(--d-annotation-warning-background-intense) } + .error-intense { background-image: var(--d-annotation-error-background-intense) } + .annotation { background-color: var(--annotation-color) } + .question { background-color: var(--question-color) } + .annotation-intense { background-color: var(--annotation-intense-color) } + .question-intense { background-color: var(--question-intense-color) } + `; + } + + static getClass(annotation: Annotation): string { + return annotation.isHovered ? `${annotation.type}-intense` : annotation.type; + } + static colors = { - "error": "var(--error-color, red)", - "warning": "var(--warning-color, yellow)", - "info": "var(--info-color, blue)", + "error": "var(--d-annotation-error, red)", + "warning": "var(--d-annotation-warning, yellow)", + "info": "var(--d-annotation-info, blue)", "annotation": "var(--annotation-color, green)", "question": "var(--question-color, orange)", "annotation-intense": "var(--annotation-intense-color, green)", "question-intense": "var(--question-intense-color, orange)", }; - static getStyle(annotation: Annotation): string { - if (["error", "warning", "info"].includes(annotation.type)) { - // shorthand notation does not work in safari - return ` - text-decoration-line: underline; - text-decoration-color: ${AnnotationMarker.colors[annotation.type]}; - text-decoration-thickness: ${annotation.isHovered ? 2 : 1}px; - text-decoration-style: wavy; - text-decoration-skip-ink: none; - `; - } else { - const key = annotation.isHovered ? `${annotation.type}-intense` : annotation.type; - return ` - background: ${AnnotationMarker.colors[key]}; - `; - } - } - /** * Returns the annotations sorted in order of importance. * Hovered annotations are prioritized over non-hovered annotations. @@ -79,16 +88,11 @@ export class AnnotationMarker extends LitElement { `; } - get annotationStyles(): string { - return this.sortedAnnotations.reverse().map(a => AnnotationMarker.getStyle(a)).join(" "); + get annotationClasses(): string { + return this.annotations.map(a => AnnotationMarker.getClass(a)).join(" "); } render(): TemplateResult { - return html`${this.machineAnnotationMarkerSVG}`; + return html`${this.machineAnnotationMarkerSVG}`; } } diff --git a/app/assets/javascripts/components/annotations/line_of_code.ts b/app/assets/javascripts/components/annotations/line_of_code.ts index ceb4bdbb96..a3751eb12d 100644 --- a/app/assets/javascripts/components/annotations/line_of_code.ts +++ b/app/assets/javascripts/components/annotations/line_of_code.ts @@ -168,7 +168,7 @@ export class LineOfCode extends ShadowlessLitElement { return html`
${ this.fullLineAnnotations.length > 0 ? html` - +
${backgroundLayer}
` : html`
${backgroundLayer}
diff --git a/app/assets/stylesheets/base.css.scss b/app/assets/stylesheets/base.css.scss index a6a822661b..4bd3144e4f 100644 --- a/app/assets/stylesheets/base.css.scss +++ b/app/assets/stylesheets/base.css.scss @@ -2,10 +2,10 @@ @import "../../../node_modules/bootstrap/scss/functions"; // 2. Include any default variable overrides here +@import "mixins.css.scss"; @import "theme/m3-theme-light.css.scss"; @import "theme/m3-theme-dark.css.scss"; @import "bootstrap_variable_overrides.css.scss"; -@import "mixins.css.scss"; @import "theme/rouge.css.scss"; @import "theme/ace.css.scss"; diff --git a/app/assets/stylesheets/components/code_listing.css.scss b/app/assets/stylesheets/components/code_listing.css.scss index f7b3b27d00..aa63b57535 100644 --- a/app/assets/stylesheets/components/code_listing.css.scss +++ b/app/assets/stylesheets/components/code_listing.css.scss @@ -527,9 +527,6 @@ d-annotation-marker, d-selection-marker { - --info-color: var(--d-annotation-info); - --warning-color: var(--d-annotation-warning); - --error-color: var(--d-annotation-error); --question-color: var(--d-annotation-question-background); --annotation-color: var(--d-annotation-user-background); --question-intense-color: var(--d-annotation-question-background-intense); diff --git a/app/assets/stylesheets/mixins.css.scss b/app/assets/stylesheets/mixins.css.scss index dd58029260..c150a79812 100644 --- a/app/assets/stylesheets/mixins.css.scss +++ b/app/assets/stylesheets/mixins.css.scss @@ -1,3 +1,6 @@ +@use "sass:string"; +@use "sass:color"; + @mixin shadow-z0 { box-shadow: none; } @@ -27,3 +30,10 @@ 0 16px 24px 2px rgba(0, 0, 0, 0.098), 0 6px 30px 5px rgba(0, 0, 0, 0.084); } + +// sets the variable equal to the url of a wavy svg with the specified color and stroke-width +@mixin wavy-underline($variable, $color, $stroke-width) { + // this is a custom wavy svg that can be used as a background image + // the color is slightly hacked to get a proper url encode version of the color + #{$variable}: url('data:image/svg+xml,%3Cpath%20d%3D%22m0%202.5%20l2%20-1.5%20l1%200%20l2%201.5%20l1%200%22%20stroke%3D%22%23#{string.slice(color.ie-hex-str($color), 4)}%22%20fill%3D%22none%22%20stroke-width%3D%22#{$stroke-width}%22%2F%3E'); +} diff --git a/app/assets/stylesheets/theme/m3-theme-dark.css.scss b/app/assets/stylesheets/theme/m3-theme-dark.css.scss index 40bdba365a..2b40af3e8b 100644 --- a/app/assets/stylesheets/theme/m3-theme-dark.css.scss +++ b/app/assets/stylesheets/theme/m3-theme-dark.css.scss @@ -203,6 +203,13 @@ --d-annotation-question-background-intense: #{color.mix($purple-80, $neutral-25, 20%)}; --d-annotation-user-background-intense: #{color.mix($success-70, $neutral-25, 20%)}; + @include wavy-underline(--d-annotation-warning-background, $warning-80, 0.7); + @include wavy-underline(--d-annotation-warning-background-intense, $warning-80, 1.7); + @include wavy-underline(--d-annotation-error-background, $danger-70, 0.7); + @include wavy-underline(--d-annotation-error-background-intense, $danger-70, 1.7); + @include wavy-underline(--d-annotation-info-background, $info-80, 0.7); + @include wavy-underline(--d-annotation-info-background-intense, $info-80, 1.7); + .image-bright { // $gray-90 converted to filter using https://codepen.io/sosuke/pen/Pjoqqp filter: invert(86%) sepia(3%) saturate(218%) hue-rotate(242deg) brightness(107%) contrast(90%); diff --git a/app/assets/stylesheets/theme/m3-theme-light.css.scss b/app/assets/stylesheets/theme/m3-theme-light.css.scss index 69ecbc3ab2..583c789aff 100644 --- a/app/assets/stylesheets/theme/m3-theme-light.css.scss +++ b/app/assets/stylesheets/theme/m3-theme-light.css.scss @@ -3,6 +3,7 @@ @use "sass:color"; @import "theme/m3-theme.css.scss"; +@import "mixins.css.scss"; :root, [data-bs-theme="light"] { @@ -217,6 +218,13 @@ --d-annotation-question-background-intense: #{color.mix($purple-40, $neutral-98, 20%)}; --d-annotation-user-background-intense: #{color.mix($success-60, $neutral-98, 20%)}; + @include wavy-underline(--d-annotation-warning-background, $warning-70, 0.7); + @include wavy-underline(--d-annotation-warning-background-intense, $warning-70, 1.7); + @include wavy-underline(--d-annotation-error-background, $danger-60, 0.7); + @include wavy-underline(--d-annotation-error-background-intense, $danger-60, 1.7); + @include wavy-underline(--d-annotation-info-background, $info-40, 0.7); + @include wavy-underline(--d-annotation-info-background-intense, $info-40, 1.7); + .image-bright { // $gray-10 converted to filter using https://codepen.io/sosuke/pen/Pjoqqp filter: invert(8%) sepia(10%) saturate(679%) hue-rotate(201deg) brightness(93%) contrast(92%);