Back to index

lightning-sunbird  0.9+nobinonly
Static Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes
nsTransferableFactory Class Reference
Collaboration diagram for nsTransferableFactory:
Collaboration graph
[legend]

List of all members.

Static Public Member Functions

static nsresult CreateFromEvent (nsIDOMEvent *inMouseEvent, nsIFlavorDataProvider *inFlavorDataProvider, nsITransferable **outTrans)

Protected Member Functions

 nsTransferableFactory (nsIDOMEvent *inMouseEvent, nsIFlavorDataProvider *inFlavorDataProvider)
nsresult Produce (nsITransferable **outTrans)

Private Types

enum  serializationMode { serializeAsText, serializeAsHTML }

Private Member Functions

nsresult ConvertStringsToTransferable (nsITransferable **outTrans)

Static Private Member Functions

static nsresult GetDraggableSelectionData (nsISelection *inSelection, nsIDOMNode *inRealTargetNode, nsIDOMNode **outImageOrLinkNode, PRBool *outDragSelectedText)
static already_AddRefed
< nsIDOMNode
FindParentLinkNode (nsIDOMNode *inNode)
static void GetAnchorURL (nsIDOMNode *inNode, nsAString &outURL)
static void GetNodeString (nsIDOMNode *inNode, nsAString &outNodeString)
static void CreateLinkText (const nsAString &inURL, const nsAString &inText, nsAString &outLinkText)
static void GetSelectedLink (nsISelection *inSelection, nsIDOMNode **outLinkNode)
static nsresult SerializeNodeOrSelection (serializationMode inMode, PRUint32 inFlags, nsIDOMWindow *inWindow, nsIDOMNode *inNode, nsAString &outResultString, nsAString &outHTMLContext, nsAString &outHTMLInfo)

Private Attributes

PRBool mInstanceAlreadyUsed
nsCOMPtr< nsIDOMEventmMouseEvent
nsCOMPtr< nsIFlavorDataProvidermFlavorDataProvider
nsString mUrlString
nsString mImageSourceString
nsString mImageDestFileName
nsString mTitleString
nsString mHtmlString
nsString mContextString
nsString mInfoString
PRBool mIsAnchor
nsCOMPtr< nsIImagemImage

Detailed Description

Definition at line 121 of file nsContentAreaDragDrop.cpp.


Member Enumeration Documentation

Enumerator:
serializeAsText 
serializeAsHTML 

Definition at line 147 of file nsContentAreaDragDrop.cpp.


Constructor & Destructor Documentation

nsTransferableFactory::nsTransferableFactory ( nsIDOMEvent inMouseEvent,
nsIFlavorDataProvider inFlavorDataProvider 
) [protected]

Definition at line 946 of file nsContentAreaDragDrop.cpp.

  : mInstanceAlreadyUsed(PR_FALSE),
    mMouseEvent(inMouseEvent),
    mFlavorDataProvider(dataProvider)
{
}

Member Function Documentation

Definition at line 1369 of file nsContentAreaDragDrop.cpp.

