Example #1
0
Style StyleProvider::forElement(const Element& element, int levelOfDetails) const
{
    StyleBuilder builder(element.tags, pimpl_->stringTable, pimpl_->filters, levelOfDetails);
    element.accept(builder);
    return std::move(builder.build());
}
Example #2
0
void
DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time)
{
  Element* root = nullptr;
  nsIFrame* rootFrame = nullptr;
  nsRect rootRect;

  if (mRoot) {
    root = mRoot;
    rootFrame = root->GetPrimaryFrame();
    if (rootFrame) {
      if (rootFrame->GetType() == nsGkAtoms::scrollFrame) {
        nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
        rootRect = nsLayoutUtils::TransformFrameRectToAncestor(
          rootFrame,
          rootFrame->GetContentRectRelativeToSelf(),
          scrollFrame->GetScrolledFrame());
      } else {
        rootRect = nsLayoutUtils::GetAllInFlowRectsUnion(rootFrame,
          nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
      }
    }
  } else {
    nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
    if (presShell) {
      rootFrame = presShell->GetRootScrollFrame();
      if (rootFrame) {
        nsPresContext* presContext = rootFrame->PresContext();
        while (!presContext->IsRootContentDocument()) {
          presContext = presContext->GetParentPresContext();
          if (!presContext) {
            break;
          }
          rootFrame = presContext->PresShell()->GetRootScrollFrame();
        }
        root = rootFrame->GetContent()->AsElement();
        nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
        rootRect = scrollFrame->GetScrollPortRect();
      }
    }
  }

  nsMargin rootMargin;
  NS_FOR_CSS_SIDES(side) {
    nscoord basis = side == eSideTop || side == eSideBottom ?
      rootRect.height : rootRect.width;
    nsCSSValue value = mRootMargin.*nsCSSRect::sides[side];
    nsStyleCoord coord;
    if (value.IsPixelLengthUnit()) {
      coord.SetCoordValue(value.GetPixelLength());
    } else if (value.IsPercentLengthUnit()) {
      coord.SetPercentValue(value.GetPercentValue());
    } else {
      MOZ_ASSERT_UNREACHABLE("invalid length unit");
    }
    rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord);
  }

  for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
    Element* target = iter.Get()->GetKey();
    nsIFrame* targetFrame = target->GetPrimaryFrame();
    nsRect targetRect;
    Maybe<nsRect> intersectionRect;

    if (rootFrame && targetFrame) {
      // If mRoot is set we are testing intersection with a container element
      // instead of the implicit root.
      if (mRoot) {
        // Skip further processing of this target if it is not in the same
        // Document as the intersection root, e.g. if root is an element of
        // the main document and target an element from an embedded iframe.
        if (target->GetComposedDoc() != root->GetComposedDoc()) {
          continue;
        }
        // Skip further processing of this target if is not a descendant of the
        // intersection root in the containing block chain. E.g. this would be
        // the case if the target is in a position:absolute element whose
        // containing block is an ancestor of root.
        if (!nsLayoutUtils::IsAncestorFrameCrossDoc(rootFrame, targetFrame)) {
          continue;
        }
      }

      targetRect = nsLayoutUtils::GetAllInFlowRectsUnion(
        targetFrame,
        nsLayoutUtils::GetContainingBlockForClientRect(targetFrame),
        nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS
      );
      intersectionRect = Some(targetFrame->GetVisualOverflowRect());

      nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame);
      while (containerFrame && containerFrame != rootFrame) {
        if (containerFrame->GetType() == nsGkAtoms::scrollFrame) {
          nsIScrollableFrame* scrollFrame = do_QueryFrame(containerFrame);
          nsRect subFrameRect = scrollFrame->GetScrollPortRect();
          nsRect intersectionRectRelativeToContainer =
            nsLayoutUtils::TransformFrameRectToAncestor(targetFrame,
                                                        intersectionRect.value(),
                                                        containerFrame);
          intersectionRect = EdgeInclusiveIntersection(intersectionRectRelativeToContainer,
                                                       subFrameRect);
          if (!intersectionRect) {
            break;
          }
          targetFrame = containerFrame;
        }

        // TODO: Apply clip-path.

        containerFrame = nsLayoutUtils::GetCrossDocParentFrame(containerFrame);
      }
    }

    nsRect rootIntersectionRect = rootRect;
    bool isInSimilarOriginBrowsingContext = rootFrame && targetFrame &&
                                            CheckSimilarOrigin(root, target);

    if (isInSimilarOriginBrowsingContext) {
      rootIntersectionRect.Inflate(rootMargin);
    }

    if (intersectionRect.isSome()) {
      nsRect intersectionRectRelativeToRoot =
        nsLayoutUtils::TransformFrameRectToAncestor(
          targetFrame,
          intersectionRect.value(),
          nsLayoutUtils::GetContainingBlockForClientRect(rootFrame)
      );
      intersectionRect = EdgeInclusiveIntersection(
        intersectionRectRelativeToRoot,
        rootIntersectionRect
      );
      if (intersectionRect.isSome()) {
        intersectionRect = Some(nsLayoutUtils::TransformFrameRectToAncestor(
          nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
          intersectionRect.value(),
          targetFrame->PresContext()->PresShell()->GetRootScrollFrame()
        ));
      }
    }

    double targetArea = targetRect.width * targetRect.height;
    double intersectionArea = !intersectionRect ?
      0 : intersectionRect->width * intersectionRect->height;
    double intersectionRatio = targetArea > 0.0 ? intersectionArea / targetArea : 0.0;

    size_t threshold = -1;
    if (intersectionRatio > 0.0) {
      if (intersectionRatio >= 1.0) {
        intersectionRatio = 1.0;
        threshold = mThresholds.Length();
      } else {
        for (size_t k = 0; k < mThresholds.Length(); ++k) {
          if (mThresholds[k] <= intersectionRatio) {
            threshold = k + 1;
          } else {
            break;
          }
        }
      }
    } else if (intersectionRect.isSome()) {
      threshold = 0;
    }

    if (target->UpdateIntersectionObservation(this, threshold)) {
      QueueIntersectionObserverEntry(
        target, time,
        isInSimilarOriginBrowsingContext ? Some(rootIntersectionRect) : Nothing(),
        targetRect, intersectionRect, intersectionRatio
      );
    }
  }
}
void FullscreenElementStack::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
{
    // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
    // for full screen mode, and do not have the concept of a full screen element stack.
    bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);

    do {
        if (!element)
            element = document()->documentElement();

        // 1. If any of the following conditions are true, terminate these steps and queue a task to fire
        // an event named fullscreenerror with its bubbles attribute set to true on the context object's
        // node document:

        // The context object is not in a document.
        if (!element->inDocument())
            break;

        // The context object's node document, or an ancestor browsing context's document does not have
        // the fullscreen enabled flag set.
        if (checkType == EnforceIFrameAllowFullScreenRequirement && !fullScreenIsAllowedForElement(element))
            break;

        // The context object's node document fullscreen element stack is not empty and its top element
        // is not an ancestor of the context object. (NOTE: Ignore this requirement if the request was
        // made via the legacy Mozilla-style API.)
        if (!m_fullScreenElementStack.isEmpty() && !inLegacyMozillaMode) {
            Element* lastElementOnStack = m_fullScreenElementStack.last().get();
            if (lastElementOnStack == element || !lastElementOnStack->contains(element))
                break;
        }

        // A descendant browsing context's document has a non-empty fullscreen element stack.
        bool descendentHasNonEmptyStack = false;
        for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
            if (fullscreenElementFrom(descendant->document())) {
                descendentHasNonEmptyStack = true;
                break;
            }
        }
        if (descendentHasNonEmptyStack && !inLegacyMozillaMode)
            break;

        // This algorithm is not allowed to show a pop-up:
        //   An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
        //   - an activation behavior is currently being processed whose click event was trusted, or
        //   - the event listener for a trusted click event is being handled.
        // FIXME: Does this need to null-check settings()?
        if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
            break;

        // There is a previously-established user preference, security risk, or platform limitation.
        if (!document()->settings() || !document()->settings()->fullScreenEnabled())
            break;

        // 2. Let doc be element's node document. (i.e. "this")
        Document* currentDoc = document();

        // 3. Let docs be all doc's ancestor browsing context's documents (if any) and doc.
        Deque<Document*> docs;

        do {
            docs.prepend(currentDoc);
            currentDoc = currentDoc->ownerElement() ? &currentDoc->ownerElement()->document() : 0;
        } while (currentDoc);

        // 4. For each document in docs, run these substeps:
        Deque<Document*>::iterator current = docs.begin(), following = docs.begin();

        do {
            ++following;

            // 1. Let following document be the document after document in docs, or null if there is no
            // such document.
            Document* currentDoc = *current;
            Document* followingDoc = following != docs.end() ? *following : 0;

            // 2. If following document is null, push context object on document's fullscreen element
            // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
            // set to true on the document.
            if (!followingDoc) {
                from(currentDoc)->pushFullscreenElementStack(element);
                addDocumentToFullScreenChangeEventQueue(currentDoc);
                continue;
            }

            // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
            // is not following document's browsing context container,
            Element* topElement = fullscreenElementFrom(currentDoc);
            if (!topElement || topElement != followingDoc->ownerElement()) {
                // ...push following document's browsing context container on document's fullscreen element
                // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
                // set to true on document.
                from(currentDoc)->pushFullscreenElementStack(followingDoc->ownerElement());
                addDocumentToFullScreenChangeEventQueue(currentDoc);
                continue;
            }

            // 4. Otherwise, do nothing for this document. It stays the same.
        } while (++current != docs.end());

        // 5. Return, and run the remaining steps asynchronously.
        // 6. Optionally, perform some animation.
        m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
        document()->page()->chrome().client().enterFullScreenForElement(element);

        // 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
        return;
    } while (0);

    m_fullScreenErrorEventTargetQueue.append(element ? element : document()->documentElement());
    m_fullScreenChangeDelayTimer.startOneShot(0);
}
Example #4
0
void ScoreAccessibility::currentInfoChanged()
      {
      clearAccessibilityInfo();
      statusBarLabel  = new QLabel(mainWindow->statusBar());
      ScoreView* scoreView =  static_cast<MuseScore*>(mainWindow)->currentScoreView();
      Score* score = scoreView->score();
      if (score->selection().isSingle()) {
            Element* e = score->selection().element();
            if (!e) {
                  return;
                  }
            Element* el = e->isSpannerSegment() ? static_cast<SpannerSegment*>(e)->spanner() : e;
            QString barsAndBeats = "";
            std::pair<int, float> bar_beat;
            if (el->isSpanner()){
                  Spanner* s = static_cast<Spanner*>(el);
                  bar_beat = barbeat(s->startSegment());
                  barsAndBeats += tr("Start Measure: %1; Start Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
                  Segment* seg = s->endSegment();
                  if(!seg)
                        seg = score->lastSegment()->prev1MM(Segment::Type::ChordRest);

                  if (seg->tick() != score->lastSegment()->prev1MM(Segment::Type::ChordRest)->tick() &&
                      s->type() != Element::Type::SLUR                                               &&
                      s->type() != Element::Type::TIE                                                )
                        seg = seg->prev1MM(Segment::Type::ChordRest);

                  bar_beat = barbeat(seg);
                  barsAndBeats += "; " + tr("End Measure: %1; End Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
                  }
            else {
                  std::pair<int, float>bar_beat = barbeat(el);
                  if (bar_beat.first) {
                        barsAndBeats += " " + tr("Measure: %1").arg(QString::number(bar_beat.first));
                        if (bar_beat.second)
                              barsAndBeats += "; " + tr("Beat: %1").arg(QString::number(bar_beat.second));
                        }
                  }

            QString rez = e->accessibleInfo();
            if (!barsAndBeats.isEmpty())
                  rez += "; " + barsAndBeats;

            QString staff = "";
            if (e->staffIdx() + 1) {
                  staff = tr("Staff %1").arg(QString::number(e->staffIdx() + 1));
                  rez = QString("%1; %2").arg(rez).arg(staff);
                  }

            statusBarLabel->setText(rez);
            QString screenReaderRez = QString("%1%2 %3 %4").arg(e->screenReaderInfo()).arg(barsAndBeats).arg(staff).arg(e->accessibleExtraInfo());
            score->setAccessibleInfo(screenReaderRez);
            }
      else if (score->selection().isRange()) {
            QString barsAndBeats = "";
            std::pair<int, float> bar_beat;

            bar_beat = barbeat(score->selection().startSegment());
            barsAndBeats += " " + tr("Start Measure: %1; Start Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
            Segment* endSegment = score->selection().endSegment();

            if (!endSegment)
                  endSegment = score->lastSegment();
            else
                  endSegment = endSegment->prev1MM();

            bar_beat = barbeat(endSegment);
            barsAndBeats += " " + tr("End Measure: %1; End Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
            statusBarLabel->setText(tr("Range Selection") + barsAndBeats);
            score->setAccessibleInfo(tr("Range Selection") + barsAndBeats);
            }
      else if (score->selection().isList()) {
            statusBarLabel->setText(tr("List Selection"));
            score->setAccessibleInfo(tr("List Selection"));
            }
      mainWindow->statusBar()->addWidget(statusBarLabel);
      }
Example #5
0
void Visitor::Visit(Element const& element)
{
    bool isElement = false;
    switch(element.Type())
    {
        // Constant Tokens
        case Types::NIL: VisitNil(); break;
        case Types::TRUE_: VisitTrue(); break; 
        case Types::FALSE_: VisitFalse(); break; 
        case Types::STRING:
        {
            String S = CastToString(element, isElement);
            VisitString(S);
        }
            break;
        case Types::SUPERSTRING:
        {
            SuperString S = CastToSuperString(element, isElement);
            VisitSuperString(S);
        }
            break;
        case Types::NUMBER:
        {
            Number N = CastToNumber(element, isElement);
            VisitNumber(N);
        }
            break;
        case Types::CONTAINER:
        {
            Container C = CastToContainer(element, isElement);
            VisitContainer(C);
        }
            break;
        case Types::BUILTIN:
        {
            Builtin B = CastToBuiltin(element, isElement);
            VisitBuiltin(B);
        }
            break;
        case Types::CALL:
        {
            Funcall F = CastToFuncall(element, isElement);
            VisitCall(F);
        }
            break;
        case Types::FUNCTION:
        {
            Function F = CastToFunction(element, isElement);
            VisitFunction(F);
        }
            break;
        case Types::IF:
        {
            If F = CastToIf(element, isElement);
            VisitIf(F);
        }
            break;
        case Types::SET:
        {
            Set F = CastToSet(element, isElement);
            VisitSet(F);
        }
            break;
        case Types::IMPERATIVE:
        {
            Imperative F = CastToImperative(element, isElement);
            VisitImperative(F);
        }
        case Types::CASE:
        {
            Case C = CastToCase(element, isElement);
            VisitCase(C);
        }
            break;
    };
}
void Mesh::formHalo2(){
#ifndef NDEBUG
  unsigned len45 = element_list.size();
  for(unsigned i=0; i<len45; i++)
    for(unsigned j=0; j<len45; j++)
      if(i!=j)
	assert(element_list[i] != element_list[j]);
  #endif

  // This is what we are looking for.
  vector< deque<unsigned> > halo2Elements(NProcs);
  set<unsigned> dangerElements;
  {  
    // Wizz through all elements.
    unsigned pos = 0;
    for(deque<Element>::const_iterator elm = element_list.begin(); elm != element_list.end(); ++elm, ++pos){

      const vector<unn_t>& nodes = (*elm).get_enlist();
      vector<bool> halo1(NProcs, false);
      bool interesting=false;

      for(int p=0; p<NProcs; p++){
	if(p==MyRank) continue;
	
	// Record if elm has a halo node with p.
	for( vector<unn_t>::const_iterator jt = nodes.begin(); jt!=nodes.end(); ++jt){
	  halo1[p] = (halo_nodes[p].find(*jt)!= halo_nodes[p].end());
	  
	  // Early exit...
	  if(halo1[p])
	    break;
	}
	
	if(!halo1[p]){
	  // Record if elm shares a node with p, but is not itself a halo1 element for p.
	  for(vector<unn_t>::const_iterator jt=nodes.begin(); jt!=nodes.end(); ++jt){
	    if(shared_nodes[p].find(*jt)!=shared_nodes[p].end()){
	      interesting = true;
	      halo2Elements[p].push_back(pos);
	      break;
	    }
	  }
	}

      }
      
      if(interesting){
	// A halo2 element may be multiably sent if it contains halo1
	// nodes for any domain.
	for(unsigned p=0;p<(unsigned)NProcs;p++){
	  if(halo1[p]){
	    dangerElements.insert( pos );
	    break;
	  }
	}	  
      }
    }
  } // Have halo2 elements and a set of dangerElements.
  

  //
  // Identify all the nodes that must be sent.
  //
  vector< set<unsigned> > sendhalo2nodes(NProcs);
  vector< set<unsigned> > sendhalo2pnodes(NProcs);
  for(unsigned p=0; p<(unsigned)NProcs; p++){

    for(deque<unsigned>::const_iterator elm=halo2Elements[p].begin(); elm!=halo2Elements[p].end(); ++elm){
      // It's enough to just check the volume elements
      if(element_list[*elm].get_flags() & ELM_SURFACE)
        continue;
      
      {// Regular nodes	
	const vector<unn_t>& nodes = element_list[*elm].get_enlist();
	for(vector<unn_t>::const_iterator nod=nodes.begin(); nod!=nodes.end(); ++nod){
	  sendhalo2nodes[p].insert( *nod );
	}
      }
      {// Pressure nodes
	const vector<unn_t>& nodes = element_list[*elm].get_MFenlist();
	for(vector<unn_t>::const_iterator nod=nodes.begin(); nod!=nodes.end(); ++nod){
	  sendhalo2pnodes[p].insert( *nod );
	}
      }
    }
    
    {// Remove nodes that p should already know through halo1.
      set<unsigned> toDel;
      for(set<unsigned>::const_iterator it=sendhalo2nodes[p].begin(); it != sendhalo2nodes[p].end(); ++it){
	if(shared_nodes[p].find( *it ) != shared_nodes[p].end()){
	  toDel.insert( *it );
	}
      }
      for(set<unsigned>::const_iterator it=toDel.begin(); it != toDel.end(); ++it){
	sendhalo2nodes[p].erase( *it );
      }
    }
    
    {// Remove pressure nodes that p should already know through halo1.
      set<unsigned> toDel;
      for(set<unsigned>::const_iterator it=sendhalo2pnodes[p].begin(); it != sendhalo2pnodes[p].end(); ++it){
	if( shared_pnodes[p].find( *it ) != shared_pnodes[p].end() ){
	  toDel.insert( *it );
	}
      }   
      for(set<unsigned>::const_iterator it=toDel.begin(); it != toDel.end(); ++it){
	sendhalo2pnodes[p].erase( *it );
      }
    }
  }

  //
  // At this point we have identified all the information which we
  // want to communicate: 
  // vector< deque<unsigned> > elems2send( NProcs );
  // vector< set<unsigned> > nodes2send( NProcs );
  //
  
  // Make the send-packs
  vector< vector<char> > SendRecvBuffer(NProcs);
  
  { // Allocate space for buffers
    unsigned max_node_size      = max_nodepack_size();
    unsigned max_pnode_size     = max_pressurepack_size();
    unsigned max_element_size   = max_elementpack_size();
    unsigned space_for_unsigned = MPI::UNSIGNED.Pack_size(1, MPI::COMM_WORLD);
    
    for(int i=0; i<NProcs; i++){
      unsigned nbytes = space_for_unsigned          +
	space_for_unsigned*halo2Elements[i].size() +
	space_for_unsigned                          +
	max_element_size*halo2Elements[i].size()    +
	space_for_unsigned                          +
	max_node_size*sendhalo2nodes[i].size()      +
	space_for_unsigned                          +
	max_pnode_size*sendhalo2pnodes[i].size();
      
      SendRecvBuffer[i].resize( (unsigned)(1.1*nbytes) );
    }
  }
  
  vector<int> offsets(NProcs, 0); // int because of mpi calls
  
  // Pack.
  for(int i=0; i<NProcs; i++){
    int len = SendRecvBuffer[i].size();
    
    if( (i == MyRank)||(len == 0) )
      continue;
    
    char *buff = &(SendRecvBuffer[i][0]);
    
    // Elements
    unsigned cnt = halo2Elements[i].size();
    MPI::UNSIGNED.Pack(&cnt, 1, buff, len, offsets[i], MPI::COMM_WORLD);
    
    ECHO("Packing "<<cnt<<" halo2 elements for "<<i<<".");
    for(unsigned j=0; j<cnt; j++){

      // Dangerious?
      unsigned danger = 0;
      if( dangerElements.find( halo2Elements[i][j] ) != dangerElements.end() )
	danger = 1;
      MPI::UNSIGNED.Pack(&danger, 1, buff, len, offsets[i], MPI::COMM_WORLD);

      // Pack element
      element_list[ halo2Elements[i][j] ].pack(buff, len, offsets[i]);
    }
    // Nodes
    cnt = sendhalo2nodes[i].size();
    MPI::UNSIGNED.Pack(&cnt, 1, buff, len, offsets[i], MPI::COMM_WORLD);

    ECHO("Packing "<<cnt<<" halo2 nodes for "<<i<<".");    
    for(set<unsigned>::const_iterator it=sendhalo2nodes[i].begin(); it!=sendhalo2nodes[i].end(); ++it){
      const Node& node = node_list.unn( *it );
      node.pack(buff, len, offsets[i]);
    }
    
    // Pressure nodes
    cnt = sendhalo2pnodes[i].size();
    MPI::UNSIGNED.Pack(&cnt, 1, buff, len, offsets[i], MPI::COMM_WORLD);
    ECHO("Packing "<<cnt<<" halo2 pressure nodes for "<<i<<".");

    for(set<unsigned>::const_iterator it=sendhalo2pnodes[i].begin(); it!=sendhalo2pnodes[i].end(); ++it){
      const PressureNode& node = MFnode_list.unn( *it );
      node.pack(buff, len, offsets[i]);
    }
    
    assert(offsets[i] <= (int)SendRecvBuffer[i].size());
  }
  
  // Clean-up.
  dangerElements.clear();
  halo2Elements.clear();
  sendhalo2nodes.clear();
  sendhalo2pnodes.clear();
  
  // Send/recieve everything.
  allSendRecv(SendRecvBuffer);

  { // Unpacking.
    ECHO("Starting unpacking.");
    
    for(int p=0; p<NProcs; p++){
      offsets[p] = 0;
    }

    set<Element>  DangerElements;
    set<unsigned> ReceivedNodes;
    set<unsigned> ReceivedPressureNodes;
    vector< set<unsigned> > extraHalo(NProcs);
    
    // Paranoid
    assert(SendRecvBuffer.size() == (unsigned)NProcs);

#ifndef NDEBUG
    CHECK( element_list.size() );	
    do_element_headcount();
    CHECK( num_elements("total") );
    CHECK( num_elements("volume") );
    CHECK( num_elements("surface") );
#endif
   
    for(int p=0; p<NProcs; p++){
      int nbytes = SendRecvBuffer[p].size();
      if( (p == MyRank)||(nbytes == 0) )
	continue;
      
      char *buffer = &(SendRecvBuffer[p][0]);
      { // elements
	unsigned cnt;
	MPI::UNSIGNED.Unpack(buffer, nbytes, &cnt, 1, offsets[p], MPI::COMM_WORLD);
	
	ECHO("Unpacking "<<cnt<<" elements from "<<p<<".");
	
	for(unsigned j=0; j<cnt; j++){
	  Element element;
	  
	  ECHO("Unpacking "<<j<<"...");
	  
	  // Unpack danger flag.
	  unsigned danger;
	  MPI::UNSIGNED.Unpack(buffer, nbytes, &danger, 1, offsets[p], MPI::COMM_WORLD);
	  CHECK(danger);
	  
	  // Unpack element...      
	  element.unpack(buffer, nbytes, offsets[p]);
	  ECHO("unpacked.");
	  
	  if(danger){
	    ECHO("Danger element...taking evasive action."); 
	    DangerElements.insert( element );	      
	  }else{
	    element_list.push_back(element);
	  }  
	}
      } // finished unpacking elements.
      
      { // nodes
	unsigned cnt;
	MPI::UNSIGNED.Unpack(buffer, nbytes, &cnt, 1, offsets[p], MPI::COMM_WORLD);
	ECHO("Unpacking "<<cnt<<" nodes from "<<p<<".");
	
	for(unsigned j=0; j<cnt; j++){
	  Node node;
	  node.unpack(buffer, nbytes, offsets[p]);
	  unsigned unn   = node.get_unn();
	  unsigned owner = node.get_owner();

	  if(halo_nodes[owner].find( unn ) == halo_nodes[owner].end())
	    if(ReceivedNodes.find( unn ) == ReceivedNodes.end()){
	      assert( !node_list.contains_unn(unn) );
	      node_list.push_back( node );
	      ReceivedNodes.insert( unn );
	    }
	}
	
      } // finished unpacking nodes
      
      { // pressure nodes
	unsigned cnt;
	MPI::UNSIGNED.Unpack(buffer, nbytes, &cnt, 1, offsets[p], MPI::COMM_WORLD);
	ECHO("Unpacking "<<cnt<<" pressure nodes from "<<p<<".");
	
	for(unsigned j=0; j<cnt; j++){
	  PressureNode node;
	  node.unpack(buffer, nbytes, offsets[p]);
	  unsigned unn = node.get_unn();
	  unsigned owner = node.get_owner();

	  if(halo_pnodes[owner].find( unn ) == halo_pnodes[owner].end())
	    if(ReceivedPressureNodes.find( node.get_unn() ) == ReceivedPressureNodes.end()){
	      assert( !MFnode_list.contains_unn(unn) );
	      MFnode_list.push_back( node );
	      ReceivedPressureNodes.insert( node.get_unn() );
	      
	      // This next line is tricky as "node.get_owner()" is used
	      // rather than p. This is because the owner of this node is
	      // not necessarly the same as the processor that sent
	      // it.
	      extraHalo[owner].insert( node.get_unn() );
	    }
	}
	
      } // finished unpacking pressure nodes
      
    }
  
    //
    // Finally, add in the danger elements
    //
    if( !DangerElements.empty() ){
      ECHO("Add in danger elements.");
      
      for(set<Element>::const_iterator it=DangerElements.begin(); it!=DangerElements.end(); ++it)
	element_list.push_back( *it ); 
      DangerElements.clear();
    }
    
#ifndef NDEBUG
    CHECK( element_list.size() );	
    do_element_headcount();
    CHECK( num_elements("total") );
    CHECK( num_elements("volume") );
    CHECK( num_elements("surface") );
#endif

    //
    // Communicate extra halo stuff.
    //
    vector< set<unsigned> > extraShared(NProcs);
    ECHO("Communicating the extended halo...");
    assert(extraHalo[MyRank].size() == 0);    
    allSendRecv(extraHalo, extraShared);
    assert(extraShared[MyRank].size() == 0);
    ECHO("...done.");
    
    // 
    // Add in extra halo values...
    //
    for(int p=0; p<NProcs; p++){
      if(p==MyRank)
	continue;
      
      // add in extra halo values
      ECHO("Adding halo nodes for "<<p);
      halo_pnodes[p].insert(extraHalo[p].begin(), extraHalo[p].end());
      extraHalo[p].clear();
      
      ECHO("Adding shared nodes for "<<p);
      shared_pnodes[p].insert(extraShared[p].begin(), extraShared[p].end());
      extraShared[p].clear();
      
    }
    extraHalo.clear();
    extraShared.clear();
    
  } // finished unpacking

#ifndef NDEBUG
  len45 = element_list.size();
  for(unsigned i=0; i<len45; i++)
    for(unsigned j=0; j<len45; j++)
      if(i!=j)
	assert(element_list[i] != element_list[j]);
#endif
  
  ECHO("Halo2 created.");
  return; 
 
}
Example #7
0
/* static */
nsresult
nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                           nsNodeInfoManager *aNewNodeInfoManager,
                           JS::Handle<JSObject*> aReparentScope,
                           nsCOMArray<nsINode> &aNodesWithProperties,
                           nsINode *aParent, nsINode **aResult)
{
  NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aReparentScope,
                  "If cloning or not getting a new nodeinfo we shouldn't "
                  "rewrap");
  NS_PRECONDITION(!aParent || aNode->IsNodeOfType(nsINode::eCONTENT),
                  "Can't insert document or attribute nodes into a parent");

  *aResult = nullptr;

  // First deal with aNode and walk its attributes (and their children). Then,
  // if aDeep is true, deal with aNode's children (and recurse into their
  // attributes and children).

  nsAutoScriptBlocker scriptBlocker;
  nsresult rv;

  nsNodeInfoManager *nodeInfoManager = aNewNodeInfoManager;

  // aNode.
  NodeInfo *nodeInfo = aNode->mNodeInfo;
  RefPtr<NodeInfo> newNodeInfo;
  if (nodeInfoManager) {

    // Don't allow importing/adopting nodes from non-privileged "scriptable"
    // documents to "non-scriptable" documents.
    nsIDocument* newDoc = nodeInfoManager->GetDocument();
    NS_ENSURE_STATE(newDoc);
    bool hasHadScriptHandlingObject = false;
    if (!newDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
        !hasHadScriptHandlingObject) {
      nsIDocument* currentDoc = aNode->OwnerDoc();
      NS_ENSURE_STATE((nsContentUtils::IsChromeDoc(currentDoc) ||
                       (!currentDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
                        !hasHadScriptHandlingObject)));
    }

    newNodeInfo = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
                                               nodeInfo->GetPrefixAtom(),
                                               nodeInfo->NamespaceID(),
                                               nodeInfo->NodeType(),
                                               nodeInfo->GetExtraName());

    nodeInfo = newNodeInfo;
  }

  Element *elem = aNode->IsElement() ? aNode->AsElement() : nullptr;

  nsCOMPtr<nsINode> clone;
  if (aClone) {
    rv = aNode->Clone(nodeInfo, getter_AddRefs(clone));
    NS_ENSURE_SUCCESS(rv, rv);

    if (clone->IsElement()) {
      // The cloned node may be a custom element that may require
      // enqueing created callback and prototype swizzling.
      Element* elem = clone->AsElement();
      if (nsContentUtils::IsCustomElementName(nodeInfo->NameAtom())) {
        elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID());
      } else {
        // Check if node may be custom element by type extension.
        // ex. <button is="x-button">
        nsAutoString extension;
        if (elem->GetAttr(kNameSpaceID_None, nsGkAtoms::is, extension) &&
            !extension.IsEmpty()) {
          elem->OwnerDoc()->SetupCustomElement(elem, nodeInfo->NamespaceID(),
                                               &extension);
        }
      }
    }

    if (aParent) {
      // If we're cloning we need to insert the cloned children into the cloned
      // parent.
      rv = aParent->AppendChildTo(static_cast<nsIContent*>(clone.get()),
                                  false);
      NS_ENSURE_SUCCESS(rv, rv);
    }
    else if (aDeep && clone->IsNodeOfType(nsINode::eDOCUMENT)) {
      // After cloning the document itself, we want to clone the children into
      // the cloned document (somewhat like cloning and importing them into the
      // cloned document).
      nodeInfoManager = clone->mNodeInfo->NodeInfoManager();
    }
  }
  else if (nodeInfoManager) {
    nsIDocument* oldDoc = aNode->OwnerDoc();
    bool wasRegistered = false;
    if (aNode->IsElement()) {
      Element* element = aNode->AsElement();
      oldDoc->ClearBoxObjectFor(element);
      wasRegistered = oldDoc->UnregisterActivityObserver(element);
    }

    aNode->mNodeInfo.swap(newNodeInfo);
    if (elem) {
      elem->NodeInfoChanged(newNodeInfo);
    }

    nsIDocument* newDoc = aNode->OwnerDoc();
    if (newDoc) {
      // XXX what if oldDoc is null, we don't know if this should be
      // registered or not! Can that really happen?
      if (wasRegistered) {
        newDoc->RegisterActivityObserver(aNode->AsElement());
      }

      if (nsPIDOMWindowInner* window = newDoc->GetInnerWindow()) {
        EventListenerManager* elm = aNode->GetExistingListenerManager();
        if (elm) {
          window->SetMutationListeners(elm->MutationListenerBits());
          if (elm->MayHavePaintEventListener()) {
            window->SetHasPaintEventListeners();
          }
          if (elm->MayHaveTouchEventListener()) {
            window->SetHasTouchEventListeners();
          }
          if (elm->MayHaveMouseEnterLeaveEventListener()) {
            window->SetHasMouseEnterLeaveEventListeners();
          }
          if (elm->MayHavePointerEnterLeaveEventListener()) {
            window->SetHasPointerEnterLeaveEventListeners();
          }
        }
      }
    }

    if (wasRegistered && oldDoc != newDoc) {
      nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aNode));
      if (domMediaElem) {
        HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aNode);
        mediaElem->NotifyOwnerDocumentActivityChanged();
      }
      nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aNode));
      if (objectLoadingContent) {
        nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
        olc->NotifyOwnerDocumentActivityChanged();
      }
    }

    if (oldDoc != newDoc && oldDoc->MayHaveDOMMutationObservers()) {
      newDoc->SetMayHaveDOMMutationObservers();
    }

    if (oldDoc != newDoc && oldDoc->MayHaveAnimationObservers()) {
      newDoc->SetMayHaveAnimationObservers();
    }

    if (elem) {
      elem->RecompileScriptEventListeners();
    }

    if (aReparentScope) {
      AutoJSContext cx;
      JS::Rooted<JSObject*> wrapper(cx);
      if ((wrapper = aNode->GetWrapper())) {
        MOZ_ASSERT(IsDOMObject(wrapper));
        JSAutoCompartment ac(cx, wrapper);
        rv = ReparentWrapper(cx, wrapper);
        if (NS_FAILED(rv)) {
          aNode->mNodeInfo.swap(nodeInfo);

          return rv;
        }
      }
    }
  }

  if (aDeep && (!aClone || !aNode->IsNodeOfType(nsINode::eATTRIBUTE))) {
    // aNode's children.
    for (nsIContent* cloneChild = aNode->GetFirstChild();
         cloneChild;
         cloneChild = cloneChild->GetNextSibling()) {
      nsCOMPtr<nsINode> child;
      rv = CloneAndAdopt(cloneChild, aClone, true, nodeInfoManager,
                         aReparentScope, aNodesWithProperties, clone,
                         getter_AddRefs(child));
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  // Cloning template element.
  if (aDeep && aClone && IsTemplateElement(aNode)) {
    DocumentFragment* origContent =
      static_cast<HTMLTemplateElement*>(aNode)->Content();
    DocumentFragment* cloneContent =
      static_cast<HTMLTemplateElement*>(clone.get())->Content();

    // Clone the children into the clone's template content owner
    // document's nodeinfo manager.
    nsNodeInfoManager* ownerNodeInfoManager =
      cloneContent->mNodeInfo->NodeInfoManager();

    for (nsIContent* cloneChild = origContent->GetFirstChild();
         cloneChild;
         cloneChild = cloneChild->GetNextSibling()) {
      nsCOMPtr<nsINode> child;
      rv = CloneAndAdopt(cloneChild, aClone, aDeep, ownerNodeInfoManager,
                         aReparentScope, aNodesWithProperties, cloneContent,
                         getter_AddRefs(child));
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  // XXX setting document on some nodes not in a document so XBL will bind
  // and chrome won't break. Make XBL bind to document-less nodes!
  // XXXbz Once this is fixed, fix up the asserts in all implementations of
  // BindToTree to assert what they would like to assert, and fix the
  // ChangeDocumentFor() call in nsXULElement::BindToTree as well.  Also,
  // remove the UnbindFromTree call in ~nsXULElement, and add back in the
  // precondition in nsXULElement::UnbindFromTree and remove the line in
  // nsXULElement.h that makes nsNodeUtils a friend of nsXULElement.
  // Note: Make sure to do this witchery _after_ we've done any deep
  // cloning, so kids of the new node aren't confused about whether they're
  // in a document.
#ifdef MOZ_XUL
  if (aClone && !aParent && aNode->IsXULElement()) {
    if (!aNode->OwnerDoc()->IsLoadedAsInteractiveData()) {
      clone->SetFlags(NODE_FORCE_XBL_BINDINGS);
    }
  }
#endif

  if (aNode->HasProperties()) {
    bool ok = aNodesWithProperties.AppendObject(aNode);
    if (aClone) {
      ok = ok && aNodesWithProperties.AppendObject(clone);
    }

    NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
  }

  clone.forget(aResult);

  return NS_OK;
}
Example #8
0
void Palette::mouseDoubleClickEvent(QMouseEvent* ev)
      {
      int i = idx(ev->pos());
      if (i == -1)
            return;
      Score* score   = mscore->currentScore();
      if (score == 0)
            return;
      const Selection& sel = score->selection();

      if (sel.state() == SEL_NONE)
            return;

      Element* element = 0;
      if (i < size() &&  cells[i])
            element = cells[i]->element;
      if (element == 0)
            return;
      ScoreView* viewer = mscore->currentScoreView();


      if (viewer->mscoreState() != STATE_EDIT
         && viewer->mscoreState() != STATE_LYRICS_EDIT
         && viewer->mscoreState() != STATE_HARMONY_FIGBASS_EDIT
         && viewer->mscoreState() != STATE_TEXT_EDIT) { // Already in startCmd in this case
            score->startCmd();
            }
      if (sel.state() == SEL_LIST) {
            foreach(Element* e, sel.elements())
                  applyDrop(score, viewer, e, element);
            }
      else if (sel.state() == SEL_RANGE) {
            // TODO: check for other element types:
            if (element->type() == Element::BAR_LINE) {
                  // TODO: apply to multiple measures
                  Measure* m = sel.startSegment()->measure();
                  QRectF r = m->staffabbox(sel.staffStart());
                  QPointF pt(r.x() + r.width() * .5, r.y() + r.height() * .5);
                  applyDrop(score, viewer, m, element, pt);
                  }
            else {
                  int track1 = sel.staffStart() * VOICES;
                  int track2 = sel.staffEnd() * VOICES;
                  Segment* startSegment = sel.startSegment();
                  Segment* endSegment = sel.endSegment(); //keep it, it could change during the loop
                  for (Segment* s = startSegment; s && s != endSegment; s = s->next1()) {
                        for (int track = track1; track < track2; ++track) {
                              Element* e = s->element(track);
                              if (e == 0)
                                    continue;
                              if (e->type() == Element::CHORD) {
                                    Chord* chord = static_cast<Chord*>(e);
                                    foreach(Note* n, chord->notes())
                                          applyDrop(score, viewer, n, element);
                                    }
                              else {
                                    // do not apply articulation to barline in a range selection
                                    if(e->type() != Element::BAR_LINE || element->type() != Element::ARTICULATION)
                                          applyDrop(score, viewer, e, element);
                                    }
                              }
                        }
                  }
            }
      else
            qDebug("unknown selection state\n");
      if (viewer->mscoreState() != STATE_EDIT
         && viewer->mscoreState() != STATE_LYRICS_EDIT
         && viewer->mscoreState() != STATE_HARMONY_FIGBASS_EDIT
         && viewer->mscoreState() != STATE_TEXT_EDIT) { //Already in startCmd mode in this case
            score->endCmd();
            }
      mscore->endCmd();
      }
void XMLDocumentParser::endElementNs()
{
    if (isStopped())
        return;

    if (m_parserPaused) {
        m_pendingCallbacks->appendEndElementNSCallback();
        return;
    }

    exitText();

    Node* n = m_currentNode;
    n->finishParsingChildren();

    if (m_scriptingPermission == FragmentScriptingNotAllowed && n->isElementNode() && toScriptElement(static_cast<Element*>(n))) {
        popCurrentNode();
        ExceptionCode ec;
        n->remove(ec);
        return;
    }

    if (!n->isElementNode() || !m_view) {
        popCurrentNode();
        return;
    }

    Element* element = static_cast<Element*>(n);

    // The element's parent may have already been removed from document.
    // Parsing continues in this case, but scripts aren't executed.
    if (!element->inDocument()) {
        popCurrentNode();
        return;
    }

    ScriptElement* scriptElement = toScriptElement(element);
    if (!scriptElement) {
        popCurrentNode();
        return;
    }

    // Don't load external scripts for standalone documents (for now).
    ASSERT(!m_pendingScript);
    m_requestingScript = true;

#if ENABLE(XHTMLMP)
    if (!scriptElement->shouldExecuteAsJavaScript())
        document()->setShouldProcessNoscriptElement(true);
    else
#endif
    {
        // FIXME: Script execution should be shared should be shared between
        // the libxml2 and Qt XMLDocumentParser implementations.

        // JavaScript can detach the parser.  Make sure this is not released
        // before the end of this method.
        RefPtr<XMLDocumentParser> protect(this);

        String scriptHref = scriptElement->sourceAttributeValue();
        if (!scriptHref.isEmpty()) {
            // we have a src attribute
            String scriptCharset = scriptElement->scriptCharset();
            if (element->dispatchBeforeLoadEvent(scriptHref) &&
                (m_pendingScript = document()->cachedResourceLoader()->requestScript(scriptHref, scriptCharset))) {
                m_scriptElement = element;
                m_pendingScript->addClient(this);

                // m_pendingScript will be 0 if script was already loaded and ref() executed it
                if (m_pendingScript)
                    pauseParsing();
            } else
                m_scriptElement = 0;
        } else
            scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));

        // JavaScript may have detached the parser
        if (isDetached())
            return;
    }
    m_requestingScript = false;
    popCurrentNode();
}
Example #10
0
void RenderTextControl::updateFromElement()
{
    Element* innerText = innerTextElement();
    if (innerText)
        updateUserModifyProperty(node(), innerText->renderer()->style());
}
Example #11
0
void
NlDEIDynamic :: computeMassMtrx(FloatArray &massMatrix, double &maxOm, TimeStep *tStep)
{
    Domain *domain = this->giveDomain(1);
    int nelem = domain->giveNumberOfElements();
    int neq = this->giveNumberOfEquations(EID_MomentumBalance);
    int i, j, jj, n;
    double maxOmi, maxOmEl;
    FloatMatrix charMtrx, charMtrx2;
    IntArray loc;
    Element *element;
    EModelDefaultEquationNumbering en;
#ifdef __PARALLEL_MODE
    int result;
#endif

#ifndef LOCAL_ZERO_MASS_REPLACEMENT
    FloatArray diagonalStiffMtrx;
#endif

    maxOm = 0.;
    massMatrix.resize(neq);
    massMatrix.zero();
    for ( i = 1; i <= nelem; i++ ) {
        element = domain->giveElement(i);

#ifdef __PARALLEL_MODE
        // skip remote elements (these are used as mirrors of remote elements on other domains
        // when nonlocal constitutive models are used. They introduction is necessary to
        // allow local averaging on domains without fine grain communication between domains).
        if ( element->giveParallelMode() == Element_remote ) {
            continue;
        }
#endif

        element->giveLocationArray(loc, EID_MomentumBalance, en);
        element->giveCharacteristicMatrix(charMtrx, LumpedMassMatrix, tStep);

#ifdef LOCAL_ZERO_MASS_REPLACEMENT
        element->giveCharacteristicMatrix(charMtrx2, StiffnessMatrix, tStep);
#endif

#ifdef DEBUG
        if ( ( n = loc.giveSize() ) != charMtrx.giveNumberOfRows() ) {
            _error("solveYourselfAt : dimension mismatch");
        }
#endif

        n = loc.giveSize();

#ifdef LOCAL_ZERO_MASS_REPLACEMENT
        maxOmEl = 0.;

        double maxElmass = -1.0;
        for ( j = 1; j <= n; j++ ) {
            maxElmass = max( maxElmass, charMtrx.at(j, j) );
        }

        if ( maxElmass <= 0.0 ) {
            _warning2("solveYourselfAt: Element (%d) with zero (or negative) lumped mass encountered\n", i);
        }

        for ( j = 1; j <= n; j++ ) {
            if ( charMtrx.at(j, j) > maxElmass * ZERO_REL_MASS ) {
                maxOmi =  charMtrx2.at(j, j) / charMtrx.at(j, j);
                maxOmEl = ( maxOmEl > maxOmi ) ? ( maxOmEl ) : ( maxOmi );
            }
        }

        maxOm = ( maxOm > maxOmEl ) ? ( maxOm ) : ( maxOmEl );

        for ( j = 1; j <= n; j++ ) {
            jj = loc.at(j);
            if ( ( jj ) && ( charMtrx.at(j, j) <= maxElmass * ZERO_REL_MASS ) ) {
                charMtrx.at(j, j) = charMtrx2.at(j, j) / maxOmEl;
            }
        }
#endif

        for ( j = 1; j <= n; j++ ) {
            jj = loc.at(j);
            if ( jj ) {
                massMatrix.at(jj) += charMtrx.at(j, j);
            }
        }
    }

#ifndef LOCAL_ZERO_MASS_REPLACEMENT
    // If init step - find minimun period of vibration in order to
    // determine maximal admisible time step
    // global variant
    for (i=1; i<=nelem; i++)
    {
        element = domain -> giveElement(i);
        element->giveLocationArray(loc, EID_MomentumBalance, en);
        element->giveCharacteristicMatrix( charMtrx, StiffnessMatrix, tStep );
        n = loc.giveSize() ;
        for (j=1; j<=n; j++) {
            jj = loc.at(j);
            if (jj) {
                diagonalStiffMtrx.at(jj) += charMtrx.at(j,j);
            }
        }
    }

    // Find find global minimun period of vibration
    double maxElmass = -1.0;
    for (j=1 ; j<=n; j++) {
        maxElmass = max(maxElmass,charMtrx.at(j,j));
    }

    if ( maxElmass <= 0.0 ) {
        _error("solveYourselfAt: Element with zero (or negative) lumped mass encountered\n");
    }

    for (j=1; j<= neq; j++) {
        if (massMatrix.at(j) > maxElmass * ZERO_REL_MASS ) {
            maxOmi =  diagonalStiffMtrx.at(j) / massMatrix.at(j);
            maxOm  = (maxOm > maxOmi) ? (maxOm) : (maxOmi);
        }
    }

    // Set ZERO MASS members in massMatrix to value which corresponds to global maxOm.
    for (i=1; i<= neq; i++) {
        if (massMatrix.at(i) <= maxElmass*ZERO_REL_MASS) {
            massMatrix.at(i) = diagonalStiffMtrx.at(i) / maxOm;
        }
    }
#endif

#ifdef __PARALLEL_MODE
    this->updateSharedDofManagers( massMatrix, MassExchangeTag );

    // Determine maxOm over all processes.
 #ifdef __USE_MPI
    double globalMaxOm;

  #ifdef __VERBOSE_PARALLEL
    VERBOSEPARALLEL_PRINT( "NlDEIDynamic :: computeMassMtrx", "Reduce of maxOm started", this->giveRank() );
  #endif

    result = MPI_Allreduce(& maxOm, & globalMaxOm, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);

  #ifdef __VERBOSE_PARALLEL
    VERBOSEPARALLEL_PRINT( "NlDEIDynamic :: computeMassMtrx", "Reduce of maxOm finished", this->giveRank() );
  #endif

    if ( result != MPI_SUCCESS ) {
        _error("setUpCommunicationMaps: MPI_Allreduce failed");
    }

    maxOm = globalMaxOm;
 #else
    WARNING: NOT SUPPORTED MESSAGE PARSING LIBRARY
 #endif

#endif
}
Example #12
0
int RenderTextControl::textBlockWidth() const
{
    Element* innerText = innerTextElement();
    ASSERT(innerText);
    return width() - borderAndPaddingWidth() - innerText->renderBox()->paddingLeft() - innerText->renderBox()->paddingRight();
}
Example #13
0
static void h_set_getall(t_h_set *x)
{
  set<Element>::iterator iter  = x->hset->getAll().begin();
  
  while(iter != x->hset->getAll().end())
  {
    Element output = *iter;
 
    if(output.getLength() == 1) // symbol or float
    {
      if (output.getAtom()[0].a_type == A_FLOAT)
	outlet_float(x->out0, output.getAtom()[0].a_w.w_float);
      if (output.getAtom()[0].a_type == A_SYMBOL)
	outlet_symbol(x->out0, output.getAtom()[0].a_w.w_symbol);
      if (output.getAtom()[0].a_type == A_POINTER)
	outlet_pointer(x->out0, output.getAtom()[0].a_w.w_gpointer);
    }
    if(output.getLength() > 1) // list
      outlet_list(x->out0,&s_list,output.getLength(),output.getAtom());

    iter++;
  }
}
Example #14
0
void InsertParagraphSeparatorCommand::doApply()
{
    bool splitText = false;
    if (endingSelection().isNone())
        return;
    
    Position insertionPosition = endingSelection().start();
        
    EAffinity affinity = endingSelection().affinity();
        
    // Delete the current selection.
    if (endingSelection().isRange()) {
        calculateStyleBeforeInsertion(insertionPosition);
        deleteSelection(false, true);
        insertionPosition = endingSelection().start();
        affinity = endingSelection().affinity();
    }
    
    // FIXME: The rangeCompliantEquivalent conversion needs to be moved into enclosingBlock.
    Node* startBlockNode = enclosingBlock(rangeCompliantEquivalent(insertionPosition).node());
    Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent();
    Element* startBlock = static_cast<Element*>(startBlockNode);
    if (!startBlockNode
            || !startBlockNode->isElementNode()
            || !startBlock->parentNode()
            || isTableCell(startBlock)
            || startBlock->hasTagName(formTag)
            || (canonicalPos.node()->renderer() && canonicalPos.node()->renderer()->isTable())
            || canonicalPos.node()->hasTagName(hrTag)) {
        applyCommandToComposite(InsertLineBreakCommand::create(document()));
        return;
    }
    
    // Use the leftmost candidate.
    insertionPosition = insertionPosition.upstream();
    if (!insertionPosition.isCandidate())
        insertionPosition = insertionPosition.downstream();

    // Adjust the insertion position after the delete
    insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition);
    VisiblePosition visiblePos(insertionPosition, affinity);
    calculateStyleBeforeInsertion(insertionPosition);

    //---------------------------------------------------------------------
    // Handle special case of typing return on an empty list item
    if (breakOutOfEmptyListItem())
        return;

    //---------------------------------------------------------------------
    // Prepare for more general cases.

    bool isFirstInBlock = isStartOfBlock(visiblePos);
    bool isLastInBlock = isEndOfBlock(visiblePos);
    bool nestNewBlock = false;

    // Create block to be inserted.
    RefPtr<Element> blockToInsert;
    if (startBlock == startBlock->rootEditableElement()) {
        blockToInsert = createDefaultParagraphElement(document());
        nestNewBlock = true;
    } else if (shouldUseDefaultParagraphElement(startBlock)) 
        blockToInsert = createDefaultParagraphElement(document());
    else
        blockToInsert = startBlock->cloneElementWithoutChildren();

    //---------------------------------------------------------------------
    // Handle case when position is in the last visible position in its block,
    // including when the block is empty. 
    if (isLastInBlock) {
        bool shouldApplyStyleAfterInsertion = true;
        if (nestNewBlock) {
            if (isFirstInBlock && !lineBreakExistsAtVisiblePosition(visiblePos)) {
                // The block is empty.  Create an empty block to
                // represent the paragraph that we're leaving.
                RefPtr<Element> extraBlock = createDefaultParagraphElement(document());
                appendNode(extraBlock, startBlock);
                appendBlockPlaceholder(extraBlock);
            }
            appendNode(blockToInsert, startBlock);
        } else {
            // We can get here if we pasted a copied portion of a blockquote with a newline at the end and are trying to paste it
            // into an unquoted area. We then don't want the newline within the blockquote or else it will also be quoted.
            if (Node* highestBlockquote = highestEnclosingNodeOfType(canonicalPos, &isMailBlockquote)) {
                startBlock = static_cast<Element*>(highestBlockquote);
                // When inserting the newline after the blockquote, we don't want to apply the original style after the insertion
                shouldApplyStyleAfterInsertion = false;
            }

            // Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists).  However,
            // for div nodes, this can result in nested div tags that are hard to break out of.
            Element* siblingNode = startBlock;
            if (blockToInsert->hasTagName(divTag))
                siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlock);
            insertNodeAfter(blockToInsert, siblingNode);
        }

        // Recreate the same structure in the new paragraph.
        
        Vector<Element*> ancestors;
        getAncestorsInsideBlock(insertionPosition.node(), startBlock, ancestors);      
        RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);
        
        appendBlockPlaceholder(parent);

        setEndingSelection(VisibleSelection(Position(parent.get(), 0), DOWNSTREAM));
        return;
    }
    

    //---------------------------------------------------------------------
    // Handle case when position is in the first visible position in its block, and
    // similar case where previous position is in another, presumeably nested, block.
    if (isFirstInBlock || !inSameBlock(visiblePos, visiblePos.previous())) {
        Node *refNode;
        if (isFirstInBlock && !nestNewBlock)
            refNode = startBlock;
        else if (insertionPosition.node() == startBlock && nestNewBlock) {
            refNode = startBlock->childNode(insertionPosition.deprecatedEditingOffset());
            ASSERT(refNode); // must be true or we'd be in the end of block case
        } else
            refNode = insertionPosition.node();

        // find ending selection position easily before inserting the paragraph
        insertionPosition = insertionPosition.downstream();
        
        insertNodeBefore(blockToInsert, refNode);

        // Recreate the same structure in the new paragraph.

        Vector<Element*> ancestors;
        getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(insertionPosition).node(), startBlock, ancestors);
        
        appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToInsert));
        
        // In this case, we need to set the new ending selection.
        setEndingSelection(VisibleSelection(insertionPosition, DOWNSTREAM));
        return;
    }

    //---------------------------------------------------------------------
    // Handle the (more complicated) general case,

    // All of the content in the current block after visiblePos is
    // about to be wrapped in a new paragraph element.  Add a br before 
    // it if visiblePos is at the start of a paragraph so that the 
    // content will move down a line.
    if (isStartOfParagraph(visiblePos)) {
        RefPtr<Element> br = createBreakElement(document());
        insertNodeAt(br.get(), insertionPosition);
        insertionPosition = positionInParentAfterNode(br.get());
    }
    
    // Move downstream. Typing style code will take care of carrying along the 
    // style of the upstream position.
    insertionPosition = insertionPosition.downstream();

    // At this point, the insertionPosition's node could be a container, and we want to make sure we include
    // all of the correct nodes when building the ancestor list.  So this needs to be the deepest representation of the position
    // before we walk the DOM tree.
    insertionPosition = VisiblePosition(insertionPosition).deepEquivalent();

    // Build up list of ancestors in between the start node and the start block.
    Vector<Element*> ancestors;
    getAncestorsInsideBlock(insertionPosition.node(), startBlock, ancestors);

    // Make sure we do not cause a rendered space to become unrendered.
    // FIXME: We need the affinity for pos, but pos.downstream() does not give it
    Position leadingWhitespace = insertionPosition.leadingWhitespacePosition(VP_DEFAULT_AFFINITY);
    // FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions
    // after the preserved newline, causing the newline to be turned into a nbsp.
    if (leadingWhitespace.isNotNull()) {
        Text* textNode = static_cast<Text*>(leadingWhitespace.node());
        ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
        replaceTextInNode(textNode, leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString());
    }
    
    // Split at pos if in the middle of a text node.
    if (insertionPosition.node()->isTextNode()) {
        Text* textNode = static_cast<Text*>(insertionPosition.node());
        bool atEnd = (unsigned)insertionPosition.deprecatedEditingOffset() >= textNode->length();
        if (insertionPosition.deprecatedEditingOffset() > 0 && !atEnd) {
            splitTextNode(textNode, insertionPosition.deprecatedEditingOffset());
            insertionPosition.moveToOffset(0);
            visiblePos = VisiblePosition(insertionPosition);
            splitText = true;
        }
    }

    // Put the added block in the tree.
    if (nestNewBlock)
        appendNode(blockToInsert.get(), startBlock);
    else
        insertNodeAfter(blockToInsert.get(), startBlock);

    updateLayout();
    
    // Make clones of ancestors in between the start node and the outer block.
    RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);

    // If the paragraph separator was inserted at the end of a paragraph, an empty line must be
    // created.  All of the nodes, starting at visiblePos, are about to be added to the new paragraph 
    // element.  If the first node to be inserted won't be one that will hold an empty line open, add a br.
    if (isEndOfParagraph(visiblePos) && !lineBreakExistsAtVisiblePosition(visiblePos))
        appendNode(createBreakElement(document()).get(), blockToInsert.get());
        
    // Move the start node and the siblings of the start node.
    if (insertionPosition.node() != startBlock) {
        Node* n = insertionPosition.node();
        if (insertionPosition.deprecatedEditingOffset() >= caretMaxOffset(n))
            n = n->nextSibling();

        while (n && n != blockToInsert) {
            Node *next = n->nextSibling();
            removeNode(n);
            appendNode(n, parent.get());
            n = next;
        }
    }            

    // Move everything after the start node.
    if (!ancestors.isEmpty()) {
        Element* leftParent = ancestors.first();
        while (leftParent && leftParent != startBlock) {
            parent = parent->parentElement();
            if (!parent)
                break;
            Node* n = leftParent->nextSibling();
            while (n && n != blockToInsert) {
                Node* next = n->nextSibling();
                removeNode(n);
                appendNode(n, parent.get());
                n = next;
            }
            leftParent = leftParent->parentElement();
        }
    }

    // Handle whitespace that occurs after the split
    if (splitText) {
        updateLayout();
        insertionPosition = Position(insertionPosition.node(), 0);
        if (!insertionPosition.isRenderedCharacter()) {
            // Clear out all whitespace and insert one non-breaking space
            ASSERT(insertionPosition.node()->isTextNode());
            ASSERT(!insertionPosition.node()->renderer() || insertionPosition.node()->renderer()->style()->collapseWhiteSpace());
            deleteInsignificantTextDownstream(insertionPosition);
            insertTextIntoNode(static_cast<Text*>(insertionPosition.node()), 0, nonBreakingSpaceString());
        }
    }

    setEndingSelection(VisibleSelection(Position(blockToInsert.get(), 0), DOWNSTREAM));
    applyStyleAfterInsertion(startBlock);
}
Example #15
0
Element* Document::getElementById(const XMLString& elementId, const XMLString& idAttribute) const
{
	Element* pElem = documentElement();
	if (pElem) pElem = pElem->getElementById(elementId, idAttribute);
	return pElem;
}
Example #16
0
void DEIDynamic :: solveYourselfAt(TimeStep *tStep)
{
    //
    // creates system of governing eq's and solves them at given time step
    //
    // this is an explicit problem: we assemble governing equating at time t
    // and solution is obtained for time t+dt
    //
    // first assemble problem at current time step to obtain results in following
    // time step.
    // and then print results for this step also.
    // for first time step we need special start code
    Domain *domain = this->giveDomain(1);
    int nelem = domain->giveNumberOfElements();
    int nman = domain->giveNumberOfDofManagers();
    IntArray loc;
    Element *element;
    DofManager *node;
    Dof *iDof;
    int nDofs, neq;
    int i, k, n, j, jj, kk, init = 0;
    double coeff, maxDt, maxOmi, maxOm = 0., maxOmEl, c1, c2, c3;
    FloatMatrix charMtrx, charMtrx2;
    FloatArray previousDisplacementVector;


    neq = this->giveNumberOfDomainEquations(1, EModelDefaultEquationNumbering());
    if ( tStep->giveNumber() == giveNumberOfFirstStep() ) {
        init = 1;
#ifdef VERBOSE
        OOFEM_LOG_INFO("Assembling mass matrix\n");
#endif

        //
        // first step  assemble mass Matrix
        //

        massMatrix.resize(neq);
        massMatrix.zero();
        EModelDefaultEquationNumbering dn;
        for ( i = 1; i <= nelem; i++ ) {
            element = domain->giveElement(i);
            element->giveLocationArray(loc, EID_MomentumBalance, dn);
            element->giveCharacteristicMatrix(charMtrx,  LumpedMassMatrix, tStep);
            // charMtrx.beLumpedOf(fullCharMtrx);
            element->giveCharacteristicMatrix(charMtrx2, StiffnessMatrix, tStep);

            //
            // assemble it manually
            //
#ifdef DEBUG
            if ( ( n = loc.giveSize() ) != charMtrx.giveNumberOfRows() ) {
                _error("solveYourselfAt : dimension mismatch");
            }

#endif

            n = loc.giveSize();

            maxOmEl = 0.;
            for ( j = 1; j <= n; j++ ) {
                if ( charMtrx.at(j, j) > ZERO_MASS ) {
                    maxOmi =  charMtrx2.at(j, j) / charMtrx.at(j, j);
                    if ( init ) {
                        maxOmEl = ( maxOmEl > maxOmi ) ? ( maxOmEl ) : ( maxOmi );
                    }
                }
            }

            maxOm = ( maxOm > maxOmEl ) ? ( maxOm ) : ( maxOmEl );

            for ( j = 1; j <= n; j++ ) {
                jj = loc.at(j);
                if ( ( jj ) && ( charMtrx.at(j, j) <= ZERO_MASS ) ) {
                    charMtrx.at(j, j) = charMtrx2.at(j, j) / maxOmEl;
                }
            }

            for ( j = 1; j <= n; j++ ) {
                jj = loc.at(j);
                if ( jj ) {
                    massMatrix.at(jj) += charMtrx.at(j, j);
                }
            }
        }

        // if init - try to determine the best deltaT
        if ( init ) {
            maxDt = 2 / sqrt(maxOm);
            if ( deltaT > maxDt ) {
                OOFEM_LOG_RELEVANT("DEIDynamic: deltaT reduced to %e\n", maxDt);
                deltaT = maxDt;
                tStep->setTimeIncrement(deltaT);
            }
        }


        //
        // special init step - compute displacements at tstep 0
        //
        displacementVector.resize(neq);
        displacementVector.zero();
        nextDisplacementVector.resize(neq);
        nextDisplacementVector.zero();
        velocityVector.resize(neq);
        velocityVector.zero();
        accelerationVector.resize(neq);
        accelerationVector.zero();


        for ( j = 1; j <= nman; j++ ) {
            node = domain->giveDofManager(j);
            nDofs = node->giveNumberOfDofs();

            for ( k = 1; k <= nDofs; k++ ) {
                // ask for initial values obtained from
                // bc (boundary conditions) and ic (initial conditions)
                // now we are setting initial cond. for step -1.
                iDof  =  node->giveDof(k);
                if ( !iDof->isPrimaryDof() ) {
                    continue;
                }

                jj = iDof->__giveEquationNumber();
                if ( jj ) {
                    nextDisplacementVector.at(jj) = iDof->giveUnknown(VM_Total, tStep);
                    // become displacementVector after init
                    velocityVector.at(jj)     = iDof->giveUnknown(VM_Velocity, tStep);
                    // accelerationVector = iDof->giveUnknown(AccelerartionVector,tStep) ;
                }
            }
        }

        for ( j = 1; j <= neq; j++ ) {
            nextDisplacementVector.at(j) -= velocityVector.at(j) * ( deltaT );
        }

        return;
    } // end of init step

#ifdef VERBOSE
    OOFEM_LOG_INFO("Assembling right hand side\n");
#endif


    c1 = ( 1. / ( deltaT * deltaT ) );
    c2 = ( 1. / ( 2. * deltaT ) );
    c3 = ( 2. / ( deltaT * deltaT ) );

    previousDisplacementVector = displacementVector;
    displacementVector         = nextDisplacementVector;

    //
    // assembling the element part of load vector
    //
    loadVector.resize( this->giveNumberOfDomainEquations(1, EModelDefaultEquationNumbering()) );
    loadVector.zero();
    this->assembleVector(loadVector, tStep, EID_MomentumBalance, ExternalForcesVector,
                         VM_Total, EModelDefaultEquationNumbering(), domain);

    //
    // assembling additional parts of right hand side
    //
    EModelDefaultEquationNumbering dn;
    for ( i = 1; i <= nelem; i++ ) {
        element = domain->giveElement(i);
        element->giveLocationArray(loc, EID_MomentumBalance, dn);
        element->giveCharacteristicMatrix(charMtrx, StiffnessMatrix, tStep);
        n = loc.giveSize();
        for ( j = 1; j <= n; j++ ) {
            jj = loc.at(j);
            if ( jj ) {
                for ( k = 1; k <= n; k++ ) {
                    kk = loc.at(k);
                    if ( kk ) {
                        loadVector.at(jj) -= charMtrx.at(j, k) * displacementVector.at(kk);
                    }
                }

                //
                // if init step - find minimum period of vibration in order to
                // determine maximal admissible time step
                //
                //maxOmi =  charMtrx.at(j,j)/massMatrix.at(jj) ;
                //if (init) maxOm = (maxOm > maxOmi) ? (maxOm) : (maxOmi) ;
            }
        }
    }



    for ( j = 1; j <= neq; j++ ) {
        coeff =  massMatrix.at(j);
        loadVector.at(j) += coeff * c3 * displacementVector.at(j) -
                            coeff * ( c1 - dumpingCoef * c2 ) *
                            previousDisplacementVector.at(j);
    }

    //
    // set-up numerical model
    //
    /* it is not necessary to call numerical method
     * approach used here is not good, but effective enough
     * inverse of diagonal mass matrix is done here
     */
    //
    // call numerical model to solve arose problem - done locally here
    //
#ifdef VERBOSE
    OOFEM_LOG_RELEVANT( "Solving [step number %8d, time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
#endif
    double prevD;

    for ( i = 1; i <= neq; i++ ) {
        prevD = previousDisplacementVector.at(i);
        nextDisplacementVector.at(i) = loadVector.at(i) /
                                       ( massMatrix.at(i) * ( c1 + dumpingCoef * c2 ) );
        velocityVector.at(i) = nextDisplacementVector.at(i) - prevD;
        accelerationVector.at(i) =
            nextDisplacementVector.at(i) -
            2. * displacementVector.at(i) + prevD;
    }

    accelerationVector.times(c1);
    velocityVector.times(c2);
}
Example #17
0
Element* Document::getElementByIdNS(const XMLString& elementId, const XMLString& idAttributeURI, const XMLString& idAttributeLocalName) const
{
	Element* pElem = documentElement();
	if (pElem) pElem = pElem->getElementByIdNS(elementId, idAttributeURI, idAttributeLocalName);
	return pElem;
}
void CompressibleNonlinearElasticitySolver<DIM>::AssembleOnElement(
            Element<DIM, DIM>& rElement,
            c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElem,
            c_matrix<double, STENCIL_SIZE, STENCIL_SIZE >& rAElemPrecond,
            c_vector<double, STENCIL_SIZE>& rBElem,
            bool assembleResidual,
            bool assembleJacobian)
{
    static c_matrix<double,DIM,DIM> jacobian;
    static c_matrix<double,DIM,DIM> inverse_jacobian;
    double jacobian_determinant;

    this->mrQuadMesh.GetInverseJacobianForElement(rElement.GetIndex(), jacobian, jacobian_determinant, inverse_jacobian);

    if (assembleJacobian)
    {
        rAElem.clear();
        rAElemPrecond.clear();
    }

    if (assembleResidual)
    {
        rBElem.clear();
    }

    // Get the current displacement at the nodes
    static c_matrix<double,DIM,NUM_NODES_PER_ELEMENT> element_current_displacements;
    for (unsigned II=0; II<NUM_NODES_PER_ELEMENT; II++)
    {
        for (unsigned JJ=0; JJ<DIM; JJ++)
        {
            element_current_displacements(JJ,II) = this->mCurrentSolution[DIM*rElement.GetNodeGlobalIndex(II) + JJ];
        }
    }

    // Allocate memory for the basis functions values and derivative values
    static c_vector<double, NUM_VERTICES_PER_ELEMENT> linear_phi;
    static c_vector<double, NUM_NODES_PER_ELEMENT> quad_phi;
    static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> grad_quad_phi;
    static c_matrix<double, NUM_NODES_PER_ELEMENT, DIM> trans_grad_quad_phi;

    // Get the material law
    AbstractCompressibleMaterialLaw<DIM>* p_material_law
       = this->mrProblemDefinition.GetCompressibleMaterialLaw(rElement.GetIndex());


    static c_matrix<double,DIM,DIM> grad_u; // grad_u = (du_i/dX_M)

    static c_matrix<double,DIM,DIM> F;      // the deformation gradient, F = dx/dX, F_{iM} = dx_i/dX_M
    static c_matrix<double,DIM,DIM> C;      // Green deformation tensor, C = F^T F
    static c_matrix<double,DIM,DIM> inv_C;  // inverse(C)
    static c_matrix<double,DIM,DIM> inv_F;  // inverse(F)
    static c_matrix<double,DIM,DIM> T;      // Second Piola-Kirchoff stress tensor (= dW/dE = 2dW/dC)

    static c_matrix<double,DIM,DIM> F_T;    // F*T
    static c_matrix<double,DIM,NUM_NODES_PER_ELEMENT> F_T_grad_quad_phi; // F*T*grad_quad_phi

    c_vector<double,DIM> body_force;

    static FourthOrderTensor<DIM,DIM,DIM,DIM> dTdE;    // dTdE(M,N,P,Q) = dT_{MN}/dE_{PQ}
    static FourthOrderTensor<DIM,DIM,DIM,DIM> dSdF;    // dSdF(M,i,N,j) = dS_{Mi}/dF_{jN}

    static FourthOrderTensor<NUM_NODES_PER_ELEMENT,DIM,DIM,DIM> temp_tensor;
    static FourthOrderTensor<NUM_NODES_PER_ELEMENT,DIM,NUM_NODES_PER_ELEMENT,DIM> dSdF_quad_quad;

    static c_matrix<double, DIM, NUM_NODES_PER_ELEMENT> temp_matrix;
    static c_matrix<double,NUM_NODES_PER_ELEMENT,DIM> grad_quad_phi_times_invF;

    if(this->mSetComputeAverageStressPerElement)
    {
        this->mAverageStressesPerElement[rElement.GetIndex()] = zero_vector<double>(DIM*(DIM+1)/2);
    }

    // Loop over Gauss points
    for (unsigned quadrature_index=0; quadrature_index < this->mpQuadratureRule->GetNumQuadPoints(); quadrature_index++)
    {
        // This is needed by the cardiac mechanics solver
        unsigned current_quad_point_global_index =   rElement.GetIndex()*this->mpQuadratureRule->GetNumQuadPoints()
                                                   + quadrature_index;

        double wJ = jacobian_determinant * this->mpQuadratureRule->GetWeight(quadrature_index);

        const ChastePoint<DIM>& quadrature_point = this->mpQuadratureRule->rGetQuadPoint(quadrature_index);

        // Set up basis function information
        LinearBasisFunction<DIM>::ComputeBasisFunctions(quadrature_point, linear_phi);
        QuadraticBasisFunction<DIM>::ComputeBasisFunctions(quadrature_point, quad_phi);
        QuadraticBasisFunction<DIM>::ComputeTransformedBasisFunctionDerivatives(quadrature_point, inverse_jacobian, grad_quad_phi);
        trans_grad_quad_phi = trans(grad_quad_phi);

        // Get the body force, interpolating X if necessary
        if (assembleResidual)
        {
            switch (this->mrProblemDefinition.GetBodyForceType())
            {
                case FUNCTIONAL_BODY_FORCE:
                {
                    c_vector<double,DIM> X = zero_vector<double>(DIM);
                    // interpolate X (using the vertices and the /linear/ bases, as no curvilinear elements
                    for (unsigned node_index=0; node_index<NUM_VERTICES_PER_ELEMENT; node_index++)
                    {
                        X += linear_phi(node_index)*this->mrQuadMesh.GetNode( rElement.GetNodeGlobalIndex(node_index) )->rGetLocation();
                    }
                    body_force = this->mrProblemDefinition.EvaluateBodyForceFunction(X, this->mCurrentTime);
                    break;
                }
                case CONSTANT_BODY_FORCE:
                {
                    body_force = this->mrProblemDefinition.GetConstantBodyForce();
                    break;
                }
                default:
                    NEVER_REACHED;
            }
        }

        // Interpolate grad_u
        grad_u = zero_matrix<double>(DIM,DIM);
        for (unsigned node_index=0; node_index<NUM_NODES_PER_ELEMENT; node_index++)
        {
            for (unsigned i=0; i<DIM; i++)
            {
                for (unsigned M=0; M<DIM; M++)
                {
                    grad_u(i,M) += grad_quad_phi(M,node_index)*element_current_displacements(i,node_index);
                }
            }
        }

        // Calculate C, inv(C) and T
        for (unsigned i=0; i<DIM; i++)
        {
            for (unsigned M=0; M<DIM; M++)
            {
                F(i,M) = (i==M?1:0) + grad_u(i,M);
            }
        }

        C = prod(trans(F),F);
        inv_C = Inverse(C);
        inv_F = Inverse(F);

        // Compute the passive stress, and dTdE corresponding to passive stress
        this->SetupChangeOfBasisMatrix(rElement.GetIndex(), current_quad_point_global_index);
        p_material_law->SetChangeOfBasisMatrix(this->mChangeOfBasisMatrix);
        p_material_law->ComputeStressAndStressDerivative(C, inv_C, 0.0, T, dTdE, assembleJacobian);

        if(this->mIncludeActiveTension)
        {
            // Add any active stresses, if there are any. Requires subclasses to overload this method,
            // see for example the cardiac mechanics assemblers.
            this->AddActiveStressAndStressDerivative(C, rElement.GetIndex(), current_quad_point_global_index,
                                                     T, dTdE, assembleJacobian);
        }

        if(this->mSetComputeAverageStressPerElement)
        {
            this->AddStressToAverageStressPerElement(T,rElement.GetIndex());
        }

        // Residual vector
        if (assembleResidual)
        {
            F_T = prod(F,T);
            F_T_grad_quad_phi = prod(F_T, grad_quad_phi);

            for (unsigned index=0; index<NUM_NODES_PER_ELEMENT*DIM; index++)
            {
                unsigned spatial_dim = index%DIM;
                unsigned node_index = (index-spatial_dim)/DIM;

                rBElem(index) += - this->mrProblemDefinition.GetDensity()
                                 * body_force(spatial_dim)
                                 * quad_phi(node_index)
                                 * wJ;

                // The T(M,N)*F(spatial_dim,M)*grad_quad_phi(N,node_index) term
                rBElem(index) +=   F_T_grad_quad_phi(spatial_dim,node_index)
                                 * wJ;
            }
        }

        // Jacobian matrix
        if (assembleJacobian)
        {
            // Save trans(grad_quad_phi) * invF
            grad_quad_phi_times_invF = prod(trans_grad_quad_phi, inv_F);

            /////////////////////////////////////////////////////////////////////////////////////////////
            // Set up the tensor dSdF
            //
            // dSdF as a function of T and dTdE (which is what the material law returns) is given by:
            //
            // dS_{Mi}/dF_{jN} = (dT_{MN}/dC_{PQ}+dT_{MN}/dC_{PQ}) F{iP} F_{jQ}  + T_{MN} delta_{ij}
            //
            // todo1: this should probably move into the material law (but need to make sure
            // memory is handled efficiently
            // todo2: get material law to return this immediately, not dTdE
            /////////////////////////////////////////////////////////////////////////////////////////////

            // Set up the tensor 0.5(dTdE(M,N,P,Q) + dTdE(M,N,Q,P))
            for (unsigned M=0; M<DIM; M++)
            {
                for (unsigned N=0; N<DIM; N++)
                {
                    for (unsigned P=0; P<DIM; P++)
                    {
                        for (unsigned Q=0; Q<DIM; Q++)
                        {
                            // this is NOT dSdF, just using this as storage space
                            dSdF(M,N,P,Q) = 0.5*(dTdE(M,N,P,Q) + dTdE(M,N,Q,P));
                        }
                    }
                }
            }

            // This is NOT dTdE, just reusing memory. A^{MdPQ}  = F^d_N * dTdE_sym^{MNPQ}
            dTdE.template SetAsContractionOnSecondDimension<DIM>(F, dSdF);

            // dSdF{MdPe} := F^d_N * F^e_Q * dTdE_sym^{MNPQ}
            dSdF.template SetAsContractionOnFourthDimension<DIM>(F, dTdE);

            // Now add the T_{MN} delta_{ij} term
            for (unsigned M=0; M<DIM; M++)
            {
                for (unsigned N=0; N<DIM; N++)
                {
                    for (unsigned i=0; i<DIM; i++)
                    {
                        dSdF(M,i,N,i) += T(M,N);
                    }
                }
            }

            ///////////////////////////////////////////////////////
            // Set up the tensor
            //   dSdF_quad_quad(node_index1, spatial_dim1, node_index2, spatial_dim2)
            //            =    dS_{M,spatial_dim1}/d_F{spatial_dim2,N}
            //               * grad_quad_phi(M,node_index1)
            //               * grad_quad_phi(P,node_index2)
            //
            //            =    dSdF(M,spatial_index1,N,spatial_index2)
            //               * grad_quad_phi(M,node_index1)
            //               * grad_quad_phi(P,node_index2)
            //
            ///////////////////////////////////////////////////////
            temp_tensor.template SetAsContractionOnFirstDimension<DIM>(trans_grad_quad_phi, dSdF);
            dSdF_quad_quad.template SetAsContractionOnThirdDimension<DIM>(trans_grad_quad_phi, temp_tensor);

            for (unsigned index1=0; index1<NUM_NODES_PER_ELEMENT*DIM; index1++)
            {
                unsigned spatial_dim1 = index1%DIM;
                unsigned node_index1 = (index1-spatial_dim1)/DIM;

                for (unsigned index2=0; index2<NUM_NODES_PER_ELEMENT*DIM; index2++)
                {
                    unsigned spatial_dim2 = index2%DIM;
                    unsigned node_index2 = (index2-spatial_dim2)/DIM;

                    // The dSdF*grad_quad_phi*grad_quad_phi term
                    rAElem(index1,index2) +=   dSdF_quad_quad(node_index1,spatial_dim1,node_index2,spatial_dim2)
                                             * wJ;
                }
            }
        }
    }

    rAElemPrecond.clear();
    if (assembleJacobian)
    {
        rAElemPrecond = rAElem;
    }

    if(this->mSetComputeAverageStressPerElement)
    {
        for(unsigned i=0; i<DIM*(DIM+1)/2; i++)
        {
            this->mAverageStressesPerElement[rElement.GetIndex()](i) /= this->mpQuadratureRule->GetNumQuadPoints();
        }
    }

}
Example #19
0
void
nsNodeUtils::LastRelease(nsINode* aNode)
{
  nsINode::nsSlots* slots = aNode->GetExistingSlots();
  if (slots) {
    if (!slots->mMutationObservers.IsEmpty()) {
      NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
                                         nsIMutationObserver,
                                         NodeWillBeDestroyed, (aNode));
    }

    delete slots;
    aNode->mSlots = nullptr;
  }

  // Kill properties first since that may run external code, so we want to
  // be in as complete state as possible at that time.
  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
    // Delete all properties before tearing down the document. Some of the
    // properties are bound to nsINode objects and the destructor functions of
    // the properties may want to use the owner document of the nsINode.
    static_cast<nsIDocument*>(aNode)->DeleteAllProperties();
  }
  else {
    if (aNode->HasProperties()) {
      // Strong reference to the document so that deleting properties can't
      // delete the document.
      nsCOMPtr<nsIDocument> document = aNode->OwnerDoc();
      document->DeleteAllPropertiesFor(aNode);
    }

    // I wonder whether it's faster to do the HasFlag check first....
    if (aNode->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) &&
        aNode->HasFlag(ADDED_TO_FORM)) {
      // Tell the form (if any) this node is going away.  Don't
      // notify, since we're being destroyed in any case.
      static_cast<nsGenericHTMLFormElement*>(aNode)->ClearForm(true);
    }

    if (aNode->IsHTMLElement(nsGkAtoms::img) &&
        aNode->HasFlag(ADDED_TO_FORM)) {
      HTMLImageElement* imageElem = static_cast<HTMLImageElement*>(aNode);
      imageElem->ClearForm(true);
    }
  }
  aNode->UnsetFlags(NODE_HAS_PROPERTIES);

  if (aNode->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
      aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
#ifdef DEBUG
    if (nsContentUtils::IsInitialized()) {
      EventListenerManager* manager =
        nsContentUtils::GetExistingListenerManagerForNode(aNode);
      if (!manager) {
        NS_ERROR("Huh, our bit says we have a listener manager list, "
                 "but there's nothing in the hash!?!!");
      }
    }
#endif

    nsContentUtils::RemoveListenerManager(aNode);
    aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
  }

  if (aNode->IsElement()) {
    nsIDocument* ownerDoc = aNode->OwnerDoc();
    Element* elem = aNode->AsElement();
    ownerDoc->ClearBoxObjectFor(elem);

    NS_ASSERTION(aNode->HasFlag(NODE_FORCE_XBL_BINDINGS) ||
                 !elem->GetXBLBinding(),
                 "Non-forced node has binding on destruction");

    // if NODE_FORCE_XBL_BINDINGS is set, the node might still have a binding
    // attached
    if (aNode->HasFlag(NODE_FORCE_XBL_BINDINGS) &&
        ownerDoc->BindingManager()) {
      ownerDoc->BindingManager()->RemovedFromDocument(elem, ownerDoc,
                                                      nsBindingManager::eRunDtor);
    }
  }

  aNode->ReleaseWrapper(aNode);

  FragmentOrElement::RemoveBlackMarkedNode(aNode);
}
void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
{
    Frame* frame = element.document().frame();
    ASSERT(frame);
    frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
}
Example #21
0
bool AccessibilityTable::isDataTable() const
{
    if (!m_renderer)
        return false;

    // Do not consider it a data table is it has an ARIA role.
    if (hasARIARole())
        return false;

    // When a section of the document is contentEditable, all tables should be
    // treated as data tables, otherwise users may not be able to work with rich
    // text editors that allow creating and editing tables.
    if (node() && node()->hasEditableStyle())
        return true;

    if (!m_renderer->isTable())
        return false;

    // This employs a heuristic to determine if this table should appear.
    // Only "data" tables should be exposed as tables.
    // Unfortunately, there is no good way to determine the difference
    // between a "layout" table and a "data" table.
    RenderTable* table = toRenderTable(m_renderer);
    HTMLTableElement* tableElement = this->tableElement();
    if (tableElement) {
        // If there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table.
        if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption())
            return true;
        
        // If someone used "rules" attribute than the table should appear.
        if (!tableElement->rules().isEmpty())
            return true;

        // If there's a colgroup or col element, it's probably a data table.
        for (const auto& child : childrenOfType<Element>(*tableElement)) {
            if (child.hasTagName(colTag) || child.hasTagName(colgroupTag))
                return true;
        }
    }
    
    // go through the cell's and check for tell-tale signs of "data" table status
    // cells have borders, or use attributes like headers, abbr, scope or axis
    table->recalcSectionsIfNeeded();
    RenderTableSection* firstBody = table->firstBody();
    if (!firstBody)
        return false;
    
    int numCols = firstBody->numColumns();
    int numRows = firstBody->numRows();
    
    // If there's only one cell, it's not a good AXTable candidate.
    if (numRows == 1 && numCols == 1)
        return false;

    // If there are at least 20 rows, we'll call it a data table.
    if (numRows >= 20)
        return true;
    
    // Store the background color of the table to check against cell's background colors.
    const RenderStyle& tableStyle = table->style();
    Color tableBGColor = tableStyle.visitedDependentColor(CSSPropertyBackgroundColor);
    
    // check enough of the cells to find if the table matches our criteria
    // Criteria: 
    //   1) must have at least one valid cell (and)
    //   2) at least half of cells have borders (or)
    //   3) at least half of cells have different bg colors than the table, and there is cell spacing
    unsigned validCellCount = 0;
    unsigned borderedCellCount = 0;
    unsigned backgroundDifferenceCellCount = 0;
    unsigned cellsWithTopBorder = 0;
    unsigned cellsWithBottomBorder = 0;
    unsigned cellsWithLeftBorder = 0;
    unsigned cellsWithRightBorder = 0;
    
    Color alternatingRowColors[5];
    int alternatingRowColorCount = 0;
    
    int headersInFirstColumnCount = 0;
    for (int row = 0; row < numRows; ++row) {
    
        int headersInFirstRowCount = 0;
        for (int col = 0; col < numCols; ++col) {    
            RenderTableCell* cell = firstBody->primaryCellAt(row, col);
            if (!cell)
                continue;

            Element* cellElement = cell->element();
            if (!cellElement)
                continue;
            
            if (cell->width() < 1 || cell->height() < 1)
                continue;
            
            validCellCount++;
            
            bool isTHCell = cellElement->hasTagName(thTag);
            // If the first row is comprised of all <th> tags, assume it is a data table.
            if (!row && isTHCell)
                headersInFirstRowCount++;

            // If the first column is comprised of all <th> tags, assume it is a data table.
            if (!col && isTHCell)
                headersInFirstColumnCount++;
            
            // In this case, the developer explicitly assigned a "data" table attribute.
            if (cellElement->hasTagName(tdTag) || cellElement->hasTagName(thTag)) {
                HTMLTableCellElement* tableCellElement = toHTMLTableCellElement(cellElement);
                if (!tableCellElement->headers().isEmpty() || !tableCellElement->abbr().isEmpty()
                    || !tableCellElement->axis().isEmpty() || !tableCellElement->scope().isEmpty())
                    return true;
            }
            const RenderStyle& renderStyle = cell->style();

            // If the empty-cells style is set, we'll call it a data table.
            if (renderStyle.emptyCells() == HIDE)
                return true;

            // If a cell has matching bordered sides, call it a (fully) bordered cell.
            if ((cell->borderTop() > 0 && cell->borderBottom() > 0)
                || (cell->borderLeft() > 0 && cell->borderRight() > 0))
                borderedCellCount++;

            // Also keep track of each individual border, so we can catch tables where most
            // cells have a bottom border, for example.
            if (cell->borderTop() > 0)
                cellsWithTopBorder++;
            if (cell->borderBottom() > 0)
                cellsWithBottomBorder++;
            if (cell->borderLeft() > 0)
                cellsWithLeftBorder++;
            if (cell->borderRight() > 0)
                cellsWithRightBorder++;
            
            // If the cell has a different color from the table and there is cell spacing,
            // then it is probably a data table cell (spacing and colors take the place of borders).
            Color cellColor = renderStyle.visitedDependentColor(CSSPropertyBackgroundColor);
            if (table->hBorderSpacing() > 0 && table->vBorderSpacing() > 0
                && tableBGColor != cellColor && cellColor.alpha() != 1)
                backgroundDifferenceCellCount++;
            
            // If we've found 10 "good" cells, we don't need to keep searching.
            if (borderedCellCount >= 10 || backgroundDifferenceCellCount >= 10)
                return true;
            
            // For the first 5 rows, cache the background color so we can check if this table has zebra-striped rows.
            if (row < 5 && row == alternatingRowColorCount) {
                RenderObject* renderRow = cell->parent();
                if (!renderRow || !renderRow->isBoxModelObject() || !toRenderBoxModelObject(renderRow)->isTableRow())
                    continue;
                const RenderStyle& rowRenderStyle = renderRow->style();
                Color rowColor = rowRenderStyle.visitedDependentColor(CSSPropertyBackgroundColor);
                alternatingRowColors[alternatingRowColorCount] = rowColor;
                alternatingRowColorCount++;
            }
        }
        
        if (!row && headersInFirstRowCount == numCols && numCols > 1)
            return true;
    }

    if (headersInFirstColumnCount == numRows && numRows > 1)
        return true;
    
    // if there is less than two valid cells, it's not a data table
    if (validCellCount <= 1)
        return false;
    
    // half of the cells had borders, it's a data table
    unsigned neededCellCount = validCellCount / 2;
    if (borderedCellCount >= neededCellCount
        || cellsWithTopBorder >= neededCellCount
        || cellsWithBottomBorder >= neededCellCount
        || cellsWithLeftBorder >= neededCellCount
        || cellsWithRightBorder >= neededCellCount)
        return true;
    
    // half had different background colors, it's a data table
    if (backgroundDifferenceCellCount >= neededCellCount)
        return true;

    // Check if there is an alternating row background color indicating a zebra striped style pattern.
    if (alternatingRowColorCount > 2) {
        Color firstColor = alternatingRowColors[0];
        for (int k = 1; k < alternatingRowColorCount; k++) {
            // If an odd row was the same color as the first row, its not alternating.
            if (k % 2 == 1 && alternatingRowColors[k] == firstColor)
                return false;
            // If an even row is not the same as the first row, its not alternating.
            if (!(k % 2) && alternatingRowColors[k] != firstColor)
                return false;
        }
        return true;
    }
    
    return false;
}
void
SolutionbasedShapeFunction :: computeCorrectionFactors(modeStruct &myMode, IntArray *Dofs, double *am, double *ap)
{
    /*
     * *Compute c0, cp, cm, Bp, Bm, Ap and Am
     */

    double A0p = 0.0, App = 0.0, A0m = 0.0, Amm = 0.0, Bp = 0.0, Bm = 0.0, c0 = 0.0, cp = 0.0, cm = 0.0;

    EngngModel *model = myMode.myEngngModel;
    Set *mySet = model->giveDomain(1)->giveSet(externalSet);

    IntArray BoundaryList = mySet->giveBoundaryList();

    for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) {
        int ElementID = BoundaryList(2 * i);
        int Boundary = BoundaryList(2 * i + 1);

        Element *thisElement = model->giveDomain(1)->giveElement(ElementID);
        FEInterpolation *geoInterpolation = thisElement->giveInterpolation();
        IntArray bnodes, zNodes, pNodes, mNodes;
        FloatMatrix nodeValues;

        geoInterpolation->boundaryGiveNodes(bnodes, Boundary);

        nodeValues.resize( this->dofs.giveSize(), bnodes.giveSize() );
        nodeValues.zero();

        // Change to global ID for bnodes and identify the intersection of bnodes and the zero boundary
        splitBoundaryNodeIDs(myMode, * thisElement, bnodes, pNodes, mNodes, zNodes, nodeValues);

        std :: unique_ptr< IntegrationRule >iRule(geoInterpolation->giveBoundaryIntegrationRule(order, Boundary));

        for ( GaussPoint *gp: *iRule ) {
            const FloatArray &lcoords = gp->giveNaturalCoordinates();
            FloatArray gcoords, normal, N;
            FloatArray Phi;

            double detJ = fabs( geoInterpolation->boundaryGiveTransformationJacobian( Boundary, lcoords, FEIElementGeometryWrapper(thisElement) ) ) * gp->giveWeight();

            geoInterpolation->boundaryEvalNormal( normal, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );
            geoInterpolation->boundaryEvalN( N, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );
            geoInterpolation->boundaryLocal2Global( gcoords, Boundary, lcoords, FEIElementGeometryWrapper(thisElement) );

            FloatArray pPhi, mPhi, zPhi;
            pPhi.resize( Dofs->giveSize() );
            pPhi.zero();
            mPhi.resize( Dofs->giveSize() );
            mPhi.zero();
            zPhi.resize( Dofs->giveSize() );
            zPhi.zero();

            // Build phi (analytical averaging, not projected onto the mesh)
            computeBaseFunctionValueAt(Phi, gcoords, * Dofs, * myMode.myEngngModel);

            // Build zPhi for this DofID
            for ( int l = 1; l <= zNodes.giveSize(); l++ ) {
                int nodeID = zNodes.at(l);
                for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
                    zPhi.at(m) = zPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
                }
            }


            // Build pPhi for this DofID
            for ( int l = 1; l <= pNodes.giveSize(); l++ ) {
                int nodeID = pNodes.at(l);
                for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
                    pPhi.at(m) = pPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
                }
            }

            // Build mPhi for this DofID
            for ( int l = 1; l <= mNodes.giveSize(); l++ ) {
                int nodeID = mNodes.at(l);
                for ( int m = 1; m <= this->dofs.giveSize(); m++ ) {
                    mPhi.at(m) = mPhi.at(m) + N.at(nodeID) * nodeValues.at(m, nodeID);
                }
            }

            c0 = c0 + zPhi.dotProduct(normal, 3) * detJ;
            cp = cp + pPhi.dotProduct(normal, 3) * detJ;
            cm = cm + mPhi.dotProduct(normal, 3) * detJ;

            App = App + pPhi.dotProduct(pPhi, 3) * detJ;
            Amm = Amm + mPhi.dotProduct(mPhi, 3) * detJ;
            A0p = A0p + zPhi.dotProduct(pPhi, 3) * detJ;
            A0m = A0m + zPhi.dotProduct(mPhi, 3) * detJ;

            Bp = Bp + Phi.dotProduct(pPhi, 3) * detJ;
            Bm = Bm + Phi.dotProduct(mPhi, 3) * detJ;
        }
    }

    * am = -( A0m * cp * cp - Bm * cp * cp - A0p * cm * cp + App * c0 * cm + Bp * cm * cp ) / ( App * cm * cm + Amm * cp * cp );
    * ap = -( A0p * cm * cm - Bp * cm * cm - A0m * cm * cp + Amm * c0 * cp + Bm * cm * cp ) / ( App * cm * cm + Amm * cp * cp );
}
Example #23
0
nsresult
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  nsNodeInfoManager *nodeInfoManager = GetContent()->GetComposedDoc()->NodeInfoManager();
  RefPtr<NodeInfo> nodeInfo;
  Element *element;

  if (HasVideoElement()) {
    // Create an anonymous image element as a child to hold the poster
    // image. We may not have a poster image now, but one could be added
    // before we load, or on a subsequent load.
    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img,
                                            nullptr,
                                            kNameSpaceID_XHTML,
                                            nsIDOMNode::ELEMENT_NODE);
    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
    element = NS_NewHTMLImageElement(nodeInfo.forget());
    mPosterImage = element;
    NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY);

    // Set the nsImageLoadingContent::ImageState() to 0. This means that the
    // image will always report its state as 0, so it will never be reframed
    // to show frames for loading or the broken image icon. This is important,
    // as the image is native anonymous, and so can't be reframed (currently).
    nsCOMPtr<nsIImageLoadingContent> imgContent = do_QueryInterface(mPosterImage);
    NS_ENSURE_TRUE(imgContent, NS_ERROR_FAILURE);

    imgContent->ForceImageState(true, 0);
    // And now have it update its internal state
    element->UpdateState(false);

    UpdatePosterSource(false);

    if (!aElements.AppendElement(mPosterImage))
      return NS_ERROR_OUT_OF_MEMORY;

    // Set up the caption overlay div for showing any TextTrack data
    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::div,
                                            nullptr,
                                            kNameSpaceID_XHTML,
                                            nsIDOMNode::ELEMENT_NODE);
    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
    mCaptionDiv = NS_NewHTMLDivElement(nodeInfo.forget());
    NS_ENSURE_TRUE(mCaptionDiv, NS_ERROR_OUT_OF_MEMORY);
    nsGenericHTMLElement* div = static_cast<nsGenericHTMLElement*>(mCaptionDiv.get());
    div->SetClassName(NS_LITERAL_STRING("caption-box"));

    if (!aElements.AppendElement(mCaptionDiv))
      return NS_ERROR_OUT_OF_MEMORY;
  }

  // Set up "videocontrols" XUL element which will be XBL-bound to the
  // actual controls.
  nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::videocontrols,
                                          nullptr,
                                          kNameSpaceID_XUL,
                                          nsIDOMNode::ELEMENT_NODE);
  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);

  NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget());
  if (!aElements.AppendElement(mVideoControls))
    return NS_ERROR_OUT_OF_MEMORY;

  return NS_OK;
}
void
SolutionbasedShapeFunction :: initializeSurfaceData(modeStruct *mode)
{

    EngngModel *m=mode->myEngngModel;
    double TOL2=1e-3;

    IntArray pNodes, mNodes, zNodes;

    Set *mySet = this->domain->giveSet( this->giveSetNumber() );
    IntArray BoundaryList = mySet->giveBoundaryList();

    // First add all nodes to pNodes or nNodes respectively depending on coordinate and normal.
    for ( int i = 0; i < BoundaryList.giveSize() / 2; i++ ) {
        int ElementID = BoundaryList(2 * i);
        int Boundary = BoundaryList(2 * i + 1);

        Element *e = m->giveDomain(1)->giveElement(ElementID);
        FEInterpolation *geoInterpolation = e->giveInterpolation();

        // Check all sides of element
        IntArray bnodes;

#define usePoints 1
#if usePoints == 1
        // Check if all nodes are on the boundary
        geoInterpolation->boundaryGiveNodes(bnodes, Boundary);
        for ( int k = 1; k <= bnodes.giveSize(); k++ ) {
            DofManager *dman = e->giveDofManager( bnodes.at(k) );
            for ( int l = 1; l <= dman->giveCoordinates()->giveSize(); l++ ) {
                if ( fabs( dman->giveCoordinates()->at(l) - maxCoord.at(l) ) < TOL2 ) {
                    pNodes.insertOnce( dman->giveNumber() );
                }
                if ( fabs( dman->giveCoordinates()->at(l) - minCoord.at(l) ) < TOL2 ) {
                    mNodes.insertOnce( dman->giveNumber() );
                }
            }
        }
#else
        // Check normal
        FloatArray lcoords;
        lcoords.resize(2);
        lcoords.at(1) = 0.33333;
        lcoords.at(2) = 0.33333;

        FloatArray normal;
        geoInterpolation->boundaryEvalNormal( normal, j, lcoords, FEIElementGeometryWrapper(e) );
        geoInterpolation->boundaryGiveNodes(bnodes, j);

        printf( "i=%u\tj=%u\t(%f\t%f\t%f)\n", i, j, normal.at(1), normal.at(2), normal.at(3) );
        for ( int k = 1; k <= normal.giveSize(); k++ ) {
            if ( fabs( ( fabs( normal.at(k) ) - 1 ) ) < 1e-4 ) { // Points in x, y or z direction
                addTo = NULL;
                if ( normal.at(k) > 0.5 ) {
                    addTo = & pNodes;
                }
                if ( normal.at(k) < -0.5 ) {
                    addTo = & mNodes;
                }
                if ( addTo != NULL ) {
                    for ( int l = 1; l <= bnodes.giveSize(); l++ ) {
                        bool isSurface = false;
                        DofManager *dman = e->giveDofManager( bnodes.at(l) );
                        dman->giveCoordinates()->printYourself();
                        for ( int m = 1; m <= dman->giveCoordinates()->giveSize(); m++ ) {
                            if ( ( fabs( dman->giveCoordinates()->at(m) - maxCoord.at(m) ) < TOL2 ) || ( fabs( dman->giveCoordinates()->at(m) - minCoord.at(m) ) < TOL2 ) ) {
                                isSurface = true;
                            }
                        }

                        if ( isSurface ) {
                            addTo->insertOnce( e->giveDofManagerNumber( bnodes.at(l) ) );
                        }
                    }
                }
            }
        }
#endif
    }

#if 0
    printf("p=[");
    for ( int i = 1; i < pNodes.giveSize(); i++ ) {
        printf( "%u, ", pNodes.at(i) );
    }
    printf("];\n");
    printf("m=[");
    for ( int i = 1; i < mNodes.giveSize(); i++ ) {
        printf( "%u, ", mNodes.at(i) );
    }
    printf("];\n");
#endif
    //The intersection of pNodes and mNodes constitutes zNodes
    {
        int i = 1, j = 1;
        while ( i <= pNodes.giveSize() ) {
            j = 1;
            while ( j <= mNodes.giveSize() && ( i <= pNodes.giveSize() ) ) {
                //printf("%u == %u?\n", pNodes.at(i), mNodes.at(j));
                if ( pNodes.at(i) == mNodes.at(j) ) {
                    zNodes.insertOnce( pNodes.at(i) );
                    pNodes.erase(i);
                    mNodes.erase(j);
                } else {
                    j++;
                }
            }
            i++;
        }
    }

    // Compute base function values on nodes for dofids
    copyDofManagersToSurfaceData(mode, pNodes, true, false, false);
    copyDofManagersToSurfaceData(mode, mNodes, false, true, false);
    copyDofManagersToSurfaceData(mode, zNodes, false, false, true);

#if 0
    printf("p2=[");
    for ( int i = 1; i <= pNodes.giveSize(); i++ ) {
        printf( "%u, ", pNodes.at(i) );
    }
    printf("];\n");
    printf("m2=[");
    for ( int i = 1; i <= mNodes.giveSize(); i++ ) {
        printf( "%u, ", mNodes.at(i) );
    }
    printf("];\n");
    printf("z2=[");
    for ( int i = 1; i <= zNodes.giveSize(); i++ ) {
        printf( "%u, ", zNodes.at(i) );
    }
    printf("];\n");

    printf("pCoords=[");
    for ( int i = 1; i <= pNodes.giveSize(); i++ ) {
        FloatArray *coords = m->giveDomain(1)->giveDofManager( pNodes.at(i) )->giveCoordinates();
        printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
    }
    printf("]\n");
    printf("mCoords=[");
    for ( int i = 1; i <= mNodes.giveSize(); i++ ) {
        FloatArray *coords = m->giveDomain(1)->giveDofManager( mNodes.at(i) )->giveCoordinates();
        printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
    }
    printf("]\n");
    printf("zCoords=[");
    for ( int i = 1; i <= zNodes.giveSize(); i++ ) {
        FloatArray *coords = m->giveDomain(1)->giveDofManager( zNodes.at(i) )->giveCoordinates();
        printf( "%f, %f, %f; ", coords->at(1), coords->at(2), coords->at(3) );
    }
    printf("];\n");
#endif
}
Example #25
0
bool H2DReader::save(const char* filename, Mesh *mesh)
{
  int i, mrk;
  Element* e;

  // open output file
  FILE* f = fopen(filename, "w");
  if (f == NULL) error("Could not create mesh file.");
  //fprintf(f, "# hermes2d saved mesh\n\n");

  // save vertices
  fprintf(f, "vertices =\n{\n");
  for (i = 0; i < mesh->ntopvert; i++)
    fprintf(f, "  { %.16g, %.16g }%s\n", mesh->nodes[i].x, mesh->nodes[i].y, (i < mesh->ntopvert-1 ? "," : ""));

  // save elements
  fprintf(f, "}\n\nelements =\n{");
  bool first = true;
  for (i = 0; i < mesh->get_num_base_elements(); i++)
  {
    const char* nl = first ? "\n" : ",\n";  first = false;
    e = mesh->get_element_fast(i);
    if (!e->used)
      fprintf(f, "%s  { }", nl);
    else if (e->is_triangle())
      fprintf(f, "%s  { %d, %d, %d, %d }", nl, e->vn[0]->id, e->vn[1]->id, e->vn[2]->id, e->marker);
    else
      fprintf(f, "%s  { %d, %d, %d, %d, %d }", nl, e->vn[0]->id, e->vn[1]->id, e->vn[2]->id, e->vn[3]->id, e->marker);
  }

  // save boundary markers
  fprintf(f, "\n}\n\nboundaries =\n{");
  first = true;
  for_all_base_elements(e, mesh)
    for (i = 0; i < e->nvert; i++)
      if ((mrk = mesh->get_base_edge_node(e, i)->marker)) {
        const char* nl = first ? "\n" : ",\n";  first = false;
        fprintf(f, "%s  { %d, %d, %d }", nl, e->vn[i]->id, e->vn[e->next_vert(i)]->id, mrk);
      }
  fprintf(f, "\n}\n\n");

  // save curved edges
  first = true;
  for_all_base_elements(e, mesh)
    if (e->is_curved())
      for (i = 0; i < e->nvert; i++)
        if (e->cm->nurbs[i] != NULL && !is_twin_nurbs(e, i)) {
          fprintf(f, first ? "curves =\n{\n" : ",\n");  first = false;
          save_nurbs(mesh, f, e->vn[i]->id, e->vn[e->next_vert(i)]->id, e->cm->nurbs[i]);
        }
  if (!first) fprintf(f, "\n}\n\n");

  // save refinements
  unsigned temp = mesh->seq;
  mesh->seq = mesh->nbase;
  first = true;
  for_all_base_elements(e, mesh)
    save_refinements(mesh, f, e, e->id, first);
  if (!first) fprintf(f, "\n}\n\n");

  mesh->seq = temp;
  fclose(f);

  return true;
}
Example #26
0
void WriteGmshFormat (const Mesh & mesh,
			 const CSGeometry & geom,
			 const string & filename)
{
  ofstream outfile (filename.c_str());
  outfile.precision(6);
  outfile.setf (ios::fixed, ios::floatfield);
  outfile.setf (ios::showpoint);

  int np = mesh.GetNP();  /// number of point
  int ne = mesh.GetNE();  /// number of element
  int nse = mesh.GetNSE();  /// number of surface element (BC)
  int i, j, k, l;


  /*
   * 3D section : Linear volume elements (only tetrahedra)
   */

   if (ne > 0 && mesh.VolumeElement(1).GetNP() == 4)
      {
      cout << "Write GMSH Format \n";
      cout << "The GMSH format is available for linear tetrahedron elements only in 3D\n" << endl;

      int inverttets = mparam.inverttets;
      int invertsurf = mparam.inverttrigs;


      /// Write nodes
      outfile << "$NOD\n";
      outfile << np << "\n";
  
      for (i = 1; i <= np; i++)
          {
          const Point3d & p = mesh.Point(i);
          outfile << i << " "; /// node number
          outfile << p.X() << " ";
          outfile << p.Y() << " ";
          outfile << p.Z() << "\n";
          }
      outfile << "$ENDNOD\n";

      /// write elements
      outfile << "$ELM\n";
      outfile << ne + nse << "\n";  ////  number of elements + number of surfaces BC

     for (i = 1; i <= nse; i++)
         {
         Element2d el = mesh.SurfaceElement(i);
         if (invertsurf) el.Invert();
         outfile << i;
         outfile << " ";
         outfile << "2";
         outfile << " ";
         outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
         /// that means that physical entity = elementary entity (arbitrary approach)
         outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
         outfile << "3";
         outfile << " ";
                 for (j = 1; j <= el.GetNP(); j++)
                     {
                     outfile << " ";
                     outfile << el.PNum(j);
                     }
                     outfile << "\n";
         }


         for (i = 1; i <= ne; i++)
             {
             Element el = mesh.VolumeElement(i);
             if (inverttets) el.Invert();
             outfile << nse + i; /// element number
             outfile << " ";
             outfile << "4"; /// element type i.e. Tetraedron == 4
             outfile << " ";
             outfile << 100000 + el.GetIndex();
             /// that means that physical entity = elementary entity (arbitrary approach)
             outfile << " ";
             outfile << 100000 + el.GetIndex();   /// volume number
             outfile << " ";
             outfile << "4";  /// number of nodes i.e. 4 for a tetrahedron
                                                                                                        
             for (j = 1; j <= el.GetNP(); j++)
                 {
                 outfile << " ";
                 outfile << el.PNum(j);
                 }
             outfile << "\n";
             }


             outfile << "$ENDELM\n";
   }

   /*
    * End of 3D section
    */





  /*
   * 2D section : available for triangles and quadrangles
   */
      else if (ne == 0)   /// means that there's no 3D element
              {
              cout << "\n Write Gmsh Surface Mesh (triangle and/or quadrangles)" << endl;

              /// Write nodes
              outfile << "$NOD\n";
              outfile << np << "\n";

              for (i = 1; i <= np; i++)
              {
              const Point3d & p = mesh.Point(i);
              outfile << i << " "; /// node number
              outfile << p.X() << " ";
              outfile << p.Y() << " ";
              outfile << p.Z() << "\n";
              }
              outfile << "$ENDNOD\n";


              /// write triangles & quadrangles
              outfile << "$ELM\n";
              outfile << nse << "\n";

              for (k = 1; k <= nse; k++)
              {
              const Element2d & el = mesh.SurfaceElement(k);


              outfile << k;
              outfile << " ";
              outfile << (el.GetNP()-1);   // 2 for a triangle and 3 for a quadrangle
              outfile << " ";
              outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
              /// that means that physical entity = elementary entity (arbitrary approach)
              outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " ";
              outfile << (el.GetNP());    // number of node per surfacic element
              outfile << " ";

              for (l = 1; l <= el.GetNP(); l++)
                  {
                  outfile << " ";
                  outfile << el.PNum(l);
                  }
	              outfile << "\n";
		  
               }
               outfile << "$ENDELM$ \n";
    }

   /*
    * End of 2D section
    */

     else
    {
    cout << " Invalide element type for Gmsh volume Format !\n";
    }


}
Example #27
0
// Sets inline CSS properties on passed in element if value is not an empty string
static void setInlineStylePropertyIfNotEmpty(Element& element,
    CSSPropertyID propertyID, const String& value)
{
    if (!value.isEmpty())
        element.setInlineStyleProperty(propertyID, value);
}
Example #28
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh, basemesh;
  H2DReader mloader;
  mloader.load("GAMM-channel.mesh", &basemesh);

  // Perform initial mesh refinements.
  for (int i = 0; i < INIT_REF_NUM; i++) basemesh.refine_all_elements();
  basemesh.refine_by_criterion(criterion, 4);
  mesh.copy(&basemesh);

  // Enter boundary markers.
  BCTypes bc_types;
  bc_types.add_bc_neumann(Hermes::Tuple<int>(BDY_SOLID_WALL, BDY_INLET_OUTLET));

  // Create L2 spaces with default shapesets.
  L2Space space_rho(&mesh, &bc_types, P_INIT);
  L2Space space_rho_v_x(&mesh, &bc_types, P_INIT);
  L2Space space_rho_v_y(&mesh, &bc_types, P_INIT);
  L2Space space_e(&mesh, &bc_types, P_INIT);

  // Initialize solutions, set initial conditions.
  Solution sln_rho, sln_rho_v_x, sln_rho_v_y, sln_e, prev_rho, prev_rho_v_x, prev_rho_v_y, prev_e;
  Solution rsln_rho, rsln_rho_v_x, rsln_rho_v_y, rsln_e;
  sln_rho.set_exact(&mesh, ic_density);
  sln_rho_v_x.set_exact(&mesh, ic_density_vel_x);
  sln_rho_v_y.set_exact(&mesh, ic_density_vel_y);
  sln_e.set_exact(&mesh, ic_energy);
  prev_rho.set_exact(&mesh, ic_density);
  prev_rho_v_x.set_exact(&mesh, ic_density_vel_x);
  prev_rho_v_y.set_exact(&mesh, ic_density_vel_y);
  prev_e.set_exact(&mesh, ic_energy);

  // Initialize weak formulation.
  WeakForm wf(4);

  // Bilinear forms coming from time discretization by explicit Euler's method.
  wf.add_matrix_form(0,0,callback(bilinear_form_0_0_time));
  wf.add_matrix_form(1,1,callback(bilinear_form_1_1_time));
  wf.add_matrix_form(2,2,callback(bilinear_form_2_2_time));
  wf.add_matrix_form(3,3,callback(bilinear_form_3_3_time));

  // Volumetric linear forms.
  // Linear forms coming from the linearization by taking the Eulerian fluxes' Jacobian matrices from the previous time step.
  // First flux.
  /*
  wf.add_vector_form(0,callback(linear_form_0_1), HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho_v_x));
  wf.add_vector_form(1, callback(linear_form_1_0_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_1_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_2_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_3_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(2, callback(linear_form_2_0_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_1_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_2_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_3_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_0_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_1_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_2_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_3_first_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  // Second flux.
  
  wf.add_vector_form(0,callback(linear_form_0_2),HERMES_ANY, Hermes::Tuple<MeshFunction*>(&prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_0_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_1_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_2_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(1, callback(linear_form_1_3_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(2, callback(linear_form_2_0_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_1_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_2_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y));
  wf.add_vector_form(2, callback(linear_form_2_3_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_0_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_1_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_2_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, callback(linear_form_3_3_second_flux), HERMES_ANY, 
                     Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  */

  // Volumetric linear forms coming from the time discretization.
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
  wf.add_vector_form(0, linear_form_vector, linear_form_order, HERMES_ANY, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(1, linear_form_vector, linear_form_order, HERMES_ANY, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(2, linear_form_vector, linear_form_order, HERMES_ANY, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form(3, linear_form_vector, linear_form_order, HERMES_ANY, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#else
  wf.add_vector_form(0,linear_form, linear_form_order, HERMES_ANY, &prev_rho);
  wf.add_vector_form(1,linear_form, linear_form_order, HERMES_ANY, &prev_rho_v_x);
  wf.add_vector_form(2,linear_form, linear_form_order, HERMES_ANY, &prev_rho_v_y);
  wf.add_vector_form(3,linear_form, linear_form_order, HERMES_ANY, &prev_e);
#endif

  // Surface linear forms - inner edges coming from the DG formulation.
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
  wf.add_vector_form_surf(0, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, linear_form_interface_vector, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#else
  wf.add_vector_form_surf(0, linear_form_interface_0, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, linear_form_interface_1, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, linear_form_interface_2, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, linear_form_interface_3, linear_form_order, H2D_DG_INNER_EDGE, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#endif

  // Surface linear forms - inlet / outlet edges.
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
  wf.add_vector_form_surf(0, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, bdy_flux_inlet_outlet_comp_vector, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#else
  wf.add_vector_form_surf(0, bdy_flux_inlet_outlet_comp_0, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, bdy_flux_inlet_outlet_comp_1, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, bdy_flux_inlet_outlet_comp_2, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, bdy_flux_inlet_outlet_comp_3, linear_form_order, BDY_INLET_OUTLET, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#endif

  // Surface linear forms - Solid wall edges.
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
  wf.add_vector_form_surf(0, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, bdy_flux_solid_wall_comp_vector, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#else
  wf.add_vector_form_surf(0, bdy_flux_solid_wall_comp_0, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(1, bdy_flux_solid_wall_comp_1, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(2, bdy_flux_solid_wall_comp_2, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
  wf.add_vector_form_surf(3, bdy_flux_solid_wall_comp_3, linear_form_order, BDY_SOLID_WALL, 
                          Hermes::Tuple<MeshFunction*>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e));
#endif

  // Filters for visualization of pressure and the two components of velocity.
  SimpleFilter pressure(calc_pressure_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e));
  SimpleFilter u(calc_u_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e));
  SimpleFilter w(calc_w_func, Hermes::Tuple<MeshFunction*>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e));

  // Initialize refinement selector.
  L2ProjBasedSelector selector(CAND_LIST, CONV_EXP, H2DRS_DEFAULT_ORDER);

  // Disable weighting of refinement candidates.
  selector.set_error_weights(1, 1, 1);

  //VectorView vview("Velocity", new WinGeom(0, 0, 600, 300));
  //ScalarView sview("Pressure", new WinGeom(700, 0, 600, 300));

  ScalarView s1("w1", new WinGeom(0, 0, 620, 300));
  s1.fix_scale_width(80);
  ScalarView s2("w2", new WinGeom(625, 0, 600, 300));
  s2.fix_scale_width(50);
  ScalarView s3("w3", new WinGeom(0, 350, 620, 300));
  s3.fix_scale_width(80);
  ScalarView s4("w4", new WinGeom(625, 350, 600, 300));
  s4.fix_scale_width(50);

  // Iteration number.
  int iteration = 0;
  
  // For calculation of the time derivative of the norm of the solution approximation.
  // Not used yet in the adaptive version.
  double difference;
  double *difference_values = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e))];
  double *last_values = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e))];
  for(int i = 0; i < Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e)); i++)
      last_values[i] = 0.;
  
  // Output of the approximate time derivative.
  // Not used yet in the adaptive version.
  std::ofstream time_der_out("time_der");
  
  for(t = 0.0; t < 10; t += TAU)
  {
    info("---- Time step %d, time %3.5f.", iteration, t);

    iteration++;

    // Periodic global derefinements.
    if (iteration > 1 && iteration % UNREF_FREQ == 0 && REFINEMENT_COUNT > 0) {
      REFINEMENT_COUNT = 0;
      info("Global mesh derefinement.");
      mesh.unrefine_all_elements();
      space_rho.set_uniform_order(P_INIT);
      space_rho_v_x.set_uniform_order(P_INIT);
      space_rho_v_y.set_uniform_order(P_INIT);
      space_e.set_uniform_order(P_INIT);
    }

    // Adaptivity loop:
    int as = 1; 
    bool done = false;
    do
    {
      info("---- Adaptivity step %d:", as);

      // Construct globally refined reference mesh and setup reference space.
      // Global polynomial order increase = 0;
      int order_increase = 0;
      Hermes::Tuple<Space *>* ref_spaces = construct_refined_spaces(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e), order_increase);

      // Project the previous time level solution onto the new fine mesh.
      info("Projecting the previous time level solution onto the new fine mesh.");
      OGProjection::project_global(*ref_spaces, Hermes::Tuple<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), 
                     Hermes::Tuple<Solution *>(&prev_rho, &prev_rho_v_x, &prev_rho_v_y, &prev_e), matrix_solver); 

      if(as > 1) {
        delete rsln_rho.get_mesh();
        delete rsln_rho_v_x.get_mesh();
        delete rsln_rho_v_y.get_mesh();
        delete rsln_e.get_mesh();
      }

      // Assemble the reference problem.
      info("Solving on reference mesh.");
      bool is_linear = true;
      DiscreteProblem* dp = new DiscreteProblem(&wf, *ref_spaces, is_linear);
      SparseMatrix* matrix = create_matrix(matrix_solver);
      Vector* rhs = create_vector(matrix_solver);
      Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

      // The FE problem is in fact a FV problem.
      dp->set_fvm();
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
      dp->use_vector_valued_forms();
