Bug 1013936, part 2 - Only load the html.css UA style sheet on-demand for SVG documents. r=bz CLOSED TREE
authorJonathan Watt <jwatt@jwatt.org>
Sat, 24 May 2014 20:29:11 +0100
changeset 184822 feff69cd698fec5e1fcc8fe7ed9418b13c98446f
parent 184821 027f3c05a629b613a9e88dcbb788ae34bfc9c688
child 184823 7dca8bddf9977934c415a77c8a6b936541311db9
push id43944
push userjwatt@jwatt.org
push dateSat, 24 May 2014 20:09:12 +0000
treeherdermozilla-inbound@feff69cd698f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1013936
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1013936, part 2 - Only load the html.css UA style sheet on-demand for SVG documents. r=bz CLOSED TREE
content/base/public/nsIDocument.h
content/base/src/nsDocument.cpp
content/svg/content/src/SVGForeignObjectElement.cpp
content/svg/content/src/SVGForeignObjectElement.h
content/svg/document/src/SVGDocument.cpp
content/svg/document/src/SVGDocument.h
layout/base/nsDocumentViewer.cpp
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
layout/style/nsStyleSet.cpp
layout/style/ua.css
layout/svg/svg.css
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -111,16 +111,17 @@ class OverfillCallback;
 class HTMLBodyElement;
 struct LifecycleCallbackArgs;
 class Link;
 class GlobalObject;
 class NodeFilter;
 class NodeIterator;
 class ProcessingInstruction;
 class StyleSheetList;
+class SVGDocument;
 class Touch;
 class TouchList;
 class TreeWalker;
 class UndoManager;
 class XPathEvaluator;
 template<typename> class OwningNonNull;
 template<typename> class Sequence;
 
@@ -2284,16 +2285,17 @@ public:
 
   void ObsoleteSheet(const nsAString& aSheetURI, mozilla::ErrorResult& rv);
 
   // ParentNode
   nsIHTMLCollection* Children();
   uint32_t ChildElementCount();
 
   virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
+  virtual mozilla::dom::SVGDocument* AsSVGDocument() { return nullptr; }
 
   virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
 
   // Each import tree has exactly one master document which is
   // the root of the tree, and owns the browser context.
   virtual already_AddRefed<nsIDocument> MasterDocument() = 0;
   virtual void SetMasterDocument(nsIDocument* master) = 0;
   virtual bool IsMasterDocument() = 0;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4000,16 +4000,20 @@ nsDocument::AddOnDemandBuiltInUASheet(ns
   // Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in
   // the same order that they should end up in the style set.
   mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet);
 
   if (aSheet->IsApplicable()) {
     // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
     nsCOMPtr<nsIPresShell> shell = GetShell();
     if (shell) {
+      // Note that prepending here is necessary to make sure that html.css etc.
+      // do not override Firefox OS/Mobile's content.css sheet. Maybe we should
+      // have an insertion point to match the order of
+      // nsDocumentViewer::CreateStyleSet though?
       shell->StyleSet()->PrependStyleSheet(nsStyleSet::eAgentSheet, aSheet);
     }
   }
 
   NotifyStyleSheetAdded(aSheet, false);
 }
 
 int32_t
--- a/content/svg/content/src/SVGForeignObjectElement.cpp
+++ b/content/svg/content/src/SVGForeignObjectElement.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 
 #include "nsCOMPtr.h"
