firefox的选择区域html的内部生成

本文详细解析了如何使用NS Clipboard API 获取文档内容和执行剪贴板操作,包括从视图编辑器获取内容、执行剪贴板命令、复制特定格式文本以及通过文档编辑器获取并设置剪贴板内容的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



NS_IMETHODIMP
nsSelectionCommand::DoCommand(const char *aCommandName,
                              nsISupports *aCommandContext)
{
  nsCOMPtr<nsIContentViewerEdit> contentEdit;
  GetContentViewerEditFromContext(aCommandContext,  getter_AddRefs(contentEdit));
  NS_ENSURE_TRUE(contentEdit, NS_ERROR_NOT_INITIALIZED);

  return DoClipboardCommand(aCommandName, contentEdit, nsnull);
}
nsresult
nsClipboardGetContentsCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
{
  NS_ENSURE_ARG(aParams);

  nsCAutoString mimeType("text/plain");

  nsXPIDLCString format;    // nsICommandParams needs to use nsACString
  if (NS_SUCCEEDED(aParams->GetCStringValue("format", getter_Copies(format))))
    mimeType.Assign(format);
  
  PRBool selectionOnly = PR_FALSE;
  aParams->GetBooleanValue("selection_only", &selectionOnly);
  
  nsAutoString contents;
  nsresult rv = aEdit->GetContents(mimeType.get(), selectionOnly, contents);
  if (NS_FAILED(rv))
    return rv;
    
  return aParams->SetStringValue("result", contents);
}

NS_IMETHODIMP DocumentViewerImpl::GetContents(const char *mimeType, PRBool selectionOnly, nsAString& aOutValue)
{
  aOutValue.Truncate();

  NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_INITIALIZED);

  // Now we have the selection.  Make sure it's nonzero:
  nsCOMPtr<nsISelection> sel;
  if (selectionOnly) {
    nsCopySupport::GetSelectionForCopy(mDocument, getter_AddRefs(sel));
    NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
  
    PRBool isCollapsed;
    sel->GetIsCollapsed(&isCollapsed);
    if (isCollapsed)
      return NS_OK;
  }

  // call the copy code
  return nsCopySupport::GetContents(nsDependentCString(mimeType), 0, sel,
                                    mDocument, aOutValue);
}

nsresult
nsCopySupport::GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata)
{
  nsresult rv = NS_OK;
  
  nsCOMPtr<nsIDocumentEncoder> docEncoder;

  nsCAutoString encoderContractID(NS_DOC_ENCODER_CONTRACTID_BASE);
  encoderContractID.Append(aMimeType);
    
  docEncoder = do_CreateInstance(encoderContractID.get());
  NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);

  PRUint32 flags = aFlags | nsIDocumentEncoder::SkipInvisibleContent;
  
  if (aMimeType.Equals("text/plain"))
    flags |= nsIDocumentEncoder::OutputPreformatted;

  NS_ConvertASCIItoUTF16 unicodeMimeType(aMimeType);

  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
  NS_ASSERTION(domDoc, "Need a document");

  rv = docEncoder->Init(domDoc, unicodeMimeType, flags);
  if (NS_FAILED(rv)) return rv;
  
  if (aSel)
  {
    rv = docEncoder->SetSelection(aSel);
    if (NS_FAILED(rv)) return rv;
  } 
  
  // encode the selection
  return docEncoder->EncodeToString(outdata);
}

NS_IMETHODIMP
nsDocumentEncoder::EncodeToString(nsAString& aOutputString)
{
  if (!mDocument)
    return NS_ERROR_NOT_INITIALIZED;

  aOutputString.Truncate();

  nsString output;
  static const size_t bufferSize = 2048;
  if (!mCachedBuffer) {
    mCachedBuffer = nsStringBuffer::Alloc(bufferSize);
  }
  NS_ASSERTION(!mCachedBuffer->IsReadonly(),
               "DocumentEncoder shouldn't keep reference to non-readonly buffer!");
  static_cast<PRUnichar*>(mCachedBuffer->Data())[0] = PRUnichar(0);
  mCachedBuffer->ToString(0, output, PR_TRUE);
  // output owns the buffer now!
  mCachedBuffer = nsnull;
  

  if (!mSerializer) {
    nsCAutoString progId(NS_CONTENTSERIALIZER_CONTRACTID_PREFIX);
    AppendUTF16toUTF8(mMimeType, progId);

    mSerializer = do_CreateInstance(progId.get());
    NS_ENSURE_TRUE(mSerializer, NS_ERROR_NOT_IMPLEMENTED);
  }

  nsresult rv = NS_OK;

  nsCOMPtr<nsIAtom> charsetAtom;
  if (!mCharset.IsEmpty()) {
    if (!mCharsetConverterManager) {
      mCharsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }
  
  PRBool rewriteEncodingDeclaration = !(mSelection || mRange || mNode) && !(mFlags & OutputDontRewriteEncodingDeclaration);
  mSerializer->Init(mFlags, mWrapColumn, mCharset.get(), mIsCopying, rewriteEncodingDeclaration);

  if (mSelection) {
    nsCOMPtr<nsIDOMRange> range;
    PRInt32 i, count = 0;

    rv = mSelection->GetRangeCount(&count);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIDOMNode> node, prevNode;
    for (i = 0; i < count; i++) {
      mSelection->GetRangeAt(i, getter_AddRefs(range));

      // Bug 236546: newlines not added when copying table cells into clipboard
      // Each selected cell shows up as a range containing a row with a single cell
      // get the row, compare it to previous row and emit </tr><tr> as needed
      range->GetStartContainer(getter_AddRefs(node));
      NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
      if (node != prevNode) {
        if (prevNode) {
          nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
          rv = SerializeNodeEnd(p, output);
          NS_ENSURE_SUCCESS(rv, rv);
          prevNode = nsnull;
        }
        nsCOMPtr<nsIContent> content = do_QueryInterface(node);
        if (content && content->Tag() == nsGkAtoms::tr) {
          nsCOMPtr<nsINode> n = do_QueryInterface(node);
          rv = SerializeNodeStart(n, 0, -1, output);
          NS_ENSURE_SUCCESS(rv, rv);
          prevNode = node;
        }
      }

      nsCOMPtr<nsIRange> r = do_QueryInterface(range);
      rv = SerializeRangeToString(r, output);
      NS_ENSURE_SUCCESS(rv, rv);
    }
    if (prevNode) {
      nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
      rv = SerializeNodeEnd(p, output);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    mSelection = nsnull;
  } else if (mRange) {
      rv = SerializeRangeToString(mRange, output);

      mRange = nsnull;
  } else if (mNode) {
    rv = SerializeToStringRecursive(mNode, output, mNodeIsContainer);
    mNode = nsnull;
  } else {
    rv = mSerializer->AppendDocumentStart(mDocument, output);

    if (NS_SUCCEEDED(rv)) {
      rv = SerializeToStringRecursive(mDocument, output, PR_FALSE);
    }
  }

  NS_ENSURE_SUCCESS(rv, rv);
  rv = mSerializer->Flush(output);
 
  if (NS_SUCCEEDED(rv)) {
    aOutputString.Append(output.get(), output.Length());
  }
  mCachedBuffer = nsStringBuffer::FromString(output);
  // Try to cache the buffer.
  if (mCachedBuffer && mCachedBuffer->StorageSize() == bufferSize &&
      !mCachedBuffer->IsReadonly()) {
    mCachedBuffer->AddRef();
  } else {
    mCachedBuffer = nsnull;
  }

  return rv;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值