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);
    }
}
nsresult
nsXULContentUtils::GetTextForNode(nsIRDFNode* aNode, nsAString& aResult)
{
    if (! aNode) {
        aResult.Truncate();
        return NS_OK;
    }

    nsresult rv;

    // Literals are the most common, so try these first.
    nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(aNode);
    if (literal) {
        const char16_t* p;
        rv = literal->GetValueConst(&p);
        if (NS_FAILED(rv)) return rv;

        aResult = p;
        return NS_OK;
    }

    nsCOMPtr<nsIRDFDate> dateLiteral = do_QueryInterface(aNode);
    if (dateLiteral) {
        PRTime value;
        rv = dateLiteral->GetValue(&value);
        if (NS_FAILED(rv)) return rv;

        nsAutoString str;
        rv = gFormat->FormatPRTime(nullptr /* nsILocale* locale */,
                                  kDateFormatShort,
                                  kTimeFormatSeconds,
                                  value,
                                  str);
        aResult.Assign(str);

        if (NS_FAILED(rv)) return rv;

        return NS_OK;
    }

    nsCOMPtr<nsIRDFInt> intLiteral = do_QueryInterface(aNode);
    if (intLiteral) {
        int32_t	value;
        rv = intLiteral->GetValue(&value);
        if (NS_FAILED(rv)) return rv;

        aResult.Truncate();
        nsAutoString intStr;
        intStr.AppendInt(value, 10);
        aResult.Append(intStr);
        return NS_OK;
    }


    nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(aNode);
    if (resource) {
        const char* p;
        rv = resource->GetValueConst(&p);
        if (NS_FAILED(rv)) return rv;
        CopyUTF8toUTF16(p, aResult);
        return NS_OK;
    }

    NS_ERROR("not a resource or a literal");
    return NS_ERROR_UNEXPECTED;
}
Example #3
0
void
nsCSPSchemeSrc::toString(nsAString& outStr) const
{
  outStr.Append(mScheme);
  outStr.AppendASCII(":");
}
Example #4
0
void
nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
{
  // eCSSProperty_UNKNOWN gets used for some recursive calls below.
  NS_ABORT_IF_FALSE((0 <= aProperty &&
                     aProperty <= eCSSProperty_COUNT_no_shorthands) ||
                    aProperty == eCSSProperty_UNKNOWN,
                    "property ID out of range");

  nsCSSUnit unit = GetUnit();
  if (unit == eCSSUnit_Null) {
    return;
  }

  if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
    if (unit == eCSSUnit_Attr) {
      aResult.AppendLiteral("attr(");
    }
    nsAutoString  buffer;
    GetStringValue(buffer);
    if (unit == eCSSUnit_String) {
      nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
    } else if (unit == eCSSUnit_Families) {
      // XXX We really need to do *some* escaping.
      aResult.Append(buffer);
    } else {
      nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
    }
  }
  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Cubic_Bezier) {
    switch (unit) {
      case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
      case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
      case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
      default: break;
    }

    nsCSSValue::Array *array = GetArrayValue();
    PRBool mark = PR_FALSE;
    for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
      if (aProperty == eCSSProperty_border_image && i >= 5) {
        if (array->Item(i).GetUnit() == eCSSUnit_Null) {
          continue;
        }
        if (i == 5) {
          aResult.AppendLiteral(" /");
        }
      }
      if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
        if (unit == eCSSUnit_Array &&
            eCSSProperty_transition_timing_function != aProperty)
          aResult.AppendLiteral(" ");
        else
          aResult.AppendLiteral(", ");
      }
      nsCSSProperty prop =
        ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
         i == array->Count() - 1)
        ? eCSSProperty_list_style_type : aProperty;
      if (array->Item(i).GetUnit() != eCSSUnit_Null) {
        array->Item(i).AppendToString(prop, aResult);
        mark = PR_TRUE;
      }
    }
    if (eCSSUnit_Array == unit &&
        aProperty == eCSSProperty_transition_timing_function) {
      aResult.AppendLiteral(")");
    }
  }
  /* Although Function is backed by an Array, we'll handle it separately
   * because it's a bit quirky.
   */
  else if (eCSSUnit_Function == unit) {
    const nsCSSValue::Array* array = GetArrayValue();
    NS_ABORT_IF_FALSE(array->Count() >= 1,
                      "Functions must have at least one element for the name.");

    /* Append the function name. */
    const nsCSSValue& functionName = array->Item(0);
    if (functionName.GetUnit() == eCSSUnit_Enumerated) {
      // We assume that the first argument is always of nsCSSKeyword type.
      const nsCSSKeyword functionId =
        static_cast<nsCSSKeyword>(functionName.GetIntValue());
      nsStyleUtil::AppendEscapedCSSIdent(
        NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(functionId)),
        aResult);
    } else {
      functionName.AppendToString(aProperty, aResult);
    }
    aResult.AppendLiteral("(");

    /* Now, step through the function contents, writing each of them as we go. */
    for (size_t index = 1; index < array->Count(); ++index) {
      array->Item(index).AppendToString(aProperty, aResult);

      /* If we're not at the final element, append a comma. */
      if (index + 1 != array->Count())
        aResult.AppendLiteral(", ");
    }

    /* Finally, append the closing parenthesis. */
    aResult.AppendLiteral(")");
  }
  else if (IsCalcUnit()) {
    NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc ||
                      GetUnit() == eCSSUnit_Calc_Maximum ||
                      GetUnit() == eCSSUnit_Calc_Minimum,
                      "unexpected unit");
    CSSValueSerializeCalcOps ops(aProperty, aResult);
    css::SerializeCalc(*this, ops);
  }
  else if (eCSSUnit_Integer == unit) {
    nsAutoString tmpStr;
    tmpStr.AppendInt(GetIntValue(), 10);
    aResult.Append(tmpStr);
  }
  else if (eCSSUnit_Enumerated == unit) {
    if (eCSSProperty_text_decoration == aProperty) {
      PRInt32 intValue = GetIntValue();
      if (NS_STYLE_TEXT_DECORATION_NONE == intValue) {
        AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
                           aResult);
      } else {
        // Ignore the "override all" internal value.
        // (It doesn't have a string representation.)
        intValue &= ~NS_STYLE_TEXT_DECORATION_OVERRIDE_ALL;
        nsStyleUtil::AppendBitmaskCSSValue(
          aProperty, intValue,
          NS_STYLE_TEXT_DECORATION_UNDERLINE,
          NS_STYLE_TEXT_DECORATION_PREF_ANCHORS,
          aResult);
      }
    }
    else if (eCSSProperty_azimuth == aProperty) {
      PRInt32 intValue = GetIntValue();
      AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, (intValue & ~NS_STYLE_AZIMUTH_BEHIND)), aResult);
      if ((NS_STYLE_AZIMUTH_BEHIND & intValue) != 0) {
        aResult.Append(PRUnichar(' '));
        AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_AZIMUTH_BEHIND), aResult);
      }
    }
    else if (eCSSProperty_marks == aProperty) {
      PRInt32 intValue = GetIntValue();
      if (intValue == NS_STYLE_PAGE_MARKS_NONE) {
        AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
                           aResult);
      } else {
        nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
                                           NS_STYLE_PAGE_MARKS_CROP,
                                           NS_STYLE_PAGE_MARKS_REGISTER,
                                           aResult);
      }
    }
    else {
      const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, GetIntValue());
      AppendASCIItoUTF16(name, aResult);
    }
  }
  else if (eCSSUnit_EnumColor == unit) {
    // we can lookup the property in the ColorTable and then
    // get a string mapping the name
    nsCAutoString str;
    if (nsCSSProps::GetColorName(GetIntValue(), str)){
      AppendASCIItoUTF16(str, aResult);
    } else {
      NS_ABORT_IF_FALSE(false, "bad color value");
    }
  }
  else if (eCSSUnit_Color == unit) {
    nscolor color = GetColorValue();
    if (color == NS_RGBA(0, 0, 0, 0)) {
      // Use the strictest match for 'transparent' so we do correct
      // round-tripping of all other rgba() values.
      aResult.AppendLiteral("transparent");
    } else {
      nsAutoString tmpStr;
      PRUint8 a = NS_GET_A(color);
      if (a < 255) {
        tmpStr.AppendLiteral("rgba(");
      } else {
        tmpStr.AppendLiteral("rgb(");
      }

      NS_NAMED_LITERAL_STRING(comma, ", ");

      tmpStr.AppendInt(NS_GET_R(color), 10);
      tmpStr.Append(comma);
      tmpStr.AppendInt(NS_GET_G(color), 10);
      tmpStr.Append(comma);
      tmpStr.AppendInt(NS_GET_B(color), 10);
      if (a < 255) {
        tmpStr.Append(comma);
        tmpStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
      }
      tmpStr.Append(PRUnichar(')'));

      aResult.Append(tmpStr);
    }
  }
  else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
    aResult.Append(NS_LITERAL_STRING("url("));
    nsStyleUtil::AppendEscapedCSSString(
      nsDependentString(GetOriginalURLValue()), aResult);
    aResult.Append(NS_LITERAL_STRING(")"));
  }
  else if (eCSSUnit_Element == unit) {
    aResult.Append(NS_LITERAL_STRING("-moz-element(#"));
    nsAutoString tmpStr;
    GetStringValue(tmpStr);
    nsStyleUtil::AppendEscapedCSSIdent(
      nsDependentString(tmpStr), aResult);
    aResult.Append(NS_LITERAL_STRING(")"));
  }
  else if (eCSSUnit_Percent == unit) {
    nsAutoString tmpStr;
    tmpStr.AppendFloat(GetPercentValue() * 100.0f);
    aResult.Append(tmpStr);
  }
  else if (eCSSUnit_Percent < unit) {  // length unit
    nsAutoString tmpStr;
    tmpStr.AppendFloat(GetFloatValue());
    aResult.Append(tmpStr);
  }
  else if (eCSSUnit_Gradient == unit) {
    nsCSSValueGradient* gradient = GetGradientValue();

    if (gradient->mIsRepeating) {
      if (gradient->mIsRadial)
        aResult.AppendLiteral("-moz-repeating-radial-gradient(");
      else
        aResult.AppendLiteral("-moz-repeating-linear-gradient(");
    } else {
      if (gradient->mIsRadial)
        aResult.AppendLiteral("-moz-radial-gradient(");
      else
        aResult.AppendLiteral("-moz-linear-gradient(");
    }

    if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
        gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
        gradient->mAngle.GetUnit() != eCSSUnit_None) {
      if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
        gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
                                                aResult);
        aResult.AppendLiteral(" ");
      }
      if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
        gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
                                                aResult);
        aResult.AppendLiteral(" ");
      }
      if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
        gradient->mAngle.AppendToString(aProperty, aResult);
      }
      aResult.AppendLiteral(", ");
    }

    if (gradient->mIsRadial &&
        (gradient->mRadialShape.GetUnit() != eCSSUnit_None ||
         gradient->mRadialSize.GetUnit() != eCSSUnit_None)) {
      if (gradient->mRadialShape.GetUnit() != eCSSUnit_None) {
        NS_ABORT_IF_FALSE(gradient->mRadialShape.GetUnit() ==
                          eCSSUnit_Enumerated,
                          "bad unit for radial gradient shape");
        PRInt32 intValue = gradient->mRadialShape.GetIntValue();
        NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
                          "radial gradient with linear shape?!");
        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
                               nsCSSProps::kRadialGradientShapeKTable),
                           aResult);
        aResult.AppendLiteral(" ");
      }

      if (gradient->mRadialSize.GetUnit() != eCSSUnit_None) {
        NS_ABORT_IF_FALSE(gradient->mRadialSize.GetUnit() ==
                          eCSSUnit_Enumerated,
                          "bad unit for radial gradient size");
        PRInt32 intValue = gradient->mRadialSize.GetIntValue();
        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
                               nsCSSProps::kRadialGradientSizeKTable),
                           aResult);
      }
      aResult.AppendLiteral(", ");
    }

    for (PRUint32 i = 0 ;;) {
      gradient->mStops[i].mColor.AppendToString(aProperty, aResult);
      if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
        aResult.AppendLiteral(" ");
        gradient->mStops[i].mLocation.AppendToString(aProperty, aResult);
      }
      if (++i == gradient->mStops.Length()) {
        break;
      }
      aResult.AppendLiteral(", ");
    }

    aResult.AppendLiteral(")");
  } else if (eCSSUnit_Pair == unit) {
    GetPairValue().AppendToString(aProperty, aResult);
  } else if (eCSSUnit_Rect == unit) {
    GetRectValue().AppendToString(aProperty, aResult);
  } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
    GetListValue()->AppendToString(aProperty, aResult);
  } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
    GetPairListValue()->AppendToString(aProperty, aResult);
  }

  switch (unit) {
    case eCSSUnit_Null:         break;
    case eCSSUnit_Auto:         aResult.AppendLiteral("auto");     break;
    case eCSSUnit_Inherit:      aResult.AppendLiteral("inherit");  break;
    case eCSSUnit_Initial:      aResult.AppendLiteral("-moz-initial"); break;
    case eCSSUnit_None:         aResult.AppendLiteral("none");     break;
    case eCSSUnit_Normal:       aResult.AppendLiteral("normal");   break;
    case eCSSUnit_System_Font:  aResult.AppendLiteral("-moz-use-system-font"); break;
    case eCSSUnit_All:          aResult.AppendLiteral("all"); break;
    case eCSSUnit_Dummy:
    case eCSSUnit_DummyInherit:
      NS_ABORT_IF_FALSE(false, "should never serialize");
      break;

    case eCSSUnit_String:       break;
    case eCSSUnit_Ident:        break;
    case eCSSUnit_Families:     break;
    case eCSSUnit_URL:          break;
    case eCSSUnit_Image:        break;
    case eCSSUnit_Element:      break;
    case eCSSUnit_Array:        break;
    case eCSSUnit_Attr:
    case eCSSUnit_Cubic_Bezier:
    case eCSSUnit_Counter:
    case eCSSUnit_Counters:     aResult.Append(PRUnichar(')'));    break;
    case eCSSUnit_Local_Font:   break;
    case eCSSUnit_Font_Format:  break;
    case eCSSUnit_Function:     break;
    case eCSSUnit_Calc:         break;
    case eCSSUnit_Calc_Plus:    break;
    case eCSSUnit_Calc_Minus:   break;
    case eCSSUnit_Calc_Times_L: break;
    case eCSSUnit_Calc_Times_R: break;
    case eCSSUnit_Calc_Divided: break;
    case eCSSUnit_Calc_Minimum: break;
    case eCSSUnit_Calc_Maximum: break;
    case eCSSUnit_Integer:      break;
    case eCSSUnit_Enumerated:   break;
    case eCSSUnit_EnumColor:    break;
    case eCSSUnit_Color:        break;
    case eCSSUnit_Percent:      aResult.Append(PRUnichar('%'));    break;
    case eCSSUnit_Number:       break;
    case eCSSUnit_Gradient:     break;
    case eCSSUnit_Pair:         break;
    case eCSSUnit_Rect:         break;
    case eCSSUnit_List:         break;
    case eCSSUnit_ListDep:      break;
    case eCSSUnit_PairList:     break;
    case eCSSUnit_PairListDep:  break;

    case eCSSUnit_Inch:         aResult.AppendLiteral("in");   break;
    case eCSSUnit_Millimeter:   aResult.AppendLiteral("mm");   break;
    case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm");   break;
    case eCSSUnit_Centimeter:   aResult.AppendLiteral("cm");   break;
    case eCSSUnit_Point:        aResult.AppendLiteral("pt");   break;
    case eCSSUnit_Pica:         aResult.AppendLiteral("pc");   break;

    case eCSSUnit_EM:           aResult.AppendLiteral("em");   break;
    case eCSSUnit_XHeight:      aResult.AppendLiteral("ex");   break;
    case eCSSUnit_Char:         aResult.AppendLiteral("ch");   break;
    case eCSSUnit_RootEM:       aResult.AppendLiteral("rem");  break;

    case eCSSUnit_Pixel:        aResult.AppendLiteral("px");   break;

    case eCSSUnit_Degree:       aResult.AppendLiteral("deg");  break;
    case eCSSUnit_Grad:         aResult.AppendLiteral("grad"); break;
    case eCSSUnit_Radian:       aResult.AppendLiteral("rad");  break;

    case eCSSUnit_Hertz:        aResult.AppendLiteral("Hz");   break;
    case eCSSUnit_Kilohertz:    aResult.AppendLiteral("kHz");  break;

    case eCSSUnit_Seconds:      aResult.Append(PRUnichar('s'));    break;
    case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms");   break;
  }
}
Example #5
0
void
nsWin32Locale::GetXPLocale(LCID winLCID, nsAString& locale)
{
  initFunctionPointers ();

  if (lcidToLocaleName)
  {
    WCHAR ret_locale[LOCALE_NAME_MAX_LENGTH];
    int rv = lcidToLocaleName(winLCID, ret_locale, LOCALE_NAME_MAX_LENGTH, 0);
    // rv 0 means that the function failed to match up the LCID, so we fallback
    // to the old function
    if (rv != 0)
    {
      locale.Assign(ret_locale);
      return;
    }
  }

  DWORD    lang_id, sublang_id;
  size_t   i, j;

  lang_id = PRIMARYLANGID(LANGIDFROMLCID(winLCID));
  sublang_id = SUBLANGID(LANGIDFROMLCID(winLCID));

  /* Special-case Norwegian Bokmal and Norwegian Nynorsk, which have the same
     LANG_ID on Windows, but have separate ISO-639-2 codes */
  if (lang_id == LANG_NORWEGIAN) {
    if (sublang_id == SUBLANG_NORWEGIAN_BOKMAL) {
      locale.AssignASCII("nb-NO");
    } else if (sublang_id == SUBLANG_NORWEGIAN_NYNORSK) {
      locale.AssignASCII("nn-NO");
    } else {
      locale.AssignASCII("no-NO");
    }
    return;
  }

  for(i=0;i<LENGTH_MAPPING_LIST;i++) {
    if (lang_id==iso_list[i].win_code) {
      /* Special-case Croatian and Serbian, which have the same LANG_ID on
         Windows, but have been split into separate ISO-639-2 codes */
      if (lang_id == LANG_CROATIAN) {
        if (sublang_id == SUBLANG_DEFAULT) {
          locale.AssignLiteral(CROATIAN_ISO_CODE);
        } else {
          locale.AssignLiteral(SERBIAN_ISO_CODE);
        }
      } else {
        locale.AssignASCII(iso_list[i].iso_code);
      }
      for(j=0;iso_list[i].sublang_list[j].win_code;j++) {
        if (sublang_id == iso_list[i].sublang_list[j].win_code) {
          locale.Append(PRUnichar('-'));
          locale.AppendASCII(iso_list[i].sublang_list[j].iso_code);
          break;
        }
      }
      return;
    }
  }

  //
  // didn't find any match. fall back to en-US, which is better 
  // than unusable buttons without 'OK', 'Cancel', etc (bug 224546)       
  //
  locale.AssignLiteral("en-US"); 
  return;
}
Example #6
0
NS_IMETHODIMP
nsLocation::GetHash(nsAString& aHash)
{
  if (!CallerSubsumes())
    return NS_ERROR_DOM_SECURITY_ERR;

  aHash.SetLength(0);

  nsCOMPtr<nsIURI> uri;
  nsresult rv = GetURI(getter_AddRefs(uri));
  if (NS_FAILED(rv) || !uri) {
    return rv;
  }

  nsAutoCString ref;
  nsAutoString unicodeRef;

  rv = uri->GetRef(ref);

  if (nsContentUtils::EncodeDecodeURLHash()) {
    if (NS_SUCCEEDED(rv)) {
      nsCOMPtr<nsITextToSubURI> textToSubURI(
          do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv));

      if (NS_SUCCEEDED(rv)) {
        nsAutoCString charset;
        uri->GetOriginCharset(charset);

        rv = textToSubURI->UnEscapeURIForUI(charset, ref, unicodeRef);
      }

      if (NS_FAILED(rv)) {
        // Oh, well.  No intl here!
        NS_UnescapeURL(ref);
        CopyASCIItoUTF16(ref, unicodeRef);
        rv = NS_OK;
      }
    }

    if (NS_SUCCEEDED(rv) && !unicodeRef.IsEmpty()) {
      aHash.Assign(char16_t('#'));
      aHash.Append(unicodeRef);
    }
  } else { // URL Hash should simply return the value of the Ref segment
    if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) {
      aHash.Assign(char16_t('#'));
      AppendUTF8toUTF16(ref, aHash);
    }
  }

  if (aHash == mCachedHash) {
    // Work around ShareThis stupidly polling location.hash every
    // 5ms all the time by handing out the same exact string buffer
    // we handed out last time.
    aHash = mCachedHash;
  } else {
    mCachedHash = aHash;
  }

  return rv;
}
Example #7
0
void nsCSSSelector::ToStringInternal(nsAString& aString,
                                     nsICSSStyleSheet* aSheet,
                                     PRBool aIsPseudoElem,
                                     PRIntn aNegatedIndex,
                                     const nsString& aIdPrefix) const
{
  nsAutoString temp;
  PRBool aIsNegated = PRBool(0 < aNegatedIndex);
  PRBool isPseudoElement = IsPseudoElement(mTag);

  // selectors are linked from right-to-left, so the next selector in the linked list
  // actually precedes this one in the resulting string
  if (mNext) {
    mNext->ToStringInternal(aString, aSheet, IsPseudoElement(mTag), 0,
                            aIdPrefix);
    if (!aIsNegated && !isPseudoElement) {
      // don't add a leading whitespace if we have a pseudo-element
      // or a negated simple selector
      aString.Append(PRUnichar(' '));
    }
  }
  if (1 < aNegatedIndex) {
    // the first mNegations does not contain a negated type element selector
    // or a negated universal selector
    NS_IF_NEGATED_START(aIsNegated, aString)
  }

  // For non-pseudo-element selectors or for lone pseudo-elements, deal with
  // namespace prefixes.
  if (!isPseudoElement || !mNext) {
    // append the namespace prefix if needed
    if (mNameSpace == kNameSpaceID_None) {
      // The only way to do this in CSS is to have an explicit namespace
      // of "none" specified in the sheet by having a '|' with nothing
      // before it.
      aString.Append(PRUnichar('|'));
    } else {
#ifndef FBML
      if (aSheet) {
        nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
        // sheetNS is non-null if and only if we had an @namespace rule.  If it's
        // null, that means that the only namespaces we could have are the
        // wildcard namespace (which can be implicit in this case) and the "none"
        // namespace, which we handled above.  So no need to output anything when
        // sheetNS is null.
        if (sheetNS) {
          nsIAtom *prefixAtom = nsnull;
          // prefixAtom is non-null if and only if we have a prefix other than
          // '*'
          if (mNameSpace != kNameSpaceID_Unknown) {
            prefixAtom = sheetNS->FindPrefix(mNameSpace);
          }
          if (prefixAtom) {
            nsAutoString prefix;
            prefixAtom->ToString(prefix);
            aString.Append(prefix);
            aString.Append(PRUnichar('|'));
          } else if (mNameSpace == kNameSpaceID_Unknown) {
            // explicit *| or only non-default namespace rules and we're not
            // using any of those namespaces
            aString.AppendLiteral("*|");
          }
          // else we are in the default namespace and don't need to output
          // anything
        }
      }
#endif
    }
  }

  // smells like a universal selector
  if (!mTag && !mIDList && !mClassList) {
    if (1 != aNegatedIndex) {
      aString.Append(PRUnichar('*'));
    }
    if (1 < aNegatedIndex) {
      NS_IF_NEGATED_END(aIsNegated, aString)
    }
  } else {
    // Append the tag name, if there is one
    if (mTag) {
Example #8
0
void
nsHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
        nsAString& aOutputStr)
{
    if (mBodyOnly && !mInBody) {
        return;
    }

    if (mDisableEntityEncoding) {
        aOutputStr.Append(aStr);
        return;
    }

    bool nonBasicEntities =
        !!(mFlags & (nsIDocumentEncoder::OutputEncodeLatin1Entities |
                     nsIDocumentEncoder::OutputEncodeHTMLEntities   |
                     nsIDocumentEncoder::OutputEncodeW3CEntities));

    if (!nonBasicEntities &&
            (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities))) {
        const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
        uint32_t start = 0;
        const uint32_t len = aStr.Length();
        for (uint32_t i = 0; i < len; ++i) {
            const char* entity = nullptr;
            i = FindNextBasicEntity(aStr, len, i, entityTable, &entity);
            uint32_t normalTextLen = i - start;
            if (normalTextLen) {
                aOutputStr.Append(Substring(aStr, start, normalTextLen));
            }
            if (entity) {
                aOutputStr.AppendASCII(entity);
                start = i + 1;
            }
        }
        return;
    } else if (nonBasicEntities) {
        nsIParserService* parserService = nsContentUtils::GetParserService();

        if (!parserService) {
            NS_ERROR("Can't get parser service");
            return;
        }

        nsReadingIterator<char16_t> done_reading;
        aStr.EndReading(done_reading);

        // for each chunk of |aString|...
        uint32_t advanceLength = 0;
        nsReadingIterator<char16_t> iter;

        const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
        nsAutoCString entityReplacement;

        for (aStr.BeginReading(iter);
                iter != done_reading;
                iter.advance(int32_t(advanceLength))) {
            uint32_t fragmentLength = iter.size_forward();
            uint32_t lengthReplaced = 0; // the number of UTF-16 codepoints
            //  replaced by a particular entity
            const char16_t* c = iter.get();
            const char16_t* fragmentStart = c;
            const char16_t* fragmentEnd = c + fragmentLength;
            const char* entityText = nullptr;
            const char* fullConstEntityText = nullptr;
            char* fullEntityText = nullptr;

            advanceLength = 0;
            // for each character in this chunk, check if it
            // needs to be replaced
            for (; c < fragmentEnd; c++, advanceLength++) {
                char16_t val = *c;
                if (val <= kValNBSP && entityTable[val]) {
                    fullConstEntityText = entityTable[val];
                    break;
                } else if (val > 127 &&
                           ((val < 256 &&
                             mFlags & nsIDocumentEncoder::OutputEncodeLatin1Entities) ||
                            mFlags & nsIDocumentEncoder::OutputEncodeHTMLEntities)) {
                    entityReplacement.Truncate();
                    parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);

                    if (!entityReplacement.IsEmpty()) {
                        entityText = entityReplacement.get();
                        break;
                    }
                }
                else if (val > 127 &&
                         mFlags & nsIDocumentEncoder::OutputEncodeW3CEntities &&
                         mEntityConverter) {
                    if (NS_IS_HIGH_SURROGATE(val) &&
                            c + 1 < fragmentEnd &&
                            NS_IS_LOW_SURROGATE(*(c + 1))) {
                        uint32_t valUTF32 = SURROGATE_TO_UCS4(val, *(++c));
                        if (NS_SUCCEEDED(mEntityConverter->ConvertUTF32ToEntity(valUTF32,
                                         nsIEntityConverter::entityW3C, &fullEntityText))) {
                            lengthReplaced = 2;
                            break;
                        }
                        else {
                            advanceLength++;
                        }
                    }
                    else if (NS_SUCCEEDED(mEntityConverter->ConvertToEntity(val,
                                          nsIEntityConverter::entityW3C,
                                          &fullEntityText))) {
                        lengthReplaced = 1;
                        break;
                    }
                }
            }

            aOutputStr.Append(fragmentStart, advanceLength);
            if (entityText) {
                aOutputStr.Append(char16_t('&'));
                AppendASCIItoUTF16(entityText, aOutputStr);
                aOutputStr.Append(char16_t(';'));
                advanceLength++;
            }
            else if (fullConstEntityText) {
                aOutputStr.AppendASCII(fullConstEntityText);
                ++advanceLength;
            }
            // if it comes from nsIEntityConverter, it already has '&' and ';'
            else if (fullEntityText) {
                AppendASCIItoUTF16(fullEntityText, aOutputStr);
                nsMemory::Free(fullEntityText);
                advanceLength += lengthReplaced;
            }
        }
    } else {
        nsXMLContentSerializer::AppendAndTranslateEntities(aStr, aOutputStr);
    }
}
Example #9
0
void
txErrorExpr::toString(nsAString& aStr)
{
    aStr.Append(mStr);
}
Example #10
0
void URL::GetProtocol(nsAString& aProtocol) const {
  URL_GETTER(aProtocol, GetScheme);
  aProtocol.Append(char16_t(':'));
}
Example #11
0
void nsCSSSelector::ToStringInternal(nsAString& aString,
                                     nsICSSStyleSheet* aSheet,
                                     PRBool aIsPseudoElem,
                                     PRBool aIsNegated) const
{
  nsAutoString temp;
  PRBool isPseudoElement = IsPseudoElement(mTag);
  
  // selectors are linked from right-to-left, so the next selector in the linked list
  // actually precedes this one in the resulting string
  if (mNext) {
    mNext->ToStringInternal(aString, aSheet, IsPseudoElement(mTag), 0);
    if (!aIsNegated && !isPseudoElement) {
      // don't add a leading whitespace if we have a pseudo-element
      // or a negated simple selector
      aString.Append(PRUnichar(' '));
    }
  }

  // For non-pseudo-element selectors or for lone pseudo-elements, deal with
  // namespace prefixes.
  PRBool wroteNamespace = PR_FALSE;
  if (!isPseudoElement || !mNext) {
    // append the namespace prefix if needed
    if (mNameSpace == kNameSpaceID_None) {
      // The only way to do this in CSS is to have an explicit namespace
      // of "none" specified in the sheet by having a '|' with nothing
      // before it.
      aString.Append(PRUnichar('|'));
      wroteNamespace = PR_TRUE;
    } else {
      if (aSheet) {
        nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
    
        // sheetNS is non-null if and only if we had an @namespace rule.  If it's
        // null, that means that the only namespaces we could have are the
        // wildcard namespace (which can be implicit in this case) and the "none"
        // namespace, which we handled above.  So no need to output anything when
        // sheetNS is null.
        if (sheetNS) {
          if (mNameSpace != kNameSpaceID_Unknown) {
            if (sheetNS->FindNameSpaceID(nsnull) != mNameSpace) {
              nsIAtom *prefixAtom = sheetNS->FindPrefix(mNameSpace);
              NS_ASSERTION(prefixAtom, "how'd we get a non-default namespace "
                                       "without a prefix?");
              nsAutoString prefix;
              prefixAtom->ToString(prefix);
              aString.Append(prefix);
              aString.Append(PRUnichar('|'));
              wroteNamespace = PR_TRUE;
            }
            // otherwise it must be the default namespace
          } else {
            // A selector for an element in any namespace.
            if (// Use explicit "*|" only when it's not implied
                sheetNS->FindNameSpaceID(nsnull) != kNameSpaceID_None &&
                // :not() is special in that the default namespace is
                // not implied for non-type selectors
                (!aIsNegated || (!mIDList && !mClassList &&
                                 !mPseudoClassList && !mAttrList))) {
              aString.AppendLiteral("*|");
              wroteNamespace = PR_TRUE;
            }
          }
        }
      }
    }
  }
      
  if (!mTag) {
    // Universal selector:  avoid writing the universal selector when we
    // can avoid it, especially since we're required to avoid it for the
    // inside of :not()
    if (wroteNamespace ||
        (!mIDList && !mClassList && !mPseudoClassList && !mAttrList &&
         (aIsNegated || !mNegations))) {
      aString.Append(PRUnichar('*'));
    }
  } else {
    // Append the tag name
    if (isPseudoElement) {
      if (!mNext) {
        // Lone pseudo-element selector -- toss in a wildcard type selector
        // XXXldb Why?
        aString.Append(PRUnichar('*'));
      }
      if (!nsCSSPseudoElements::IsCSS2PseudoElement(mTag)) {
        aString.Append(PRUnichar(':'));
      }
    }
    nsAutoString prefix;
    mTag->ToString(prefix);
    aString.Append(prefix);
  }

  // Append the id, if there is one
  if (mIDList) {
    nsAtomList* list = mIDList;
    while (list != nsnull) {
      list->mAtom->ToString(temp);
      aString.Append(PRUnichar('#'));
      aString.Append(temp);
      list = list->mNext;
    }
  }

  // Append each class in the linked list
  if (mClassList) {
    nsAtomList* list = mClassList;
    while (list != nsnull) {
      list->mAtom->ToString(temp);
      aString.Append(PRUnichar('.'));
      aString.Append(temp);
      list = list->mNext;
    }
  }

  // Append each attribute selector in the linked list
  if (mAttrList) {
    nsAttrSelector* list = mAttrList;
    while (list != nsnull) {
      aString.Append(PRUnichar('['));
      // Append the namespace prefix
      if (list->mNameSpace > 0) {
        if (aSheet) {
          nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
          // will return null if namespace was the default
          nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace);
          if (prefixAtom) { 
            nsAutoString prefix;
            prefixAtom->ToString(prefix);
            aString.Append(prefix);
            aString.Append(PRUnichar('|'));
          }
        }
      }
      // Append the attribute name
      list->mAttr->ToString(temp);
      aString.Append(temp);

      if (list->mFunction != NS_ATTR_FUNC_SET) {
        // Append the function
        if (list->mFunction == NS_ATTR_FUNC_INCLUDES)
          aString.Append(PRUnichar('~'));
        else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH)
          aString.Append(PRUnichar('|'));
        else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH)
          aString.Append(PRUnichar('^'));
        else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH)
          aString.Append(PRUnichar('$'));
        else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH)
          aString.Append(PRUnichar('*'));

        aString.Append(PRUnichar('='));
      
        // Append the value
        nsAutoString escaped;
        nsStyleUtil::EscapeCSSString(list->mValue, escaped);
      
        aString.Append(PRUnichar('\"'));
        aString.Append(escaped);
        aString.Append(PRUnichar('\"'));
      }

      aString.Append(PRUnichar(']'));
      
      list = list->mNext;
    }
  }

  // Append each pseudo-class in the linked list
  if (mPseudoClassList) {
    nsAtomStringList* list = mPseudoClassList;
    while (list != nsnull) {
      list->mAtom->ToString(temp);
      aString.Append(temp);
      if (nsnull != list->mString) {
        aString.Append(PRUnichar('('));
        aString.Append(list->mString);
        aString.Append(PRUnichar(')'));
      }
      list = list->mNext;
    }
  }

  if (!aIsNegated) {
    for (nsCSSSelector* negation = mNegations; negation;
         negation = negation->mNegations) {
      aString.AppendLiteral(":not(");
      negation->ToStringInternal(aString, aSheet, PR_FALSE, PR_TRUE);
      aString.Append(PRUnichar(')'));
    }
  }

  // Append the operator only if the selector is not negated and is not
  // a pseudo-element
  if (!aIsNegated && mOperator && !aIsPseudoElem) {
    aString.Append(PRUnichar(' '));
    aString.Append(mOperator);
  }
}
Example #12
0
nsresult nsMsgI18NConvertToUnicode(const char* aCharset,
                                   const nsCString& inString, 
                                   nsAString& outString,
                                   bool aIsCharsetCanonical)
{
  if (inString.IsEmpty()) {
    outString.Truncate();
    return NS_OK;
  }
  else if (!*aCharset || !PL_strcasecmp(aCharset, "us-ascii") ||
           !PL_strcasecmp(aCharset, "ISO-8859-1")) {
    // Despite its name, it also works for Latin-1.
    CopyASCIItoUTF16(inString, outString);
    return NS_OK;
  }
  else if (!PL_strcasecmp(aCharset, "UTF-8")) {
    if (MsgIsUTF8(inString)) {
      nsAutoString tmp;
      CopyUTF8toUTF16(inString, tmp);
      if (!tmp.IsEmpty() && tmp.get()[0] == char16_t(0xFEFF))
        tmp.Cut(0, 1);
      outString.Assign(tmp);
      return NS_OK;
    }
    NS_WARNING("Invalid UTF-8 string");
    return NS_ERROR_UNEXPECTED;
  }

  nsresult rv;
  nsCOMPtr <nsICharsetConverterManager> ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr <nsIUnicodeDecoder> decoder;

  // get an unicode converter
  if (aIsCharsetCanonical)  // optimize for modified UTF-7 used by IMAP
    rv = ccm->GetUnicodeDecoderRaw(aCharset, getter_AddRefs(decoder));
  else
    rv = ccm->GetUnicodeDecoderInternal(aCharset, getter_AddRefs(decoder));
  NS_ENSURE_SUCCESS(rv, rv);

  const char *originalSrcPtr = inString.get();
  const char *currentSrcPtr = originalSrcPtr;
  int32_t originalLength = inString.Length();
  int32_t srcLength;
  int32_t dstLength;
  char16_t localbuf[512];
  int32_t consumedLen = 0;

  outString.Truncate();

  // convert
  while (consumedLen < originalLength) {
    srcLength = originalLength - consumedLen;  
    dstLength = 512;
    rv = decoder->Convert(currentSrcPtr, &srcLength, localbuf, &dstLength);
    if (NS_FAILED(rv) || dstLength == 0)
      break;
    outString.Append(localbuf, dstLength);

    currentSrcPtr += srcLength;
    consumedLen = currentSrcPtr - originalSrcPtr; // src length used so far
  }
  return rv;
}
void 
nsXMLContentSerializer::AppendToString(const PRUnichar aChar,
                                       nsAString& aOutputStr)
{
  aOutputStr.Append(aChar);
}
Example #14
0
NS_IMETHODIMP
nsDOMFile::GetAsDataURL(nsAString &aResult)
{
    aResult.AssignLiteral("data:");

    nsresult rv;
    if (!mContentType.Length()) {
        nsCOMPtr<nsIMIMEService> mimeService =
            do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
        NS_ENSURE_SUCCESS(rv, rv);

        nsCAutoString contentType;
        rv = mimeService->GetTypeFromFile(mFile, contentType);
        if (NS_SUCCEEDED(rv)) {
            CopyUTF8toUTF16(contentType, mContentType);
        }
    }

    if (mContentType.Length()) {
        aResult.Append(mContentType);
    } else {
        aResult.AppendLiteral("application/octet-stream");
    }
    aResult.AppendLiteral(";base64,");

    nsCOMPtr<nsIInputStream> stream;
    rv = GetInternalStream(getter_AddRefs(stream));
    NS_ENSURE_SUCCESS(rv, DOMFileResult(rv));

    char readBuf[4096];
    PRUint32 leftOver = 0;
    PRUint32 numRead;
    do {
        rv = stream->Read(readBuf + leftOver, sizeof(readBuf) - leftOver, &numRead);
        NS_ENSURE_SUCCESS(rv, DOMFileResult(rv));

        PRUint32 numEncode = numRead + leftOver;
        leftOver = 0;

        if (numEncode == 0) break;

        // unless this is the end of the file, encode in multiples of 3
        if (numRead > 0) {
            leftOver = numEncode % 3;
            numEncode -= leftOver;
        }

        // out buffer should be at least 4/3rds the read buf, plus a terminator
        char *base64 = PL_Base64Encode(readBuf, numEncode, nsnull);
        if (!base64) {
            return DOMFileResult(NS_ERROR_OUT_OF_MEMORY);
        }
        nsDependentCString str(base64);
        PRUint32 strLen = str.Length();
        PRUint32 oldLength = aResult.Length();
        AppendASCIItoUTF16(str, aResult);
        PR_Free(base64);
        if (aResult.Length() - oldLength != strLen) {
            return DOMFileResult(NS_ERROR_OUT_OF_MEMORY);
        }

        if (leftOver) {
            memmove(readBuf, readBuf + numEncode, leftOver);
        }
    } while (numRead > 0);

    return NS_OK;
}
// performs a locale sensitive date formatting operation on the struct tm parameter
nsresult nsDateTimeFormatWin::FormatTMTime(nsILocale* locale, 
                                           const nsDateFormatSelector  dateFormatSelector, 
                                           const nsTimeFormatSelector timeFormatSelector, 
                                           const struct tm*  tmTime, 
                                           nsAString& stringOut)
{
  SYSTEMTIME system_time;
  DWORD dwFlags_Date = 0, dwFlags_Time = 0;
  int dateLen, timeLen;
  PRUnichar dateBuffer[NSDATETIMEFORMAT_BUFFER_LEN], timeBuffer[NSDATETIMEFORMAT_BUFFER_LEN];

  // set up locale data
  (void) Initialize(locale);

  // Map tm to SYSTEMTIME
  system_time.wYear = 1900 + tmTime->tm_year;
  system_time.wMonth = tmTime->tm_mon + 1;
  system_time.wDayOfWeek = tmTime->tm_wday;
  system_time.wDay = tmTime->tm_mday;
  system_time.wHour = tmTime->tm_hour;
  system_time.wMinute = tmTime->tm_min;
  system_time.wSecond = tmTime->tm_sec;
  system_time.wMilliseconds = 0;

  // Map to WinAPI date format
  switch (dateFormatSelector) {
  case kDateFormatLong:
    dwFlags_Date = DATE_LONGDATE;
    break;
  case kDateFormatShort:
    dwFlags_Date = DATE_SHORTDATE;
    break;
  case kDateFormatWeekday:
    dwFlags_Date = 0;
    break;
  case kDateFormatYearMonth:
    dwFlags_Date = 0;     // TODO:only availabe NT5
    break;
  }

  // Map to WinAPI time format
  switch (timeFormatSelector) {
  case kTimeFormatSeconds:
    dwFlags_Time = 0;
    break;
  case kTimeFormatNoSeconds:
    dwFlags_Time = TIME_NOSECONDS;
    break;
  case kTimeFormatSecondsForce24Hour:
    dwFlags_Time = TIME_FORCE24HOURFORMAT;
    break;
  case kTimeFormatNoSecondsForce24Hour:
    dwFlags_Time = TIME_NOSECONDS + TIME_FORCE24HOURFORMAT;
    break;
  }

  // Call GetDateFormatW
  if (dateFormatSelector == kDateFormatNone) {
    dateLen = 0;
  }
  else {
    if (dateFormatSelector == kDateFormatYearMonth) {
      dateLen = nsGetDateFormatW(0, &system_time, "yyyy/MM", 
                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
    }
    else if (dateFormatSelector == kDateFormatWeekday) {
      dateLen = nsGetDateFormatW(0, &system_time, "ddd", 
                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
    }
    else {
      dateLen = nsGetDateFormatW(dwFlags_Date, &system_time, NULL, 
                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
    }
    if (dateLen != 0) {
      dateLen--;  // Since the count includes the terminating null.
    }
  }

  // Call GetTimeFormatW
  if (timeFormatSelector == kTimeFormatNone) {
    timeLen = 0;
  }
  else {
    timeLen = nsGetTimeFormatW(dwFlags_Time, &system_time, NULL, 
                               timeBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
    if (timeLen != 0) {
      timeLen--;  // Since the count includes the terminating null.
    }
  }

  NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (dateLen + 1), "internal date buffer is not large enough");
  NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (timeLen + 1), "internal time buffer is not large enough");

  // Copy the result
  stringOut.Truncate();
  if (dateLen != 0 && timeLen != 0) {
    stringOut.Assign(dateBuffer, dateLen);
    stringOut.Append((PRUnichar *)(L" "), 1);
    stringOut.Append(timeBuffer, timeLen);
  }
  else if (dateLen != 0 && timeLen == 0) {
    stringOut.Assign(dateBuffer, dateLen);
  }
  else if (dateLen == 0 && timeLen != 0) {
    stringOut.Assign(timeBuffer, timeLen);
  }

  return NS_OK;
}
/*
 * Converts the value of the given double to a String, and places
 * The result into the destination String.
 * @return the given dest string
 */
void Double::toString(double aValue, nsAString& aDest)
{

    // check for special cases

    if (isNaN(aValue)) {
        aDest.AppendLiteral("NaN");
        return;
    }
    if (isInfinite(aValue)) {
        if (aValue < 0)
            aDest.Append(PRUnichar('-'));
        aDest.AppendLiteral("Infinity");
        return;
    }

    // Mantissa length is 17, so this is plenty
    const int buflen = 20;
    char buf[buflen];

    PRIntn intDigits, sign;
    char* endp;
    PR_dtoa(aValue, 0, 0, &intDigits, &sign, &endp, buf, buflen - 1);

    // compute length
    PRInt32 length = endp - buf;
    if (length > intDigits) {
        // decimal point needed
        ++length;
        if (intDigits < 1) {
            // leading zeros, -intDigits + 1
            length += 1 - intDigits;
        }
    }
    else {
        // trailing zeros, total length given by intDigits
        length = intDigits;
    }
    if (aValue < 0)
        ++length;
    // grow the string
    PRUint32 oldlength = aDest.Length();
    if (!EnsureStringLength(aDest, oldlength + length))
        return; // out of memory
    nsAString::iterator dest;
    aDest.BeginWriting(dest).advance(PRInt32(oldlength));
    if (aValue < 0) {
        *dest = '-'; ++dest;
    }
    int i;
    // leading zeros
    if (intDigits < 1) {
        *dest = '0'; ++dest;
        *dest = '.'; ++dest;
        for (i = 0; i > intDigits; --i) {
            *dest = '0'; ++dest;
        }
    }
    // mantissa
    int firstlen = PR_MIN(intDigits, endp - buf);
    for (i = 0; i < firstlen; i++) {
        *dest = buf[i]; ++dest;
    }
    if (i < endp - buf) {
        if (i > 0) {
            *dest = '.'; ++dest;
        }
        for (; i < endp - buf; i++) {
            *dest = buf[i]; ++dest;
        }
    }
    // trailing zeros
    for (; i < intDigits; i++) {
        *dest = '0'; ++dest;
    }
}
Example #17
0
nsresult
txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
                          Expr* aFormat, txIEvalContext* aContext,
                          txList& aCounters, nsAString& aHead,
                          nsAString& aTail)
{
    aHead.Truncate();
    aTail.Truncate();

    nsresult rv = NS_OK;

    nsAutoString groupSeparator;
    PRInt32 groupSize = 0;
    if (aGroupSize && aGroupSeparator) {
        nsAutoString sizeStr;
        rv = aGroupSize->evaluateToString(aContext, sizeStr);
        NS_ENSURE_SUCCESS(rv, rv);

        double size = Double::toDouble(sizeStr);
        groupSize = (PRInt32)size;
        if ((double)groupSize != size) {
            groupSize = 0;
        }

        rv = aGroupSeparator->evaluateToString(aContext, groupSeparator);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    nsAutoString format;
    if (aFormat) {
        rv = aFormat->evaluateToString(aContext, format);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    PRUint32 formatLen = format.Length();
    PRUint32 formatPos = 0;
    PRUnichar ch = 0;

    // start with header
    while (formatPos < formatLen &&
           !isAlphaNumeric(ch = format.CharAt(formatPos))) {
        aHead.Append(ch);
        ++formatPos;
    }

    // If there are no formatting tokens we need to create a default one.
    if (formatPos == formatLen) {
        txFormattedCounter* defaultCounter;
        rv = txFormattedCounter::getCounterFor(NS_LITERAL_STRING("1"), groupSize,
                                               groupSeparator, defaultCounter);
        NS_ENSURE_SUCCESS(rv, rv);

        defaultCounter->mSeparator.AssignLiteral(".");
        rv = aCounters.add(defaultCounter);
        if (NS_FAILED(rv)) {
            // XXX ErrorReport: out of memory
            delete defaultCounter;
            return rv;
        }

        return NS_OK;
    }

    while (formatPos < formatLen) {
        nsAutoString sepToken;
        // parse separator token
        if (!aCounters.getLength()) {
            // Set the first counters separator to default value so that if
            // there is only one formatting token and we're formatting a
            // value-list longer then one we use the default separator. This
            // won't be used when formatting the first value anyway.
            sepToken.AssignLiteral(".");
        }
        else {
            while (formatPos < formatLen &&
                   !isAlphaNumeric(ch = format.CharAt(formatPos))) {
                sepToken.Append(ch);
                ++formatPos;
            }
        }

        // if we're at the end of the string then the previous token was the tail
        if (formatPos == formatLen) {
            aTail = sepToken;
            return NS_OK;
        }

        // parse formatting token
        nsAutoString numToken;
        while (formatPos < formatLen &&
               isAlphaNumeric(ch = format.CharAt(formatPos))) {
            numToken.Append(ch);
            ++formatPos;
        }
        
        txFormattedCounter* counter = 0;
        rv = txFormattedCounter::getCounterFor(numToken, groupSize,
                                               groupSeparator, counter);
        if (NS_FAILED(rv)) {
            txListIterator iter(&aCounters);
            while (iter.hasNext()) {
                delete (txFormattedCounter*)iter.next();
            }
            aCounters.clear();
            return rv;
        }

        // Add to list of counters
        counter->mSeparator = sepToken;
        rv = aCounters.add(counter);
        if (NS_FAILED(rv)) {
            // XXX ErrorReport: out of memory
            txListIterator iter(&aCounters);
            while (iter.hasNext()) {
                delete (txFormattedCounter*)iter.next();
            }
            aCounters.clear();
            return rv;
        }
    }
    
    return NS_OK;
}
Example #18
0
void
FileSystemBase::GetDOMPath(nsIFile* aFile,
                           nsAString& aRetval,
                           ErrorResult& aRv) const
{
  AssertIsOnOwningThread();
  MOZ_ASSERT(aFile);

  aRetval.Truncate();

  nsCOMPtr<nsIFile> fileSystemPath;
  aRv = NS_NewLocalFile(LocalOrDeviceStorageRootPath(),
                        true, getter_AddRefs(fileSystemPath));
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  nsCOMPtr<nsIFile> path;
  aRv = aFile->Clone(getter_AddRefs(path));
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  nsTArray<nsString> parts;

  while (true) {
    nsAutoString leafName;
    aRv = path->GetLeafName(leafName);
    if (NS_WARN_IF(aRv.Failed())) {
      return;
    }

    if (!leafName.IsEmpty()) {
      parts.AppendElement(leafName);
    }

    bool equal = false;
    aRv = fileSystemPath->Equals(path, &equal);
    if (NS_WARN_IF(aRv.Failed())) {
      return;
    }

    if (equal) {
      break;
    }

    nsCOMPtr<nsIFile> parentPath;
    aRv = path->GetParent(getter_AddRefs(parentPath));
    if (NS_WARN_IF(aRv.Failed())) {
      return;
    }

    MOZ_ASSERT(parentPath);

    aRv = parentPath->Clone(getter_AddRefs(path));
    if (NS_WARN_IF(aRv.Failed())) {
      return;
    }
  }

  if (parts.IsEmpty()) {
    aRetval.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
    return;
  }

  for (int32_t i = parts.Length() - 1; i >= 0; --i) {
    aRetval.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
    aRetval.Append(parts[i]);
  }
}
Example #19
0
NS_IMETHODIMP
nsInternetCiter::Rewrap(const nsAString& aInString,
                        PRUint32 aWrapCol, PRUint32 aFirstLineOffset,
                        PRBool aRespectNewlines,
                        nsAString& aOutString)
{
  // There shouldn't be returns in this string, only dom newlines.
  // Check to make sure:
#ifdef DEBUG
  PRInt32 cr = aInString.FindChar(PRUnichar('\r'));
  NS_ASSERTION((cr < 0), "Rewrap: CR in string gotten from DOM!\n");
#endif /* DEBUG */

  aOutString.Truncate();

  nsCOMPtr<nsILineBreaker> lineBreaker;
  nsILineBreakerFactory *lf;
  nsresult rv;
  rv = CallGetService(NS_LWBRK_CONTRACTID, &lf);
  if (NS_SUCCEEDED(rv))
  {
    nsAutoString lbarg;
    lf->GetBreaker(lbarg, getter_AddRefs(lineBreaker));
    NS_RELEASE(lf);
  }

  // Loop over lines in the input string, rewrapping each one.
  PRUint32 length;
  PRUint32 posInString = 0;
  PRUint32 outStringCol = 0;
  PRUint32 citeLevel = 0;
  const nsPromiseFlatString &tString = PromiseFlatString(aInString);
  length = tString.Length();
#ifdef DEBUG_wrapping
  int loopcount = 0;
#endif
  while (posInString < length)
  {
#ifdef DEBUG_wrapping
    printf("Outer loop: '%s'\n",
           NS_LossyConvertUCS2toASCII(Substring(tString, posInString,
                                                length-posInString)).get());
    printf("out string is now: '%s'\n",
           NS_LossyConvertUCS2toASCII(aOutString).get());

#endif

    // Get the new cite level here since we're at the beginning of a line
    PRUint32 newCiteLevel = 0;
    while (posInString < length && tString[posInString] == gt)
    {
      ++newCiteLevel;
      ++posInString;
      while (posInString < length && tString[posInString] == space)
        ++posInString;
    }
    if (posInString >= length)
      break;

    // Special case: if this is a blank line, maintain a blank line
    // (retain the original paragraph breaks)
    if (tString[posInString] == nl && !aOutString.IsEmpty())
    {
      if (aOutString.Last() != nl)
        aOutString.Append(nl);
      AddCite(aOutString, newCiteLevel);
      aOutString.Append(nl);

      ++posInString;
      outStringCol = 0;
      continue;
    }

    // If the cite level has changed, then start a new line with the
    // new cite level (but if we're at the beginning of the string,
    // don't bother).
    if (newCiteLevel != citeLevel && posInString > newCiteLevel+1
        && outStringCol != 0)
    {
      BreakLine(aOutString, outStringCol, 0);
    }
    citeLevel = newCiteLevel;

    // Prepend the quote level to the out string if appropriate
    if (outStringCol == 0)
    {
      AddCite(aOutString, citeLevel);
      outStringCol = citeLevel + (citeLevel ? 1 : 0);
    }
    // If it's not a cite, and we're not at the beginning of a line in
    // the output string, add a space to separate new text from the
    // previous text.
    else if (outStringCol > citeLevel)
    {
      aOutString.Append(space);
      ++outStringCol;
    }

    // find the next newline -- don't want to go farther than that
    PRInt32 nextNewline = tString.FindChar(nl, posInString);
    if (nextNewline < 0) nextNewline = length;

    // For now, don't wrap unquoted lines at all.
    // This is because the plaintext edit window has already wrapped them
    // by the time we get them for rewrap, yet when we call the line
    // breaker, it will refuse to break backwards, and we'll end up
    // with a line that's too long and gets displayed as a lone word
    // on a line by itself.  Need special logic to detect this case
    // and break it ourselves without resorting to the line breaker.
    if (citeLevel == 0)
    {
      aOutString.Append(Substring(tString, posInString,
                                  nextNewline-posInString));
      outStringCol += nextNewline - posInString;
      if (nextNewline != (PRInt32)length)
      {
        aOutString.Append(nl);
        outStringCol = 0;
      }
      posInString = nextNewline+1;
      continue;
    }

    // Otherwise we have to use the line breaker and loop
    // over this line of the input string to get all of it:
    while ((PRInt32)posInString < nextNewline)
    {
#ifdef DEBUG_wrapping
      if (++loopcount > 1000)
        NS_ASSERTION(PR_FALSE, "possible infinite loop in nsInternetCiter\n");

      printf("Inner loop: '%s'\n",
             NS_LossyConvertUCS2toASCII(Substring(tString, posInString,
                                              nextNewline-posInString)).get());
#endif

      // Skip over initial spaces:
      while ((PRInt32)posInString < nextNewline
             && nsCRT::IsAsciiSpace(tString[posInString]))
        ++posInString;

      // If this is a short line, just append it and continue:
      if (outStringCol + nextNewline - posInString <= aWrapCol-citeLevel-1)
      {
        // If this short line is the final one in the in string,
        // then we need to include the final newline, if any:
        if (nextNewline+1 == (PRInt32)length && tString[nextNewline-1] == nl)
          ++nextNewline;

        // Trim trailing spaces:
        PRInt32 lastRealChar = nextNewline;
        while ((PRUint32)lastRealChar > posInString
               && nsCRT::IsAsciiSpace(tString[lastRealChar-1]))
          --lastRealChar;

        aOutString += Substring(tString,
                                posInString, lastRealChar - posInString);
        outStringCol += lastRealChar - posInString;
        posInString = nextNewline + 1;
        continue;
      }

      PRInt32 eol = posInString + aWrapCol - citeLevel - outStringCol;
      // eol is the prospective end of line.
      // We'll first look backwards from there for a place to break.
      // If it's already less than our current position,
      // then our line is already too long, so break now.
      if (eol <= (PRInt32)posInString)
      {
        BreakLine(aOutString, outStringCol, citeLevel);
        continue;    // continue inner loop, with outStringCol now at bol
      }

      PRUint32 breakPt;
      rv = NS_ERROR_BASE;
      if (lineBreaker)
      {
        PRBool needMore;
        rv = lineBreaker->Prev(tString.get() + posInString,
                               length - posInString,
                               eol + 1 - posInString, &breakPt, &needMore);
        if (NS_FAILED(rv) || needMore)
        {
          // if we couldn't find a breakpoint looking backwards,
          // and we're not starting a new line, then end this line
          // and loop around again:
          if (outStringCol > citeLevel + 1)
          {
            BreakLine(aOutString, outStringCol, citeLevel);
            continue;    // continue inner loop, with outStringCol now at bol
          }

          // Else try looking forwards:
          rv = lineBreaker->Next(tString.get() + posInString,
                                 length - posInString,
                                 eol - posInString, &breakPt, &needMore);
          if (needMore) rv = NS_ERROR_BASE;
        }
      }
      // If rv is okay, then breakPt is the place to break.
      // If we get out here and rv is set, something went wrong with line
      // breaker.  Just break the line, hard.
      if (NS_FAILED(rv))
      {
#ifdef DEBUG_akkana
        printf("nsInternetCiter: LineBreaker not working -- breaking hard\n");
#endif
        breakPt = eol;
      }

      // Special case: maybe we should have wrapped last time.
      // If the first breakpoint here makes the current line too long,
      // then if we already have text on the current line,
      // break and loop around again.
      // If we're at the beginning of the current line, though,
      // don't force a break since the long word might be a url
      // and breaking it would make it unclickable on the other end.
      const int SLOP = 6;
      if (outStringCol + breakPt > aWrapCol + SLOP
          && outStringCol > citeLevel+1)
      {
        BreakLine(aOutString, outStringCol, citeLevel);
        continue;
      }

      nsAutoString sub (Substring(tString, posInString, breakPt));
      // skip newlines or whitespace at the end of the string
      PRInt32 subend = sub.Length();
      while (subend > 0 && IsSpace(sub[subend-1]))
        --subend;
      sub.Left(sub, subend);
      aOutString += sub;
      outStringCol += sub.Length();
      // Advance past the whitespace which caused the wrap:
      posInString += breakPt;
      while (posInString < length && IsSpace(tString[posInString]))
        ++posInString;

      // Add a newline and the quote level to the out string
      if (posInString < length)    // not for the last line, though
        BreakLine(aOutString, outStringCol, citeLevel);

    } // end inner loop within one line of aInString
#ifdef DEBUG_wrapping
    printf("---------\nEnd inner loop: out string is now '%s'\n-----------\n",
           NS_LossyConvertUCS2toASCII(aOutString).get());
#endif
  } // end outer loop over lines of aInString

#ifdef DEBUG_wrapping
  printf("Final out string is now: '%s'\n",
         NS_LossyConvertUCS2toASCII(aOutString).get());

#endif
  return NS_OK;
}
void
nsAttrValue::ToString(nsAString& aResult) const
{
  switch(Type()) {
    case eString:
    {
      nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
      if (str) {
        str->ToString(str->StorageSize()/sizeof(PRUnichar) - 1, aResult);
      }
      else {
        aResult.Truncate();
      }
      break;
    }
    case eAtom:
    {
      nsIAtom *atom = static_cast<nsIAtom*>(GetPtr());
      atom->ToString(aResult);

      break;
    }
    case eInteger:
    {
      nsAutoString intStr;
      intStr.AppendInt(GetIntInternal());
      aResult = intStr;

      break;
    }
    case eColor:
    {
      nscolor v;
      GetColorValue(v);
      NS_RGBToHex(v, aResult);

      break;
    }
    case eEnum:
    {
      PRInt16 val = GetEnumValue();
      const EnumTable* table = sEnumTableArray->
          ElementAt(GetIntInternal() & NS_ATTRVALUE_ENUMTABLEINDEX_MASK);
      while (table->tag) {
        if (table->value == val) {
          aResult.AssignASCII(table->tag);

          return;
        }
        table++;
      }

      NS_NOTREACHED("couldn't find value in EnumTable");

      break;
    }
    case ePercent:
    {
      nsAutoString intStr;
      intStr.AppendInt(GetIntInternal());
      aResult = intStr + NS_LITERAL_STRING("%");

      break;
    }
    case eCSSStyleRule:
    {
      aResult.Truncate();
      MiscContainer *container = GetMiscContainer();
      nsCSSDeclaration* decl = container->mCSSStyleRule->GetDeclaration();
      if (decl) {
        decl->ToString(aResult);
      }

      break;
    }
    case eAtomArray:
    {
      MiscContainer* cont = GetMiscContainer();
      PRInt32 count = cont->mAtomArray->Count();
      if (count) {
        cont->mAtomArray->ObjectAt(0)->ToString(aResult);
        nsAutoString tmp;
        PRInt32 i;
        for (i = 1; i < count; ++i) {
          cont->mAtomArray->ObjectAt(i)->ToString(tmp);
          aResult.Append(NS_LITERAL_STRING(" ") + tmp);
        }
      }
      else {
        aResult.Truncate();
      }
      break;
    }
#ifdef MOZ_SVG
    case eSVGValue:
    {
      GetMiscContainer()->mSVGValue->GetValueString(aResult);
    }
#endif
  }
}
bool
nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
                                    nsAString& aSanitized,
                                    nsIDocument* aDocument,
                                    nsIURI* aBaseURI)
{
  nsresult rv;
  aSanitized.Truncate();
  // aSanitized will hold the permitted CSS text.
  // -moz-binding is blacklisted.
  bool didSanitize = false;
  // Create a sheet to hold the parsed CSS
  nsRefPtr<nsCSSStyleSheet> sheet;
  rv = NS_NewCSSStyleSheet(getter_AddRefs(sheet));
  NS_ENSURE_SUCCESS(rv, true);
  sheet->SetURIs(aDocument->GetDocumentURI(), nsnull, aBaseURI);
  sheet->SetPrincipal(aDocument->NodePrincipal());
  // Create the CSS parser, and parse the CSS text.
  nsCSSParser parser(nsnull, sheet);
  rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
                         aDocument->NodePrincipal(), 0, false);
  NS_ENSURE_SUCCESS(rv, true);
  // Mark the sheet as complete.
  NS_ABORT_IF_FALSE(!sheet->IsModified(),
      "should not get marked modified during parsing");
  sheet->SetComplete();
  // Loop through all the rules found in the CSS text
  PRInt32 ruleCount = sheet->StyleRuleCount();
  for (PRInt32 i = 0; i < ruleCount; ++i) {
    nsRefPtr<mozilla::css::Rule> rule;
    rv = sheet->GetStyleRuleAt(i, *getter_AddRefs(rule));
    if (NS_FAILED(rv))
      continue; NS_ASSERTION(rule, "We should have a rule by now");
    switch (rule->GetType()) {
      default:
        didSanitize = true;
        // Ignore these rule types.
        break;
      case mozilla::css::Rule::NAMESPACE_RULE:
      case mozilla::css::Rule::FONT_FACE_RULE: {
        // Append @namespace and @font-face rules verbatim.
        nsAutoString cssText;
        nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule);
        if (styleRule) {
          rv = styleRule->GetCssText(cssText);
          if (NS_SUCCEEDED(rv)) {
            aSanitized.Append(cssText);
          }
        }
        break;
      }
      case mozilla::css::Rule::STYLE_RULE: {
        // For style rules, we will just look for and remove the
        // -moz-binding properties.
        nsRefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule);
        NS_ASSERTION(styleRule, "Must be a style rule");
        nsAutoString decl;
        bool sanitized = SanitizeStyleRule(styleRule, decl);
        didSanitize = sanitized || didSanitize;
        if (!sanitized) {
          styleRule->GetCssText(decl);
        }
        aSanitized.Append(decl);
      }
    }
  }
  return didSanitize;
}
void
nsXHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
                                                     nsAString& aOutputStr)
{
  if (mBodyOnly && !mInBody) {
    return;
  }

  if (mDisableEntityEncoding) {
    aOutputStr.Append(aStr);
    return;
  }

  if (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities  |
                nsIDocumentEncoder::OutputEncodeLatin1Entities |
                nsIDocumentEncoder::OutputEncodeHTMLEntities   |
                nsIDocumentEncoder::OutputEncodeW3CEntities)) {
    nsIParserService* parserService = nsContentUtils::GetParserService();

    if (!parserService) {
      NS_ERROR("Can't get parser service");
      return;
    }

    nsReadingIterator<PRUnichar> done_reading;
    aStr.EndReading(done_reading);

    // for each chunk of |aString|...
    PRUint32 advanceLength = 0;
    nsReadingIterator<PRUnichar> iter;

    const char **entityTable = mInAttribute ? kAttrEntities : kEntities;

    for (aStr.BeginReading(iter);
          iter != done_reading;
          iter.advance(PRInt32(advanceLength))) {
      PRUint32 fragmentLength = iter.size_forward();
      PRUint32 lengthReplaced = 0; // the number of UTF-16 codepoints
                                    //  replaced by a particular entity
      const PRUnichar* c = iter.get();
      const PRUnichar* fragmentStart = c;
      const PRUnichar* fragmentEnd = c + fragmentLength;
      const char* entityText = nsnull;
      nsCAutoString entityReplacement;
      char* fullEntityText = nsnull;

      advanceLength = 0;
      // for each character in this chunk, check if it
      // needs to be replaced
      for (; c < fragmentEnd; c++, advanceLength++) {
        PRUnichar val = *c;
        if (val == kValNBSP) {
          entityText = kEntityNBSP;
          break;
        }
        else if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
          entityText = entityTable[val];
          break;
        } else if (val > 127 &&
                  ((val < 256 &&
                    mFlags & nsIDocumentEncoder::OutputEncodeLatin1Entities) ||
                    mFlags & nsIDocumentEncoder::OutputEncodeHTMLEntities)) {
          parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);

          if (!entityReplacement.IsEmpty()) {
            entityText = entityReplacement.get();
            break;
          }
        }
        else if (val > 127 &&
                  mFlags & nsIDocumentEncoder::OutputEncodeW3CEntities &&
                  mEntityConverter) {
          if (NS_IS_HIGH_SURROGATE(val) &&
              c + 1 < fragmentEnd &&
              NS_IS_LOW_SURROGATE(*(c + 1))) {
            PRUint32 valUTF32 = SURROGATE_TO_UCS4(val, *(++c));
            if (NS_SUCCEEDED(mEntityConverter->ConvertUTF32ToEntity(valUTF32,
                              nsIEntityConverter::entityW3C, &fullEntityText))) {
              lengthReplaced = 2;
              break;
            }
            else {
              advanceLength++;
            }
          }
          else if (NS_SUCCEEDED(mEntityConverter->ConvertToEntity(val,
                                nsIEntityConverter::entityW3C, 
                                &fullEntityText))) {
            lengthReplaced = 1;
            break;
          }
        }
      }

      aOutputStr.Append(fragmentStart, advanceLength);
      if (entityText) {
        aOutputStr.Append(PRUnichar('&'));
        AppendASCIItoUTF16(entityText, aOutputStr);
        aOutputStr.Append(PRUnichar(';'));
        advanceLength++;
      }
      // if it comes from nsIEntityConverter, it already has '&' and ';'
      else if (fullEntityText) {
        AppendASCIItoUTF16(fullEntityText, aOutputStr);
        nsMemory::Free(fullEntityText);
        advanceLength += lengthReplaced;
      }
    }
  } else {
    nsXMLContentSerializer::AppendAndTranslateEntities(aStr, aOutputStr);
  }
}
Example #23
0
void
TextLeafAccessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
                                 uint32_t aLength)
{
  aText.Append(Substring(mText, aStartOffset, aLength));
}
nsresult
nsMsgSearchAdapter::GetSearchCharsets(nsAString &srcCharset, nsAString &dstCharset)
{
  nsresult rv;

  if (m_defaultCharset.IsEmpty())
  {
    m_forceAsciiSearch = PR_FALSE;  // set the default value in case of error
    nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
    if (NS_SUCCEEDED(rv))
    {
      nsCOMPtr<nsIPrefLocalizedString> localizedstr;
      rv = prefs->GetComplexValue("mailnews.view_default_charset", NS_GET_IID(nsIPrefLocalizedString),
                                  getter_AddRefs(localizedstr));
      if (NS_SUCCEEDED(rv))
        localizedstr->GetData(getter_Copies(m_defaultCharset));

      prefs->GetBoolPref("mailnews.force_ascii_search", &m_forceAsciiSearch);
    }
  }
  srcCharset = m_defaultCharset.IsEmpty() ?
    NS_LITERAL_STRING("ISO-8859-1") : m_defaultCharset;

  if (m_scope)
  {
    // ### DMB is there a way to get the charset for the "window"?

    nsCOMPtr<nsIMsgFolder> folder;
    rv = m_scope->GetFolder(getter_AddRefs(folder));

    // Ask the newsgroup/folder for its csid.
    if (NS_SUCCEEDED(rv) && folder)
    {
      nsCString folderCharset;
      folder->GetCharset(folderCharset);
      dstCharset.Append(NS_ConvertASCIItoUTF16(folderCharset));
    }
  }
  else
    dstCharset.Assign(srcCharset);

  // If
  // the destination is still CS_DEFAULT, make the destination match
  // the source. (CS_DEFAULT is an indication that the charset
  // was undefined or unavailable.)
  // ### well, it's not really anymore. Is there an equivalent?
  if (dstCharset.Equals(m_defaultCharset))
  {
    dstCharset.Assign(srcCharset);
  }

  if (m_forceAsciiSearch)
  {
    // Special cases to use in order to force US-ASCII searching with Latin1
    // or MacRoman text. Eurgh. This only has to happen because IMAP
    // and Dredd servers currently (4/23/97) only support US-ASCII.
    //
    // If the dest csid is ISO Latin 1 or MacRoman, attempt to convert the
    // source text to US-ASCII. (Not for now.)
    // if ((dst_csid == CS_LATIN1) || (dst_csid == CS_MAC_ROMAN))
    dstCharset.AssignLiteral("us-ascii");
  }

  return NS_OK;
}
nsresult
nsXHTMLContentSerializer::EscapeURI(nsIContent* aContent, const nsAString& aURI, nsAString& aEscapedURI)
{
  // URL escape %xx cannot be used in JS.
  // No escaping if the scheme is 'javascript'.
  if (IsJavaScript(aContent, nsGkAtoms::href, kNameSpaceID_None, aURI)) {
    aEscapedURI = aURI;
    return NS_OK;
  }

  // nsITextToSubURI does charset convert plus uri escape
  // This is needed to convert to a document charset which is needed to support existing browsers.
  // But we eventually want to use UTF-8 instead of a document charset, then the code would be much simpler.
  // See HTML 4.01 spec, "Appendix B.2.1 Non-ASCII characters in URI attribute values"
  nsCOMPtr<nsITextToSubURI> textToSubURI;
  nsAutoString uri(aURI); // in order to use FindCharInSet()
  nsresult rv = NS_OK;

  if (!mCharset.IsEmpty() && !IsASCII(uri)) {
    textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  int32_t start = 0;
  int32_t end;
  nsAutoString part;
  nsXPIDLCString escapedURI;
  aEscapedURI.Truncate(0);

  // Loop and escape parts by avoiding escaping reserved characters
  // (and '%', '#', as well as '[' and ']' for IPv6 address literals).
  while ((end = uri.FindCharInSet("%#;/?:@&=+$,[]", start)) != -1) {
    part = Substring(aURI, start, (end-start));
    if (textToSubURI && !IsASCII(part)) {
      rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI));
      NS_ENSURE_SUCCESS(rv, rv);
    } else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI,
                                     url_Path))) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    AppendASCIItoUTF16(escapedURI, aEscapedURI);

    // Append a reserved character without escaping.
    part = Substring(aURI, end, 1);
    aEscapedURI.Append(part);
    start = end + 1;
  }

  if (start < (int32_t) aURI.Length()) {
    // Escape the remaining part.
    part = Substring(aURI, start, aURI.Length()-start);
    if (textToSubURI) {
      rv = textToSubURI->ConvertAndEscape(mCharset.get(), part.get(), getter_Copies(escapedURI));
      NS_ENSURE_SUCCESS(rv, rv);
    } else if (NS_WARN_IF(!NS_Escape(NS_ConvertUTF16toUTF8(part), escapedURI,
                                     url_Path))) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    AppendASCIItoUTF16(escapedURI, aEscapedURI);
  }

  return rv;
}
Example #26
0
/**
 * @update	harishd 3/23/00
 * @return  reference to string containing string value
 */
