void
gfxPlatformMac::GetCommonFallbackFonts(const uint32_t aCh,
                                       int32_t aRunScript,
                                       nsTArray<const char*>& aFontList)
{
    aFontList.AppendElement(kFontLucidaGrande);

    if (!IS_IN_BMP(aCh)) {
        uint32_t p = aCh >> 16;
        uint32_t b = aCh >> 8;
        if (p == 1) {
            if (b >= 0x1f0 && b < 0x1f7) {
                aFontList.AppendElement(kFontAppleColorEmoji);
            } else {
                aFontList.AppendElement(kFontAppleSymbols);
                aFontList.AppendElement(kFontSTIXGeneral);
                aFontList.AppendElement(kFontGeneva);
            }
        } else if (p == 2) {
            // OSX installations with MS Office may have these fonts
            aFontList.AppendElement(kFontMingLiUExtB);
            aFontList.AppendElement(kFontSimSunExtB);
        }
    } else {
void
gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
                                       Script aRunScript,
                                       nsTArray<const char*>& aFontList)
{
    if (aNextCh == 0xfe0fu) {
      // if char is followed by VS16, try for a color emoji glyph
      aFontList.AppendElement(kFontEmojiOneMozilla);
    }

    aFontList.AppendElement(kFontDejaVuSerif);
    aFontList.AppendElement(kFontFreeSerif);
    aFontList.AppendElement(kFontDejaVuSans);
    aFontList.AppendElement(kFontFreeSans);

    if (!IS_IN_BMP(aCh)) {
        uint32_t p = aCh >> 16;
        if (p == 1) { // try color emoji font, unless VS15 (text style) present
            if (aNextCh != 0xfe0fu && aNextCh != 0xfe0eu) {
                aFontList.AppendElement(kFontEmojiOneMozilla);
            }
        }
    }
Exemple #3
0
void
nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter)
{
  aElements.AppendElement(mCustomContentContainer);
}
nsresult
nsSVGFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                     nsTArray<RefPtr<SourceSurface>>& aInputImages,
                                     bool aInputIsTainted)
{
  mSourceGraphicIndex = GetLastResultIndex(aPrimitiveDescrs);

  // Clip previous filter's output to this filter's filter region.
  if (mSourceGraphicIndex >= 0) {
    FilterPrimitiveDescription& sourceDescr = aPrimitiveDescrs[mSourceGraphicIndex];
    sourceDescr.SetPrimitiveSubregion(sourceDescr.PrimitiveSubregion().Intersect(mFilterSpaceBounds));
  }

  // Get the filter primitive elements.
  nsTArray<RefPtr<nsSVGFE> > primitives;
  for (nsIContent* child = mFilterElement->nsINode::GetFirstChild();
       child;
       child = child->GetNextSibling()) {
    RefPtr<nsSVGFE> primitive;
    CallQueryInterface(child, (nsSVGFE**)getter_AddRefs(primitive));
    if (primitive) {
      primitives.AppendElement(primitive);
    }
  }

  // Maps source image name to source index.
  nsDataHashtable<nsStringHashKey, int32_t> imageTable(8);

  // The principal that we check principals of any loaded images against.
  nsCOMPtr<nsIPrincipal> principal = mTargetContent->NodePrincipal();

  for (uint32_t primitiveElementIndex = 0;
       primitiveElementIndex < primitives.Length();
       ++primitiveElementIndex) {
    nsSVGFE* filter = primitives[primitiveElementIndex];

    AutoTArray<int32_t,2> sourceIndices;
    nsresult rv = GetSourceIndices(filter, aPrimitiveDescrs, imageTable, sourceIndices);
    if (NS_FAILED(rv)) {
      return rv;
    }

    IntRect primitiveSubregion =
      ComputeFilterPrimitiveSubregion(filter, aPrimitiveDescrs, sourceIndices);

    nsTArray<bool> sourcesAreTainted;
    GetInputsAreTainted(aPrimitiveDescrs, sourceIndices, aInputIsTainted, sourcesAreTainted);

    FilterPrimitiveDescription descr =
      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, aInputImages);

    descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal));
    descr.SetFilterSpaceBounds(mFilterSpaceBounds);
    descr.SetPrimitiveSubregion(primitiveSubregion.Intersect(descr.FilterSpaceBounds()));

    for (uint32_t i = 0; i < sourceIndices.Length(); i++) {
      int32_t inputIndex = sourceIndices[i];
      descr.SetInputPrimitive(i, inputIndex);

      ColorSpace inputColorSpace = inputIndex >= 0
        ? aPrimitiveDescrs[inputIndex].OutputColorSpace()
        : ColorSpace(ColorSpace::SRGB);

      ColorSpace desiredInputColorSpace = filter->GetInputColorSpace(i, inputColorSpace);
      descr.SetInputColorSpace(i, desiredInputColorSpace);
      if (i == 0) {
        // the output color space is whatever in1 is if there is an in1
        descr.SetOutputColorSpace(desiredInputColorSpace);
      }
    }

    if (sourceIndices.Length() == 0) {
      descr.SetOutputColorSpace(filter->GetOutputColorSpace());
    }

    aPrimitiveDescrs.AppendElement(descr);
    uint32_t primitiveDescrIndex = aPrimitiveDescrs.Length() - 1;

    nsAutoString str;
    filter->GetResultImageName().GetAnimValue(str, filter);
    imageTable.Put(str, primitiveDescrIndex);
  }

  return NS_OK;
}
bool
nsCaseTransformTextRunFactory::TransformString(
    const nsAString& aString,
    nsString& aConvertedString,
    bool aAllUppercase,
    const nsIAtom* aLanguage,
    nsTArray<bool>& aCharsToMergeArray,
    nsTArray<bool>& aDeletedCharsArray,
    nsTransformedTextRun* aTextRun,
    nsTArray<uint8_t>* aCanBreakBeforeArray,
    nsTArray<nsStyleContext*>* aStyleArray)
{
  NS_PRECONDITION(!aTextRun || (aCanBreakBeforeArray && aStyleArray),
                  "either none or all three optional parameters required");

  uint32_t length = aString.Length();
  const char16_t* str = aString.BeginReading();

  bool mergeNeeded = false;

  bool capitalizeDutchIJ = false;
  bool prevIsLetter = false;
  bool ntPrefix = false; // true immediately after a word-initial 'n' or 't'
                         // when doing Irish lowercasing
  uint32_t sigmaIndex = uint32_t(-1);
  nsIUGenCategory::nsUGenCategory cat;

  uint8_t style = aAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE : 0;
  const nsIAtom* lang = aLanguage;

  LanguageSpecificCasingBehavior languageSpecificCasing = GetCasingFor(lang);
  mozilla::GreekCasing::State greekState;
  mozilla::IrishCasing::State irishState;
  uint32_t irishMark = uint32_t(-1); // location of possible prefix letter(s)

  for (uint32_t i = 0; i < length; ++i) {
    uint32_t ch = str[i];

    nsStyleContext* styleContext;
    if (aTextRun) {
      styleContext = aTextRun->mStyles[i];
      style = aAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE :
        styleContext->StyleText()->mTextTransform;

      if (lang != styleContext->StyleFont()->mLanguage) {
        lang = styleContext->StyleFont()->mLanguage;
        languageSpecificCasing = GetCasingFor(lang);
        greekState.Reset();
        irishState.Reset();
        irishMark = uint32_t(-1);
      }
    }

    int extraChars = 0;
    const mozilla::unicode::MultiCharMapping *mcm;
    bool inhibitBreakBefore = false; // have we just deleted preceding hyphen?

    if (NS_IS_HIGH_SURROGATE(ch) && i < length - 1 &&
        NS_IS_LOW_SURROGATE(str[i + 1])) {
      ch = SURROGATE_TO_UCS4(ch, str[i + 1]);
    }

    switch (style) {
    case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
      if (languageSpecificCasing == eLSCB_Turkish) {
        if (ch == 'I') {
          ch = LATIN_SMALL_LETTER_DOTLESS_I;
          prevIsLetter = true;
          sigmaIndex = uint32_t(-1);
          break;
        }
        if (ch == LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE) {
          ch = 'i';
          prevIsLetter = true;
          sigmaIndex = uint32_t(-1);
          break;
        }
      }

      cat = mozilla::unicode::GetGenCategory(ch);

      if (languageSpecificCasing == eLSCB_Irish &&
          cat == nsIUGenCategory::kLetter) {
        // See bug 1018805 for Irish lowercasing requirements
        if (!prevIsLetter && (ch == 'n' || ch == 't')) {
          ntPrefix = true;
        } else {
          if (ntPrefix && mozilla::IrishCasing::IsUpperVowel(ch)) {
            aConvertedString.Append('-');
            ++extraChars;
          }
          ntPrefix = false;
        }
      } else {
        ntPrefix = false;
      }

      // Special lowercasing behavior for Greek Sigma: note that this is listed
      // as context-sensitive in Unicode's SpecialCasing.txt, but is *not* a
      // language-specific mapping; it applies regardless of the language of
      // the element.
      //
      // The lowercase mapping for CAPITAL SIGMA should be to SMALL SIGMA (i.e.
      // the non-final form) whenever there is a following letter, or when the
      // CAPITAL SIGMA occurs in isolation (neither preceded nor followed by a
      // LETTER); and to FINAL SIGMA when it is preceded by another letter but
      // not followed by one.
      //
      // To implement the context-sensitive nature of this mapping, we keep
      // track of whether the previous character was a letter. If not, CAPITAL
      // SIGMA will map directly to SMALL SIGMA. If the previous character
      // was a letter, CAPITAL SIGMA maps to FINAL SIGMA and we record the
      // position in the converted string; if we then encounter another letter,
      // that FINAL SIGMA is replaced with a standard SMALL SIGMA.

      // If sigmaIndex is not -1, it marks where we have provisionally mapped
      // a CAPITAL SIGMA to FINAL SIGMA; if we now find another letter, we
      // need to change it to SMALL SIGMA.
      if (sigmaIndex != uint32_t(-1)) {
        if (cat == nsIUGenCategory::kLetter) {
          aConvertedString.SetCharAt(GREEK_SMALL_LETTER_SIGMA, sigmaIndex);
        }
      }

      if (ch == GREEK_CAPITAL_LETTER_SIGMA) {
        // If preceding char was a letter, map to FINAL instead of SMALL,
        // and note where it occurred by setting sigmaIndex; we'll change it
        // to standard SMALL SIGMA later if another letter follows
        if (prevIsLetter) {
          ch = GREEK_SMALL_LETTER_FINAL_SIGMA;
          sigmaIndex = aConvertedString.Length();
        } else {
          // CAPITAL SIGMA not preceded by a letter is unconditionally mapped
          // to SMALL SIGMA
          ch = GREEK_SMALL_LETTER_SIGMA;
          sigmaIndex = uint32_t(-1);
        }
        prevIsLetter = true;
        break;
      }

      // ignore diacritics for the purpose of contextual sigma mapping;
      // otherwise, reset prevIsLetter appropriately and clear the
      // sigmaIndex marker
      if (cat != nsIUGenCategory::kMark) {
        prevIsLetter = (cat == nsIUGenCategory::kLetter);
        sigmaIndex = uint32_t(-1);
      }

      mcm = mozilla::unicode::SpecialLower(ch);
      if (mcm) {
        int j = 0;
        while (j < 2 && mcm->mMappedChars[j + 1]) {
          aConvertedString.Append(mcm->mMappedChars[j]);
          ++extraChars;
          ++j;
        }
        ch = mcm->mMappedChars[j];
        break;
      }

      ch = ToLowerCase(ch);
      break;

    case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
      if (languageSpecificCasing == eLSCB_Turkish && ch == 'i') {
        ch = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
        break;
      }

      if (languageSpecificCasing == eLSCB_Greek) {
        ch = mozilla::GreekCasing::UpperCase(ch, greekState);
        break;
      }

      if (languageSpecificCasing == eLSCB_Irish) {
        bool mark;
        uint8_t action;
        ch = mozilla::IrishCasing::UpperCase(ch, irishState, mark, action);
        if (mark) {
          irishMark = aConvertedString.Length();
          break;
        } else if (action) {
          nsString& str = aConvertedString; // shorthand
          switch (action) {
          case 1:
            // lowercase a single prefix letter
            NS_ASSERTION(str.Length() > 0 && irishMark < str.Length(),
                         "bad irishMark!");
            str.SetCharAt(ToLowerCase(str[irishMark]), irishMark);
            irishMark = uint32_t(-1);
            break;
          case 2:
            // lowercase two prefix letters (immediately before current pos)
            NS_ASSERTION(str.Length() >= 2 && irishMark == str.Length() - 2,
                         "bad irishMark!");
            str.SetCharAt(ToLowerCase(str[irishMark]), irishMark);
            str.SetCharAt(ToLowerCase(str[irishMark + 1]), irishMark + 1);
            irishMark = uint32_t(-1);
            break;
          case 3:
            // lowercase one prefix letter, and delete following hyphen
            // (which must be the immediately-preceding char)
            NS_ASSERTION(str.Length() >= 2 && irishMark == str.Length() - 2,
                         "bad irishMark!");
            str.Replace(irishMark, 2, ToLowerCase(str[irishMark]));
            aDeletedCharsArray[irishMark + 1] = true;
            // Remove the trailing entries (corresponding to the deleted hyphen)
            // from the auxiliary arrays.
            aCharsToMergeArray.SetLength(aCharsToMergeArray.Length() - 1);
            if (aTextRun) {
              aStyleArray->SetLength(aStyleArray->Length() - 1);
              aCanBreakBeforeArray->SetLength(aCanBreakBeforeArray->Length() - 1);
              inhibitBreakBefore = true;
            }
            mergeNeeded = true;
            irishMark = uint32_t(-1);
            break;
          }
          // ch has been set to the uppercase for current char;
          // No need to check for SpecialUpper here as none of the characters
          // that could trigger an Irish casing action have special mappings.
          break;
        }
        // If we didn't have any special action to perform, fall through
        // to check for special uppercase (ß)
      }

      mcm = mozilla::unicode::SpecialUpper(ch);
      if (mcm) {
        int j = 0;
        while (j < 2 && mcm->mMappedChars[j + 1]) {
          aConvertedString.Append(mcm->mMappedChars[j]);
          ++extraChars;
          ++j;
        }
        ch = mcm->mMappedChars[j];
        break;
      }

      ch = ToUpperCase(ch);
      break;

    case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
      if (aTextRun) {
        if (capitalizeDutchIJ && ch == 'j') {
          ch = 'J';
          capitalizeDutchIJ = false;
          break;
        }
        capitalizeDutchIJ = false;
        if (i < aTextRun->mCapitalize.Length() && aTextRun->mCapitalize[i]) {
          if (languageSpecificCasing == eLSCB_Turkish && ch == 'i') {
            ch = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
            break;
          }
          if (languageSpecificCasing == eLSCB_Dutch && ch == 'i') {
            ch = 'I';
            capitalizeDutchIJ = true;
            break;
          }

          mcm = mozilla::unicode::SpecialTitle(ch);
          if (mcm) {
            int j = 0;
            while (j < 2 && mcm->mMappedChars[j + 1]) {
              aConvertedString.Append(mcm->mMappedChars[j]);
              ++extraChars;
              ++j;
            }
            ch = mcm->mMappedChars[j];
            break;
          }

          ch = ToTitleCase(ch);
        }
      }
      break;

    case NS_STYLE_TEXT_TRANSFORM_FULLWIDTH:
      ch = mozilla::unicode::GetFullWidth(ch);
      break;

    default:
      break;
    }

    if (ch == uint32_t(-1)) {
      aDeletedCharsArray.AppendElement(true);
      mergeNeeded = true;
    } else {
      aDeletedCharsArray.AppendElement(false);
      aCharsToMergeArray.AppendElement(false);
      if (aTextRun) {
        aStyleArray->AppendElement(styleContext);
        aCanBreakBeforeArray->AppendElement(inhibitBreakBefore ? false :
                                            aTextRun->CanBreakLineBefore(i));
      }

      if (IS_IN_BMP(ch)) {
        aConvertedString.Append(ch);
      } else {
        aConvertedString.Append(H_SURROGATE(ch));
        aConvertedString.Append(L_SURROGATE(ch));
        ++i;
        aDeletedCharsArray.AppendElement(true); // not exactly deleted, but the
                                                // trailing surrogate is skipped
        ++extraChars;
      }

      while (extraChars-- > 0) {
        mergeNeeded = true;
        aCharsToMergeArray.AppendElement(true);
        if (aTextRun) {
          aStyleArray->AppendElement(styleContext);
          aCanBreakBeforeArray->AppendElement(false);
        }
      }
    }
  }

  return mergeNeeded;
}
Exemple #6
0
nsresult
nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  NS_ASSERTION(mContent, "We should have a content!");

  mState |= NS_FRAME_INDEPENDENT_SELECTION;

  nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
  NS_ASSERTION(txtCtrl, "Content not a text control element");

  // Bind the frame to its text control
  nsresult rv = txtCtrl->BindToFrame(this);
  NS_ENSURE_SUCCESS(rv, rv);

  nsIContent* rootNode = txtCtrl->GetRootEditorNode();
  NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY);

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

  // Do we need a placeholder node?
  nsAutoString placeholderTxt;
  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder,
                    placeholderTxt);
  nsContentUtils::RemoveNewlines(placeholderTxt);
  mUsePlaceholder = !placeholderTxt.IsEmpty();

  // Create the placeholder anonymous content if needed.
  if (mUsePlaceholder) {
    nsIContent* placeholderNode = txtCtrl->CreatePlaceholderNode();
    NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY);

    // Associate ::-moz-placeholder pseudo-element with the placeholder node.
    nsCSSPseudoElements::Type pseudoType =
      nsCSSPseudoElements::ePseudo_mozPlaceholder;

    nsRefPtr<nsStyleContext> placeholderStyleContext =
      PresContext()->StyleSet()->ResolvePseudoElementStyle(
          mContent->AsElement(), pseudoType, StyleContext(),
          placeholderNode->AsElement());

    if (!aElements.AppendElement(ContentInfo(placeholderNode,
                                 placeholderStyleContext))) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  rv = UpdateValueDisplay(false);
  NS_ENSURE_SUCCESS(rv, rv);

  // textareas are eagerly initialized
  bool initEagerly = !IsSingleLineTextControl();
  if (!initEagerly) {
    // Also, input elements which have a cached selection should get eager
    // editor initialization.
    nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
    NS_ASSERTION(txtCtrl, "Content not a text control element");
    initEagerly = txtCtrl->HasCachedSelection();
  }
  if (!initEagerly) {
    nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(txtCtrl);
    if (element) {
      // so are input text controls with spellcheck=true
      element->GetSpellcheck(&initEagerly);
    }
  }

  if (initEagerly) {
    NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                 "Someone forgot a script blocker?");
    EditorInitializer* initializer = (EditorInitializer*) Properties().Get(TextControlInitializer());
    if (initializer) {
      initializer->Revoke();
    }
    initializer = new EditorInitializer(this);
    Properties().Set(TextControlInitializer(),initializer);
    if (!nsContentUtils::AddScriptRunner(initializer)) {
      initializer->Revoke(); // paranoia
      Properties().Delete(TextControlInitializer());
      delete initializer;
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  return NS_OK;
}
nsresult
sbWinFindDevicesByStorageDevNum(STORAGE_DEVICE_NUMBER* aStorageDevNum,
                                PRBool                 aMatchPartitionNumber,
                                const GUID*            aGUID,
                                nsTArray<DEVINST>&     aDevInstList)
{
  // Validate arguments.
  NS_ENSURE_ARG_POINTER(aStorageDevNum);
  NS_ENSURE_ARG_POINTER(aGUID);

  // Function variables.
  nsresult rv;

  // Get the interface device class info and set up for auto-disposal.
  HDEVINFO devInfo =
             SetupDiGetClassDevsW(aGUID,
                                  NULL,
                                  NULL,
                                  DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
  NS_ENSURE_TRUE(devInfo != INVALID_HANDLE_VALUE, NS_ERROR_FAILURE);
  sbAutoHDEVINFO autoDevInfo(devInfo);

  // Search for device instances with a matching storage device number.
  aDevInstList.Clear();
  DWORD devIndex = 0;
  while (1) {
    // Get the next device detail data and set it up for auto-disposal.
    PSP_DEVICE_INTERFACE_DETAIL_DATA devIfDetailData;
    SP_DEVINFO_DATA                  devInfoData;
    rv = sbWinGetDevDetail(&devIfDetailData,
                           &devInfoData,
                           devInfo,
                           aGUID,
                           devIndex++);
    if (rv == NS_ERROR_NOT_AVAILABLE)
      break;
    NS_ENSURE_SUCCESS(rv, rv);
    sbAutoMemPtr<SP_DEVICE_INTERFACE_DETAIL_DATA>
      autoDevIfDetailData(devIfDetailData);

    // Get the next storage device number.
    STORAGE_DEVICE_NUMBER storageDevNum;
    rv = sbWinGetStorageDevNum(devIfDetailData->DevicePath, &storageDevNum);
    if (NS_FAILED(rv))
      continue;

    // Skip device instance if it doesn't match the target storage device
    // number.
    if (storageDevNum.DeviceType != aStorageDevNum->DeviceType)
      continue;
    if (storageDevNum.DeviceNumber != aStorageDevNum->DeviceNumber)
      continue;
    if (aMatchPartitionNumber &&
        (storageDevNum.PartitionNumber != aStorageDevNum->PartitionNumber)) {
      continue;
    }

    // Add device instance to list.
    NS_ENSURE_TRUE(aDevInstList.AppendElement(devInfoData.DevInst),
                   NS_ERROR_OUT_OF_MEMORY);
  }

  return NS_OK;
}
nsresult
nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  if (!mContent) {
    return NS_OK;
  }

  nsCOMPtr<nsIDocument> doc = mContent->OwnerDoc();
  nsresult rv = NS_OK;
  ErrorResult er;
  // We won't create touch caret element if preference is not enabled.
  if (PresShell::TouchCaretPrefEnabled()) {
    nsRefPtr<NodeInfo> nodeInfo;

    // Create and append touch caret frame.
    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nullptr,
                                                   kNameSpaceID_XHTML,
                                                   nsIDOMNode::ELEMENT_NODE);
    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);

    rv = NS_NewHTMLElement(getter_AddRefs(mTouchCaretElement), nodeInfo.forget(),
                           NOT_FROM_PARSER);
    NS_ENSURE_SUCCESS(rv, rv);
    aElements.AppendElement(mTouchCaretElement);

    // Set touch caret to visibility: hidden by default.
    nsAutoString classValue;
    classValue.AppendLiteral("moz-touchcaret hidden");
    rv = mTouchCaretElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                     classValue, true);

    if (!mDummyTouchListener) {
      mDummyTouchListener = new DummyTouchListener();
    }
    mTouchCaretElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                         mDummyTouchListener, false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (PresShell::SelectionCaretPrefEnabled()) {
    // Selection caret
    mSelectionCaretsStartElement = doc->CreateHTMLElement(nsGkAtoms::div);
    aElements.AppendElement(mSelectionCaretsStartElement);
    nsCOMPtr<mozilla::dom::Element> selectionCaretsStartElementInner = doc->CreateHTMLElement(nsGkAtoms::div);
    mSelectionCaretsStartElement->AppendChildTo(selectionCaretsStartElementInner, false);

    mSelectionCaretsEndElement = doc->CreateHTMLElement(nsGkAtoms::div);
    aElements.AppendElement(mSelectionCaretsEndElement);
    nsCOMPtr<mozilla::dom::Element> selectionCaretsEndElementInner = doc->CreateHTMLElement(nsGkAtoms::div);
    mSelectionCaretsEndElement->AppendChildTo(selectionCaretsEndElementInner, false);

    rv = mSelectionCaretsStartElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                               NS_LITERAL_STRING("moz-selectioncaret-left hidden"),
                                               true);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mSelectionCaretsEndElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                             NS_LITERAL_STRING("moz-selectioncaret-right hidden"),
                                             true);

    if (!mDummyTouchListener) {
      mDummyTouchListener = new DummyTouchListener();
    }
    mSelectionCaretsStartElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                                   mDummyTouchListener, false);
    mSelectionCaretsEndElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                                 mDummyTouchListener, false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Create the custom content container.
  mCustomContentContainer = doc->CreateHTMLElement(nsGkAtoms::div);
  aElements.AppendElement(mCustomContentContainer);

  // XXX add :moz-native-anonymous or will that be automatically set?
  rv = mCustomContentContainer->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                        NS_LITERAL_STRING("moz-custom-content-container"),
                                        true);
  NS_ENSURE_SUCCESS(rv, rv);

  // Append all existing AnonymousContent nodes stored at document level if any.
  size_t len = doc->GetAnonymousContents().Length();
  for (size_t i = 0; i < len; ++i) {
    nsCOMPtr<Element> node = doc->GetAnonymousContents()[i]->GetContentNode();
    mCustomContentContainer->AppendChildTo(node->AsContent(), true);
  }

  // Only create a frame for mCustomContentContainer if it has some children.
  if (len == 0) {
    HideCustomContentContainer();
  }

  return NS_OK;
}
nsresult
nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
  nsCOMPtr<nsINodeInfo> nodeInfo;

  // Create and setup the file picking button.
  nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::button, nullptr,
                                                 kNameSpaceID_XHTML,
                                                 nsIDOMNode::ELEMENT_NODE);
  NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo.forget(),
                    dom::NOT_FROM_PARSER);
  // NOTE: SetNativeAnonymous() has to be called before setting any attribute.
  mBrowse->SetNativeAnonymous();
  mBrowse->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                   NS_LITERAL_STRING("button"), false);

  // Set the file picking button text depending on the current locale.
  nsXPIDLString buttonTxt;
  nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                     "Browse", buttonTxt);

  // Set the browse button text. It's a bit of a pain to do because we want to
  // make sure we are not notifying.
  nsRefPtr<nsTextNode> textContent =
    new nsTextNode(mBrowse->NodeInfo()->NodeInfoManager());

  textContent->SetText(buttonTxt, false);

  nsresult rv = mBrowse->AppendChildTo(textContent, false);
  NS_ENSURE_SUCCESS(rv, rv);

  // Make sure access key and tab order for the element actually redirect to the
  // file picking button.
  nsCOMPtr<nsIDOMHTMLInputElement> fileContent = do_QueryInterface(mContent);
  nsCOMPtr<nsIDOMHTMLButtonElement> browseControl = do_QueryInterface(mBrowse);

  nsAutoString accessKey;
  fileContent->GetAccessKey(accessKey);
  browseControl->SetAccessKey(accessKey);

  int32_t tabIndex;
  fileContent->GetTabIndex(&tabIndex);
  browseControl->SetTabIndex(tabIndex);

  if (!aElements.AppendElement(mBrowse)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // Create and setup the text showing the selected files.
  nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::label, nullptr,
                                                 kNameSpaceID_XUL,
                                                 nsIDOMNode::ELEMENT_NODE);
  NS_TrustedNewXULElement(getter_AddRefs(mTextContent), nodeInfo.forget());
  // NOTE: SetNativeAnonymous() has to be called before setting any attribute.
  mTextContent->SetNativeAnonymous();
  mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::crop,
                        NS_LITERAL_STRING("center"), false);

  // Update the displayed text to reflect the current element's value.
  nsAutoString value;
  HTMLInputElement::FromContent(mContent)->GetDisplayFileName(value);
  UpdateDisplayedValue(value, false);

  if (!aElements.AppendElement(mTextContent)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  // We should be able to interact with the element by doing drag and drop.
  mContent->AddSystemEventListener(NS_LITERAL_STRING("drop"),
                                   mMouseListener, false);
  mContent->AddSystemEventListener(NS_LITERAL_STRING("dragover"),
                                   mMouseListener, false);

  SyncDisabledState();

  return NS_OK;
}
Exemple #10
0
void
GMPVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
{
  aTags.AppendElement(NS_LITERAL_CSTRING("h264"));
}
// Build whitelist to check for board type.
static void InitWhiteList(nsTArray<nsString>& list)
{
  nsString ele;
  ele.AssignASCII("droid2"); // Motorola Droid 2
  list.AppendElement(ele);
  ele.AssignASCII("GT-I9100"); // Samsung Galaxy SII
  list.AppendElement(ele);
  ele.AssignASCII("herring"); // Samsung Nexus S
  list.AppendElement(ele);
  ele.AssignASCII("omap4sdp"); // Amazon Kindle Fire
  list.AppendElement(ele);
  ele.AssignASCII("SGH-I897"); // Samsung Galaxy S
  list.AppendElement(ele);
  ele.AssignASCII("sgh-i997"); // Samsung Infuse 4G
  list.AppendElement(ele);
  ele.AssignASCII("sgh-t839"); // Samsung Sidekick 4G
  list.AppendElement(ele);
  ele.AssignASCII("shadow"); // Motorola Droid X
  list.AppendElement(ele);
  ele.AssignASCII("spyder"); // Motorola Razr
  list.AppendElement(ele);
  ele.AssignASCII("targa"); // Motorola Droid Bionic
  list.AppendElement(ele);
  ele.AssignASCII("tuna"); // Galaxy Nexus
  list.AppendElement(ele);
  ele.AssignASCII("venus2"); // Motorla Droid Pro
  list.AppendElement(ele);
}
nsresult
nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  if (!mContent) {
    return NS_OK;
  }

  nsCOMPtr<nsIDocument> doc = mContent->OwnerDoc();
  nsresult rv = NS_OK;
  ErrorResult er;
  // We won't create touch caret element if preference is not enabled.
  if (PresShell::TouchCaretPrefEnabled()) {
    RefPtr<NodeInfo> nodeInfo;

    // Create and append touch caret frame.
    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nullptr,
                                                   kNameSpaceID_XHTML,
                                                   nsIDOMNode::ELEMENT_NODE);
    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);

    rv = NS_NewHTMLElement(getter_AddRefs(mTouchCaretElement), nodeInfo.forget(),
                           NOT_FROM_PARSER);
    NS_ENSURE_SUCCESS(rv, rv);
    aElements.AppendElement(mTouchCaretElement);

    // Set touch caret to visibility: hidden by default.
    nsAutoString classValue;
    classValue.AppendLiteral("moz-touchcaret hidden");
    rv = mTouchCaretElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                     classValue, true);

    if (!mDummyTouchListener) {
      mDummyTouchListener = new DummyTouchListener();
    }
    mTouchCaretElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                         mDummyTouchListener, false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (PresShell::SelectionCaretPrefEnabled()) {
    // Selection caret
    mSelectionCaretsStartElement = doc->CreateHTMLElement(nsGkAtoms::div);
    aElements.AppendElement(mSelectionCaretsStartElement);
    nsCOMPtr<mozilla::dom::Element> selectionCaretsStartElementInner = doc->CreateHTMLElement(nsGkAtoms::div);
    mSelectionCaretsStartElement->AppendChildTo(selectionCaretsStartElementInner, false);

    mSelectionCaretsEndElement = doc->CreateHTMLElement(nsGkAtoms::div);
    aElements.AppendElement(mSelectionCaretsEndElement);
    nsCOMPtr<mozilla::dom::Element> selectionCaretsEndElementInner = doc->CreateHTMLElement(nsGkAtoms::div);
    mSelectionCaretsEndElement->AppendChildTo(selectionCaretsEndElementInner, false);

    rv = mSelectionCaretsStartElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                               NS_LITERAL_STRING("moz-selectioncaret-left hidden"),
                                               true);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mSelectionCaretsEndElement->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                             NS_LITERAL_STRING("moz-selectioncaret-right hidden"),
                                             true);

    if (!mDummyTouchListener) {
      mDummyTouchListener = new DummyTouchListener();
    }
    mSelectionCaretsStartElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                                   mDummyTouchListener, false);
    mSelectionCaretsEndElement->AddEventListener(NS_LITERAL_STRING("touchstart"),
                                                 mDummyTouchListener, false);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Create the custom content container.
  mCustomContentContainer = doc->CreateHTMLElement(nsGkAtoms::div);