#endif
      dp->assemble(matrix, rhs);

      // Solve the linear system of the reference problem. If successful, obtain the solutions.
      if(solver->solve()) Solution::vector_to_solutions(solver->get_solution(), *ref_spaces, 
                                              Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e));
      else error ("Matrix solver failed.\n");

      // Project the fine mesh solution onto the coarse mesh.
      info("Projecting reference solution on coarse mesh.");
      OGProjection::project_global(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e), Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), 
                     Hermes::Tuple<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), matrix_solver, 
                     Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM)); 

      // Calculate element errors and total error estimate.
      info("Calculating error estimate.");
      Adapt* adaptivity = new Adapt(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e), Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM));
      // Error components.
      Hermes::Tuple<double> *error_components = new Hermes::Tuple<double>(4);
      double err_est_rel_total = adaptivity->calc_err_est(Hermes::Tuple<Solution *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e),
							  Hermes::Tuple<Solution *>(&rsln_rho, &rsln_rho_v_x, &rsln_rho_v_y, &rsln_e), 
                                                          error_components, HERMES_TOTAL_ERROR_REL | HERMES_ELEMENT_ERROR_ABS) * 100;

      // Report results.
      info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%", 
        Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
        &space_rho_v_y, &space_e)), Space::get_num_dofs(*ref_spaces), err_est_rel_total);

      // Determine the time step.
      double *solution_vector = new double[Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e))];
      OGProjection::project_global(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
      &space_rho_v_y, &space_e), Hermes::Tuple<MeshFunction *>(&sln_rho, &sln_rho_v_x, &sln_rho_v_y, &sln_e), solution_vector, matrix_solver, 
      Hermes::Tuple<ProjNormType>(HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM, HERMES_L2_NORM));
      double min_condition = 0;
      Element *e;
      for (int _id = 0, _max = mesh.get_max_element_id(); _id < _max; _id++) \
            if (((e) = mesh.get_element_fast(_id))->used) \
              if ((e)->active)
      {
        AsmList al;
        space_rho.get_element_assembly_list(e, &al);
        double rho = solution_vector[al.dof[0]];
        space_rho_v_x.get_element_assembly_list(e, &al);
        double v1 = solution_vector[al.dof[0]] / rho;
        space_rho_v_y.get_element_assembly_list(e, &al);
        double v2 = solution_vector[al.dof[0]] / rho;
        space_e.get_element_assembly_list(e, &al);
        double energy = solution_vector[al.dof[0]];
        
        double condition = e->get_area() / (std::sqrt(v1*v1 + v2*v2) + calc_sound_speed(rho, rho*v1, rho*v2, energy));
        
        if(condition < min_condition || min_condition == 0.)
          min_condition = condition;
      }
      if(TAU > min_condition)
        TAU = min_condition;
      if(TAU < min_condition * 0.9)
        TAU = min_condition;

      delete [] solution_vector;

      // Visualization.
      s1.show(&sln_rho);
      s2.show(&sln_rho_v_x);
      s3.show(&sln_rho_v_y);
      s4.show(&sln_e);

      // If err_est too large, adapt the mesh.
      if (err_est_rel_total < ERR_STOP && (*error_components)[1] * 100 < ERR_STOP_VEL_X) 
        done = true;
      else 
      {
        info("Adapting coarse mesh.");
        done = adaptivity->adapt(Hermes::Tuple<RefinementSelectors::Selector *>(&selector, &selector, &selector, &selector), 
                                 THRESHOLD, STRATEGY, MESH_REGULARITY);

        REFINEMENT_COUNT++;
        if (Space::get_num_dofs(Hermes::Tuple<Space *>(&space_rho, &space_rho_v_x, 
          &space_rho_v_y, &space_e)) >= NDOF_STOP) 
          done = true;
        else
          // Increase the counter of performed adaptivity steps.
          as++;
      }

      // We have to empty the cache of NeighborSearch class instances.
      NeighborSearch::empty_main_caches();

