void WindowGlobalChild::HandleAsyncMessage(const nsString& aActorName,
                                           const nsString& aMessageName,
                                           StructuredCloneData& aData) {
  if (NS_WARN_IF(mIPCClosed)) {
    return;
  }

  // Force creation of the actor if it hasn't been created yet.
  IgnoredErrorResult rv;
  RefPtr<JSWindowActorChild> actor = GetActor(aActorName, rv);
  if (NS_WARN_IF(rv.Failed())) {
    return;
  }

  // Get the JSObject for the named actor.
  JS::RootedObject obj(RootingCx(), actor->GetWrapper());
  if (NS_WARN_IF(!obj)) {
    // If we don't have a preserved wrapper, there won't be any receiver
    // method to call.
    return;
  }

  RefPtr<JSWindowActorService> actorSvc = JSWindowActorService::GetSingleton();
  if (NS_WARN_IF(!actorSvc)) {
    return;
  }

  actorSvc->ReceiveMessage(actor, obj, aMessageName, aData);
}
Esempio n. 2
0
void JSWindowActor::QueryHandler::ResolvedCallback(
    JSContext* aCx, JS::Handle<JS::Value> aValue) {
  if (!mActor) {
    return;
  }

  ipc::StructuredCloneData data;
  data.InitScope(JS::StructuredCloneScope::DifferentProcess);

  IgnoredErrorResult error;
  data.Write(aCx, aValue, error);
  if (NS_WARN_IF(error.Failed())) {
    // We failed to serialize the message over IPC. Report this error to the
    // console, and send a reject reply.
    nsAutoString msg;
    msg.Append(mActor->Name());
    msg.Append(':');
    msg.Append(mMessageName);
    msg.Append(NS_LITERAL_STRING(": message reply cannot be cloned."));
    nsContentUtils::LogSimpleConsoleError(msg, "chrome", false, true);

    JS_ClearPendingException(aCx);

    SendReply(aCx, JSWindowActorMessageKind::QueryReject,
              ipc::StructuredCloneData());
    return;
  }

  SendReply(aCx, JSWindowActorMessageKind::QueryResolve, std::move(data));
}
// static
nsresult CompositionTransaction::SetIMESelection(
    EditorBase& aEditorBase, Text* aTextNode, uint32_t aOffsetInNode,
    uint32_t aLengthOfCompositionString, const TextRangeArray* aRanges) {
  RefPtr<Selection> selection = aEditorBase.GetSelection();
  NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);

  SelectionBatcher selectionBatcher(selection);

  // First, remove all selections of IME composition.
  static const RawSelectionType kIMESelections[] = {
      nsISelectionController::SELECTION_IME_RAWINPUT,
      nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
      nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
      nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT};

  nsCOMPtr<nsISelectionController> selCon;
  aEditorBase.GetSelectionController(getter_AddRefs(selCon));
  NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);

  nsresult rv = NS_OK;
  for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) {
    RefPtr<Selection> selectionOfIME = selCon->GetSelection(kIMESelections[i]);
    if (!selectionOfIME) {
      continue;
    }
    selectionOfIME->RemoveAllRanges(IgnoreErrors());
  }

  // Set caret position and selection of IME composition with TextRangeArray.
  bool setCaret = false;
  uint32_t countOfRanges = aRanges ? aRanges->Length() : 0;

#ifdef DEBUG
  // Bounds-checking on debug builds
  uint32_t maxOffset = aTextNode->Length();
#endif

  // NOTE: composition string may be truncated when it's committed and
  //       maxlength attribute value doesn't allow input of all text of this
  //       composition.
  for (uint32_t i = 0; i < countOfRanges; ++i) {
    const TextRange& textRange = aRanges->ElementAt(i);

    // Caret needs special handling since its length may be 0 and if it's not
    // specified explicitly, we need to handle it ourselves later.
    if (textRange.mRangeType == TextRangeType::eCaret) {
      NS_ASSERTION(!setCaret, "The ranges already has caret position");
      NS_ASSERTION(!textRange.Length(),
                   "EditorBase doesn't support wide caret");
      int32_t caretOffset = static_cast<int32_t>(
          aOffsetInNode +
          std::min(textRange.mStartOffset, aLengthOfCompositionString));
      MOZ_ASSERT(caretOffset >= 0 &&
                 static_cast<uint32_t>(caretOffset) <= maxOffset);
      rv = selection->Collapse(aTextNode, caretOffset);
      setCaret = setCaret || NS_SUCCEEDED(rv);
      if (NS_WARN_IF(!setCaret)) {
        continue;
      }
      // If caret range is specified explicitly, we should show the caret if
      // it should be so.
      aEditorBase.HideCaret(false);
      continue;
    }

    // If the clause length is 0, it should be a bug.
    if (!textRange.Length()) {
      NS_WARNING("Any clauses must not be empty");
      continue;
    }

    RefPtr<nsRange> clauseRange;
    int32_t startOffset = static_cast<int32_t>(
        aOffsetInNode +
        std::min(textRange.mStartOffset, aLengthOfCompositionString));
    MOZ_ASSERT(startOffset >= 0 &&
               static_cast<uint32_t>(startOffset) <= maxOffset);
    int32_t endOffset = static_cast<int32_t>(
        aOffsetInNode +
        std::min(textRange.mEndOffset, aLengthOfCompositionString));
    MOZ_ASSERT(endOffset >= startOffset &&
               static_cast<uint32_t>(endOffset) <= maxOffset);
    rv = nsRange::CreateRange(aTextNode, startOffset, aTextNode, endOffset,
                              getter_AddRefs(clauseRange));
    if (NS_FAILED(rv)) {
      NS_WARNING("Failed to create a DOM range for a clause of composition");
      break;
    }

    // Set the range of the clause to selection.
    RefPtr<Selection> selectionOfIME =
        selCon->GetSelection(ToRawSelectionType(textRange.mRangeType));
    if (!selectionOfIME) {
      NS_WARNING("Failed to get IME selection");
      break;
    }

    IgnoredErrorResult err;
    selectionOfIME->AddRange(*clauseRange, err);
    if (err.Failed()) {
      NS_WARNING("Failed to add selection range for a clause of composition");
      break;
    }

    // Set the style of the clause.
    rv = selectionOfIME->SetTextRangeStyle(clauseRange, textRange.mRangeStyle);
    if (NS_FAILED(rv)) {
      NS_WARNING("Failed to set selection style");
      break;  // but this is unexpected...
    }
  }

  // If the ranges doesn't include explicit caret position, let's set the
  // caret to the end of composition string.
  if (!setCaret) {
    int32_t caretOffset =
        static_cast<int32_t>(aOffsetInNode + aLengthOfCompositionString);
    MOZ_ASSERT(caretOffset >= 0 &&
               static_cast<uint32_t>(caretOffset) <= maxOffset);
    rv = selection->Collapse(aTextNode, caretOffset);
    NS_ASSERTION(NS_SUCCEEDED(rv),
                 "Failed to set caret at the end of composition string");

    // If caret range isn't specified explicitly, we should hide the caret.
    // Hiding the caret benefits a Windows build (see bug 555642 comment #6).
    // However, when there is no range, we should keep showing caret.
    if (countOfRanges) {
      aEditorBase.HideCaret(true);
    }
  }

  return rv;
}