#ifdef DEBUG
  // We restyle our mCustomContentContainer, even though it's root anonymous
  // content.  Normally that's not OK because the frame constructor doesn't know
  // how to order the frame tree in such cases, but we make this work for this
  // particular case, so it's OK.
  mCustomContentContainer->SetProperty(nsGkAtoms::restylableAnonymousNode,
                                       reinterpret_cast<void*>(true));
#endif // DEBUG

  aElements.AppendElement(mCustomContentContainer);

  // XXX add :moz-native-anonymous or will that be automatically set?
  rv = mCustomContentContainer->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
                                        NS_LITERAL_STRING("moz-custom-content-container"),
                                        true);
  NS_ENSURE_SUCCESS(rv, rv);

  // Append all existing AnonymousContent nodes stored at document level if any.
  size_t len = doc->GetAnonymousContents().Length();
  for (size_t i = 0; i < len; ++i) {
    nsCOMPtr<Element> node = doc->GetAnonymousContents()[i]->GetContentNode();
    mCustomContentContainer->AppendChildTo(node->AsContent(), true);
  }

  // Only create a frame for mCustomContentContainer if it has some children.
  if (len == 0) {
    HideCustomContentContainer();
  }

  RefPtr<AccessibleCaretEventHub> eventHub =
    PresContext()->GetPresShell()->GetAccessibleCaretEventHub();
  if (eventHub) {
    // AccessibleCaret will insert anonymous caret elements.
    eventHub->Init();
  }

  return NS_OK;
}
nsresult
nsFontCache::GetMetricsFor(const nsFont& aFont,
                           nsIAtom* aLanguage, bool aExplicitLanguage,
                           gfxFont::Orientation aOrientation,
                           gfxUserFontSet* aUserFontSet,
                           gfxTextPerfMetrics* aTextPerf,
                           nsFontMetrics*& aMetrics)
{
    if (!aLanguage)
        aLanguage = mLocaleLanguage;

    // First check our cache
    // start from the end, which is where we put the most-recent-used element

    nsFontMetrics* fm;
    int32_t n = mFontMetrics.Length() - 1;
    for (int32_t i = n; i >= 0; --i) {
        fm = mFontMetrics[i];
        if (fm->Font().Equals(aFont) && fm->GetUserFontSet() == aUserFontSet &&
            fm->Language() == aLanguage && fm->Orientation() == aOrientation) {
            if (i != n) {
                // promote it to the end of the cache
                mFontMetrics.RemoveElementAt(i);
                mFontMetrics.AppendElement(fm);
            }
            fm->GetThebesFontGroup()->UpdateUserFonts();
            NS_ADDREF(aMetrics = fm);
            return NS_OK;
        }
    }

    // It's not in the cache. Get font metrics and then cache them.

    fm = new nsFontMetrics();
    NS_ADDREF(fm);
    nsresult rv = fm->Init(aFont, aLanguage, aExplicitLanguage, aOrientation,
                           mContext, aUserFontSet, aTextPerf);
    if (NS_SUCCEEDED(rv)) {
        // the mFontMetrics list has the "head" at the end, because append
        // is cheaper than insert
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        NS_ADDREF(aMetrics);
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // One reason why Init() fails is because the system is running out of
    // resources. e.g., on Win95/98 only a very limited number of GDI
    // objects are available. Compact the cache and try again.

    Compact();
    fm = new nsFontMetrics();
    NS_ADDREF(fm);
    rv = fm->Init(aFont, aLanguage, aExplicitLanguage, aOrientation, mContext,
                  aUserFontSet, aTextPerf);
    if (NS_SUCCEEDED(rv)) {
        mFontMetrics.AppendElement(fm);
        aMetrics = fm;
        return NS_OK;
    }
    fm->Destroy();
    NS_RELEASE(fm);

    // could not setup a new one, send an old one (XXX search a "best
    // match"?)

    n = mFontMetrics.Length() - 1; // could have changed in Compact()
    if (n >= 0) {
        aMetrics = mFontMetrics[n];
        NS_ADDREF(aMetrics);
        return NS_OK;
    }

    NS_POSTCONDITION(NS_SUCCEEDED(rv),
                     "font metrics should not be null - bug 136248");
    return rv;
}
void
SVGFEDropShadowElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
}
Exemple #15
0
nsresult
nsFileControlFrame::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
{
  // Get the NodeInfoManager and tag necessary to create input elements
  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();

  nsCOMPtr<nsINodeInfo> nodeInfo;
  doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
                                      kNameSpaceID_None,
                                      getter_AddRefs(nodeInfo));

  // Create the text content
  NS_NewHTMLElement(getter_AddRefs(mTextContent), nodeInfo, PR_FALSE);
  if (!mTextContent)
    return NS_ERROR_OUT_OF_MEMORY;

  mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                        NS_LITERAL_STRING("text"), PR_FALSE);

  nsCOMPtr<nsIDOMHTMLInputElement> textControl = do_QueryInterface(mTextContent);
  if (textControl) {
    nsCOMPtr<nsIFileControlElement> fileControl = do_QueryInterface(mContent);
    if (fileControl) {
      // Initialize value when we create the content in case the value was set
      // before we got here
      nsAutoString value;
      fileControl->GetFileName(value);
      textControl->SetValue(value);
    }

    textControl->SetTabIndex(-1);
    textControl->SetReadOnly(PR_TRUE);
  }

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

  NS_NAMED_LITERAL_STRING(click, "click");
  nsCOMPtr<nsIDOMEventGroup> systemGroup;
  mContent->GetSystemEventGroup(getter_AddRefs(systemGroup));
  nsCOMPtr<nsIDOM3EventTarget> dom3TextContent =
    do_QueryInterface(mTextContent);
  NS_ENSURE_STATE(dom3TextContent);
  // Register as an event listener of the textbox
  // to open file dialog on mouse click
  dom3TextContent->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
                                           systemGroup);

  // Create the browse button
  NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo, PR_FALSE);
  if (!mBrowse)
    return NS_ERROR_OUT_OF_MEMORY;

  mBrowse->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                   NS_LITERAL_STRING("button"), PR_FALSE);
  nsCOMPtr<nsIDOMHTMLInputElement> fileContent = do_QueryInterface(mContent);
  nsCOMPtr<nsIDOMHTMLInputElement> browseControl = do_QueryInterface(mBrowse);
  if (fileContent && browseControl) {
    PRInt32 tabIndex;
    nsAutoString accessKey;

    fileContent->GetAccessKey(accessKey);
    browseControl->SetAccessKey(accessKey);
    fileContent->GetTabIndex(&tabIndex);
    browseControl->SetTabIndex(tabIndex);
  }

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

  nsCOMPtr<nsIDOM3EventTarget> dom3Browse = do_QueryInterface(mBrowse);
  NS_ENSURE_STATE(dom3Browse);
  // Register as an event listener of the button
  // to open file dialog on mouse click
  dom3Browse->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
                                      systemGroup);

  SyncAttr(kNameSpaceID_None, nsGkAtoms::size,     SYNC_TEXT);
  SyncAttr(kNameSpaceID_None, nsGkAtoms::disabled, SYNC_BOTH);

  return NS_OK;
}
void
KeyframeEffectReadOnly::GetKeyframes(JSContext*& aCx,
                                     nsTArray<JSObject*>& aResult,
                                     ErrorResult& aRv)
{
  MOZ_ASSERT(aResult.IsEmpty());
  MOZ_ASSERT(!aRv.Failed());

  if (!aResult.SetCapacity(mKeyframes.Length(), mozilla::fallible)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  for (const Keyframe& keyframe : mKeyframes) {
    // Set up a dictionary object for the explicit members
    BaseComputedKeyframe keyframeDict;
    if (keyframe.mOffset) {
      keyframeDict.mOffset.SetValue(keyframe.mOffset.value());
    }
    MOZ_ASSERT(keyframe.mComputedOffset != Keyframe::kComputedOffsetNotSet,
               "Invalid computed offset");
    keyframeDict.mComputedOffset.Construct(keyframe.mComputedOffset);
    if (keyframe.mTimingFunction) {
      keyframeDict.mEasing.Truncate();
      keyframe.mTimingFunction.ref().AppendToString(keyframeDict.mEasing);
    } // else if null, leave easing as its default "linear".

    JS::Rooted<JS::Value> keyframeJSValue(aCx);
    if (!ToJSValue(aCx, keyframeDict, &keyframeJSValue)) {
      aRv.Throw(NS_ERROR_FAILURE);
      return;
    }

    JS::Rooted<JSObject*> keyframeObject(aCx, &keyframeJSValue.toObject());
    for (const PropertyValuePair& propertyValue : keyframe.mPropertyValues) {

      const char* name = nsCSSProps::PropertyIDLName(propertyValue.mProperty);

      // nsCSSValue::AppendToString does not accept shorthands properties but
      // works with token stream values if we pass eCSSProperty_UNKNOWN as
      // the property.
      nsCSSPropertyID propertyForSerializing =
        nsCSSProps::IsShorthand(propertyValue.mProperty)
        ? eCSSProperty_UNKNOWN
        : propertyValue.mProperty;

      nsAutoString stringValue;
      propertyValue.mValue.AppendToString(
        propertyForSerializing, stringValue, nsCSSValue::eNormalized);

      JS::Rooted<JS::Value> value(aCx);
      if (!ToJSValue(aCx, stringValue, &value) ||
          !JS_DefineProperty(aCx, keyframeObject, name, value,
                             JSPROP_ENUMERATE)) {
        aRv.Throw(NS_ERROR_FAILURE);
        return;
      }
    }

    aResult.AppendElement(keyframeObject);
  }
}
Exemple #17
0
nsresult
nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  NS_ASSERTION(mContent, "We should have a content!");

  mState |= NS_FRAME_INDEPENDENT_SELECTION;

  nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
  NS_ASSERTION(txtCtrl, "Content not a text control element");

  // Bind the frame to its text control
  nsresult rv = txtCtrl->BindToFrame(this);
  NS_ENSURE_SUCCESS(rv, rv);

  nsIContent* rootNode = txtCtrl->GetRootEditorNode();
  NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY);

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

  // Do we need a placeholder node?
  nsAutoString placeholderTxt;
  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder,
                    placeholderTxt);
  nsContentUtils::RemoveNewlines(placeholderTxt);
  mUsePlaceholder = !placeholderTxt.IsEmpty();

  // Create the placeholder anonymous content if needed.
  if (mUsePlaceholder) {
    nsIContent* placeholderNode = txtCtrl->CreatePlaceholderNode();
    NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY);

    // Associate ::placeholder pseudo-element with the placeholder node.
    CSSPseudoElementType pseudoType = CSSPseudoElementType::placeholder;

    // If this is a text input inside a number input then we want to use the
    // main number input as the source of style for the placeholder frame.
    nsIFrame* mainInputFrame = this;
    if (StyleContext()->GetPseudoType() == CSSPseudoElementType::mozNumberText) {
      do {
        mainInputFrame = mainInputFrame->GetParent();
      } while (mainInputFrame &&
               mainInputFrame->GetType() != nsGkAtoms::numberControlFrame);
      MOZ_ASSERT(mainInputFrame);
    }

    RefPtr<nsStyleContext> placeholderStyleContext =
      PresContext()->StyleSet()->ResolvePseudoElementStyle(
          mainInputFrame->GetContent()->AsElement(), pseudoType, StyleContext(),
          placeholderNode->AsElement());

    if (!aElements.AppendElement(ContentInfo(placeholderNode,
                                 placeholderStyleContext))) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    if (!IsSingleLineTextControl()) {
      // For textareas, UpdateValueDisplay doesn't initialize the visibility
      // status of the placeholder because it returns early, so we have to
      // do that manually here.
      txtCtrl->UpdatePlaceholderVisibility(true);
    }
  }

  rv = UpdateValueDisplay(false);
  NS_ENSURE_SUCCESS(rv, rv);

  // textareas are eagerly initialized
  bool initEagerly = !IsSingleLineTextControl();
  if (!initEagerly) {
    // Also, input elements which have a cached selection should get eager
    // editor initialization.
    nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
    NS_ASSERTION(txtCtrl, "Content not a text control element");
    initEagerly = txtCtrl->HasCachedSelection();
  }
  if (!initEagerly) {
    nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(txtCtrl);
    if (element) {
      // so are input text controls with spellcheck=true
      element->GetSpellcheck(&initEagerly);
    }
  }

  if (initEagerly) {
    NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                 "Someone forgot a script blocker?");
    EditorInitializer* initializer = Properties().Get(TextControlInitializer());
    if (initializer) {
      initializer->Revoke();
    }
    initializer = new EditorInitializer(this);
    Properties().Set(TextControlInitializer(),initializer);
    nsContentUtils::AddScriptRunner(initializer);
  }

  return NS_OK;
}
already_AddRefed<Layer> CreateLayerTree(
    const char* aLayerTreeDescription,
    nsIntRegion* aVisibleRegions,
    const Matrix4x4* aTransforms,
    RefPtr<LayerManager>& manager,
    nsTArray<RefPtr<Layer> >& aLayersOut) {

  aLayersOut.Clear();

  if (!manager) {
    manager = new TestLayerManager();
  }

  RefPtr<Layer> rootLayer = nullptr;
  RefPtr<ContainerLayer> parentContainerLayer = nullptr;
  RefPtr<Layer> lastLayer = nullptr;
  int layerNumber = 0;
  for (size_t i = 0; i < strlen(aLayerTreeDescription); i++) {
    if (aLayerTreeDescription[i] == '(') {
      if (!lastLayer) {
        printf("Syntax error, likely '(' character isn't preceded by a container.\n");
        MOZ_CRASH();
      }
      parentContainerLayer = lastLayer->AsContainerLayer();
      if (!parentContainerLayer) {
        printf("Layer before '(' must be a container.\n");
        MOZ_CRASH();
      }
    } else if (aLayerTreeDescription[i] == ')') {
      parentContainerLayer = parentContainerLayer->GetParent();
      lastLayer = nullptr;
    } else {
      RefPtr<Layer> layer = CreateLayer(aLayerTreeDescription[i], manager.get());
      if (aVisibleRegions) {
        layer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(aVisibleRegions[layerNumber]));
        layer->SetEventRegions(EventRegions(aVisibleRegions[layerNumber]));
      }
      if (aTransforms) {
        layer->SetBaseTransform(aTransforms[layerNumber]);
      }
      aLayersOut.AppendElement(layer);
      layerNumber++;
      if (rootLayer && !parentContainerLayer) {
        MOZ_CRASH();
      }
      if (!rootLayer) {
        rootLayer = layer;
      }
      if (parentContainerLayer) {
        parentContainerLayer->InsertAfter(layer, parentContainerLayer->GetLastChild());
        layer->SetParent(parentContainerLayer);
      }
      lastLayer = layer;
    }
  }
  if (rootLayer) {
    rootLayer->ComputeEffectiveTransforms(Matrix4x4());
    manager->SetRoot(rootLayer);
    if (rootLayer->AsLayerComposite()) {
      // Only perform this for LayerManagerComposite
      CompositorBridgeParent::SetShadowProperties(rootLayer);
    }
  }
  return rootLayer.forget();
}
Exemple #19
0
void
GMPAudioDecoder::InitTags(nsTArray<nsCString>& aTags)
{
  aTags.AppendElement(NS_LITERAL_CSTRING("aac"));
}
void
EMEVideoDecoder::InitTags(nsTArray<nsCString>& aTags)
{
  GMPVideoDecoder::InitTags(aTags);
  aTags.AppendElement(NS_ConvertUTF16toUTF8(mProxy->KeySystem()));
}
Exemple #21
0
nsresult
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager();
  nsRefPtr<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;
}
static nsresult
ParseSSSHeaders(uint32_t aType,
                const char* aHeader,
                bool& foundIncludeSubdomains,
                bool& foundMaxAge,
                bool& foundUnrecognizedDirective,
                int64_t& maxAge,
                nsTArray<nsCString>& sha256keys)
{
  // Stric transport security and Public Key Pinning have very similar
  // Header formats.

  // "Strict-Transport-Security" ":" OWS
  //      STS-d  *( OWS ";" OWS STS-d  OWS)
  //
  //  ; STS directive
  //  STS-d      = maxAge / includeSubDomains
  //
  //  maxAge     = "max-age" "=" delta-seconds v-ext
  //
  //  includeSubDomains = [ "includeSubDomains" ]
  //

  // "Public-Key-Pins ":" OWS
  //      PKP-d  *( OWS ";" OWS PKP-d  OWS)
  //
  //  ; PKP directive
  //  PKP-d      = maxAge / includeSubDomains / reportUri / pin-directive
  //
  //  maxAge     = "max-age" "=" delta-seconds v-ext
  //
  //  includeSubDomains = [ "includeSubDomains" ]
  //
  //  reportURi  = "report-uri" "=" quoted-string
  //
  //  pin-directive = "pin-" token "=" quoted-string
  //
  //  the only valid token currently specified is sha256
  //  the quoted string for a pin directive is the base64 encoding
  //  of the hash of the public key of the fingerprint
  //

  //  The order of the directives is not significant.
  //  All directives must appear only once.
  //  Directive names are case-insensitive.
  //  The entire header is invalid if a directive not conforming to the
  //  syntax is encountered.
  //  Unrecognized directives (that are otherwise syntactically valid) are
  //  ignored, and the rest of the header is parsed as normal.

  bool foundReportURI = false;

  NS_NAMED_LITERAL_CSTRING(max_age_var, "max-age");
  NS_NAMED_LITERAL_CSTRING(include_subd_var, "includesubdomains");
  NS_NAMED_LITERAL_CSTRING(pin_sha256_var, "pin-sha256");
  NS_NAMED_LITERAL_CSTRING(report_uri_var, "report-uri");

  nsSecurityHeaderParser parser(aHeader);
  nsresult rv = parser.Parse();
  if (NS_FAILED(rv)) {
    SSSLOG(("SSS: could not parse header"));
    return rv;
  }
  mozilla::LinkedList<nsSecurityHeaderDirective>* directives = parser.GetDirectives();

  for (nsSecurityHeaderDirective* directive = directives->getFirst();
       directive != nullptr; directive = directive->getNext()) {
    SSSLOG(("SSS: found directive %s\n", directive->mName.get()));
    if (directive->mName.Length() == max_age_var.Length() &&
        directive->mName.EqualsIgnoreCase(max_age_var.get(),
                                          max_age_var.Length())) {
      if (foundMaxAge) {
        SSSLOG(("SSS: found two max-age directives"));
        return NS_ERROR_FAILURE;
      }

      SSSLOG(("SSS: found max-age directive"));
      foundMaxAge = true;

      size_t len = directive->mValue.Length();
      for (size_t i = 0; i < len; i++) {
        char chr = directive->mValue.CharAt(i);
        if (chr < '0' || chr > '9') {
          SSSLOG(("SSS: invalid value for max-age directive"));
          return NS_ERROR_FAILURE;
        }
      }

      if (PR_sscanf(directive->mValue.get(), "%lld", &maxAge) != 1) {
        SSSLOG(("SSS: could not parse delta-seconds"));
        return NS_ERROR_FAILURE;
      }

      SSSLOG(("SSS: parsed delta-seconds: %lld", maxAge));
    } else if (directive->mName.Length() == include_subd_var.Length() &&
               directive->mName.EqualsIgnoreCase(include_subd_var.get(),
                                                 include_subd_var.Length())) {
      if (foundIncludeSubdomains) {
        SSSLOG(("SSS: found two includeSubdomains directives"));
        return NS_ERROR_FAILURE;
      }

      SSSLOG(("SSS: found includeSubdomains directive"));
      foundIncludeSubdomains = true;

      if (directive->mValue.Length() != 0) {
        SSSLOG(("SSS: includeSubdomains directive unexpectedly had value '%s'",
                directive->mValue.get()));
        return NS_ERROR_FAILURE;
      }
    } else if (aType == nsISiteSecurityService::HEADER_HPKP &&
               directive->mName.Length() == pin_sha256_var.Length() &&
               directive->mName.EqualsIgnoreCase(pin_sha256_var.get(),
                                                 pin_sha256_var.Length())) {
       SSSLOG(("SSS: found pinning entry '%s' length=%d",
               directive->mValue.get(), directive->mValue.Length()));
       if (!stringIsBase64EncodingOf256bitValue(directive->mValue)) {
         return NS_ERROR_FAILURE;
       }
       sha256keys.AppendElement(directive->mValue);
   } else if (aType == nsISiteSecurityService::HEADER_HPKP &&
              directive->mName.Length() == report_uri_var.Length() &&
              directive->mName.EqualsIgnoreCase(report_uri_var.get(),
                                                report_uri_var.Length())) {
       // We doni't support the report-uri yet, but to avoid unrecognized
       // directive warnings, we still have to handle its presence
      if (foundReportURI) {
        SSSLOG(("SSS: found two report-uri directives"));
        return NS_ERROR_FAILURE;
      }
      SSSLOG(("SSS: found report-uri directive"));
      foundReportURI = true;
   } else {
      SSSLOG(("SSS: ignoring unrecognized directive '%s'",
              directive->mName.get()));
      foundUnrecognizedDirective = true;
    }
  }
  return NS_OK;
}
nsresult
HTMLFormControlsCollection::GetSortedControls(
  nsTArray<nsGenericHTMLFormElement*>& aControls) const
{
#ifdef DEBUG
  HTMLFormElement::AssertDocumentOrder(mElements, mForm);
  HTMLFormElement::AssertDocumentOrder(mNotInElements, mForm);
#endif

  aControls.Clear();

  // Merge the elements list and the not in elements list. Both lists are
  // already sorted.
  uint32_t elementsLen = mElements.Length();
  uint32_t notInElementsLen = mNotInElements.Length();
  aControls.SetCapacity(elementsLen + notInElementsLen);

  uint32_t elementsIdx = 0;
  uint32_t notInElementsIdx = 0;

  while (elementsIdx < elementsLen || notInElementsIdx < notInElementsLen) {
    // Check whether we're done with mElements
    if (elementsIdx == elementsLen) {
      NS_ASSERTION(notInElementsIdx < notInElementsLen,
                   "Should have remaining not-in-elements");
      // Append the remaining mNotInElements elements
      if (!aControls.AppendElements(mNotInElements.Elements() +
                                      notInElementsIdx,
                                    notInElementsLen -
                                      notInElementsIdx)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      break;
    }
    // Check whether we're done with mNotInElements
    if (notInElementsIdx == notInElementsLen) {
      NS_ASSERTION(elementsIdx < elementsLen,
                   "Should have remaining in-elements");
      // Append the remaining mElements elements
      if (!aControls.AppendElements(mElements.Elements() +
                                      elementsIdx,
                                    elementsLen -
                                      elementsIdx)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      break;
    }
    // Both lists have elements left.
    NS_ASSERTION(mElements[elementsIdx] &&
                 mNotInElements[notInElementsIdx],
                 "Should have remaining elements");
    // Determine which of the two elements should be ordered
    // first and add it to the end of the list.
    nsGenericHTMLFormElement* elementToAdd;
    if (HTMLFormElement::CompareFormControlPosition(
          mElements[elementsIdx], mNotInElements[notInElementsIdx], mForm) < 0) {
      elementToAdd = mElements[elementsIdx];
      ++elementsIdx;
    } else {
      elementToAdd = mNotInElements[notInElementsIdx];
      ++notInElementsIdx;
    }
    // Add the first element to the list.
    if (!aControls.AppendElement(elementToAdd)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  NS_ASSERTION(aControls.Length() == elementsLen + notInElementsLen,
               "Not all form controls were added to the sorted list");
#ifdef DEBUG
  HTMLFormElement::AssertDocumentOrder(aControls, mForm);
#endif

  return NS_OK;
}
 void Generate(nsTArray<RefPtr<Image> > &aImages)
 {
   aImages.AppendElement(CreateI420Image());
   aImages.AppendElement(CreateNV12Image());
   aImages.AppendElement(CreateNV21Image());
 }
Exemple #25
0
nsresult
nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  NS_ASSERTION(mContent, "We should have a content!");

  mState |= NS_FRAME_INDEPENDENT_SELECTION;

  nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
  NS_ASSERTION(txtCtrl, "Content not a text control element");

  // Bind the frame to its text control
  nsresult rv = txtCtrl->BindToFrame(this);
  NS_ENSURE_SUCCESS(rv, rv);

  nsIContent* rootNode = txtCtrl->GetRootEditorNode();
  NS_ENSURE_TRUE(rootNode, NS_ERROR_OUT_OF_MEMORY);

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

  // Do we need a placeholder node?
  nsAutoString placeholderTxt;
  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder,
                    placeholderTxt);
  nsContentUtils::RemoveNewlines(placeholderTxt);
  mUsePlaceholder = !placeholderTxt.IsEmpty();

  // Create the placeholder anonymous content if needed.
  if (mUsePlaceholder) {
    nsIContent* placeholderNode = txtCtrl->CreatePlaceholderNode();
    NS_ENSURE_TRUE(placeholderNode, NS_ERROR_OUT_OF_MEMORY);

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

  rv = UpdateValueDisplay(PR_FALSE);
  NS_ENSURE_SUCCESS(rv, rv);

  // textareas are eagerly initialized
  PRBool initEagerly = !IsSingleLineTextControl();
  if (!initEagerly) {
    nsCOMPtr<nsIDOMNSHTMLElement> element = do_QueryInterface(txtCtrl);
    if (element) {
      // so are input text controls with spellcheck=true
      element->GetSpellcheck(&initEagerly);
    }
  }

  if (initEagerly) {
    NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                 "Someone forgot a script blocker?");
    EditorInitializer* initializer = (EditorInitializer*) Properties().Get(TextControlInitializer());
    if (initializer) {
      initializer->Revoke();
    }
    initializer = new EditorInitializer(this);
    Properties().Set(TextControlInitializer(),initializer);
    if (!nsContentUtils::AddScriptRunner(initializer)) {
      initializer->Revoke(); // paranoia
      Properties().Delete(TextControlInitializer());
      delete initializer;
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }

  return NS_OK;
}
 void AppendElement(T aValue) {
   mValues.AppendElement(new TemplatePropertyValue<T>(aValue));
 }
void
SVGFECompositeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
{
  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
}
nsresult
nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
  // Get the NodeInfoManager and tag necessary to create input elements
  nsCOMPtr<nsIDocument> doc = mContent->GetDocument();

  nsCOMPtr<nsINodeInfo> nodeInfo;
  nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nullptr,
                                                 kNameSpaceID_XHTML,
                                                 nsIDOMNode::ELEMENT_NODE);

  // Create the text content
  NS_NewHTMLElement(getter_AddRefs(mTextContent), nodeInfo.forget(),
                    dom::NOT_FROM_PARSER);
  if (!mTextContent)
    return NS_ERROR_OUT_OF_MEMORY;

  // Mark the element to be native anonymous before setting any attributes.
  mTextContent->SetNativeAnonymous();

  mTextContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                        NS_LITERAL_STRING("text"), false);

  nsHTMLInputElement* inputElement =
    nsHTMLInputElement::FromContent(mContent);
  NS_ASSERTION(inputElement, "Why is our content not a <input>?");

  // Initialize value when we create the content in case the value was set
  // before we got here
  nsAutoString value;
  inputElement->GetDisplayFileName(value);

  nsCOMPtr<nsIDOMHTMLInputElement> textControl = do_QueryInterface(mTextContent);
  NS_ASSERTION(textControl, "Why is the <input> we created not a <input>?");
  textControl->SetValue(value);

  textControl->SetTabIndex(-1);
  textControl->SetReadOnly(true);

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

  // Register the whole frame as an event listener of drag events
  mContent->AddSystemEventListener(NS_LITERAL_STRING("drop"),
                                   mMouseListener, false);
  mContent->AddSystemEventListener(NS_LITERAL_STRING("dragover"),
                                   mMouseListener, false);

  // Register as an event listener of the textbox
  // to open file dialog on mouse click
  mTextContent->AddSystemEventListener(NS_LITERAL_STRING("click"),
                                       mMouseListener, false);

  // Create the browse button
  nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nullptr,
                                                 kNameSpaceID_XHTML,
                                                 nsIDOMNode::ELEMENT_NODE);
  NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo.forget(),
                    dom::NOT_FROM_PARSER);
  if (!mBrowse)
    return NS_ERROR_OUT_OF_MEMORY;

  // Mark the element to be native anonymous before setting any attributes.
  mBrowse->SetNativeAnonymous();

  mBrowse->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                   NS_LITERAL_STRING("button"), false);

  // Create the capture button
  nsCOMPtr<nsICapturePicker> capturePicker;
  capturePicker = do_GetService("@mozilla.org/capturepicker;1");
  if (capturePicker) {
    CaptureCallbackData data;
    data.picker = capturePicker;
    data.mode = GetCaptureMode(data);

    if (data.mode != 0) {
      mCaptureMouseListener->mMode = data.mode;
      nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nullptr,
                                                     kNameSpaceID_XHTML,
                                                     nsIDOMNode::ELEMENT_NODE);
      NS_NewHTMLElement(getter_AddRefs(mCapture), nodeInfo.forget(),
                        dom::NOT_FROM_PARSER);
      if (!mCapture)
        return NS_ERROR_OUT_OF_MEMORY;

      // Mark the element to be native anonymous before setting any attributes.
      mCapture->SetNativeAnonymous();

      mCapture->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                        NS_LITERAL_STRING("button"), false);

      mCapture->SetAttr(kNameSpaceID_None, nsGkAtoms::value,
                        NS_LITERAL_STRING("capture"), false);

      mCapture->AddSystemEventListener(NS_LITERAL_STRING("click"),
                                       mCaptureMouseListener, false);
    }
  }
  nsCOMPtr<nsIDOMHTMLInputElement> fileContent = do_QueryInterface(mContent);
  nsCOMPtr<nsIDOMHTMLInputElement> browseControl = do_QueryInterface(mBrowse);
  if (fileContent && browseControl) {
    int32_t tabIndex;
    nsAutoString accessKey;

    fileContent->GetAccessKey(accessKey);
    browseControl->SetAccessKey(accessKey);
    fileContent->GetTabIndex(&tabIndex);
    browseControl->SetTabIndex(tabIndex);
  }

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

  if (mCapture && !aElements.AppendElement(mCapture))
    return NS_ERROR_OUT_OF_MEMORY;

  // Register as an event listener of the button
  // to open file dialog on mouse click
  mBrowse->AddSystemEventListener(NS_LITERAL_STRING("click"),
                                  mMouseListener, false);

  SyncAttr(kNameSpaceID_None, nsGkAtoms::size,     SYNC_TEXT);
  SyncDisabledState();

  return NS_OK;
}
void
Logger::LogEvent(ICallFrame* aCallFrame, IUnknown* aTargetInterface)
{
  // (1) Gather info about the call
  double elapsed = GetElapsedTime();

  CALLFRAMEINFO callInfo;
  HRESULT hr = aCallFrame->GetInfo(&callInfo);
  if (FAILED(hr)) {
    return;
  }

  PWSTR interfaceName = nullptr;
  PWSTR methodName = nullptr;
  hr = aCallFrame->GetNames(&interfaceName, &methodName);
  if (FAILED(hr)) {
    return;
  }

  // (2) Serialize the call
  nsPrintfCString line("%fus\t0x%p\t%S::%S\t(", elapsed,
                       aTargetInterface, interfaceName, methodName);

  CoTaskMemFree(interfaceName);
  interfaceName = nullptr;
  CoTaskMemFree(methodName);
  methodName = nullptr;

  // Check for supplemental array data
  const ArrayData* arrayData = FindArrayData(callInfo.iid, callInfo.iMethod);

  for (ULONG paramIndex = 0; paramIndex < callInfo.cParams; ++paramIndex) {
    CALLFRAMEPARAMINFO paramInfo;
    hr = aCallFrame->GetParamInfo(paramIndex, &paramInfo);
    if (SUCCEEDED(hr)) {
      line.AppendLiteral("[");
      if (paramInfo.fIn) {
        line.AppendLiteral("in");
      }
      if (paramInfo.fOut) {
        line.AppendLiteral("out");
      }
      line.AppendLiteral("] ");
    }
    VARIANT paramValue;
    hr = aCallFrame->GetParam(paramIndex, &paramValue);
    if (SUCCEEDED(hr)) {
      if (arrayData && paramIndex == arrayData->mArrayParamIndex) {
        VARIANT lengthParam;
        hr = aCallFrame->GetParam(arrayData->mLengthParamIndex, &lengthParam);
        if (SUCCEEDED(hr)) {
          line.AppendLiteral("{ ");
          for (LONG i = 0; i < *lengthParam.plVal; ++i) {
            VariantToString(paramValue, line, i);
            if (i < *lengthParam.plVal - 1) {
              line.AppendLiteral(", ");
            }
          }
          line.AppendLiteral(" }");
        } else {
          line.AppendPrintf("(GetParam failed with HRESULT 0x%08X)", hr);
        }
      } else {
        VariantToString(paramValue, line);
      }
    } else {
      line.AppendPrintf("(GetParam failed with HRESULT 0x%08X)", hr);
    }
    if (paramIndex < callInfo.cParams - 1) {
      line.AppendLiteral(", ");
    }
  }
  line.AppendLiteral(")\t");

  HRESULT callResult = aCallFrame->GetReturnValue();
  line.AppendPrintf("0x%08X\n", callResult);

  // (3) Enqueue event for logging
  MutexAutoLock lock(mMutex);
  mEntries.AppendElement(line);
  mThread->Dispatch(NewNonOwningRunnableMethod(this, &Logger::Flush),
                    NS_DISPATCH_NORMAL);
}
void
KeyframeEffectReadOnly::GetProperties(
    nsTArray<AnimationPropertyDetails>& aProperties,
    ErrorResult& aRv) const
{
  for (const AnimationProperty& property : mProperties) {
    AnimationPropertyDetails propertyDetails;
    propertyDetails.mProperty =
      NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(property.mProperty));
    propertyDetails.mRunningOnCompositor = property.mIsRunningOnCompositor;

    nsXPIDLString localizedString;
    if (property.mPerformanceWarning &&
        property.mPerformanceWarning->ToLocalizedString(localizedString)) {
      propertyDetails.mWarning.Construct(localizedString);
    }

    if (!propertyDetails.mValues.SetCapacity(property.mSegments.Length(),
                                             mozilla::fallible)) {
      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
      return;
    }

    for (size_t segmentIdx = 0, segmentLen = property.mSegments.Length();
         segmentIdx < segmentLen;
         segmentIdx++)
    {
      const AnimationPropertySegment& segment = property.mSegments[segmentIdx];

      binding_detail::FastAnimationPropertyValueDetails fromValue;
      CreatePropertyValue(property.mProperty, segment.mFromKey,
                          segment.mTimingFunction, segment.mFromValue,
                          fromValue);
      // We don't apply timing functions for zero-length segments, so
      // don't return one here.
      if (segment.mFromKey == segment.mToKey) {
        fromValue.mEasing.Reset();
      }
      // The following won't fail since we have already allocated the capacity
      // above.
      propertyDetails.mValues.AppendElement(fromValue, mozilla::fallible);

      // Normally we can ignore the to-value for this segment since it is
      // identical to the from-value from the next segment. However, we need
      // to add it if either:
      // a) this is the last segment, or
      // b) the next segment's from-value differs.
      if (segmentIdx == segmentLen - 1 ||
          property.mSegments[segmentIdx + 1].mFromValue != segment.mToValue) {
        binding_detail::FastAnimationPropertyValueDetails toValue;
        CreatePropertyValue(property.mProperty, segment.mToKey,
                            Nothing(), segment.mToValue, toValue);
        // It doesn't really make sense to have a timing function on the
        // last property value or before a sudden jump so we just drop the
        // easing property altogether.
        toValue.mEasing.Reset();
        propertyDetails.mValues.AppendElement(toValue, mozilla::fallible);
      }
    }

    aProperties.AppendElement(propertyDetails);
  }
}