// If used, we need to clean the vector valued form caches.
#ifdef HERMES_USE_VECTOR_VALUED_FORMS
      DiscreteProblem::empty_form_caches();
#endif

      // Clean up.
      delete solver;
      delete matrix;
      delete rhs;
      delete adaptivity;
      for(unsigned int i = 0; i < ref_spaces->size(); i++)
        delete (*ref_spaces)[i];
      delete dp;
    }
    while (done == false);

    // Debugging.
    /*    
    std::ofstream out("matrix");
    for(int i = 0; i < matrix->get_size(); i++)
      for(int j = 0; j < matrix->get_size(); j++)
        if(std::abs(matrix->get(i,j)) != 0)
          out << '(' << i << ',' << j << ')' << ':' << matrix->get(i,j) << std::endl;
    out.close();

    out.open("rhs");
      for(int j = 0; j < matrix->get_size(); j++)
        if(std::abs(rhs->get(j)) != 0)
          out << '(' << j << ')' << ':' << rhs->get(j) << std::endl;
    out.close();
     
    out.open("sol");
      for(int j = 0; j < matrix->get_size(); j++)
        out << '(' << j << ')' << ':' << solver->get_solution()[j] << std::endl;
    out.close();
    */

    // Copy the solutions into the previous time level ones.
    prev_rho.copy(&rsln_rho);
    prev_rho_v_x.copy(&rsln_rho_v_x);
    prev_rho_v_y.copy(&rsln_rho_v_y);
    prev_e.copy(&rsln_e);

    delete rsln_rho.get_mesh(); 
    delete rsln_rho_v_x.get_mesh(); 
    delete rsln_rho_v_y.get_mesh();
    delete rsln_e.get_mesh(); 

    // Visualization.
    /*
    pressure.reinit();
    u.reinit();
    w.reinit();
    sview.show(&pressure);
    vview.show(&u,&w);
    */
  }
  
  time_der_out.close();
  return 0;
}
void FullscreenElementStack::webkitExitFullscreen()
{
    // The exitFullscreen() method must run these steps:

    // 1. Let doc be the context object. (i.e. "this")
    Document* currentDoc = document();

    // 2. If doc's fullscreen element stack is empty, terminate these steps.
    if (m_fullScreenElementStack.isEmpty())
        return;

    // 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
    // element stack (if any), ordered so that the child of the doc is last and the document furthest
    // away from the doc is first.
    Deque<RefPtr<Document> > descendants;
    for (Frame* descendant = document()->frame() ?  document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
        if (fullscreenElementFrom(descendant->document()))
            descendants.prepend(descendant->document());
    }

    // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
    // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
    for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
        from(i->get())->clearFullscreenElementStack();
        addDocumentToFullScreenChangeEventQueue(i->get());
    }

    // 5. While doc is not null, run these substeps:
    Element* newTop = 0;
    while (currentDoc) {
        // 1. Pop the top element of doc's fullscreen element stack.
        from(currentDoc)->popFullscreenElementStack();

        //    If doc's fullscreen element stack is non-empty and the element now at the top is either
        //    not in a document or its node document is not doc, repeat this substep.
        newTop = fullscreenElementFrom(currentDoc);
        if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
            continue;

        // 2. Queue a task to fire an event named fullscreenchange with its bubbles attribute set to true
        // on doc.
        addDocumentToFullScreenChangeEventQueue(currentDoc);

        // 3. If doc's fullscreen element stack is empty and doc's browsing context has a browsing context
        // container, set doc to that browsing context container's node document.
        if (!newTop && currentDoc->ownerElement()) {
            currentDoc = &currentDoc->ownerElement()->document();
            continue;
        }

        // 4. Otherwise, set doc to null.
        currentDoc = 0;
    }

    // 6. Return, and run the remaining steps asynchronously.
    // 7. Optionally, perform some animation.

    if (!document()->page())
        return;

    // Only exit out of full screen window mode if there are no remaining elements in the
    // full screen stack.
    if (!newTop) {
        document()->page()->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
        return;
    }

    // Otherwise, notify the chrome of the new full screen element.
    document()->page()->chrome().client().enterFullScreenForElement(newTop);
}
void
nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation,
                                             AnimationMutation aMutationType)
{
  mozilla::dom::KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
  if (!effect) {
    return;
  }

  Maybe<NonOwningAnimationTarget> animationTarget = effect->GetTarget();
  if (!animationTarget) {
    return;
  }

  Element* elem = animationTarget->mElement;
  if (!Animations() || !(Subtree() || elem == Target()) ||
      elem->ChromeOnlyAccess()) {
    return;
  }

  // Record animations targeting to a pseudo element only when subtree is true.
  if (animationTarget->mPseudoType != mozilla::CSSPseudoElementType::NotPseudo &&
      !Subtree()) {
    return;
  }

  if (nsAutoAnimationMutationBatch::IsBatching()) {
    switch (aMutationType) {
      case eAnimationMutation_Added:
        nsAutoAnimationMutationBatch::AnimationAdded(aAnimation, elem);
        break;
      case eAnimationMutation_Changed:
        nsAutoAnimationMutationBatch::AnimationChanged(aAnimation, elem);
        break;
      case eAnimationMutation_Removed:
        nsAutoAnimationMutationBatch::AnimationRemoved(aAnimation, elem);
        break;
    }

    nsAutoAnimationMutationBatch::AddObserver(Observer());
    return;
  }

  nsDOMMutationRecord* m =
    Observer()->CurrentRecord(nsGkAtoms::animations);

  NS_ASSERTION(!m->mTarget, "Wrong target!");

  m->mTarget = elem;

  switch (aMutationType) {
    case eAnimationMutation_Added:
      m->mAddedAnimations.AppendElement(aAnimation);
      break;
    case eAnimationMutation_Changed:
      m->mChangedAnimations.AppendElement(aAnimation);
      break;
    case eAnimationMutation_Removed:
      m->mRemovedAnimations.AppendElement(aAnimation);
      break;
  }
}