Example #1
0
daeInt DAE::saveAs(daeString name, daeString documentName, daeBool replace)
{
	if (!database)
		setDatabase(NULL);

	if (!plugin)
		setIOPlugin(NULL);

	if (registerFunc) 
		registerFunc();
	
	if ( !plugin || !database ) {
		return DAE_ERR_BACKEND_IO;
	}

	plugin->setDatabase(database);
	
	// Find the document we want by name
	daeDocument* document = database->getDocument(documentName);
	if(document == NULL)
		return DAE_ERR_COLLECTION_DOES_NOT_EXIST;

	// Make a URI from "name" and save to that

	daeURI tempURI(name, true);
	return plugin->write(&tempURI, document, replace);
	
}
Example #2
0
daeInt DAE::saveAs(daeString name, daeUInt documentIndex, daeBool replace)
{
	if (!database)
		setDatabase(NULL);

	if (!plugin)
		setIOPlugin(NULL);

	if (registerFunc) 
		registerFunc();
	
	if ( !plugin || !database ) {
		return DAE_ERR_BACKEND_IO;
	}

	plugin->setDatabase(database);
	
	if(documentIndex >= database->getDocumentCount())
		return DAE_ERR_COLLECTION_DOES_NOT_EXIST;

	daeDocument *document = database->getDocument(documentIndex);
	
	daeURI tempURI(name);
	return plugin->write(&tempURI, document, replace);
}
Example #3
0
// batch file operations
daeInt DAE::load(daeString name, daeString docBuffer)
{
	if (!database)
		setDatabase(NULL);

	if (!plugin)
		setIOPlugin(NULL);
	
	if (registerFunc) 
		registerFunc();

	if ( !plugin || !database ) {
		//printf( "no plugin or database\n" );
		daeErrorHandler::get()->handleError("no plugin or database\n");
		return DAE_ERR_BACKEND_IO;
	}

	plugin->setDatabase(database);

	if (!name || name[0] == '\0')
		return DAE_ERR_INVALID_CALL;

	daeURI tempURI(name);
	
	return plugin->read(tempURI, docBuffer);
}
void daeDocument::addExternalReference( daeURI &uri ) {
    if ( uri.getContainer() == NULL || uri.getContainer()->getDocument() != this ) {
        return;
    }
    daeURI tempURI( *dae, uri.getURI(), true );  // Remove fragment
    referencedDocuments.appendUnique( tempURI.getURI() );
}
Example #5
0
daeDocument* daeSTLDatabase::getDocument(daeString name)
{
	// Normalize the input string to an absolute URI with no fragment

	daeURI tempURI(name, true);
	daeString targetURI = tempURI.getURI();

	// Try to find a document that matches

	daeDocument *document;
	int documentCount	= getDocumentCount();
	for (int i=0;i<documentCount;i++)
	{
		document = getDocument(i);
		if(strcmp(document->getDocumentURI()->getURI(), targetURI)==0)
			return(document);
	}
	return(NULL);
}
Example #6
0
daeInt daeSTLDatabase::getElement(daeElement** pElement,daeInt index,daeString name,daeString type,daeString file)
{	
	// this sorts the vector if necessary
	validate(); 
	
	// If the index is out of range, there can be no match
	if ( index < 0 ) 
	{
		return DAE_ERR_QUERY_NO_MATCH;
	}

	// If no name, type or file was specified we return the element at "index" - SLOW
	if ( !name && !type && !file ) 
	{
		daeUInt count = 0;
		std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.begin();
		std::map< std::string, std::vector< daeElement*> >::iterator end = elements.end();
		while( iter != end )
		{
			count += (daeUInt)(*iter).second.size();
			if ( (daeInt)count > index )
			{
				*pElement = (*iter).second[index - (count - (*iter).second.size())] ;
				return DAE_OK;
			}
			++iter;
		}
		return DAE_ERR_QUERY_NO_MATCH;
	}
	
	if ( name ) 
	{ 
		//name specified
		int count = 0;
		if ( file ) 
		{ 
			// If a document URI was a search key (in file) resolve it to a text URI with no fragment
			daeURI tempURI(file,true);
			daeDocument *col = getDocument( tempURI.getURI() );
			if ( col == NULL ) {
				*pElement = NULL;
				return DAE_ERR_QUERY_NO_MATCH;
			}
			//a document was specified
			std::pair< std::multimap< std::string, daeElement* >::iterator, std::multimap< std::string, daeElement* >::iterator> range;
			range = elementsIDMap.equal_range( std::string( name ) );
			std::multimap< std::string, daeElement* >::iterator i = range.first;
			while ( i != range.second )
			{
				if ( col == (*i).second->getDocument() )
				{
					if ( count == index )
					{
						*pElement = (*i).second;
						return DAE_OK;
					}
					count++;
				}
				++i;
			}
			*pElement = NULL;
			return DAE_ERR_QUERY_NO_MATCH;
		}
		else 
		{ 
			//no document specified
			std::multimap< std::string, daeElement* >::iterator i = elementsIDMap.find( std::string( name ) );
			if ( index > (daeInt)elementsIDMap.count( std::string( name ) ) || i == elementsIDMap.end() )
			{
				*pElement = NULL;
				return DAE_ERR_QUERY_NO_MATCH;
			}
			for ( int x = 0; x < index; x++ )
			{
				++i;
			}
			*pElement = i->second;
			return DAE_OK;
		}
	}
	
	if ( type ) 
	{ 
		std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.find( std::string( type ) );
		if ( iter == elements.end() )
		{
			*pElement = NULL;
			return DAE_ERR_QUERY_NO_MATCH;
		}
		//type specified
		int count = 0;
		if ( file ) 
		{ 
			// If a document URI was a search key (in file) resolve it to a text URI with no fragment
			daeURI tempURI(file,true);
			daeDocument *col = getDocument( tempURI.getURI() );
			if ( col == NULL ) {
				return DAE_ERR_QUERY_NO_MATCH;
			}
			//a document was specified
			// a document was specified
			std::vector< daeElement* > &vec = (*iter).second;
			std::vector< daeElement* >::iterator i = vec.begin();
			std::vector< daeElement* >::iterator end = vec.end();
			while( i != end )
			{
				if ( col == (*i)->getDocument() )
				{
					if ( count == index )
					{
						*pElement = (*i);
						return DAE_OK;
					}
					++count;
				}
				++i;
			}
			return DAE_ERR_QUERY_NO_MATCH;
		}
		else 
		{ 
			//no document specified
			if ( index >= (daeInt)(*iter).second.size() )
			{
				*pElement = NULL;
				return DAE_ERR_QUERY_NO_MATCH;
			}
			*pElement = (*iter).second[index];
			return DAE_OK;
		}
	}

	//if you get here only the file was specified - SLOW
	daeURI tempURI(file,true);
	daeDocument *col = getDocument( tempURI.getURI() );
	if ( col == NULL ) {
		return DAE_ERR_QUERY_NO_MATCH;
	}
	//a document was specified
	int count = 0;
	std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.begin();
	std::map< std::string, std::vector< daeElement*> >::iterator end = elements.end();
	while( iter != end )
	{
		std::vector< daeElement* > &vec = (*iter).second;
		std::vector< daeElement* >::iterator i = vec.begin();
		std::vector< daeElement* >::iterator end2 = vec.end();
		while( i != end2 )
		{
			if( col == (*i)->getDocument() ) 
			{
				if( count == index ) 
				{
					*pElement = (*i);
					return DAE_OK;
				}
				++count;
			}
			++i;
		}
		++iter;
	}
	return DAE_ERR_QUERY_NO_MATCH;

}
Example #7
0
daeUInt daeSTLDatabase::getElementCount(daeString name,daeString type,daeString file)
{	
	validate(); 
	
	// If none of the search keys was specified, return the total element count in the database
	if ( !name && !type && !file ) 
	{
		daeUInt count = 0;
		std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.begin();
		std::map< std::string, std::vector< daeElement*> >::iterator end = elements.end();
		while( iter != end )
		{
			count += (daeUInt)(*iter).second.size();
			++iter;
		}
		return count;
	}

	if ( name ) 
	{ 
		// name specified
		int count = 0;
		if ( file ) 
		{ 
			// If a document URI was a search key (in file) resolve it to a text URI with no fragment
			daeURI tempURI(file,true);
			daeDocument *col = getDocument( tempURI.getURI() );
			if ( col == NULL ) {
				return 0;
			}
			// a document was specified
			std::pair< std::multimap< std::string, daeElement* >::iterator, std::multimap< std::string, daeElement* >::iterator > range;
			range = elementsIDMap.equal_range( std::string( name ) );
			std::multimap< std::string, daeElement* >::iterator i = range.first;
			while ( i != range.second )
			{
				if ( col == (*i).second->getDocument() )
				{
					count++;
				}
				++i;
			}
			return count;
		}
		else 
		{ 
			//no file specified - just name
			return (daeUInt)elementsIDMap.count( std::string( name ) );
		}
	}

	if ( type ) 
	{ 
		// type specified
		std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.find( std::string( type ) );
		if ( iter == elements.end() )
		{
			return 0;
		}

		int count = 0;
		if ( file ) 
		{ 
			// If a document URI was a search key (in file) resolve it to a text URI with no fragment
			daeURI tempURI(file,true);
			daeDocument *col = getDocument( tempURI.getURI() );
			if ( col == NULL ) {
				return 0;
			}
			// a document was specified
			std::vector< daeElement* > &vec = (*iter).second;
			std::vector< daeElement* >::iterator i = vec.begin();
			std::vector< daeElement* >::iterator end = vec.end();
			while( i != end )
			{
				if ( col == (*i)->getDocument() )
				{
					++count;
				}
				++i;
			}
			return count;
		}
		else 
		{ 
			//no file specified - just type
			return (daeUInt)(*iter).second.size();
		}
	}

	//if you get here only a file was specified
	daeURI tempURI(file,true);
	daeDocument *col = getDocument( tempURI.getURI() );
	if ( col == NULL ) {
		return 0;
	}
	//a document was specified
	int count = 0;
	std::map< std::string, std::vector< daeElement*> >::iterator iter = elements.begin();
	std::map< std::string, std::vector< daeElement*> >::iterator end = elements.end();
	while( iter != end )
	{
		std::vector< daeElement* > &vec = (*iter).second;
		std::vector< daeElement* >::iterator i = vec.begin();
		std::vector< daeElement* >::iterator end2 = vec.end();
		while( i != end2 )
		{
			if( col == (*i)->getDocument() )
			{
				++count;
			}
			++i;
		}
		++iter;
	}
	return count;

}
void 
nsHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
                                             nsIDOMElement *aOriginalElement,
                                             nsAString& aTagPrefix,
                                             const nsAString& aTagNamespaceURI,
                                             nsIAtom* aTagName,
                                             nsAString& aStr)
{
  PRInt32 count = aContent->GetAttrCount();
  if (!count)
    return;

  nsresult rv;
  nsAutoString nameStr, valueStr;
  NS_NAMED_LITERAL_STRING(_mozStr, "_moz");

  // HTML5 parser stored them in the order they were parsed so we want to
  // loop forward in that case.
  nsIDocument* doc = aContent->GetOwnerDocument();
  PRBool caseSensitive = doc && doc->IsCaseSensitive();
  PRBool loopForward = PR_FALSE;
  if (!caseSensitive) {
    nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
    if (htmlDoc) {
      loopForward = nsHtml5Module::sEnabled;
    }
  }
  PRInt32 index, limit, step;
  if (loopForward) {
    index = 0;
    limit = count;
    step = 1;
  }
  else {
    // Loop backward over the attributes, since the order they are stored in is
    // the opposite of the order they were parsed in (see bug 213347 for reason).
    index = count - 1;
    limit = -1;
    step = -1;
  }
  
  for (; index != limit; index += step) {
    const nsAttrName* name = aContent->GetAttrNameAt(index);
    PRInt32 namespaceID = name->NamespaceID();
    nsIAtom* attrName = name->LocalName();

    // Filter out any attribute starting with [-|_]moz
    const char* sharedName;
    attrName->GetUTF8String(&sharedName);
    if ((('_' == *sharedName) || ('-' == *sharedName)) &&
        !nsCRT::strncmp(sharedName+1, kMozStr, PRUint32(sizeof(kMozStr)-1))) {
      continue;
    }
    aContent->GetAttr(namespaceID, attrName, valueStr);

    // 
    // Filter out special case of <br type="_moz"> or <br _moz*>,
    // used by the editor.  Bug 16988.  Yuck.
    //
    if (aTagName == nsGkAtoms::br && attrName == nsGkAtoms::type &&
        StringBeginsWith(valueStr, _mozStr)) {
      continue;
    }

    if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsGkAtoms::li) && 
        (attrName == nsGkAtoms::value)){
      // This is handled separately in SerializeLIValueAttribute()
      continue;
    }
    PRBool isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
    
    if (((attrName == nsGkAtoms::href) || 
         (attrName == nsGkAtoms::src))) {
      // Make all links absolute when converting only the selection:
      if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
        // Would be nice to handle OBJECT and APPLET tags,
        // but that gets more complicated since we have to
        // search the tag list for CODEBASE as well.
        // For now, just leave them relative.
        nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
        if (uri) {
          nsAutoString absURI;
          rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
          if (NS_SUCCEEDED(rv)) {
            valueStr = absURI;
          }
        }
      }
      // Need to escape URI.
      nsAutoString tempURI(valueStr);
      if (!isJS && NS_FAILED(EscapeURI(aContent, tempURI, valueStr)))
        valueStr = tempURI;
    }

    if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
        attrName == nsGkAtoms::content) {
      // If we're serializing a <meta http-equiv="content-type">,
      // use the proper value, rather than what's in the document.
      nsAutoString header;
      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
      if (header.LowerCaseEqualsLiteral("content-type")) {
        valueStr = NS_LITERAL_STRING("text/html; charset=") +
          NS_ConvertASCIItoUTF16(mCharset);
      }
    }

    attrName->ToString(nameStr);

    // Expand shorthand attribute.
    if (IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
      valueStr = nameStr;
    }
    SerializeAttr(EmptyString(), nameStr, valueStr, aStr, !isJS);
  }
}
bool
nsXHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
                                              nsIContent *aOriginalElement,
                                              nsAString& aTagPrefix,
                                              const nsAString& aTagNamespaceURI,
                                              nsIAtom* aTagName,
                                              nsAString& aStr,
                                              uint32_t aSkipAttr,
                                              bool aAddNSAttr)
{
  nsresult rv;
  uint32_t index, count;
  nsAutoString prefixStr, uriStr, valueStr;
  nsAutoString xmlnsStr;
  xmlnsStr.AssignLiteral(kXMLNS);

  int32_t contentNamespaceID = aContent->GetNameSpaceID();

  // this method is not called by nsHTMLContentSerializer
  // so we don't have to check HTML element, just XHTML

  if (mIsCopying && kNameSpaceID_XHTML == contentNamespaceID) {

    // Need to keep track of OL and LI elements in order to get ordinal number
    // for the LI.
    if (aTagName == nsGkAtoms::ol) {
      // We are copying and current node is an OL;
      // Store its start attribute value in olState->startVal.
      nsAutoString start;
      int32_t startAttrVal = 0;
      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::start, start);
      if (!start.IsEmpty()) {
        nsresult rv = NS_OK;
        startAttrVal = start.ToInteger(&rv);
        //If OL has "start" attribute, first LI element has to start with that value
        //Therefore subtracting 1 as all the LI elements are incrementing it before using it;
        //In failure of ToInteger(), default StartAttrValue to 0.
        if (NS_SUCCEEDED(rv))
          --startAttrVal;
        else
          startAttrVal = 0;
      }
      olState state (startAttrVal, true);
      mOLStateStack.AppendElement(state);
    }
    else if (aTagName == nsGkAtoms::li) {
      mIsFirstChildOfOL = IsFirstChildOfOL(aOriginalElement);
      if (mIsFirstChildOfOL) {
        // If OL is parent of this LI, serialize attributes in different manner.
        NS_ENSURE_TRUE(SerializeLIValueAttribute(aContent, aStr), false);
      }
    }
  }

  // If we had to add a new namespace declaration, serialize
  // and push it on the namespace stack
  if (aAddNSAttr) {
    if (aTagPrefix.IsEmpty()) {
      // Serialize default namespace decl
      NS_ENSURE_TRUE(SerializeAttr(EmptyString(), xmlnsStr,
                                   aTagNamespaceURI,
                                   aStr, true), false);
    } else {
      // Serialize namespace decl
      NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, aTagPrefix,
                                   aTagNamespaceURI,
                                   aStr, true), false);
    }
    PushNameSpaceDecl(aTagPrefix, aTagNamespaceURI, aOriginalElement);
  }

  NS_NAMED_LITERAL_STRING(_mozStr, "_moz");

  count = aContent->GetAttrCount();

  // Now serialize each of the attributes
  // XXX Unfortunately we need a namespace manager to get
  // attribute URIs.
  for (index = 0; index < count; index++) {

    if (aSkipAttr == index) {
        continue;
    }

    mozilla::dom::BorrowedAttrInfo info = aContent->GetAttrInfoAt(index);
    const nsAttrName* name = info.mName;

    int32_t namespaceID = name->NamespaceID();
    nsIAtom* attrName = name->LocalName();
    nsIAtom* attrPrefix = name->GetPrefix();

    // Filter out any attribute starting with [-|_]moz
    nsDependentAtomString attrNameStr(attrName);
    if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
        StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
      continue;
    }

    if (attrPrefix) {
      attrPrefix->ToString(prefixStr);
    }
    else {
      prefixStr.Truncate();
    }

    bool addNSAttr = false;
    if (kNameSpaceID_XMLNS != namespaceID) {
      nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
      addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, true);
    }

    info.mValue->ToString(valueStr);

    nsDependentAtomString nameStr(attrName);
    bool isJS = false;

    if (kNameSpaceID_XHTML == contentNamespaceID) {
      //
      // Filter out special case of <br type="_moz"> or <br _moz*>,
      // used by the editor.  Bug 16988.  Yuck.
      //
      if (namespaceID == kNameSpaceID_None && aTagName == nsGkAtoms::br && attrName == nsGkAtoms::type
          && StringBeginsWith(valueStr, _mozStr)) {
        continue;
      }

      if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsGkAtoms::li)
          && (attrName == nsGkAtoms::value)) {
        // This is handled separately in SerializeLIValueAttribute()
        continue;
      }

      isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);

      if (namespaceID == kNameSpaceID_None &&
          ((attrName == nsGkAtoms::href) ||
          (attrName == nsGkAtoms::src))) {
        // Make all links absolute when converting only the selection:
        if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
          // Would be nice to handle OBJECT and APPLET tags,
          // but that gets more complicated since we have to
          // search the tag list for CODEBASE as well.
          // For now, just leave them relative.
          nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
          if (uri) {
            nsAutoString absURI;
            rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
            if (NS_SUCCEEDED(rv)) {
              valueStr = absURI;
            }
          }
        }
        // Need to escape URI.
        nsAutoString tempURI(valueStr);
        if (!isJS && NS_FAILED(EscapeURI(aContent, tempURI, valueStr)))
          valueStr = tempURI;
      }

      if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
          attrName == nsGkAtoms::content) {
        // If we're serializing a <meta http-equiv="content-type">,
        // use the proper value, rather than what's in the document.
        nsAutoString header;
        aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
        if (header.LowerCaseEqualsLiteral("content-type")) {
          valueStr = NS_LITERAL_STRING("text/html; charset=") +
            NS_ConvertASCIItoUTF16(mCharset);
        }
      }

      // Expand shorthand attribute.
      if (namespaceID == kNameSpaceID_None && IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
        valueStr = nameStr;
      }
    }
    else {
      isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
    }

    NS_ENSURE_TRUE(SerializeAttr(prefixStr, nameStr, valueStr, aStr, !isJS), false);

    if (addNSAttr) {
      NS_ASSERTION(!prefixStr.IsEmpty(),
                   "Namespaced attributes must have a prefix");
      NS_ENSURE_TRUE(SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, true), false);
      PushNameSpaceDecl(prefixStr, uriStr, aOriginalElement);
    }
  }

  return true;
}
void
nsHTMLContentSerializer::SerializeAttributes(nsIContent* aContent,
        nsIAtom* aTagName,
        nsAString& aStr)
{
    nsresult rv;
    PRUint32 index, count;
    nsAutoString nameStr, valueStr;

    count = aContent->GetAttrCount();

    NS_NAMED_LITERAL_STRING(_mozStr, "_moz");

    // Loop backward over the attributes, since the order they are stored in is
    // the opposite of the order they were parsed in (see bug 213347 for reason).
    // index is unsigned, hence index >= 0 is always true.
    for (index = count; index > 0; ) {
        --index;
        const nsAttrName* name = aContent->GetAttrNameAt(index);
        PRInt32 namespaceID = name->NamespaceID();
        nsIAtom* attrName = name->LocalName();

        // Filter out any attribute starting with [-|_]moz
        const char* sharedName;
        attrName->GetUTF8String(&sharedName);
        if ((('_' == *sharedName) || ('-' == *sharedName)) &&
                !nsCRT::strncmp(sharedName+1, kMozStr, PRUint32(sizeof(kMozStr)-1))) {
            continue;
        }
        aContent->GetAttr(namespaceID, attrName, valueStr);

        //
        // Filter out special case of <br type="_moz"> or <br _moz*>,
        // used by the editor.  Bug 16988.  Yuck.
        //
        if (aTagName == nsGkAtoms::br && attrName == nsGkAtoms::type &&
                StringBeginsWith(valueStr, _mozStr)) {
            continue;
        }

        if (mIsCopying && mIsFirstChildOfOL && (aTagName == nsGkAtoms::li) &&
                (attrName == nsGkAtoms::value)) {
            // This is handled separately in SerializeLIValueAttribute()
            continue;
        }
        PRBool isJS = IsJavaScript(attrName, valueStr);

        if (((attrName == nsGkAtoms::href) ||
                (attrName == nsGkAtoms::src))) {
            // Make all links absolute when converting only the selection:
            if (mFlags & nsIDocumentEncoder::OutputAbsoluteLinks) {
                // Would be nice to handle OBJECT and APPLET tags,
                // but that gets more complicated since we have to
                // search the tag list for CODEBASE as well.
                // For now, just leave them relative.
                nsCOMPtr<nsIURI> uri = aContent->GetBaseURI();
                if (uri) {
                    nsAutoString absURI;
                    rv = NS_MakeAbsoluteURI(absURI, valueStr, uri);
                    if (NS_SUCCEEDED(rv)) {
                        valueStr = absURI;
                    }
                }
            }
            // Need to escape URI.
            nsAutoString tempURI(valueStr);
            if (!isJS && NS_FAILED(EscapeURI(tempURI, valueStr)))
                valueStr = tempURI;
        }

        if (mIsWholeDocument && aTagName == nsGkAtoms::meta &&
                attrName == nsGkAtoms::content) {
            // If we're serializing a <meta http-equiv="content-type">,
            // use the proper value, rather than what's in the document.
            nsAutoString header;
            aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
            if (header.LowerCaseEqualsLiteral("content-type")) {
                valueStr = NS_LITERAL_STRING("text/html; charset=") +
                           NS_ConvertASCIItoUTF16(mCharset);
            }
        }

        attrName->ToString(nameStr);

        /*If we already crossed the MaxColumn limit or
        * if this attr name-value pair(including a space,=,opening and closing quotes) is greater than MaxColumn limit
        * then start the attribute from a new line.
        */

        if (mDoFormat
                && (mColPos >= mMaxColumn
                    || ((PRInt32)(mColPos + nameStr.Length() +
                                  valueStr.Length() + 4) > mMaxColumn))) {
            aStr.Append(mLineBreak);
            mColPos = 0;
        }

        // Expand shorthand attribute.
        if (IsShorthandAttr(attrName, aTagName) && valueStr.IsEmpty()) {
            valueStr = nameStr;
        }
        SerializeAttr(EmptyString(), nameStr, valueStr, aStr, !isJS);
    }
}