From c5664b00d66b8f65b661b092840da64cc5625aec Mon Sep 17 00:00:00 2001 From: Vanessa Date: Fri, 11 Oct 2024 01:14:37 +0800 Subject: [PATCH] :art: fix https://github.com/siyuan-note/siyuan/issues/12482 --- .../scss/pdf/annotation_layer_builder.scss | 577 ++++++++++-------- app/src/assets/scss/pdf/pdf_viewer.scss | 113 ++-- .../assets/scss/pdf/text_layer_builder.scss | 160 +++-- .../assets/scss/pdf/xfa_layer_builder.scss | 79 ++- 4 files changed, 514 insertions(+), 415 deletions(-) diff --git a/app/src/assets/scss/pdf/annotation_layer_builder.scss b/app/src/assets/scss/pdf/annotation_layer_builder.scss index c6f74b590..e6a8697a5 100644 --- a/app/src/assets/scss/pdf/annotation_layer_builder.scss +++ b/app/src/assets/scss/pdf/annotation_layer_builder.scss @@ -13,324 +13,377 @@ * limitations under the License. */ -:root { - --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); +.annotationLayer { + --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); --input-focus-border-color: Highlight; --input-focus-outline: 1px solid Canvas; --input-unfocused-border-color: transparent; --input-disabled-border-color: transparent; --input-hover-border-color: black; --link-outline: none; -} -@media screen and (forced-colors: active) { - :root { + @media screen and (forced-colors: active) { --input-focus-border-color: CanvasText; --input-unfocused-border-color: ActiveText; --input-disabled-border-color: GrayText; --input-hover-border-color: Highlight; --link-outline: 1.5px solid LinkText; + + .textWidgetAnnotation :is(input, textarea):required, + .choiceWidgetAnnotation select:required, + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required { + outline: 1.5px solid selectedItem; + } + + .linkAnnotation { + outline: var(--link-outline); + + &:hover { + backdrop-filter: var(--hcm-highlight-filter); + } + + & > a:hover { + opacity: 0 !important; + background: none !important; + box-shadow: none; + } + } + + .popupAnnotation .popup { + outline: calc(1.5px * var(--scale-factor)) solid CanvasText !important; + background-color: ButtonFace !important; + color: ButtonText !important; + } + + .highlightArea:hover::after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + backdrop-filter: var(--hcm-highlight-filter); + content: ""; + pointer-events: none; + } + + .popupAnnotation.focused .popup { + outline: calc(3px * var(--scale-factor)) solid Highlight !important; + } } - .annotationLayer .linkAnnotation:hover { - backdrop-filter: invert(100%); - } -} - -.annotationLayer { position: absolute; top: 0; left: 0; pointer-events: none; transform-origin: 0 0; - z-index: 3; -} -.annotationLayer[data-main-rotation="90"] .norotate { - transform: rotate(270deg) translateX(-100%); -} -.annotationLayer[data-main-rotation="180"] .norotate { - transform: rotate(180deg) translate(-100%, -100%); -} -.annotationLayer[data-main-rotation="270"] .norotate { - transform: rotate(90deg) translateY(-100%); -} + &[data-main-rotation="90"] .norotate { + transform: rotate(270deg) translateX(-100%); + } + &[data-main-rotation="180"] .norotate { + transform: rotate(180deg) translate(-100%, -100%); + } + &[data-main-rotation="270"] .norotate { + transform: rotate(90deg) translateY(-100%); + } -.annotationLayer canvas { - position: absolute; - width: 100%; - height: 100%; -} + &.disabled { + section, + .popup { + pointer-events: none; + } + } -.annotationLayer section { - position: absolute; - text-align: initial; - pointer-events: auto; - box-sizing: border-box; - transform-origin: 0 0; -} + .annotationContent { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; -.annotationLayer .linkAnnotation { - outline: var(--link-outline); -} + &.freetext { + background: transparent; + border: none; + inset: 0; + overflow: visible; + white-space: nowrap; + font: 10px sans-serif; + line-height: 1.35; + user-select: none; + } + } -.annotationLayer .linkAnnotation > a, -.annotationLayer .buttonWidgetAnnotation.pushButton > a { - position: absolute; - font-size: 1em; - top: 0; - left: 0; - width: 100%; - height: 100%; -} + section { + position: absolute; + text-align: initial; + pointer-events: auto; + box-sizing: border-box; + transform-origin: 0 0; -.annotationLayer .linkAnnotation > a:hover, -.annotationLayer .buttonWidgetAnnotation.pushButton > a:hover { - opacity: .2; - background: rgba(255, 255, 0, 1); - box-shadow: 0 2px 10px rgba(255, 255, 0, 1); -} + &:has(div.annotationContent) { + canvas.annotationContent { + display: none; + } + } + } -.annotationLayer .textAnnotation img { - position: absolute; - cursor: pointer; - width: 100%; - height: 100%; - top: 0; - left: 0; -} + .textLayer.selecting ~ & section { + pointer-events: none; + } -.annotationLayer .textWidgetAnnotation input, -.annotationLayer .textWidgetAnnotation textarea, -.annotationLayer .choiceWidgetAnnotation select, -.annotationLayer .buttonWidgetAnnotation.checkBox input, -.annotationLayer .buttonWidgetAnnotation.radioButton input { - background-color: rgba(0, 54, 255, .13); // NOTE - border: 2px solid var(--input-unfocused-border-color); - box-sizing: border-box; - font: calc(9px * var(--scale-factor)) sans-serif; - height: 100%; - margin: 0; - vertical-align: top; - width: 100%; -} + :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a { + position: absolute; + font-size: 1em; + top: 0; + left: 0; + width: 100%; + height: 100%; + } -.annotationLayer .textWidgetAnnotation input:required, -.annotationLayer .textWidgetAnnotation textarea:required, -.annotationLayer .choiceWidgetAnnotation select:required, -.annotationLayer .buttonWidgetAnnotation.checkBox input:required, -.annotationLayer .buttonWidgetAnnotation.radioButton input:required { - outline: 1.5px solid red; -} + :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) + > a:hover { + opacity: 0.2; + background-color: rgb(255 255 0); + box-shadow: 0 2px 10px rgb(255 255 0); + } -.annotationLayer .choiceWidgetAnnotation select option { - padding: 0; -} + .linkAnnotation.hasBorder:hover { + background-color: rgb(255 255 0 / 0.2); + } -.annotationLayer .buttonWidgetAnnotation.radioButton input { - border-radius: 50%; -} + .hasBorder { + background-size: 100% 100%; + } -.annotationLayer .textWidgetAnnotation textarea { - resize: none; -} + .textAnnotation img { + position: absolute; + cursor: pointer; + width: 100%; + height: 100%; + top: 0; + left: 0; + } -.annotationLayer .textWidgetAnnotation input[disabled], -.annotationLayer .textWidgetAnnotation textarea[disabled], -.annotationLayer .choiceWidgetAnnotation select[disabled], -.annotationLayer .buttonWidgetAnnotation.checkBox input[disabled], -.annotationLayer .buttonWidgetAnnotation.radioButton input[disabled] { - background: none; - border: 2px solid var(--input-disabled-border-color); - cursor: not-allowed; -} + .textWidgetAnnotation :is(input, textarea), + .choiceWidgetAnnotation select, + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + background-color: rgba(0, 54, 255, .13); // NOTE + border: 2px solid var(--input-unfocused-border-color); + box-sizing: border-box; + font: calc(9px * var(--scale-factor)) sans-serif; + height: 100%; + margin: 0; + vertical-align: top; + width: 100%; + } -.annotationLayer .textWidgetAnnotation input:hover, -.annotationLayer .textWidgetAnnotation textarea:hover, -.annotationLayer .choiceWidgetAnnotation select:hover, -.annotationLayer .buttonWidgetAnnotation.checkBox input:hover, -.annotationLayer .buttonWidgetAnnotation.radioButton input:hover { - border: 2px solid var(--input-hover-border-color); -} -.annotationLayer .textWidgetAnnotation input:hover, -.annotationLayer .textWidgetAnnotation textarea:hover, -.annotationLayer .choiceWidgetAnnotation select:hover, -.annotationLayer .buttonWidgetAnnotation.checkBox input:hover { - border-radius: var(--b3-border-radius); -} + .textWidgetAnnotation :is(input, textarea):required, + .choiceWidgetAnnotation select:required, + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:required { + outline: 1.5px solid red; + } -.annotationLayer .textWidgetAnnotation input:focus, -.annotationLayer .textWidgetAnnotation textarea:focus, -.annotationLayer .choiceWidgetAnnotation select:focus { - background: none; - border: 2px solid var(--input-focus-border-color); - border-radius: var(--b3-border-radius); - outline: var(--input-focus-outline); -} + .choiceWidgetAnnotation select option { + padding: 0; + } -.annotationLayer .buttonWidgetAnnotation.checkBox :focus, -.annotationLayer .buttonWidgetAnnotation.radioButton :focus { - background-image: none; - background-color: transparent; -} + .buttonWidgetAnnotation.radioButton input { + border-radius: 50%; + } -.annotationLayer .buttonWidgetAnnotation.checkBox :focus { - border: 2px solid var(--input-focus-border-color); - border-radius: var(--b3-border-radius); - outline: var(--input-focus-outline); -} + .textWidgetAnnotation textarea { + resize: none; + } -.annotationLayer .buttonWidgetAnnotation.radioButton :focus { - border: 2px solid var(--input-focus-border-color); - outline: var(--input-focus-outline); -} + .textWidgetAnnotation :is(input, textarea)[disabled], + .choiceWidgetAnnotation select[disabled], + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input[disabled] { + background: none; + border: 2px solid var(--input-disabled-border-color); + cursor: not-allowed; + } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before, -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after, -.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before { - background-color: rgba(0, 0, 0, 1); // NOTE - content: ""; - display: block; - position: absolute; -} + .textWidgetAnnotation :is(input, textarea):hover, + .choiceWidgetAnnotation select:hover, + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input:hover { + border: 2px solid var(--input-hover-border-color); + } + .textWidgetAnnotation :is(input, textarea):hover, + .choiceWidgetAnnotation select:hover, + .buttonWidgetAnnotation.checkBox input:hover { + border-radius: 2px; + } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before, -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after { - height: 80%; - left: 45%; - width: 1px; -} + .textWidgetAnnotation :is(input, textarea):focus, + .choiceWidgetAnnotation select:focus { + background: none; + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); + } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:before { - transform: rotate(45deg); -} + .buttonWidgetAnnotation:is(.checkBox, .radioButton) :focus { + background-image: none; + background-color: transparent; + } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked:after { - transform: rotate(-45deg); -} + .buttonWidgetAnnotation.checkBox :focus { + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); + } -.annotationLayer .buttonWidgetAnnotation.radioButton input:checked:before { - border-radius: 50%; - height: 50%; - left: 30%; - top: 20%; - width: 50%; -} + .buttonWidgetAnnotation.radioButton :focus { + border: 2px solid var(--input-focus-border-color); + outline: var(--input-focus-outline); + } -.annotationLayer .textWidgetAnnotation input.comb { - font-family: monospace; - padding-left: 2px; - padding-right: 0; -} + .buttonWidgetAnnotation.checkBox input:checked::before, + .buttonWidgetAnnotation.checkBox input:checked::after, + .buttonWidgetAnnotation.radioButton input:checked::before { + background-color: rgba(0, 0, 0, 1); // NOTE + content: ""; + display: block; + position: absolute; + } -.annotationLayer .textWidgetAnnotation input.comb:focus { - /* - * Letter spacing is placed on the right side of each character. Hence, the - * letter spacing of the last character may be placed outside the visible - * area, causing horizontal scrolling. We avoid this by extending the width - * when the element has focus and revert this when it loses focus. - */ - width: 103%; -} + .buttonWidgetAnnotation.checkBox input:checked::before, + .buttonWidgetAnnotation.checkBox input:checked::after { + height: 80%; + left: 45%; + width: 1px; + } -.annotationLayer .buttonWidgetAnnotation.checkBox input, -.annotationLayer .buttonWidgetAnnotation.radioButton input { - appearance: none; -} + .buttonWidgetAnnotation.checkBox input:checked::before { + transform: rotate(45deg); + } -.annotationLayer .popupTriggerArea { - height: 100%; - width: 100%; -} + .buttonWidgetAnnotation.checkBox input:checked::after { + transform: rotate(-45deg); + } -.annotationLayer .fileAttachmentAnnotation .popupTriggerArea { - position: absolute; -} + .buttonWidgetAnnotation.radioButton input:checked::before { + border-radius: 50%; + height: 50%; + left: 25%; + top: 25%; + width: 50%; + } -.annotationLayer .popupWrapper { - position: absolute; - font-size: calc(9px * var(--scale-factor)); - width: 100%; - min-width: calc(180px * var(--scale-factor)); - pointer-events: none; -} + .textWidgetAnnotation input.comb { + font-family: monospace; + padding-left: 2px; + padding-right: 0; + } -.annotationLayer .popup { - position: absolute; - max-width: calc(180px * var(--scale-factor)); - background-color: rgba(255, 255, 153, 1); - box-shadow: 0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor)) - rgba(136, 136, 136, 1); - border-radius: calc(2px * var(--scale-factor)); - padding: calc(6px * var(--scale-factor)); - margin-left: calc(5px * var(--scale-factor)); - cursor: pointer; - font: message-box; - white-space: normal; - word-wrap: break-word; - pointer-events: auto; -} + .textWidgetAnnotation input.comb:focus { + /* + * Letter spacing is placed on the right side of each character. Hence, the + * letter spacing of the last character may be placed outside the visible + * area, causing horizontal scrolling. We avoid this by extending the width + * when the element has focus and revert this when it loses focus. + */ + width: 103%; + } -.annotationLayer .popup > * { - font-size: calc(9px * var(--scale-factor)); -} + .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + appearance: none; + } -.annotationLayer .popup h1 { - display: inline-block; -} + .fileAttachmentAnnotation .popupTriggerArea { + height: 100%; + width: 100%; + } -.annotationLayer .popupDate { - display: inline-block; - margin-left: calc(5px * var(--scale-factor)); -} + .popupAnnotation { + position: absolute; + font-size: calc(9px * var(--scale-factor)); + pointer-events: none; + width: max-content; + max-width: 45%; + height: auto; + } -.annotationLayer .popupContent { - border-top: 1px solid rgba(51, 51, 51, 1); - margin-top: calc(2px * var(--scale-factor)); - padding-top: calc(2px * var(--scale-factor)); -} + .popup { + background-color: rgb(255 255 153); + box-shadow: 0 calc(2px * var(--scale-factor)) + calc(5px * var(--scale-factor)) rgb(136 136 136); + border-radius: calc(2px * var(--scale-factor)); + outline: 1.5px solid rgb(255 255 74); + padding: calc(6px * var(--scale-factor)); + cursor: pointer; + font: message-box; + white-space: normal; + word-wrap: break-word; + pointer-events: auto; + } -.annotationLayer .richText > * { - white-space: pre-wrap; - font-size: calc(9px * var(--scale-factor)); -} + .popupAnnotation.focused .popup { + outline-width: 3px; + } -.annotationLayer .highlightAnnotation, -.annotationLayer .underlineAnnotation, -.annotationLayer .squigglyAnnotation, -.annotationLayer .strikeoutAnnotation, -.annotationLayer .freeTextAnnotation, -.annotationLayer .lineAnnotation svg line, -.annotationLayer .squareAnnotation svg rect, -.annotationLayer .circleAnnotation svg ellipse, -.annotationLayer .polylineAnnotation svg polyline, -.annotationLayer .polygonAnnotation svg polygon, -.annotationLayer .caretAnnotation, -.annotationLayer .inkAnnotation svg polyline, -.annotationLayer .stampAnnotation, -.annotationLayer .fileAttachmentAnnotation { - cursor: pointer; -} + .popup * { + font-size: calc(9px * var(--scale-factor)); + } -.annotationLayer section svg { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; -} + .popup > .header { + display: inline-block; + } -.annotationLayer .annotationTextContent { - position: absolute; - width: 100%; - height: 100%; - opacity: 0; - color: transparent; - user-select: none; - pointer-events: none; -} + .popup > .header h1 { + display: inline; + } -.annotationLayer .annotationTextContent span { - width: 100%; - display: inline-block; + .popup > .header .popupDate { + display: inline-block; + margin-left: calc(5px * var(--scale-factor)); + width: fit-content; + } + + .popupContent { + border-top: 1px solid rgb(51 51 51); + margin-top: calc(2px * var(--scale-factor)); + padding-top: calc(2px * var(--scale-factor)); + } + + .richText > * { + white-space: pre-wrap; + font-size: calc(9px * var(--scale-factor)); + } + + .popupTriggerArea { + cursor: pointer; + } + + section svg { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + } + + .annotationTextContent { + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + color: transparent; + user-select: none; + pointer-events: none; + + span { + width: 100%; + display: inline-block; + } + } + + svg.quadrilateralsContainer { + contain: strict; + width: 0; + height: 0; + position: absolute; + top: 0; + left: 0; + z-index: -1; + } } diff --git a/app/src/assets/scss/pdf/pdf_viewer.scss b/app/src/assets/scss/pdf/pdf_viewer.scss index 3b1119e9a..6c542efa6 100644 --- a/app/src/assets/scss/pdf/pdf_viewer.scss +++ b/app/src/assets/scss/pdf/pdf_viewer.scss @@ -29,7 +29,7 @@ :root { --pdfViewer-padding-bottom: 9px; --page-margin: 8px auto -1px; - --page-border: none; + --page-border: 1px solid CanvasText; --spreadHorizontalWrapped-margin-LR: 3.5px; } } @@ -44,22 +44,66 @@ transform: rotate(270deg) translateX(-100%); } +#hiddenCopyElement, +.hiddenCanvasElement { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + display: none; +} + .pdfViewer { /* Define this variable here and not in :root to avoid to reflow all the UI when scaling (see #15929). */ --scale-factor: 1; + --page-bg-color: unset; padding-bottom: var(--pdfViewer-padding-bottom); -} -.pdfViewer .canvasWrapper { - overflow: hidden; - width: 100%; - height: 100%; - z-index: 1; + --hcm-highlight-filter: none; + --hcm-highlight-selected-filter: none; + + @media screen and (forced-colors: active) { + --hcm-highlight-filter: invert(100%); + } + + &.copyAll { + cursor: wait; + } + + .canvasWrapper { + overflow: hidden; + width: 100%; + height: 100%; + + canvas { + margin: 0; + display: block; + width: 100%; + height: 100%; + + &[hidden] { + display: none; + } + + &[zooming] { + width: 100%; + height: 100%; + } + + .structTree { + contain: strict; + } + } + } } .pdfViewer .page { + --scale-round-x: 1px; + --scale-round-y: 1px; + direction: ltr; width: 816px; height: 1056px; @@ -68,7 +112,7 @@ overflow: visible; border: var(--page-border); background-clip: content-box; - background-color: rgba(255, 255, 255, 1); + background-color: var(--page-bg-color, rgb(255 255 255)); } .pdfViewer .dummyPage { @@ -77,6 +121,10 @@ height: var(--viewer-container-height); } +.pdfViewer.noUserSelect { + user-select: none; +} + /*#if GENERIC*/ .pdfViewer.removePageBorders .page { margin: 0 auto 10px; @@ -95,8 +143,7 @@ } /*#endif*/ -.pdfViewer.scrollHorizontal, -.pdfViewer.scrollWrapped, +.pdfViewer:is(.scrollHorizontal, .scrollWrapped), .spread { margin-inline: 3.5px; text-align: center; @@ -110,54 +157,29 @@ /*#if GENERIC*/ .pdfViewer.removePageBorders, /*#endif*/ -.pdfViewer.scrollHorizontal .spread, -.pdfViewer.scrollWrapped .spread { +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .spread { margin-inline: 0; } -.spread .page, -.spread .dummyPage, -.pdfViewer.scrollHorizontal .page, -.pdfViewer.scrollWrapped .page, -.pdfViewer.scrollHorizontal .spread, -.pdfViewer.scrollWrapped .spread { +.spread :is(.page, .dummyPage), +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread) { display: inline-block; vertical-align: middle; } .spread .page, -.pdfViewer.scrollHorizontal .page, -.pdfViewer.scrollWrapped .page { +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .page { margin-inline: var(--spreadHorizontalWrapped-margin-LR); } /*#if GENERIC*/ .pdfViewer.removePageBorders .spread .page, -.pdfViewer.removePageBorders.scrollHorizontal .page, -.pdfViewer.removePageBorders.scrollWrapped .page { +.pdfViewer.removePageBorders:is(.scrollHorizontal, .scrollWrapped) .page { margin-inline: 5px; } /*#endif*/ -.pdfViewer .page canvas { - margin: 0; - display: block; -} - -.pdfViewer .page canvas .structTree { - contain: strict; -} - -.pdfViewer .page canvas[hidden] { - display: none; -} - -.pdfViewer .page canvas[zooming] { - width: 100%; - height: 100%; -} - -.pdfViewer .page.loadingIcon:after { +.pdfViewer .page.loadingIcon::after { position: absolute; top: 0; left: 0; @@ -174,20 +196,15 @@ contain: strict; } -.pdfViewer .page.loading:after { +.pdfViewer .page.loading::after { display: block; } -.pdfViewer .page:not(.loading):after { +.pdfViewer .page:not(.loading)::after { transition-property: none; display: none; } -.pdfViewer.enablePermissions .textLayer span { - user-select: none !important; - cursor: not-allowed; -} - .pdfPresentationMode .pdfViewer { padding-bottom: 0; } diff --git a/app/src/assets/scss/pdf/text_layer_builder.scss b/app/src/assets/scss/pdf/text_layer_builder.scss index 26f201231..c2954ec39 100644 --- a/app/src/assets/scss/pdf/text_layer_builder.scss +++ b/app/src/assets/scss/pdf/text_layer_builder.scss @@ -16,82 +16,116 @@ .textLayer { position: absolute; text-align: initial; - left: 0; - top: 0; - right: 0; - bottom: 0; - overflow: hidden; - // NOTE + inset: 0; + overflow: clip; + opacity: 1; line-height: 1; text-size-adjust: none; + forced-color-adjust: none; transform-origin: 0 0; -} + caret-color: CanvasText; + z-index: 0; -.textLayer span, -.textLayer br { - color: transparent; - position: absolute; - white-space: pre; - cursor: text; - transform-origin: 0% 0%; -} + &.highlighting { + touch-action: none; + } -/* Only necessary in Google Chrome, see issue 14205, and most unfortunately - * the problem doesn't show up in "text" reference tests. */ -.textLayer span.markedContent { - top: 0; - height: 0; -} + :is(span, br) { + color: transparent; + position: absolute; + white-space: pre; + cursor: text; + transform-origin: 0% 0%; + } -.textLayer .highlight { - margin: -1px; - padding: 1px; - background-color: rgba(180, 0, 170, 1); - border-radius: var(--b3-border-radius); -} + > :not(.markedContent), + .markedContent span:not(.markedContent) { + z-index: 1; + } -.textLayer .highlight.appended { - position: initial; -} + /* Only necessary in Google Chrome, see issue 14205, and most unfortunately + * the problem doesn't show up in "text" reference tests. */ + /*#if !MOZCENTRAL*/ + span.markedContent { + top: 0; + height: 0; + } + /*#endif*/ -.textLayer .highlight.begin { - border-radius: var(--b3-border-radius) 0 0 var(--b3-border-radius); -} + span[role="img"] { + user-select: none; + cursor: default; + } -.textLayer .highlight.end { - border-radius: 0 var(--b3-border-radius) var(--b3-border-radius) 0; -} + .highlight { + --highlight-bg-color: rgb(180 0 170 / 0.25); + --highlight-selected-bg-color: rgb(0 100 0 / 0.25); + --highlight-backdrop-filter: none; + --highlight-selected-backdrop-filter: none; -.textLayer .highlight.middle { - border-radius: 0; -} + @media screen and (forced-colors: active) { + --highlight-bg-color: transparent; + --highlight-selected-bg-color: transparent; + --highlight-backdrop-filter: var(--hcm-highlight-filter); + --highlight-selected-backdrop-filter: var( + --hcm-highlight-selected-filter + ); + } -.textLayer .highlight.selected { - background-color: rgba(0, 100, 0, 1); -} + margin: -1px; + padding: 1px; + background-color: var(--highlight-bg-color); + backdrop-filter: var(--highlight-backdrop-filter); + border-radius: 4px; -.textLayer ::selection { - // NOTE - background: var(--b3-pdf-selection); -} + &.appended { + position: initial; + } -/* Avoids https://github.com/mozilla/pdf.js/issues/13840 in Chrome */ -.textLayer br::selection { - background: transparent; -} + &.begin { + border-radius: 4px 0 0 4px; + } -.textLayer .endOfContent { - display: block; - position: absolute; - left: 0; - top: 100%; - right: 0; - bottom: 0; - z-index: -1; - cursor: default; - user-select: none; -} + &.end { + border-radius: 0 4px 4px 0; + } -.textLayer .endOfContent.active { - top: 0; + &.middle { + border-radius: 0; + } + + &.selected { + background-color: var(--highlight-selected-bg-color); + backdrop-filter: var(--highlight-selected-backdrop-filter); + } + } + + ::selection { + /* stylelint-disable declaration-block-no-duplicate-properties */ + /*#if !MOZCENTRAL*/ + background: var(--b3-pdf-selection); // NOTE + /*#endif*/ + /* stylelint-enable declaration-block-no-duplicate-properties */ + background: color-mix(in srgb, AccentColor, transparent 75%); + } + + /* Avoids https://github.com/mozilla/pdf.js/issues/13840 in Chrome */ + /*#if !MOZCENTRAL*/ + br::selection { + background: transparent; + } + /*#endif*/ + + .endOfContent { + display: block; + position: absolute; + inset: 100% 0 0; + z-index: 0; + cursor: default; + user-select: none; + } + + &.selecting .endOfContent { + top: 0; + } } diff --git a/app/src/assets/scss/pdf/xfa_layer_builder.scss b/app/src/assets/scss/pdf/xfa_layer_builder.scss index edac317cf..72961eda5 100644 --- a/app/src/assets/scss/pdf/xfa_layer_builder.scss +++ b/app/src/assets/scss/pdf/xfa_layer_builder.scss @@ -14,14 +14,28 @@ */ :root { - --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --xfa-focus-outline: auto; +} + +@media screen and (forced-colors: active) { + :root { + --xfa-focus-outline: 2px solid CanvasText; + } + .xfaLayer *:required { + outline: 1.5px solid selectedItem; + } +} + +.xfaLayer { + background-color: transparent; } .xfaLayer .highlight { margin: -1px; padding: 1px; - background-color: rgba(239, 203, 237, 1); - border-radius: var(--b3-border-radius); + background-color: rgb(239 203 237); + border-radius: 4px; } .xfaLayer .highlight.appended { @@ -29,11 +43,11 @@ } .xfaLayer .highlight.begin { - border-radius: var(--b3-border-radius) 0 0 var(--b3-border-radius); + border-radius: 4px 0 0 4px; } .xfaLayer .highlight.end { - border-radius: 0 var(--b3-border-radius) var(--b3-border-radius) 0; + border-radius: 0 4px 4px 0; } .xfaLayer .highlight.middle { @@ -41,12 +55,7 @@ } .xfaLayer .highlight.selected { - background-color: rgba(203, 223, 203, 1); -} - -.xfaLayer ::selection { - // NOTE - background: var(--b3-pdf-selection); + background-color: var(--b3-pdf-selection); // NOTE } .xfaPage { @@ -77,7 +86,7 @@ font-style: inherit; font-weight: inherit; font-kerning: inherit; - letter-spacing: -.01px; + letter-spacing: -0.01px; text-align: inherit; text-decoration: inherit; box-sizing: border-box; @@ -88,14 +97,12 @@ line-height: inherit; } -.xfaLayer div { - pointer-events: none; -} - -.xfaLayer svg { - pointer-events: none; +.xfaLayer *:required { + outline: 1.5px solid red; } +.xfaLayer div, +.xfaLayer svg, .xfaLayer svg * { pointer-events: none; } @@ -146,10 +153,7 @@ align-items: center; } -.xfaLeft > .xfaCaption, -.xfaLeft > .xfaCaptionForCheckButton, -.xfaRight > .xfaCaption, -.xfaRight > .xfaCaptionForCheckButton { +:is(.xfaLeft, .xfaRight) > :is(.xfaCaption, .xfaCaptionForCheckButton) { max-height: 100%; } @@ -165,10 +169,7 @@ align-items: flex-start; } -.xfaTop > .xfaCaption, -.xfaTop > .xfaCaptionForCheckButton, -.xfaBottom > .xfaCaption, -.xfaBottom > .xfaCaptionForCheckButton { +:is(.xfaTop, .xfaBottom) > :is(.xfaCaption, .xfaCaptionForCheckButton) { width: 100%; } @@ -183,17 +184,15 @@ height: 100%; } -.xfaTextfield:focus, -.xfaSelect:focus { +:is(.xfaTextfield, .xfaSelect):focus { background-image: none; background-color: transparent; - outline: auto; + outline: var(--xfa-focus-outline); outline-offset: -1px; } -.xfaCheckbox:focus, -.xfaRadio:focus { - outline: auto; +:is(.xfaCheckbox, .xfaRadio):focus { + outline: var(--xfa-focus-outline); } .xfaTextfield, @@ -206,10 +205,11 @@ background-image: var(--xfa-unfocused-field-background); } -.xfaTop > .xfaTextfield, -.xfaTop > .xfaSelect, -.xfaBottom > .xfaTextfield, -.xfaBottom > .xfaSelect { +.xfaSelect { + padding-inline: 2px; +} + +:is(.xfaTop, .xfaBottom) > :is(.xfaTextfield, .xfaSelect) { flex: 0 1 auto; } @@ -310,12 +310,7 @@ flex: 1; } -.xfaNonInteractive input, -.xfaNonInteractive textarea, -.xfaDisabled input, -.xfaDisabled textarea, -.xfaReadOnly input, -.xfaReadOnly textarea { +:is(.xfaNonInteractive, .xfaDisabled, .xfaReadOnly) :is(input, textarea) { background: initial; }