WebKit Bugzilla
Attachment 343361 Details for
Bug 186614
: Make it possible to add a border around loading or failed-to-load images
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186614-20180622133445.patch (text/plain), 20.28 KB, created by
Tim Horton
on 2018-06-22 13:34:46 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Tim Horton
Created:
2018-06-22 13:34:46 PDT
Size:
20.28 KB
patch
obsolete
>Subversion Revision: 233002 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index b5764653f640dec369bf1d416b83edeaa4c8eb09..05225bcb17d9705feed374c2b3bf6d90f32513dc 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,32 @@ >+2018-06-13 Tim Horton <timothy_horton@apple.com> >+ >+ Make it possible to add a border around loading or failed-to-load images >+ https://bugs.webkit.org/show_bug.cgi?id=186614 >+ <rdar://problem/39050152> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Tests: http/tests/images/loading-image-border.html >+ http/tests/images/loading-image-no-border.html >+ >+ >+ * rendering/RenderImage.cpp: >+ (WebCore::RenderImage::paintIncompleteImageOutline): >+ (WebCore::RenderImage::paintReplaced): >+ * rendering/RenderImage.h: >+ Factor the missing-image outline out, and - if desired - paint it in >+ cases where the image is still loading or otherwise pending, not just >+ when the image fails to load. >+ >+ * page/Settings.yaml: >+ * testing/InternalSettings.cpp: >+ (WebCore::InternalSettings::Backup::Backup): >+ (WebCore::InternalSettings::Backup::restoreTo): >+ (WebCore::InternalSettings::setIncompleteImageBorderEnabled): >+ * testing/InternalSettings.h: >+ * testing/InternalSettings.idl: >+ Add and expose a setting to enable the feature. >+ > 2018-06-19 Basuke Suzuki <Basuke.Suzuki@sony.com> > > [Curl] Allow passing contents of Root CA data directly. >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 74119bb35a3e3a958c84e7635300330e49d65bbf..d6ced5d6f2e4b0b2615e8c3b75a88f62e572456d 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,18 @@ >+2018-06-13 Tim Horton <timothy_horton@apple.com> >+ >+ Make it possible to add a border around loading or failed-to-load images >+ https://bugs.webkit.org/show_bug.cgi?id=186614 >+ <rdar://problem/39050152> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Shared/WebPreferences.yaml: >+ * UIProcess/API/Cocoa/WKPreferences.mm: >+ (-[WKPreferences _setIncompleteImageBorderEnabled:]): >+ (-[WKPreferences _incompleteImageBorderEnabled]): >+ * UIProcess/API/Cocoa/WKPreferencesPrivate.h: >+ Plumb the setting to WebKit2. >+ > 2018-06-19 Dean Jackson <dino@apple.com> > > Blank viewer comes up and then auto-dismisses when device is not connected to Internet >diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml >index dd9ed86fa1554cf7d76e49a1fe9667112ee6609a..c1c41b353212183895ee2d1032071741296f54fb 100644 >--- a/Source/WebCore/page/Settings.yaml >+++ b/Source/WebCore/page/Settings.yaml >@@ -750,3 +750,6 @@ crossOriginWindowPolicySupportEnabled: > accessibilityEventsEnabled: > initial: true > conditional: ACCESSIBILITY_EVENTS >+ >+incompleteImageBorderEnabled: >+ initial: false >diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp >index 12641525f67c3c842971fa9182048517a1f72bed..a0f8a3549c761b6e62e7717c8f0daf7ee86714bb 100644 >--- a/Source/WebCore/rendering/RenderImage.cpp >+++ b/Source/WebCore/rendering/RenderImage.cpp >@@ -379,12 +379,32 @@ bool RenderImage::hasNonBitmapImage() const > return image && !is<BitmapImage>(image); > } > >+void RenderImage::paintIncompleteImageOutline(PaintInfo& paintInfo, const LayoutPoint& paintOffset, const LayoutUnit& borderWidth) const >+{ >+ LayoutSize contentSize = this->contentSize(); >+ if (contentSize.width() <= 2 || contentSize.height() <= 2) >+ return; >+ >+ auto leftBorder = borderLeft(); >+ auto topBorder = borderTop(); >+ auto leftPadding = paddingLeft(); >+ auto topPadding = paddingTop(); >+ >+ // Draw an outline rect where the image should be. >+ GraphicsContext& context = paintInfo.context(); >+ context.setStrokeStyle(SolidStroke); >+ context.setStrokeColor(Color::lightGray); >+ context.setFillColor(Color::transparent); >+ context.drawRect(snapRectToDevicePixels(LayoutRect({ paintOffset.x() + leftBorder + leftPadding, paintOffset.y() + topBorder + topPadding }, contentSize), document().deviceScaleFactor()), borderWidth); >+} >+ > void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) > { > LayoutSize contentSize = this->contentSize(); > > GraphicsContext& context = paintInfo.context(); > float deviceScaleFactor = document().deviceScaleFactor(); >+ LayoutUnit missingImageBorderWidth(1 / deviceScaleFactor); > > if (!imageResource().cachedImage() || imageResource().errorOccurred()) { > if (paintInfo.phase == PaintPhaseSelection) >@@ -393,31 +413,25 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf > if (paintInfo.phase == PaintPhaseForeground) > page().addRelevantUnpaintedObject(this, visualOverflowRect()); > >- if (contentSize.width() > 2 && contentSize.height() > 2) { >- LayoutUnit borderWidth = LayoutUnit(1 / deviceScaleFactor); >+ paintIncompleteImageOutline(paintInfo, paintOffset, missingImageBorderWidth); > >+ if (contentSize.width() > 2 && contentSize.height() > 2) { > LayoutUnit leftBorder = borderLeft(); > LayoutUnit topBorder = borderTop(); > LayoutUnit leftPad = paddingLeft(); > LayoutUnit topPad = paddingTop(); > >- // Draw an outline rect where the image should be. >- context.setStrokeStyle(SolidStroke); >- context.setStrokeColor(Color::lightGray); >- context.setFillColor(Color::transparent); >- context.drawRect(snapRectToDevicePixels(LayoutRect({ paintOffset.x() + leftBorder + leftPad, paintOffset.y() + topBorder + topPad }, contentSize), deviceScaleFactor), borderWidth); >- > bool errorPictureDrawn = false; > LayoutSize imageOffset; > // When calculating the usable dimensions, exclude the pixels of > // the ouline rect so the error image/alt text doesn't draw on it. >- LayoutSize usableSize = contentSize - LayoutSize(2 * borderWidth, 2 * borderWidth); >+ LayoutSize usableSize = contentSize - LayoutSize(2 * missingImageBorderWidth, 2 * missingImageBorderWidth); > > RefPtr<Image> image = imageResource().image(); > > if (imageResource().errorOccurred() && !image->isNull() && usableSize.width() >= image->width() && usableSize.height() >= image->height()) { > // Call brokenImage() explicitly to ensure we get the broken image icon at the appropriate resolution. >- std::pair<Image*, float> brokenImageAndImageScaleFactor = cachedImage()->brokenImage(document().deviceScaleFactor()); >+ std::pair<Image*, float> brokenImageAndImageScaleFactor = cachedImage()->brokenImage(deviceScaleFactor); > image = brokenImageAndImageScaleFactor.first; > FloatSize imageSize = image->size(); > imageSize.scale(1 / brokenImageAndImageScaleFactor.second); >@@ -428,7 +442,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf > LayoutUnit centerY = (usableSize.height() - imageSize.height()) / 2; > if (centerY < 0) > centerY = 0; >- imageOffset = LayoutSize(leftBorder + leftPad + centerX + borderWidth, topBorder + topPad + centerY + borderWidth); >+ imageOffset = LayoutSize(leftBorder + leftPad + centerX + missingImageBorderWidth, topBorder + topPad + centerY + missingImageBorderWidth); > > ImageOrientationDescription orientationDescription(shouldRespectImageOrientation()); > #if ENABLE(CSS_IMAGE_ORIENTATION) >@@ -445,7 +459,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf > const FontMetrics& fontMetrics = font.fontMetrics(); > LayoutUnit ascent = fontMetrics.ascent(); > LayoutPoint altTextOffset = paintOffset; >- altTextOffset.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + ascent + (paddingHeight / 2) - borderWidth); >+ altTextOffset.move(leftBorder + leftPad + (paddingWidth / 2) - missingImageBorderWidth, topBorder + topPad + ascent + (paddingHeight / 2) - missingImageBorderWidth); > > // Only draw the alt text if it'll fit within the content box, > // and only if it fits above the error image. >@@ -464,8 +478,13 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf > if (contentSize.isEmpty()) > return; > >+ bool showBorderForIncompleteImage = settings().incompleteImageBorderEnabled(); >+ > RefPtr<Image> img = imageResource().image(flooredIntSize(contentSize)); > if (!img || img->isNull()) { >+ if (showBorderForIncompleteImage) >+ paintIncompleteImageOutline(paintInfo, paintOffset, missingImageBorderWidth); >+ > if (paintInfo.phase == PaintPhaseForeground) > page().addRelevantUnpaintedObject(this, visualOverflowRect()); > return; >@@ -481,6 +500,9 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf > context.clip(contentBoxRect); > > ImageDrawResult result = paintIntoRect(paintInfo, snapRectToDevicePixels(replacedContentRect, deviceScaleFactor)); >+ >+ if (showBorderForIncompleteImage && (result != ImageDrawResult::DidDraw || (cachedImage() && cachedImage()->isLoading()))) >+ paintIncompleteImageOutline(paintInfo, paintOffset, missingImageBorderWidth); > > if (cachedImage() && paintInfo.phase == PaintPhaseForeground) { > // For now, count images as unpainted if they are still progressively loading. We may want >diff --git a/Source/WebCore/rendering/RenderImage.h b/Source/WebCore/rendering/RenderImage.h >index 565431010ca2e98e190b094cdfc854df6b8931f3..8441ea2b4acee3df7af2ec79606605d9fe9317a9 100644 >--- a/Source/WebCore/rendering/RenderImage.h >+++ b/Source/WebCore/rendering/RenderImage.h >@@ -107,6 +107,7 @@ private: > bool isRenderImage() const final { return true; } > > void paintReplaced(PaintInfo&, const LayoutPoint&) override; >+ void paintIncompleteImageOutline(PaintInfo&, const LayoutPoint&, const LayoutUnit&) const; > > bool computeBackgroundIsKnownToBeObscured(const LayoutPoint& paintOffset) final; > >diff --git a/Source/WebCore/testing/InternalSettings.cpp b/Source/WebCore/testing/InternalSettings.cpp >index 24e4aaebe3746e0204cb3e7f0affc71e27b54038..3f8fc860c799b023de8c8ec69b44d2da130d1b2d 100644 >--- a/Source/WebCore/testing/InternalSettings.cpp >+++ b/Source/WebCore/testing/InternalSettings.cpp >@@ -93,6 +93,7 @@ InternalSettings::Backup::Backup(Settings& settings) > , m_inlineMediaPlaybackRequiresPlaysInlineAttribute(settings.inlineMediaPlaybackRequiresPlaysInlineAttribute()) > , m_deferredCSSParserEnabled(settings.deferredCSSParserEnabled()) > , m_inputEventsEnabled(settings.inputEventsEnabled()) >+ , m_incompleteImageBorderEnabled(settings.incompleteImageBorderEnabled()) > #if ENABLE(ACCESSIBILITY_EVENTS) > , m_accessibilityEventsEnabled(settings.accessibilityEventsEnabled()) > #endif >@@ -204,6 +205,7 @@ void InternalSettings::Backup::restoreTo(Settings& settings) > RenderTheme::singleton().setShouldMockBoldSystemFontForAccessibility(m_shouldMockBoldSystemFontForAccessibility); > FontCache::singleton().setShouldMockBoldSystemFontForAccessibility(m_shouldMockBoldSystemFontForAccessibility); > settings.setFrameFlattening(m_frameFlattening); >+ settings.setIncompleteImageBorderEnabled(m_incompleteImageBorderEnabled); > #if ENABLE(ACCESSIBILITY_EVENTS) > settings.setAccessibilityEventsEnabled(m_accessibilityEventsEnabled); > #endif >@@ -902,6 +904,14 @@ ExceptionOr<void> InternalSettings::setAccessibilityEventsEnabled(bool enabled) > return { }; > } > >+ExceptionOr<void> InternalSettings::setIncompleteImageBorderEnabled(bool enabled) >+{ >+ if (!m_page) >+ return Exception { InvalidAccessError }; >+ settings().setIncompleteImageBorderEnabled(enabled); >+ return { }; >+} >+ > static InternalSettings::ForcedAccessibilityValue settingsToInternalSettingsValue(Settings::ForcedAccessibilityValue value) > { > switch (value) { >diff --git a/Source/WebCore/testing/InternalSettings.h b/Source/WebCore/testing/InternalSettings.h >index 9a48f156c414442ab4fa9b4357e71fe3fb724b72..6707fe6aa192fb8745a2a7d83564480362728a37 100644 >--- a/Source/WebCore/testing/InternalSettings.h >+++ b/Source/WebCore/testing/InternalSettings.h >@@ -101,6 +101,7 @@ public: > ExceptionOr<void> setShouldManageAudioSessionCategory(bool); > ExceptionOr<void> setCustomPasteboardDataEnabled(bool); > ExceptionOr<void> setAccessibilityEventsEnabled(bool); >+ ExceptionOr<void> setIncompleteImageBorderEnabled(bool); > > using FrameFlatteningValue = FrameFlattening; > ExceptionOr<void> setFrameFlattening(FrameFlatteningValue); >@@ -192,6 +193,7 @@ private: > bool m_inlineMediaPlaybackRequiresPlaysInlineAttribute; > bool m_deferredCSSParserEnabled; > bool m_inputEventsEnabled; >+ bool m_incompleteImageBorderEnabled; > #if ENABLE(ACCESSIBILITY_EVENTS) > bool m_accessibilityEventsEnabled; > #endif >diff --git a/Source/WebCore/testing/InternalSettings.idl b/Source/WebCore/testing/InternalSettings.idl >index ab6157f5cf8eb6617c317239d8a7a9e644c03846..d16986e8c28d9df332369ec3e1ad6d20197883f1 100644 >--- a/Source/WebCore/testing/InternalSettings.idl >+++ b/Source/WebCore/testing/InternalSettings.idl >@@ -85,6 +85,7 @@ enum FontLoadTimingOverride { "Block", "Swap", "Failure" }; > [MayThrowException] void setAllowsInlineMediaPlaybackAfterFullscreen(boolean allows); > [MayThrowException] void setInlineMediaPlaybackRequiresPlaysInlineAttribute(boolean requires); > [MayThrowException] void setFrameFlattening(FrameFlatteningValue frameFlattening); >+ [MayThrowException] void setIncompleteImageBorderEnabled(boolean enabled); > > // RuntimeEnabledFeatures. > void setIndexedDBWorkersEnabled(boolean enabled); >diff --git a/Source/WebKit/Shared/WebPreferences.yaml b/Source/WebKit/Shared/WebPreferences.yaml >index d370f59a76d502338af021f5505e1496f9d0bd2e..542a45c17a78f97e0454e610ce5308dab3a4c301 100644 >--- a/Source/WebKit/Shared/WebPreferences.yaml >+++ b/Source/WebKit/Shared/WebPreferences.yaml >@@ -1303,3 +1303,7 @@ DisabledAdaptationsMetaTagEnabled: > ColorFilterEnabled: > type: bool > defaultValue: false >+ >+IncompleteImageBorderEnabled: >+ type: bool >+ defaultValue: false >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >index 5fc0bc5a73af08d6188b1618cae1c79f5eddf42f..7967abd98d729c055f522bb651f8570c578230dc 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm >@@ -1255,6 +1255,16 @@ - (BOOL)_shouldEnableTextAutosizingBoost > #endif > } > >+- (void)_setIncompleteImageBorderEnabled:(BOOL)incompleteImageBorderEnabled >+{ >+ _preferences->setIncompleteImageBorderEnabled(incompleteImageBorderEnabled); >+} >+ >+- (BOOL)_incompleteImageBorderEnabled >+{ >+ return _preferences->incompleteImageBorderEnabled(); >+} >+ > @end > > #endif // WK_API_ENABLED >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h >index c005fcbc27f340c1f7c9be23e9e1af1369fa2b08..6d64185d7a8c71f7944468667e72c1492f60b7eb 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h >@@ -138,6 +138,8 @@ typedef NS_ENUM(NSInteger, _WKEditableLinkBehavior) { > > @property (nonatomic, setter=_setStorageAccessPromptsEnabled:) BOOL _storageAccessPromptsEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); > >+@property (nonatomic, setter=_setIncompleteImageBorderEnabled:) BOOL _incompleteImageBorderEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); >+ > #if !TARGET_OS_IPHONE > @property (nonatomic, setter=_setWebGLEnabled:) BOOL _webGLEnabled WK_API_AVAILABLE(macosx(10.13.4)); > @property (nonatomic, setter=_setJavaEnabledForLocalFiles:) BOOL _javaEnabledForLocalFiles WK_API_AVAILABLE(macosx(10.13.4)); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 5e064113bb7bf6b97da9162e70f1d8fa789f61e5..33f90cf813f0d82513e72664bf987803b13ad404 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2018-06-13 Tim Horton <timothy_horton@apple.com> >+ >+ Make it possible to add a border around loading or failed-to-load images >+ https://bugs.webkit.org/show_bug.cgi?id=186614 >+ <rdar://problem/39050152> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * http/tests/images/loading-image-border-expected.html: Added. >+ * http/tests/images/loading-image-border.html: Added. >+ * http/tests/images/loading-image-no-border-expected.html: Added. >+ * http/tests/images/loading-image-no-border.html: Added. >+ * platform/wk2/TestExpectations: >+ Add a test ensuring that the setting works correctly. >+ These and similar tests do not currently work in WebKitTestRunner, so they are skipped there. >+ > 2018-06-19 Per Arne Vollan <pvollan@apple.com> > > Layout Test imported/mozilla/css-animations/test_animation-playstate.html is failing. >diff --git a/LayoutTests/http/tests/images/loading-image-border-expected.html b/LayoutTests/http/tests/images/loading-image-border-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..aa00d3f135b720b66b744bbbbd4f3e65cf6e0b53 >--- /dev/null >+++ b/LayoutTests/http/tests/images/loading-image-border-expected.html >@@ -0,0 +1,6 @@ >+<body> >+ <img src="broken-image.png" width="500px" height="500px"> >+ >+ <!-- Cover up the broken image icon (but not the border) to make this match the not-loaded state --> >+ <div style="width: 100px; height: 100px; position: absolute; top: 200px; left: 200px; background-color: white;"> >+</body> >diff --git a/LayoutTests/http/tests/images/loading-image-border.html b/LayoutTests/http/tests/images/loading-image-border.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9f1dd6f0fd68cd1c4a1a6702dcb0b955db0313b2 >--- /dev/null >+++ b/LayoutTests/http/tests/images/loading-image-border.html >@@ -0,0 +1,14 @@ >+<body> >+ <img id="img" width="500px" height="500px"> >+ <script> >+ internals.settings.setIncompleteImageBorderEnabled(true); >+ >+ setTimeout(function () { >+ img.src = "http://127.0.0.1:8000/resources/load-and-stall.php?name=../../../fast/images/resources/green-400x400.png&mimeType=image%2Fpng&stallAt=0&stallFor=100"; >+ >+ testRunner.notifyDone(); >+ }, 0); >+ >+ testRunner.waitUntilDone(); >+ </script> >+</body> >diff --git a/LayoutTests/http/tests/images/loading-image-no-border-expected.html b/LayoutTests/http/tests/images/loading-image-no-border-expected.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 >diff --git a/LayoutTests/http/tests/images/loading-image-no-border.html b/LayoutTests/http/tests/images/loading-image-no-border.html >new file mode 100644 >index 0000000000000000000000000000000000000000..cec54944b31b5350f0c4ea6f15fff01183cff41e >--- /dev/null >+++ b/LayoutTests/http/tests/images/loading-image-no-border.html >@@ -0,0 +1,14 @@ >+<body> >+ <img id="img" width="500px" height="500px"> >+ <script> >+ internals.settings.setIncompleteImageBorderEnabled(false); >+ >+ setTimeout(function () { >+ img.src = "http://127.0.0.1:8000/resources/load-and-stall.php?name=../../../fast/images/resources/green-400x400.png&mimeType=image%2Fpng&stallAt=0&stallFor=100"; >+ >+ testRunner.notifyDone(); >+ }, 0); >+ >+ testRunner.waitUntilDone(); >+ </script> >+</body> >diff --git a/LayoutTests/platform/wk2/TestExpectations b/LayoutTests/platform/wk2/TestExpectations >index b87ddb0ae5c41b72f81667401ebca91aaf283ae4..117a2fffd5b368363e19d724ea56ab1d52ed4771 100644 >--- a/LayoutTests/platform/wk2/TestExpectations >+++ b/LayoutTests/platform/wk2/TestExpectations >@@ -199,6 +199,11 @@ http/tests/download/default-encoding.html > http/tests/download/inherited-encoding-form-submission-result.html > http/tests/download/inherited-encoding.html > >+# Incomplete-image tests fail in WebKitTestRunner >+# https://bugs.webkit.org/show_bug.cgi?id=186613 >+http/tests/images/loading-image-border.html >+http/tests/images/loading-image-no-border.html >+ > ### END OF (1) Classified failures with bug reports > ######################################## >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186614
:
342717
|
342718
|
342719
|
342771
|
343218
|
343222
|
343223
|
343237
|
343361
|
343392