{
  // now create the transferable and stuff data into it.
  nsCOMPtr<nsITransferable> trans =
    do_CreateInstance("@mozilla.org/widget/transferable;1");
  NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE);

  // add a special flavor if we're an anchor to indicate that we have
  // a URL in the drag data
  if (!mUrlString.IsEmpty() && mIsAnchor) {
    nsAutoString dragData(mUrlString);
    dragData.AppendLiteral("\n");
    dragData += mTitleString;

    nsCOMPtr<nsISupportsString> urlPrimitive =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(urlPrimitive, NS_ERROR_FAILURE);

    urlPrimitive->SetData(dragData);
    trans->SetTransferData(kURLMime, urlPrimitive,
                           dragData.Length() * sizeof(PRUnichar));

    nsCOMPtr<nsISupportsString> urlDataPrimitive =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(urlDataPrimitive, NS_ERROR_FAILURE);

    urlDataPrimitive->SetData(mUrlString);
    trans->SetTransferData(kURLDataMime, urlDataPrimitive,
                           mUrlString.Length() * sizeof(PRUnichar));

    nsCOMPtr<nsISupportsString> urlDescPrimitive =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(urlDescPrimitive, NS_ERROR_FAILURE);

    urlDescPrimitive->SetData(mTitleString);
    trans->SetTransferData(kURLDescriptionMime, urlDescPrimitive,
                           mTitleString.Length() * sizeof(PRUnichar));
  }

  // add a special flavor, even if we don't have html context data
  nsCOMPtr<nsISupportsString> context =
    do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
  NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);

  nsAutoString contextData(mContextString);
  context->SetData(contextData);
  trans->SetTransferData(kHTMLContext, context, contextData.Length() * 2);

  // add a special flavor if we have html info data
  if (!mInfoString.IsEmpty()) {
    nsCOMPtr<nsISupportsString> info =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(info, NS_ERROR_FAILURE);

    nsAutoString infoData(mInfoString);
    info->SetData(infoData);
    trans->SetTransferData(kHTMLInfo, info, infoData.Length() * 2);
  }

  // add the full html
  nsCOMPtr<nsISupportsString> htmlPrimitive =
    do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
  NS_ENSURE_TRUE(htmlPrimitive, NS_ERROR_FAILURE);

  htmlPrimitive->SetData(mHtmlString);
  trans->SetTransferData(kHTMLMime, htmlPrimitive,
                         mHtmlString.Length() * sizeof(PRUnichar));

  // add the plain (unicode) text. we use the url for text/unicode
  // data if an anchor is being dragged, rather than the title text of
  // the link or the alt text for an anchor image.
  nsCOMPtr<nsISupportsString> textPrimitive =
    do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
  NS_ENSURE_TRUE(textPrimitive, NS_ERROR_FAILURE);

  textPrimitive->SetData(mIsAnchor ? mUrlString : mTitleString);
  trans->SetTransferData(kUnicodeMime, textPrimitive,
                         (mIsAnchor ? mUrlString.Length() :
                          mTitleString.Length()) * sizeof(PRUnichar));

  // add image data, if present. For now, all we're going to do with
  // this is turn it into a native data flavor, so indicate that with
  // a new flavor so as not to confuse anyone who is really registered
  // for image/gif or image/jpg.
  if (mImage) {
    nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive =
      do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID);
    NS_ENSURE_TRUE(ptrPrimitive, NS_ERROR_FAILURE);

    ptrPrimitive->SetData(mImage);
    trans->SetTransferData(kNativeImageMime, ptrPrimitive,
                           sizeof(nsISupportsInterfacePointer*));
    // assume the image comes from a file, and add a file promise. We
    // register ourselves as a nsIFlavorDataProvider, and will use the
    // GetFlavorData callback to save the image to disk.
    trans->SetTransferData(kFilePromiseMime, mFlavorDataProvider,
                           nsITransferable::kFlavorHasDataProvider);

    nsCOMPtr<nsISupportsString> imageUrlPrimitive =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(imageUrlPrimitive, NS_ERROR_FAILURE);

    imageUrlPrimitive->SetData(mImageSourceString);
    trans->SetTransferData(kFilePromiseURLMime, imageUrlPrimitive,
                           mImageSourceString.Length() * sizeof(PRUnichar));

    nsCOMPtr<nsISupportsString> imageFileNamePrimitive =
      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
    NS_ENSURE_TRUE(imageFileNamePrimitive, NS_ERROR_FAILURE);

    imageFileNamePrimitive->SetData(mImageDestFileName);
    trans->SetTransferData(kFilePromiseDestFilename, imageFileNamePrimitive,
                           mImageDestFileName.Length() * sizeof(PRUnichar));

    // if not an anchor, add the image url
    if (!mIsAnchor) {
      nsCOMPtr<nsISupportsString> urlDataPrimitive =
        do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
      NS_ENSURE_TRUE(urlDataPrimitive, NS_ERROR_FAILURE);

      urlDataPrimitive->SetData(mUrlString);
      trans->SetTransferData(kURLDataMime, urlDataPrimitive,
                             mUrlString.Length() * sizeof(PRUnichar));
    }
  }

  *outTrans = trans;
  NS_IF_ADDREF(*outTrans);

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTransferableFactory::CreateFromEvent ( nsIDOMEvent inMouseEvent,
nsIFlavorDataProvider inFlavorDataProvider,
nsITransferable **  outTrans 
) [static]

Definition at line 938 of file nsContentAreaDragDrop.cpp.