+#include "mozilla/dom/SVGDocument.h"
 #include "mozilla/dom/SVGForeignObjectElement.h"
 #include "mozilla/dom/SVGForeignObjectElementBinding.h"
 
 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(ForeignObject)
 
 namespace mozilla {
 namespace dom {
 
@@ -102,16 +103,41 @@ SVGForeignObjectElement::HasValidDimensi
          mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 &&
          mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() &&
          mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0;
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods
 
+nsresult
+SVGForeignObjectElement::BindToTree(nsIDocument* aDocument,
+                                    nsIContent* aParent,
+                                    nsIContent* aBindingParent,
+                                    bool aCompileEventHandlers)
+{
+  nsresult rv = SVGGraphicsElement::BindToTree(aDocument, aParent,
+                                               aBindingParent,
+                                               aCompileEventHandlers);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (aDocument && aDocument->IsSVG()) {
+    // We assume that we're going to have HTML content, so we ensure that the
+    // UA style sheets that nsDocumentViewer::CreateStyleSet skipped when
+    // it saw the document was an SVG document are loaded.
+    //
+    // We setup these style sheets during binding, not element construction,
+    // because elements can be moved from the document that creates them to
+    // another document.
+    aDocument->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
+  }
+
+  return rv;
+}
+
 NS_IMETHODIMP_(bool)
 SVGForeignObjectElement::IsAttributeMapped(const nsIAtom* name) const
 {
   static const MappedAttributeEntry* const map[] = {
     sFEFloodMap,
     sFiltersMap,
     sFontSpecificationMap,
     sGradientStopMap,
--- a/content/svg/content/src/SVGForeignObjectElement.h
+++ b/content/svg/content/src/SVGForeignObjectElement.h
@@ -29,16 +29,19 @@ protected:
 
 public:
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
   virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsIContent interface
+  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                              nsIContent* aBindingParent,
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
--- a/content/svg/document/src/SVGDocument.cpp
+++ b/content/svg/document/src/SVGDocument.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGDocument.h"
+#include "nsLayoutStylesheetCache.h"
 #include "nsString.h"
 #include "nsLiteralString.h"
 #include "nsIDOMSVGElement.h"
 #include "mozilla/dom/Element.h"
 #include "nsSVGElement.h"
 #include "mozilla/dom/SVGDocumentBinding.h"
 
 using namespace mozilla::dom;
@@ -63,16 +64,31 @@ SVGDocument::Clone(nsINodeInfo *aNodeInf
 
   nsRefPtr<SVGDocument> clone = new SVGDocument();
   nsresult rv = CloneDocHelper(clone.get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(clone.get(), aResult);
 }
 
+void
+SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded()
+{
+  if (mHasLoadedNonSVGUserAgentStyleSheets) {
+    return;
+  }
+
+  mHasLoadedNonSVGUserAgentStyleSheets = true;
+
+  EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::NumberControlSheet());
+  EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::FormsSheet());
+  EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::HTMLSheet());
+  EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::UASheet());
+}
+
 JSObject*
 SVGDocument::WrapNode(JSContext *aCx)
 {
   return SVGDocumentBinding::Wrap(aCx, this);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/document/src/SVGDocument.h
+++ b/content/svg/document/src/SVGDocument.h
@@ -9,31 +9,44 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/XMLDocument.h"
 
 class nsSVGElement;
 
 namespace mozilla {
 namespace dom {
 
+class SVGForeignObjectElement;
+
 class SVGDocument MOZ_FINAL : public XMLDocument
 {
+  friend class SVGForeignObjectElement; // To call EnsureNonSVGUserAgentStyleSheetsLoaded
+
 public:
   SVGDocument()
     : XMLDocument("image/svg+xml")
+    , mHasLoadedNonSVGUserAgentStyleSheets(false)
   {
     mType = eSVG;
   }
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL API
   void GetDomain(nsAString& aDomain, ErrorResult& aRv);
   nsSVGElement* GetRootElement(ErrorResult& aRv);
 
-protected:
+  virtual SVGDocument* AsSVGDocument() MOZ_OVERRIDE {
+    return this;
+  }
+
+private:
+  void EnsureNonSVGUserAgentStyleSheetsLoaded();
+
   virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+
+  bool mHasLoadedNonSVGUserAgentStyleSheets;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGDocument_h
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2245,62 +2245,87 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
 
   if (!shouldOverride) {
     sheet = nsLayoutStylesheetCache::ScrollbarsSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
 
-  sheet = nsLayoutStylesheetCache::NumberControlSheet();
-  if (sheet) {
-    styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
-  }
-
-  sheet = nsLayoutStylesheetCache::FormsSheet();
-  if (sheet) {
-    styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
-  }
-
   sheet = nsLayoutStylesheetCache::FullScreenOverrideSheet();
   if (sheet) {
     styleSet->PrependStyleSheet(nsStyleSet::eOverrideSheet, sheet);
   }
 
-  // Make sure to clone the quirk sheet so that it can be usefully
-  // enabled/disabled as needed.
-  nsRefPtr<nsCSSStyleSheet> quirkClone;
-  nsCSSStyleSheet* quirkSheet;
-  if (!nsLayoutStylesheetCache::UASheet() ||
-      !(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
-      !(quirkClone = quirkSheet->Clone(nullptr, nullptr, nullptr, nullptr)) ||
-      !sheet) {
-    delete styleSet;
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  // quirk.css needs to come after the regular UA sheet (or more precisely,
-  // after the html.css and so forth that the UA sheet imports).
-  styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
-  styleSet->SetQuirkStyleSheet(quirkClone);
-  if (aDocument->LoadsFullXULStyleSheetUpFront()) {
-    // nsXULElement::BindToTree loads xul.css on-demand if we don't load it
-    // up-front here.
-    sheet = nsLayoutStylesheetCache::XULSheet();
+  if (!aDocument->IsSVG()) {
+    // !!! IMPORTANT - KEEP THIS BLOCK IN SYNC WITH
+    // !!! SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded.
+
+    // SVGForeignObjectElement::BindToTree calls SVGDocument::
+    // EnsureNonSVGUserAgentStyleSheetsLoaded to loads these UA sheet
+    // on-demand. (Excluding the quirks sheet, which should never be loaded for
+    // an SVG document, and excluding xul.css which will be loaded on demand by
+    // nsXULElement::BindToTree.)
+
+    sheet = nsLayoutStylesheetCache::NumberControlSheet();
+    if (sheet) {
+      styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+    }
+
+    sheet = nsLayoutStylesheetCache::FormsSheet();
+    if (sheet) {
+      styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+    }
+
+    // Make sure to clone the quirk sheet so that it can be usefully
+    // enabled/disabled as needed.
+    nsRefPtr<nsCSSStyleSheet> quirkClone;
+    nsCSSStyleSheet* quirkSheet;
+    if (!nsLayoutStylesheetCache::UASheet() ||
+        !(quirkSheet = nsLayoutStylesheetCache::QuirkSheet()) ||
+        !(quirkClone = quirkSheet->Clone(nullptr, nullptr, nullptr, nullptr)) ||
+        !sheet) {
+      delete styleSet;
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+    // quirk.css needs to come after the regular UA sheet (or more precisely,
+    // after the html.css and so forth that the UA sheet imports).
+    styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, quirkClone);
+    styleSet->SetQuirkStyleSheet(quirkClone);
+
+    if (aDocument->LoadsFullXULStyleSheetUpFront()) {
+      // nsXULElement::BindToTree loads xul.css on-demand if we don't load it
+      // up-front here.
+      sheet = nsLayoutStylesheetCache::XULSheet();
+      if (sheet) {
+        styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+      }
+    }
+
+    sheet = nsLayoutStylesheetCache::MinimalXULSheet();
+    if (sheet) {
+      // Load the minimal XUL rules for scrollbars and a few other XUL things
+      // that non-XUL (typically HTML) documents commonly use.
+      styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+    }
+
+    sheet = nsLayoutStylesheetCache::HTMLSheet();
+    if (sheet) {
+      styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
+    }
+
+    styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
+                                nsLayoutStylesheetCache::UASheet());
+  } else {
+    // SVG documents may have scrollbars and need the scrollbar styling.
+    sheet = nsLayoutStylesheetCache::MinimalXULSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
-  sheet = nsLayoutStylesheetCache::MinimalXULSheet();
-  if (sheet) {
-    // Load the minimal XUL rules for scrollbars and a few other XUL things
-    // that non-XUL (typically HTML) documents commonly use.
-    styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, sheet);
-  }
-  styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet,
-                              nsLayoutStylesheetCache::UASheet());
 
   nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
   if (sheetService) {
     sheetService->AgentStyleSheets()->EnumerateForwards(AppendAgentSheet,
                                                         styleSet);
     sheetService->UserStyleSheets()->EnumerateBackwards(PrependUserSheet,
                                                         styleSet);
   }
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -144,16 +144,26 @@ nsLayoutStylesheetCache::UASheet()
   EnsureGlobal();
   if (!gStyleCache)
     return nullptr;
 
   return gStyleCache->mUASheet;
 }
 
 nsCSSStyleSheet*
+nsLayoutStylesheetCache::HTMLSheet()
+{
+  EnsureGlobal();
+  if (!gStyleCache)
+    return nullptr;
+
+  return gStyleCache->mHTMLSheet;
+}
+
+nsCSSStyleSheet*
 nsLayoutStylesheetCache::MinimalXULSheet()
 {
   EnsureGlobal();
   if (!gStyleCache)
     return nullptr;
 
   return gStyleCache->mMinimalXULSheet;
 }
@@ -245,16 +255,17 @@ nsLayoutStylesheetCache::SizeOfIncluding
   #define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
 
   MEASURE(mScrollbarsSheet);
   MEASURE(mFormsSheet);
   MEASURE(mNumberControlSheet);
   MEASURE(mUserContentSheet);
   MEASURE(mUserChromeSheet);
   MEASURE(mUASheet);
+  MEASURE(mHTMLSheet);
   MEASURE(mMinimalXULSheet);
   MEASURE(mXULSheet);
   MEASURE(mQuirkSheet);
   MEASURE(mFullScreenOverrideSheet);
   MEASURE(mSVGSheet);
   if (mMathMLSheet) {
     MEASURE(mMathMLSheet);
   }
@@ -285,16 +296,22 @@ nsLayoutStylesheetCache::nsLayoutStylesh
   // per-profile, since they're profile-invariant.
   nsCOMPtr<nsIURI> uri;
   NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/ua.css");
   if (uri) {
     LoadSheet(uri, mUASheet, true);
   }
   NS_ASSERTION(mUASheet, "Could not load ua.css");
 
+  NS_NewURI(getter_AddRefs(uri), "resource://gre-resources/html.css");
+  if (uri) {
+    LoadSheet(uri, mHTMLSheet, true);
+  }
+  NS_ASSERTION(mHTMLSheet, "Could not load xul.css");
+
   NS_NewURI(getter_AddRefs(uri), "chrome://global/content/minimal-xul.css");
   if (uri) {
     LoadSheet(uri, mMinimalXULSheet, true);
   }
   NS_ASSERTION(mMinimalXULSheet, "Could not load minimal-xul.css");
 
   NS_NewURI(getter_AddRefs(uri), "chrome://global/content/xul.css");
   if (uri) {
--- a/layout/style/nsLayoutStylesheetCache.h
+++ b/layout/style/nsLayoutStylesheetCache.h
@@ -34,16 +34,17 @@ class nsLayoutStylesheetCache MOZ_FINAL
   static nsCSSStyleSheet* ScrollbarsSheet();
   static nsCSSStyleSheet* FormsSheet();
   // This function is expected to return nullptr when the dom.forms.number
   // pref is disabled.
   static nsCSSStyleSheet* NumberControlSheet();
   static nsCSSStyleSheet* UserContentSheet();
   static nsCSSStyleSheet* UserChromeSheet();
   static nsCSSStyleSheet* UASheet();
+  static nsCSSStyleSheet* HTMLSheet();
   static nsCSSStyleSheet* MinimalXULSheet();
   static nsCSSStyleSheet* XULSheet();
   static nsCSSStyleSheet* QuirkSheet();
   static nsCSSStyleSheet* FullScreenOverrideSheet();
   static nsCSSStyleSheet* SVGSheet();
   static nsCSSStyleSheet* MathMLSheet();
 
   static void Shutdown();
@@ -64,16 +65,17 @@ private:
   static nsLayoutStylesheetCache* gStyleCache;
   static mozilla::css::Loader* gCSSLoader;
   nsRefPtr<nsCSSStyleSheet> mScrollbarsSheet;
   nsRefPtr<nsCSSStyleSheet> mFormsSheet;
   nsRefPtr<nsCSSStyleSheet> mNumberControlSheet;
   nsRefPtr<nsCSSStyleSheet> mUserContentSheet;
   nsRefPtr<nsCSSStyleSheet> mUserChromeSheet;
   nsRefPtr<nsCSSStyleSheet> mUASheet;
+  nsRefPtr<nsCSSStyleSheet> mHTMLSheet;
   nsRefPtr<nsCSSStyleSheet> mMinimalXULSheet;
   nsRefPtr<nsCSSStyleSheet> mXULSheet;
   nsRefPtr<nsCSSStyleSheet> mQuirkSheet;
   nsRefPtr<nsCSSStyleSheet> mFullScreenOverrideSheet;
   nsRefPtr<nsCSSStyleSheet> mSVGSheet;
   nsRefPtr<nsCSSStyleSheet> mMathMLSheet;
 };
 
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -627,16 +627,20 @@ nsStyleSet::EndUpdate()
 
   mDirty = 0;
   return NS_OK;
 }
 
 void
 nsStyleSet::EnableQuirkStyleSheet(bool aEnable)
 {
+  if (!mQuirkStyleSheet) {
+    // SVG-as-an-image doesn't load this sheet
+    return;
+  }
 #ifdef DEBUG
   bool oldEnabled;
   {
     nsCOMPtr<nsIDOMCSSStyleSheet> domSheet =
       do_QueryInterface(mQuirkStyleSheet);
     domSheet->GetDisabled(&oldEnabled);
     oldEnabled = !oldEnabled;
   }
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -1,14 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-@import url(resource://gre-resources/html.css);
-
 @namespace parsererror url(http://www.mozilla.org/newlayout/xml/parsererror.xml);
 @namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
 
 /* magic -- some of these rules are important to keep pages from overriding
             them
 */
 
 /* Tables */
--- a/layout/svg/svg.css
+++ b/layout/svg/svg.css
@@ -69,8 +69,16 @@ foreignObject {
 }
 
 *|*::-moz-svg-marker-anon-child {
   clip-path: inherit;
   filter: inherit;
   mask: inherit;
   opacity: inherit;
 }
+
+/* nsDocumentViewer::CreateStyleSet doesn't load ua.css for SVG-as-an-image,
+ * but SVG-as-an-image needs this rule from that file.
+ */
+*|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas, *|*::-moz-scrolled-canvas {
+  display: block !important;
+  background-color: inherit;
+}