void CToken::AppendSourceTo(nsAString& anOutputString) {
  anOutputString.Append(GetStringValue());
}
Example #27
0
/*
 * Converts the value of the given double to a String, and places
 * The result into the destination String.
 * @return the given dest string
 */
void txDouble::toString(double aValue, nsAString& aDest)
{

    // check for special cases

    if (MOZ_DOUBLE_IS_NaN(aValue)) {
        aDest.AppendLiteral("NaN");
        return;
    }
    if (MOZ_DOUBLE_IS_INFINITE(aValue)) {
        if (aValue < 0)
            aDest.Append(PRUnichar('-'));
        aDest.AppendLiteral("Infinity");
        return;
    }

    // Mantissa length is 17, so this is plenty
    const int buflen = 20;
    char buf[buflen];

    int intDigits, sign;
    char* endp;
    PR_dtoa(aValue, 0, 0, &intDigits, &sign, &endp, buf, buflen - 1);

    // compute length
    int32_t length = endp - buf;
    if (length > intDigits) {
        // decimal point needed
        ++length;
        if (intDigits < 1) {
            // leading zeros, -intDigits + 1
            length += 1 - intDigits;
        }
    }
    else {
        // trailing zeros, total length given by intDigits
        length = intDigits;
    }
    if (aValue < 0)
        ++length;
    // grow the string
    uint32_t oldlength = aDest.Length();
    if (!aDest.SetLength(oldlength + length, mozilla::fallible_t()))
        return; // out of memory
    nsAString::iterator dest;
    aDest.BeginWriting(dest).advance(int32_t(oldlength));
    if (aValue < 0) {
        *dest = '-'; ++dest;
    }
    int i;
    // leading zeros
    if (intDigits < 1) {
        *dest = '0'; ++dest;
        *dest = '.'; ++dest;
        for (i = 0; i > intDigits; --i) {
            *dest = '0'; ++dest;
        }
    }
    // mantissa
    int firstlen = std::min<size_t>(intDigits, endp - buf);
    for (i = 0; i < firstlen; i++) {
        *dest = buf[i]; ++dest;
    }
    if (i < endp - buf) {
        if (i > 0) {
            *dest = '.'; ++dest;
        }
        for (; i < endp - buf; i++) {
            *dest = buf[i]; ++dest;
        }
    }
    // trailing zeros
    for (; i < intDigits; i++) {
        *dest = '0'; ++dest;
    }
}
Example #28
0
NS_IMETHODIMP nsMsgGroupView::CellTextForColumn(int32_t aRow,
                                                const char16_t *aColumnName,
                                                nsAString &aValue) {
  if (!IsValidIndex(aRow))
    return NS_MSG_INVALID_DBVIEW_INDEX;

  if (m_flags[aRow] & MSG_VIEW_FLAG_DUMMY && aColumnName[0] != 'u')
  {
    nsCOMPtr <nsIMsgDBHdr> msgHdr;
    nsresult rv = GetMsgHdrForViewIndex(aRow, getter_AddRefs(msgHdr));
    NS_ENSURE_SUCCESS(rv, rv);
    nsString hashKey;
    rv = HashHdr(msgHdr, hashKey);
    if (NS_FAILED(rv))
      return NS_OK;
    nsCOMPtr<nsIMsgThread> msgThread;
    m_groupsTable.Get(hashKey, getter_AddRefs(msgThread));
    nsMsgGroupThread * groupThread = static_cast<nsMsgGroupThread *>(msgThread.get());
    if (aColumnName[0] == 's'  && aColumnName[1] == 'u' )
    {
      uint32_t flags;
      bool rcvDate = false;
      msgHdr->GetFlags(&flags);
      aValue.Truncate();
      nsString tmp_str;
      switch (m_sortType)
      {
        case nsMsgViewSortType::byReceived:
          rcvDate = true;
        case nsMsgViewSortType::byDate:
        {
          uint32_t ageBucket = 0;
          GetAgeBucketValue(msgHdr, &ageBucket, rcvDate);
          switch (ageBucket)
          {
          case 1:
            if (m_kTodayString.IsEmpty())
              m_kTodayString.Adopt(GetString(MOZ_UTF16("today")));
            aValue.Assign(m_kTodayString);
            break;
          case 2:
            if (m_kYesterdayString.IsEmpty())
              m_kYesterdayString.Adopt(GetString(MOZ_UTF16("yesterday")));
            aValue.Assign(m_kYesterdayString);
            break;
          case 3:
            if (m_kLastWeekString.IsEmpty())
              m_kLastWeekString.Adopt(GetString(MOZ_UTF16("lastWeek")));
            aValue.Assign(m_kLastWeekString);
            break;
          case 4:
            if (m_kTwoWeeksAgoString.IsEmpty())
              m_kTwoWeeksAgoString.Adopt(GetString(MOZ_UTF16("twoWeeksAgo")));
            aValue.Assign(m_kTwoWeeksAgoString);
            break;
          case 5:
            if (m_kOldMailString.IsEmpty())
              m_kOldMailString.Adopt(GetString(MOZ_UTF16("older")));
            aValue.Assign(m_kOldMailString);
            break;
          default:
            NS_ASSERTION(false, "bad age thread");
            break;
          }
          break;
        }
        case nsMsgViewSortType::bySubject:
          FetchSubject(msgHdr, m_flags[aRow], aValue);
          break;
        case nsMsgViewSortType::byAuthor:
          FetchAuthor(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byStatus:
          rv = FetchStatus(m_flags[aRow], aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(MOZ_UTF16("messagesWithNoStatus")));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byTags:
          rv = FetchTags(msgHdr, aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(MOZ_UTF16("untaggedMessages")));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byPriority:
          FetchPriority(msgHdr, aValue);
          if (aValue.IsEmpty()) {
            tmp_str.Adopt(GetString(MOZ_UTF16("noPriority")));
            aValue.Assign(tmp_str);
          }
          break;
        case nsMsgViewSortType::byAccount:
          FetchAccount(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byRecipient:
          FetchRecipients(msgHdr, aValue);
          break;
        case nsMsgViewSortType::byAttachments:
          tmp_str.Adopt(GetString(flags & nsMsgMessageFlags::Attachment ?
            MOZ_UTF16("attachments") : MOZ_UTF16("noAttachments")));
          aValue.Assign(tmp_str);
          break;
        case nsMsgViewSortType::byFlagged:
          tmp_str.Adopt(GetString(flags & nsMsgMessageFlags::Marked ?
            MOZ_UTF16("groupFlagged") : MOZ_UTF16("notFlagged")));
          aValue.Assign(tmp_str);
          break;
        // byLocation is a special case; we don't want to have duplicate
        //  all this logic in nsMsgSearchDBView, and its hash key is what we
        //  want anyways, so just copy it across.
        case nsMsgViewSortType::byLocation:
        case nsMsgViewSortType::byCorrespondent:
          aValue = hashKey;
          break;
        case nsMsgViewSortType::byCustom:
        {
          nsIMsgCustomColumnHandler* colHandler =
            GetCurColumnHandlerFromDBInfo();
          if (colHandler)
          {
            rv = colHandler->GetSortStringForRow(msgHdr.get(), aValue);
            break;
          }
        }

        default:
          NS_ASSERTION(false, "we don't sort by group for this type");
          break;
      }

      if (groupThread)
      {
        // Get number of messages in group
        nsAutoString formattedCountMsg;
        uint32_t numMsg = groupThread->NumRealChildren();
        formattedCountMsg.AppendInt(numMsg);

        // Get number of unread messages
        nsAutoString formattedCountUnrMsg;
        uint32_t numUnrMsg = 0;
        groupThread->GetNumUnreadChildren(&numUnrMsg);
        formattedCountUnrMsg.AppendInt(numUnrMsg);

        // Add text to header
        aValue.Append(NS_LITERAL_STRING(" ("));
        if (numUnrMsg)
        {
          aValue.Append(formattedCountUnrMsg);
          aValue.Append(NS_LITERAL_STRING("/"));
        }

        aValue.Append(formattedCountMsg);
        aValue.Append(NS_LITERAL_STRING(")"));
      }
    }
    else if (aColumnName[0] == 't' && aColumnName[1] == 'o')
    {
      nsAutoString formattedCountString;
      uint32_t numChildren = (groupThread) ? groupThread->NumRealChildren() : 0;
      formattedCountString.AppendInt(numChildren);
      aValue.Assign(formattedCountString);
    }
    return NS_OK;
  }
  return nsMsgDBView::CellTextForColumn(aRow, aColumnName, aValue);
}
Example #29
0
void
nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations
                   (nsAString& aString, CSSStyleSheet* aSheet,
                   bool aIsNegated) const
{
  nsAutoString temp;
  bool isPseudoElement = IsPseudoElement();

  // For non-pseudo-element selectors or for lone pseudo-elements, deal with
  // namespace prefixes.
  bool wroteNamespace = false;
  if (!isPseudoElement || !mNext) {
    // append the namespace prefix if needed
    nsXMLNameSpaceMap *sheetNS = aSheet ? aSheet->GetNameSpaceMap() : nullptr;

    // sheetNS is non-null if and only if we had an @namespace rule.  If it's
    // null, that means that the only namespaces we could have are the
    // wildcard namespace (which can be implicit in this case) and the "none"
    // namespace, which then needs to be explicitly specified.
    if (!sheetNS) {
      NS_ASSERTION(mNameSpace == kNameSpaceID_Unknown ||
                   mNameSpace == kNameSpaceID_None,
                   "How did we get this namespace?");
      if (mNameSpace == kNameSpaceID_None) {
        aString.Append(char16_t('|'));
        wroteNamespace = true;
      }
    } else if (sheetNS->FindNameSpaceID(nullptr) == mNameSpace) {
      // We have the default namespace (possibly including the wildcard
      // namespace).  Do nothing.
      NS_ASSERTION(mNameSpace == kNameSpaceID_Unknown ||
                   CanBeNamespaced(aIsNegated),
                   "How did we end up with this namespace?");
    } else if (mNameSpace == kNameSpaceID_None) {
      NS_ASSERTION(CanBeNamespaced(aIsNegated),
                   "How did we end up with this namespace?");
      aString.Append(char16_t('|'));
      wroteNamespace = true;
    } else if (mNameSpace != kNameSpaceID_Unknown) {
      NS_ASSERTION(CanBeNamespaced(aIsNegated),
                   "How did we end up with this namespace?");
      nsIAtom *prefixAtom = sheetNS->FindPrefix(mNameSpace);
      NS_ASSERTION(prefixAtom, "how'd we get a non-default namespace "
                   "without a prefix?");
      nsStyleUtil::AppendEscapedCSSIdent(nsDependentAtomString(prefixAtom),
                                         aString);
      aString.Append(char16_t('|'));
      wroteNamespace = true;
    } else {
      // A selector for an element in any namespace, while the default
      // namespace is something else.  :not() is special in that the default
      // namespace is not implied for non-type selectors, so if this is a
      // negated non-type selector we don't need to output an explicit wildcard
      // namespace here, since those default to a wildcard namespace.
      if (CanBeNamespaced(aIsNegated)) {
        aString.AppendLiteral("*|");
        wroteNamespace = true;
      }
    }
  }
      
  if (!mLowercaseTag) {
    // Universal selector:  avoid writing the universal selector when we
    // can avoid it, especially since we're required to avoid it for the
    // inside of :not()
    if (wroteNamespace ||
        (!mIDList && !mClassList && !mPseudoClassList && !mAttrList &&
         (aIsNegated || !mNegations))) {
      aString.Append(char16_t('*'));
    }
  } else {
    // Append the tag name
    nsAutoString tag;
    (isPseudoElement ? mLowercaseTag : mCasedTag)->ToString(tag);
    if (isPseudoElement) {
      if (!mNext) {
        // Lone pseudo-element selector -- toss in a wildcard type selector
        // XXXldb Why?
        aString.Append(char16_t('*'));
      }
      // While our atoms use one colon, most pseudo-elements require two
      // colons (those not in CSS level 2) and all pseudo-elements allow
      // two colons. So serialize to the non-deprecated two colon syntax.
      aString.Append(char16_t(':'));
      // This should not be escaped since (a) the pseudo-element string
      // has a ":" that can't be escaped and (b) all pseudo-elements at
      // this point are known, and therefore we know they don't need
      // escaping.
      aString.Append(tag);
    } else {
      nsStyleUtil::AppendEscapedCSSIdent(tag, aString);
    }
  }

  // Append the id, if there is one
  if (mIDList) {
    nsAtomList* list = mIDList;
    while (list != nullptr) {
      list->mAtom->ToString(temp);
      aString.Append(char16_t('#'));
      nsStyleUtil::AppendEscapedCSSIdent(temp, aString);
      list = list->mNext;
    }
  }

  // Append each class in the linked list
  if (mClassList) {
    if (isPseudoElement) {
#ifdef MOZ_XUL
      MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(mLowercaseTag),
                 "must be tree pseudo-element");

      aString.Append(char16_t('('));
      for (nsAtomList* list = mClassList; list; list = list->mNext) {
        nsStyleUtil::AppendEscapedCSSIdent(nsDependentAtomString(list->mAtom), aString);
        aString.Append(char16_t(','));
      }
      // replace the final comma with a close-paren
      aString.Replace(aString.Length() - 1, 1, char16_t(')'));
#else
      NS_ERROR("Can't happen");
#endif
    } else {
      nsAtomList* list = mClassList;
      while (list != nullptr) {
        list->mAtom->ToString(temp);
        aString.Append(char16_t('.'));
        nsStyleUtil::AppendEscapedCSSIdent(temp, aString);
        list = list->mNext;
      }
    }
  }

  // Append each attribute selector in the linked list
  if (mAttrList) {
    nsAttrSelector* list = mAttrList;
    while (list != nullptr) {
      aString.Append(char16_t('['));
      // Append the namespace prefix
      if (list->mNameSpace == kNameSpaceID_Unknown) {
        aString.Append(char16_t('*'));
        aString.Append(char16_t('|'));
      } else if (list->mNameSpace != kNameSpaceID_None) {
        if (aSheet) {
          nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
          nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace);
          // Default namespaces don't apply to attribute selectors, so
          // we must have a useful prefix.
          NS_ASSERTION(prefixAtom,
                       "How did we end up with a namespace if the prefix "
                       "is unknown?");
          nsAutoString prefix;
          prefixAtom->ToString(prefix);
          nsStyleUtil::AppendEscapedCSSIdent(prefix, aString);
          aString.Append(char16_t('|'));
        }
      }
      // Append the attribute name
      list->mCasedAttr->ToString(temp);
      nsStyleUtil::AppendEscapedCSSIdent(temp, aString);

      if (list->mFunction != NS_ATTR_FUNC_SET) {
        // Append the function
        if (list->mFunction == NS_ATTR_FUNC_INCLUDES)
          aString.Append(char16_t('~'));
        else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH)
          aString.Append(char16_t('|'));
        else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH)
          aString.Append(char16_t('^'));
        else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH)
          aString.Append(char16_t('$'));
        else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH)
          aString.Append(char16_t('*'));

        aString.Append(char16_t('='));
      
        // Append the value
        nsStyleUtil::AppendEscapedCSSString(list->mValue, aString);
      }

      aString.Append(char16_t(']'));
      
      list = list->mNext;
    }
  }

  // Append each pseudo-class in the linked list
  for (nsPseudoClassList* list = mPseudoClassList; list; list = list->mNext) {
    nsCSSPseudoClasses::PseudoTypeToString(list->mType, temp);
    // This should not be escaped since (a) the pseudo-class string
    // has a ":" that can't be escaped and (b) all pseudo-classes at
    // this point are known, and therefore we know they don't need
    // escaping.
    aString.Append(temp);
    if (list->u.mMemory) {
      aString.Append(char16_t('('));
      if (nsCSSPseudoClasses::HasStringArg(list->mType)) {
        nsStyleUtil::AppendEscapedCSSIdent(
          nsDependentString(list->u.mString), aString);
      } else if (nsCSSPseudoClasses::HasNthPairArg(list->mType)) {
        int32_t a = list->u.mNumbers[0],
                b = list->u.mNumbers[1];
        temp.Truncate();
        if (a != 0) {
          if (a == -1) {
            temp.Append(char16_t('-'));
          } else if (a != 1) {
            temp.AppendInt(a);
          }
          temp.Append(char16_t('n'));
        }
        if (b != 0 || a == 0) {
          if (b >= 0 && a != 0) // check a != 0 for whether we printed above
            temp.Append(char16_t('+'));
          temp.AppendInt(b);
        }
        aString.Append(temp);
      } else {
        NS_ASSERTION(nsCSSPseudoClasses::HasSelectorListArg(list->mType),
                     "unexpected pseudo-class");
        nsString tmp;
        list->u.mSelectors->ToString(tmp, aSheet);
        aString.Append(tmp);
      }
      aString.Append(char16_t(')'));
    }
  }
}
void nsHTMLContentSerializer::AppendWrapped_NonWhitespaceSequence(
    nsASingleFragmentString::const_char_iterator &aPos,
    const nsASingleFragmentString::const_char_iterator aEnd,
    const nsASingleFragmentString::const_char_iterator aSequenceStart,
    PRBool &aMayIgnoreStartOfLineWhitespaceSequence,
    nsAString& aOutputStr)
{
    mMayIgnoreLineBreakSequence = PR_FALSE;
    aMayIgnoreStartOfLineWhitespaceSequence = PR_FALSE;

    // Handle the complete sequence of non-whitespace in this block
    // Iterate until we find the first whitespace char or an aEnd condition
    // Updates "aPos" to point to the first unhandled char.
    // Also updates the aMayIgnoreStartOfLineWhitespaceSequence flag,
    // as well as the other "global" state flags.

    PRBool thisSequenceStartsAtBeginningOfLine = !mColPos;
    PRBool onceAgainBecauseWeAddedBreakInFront;
    PRBool foundWhitespaceInLoop;

    do {
        onceAgainBecauseWeAddedBreakInFront = PR_FALSE;
        foundWhitespaceInLoop = PR_FALSE;

        do {
            if (*aPos == ' ' || *aPos == '\t' || *aPos == '\n') {
                foundWhitespaceInLoop = PR_TRUE;
                break;
            }

            ++aPos;
            ++mColPos;
        } while (mColPos < mMaxColumn && aPos < aEnd);

        if (aPos == aEnd || foundWhitespaceInLoop) {
            // there is enough room for the complete block we found

            if (mAddSpace) {
                aOutputStr.Append(PRUnichar(' '));
                mAddSpace = PR_FALSE;
            }

            aOutputStr.Append(aSequenceStart, aPos - aSequenceStart);
            // We have not yet reached the max column, we will continue to
            // fill the current line in the next outer loop iteration.
        }
        else { // mColPos == mMaxColumn
            if (!thisSequenceStartsAtBeginningOfLine && mAddSpace) {
                // We can avoid to wrap.

                aOutputStr.Append(mLineBreak);
                mAddSpace = PR_FALSE;
                aPos = aSequenceStart;
                mColPos = 0;
                thisSequenceStartsAtBeginningOfLine = PR_TRUE;
                onceAgainBecauseWeAddedBreakInFront = PR_TRUE;
            }
            else {
                // we must wrap

                PRBool foundWrapPosition = PR_FALSE;
                nsILineBreaker *lineBreaker = nsContentUtils::LineBreaker();

                PRInt32 wrapPosition;

                wrapPosition = lineBreaker->Prev(aSequenceStart,
                                                 (aEnd - aSequenceStart),
                                                 (aPos - aSequenceStart) + 1);
                if (wrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT) {
                    foundWrapPosition = PR_TRUE;
                }
                else {
                    wrapPosition = lineBreaker->Next(aSequenceStart,
                                                     (aEnd - aSequenceStart),
                                                     (aPos - aSequenceStart));
                    if (wrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT) {
                        foundWrapPosition = PR_TRUE;
                    }
                }

                if (foundWrapPosition) {
                    if (mAddSpace) {
                        aOutputStr.Append(PRUnichar(' '));
                        mAddSpace = PR_FALSE;
                    }

                    aOutputStr.Append(aSequenceStart, wrapPosition);
                    aOutputStr.Append(mLineBreak);
                    aPos = aSequenceStart + wrapPosition;
                    mColPos = 0;
                    aMayIgnoreStartOfLineWhitespaceSequence = PR_TRUE;
                    mMayIgnoreLineBreakSequence = PR_TRUE;
                }
                else {
                    // try some simple fallback logic
                    // go forward up to the next whitespace position,
                    // in the worst case this will be all the rest of the data

                    do {
                        if (*aPos == ' ' || *aPos == '\t' || *aPos == '\n') {
                            break;
                        }

                        ++aPos;
                        ++mColPos;
                    } while (aPos < aEnd);

                    if (mAddSpace) {
                        aOutputStr.Append(PRUnichar(' '));
                        mAddSpace = PR_FALSE;
                    }

                    aOutputStr.Append(aSequenceStart, aPos - aSequenceStart);
                }
            }
        }
    } while (onceAgainBecauseWeAddedBreakInFront);
}