diff --git a/Source/WebCore/html/HTMLAttachmentElement.cpp b/Source/WebCore/html/HTMLAttachmentElement.cpp index 1accd1c79b42..ad3b37422f99 100644 --- a/Source/WebCore/html/HTMLAttachmentElement.cpp +++ b/Source/WebCore/html/HTMLAttachmentElement.cpp @@ -114,6 +114,18 @@ static const AtomString& attachmentPreviewIdentifier() return identifier; } +static const AtomString& attachmentProgressIdentifier() +{ + static MainThreadNeverDestroyed identifier("attachment-progress"_s); + return identifier; +} + +static const AtomString& attachmentProgressCircleIdentifier() +{ + static MainThreadNeverDestroyed identifier("attachment-progress-circle"_s); + return identifier; +} + static const AtomString& attachmentInformationAreaIdentifier() { static MainThreadNeverDestroyed identifier("attachment-information-area"_s); @@ -226,6 +238,11 @@ void HTMLAttachmentElement::ensureModernShadowTree(ShadowRoot& root) m_innerLegacyAttachment->setIdAttribute(attachmentPreviewIdentifier()); previewArea->appendChild(*m_innerLegacyAttachment); + m_progressElement = createContainedElement(previewArea, attachmentProgressIdentifier()); + updateProgress(attributeWithoutSynchronization(progressAttr)); + + createContainedElement(*m_progressElement, attachmentProgressCircleIdentifier()); + auto informationArea = createContainedElement(*m_containerElement, attachmentInformationAreaIdentifier()); m_informationBlock = createContainedElement(informationArea, attachmentInformationBlockIdentifier()); @@ -275,6 +292,21 @@ class AttachmentSaveEventListener final : public EventListener { WeakPtr m_attachment; }; +void HTMLAttachmentElement::updateProgress(const AtomString& progress) +{ + if (!m_progressElement) + return; + + bool validProgress = false; + float value = progress.toFloat(&validProgress); + if (validProgress && std::isfinite(value)) { + m_progressElement->setAttributeWithoutSynchronization(styleAttr, makeAtomString("--progress: ", (value < 0.0) ? "0"_s : (value > 1.0) ? "1"_s : progress)); + return; + } + + m_progressElement->setAttributeWithoutSynchronization(styleAttr, "display: none;"_s); +} + void HTMLAttachmentElement::updateSaveButton(bool show) { if (!show) { @@ -425,10 +457,12 @@ RefPtr HTMLAttachmentElement::enclosingImageElement() const void HTMLAttachmentElement::parseAttribute(const QualifiedName& name, const AtomString& value) { - if (name == actionAttr || name == progressAttr || name == subtitleAttr() || name == titleAttr || name == typeAttr) { + if (name == actionAttr || name == subtitleAttr() || name == titleAttr || name == typeAttr) { if (m_innerLegacyAttachment) m_innerLegacyAttachment->setAttributeWithoutSynchronization(name, value); invalidateRendering(); + } else if (name == progressAttr && m_implementation == Implementation::Legacy) { + invalidateRendering(); } HTMLElement::parseAttribute(name, value); @@ -442,7 +476,9 @@ void HTMLAttachmentElement::parseAttribute(const QualifiedName& name, const Atom } else if (name == subtitleAttr()) { if (m_subtitleElement) m_subtitleElement->setTextContent(String(value.string())); - } else if (name == saveAttr()) + } else if (name == progressAttr) + updateProgress(value); + else if (name == saveAttr()) updateSaveButton(!value.isNull()); #if ENABLE(SERVICE_CONTROLS) diff --git a/Source/WebCore/html/HTMLAttachmentElement.h b/Source/WebCore/html/HTMLAttachmentElement.h index e90c5ba7321b..e76d993b7ef1 100644 --- a/Source/WebCore/html/HTMLAttachmentElement.h +++ b/Source/WebCore/html/HTMLAttachmentElement.h @@ -98,6 +98,7 @@ class HTMLAttachmentElement final : public HTMLElement { void didAddUserAgentShadowRoot(ShadowRoot&) final; void ensureModernShadowTree(ShadowRoot&); + void updateProgress(const AtomString&); void updateSaveButton(bool); RenderPtr createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; @@ -126,6 +127,7 @@ class HTMLAttachmentElement final : public HTMLElement { RefPtr m_innerLegacyAttachment; RefPtr m_containerElement; + RefPtr m_progressElement; RefPtr m_informationBlock; RefPtr m_actionTextElement; RefPtr m_titleElement; diff --git a/Source/WebCore/html/shadow/attachmentElementShadow.css b/Source/WebCore/html/shadow/attachmentElementShadow.css index f98b63688614..a307439a56bc 100644 --- a/Source/WebCore/html/shadow/attachmentElementShadow.css +++ b/Source/WebCore/html/shadow/attachmentElementShadow.css @@ -80,6 +80,25 @@ attachment#attachment-preview { overflow: hidden; } +div#attachment-progress { + grid-row: 1; + grid-column: 1; + width: 100%; + aspect-ratio: 1; + border-radius: 50%; + color: -apple-system-secondary-label; + background: conic-gradient(currentcolor calc(var(--progress) * 100%), transparent 0); +} + +/* FIXME: Move the border into attachment-progress above, and remove this div, when rdar://107621207 is fixed (currently it produces artifacts at the edges). */ +div#attachment-progress-circle { + width: 100%; + aspect-ratio: 1; + border-radius: 50%; + border: 4px solid currentcolor; + box-sizing: border-box; +} + div#attachment-information-area { grid-row: 1; grid-column: 2;