Skip to content

Commit

Permalink
Reimplement the progress display in wide-layout attachments
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=255100
rdar://problem/107716507

Reviewed by Aditya Keerthi.

When a wide-layout attachment has an attribute "progress" with a number, it is now directly handled by the top-level attachment element, by displaying a pie chart; previously it was handled by the inner attachment's legacy code.

* Source/WebCore/html/HTMLAttachmentElement.cpp:
(WebCore::attachmentProgressIdentifier):
(WebCore::HTMLAttachmentElement::ensureModernShadowTree):
(WebCore::HTMLAttachmentElement::updateProgress):
(WebCore::HTMLAttachmentElement::parseAttribute):
* Source/WebCore/html/HTMLAttachmentElement.h:
* Source/WebCore/html/shadow/attachmentElementShadow.css:
(div#attachment-progress):

Canonical link: https://commits.webkit.org/262758@main
  • Loading branch information
squelart committed Apr 9, 2023
1 parent 4a28e3c commit 31c3e79
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
40 changes: 38 additions & 2 deletions Source/WebCore/html/HTMLAttachmentElement.cpp
Expand Up @@ -114,6 +114,18 @@ static const AtomString& attachmentPreviewIdentifier()
return identifier;
}

static const AtomString& attachmentProgressIdentifier()
{
static MainThreadNeverDestroyed<const AtomString> identifier("attachment-progress"_s);
return identifier;
}

static const AtomString& attachmentProgressCircleIdentifier()
{
static MainThreadNeverDestroyed<const AtomString> identifier("attachment-progress-circle"_s);
return identifier;
}

static const AtomString& attachmentInformationAreaIdentifier()
{
static MainThreadNeverDestroyed<const AtomString> identifier("attachment-information-area"_s);
Expand Down Expand Up @@ -226,6 +238,11 @@ void HTMLAttachmentElement::ensureModernShadowTree(ShadowRoot& root)
m_innerLegacyAttachment->setIdAttribute(attachmentPreviewIdentifier());
previewArea->appendChild(*m_innerLegacyAttachment);

m_progressElement = createContainedElement<HTMLDivElement>(previewArea, attachmentProgressIdentifier());
updateProgress(attributeWithoutSynchronization(progressAttr));

createContainedElement<HTMLDivElement>(*m_progressElement, attachmentProgressCircleIdentifier());

auto informationArea = createContainedElement<HTMLDivElement>(*m_containerElement, attachmentInformationAreaIdentifier());

m_informationBlock = createContainedElement<HTMLDivElement>(informationArea, attachmentInformationBlockIdentifier());
Expand Down Expand Up @@ -275,6 +292,21 @@ class AttachmentSaveEventListener final : public EventListener {
WeakPtr<HTMLAttachmentElement, WeakPtrImplWithEventTargetData> 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) {
Expand Down Expand Up @@ -425,10 +457,12 @@ RefPtr<HTMLImageElement> 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);
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/html/HTMLAttachmentElement.h
Expand Up @@ -98,6 +98,7 @@ class HTMLAttachmentElement final : public HTMLElement {

void didAddUserAgentShadowRoot(ShadowRoot&) final;
void ensureModernShadowTree(ShadowRoot&);
void updateProgress(const AtomString&);
void updateSaveButton(bool);

RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
Expand Down Expand Up @@ -126,6 +127,7 @@ class HTMLAttachmentElement final : public HTMLElement {

RefPtr<HTMLAttachmentElement> m_innerLegacyAttachment;
RefPtr<HTMLElement> m_containerElement;
RefPtr<HTMLElement> m_progressElement;
RefPtr<HTMLElement> m_informationBlock;
RefPtr<HTMLElement> m_actionTextElement;
RefPtr<HTMLElement> m_titleElement;
Expand Down
19 changes: 19 additions & 0 deletions Source/WebCore/html/shadow/attachmentElementShadow.css
Expand Up @@ -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;
Expand Down

0 comments on commit 31c3e79

Please sign in to comment.