Permalink
Browse files

Change the conversion code to iterative solution.

  • Loading branch information...
RickEyre committed May 15, 2013
1 parent b1eb949 commit 1344e315e74cf89528d53fef74b9257684b97a70
Showing with 131 additions and 101 deletions.
  1. +123 −97 content/media/TextTrackCue.cpp
  2. +8 −4 content/media/TextTrackCue.h
@@ -9,6 +9,7 @@
#include "nsIFrame.h"
#include "nsVideoFrame.h"
#include "webvtt/string.h"
+#include "nsTArray.h"
namespace mozilla {
namespace dom {
@@ -131,120 +132,147 @@ TextTrackCue::GetCueAsHTML()
return nullptr;
}
- for (webvtt_uint i = 0; i < mHead->data.internal_data->length; i++) {
- nsCOMPtr<nsIContent> cueTextContent = ConvertNodeToCueTextContent(
- mHead->data.internal_data->children[i]);
- if (!cueTextContent) {
- return nullptr;
+ ConvertNodeTreeToDOMTree(frag);
+
+ return frag.forget();
+}
+
+void
+TextTrackCue::ConvertNodeTreeToDOMTree(nsIContent *parentContent)
+{
+ nsTArray<webvtt_node *> nodeStack;
+ nsTArray<webvtt_node *> parentStack;
+
+ nodeStack.AppendElement(mHead);
+
+ webvtt_node *node;
+ while (nodeStack.Length() > 0) {
+ node = nodeStack[nodeStack.Length() - 1];
+ nodeStack.RemoveElementAt(nodeStack.Length() - 1);
+ nsCOMPtr<nsIContent> content;
+ if (WEBVTT_IS_VALID_LEAF_NODE(node->kind)) {
+ content = ConvertLeafNodeToContent(node);
+ } else if (WEBVTT_IS_VALID_INTERNAL_NODE(node->kind)) {
+ content = ConvertInternalNodeToContent(node);
+
+ uint16_t childCount = node->data.internal_data->length;
+ if (childCount > 0) {
+ if (nodeStack.Length() > 0) {
+ parentStack.AppendElement(nodeStack[nodeStack.Length() - 1]);
+ }
+ for (uint16_t i = childCount; i > 0; i--) {
+ nodeStack.AppendElement(node->data.internal_data->children[i - 1]);
+ }
+ }
}
- nsCOMPtr<nsINode> contentNode = do_QueryInterface(cueTextContent);
- if (!contentNode) {
- return nullptr;
+ if (content && parentContent) {
+ ErrorResult rv;
+ nsCOMPtr<nsINode> childNode = do_QueryInterface(content);
+ nsCOMPtr<nsINode> parentNode = do_QueryInterface(parentContent);
+ if (childNode && parentNode) {
+ parentNode->AppendChild(*childNode, rv);
+ }
+ if (WEBVTT_IS_VALID_INTERNAL_NODE(node->kind) &&
+ node->data.internal_data->length > 0) {
+ parentContent = content;
+ }
}
- nsINode *fragNode = frag;
- fragNode->AppendChild(*contentNode, rv);
+ uint32_t nodeLen = nodeStack.Length();
+ uint32_t parentLen = parentStack.Length();
+ if (nodeLen > 0 && parentLen > 0 &&
+ parentStack[parentLen - 1] == nodeStack[nodeLen - 1]) {
+ parentStack.RemoveElementAt(parentStack.Length() - 1);
+ nsCOMPtr<nsIContent> temp = parentContent->GetParent();
+ if (temp) {
+ parentContent = temp;
+ }
+ }
}
-
- return frag.forget();
}
-// TODO: Change to iterative solution instead of recursive
nsCOMPtr<nsIContent>
-TextTrackCue::ConvertNodeToCueTextContent(const webvtt_node *aWebVTTNode)
+TextTrackCue::ConvertInternalNodeToContent( const webvtt_node *aWebVTTNode )
{
- nsCOMPtr<nsIContent> cueTextContent;
+ nsIAtom *atomName;
+
+ aWebVTTNode->kind;
+ switch (aWebVTTNode->kind) {
+ case WEBVTT_BOLD:
+ atomName = nsGkAtoms::b;
+ break;
+ case WEBVTT_ITALIC:
+ atomName = nsGkAtoms::i;
+ break;
+ case WEBVTT_UNDERLINE:
+ atomName = nsGkAtoms::u;
+ break;
+ case WEBVTT_RUBY:
+ atomName = nsGkAtoms::ruby;
+ break;
+ case WEBVTT_RUBY_TEXT:
+ atomName = nsGkAtoms::rt;
+ break;
+ case WEBVTT_VOICE:
+ {
+ atomName = nsGkAtoms::span;
+ break;
+ case WEBVTT_CLASS:
+ atomName = nsGkAtoms::span;
+ break;
+ }
+ default:
+ return nullptr;
+ break;
+ }
nsNodeInfoManager *nimgr = mTrackElement->NodeInfo()->NodeInfoManager();
+ nsCOMPtr<nsINodeInfo> nodeInfo = nimgr->GetNodeInfo(atomName, nullptr,
+ kNameSpaceID_XHTML,
+ nsIDOMNode::ELEMENT_NODE);
- if (WEBVTT_IS_VALID_INTERNAL_NODE(aWebVTTNode->kind))
- {
- nsIAtom *atomName;
- switch (aWebVTTNode->kind) {
- case WEBVTT_BOLD:
- atomName = nsGkAtoms::b;
- break;
- case WEBVTT_ITALIC:
- atomName = nsGkAtoms::i;
- break;
- case WEBVTT_UNDERLINE:
- atomName = nsGkAtoms::u;
- break;
- case WEBVTT_RUBY:
- atomName = nsGkAtoms::ruby;
- break;
- case WEBVTT_RUBY_TEXT:
- atomName = nsGkAtoms::rt;
- break;
- case WEBVTT_VOICE:
- {
- atomName = nsGkAtoms::span;
- break;
- case WEBVTT_CLASS:
- atomName = nsGkAtoms::span;
- break;
- }
- default:
- return nullptr;
- break;
- }
- nsCOMPtr<nsINodeInfo> nodeInfo =
- nimgr->GetNodeInfo(atomName, nullptr,
- kNameSpaceID_XHTML,
- nsIDOMNode::ELEMENT_NODE);
-
- NS_NewHTMLElement(getter_AddRefs(cueTextContent), nodeInfo.forget(),
- mozilla::dom::NOT_FROM_PARSER);
-
- if (aWebVTTNode->kind == WEBVTT_VOICE) {
- nsCOMPtr<nsGenericHTMLElement> genericHtmlElement =
- do_QueryInterface(cueTextContent);
-
- if (genericHtmlElement) {
- const char* text =
- webvtt_string_text(&aWebVTTNode->data.internal_data->annotation);
- genericHtmlElement->SetTitle(NS_ConvertUTF8toUTF16(text));
- }
- }
+ nsCOMPtr<nsIContent> cueTextContent;
+ NS_NewHTMLElement(getter_AddRefs(cueTextContent), nodeInfo.forget(),
+ mozilla::dom::NOT_FROM_PARSER);
- webvtt_stringlist *classes = aWebVTTNode->data.internal_data->css_classes;
- if (classes && classes->length > 0) {
- nsAutoString classString;
- const char *text;
+ nsCOMPtr<nsGenericHTMLElement> genericHtmlElement;
+ const char *text;
+ if (aWebVTTNode->kind == WEBVTT_VOICE) {
+ genericHtmlElement = do_QueryInterface(cueTextContent);
- text = webvtt_string_text(classes->items);
- classString.Append(NS_ConvertUTF8toUTF16(text));
+ if (genericHtmlElement) {
+ text = webvtt_string_text(&aWebVTTNode->data.internal_data->annotation);
+ genericHtmlElement->SetTitle(NS_ConvertUTF8toUTF16(text));
+ }
+ }
- for (webvtt_uint i = 1; i < classes->length; i++) {
- classString.Append(NS_LITERAL_STRING(" "));
- text = webvtt_string_text(classes->items + i);
- classString.Append(NS_ConvertUTF8toUTF16(text));
- }
+ webvtt_stringlist *classes = aWebVTTNode->data.internal_data->css_classes;
+ if (classes && classes->length > 0) {
+ nsAutoString classString;
- nsCOMPtr<nsGenericHTMLElement> genericHtmlElement =
- do_QueryInterface(cueTextContent);
- if (genericHtmlElement) {
- genericHtmlElement->SetClassName(classString);
- }
- }
+ text = webvtt_string_text(classes->items);
+ classString.Append(NS_ConvertUTF8toUTF16(text));
- ErrorResult rv;
- for (webvtt_uint i = 0; i < aWebVTTNode->data.internal_data->length; i++) {
- nsCOMPtr<nsIContent> childCueTextContent = ConvertNodeToCueTextContent(
- aWebVTTNode->data.internal_data->children[i]);
+ for (uint32_t i = 1; i < classes->length; i++) {
+ classString.Append(NS_LITERAL_STRING("."));
+ text = webvtt_string_text(classes->items + i);
+ classString.Append(NS_ConvertUTF8toUTF16(text));
+ }
- if (childCueTextContent) {
- nsCOMPtr<nsINode> childNode = do_QueryInterface(childCueTextContent);
- nsCOMPtr<nsINode> htmlElement = do_QueryInterface(cueTextContent);
- if (childNode && htmlElement) {
- htmlElement->AppendChild(*childNode, rv);
- }
- }
+ genericHtmlElement = do_QueryInterface(cueTextContent);
+ if (genericHtmlElement) {
+ genericHtmlElement->SetClassName(classString);
}
}
- else if (WEBVTT_IS_VALID_LEAF_NODE(aWebVTTNode->kind))
- {
- switch (aWebVTTNode->kind) {
+ return cueTextContent;
+}
+
+nsCOMPtr<nsIContent>
+TextTrackCue::ConvertLeafNodeToContent( const webvtt_node *aWebVTTNode )
+{
+ nsCOMPtr<nsIContent> cueTextContent;
+ nsNodeInfoManager *nimgr = mTrackElement->NodeInfo()->NodeInfoManager();
+ switch (aWebVTTNode->kind) {
case WEBVTT_TEXT:
{
NS_NewTextNode(getter_AddRefs(cueTextContent), nimgr);
@@ -270,9 +298,7 @@ TextTrackCue::ConvertNodeToCueTextContent(const webvtt_node *aWebVTTNode)
default:
return nullptr;
break;
- }
}
-
return cueTextContent;
}
@@ -268,12 +268,16 @@ class TextTrackCue MOZ_FINAL : public nsDOMEventTargetHelper
already_AddRefed<DocumentFragment> GetCueAsHTML();
/**
- * Converts aWebVTTNode to the appropriate anonymous DOM object.
- *
- * Returns the anonymous content that was constructed based on aWebVTTNode.
+ * Converts mHead to a list of DOM elements and attaches it to aParentContent.
*/
+ void
+ ConvertNodeTreeToDOMTree(nsIContent *aParentContent);
+
+ nsCOMPtr<nsIContent>
+ ConvertInternalNodeToContent( const webvtt_node *aWebVTTNode );
+
nsCOMPtr<nsIContent>
- ConvertNodeToCueTextContent(const webvtt_node *aWebVTTNode);
+ ConvertLeafNodeToContent( const webvtt_node *aWebVTTNode );
IMPL_EVENT_HANDLER(enter)
IMPL_EVENT_HANDLER(exit)

0 comments on commit 1344e31

Please sign in to comment.