{
  nsTransferableFactory factory(inMouseEvent, dataProvider);
  return factory.Produce(outTrans);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTransferableFactory::CreateLinkText ( const nsAString &  inURL,
const nsAString &  inText,
nsAString &  outLinkText 
) [static, private]

Definition at line 1017 of file nsContentAreaDragDrop.cpp.

{
  // use a temp var in case |inText| is the same string as
  // |outLinkText| to avoid overwriting it while building up the
  // string in pieces.
  nsAutoString linkText(NS_LITERAL_STRING("<a href=\"") +
                        inURL +
                        NS_LITERAL_STRING("\">") +
                        inText +
                        NS_LITERAL_STRING("</a>") );

  outLinkText = linkText;
}

Here is the caller graph for this function:

Definition at line 963 of file nsContentAreaDragDrop.cpp.

{
  nsCOMPtr<nsIContent> content(do_QueryInterface(inNode));
  if (!content) {
    // That must have been the document node; nothing else to do here;
    return nsnull;
  }

  for (; content; content = content->GetParent()) {
    if (nsContentUtils::IsDraggableLink(content)) {
      nsIDOMNode* node = nsnull;
      CallQueryInterface(content, &node);
      return node;
    }
  }

  return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTransferableFactory::GetAnchorURL ( nsIDOMNode inNode,
nsAString &  outURL 
) [static, private]

Definition at line 990 of file nsContentAreaDragDrop.cpp.

{
  outURL.Truncate();
  nsCOMPtr<nsIContent> content(do_QueryInterface(inNode));
  if (!content) {
    // Not a link
    return;
  }

  nsCOMPtr<nsIURI> linkURI = nsContentUtils::GetLinkURI(content);
  if (!linkURI) {
    return;
  }

  nsCAutoString spec;
  linkURI->GetSpec(spec);
  CopyUTF8toUTF16(spec, outURL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTransferableFactory::GetDraggableSelectionData ( nsISelection inSelection,
nsIDOMNode inRealTargetNode,
nsIDOMNode **  outImageOrLinkNode,
PRBool outDragSelectedText 
) [static, private]

Definition at line 1504 of file nsContentAreaDragDrop.cpp.

{
  NS_ENSURE_ARG(inSelection);
  NS_ENSURE_ARG(inRealTargetNode);
  NS_ENSURE_ARG_POINTER(outImageOrLinkNode);

  *outImageOrLinkNode = nsnull;
  *outDragSelectedText = PR_FALSE;

  PRBool selectionContainsTarget = PR_FALSE;

  PRBool isCollapsed = PR_FALSE;
  inSelection->GetIsCollapsed(&isCollapsed);
  if (!isCollapsed) {
    inSelection->ContainsNode(inRealTargetNode, PR_FALSE,
                              &selectionContainsTarget);

    if (selectionContainsTarget) {
      // track down the anchor node, if any, for the url
      nsCOMPtr<nsIDOMNode> selectionStart;
      inSelection->GetAnchorNode(getter_AddRefs(selectionStart));

      nsCOMPtr<nsIDOMNode> selectionEnd;
      inSelection->GetFocusNode(getter_AddRefs(selectionEnd));

      // look for a selection around a single node, like an image.
      // in this case, drag the image, rather than a serialization of the HTML
      // XXX generalize this to other draggable element types?
      if (selectionStart == selectionEnd) {
        PRBool hasChildren;
        selectionStart->HasChildNodes(&hasChildren);
        if (hasChildren) {
          // see if just one node is selected
          PRInt32 anchorOffset, focusOffset;
          inSelection->GetAnchorOffset(&anchorOffset);
          inSelection->GetFocusOffset(&focusOffset);
          if (abs(anchorOffset - focusOffset) == 1) {
            nsCOMPtr<nsIContent> selStartContent =
              do_QueryInterface(selectionStart);

            if (selStartContent) {
              PRInt32 childOffset =
                (anchorOffset < focusOffset) ? anchorOffset : focusOffset;
              nsIContent *childContent =
                selStartContent->GetChildAt(childOffset);
              // if we find an image, we'll fall into the node-dragging code,
              // rather the the selection-dragging code
              if (nsContentUtils::IsDraggableImage(childContent)) {
                CallQueryInterface(childContent, outImageOrLinkNode);

                return NS_OK;
              }
            }
          }
        }
      }

      // see if the selection is a link;  if so, its node will be returned
      GetSelectedLink(inSelection, outImageOrLinkNode);

      // indicate that a link or text is selected
      *outDragSelectedText = PR_TRUE;
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTransferableFactory::GetNodeString ( nsIDOMNode inNode,
nsAString &  outNodeString 
) [static, private]

Definition at line 1040 of file nsContentAreaDragDrop.cpp.

{
  outNodeString.Truncate();

  // use a range to get the text-equivalent of the node
  nsCOMPtr<nsIDOMDocument> doc;
  inNode->GetOwnerDocument(getter_AddRefs(doc));
  nsCOMPtr<nsIDOMDocumentRange> docRange(do_QueryInterface(doc));
  if (docRange) {
    nsCOMPtr<nsIDOMRange> range;
    docRange->CreateRange(getter_AddRefs(range));
    if (range) {
      range->SelectNode(inNode);
      range->ToString(outNodeString);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTransferableFactory::GetSelectedLink ( nsISelection inSelection,
nsIDOMNode **  outLinkNode 
) [static, private]

Definition at line 1576 of file nsContentAreaDragDrop.cpp.

{
  *outLinkNode = nsnull;

  nsCOMPtr<nsIDOMNode> selectionStart;
  inSelection->GetAnchorNode(getter_AddRefs(selectionStart));
  nsCOMPtr<nsIDOMNode> selectionEnd;
  inSelection->GetFocusNode(getter_AddRefs(selectionEnd));

  // simple case:  only one node is selected
  // see if it or its parent is an anchor, then exit

  if (selectionStart == selectionEnd) {
    nsCOMPtr<nsIDOMNode> link = FindParentLinkNode(selectionStart);
    if (link) {
      link.swap(*outLinkNode);
    }

    return;
  }

  // more complicated case:  multiple nodes are selected

  // Unless you use the Alt key while selecting anchor text, it is
  // nearly impossible to avoid overlapping into adjacent nodes.
  // Deal with this by trimming off the leading and/or trailing
  // nodes of the selection if the strings they produce are empty.

  // first, use a range determine if the selection was marked LTR or RTL;
  // if the latter, swap endpoints so we trim in the right direction

  PRInt32 startOffset, endOffset;
  {
    nsCOMPtr<nsIDOMRange> range;
    inSelection->GetRangeAt(0, getter_AddRefs(range));
    if (!range) {
      return;
    }

    nsCOMPtr<nsIDOMNode> tempNode;
    range->GetStartContainer( getter_AddRefs(tempNode));
    if (tempNode != selectionStart) {
      selectionEnd = selectionStart;
      selectionStart = tempNode;
      inSelection->GetAnchorOffset(&endOffset);
      inSelection->GetFocusOffset(&startOffset);
    } else {
      inSelection->GetAnchorOffset(&startOffset);
      inSelection->GetFocusOffset(&endOffset);
    }
  }

  // trim leading node if the string is empty or
  // the selection starts at the end of the text

  nsAutoString nodeStr;
  selectionStart->GetNodeValue(nodeStr);
  if (nodeStr.IsEmpty() ||
      startOffset+1 >= NS_STATIC_CAST(PRInt32, nodeStr.Length())) {
    nsCOMPtr<nsIDOMNode> curr = selectionStart;
    nsIDOMNode* next;

    while (curr) {
      curr->GetNextSibling(&next);

      if (next) {
        selectionStart = dont_AddRef(next);
        break;
      }

      curr->GetParentNode(&next);
      curr = dont_AddRef(next);
    }
  }

  // trim trailing node if the selection ends before its text begins

  if (endOffset == 0) {
    nsCOMPtr<nsIDOMNode> curr = selectionEnd;
    nsIDOMNode* next;

    while (curr) {
      curr->GetPreviousSibling(&next);

      if (next){
        selectionEnd = dont_AddRef(next);
        break;
      }

      curr->GetParentNode(&next);
      curr = dont_AddRef(next);
    }
  }

  // see if the leading & trailing nodes are part of the
  // same anchor - if so, return the anchor node
  nsCOMPtr<nsIDOMNode> link = FindParentLinkNode(selectionStart);
  if (link) {
    nsCOMPtr<nsIDOMNode> link2 = FindParentLinkNode(selectionEnd);

    if (link == link2) {
      NS_IF_ADDREF(*outLinkNode = link);
    }
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1061 of file nsContentAreaDragDrop.cpp.

{
  if (mInstanceAlreadyUsed) {
    return NS_ERROR_FAILURE;
  }

  if (!outTrans || !mMouseEvent || !mFlavorDataProvider) {
    return NS_ERROR_FAILURE;
  }

  mInstanceAlreadyUsed = PR_TRUE;
  *outTrans = nsnull;

  nsCOMPtr<nsIDOMWindow> window;
  PRBool isAltKeyDown = PR_FALSE;
  mIsAnchor = PR_FALSE;

  {
    nsCOMPtr<nsIDOMUIEvent> uiEvent(do_QueryInterface(mMouseEvent));
    if (!uiEvent) {
      return NS_OK;
    }

    // find the selection to see what we could be dragging and if
    // what we're dragging is in what is selected.
    nsCOMPtr<nsIDOMAbstractView> view;
    uiEvent->GetView(getter_AddRefs(view));
    window = do_QueryInterface(view);
    if (!window) {
      return NS_OK;
    }
  }

  {
    nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(mMouseEvent));
    if (mouseEvent) {
      mouseEvent->GetAltKey(&isAltKeyDown);
    }
  }

  nsCOMPtr<nsISelection> selection;
  window->GetSelection(getter_AddRefs(selection));
  if (!selection) {
    return NS_OK;
  }

  // if set, serialize the content under this node
  nsCOMPtr<nsIDOMNode> nodeToSerialize;
  PRBool useSelectedText = PR_FALSE;

  {
    PRBool haveSelectedContent = PR_FALSE;

    // possible parent link node
    nsCOMPtr<nsIDOMNode> parentLink;
    nsCOMPtr<nsIDOMNode> draggedNode;

    {
      nsCOMPtr<nsIDOMEventTarget> target;
      mMouseEvent->GetTarget(getter_AddRefs(target));

      // only drag form elements by using the alt key,
      // otherwise buttons and select widgets are hard to use

      // Note that while <object> elements implement nsIFormControl, we should
      // really allow dragging them if they happen to be images.
      nsCOMPtr<nsIFormControl> form(do_QueryInterface(target));
      if (form && !isAltKeyDown && form->GetType() != NS_FORM_OBJECT) {
        return NS_OK;
      }

      draggedNode = do_QueryInterface(target);
    }

    nsCOMPtr<nsIDOMHTMLAreaElement>   area;   // client-side image map
    nsCOMPtr<nsIImageLoadingContent>  image;
    nsCOMPtr<nsIDOMHTMLAnchorElement> link;

    {
      // Get the real target and see if it is in the selection
      nsCOMPtr<nsIDOMNode> realTargetNode;

      {
        nsCOMPtr<nsIDOMNSEvent> internalEvent = do_QueryInterface(mMouseEvent);
        if (internalEvent) {
          nsCOMPtr<nsIDOMEventTarget> realTarget;
          internalEvent->GetExplicitOriginalTarget(getter_AddRefs(realTarget));
          realTargetNode = do_QueryInterface(realTarget);
        }
      }

      {
        nsCOMPtr<nsIDOMNode> selectedImageOrLinkNode;
        GetDraggableSelectionData(selection, realTargetNode,
                                  getter_AddRefs(selectedImageOrLinkNode),
                                  &haveSelectedContent);

        // either plain text or anchor text is selected
        if (haveSelectedContent) {
          link = do_QueryInterface(selectedImageOrLinkNode);
          if (link && isAltKeyDown) {
            return NS_OK;
          }

          useSelectedText = PR_TRUE;
        } else if (selectedImageOrLinkNode) {
          // an image is selected
          image = do_QueryInterface(selectedImageOrLinkNode);
        } else {
          // nothing is selected -
          //
          // look for draggable elements under the mouse
          //
          // if the alt key is down, don't start a drag if we're in an
          // anchor because we want to do selection.
          parentLink = FindParentLinkNode(draggedNode);
          if (parentLink && isAltKeyDown) {
            return NS_OK;
          }

          area  = do_QueryInterface(draggedNode);
          image = do_QueryInterface(draggedNode);
          link  = do_QueryInterface(draggedNode);
        }
      }
    }

    {
      // set for linked images, and links
      nsCOMPtr<nsIDOMNode> linkNode;

      if (area) {
        // use the alt text (or, if missing, the href) as the title
        area->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
        if (mTitleString.IsEmpty()) {
          // this can be a relative link
          area->GetAttribute(NS_LITERAL_STRING("href"), mTitleString);
        }

        // we'll generate HTML like <a href="absurl">alt text</a>
        mIsAnchor = PR_TRUE;

        // gives an absolute link
        GetAnchorURL(area, mUrlString);

        mHtmlString.AssignLiteral("<a href=\"");
        mHtmlString.Append(mUrlString);
        mHtmlString.AppendLiteral("\">");
        mHtmlString.Append(mTitleString);
        mHtmlString.AppendLiteral("</a>");
      } else if (image) {
        mIsAnchor = PR_TRUE;
        // grab the href as the url, use alt text as the title of the
        // area if it's there.  the drag data is the image tag and src
        // attribute.
        nsCOMPtr<nsIURI> imageURI;
        image->GetCurrentURI(getter_AddRefs(imageURI));
        if (imageURI) {
          nsCAutoString spec;
          imageURI->GetSpec(spec);
          CopyUTF8toUTF16(spec, mUrlString);
        }

        nsCOMPtr<nsIDOMElement> imageElement(do_QueryInterface(image));
        // XXXbz Shouldn't we use the "title" attr for title?  Using
        // "alt" seems very wrong....
        if (imageElement) {
          imageElement->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
        }

        if (mTitleString.IsEmpty()) {
          mTitleString = mUrlString;
        }

        nsCOMPtr<imgIRequest> imgRequest;

        // grab the image data, and its request.
        nsCOMPtr<nsIImage> img =
          nsContentUtils::GetImageFromContent(image,
                                              getter_AddRefs(imgRequest));

        nsCOMPtr<nsIMIMEService> mimeService =
          do_GetService("@mozilla.org/mime;1");

        // Fix the file extension in the URL if necessary
        if (imgRequest && mimeService) {
          nsCOMPtr<nsIURI> imgUri;
          imgRequest->GetURI(getter_AddRefs(imgUri));

          nsCOMPtr<nsIURL> imgUrl(do_QueryInterface(imgUri));

          if (imgUrl) {
            nsCAutoString extension;
            imgUrl->GetFileExtension(extension);

            nsXPIDLCString mimeType;
            imgRequest->GetMimeType(getter_Copies(mimeType));

            nsCOMPtr<nsIMIMEInfo> mimeInfo;
            mimeService->GetFromTypeAndExtension(mimeType, EmptyCString(),
                                                 getter_AddRefs(mimeInfo));

            if (mimeInfo) {
              nsCAutoString spec;
              imgUrl->GetSpec(spec);

              // pass out the image source string
              CopyUTF8toUTF16(spec, mImageSourceString);

              PRBool validExtension;
              if (NS_FAILED(mimeInfo->ExtensionExists(extension,
                                                      &validExtension)) ||
                  !validExtension) {
                // Fix the file extension in the URL
                nsresult rv = imgUrl->Clone(getter_AddRefs(imgUri));
                NS_ENSURE_SUCCESS(rv, rv);

                imgUrl = do_QueryInterface(imgUri);

                nsCAutoString primaryExtension;
                mimeInfo->GetPrimaryExtension(primaryExtension);

                imgUrl->SetFileExtension(primaryExtension);
              }

              nsCAutoString fileName;
              imgUrl->GetFileName(fileName);

              NS_UnescapeURL(fileName);

              // make the filename safe for the filesystem
              fileName.ReplaceChar(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS,
                                   '-');

              CopyUTF8toUTF16(fileName, mImageDestFileName);

              // and the image object
              mImage = img;
            }
          }
        }

        if (parentLink) {
          // If we are dragging around an image in an anchor, then we
          // are dragging the entire anchor
          linkNode = parentLink;
          nodeToSerialize = linkNode;
        } else {
          nodeToSerialize = draggedNode;
        }
      } else if (link) {
        // set linkNode. The code below will handle this
        linkNode = link;    // XXX test this
        GetNodeString(draggedNode, mTitleString);
      } else if (parentLink) {
        // parentLink will always be null if there's selected content
        linkNode = parentLink;
        nodeToSerialize = linkNode;
      } else if (!haveSelectedContent) {
        // nothing draggable
        return NS_OK;
      }

      if (linkNode) {
        mIsAnchor = PR_TRUE;
        GetAnchorURL(linkNode, mUrlString);
      }
    }
  }

  if (nodeToSerialize || useSelectedText) {
    // if we have selected text, use it in preference to the node
    if (useSelectedText) {
      nodeToSerialize = nsnull;
    }

    SerializeNodeOrSelection(serializeAsHTML,
                             nsIDocumentEncoder::OutputAbsoluteLinks |
                             nsIDocumentEncoder::OutputEncodeW3CEntities,
                             window, nodeToSerialize,
                             mHtmlString, mContextString, mInfoString);

    nsAutoString dummy1, dummy2;
    SerializeNodeOrSelection(serializeAsText, 0,
                             window, nodeToSerialize,
                             mTitleString, dummy1, dummy2);

#ifdef CHANGE_SELECTION_ON_DRAG
    // We used to change the selection to wrap the dragged node (mainly
    // to work around now-fixed issues with dragging unselected elements).
    // There is no reason to do this any more.
    NormalizeSelection(selectionNormalizeNode, selection);
#endif
  }

  // default text value is the URL
  if (mTitleString.IsEmpty()) {
    mTitleString = mUrlString;
  }

  // if we haven't constructed a html version, make one now
  if (mHtmlString.IsEmpty() && !mUrlString.IsEmpty())
    CreateLinkText(mUrlString, mTitleString, mHtmlString);

  return ConvertStringsToTransferable(outTrans);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTransferableFactory::SerializeNodeOrSelection ( serializationMode  inMode,
PRUint32  inFlags,
nsIDOMWindow inWindow,
nsIDOMNode inNode,
nsAString &  outResultString,
nsAString &  outHTMLContext,
nsAString &  outHTMLInfo 
) [static, private]

Definition at line 1687 of file nsContentAreaDragDrop.cpp.

{
  NS_ENSURE_ARG_POINTER(inWindow);

  nsresult rv;
  nsCOMPtr<nsIDocumentEncoder> encoder;
  static const char *textplain = "text/plain";

  if (inMode == serializeAsText) {
    nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
    formatType.Append(textplain);
    encoder = do_CreateInstance(formatType.get(), &rv);
  } else {
    encoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID, &rv);
  }
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIDOMDocument> domDoc;
  inWindow->GetDocument(getter_AddRefs(domDoc));
  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);

  nsCOMPtr<nsIDOMRange> range;
  nsCOMPtr<nsISelection> selection;
  if (inNode) {
    // make a range around this node
    rv = NS_NewRange(getter_AddRefs(range));
    NS_ENSURE_SUCCESS(rv, rv);
    rv = range->SelectNode(inNode);
    NS_ENSURE_SUCCESS(rv, rv);
  } else {
    inWindow->GetSelection(getter_AddRefs(selection));
    inFlags |= nsIDocumentEncoder::OutputSelectionOnly;
  }

  if (inMode == serializeAsText) {
    rv = encoder->Init(doc, NS_ConvertASCIItoUCS2(textplain), inFlags);
  } else {
    rv = encoder->Init(doc, NS_LITERAL_STRING(kHTMLMime), inFlags);
  }
  NS_ENSURE_SUCCESS(rv, rv);

  if (range) {
    encoder->SetRange(range);
  } else if (selection) {
    encoder->SetSelection(selection);
  }

  if (inMode == serializeAsText) {
    outContext.Truncate();
    outInfo.Truncate();
    return encoder->EncodeToString(outResultString);
  }

  return encoder->EncodeToStringWithContext(outResultString, outContext,
                                            outInfo);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 168 of file nsContentAreaDragDrop.cpp.

Definition at line 160 of file nsContentAreaDragDrop.cpp.

Definition at line 167 of file nsContentAreaDragDrop.cpp.

Definition at line 172 of file nsContentAreaDragDrop.cpp.

Definition at line 164 of file nsContentAreaDragDrop.cpp.

Definition at line 163 of file nsContentAreaDragDrop.cpp.

Definition at line 169 of file nsContentAreaDragDrop.cpp.

Definition at line 157 of file nsContentAreaDragDrop.cpp.

Definition at line 171 of file nsContentAreaDragDrop.cpp.

Definition at line 159 of file nsContentAreaDragDrop.cpp.

Definition at line 165 of file nsContentAreaDragDrop.cpp.

Definition at line 162 of file nsContentAreaDragDrop.cpp.


The documentation for this class was generated from the following file: