HTMLStyleElement.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/dom/HTMLStyleElement.h"
  6. #include "mozilla/dom/HTMLStyleElementBinding.h"
  7. #include "nsGkAtoms.h"
  8. #include "nsStyleConsts.h"
  9. #include "nsIDOMStyleSheet.h"
  10. #include "nsIDocument.h"
  11. #include "nsUnicharUtils.h"
  12. #include "nsThreadUtils.h"
  13. #include "nsContentUtils.h"
  14. #include "nsStubMutationObserver.h"
  15. NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
  16. namespace mozilla {
  17. namespace dom {
  18. HTMLStyleElement::HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
  19. : nsGenericHTMLElement(aNodeInfo)
  20. {
  21. AddMutationObserver(this);
  22. }
  23. HTMLStyleElement::~HTMLStyleElement()
  24. {
  25. }
  26. NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLStyleElement)
  27. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLStyleElement,
  28. nsGenericHTMLElement)
  29. tmp->nsStyleLinkElement::Traverse(cb);
  30. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  31. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLStyleElement,
  32. nsGenericHTMLElement)
  33. tmp->nsStyleLinkElement::Unlink();
  34. NS_IMPL_CYCLE_COLLECTION_UNLINK_END
  35. NS_IMPL_ADDREF_INHERITED(HTMLStyleElement, Element)
  36. NS_IMPL_RELEASE_INHERITED(HTMLStyleElement, Element)
  37. // QueryInterface implementation for HTMLStyleElement
  38. NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLStyleElement)
  39. NS_INTERFACE_TABLE_INHERITED(HTMLStyleElement,
  40. nsIDOMHTMLStyleElement,
  41. nsIStyleSheetLinkingElement,
  42. nsIMutationObserver)
  43. NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
  44. NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
  45. NS_IMETHODIMP
  46. HTMLStyleElement::GetMozDisabled(bool* aDisabled)
  47. {
  48. NS_ENSURE_ARG_POINTER(aDisabled);
  49. *aDisabled = Disabled();
  50. return NS_OK;
  51. }
  52. bool
  53. HTMLStyleElement::Disabled() const
  54. {
  55. StyleSheet* ss = GetSheet();
  56. return ss && ss->Disabled();
  57. }
  58. NS_IMETHODIMP
  59. HTMLStyleElement::SetMozDisabled(bool aDisabled)
  60. {
  61. SetDisabled(aDisabled);
  62. return NS_OK;
  63. }
  64. void
  65. HTMLStyleElement::SetDisabled(bool aDisabled)
  66. {
  67. if (StyleSheet* ss = GetSheet()) {
  68. ss->SetDisabled(aDisabled);
  69. }
  70. }
  71. NS_IMPL_STRING_ATTR(HTMLStyleElement, Media, media)
  72. NS_IMPL_BOOL_ATTR(HTMLStyleElement, Scoped, scoped)
  73. NS_IMPL_STRING_ATTR(HTMLStyleElement, Type, type)
  74. void
  75. HTMLStyleElement::CharacterDataChanged(nsIDocument* aDocument,
  76. nsIContent* aContent,
  77. CharacterDataChangeInfo* aInfo)
  78. {
  79. ContentChanged(aContent);
  80. }
  81. void
  82. HTMLStyleElement::ContentAppended(nsIDocument* aDocument,
  83. nsIContent* aContainer,
  84. nsIContent* aFirstNewContent,
  85. int32_t aNewIndexInContainer)
  86. {
  87. ContentChanged(aContainer);
  88. }
  89. void
  90. HTMLStyleElement::ContentInserted(nsIDocument* aDocument,
  91. nsIContent* aContainer,
  92. nsIContent* aChild,
  93. int32_t aIndexInContainer)
  94. {
  95. ContentChanged(aChild);
  96. }
  97. void
  98. HTMLStyleElement::ContentRemoved(nsIDocument* aDocument,
  99. nsIContent* aContainer,
  100. nsIContent* aChild,
  101. int32_t aIndexInContainer,
  102. nsIContent* aPreviousSibling)
  103. {
  104. ContentChanged(aChild);
  105. }
  106. void
  107. HTMLStyleElement::ContentChanged(nsIContent* aContent)
  108. {
  109. if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
  110. UpdateStyleSheetInternal(nullptr, nullptr);
  111. }
  112. }
  113. nsresult
  114. HTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
  115. nsIContent* aBindingParent,
  116. bool aCompileEventHandlers)
  117. {
  118. nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
  119. aBindingParent,
  120. aCompileEventHandlers);
  121. NS_ENSURE_SUCCESS(rv, rv);
  122. void (HTMLStyleElement::*update)() = &HTMLStyleElement::UpdateStyleSheetInternal;
  123. nsContentUtils::AddScriptRunner(NewRunnableMethod(this, update));
  124. return rv;
  125. }
  126. void
  127. HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
  128. {
  129. nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
  130. ShadowRoot* oldShadow = GetContainingShadow();
  131. nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
  132. if (oldShadow && GetContainingShadow()) {
  133. // The style is in a shadow tree and is still in the
  134. // shadow tree. Thus the sheets in the shadow DOM
  135. // do not need to be updated.
  136. return;
  137. }
  138. UpdateStyleSheetInternal(oldDoc, oldShadow);
  139. }
  140. nsresult
  141. HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
  142. const nsAttrValue* aValue,
  143. const nsAttrValue* aOldValue, bool aNotify)
  144. {
  145. if (aNameSpaceID == kNameSpaceID_None) {
  146. if (aName == nsGkAtoms::title ||
  147. aName == nsGkAtoms::media ||
  148. aName == nsGkAtoms::type) {
  149. UpdateStyleSheetInternal(nullptr, nullptr, true);
  150. } else if (aName == nsGkAtoms::scoped) {
  151. bool isScoped = aValue;
  152. UpdateStyleSheetScopedness(isScoped);
  153. }
  154. }
  155. return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
  156. aOldValue, aNotify);
  157. }
  158. NS_IMETHODIMP
  159. HTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML)
  160. {
  161. if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML, fallible)) {
  162. return NS_ERROR_OUT_OF_MEMORY;
  163. }
  164. return NS_OK;
  165. }
  166. void
  167. HTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML,
  168. ErrorResult& aError)
  169. {
  170. SetEnableUpdates(false);
  171. aError = nsContentUtils::SetNodeTextContent(this, aInnerHTML, true);
  172. SetEnableUpdates(true);
  173. UpdateStyleSheetInternal(nullptr, nullptr);
  174. }
  175. already_AddRefed<nsIURI>
  176. HTMLStyleElement::GetStyleSheetURL(bool* aIsInline)
  177. {
  178. *aIsInline = true;
  179. return nullptr;
  180. }
  181. void
  182. HTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
  183. nsAString& aType,
  184. nsAString& aMedia,
  185. bool* aIsScoped,
  186. bool* aIsAlternate,
  187. bool* aIsExplicitlyEnabled)
  188. {
  189. aTitle.Truncate();
  190. aType.Truncate();
  191. aMedia.Truncate();
  192. *aIsAlternate = false;
  193. *aIsExplicitlyEnabled = false;
  194. nsAutoString title;
  195. GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
  196. title.CompressWhitespace();
  197. aTitle.Assign(title);
  198. GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
  199. // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
  200. // that media queries should be ASCII lowercased during serialization.
  201. nsContentUtils::ASCIIToLower(aMedia);
  202. GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
  203. *aIsScoped = HasAttr(kNameSpaceID_None, nsGkAtoms::scoped);
  204. nsAutoString mimeType;
  205. nsAutoString notUsed;
  206. nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
  207. if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
  208. return;
  209. }
  210. // If we get here we assume that we're loading a css file, so set the
  211. // type to 'text/css'
  212. aType.AssignLiteral("text/css");
  213. }
  214. JSObject*
  215. HTMLStyleElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
  216. {
  217. return HTMLStyleElementBinding::Wrap(aCx, this, aGivenProto);
  218. }
  219. } // namespace dom
  220. } // namespace mozilla