import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

26
dom/xslt/base/moz.build Normal file
View file

@ -0,0 +1,26 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'txDouble.cpp',
'txExpandedName.cpp',
'txExpandedNameMap.cpp',
'txList.cpp',
'txNamespaceMap.cpp',
'txURIUtils.cpp',
]
LOCAL_INCLUDES += [
'..',
'../xml',
'../xpath',
'../xslt',
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

51
dom/xslt/base/txCore.h Normal file
View file

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __txCore_h__
#define __txCore_h__
#include "nscore.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
class nsAString;
class txObject
{
public:
txObject()
{
MOZ_COUNT_CTOR(txObject);
}
/**
* Deletes this txObject
*/
virtual ~txObject()
{
MOZ_COUNT_DTOR(txObject);
}
};
/**
* Utility class for doubles
*/
class txDouble
{
public:
/**
* Converts the value of the given double to a string, and appends
* the result to the destination string.
*/
static void toString(double aValue, nsAString& aDest);
/**
* Converts the given String to a double, if the string value does not
* represent a double, NaN will be returned.
*/
static double toDouble(const nsAString& aStr);
};
#endif

215
dom/xslt/base/txDouble.cpp Normal file
View file

@ -0,0 +1,215 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/FloatingPoint.h"
#include "nsString.h"
#include "txCore.h"
#include "txXMLUtils.h"
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#ifdef WIN32
#include <float.h>
#endif
#include "prdtoa.h"
/*
* Utility class for doubles
*/
/*
* Converts the given String to a double, if the String value does not
* represent a double, NaN will be returned
*/
class txStringToDouble
{
public:
typedef char16_t input_type;
typedef char16_t value_type;
txStringToDouble(): mState(eWhitestart), mSign(ePositive) {}
void
write(const input_type* aSource, uint32_t aSourceLength)
{
if (mState == eIllegal) {
return;
}
uint32_t i = 0;
char16_t c;
for ( ; i < aSourceLength; ++i) {
c = aSource[i];
switch (mState) {
case eWhitestart:
if (c == '-') {
mState = eDecimal;
mSign = eNegative;
}
else if (c >= '0' && c <= '9') {
mState = eDecimal;
mBuffer.Append((char)c);
}
else if (c == '.') {
mState = eMantissa;
mBuffer.Append((char)c);
}
else if (!XMLUtils::isWhitespace(c)) {
mState = eIllegal;
return;
}
break;
case eDecimal:
if (c >= '0' && c <= '9') {
mBuffer.Append((char)c);
}
else if (c == '.') {
mState = eMantissa;
mBuffer.Append((char)c);
}
else if (XMLUtils::isWhitespace(c)) {
mState = eWhiteend;
}
else {
mState = eIllegal;
return;
}
break;
case eMantissa:
if (c >= '0' && c <= '9') {
mBuffer.Append((char)c);
}
else if (XMLUtils::isWhitespace(c)) {
mState = eWhiteend;
}
else {
mState = eIllegal;
return;
}
break;
case eWhiteend:
if (!XMLUtils::isWhitespace(c)) {
mState = eIllegal;
return;
}
break;
default:
break;
}
}
}
double
getDouble()
{
if (mState == eIllegal || mBuffer.IsEmpty() ||
(mBuffer.Length() == 1 && mBuffer[0] == '.')) {
return mozilla::UnspecifiedNaN<double>();
}
return mSign*PR_strtod(mBuffer.get(), 0);
}
private:
nsAutoCString mBuffer;
enum {
eWhitestart,
eDecimal,
eMantissa,
eWhiteend,
eIllegal
} mState;
enum {
eNegative = -1,
ePositive = 1
} mSign;
};
double txDouble::toDouble(const nsAString& aSrc)
{
txStringToDouble sink;
nsAString::const_iterator fromBegin, fromEnd;
copy_string(aSrc.BeginReading(fromBegin), aSrc.EndReading(fromEnd), sink);
return sink.getDouble();
}
/*
* 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 (mozilla::IsNaN(aValue)) {
aDest.AppendLiteral("NaN");
return;
}
if (mozilla::IsInfinite(aValue)) {
if (aValue < 0)
aDest.Append(char16_t('-'));
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))
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;
}
}

View file

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MITRE_ERROROBSERVER_H
#define MITRE_ERROROBSERVER_H
#include "txCore.h"
/**
* A simple interface for observing errors
**/
class ErrorObserver {
public:
/**
* Default Destructor for ErrorObserver
**/
virtual ~ErrorObserver() {};
/**
* Notifies this Error observer of a new error aRes
**/
virtual void receiveError(const nsAString& errorMessage, nsresult aRes) = 0;
/**
* Notifies this Error observer of a new error, with default
* error code NS_ERROR_FAILURE
**/
void receiveError(const nsAString& errorMessage)
{
receiveError(errorMessage, NS_ERROR_FAILURE);
}
}; //-- ErrorObserver
#endif

View file

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "txExpandedName.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "txStringUtils.h"
#include "txNamespaceMap.h"
#include "txXMLUtils.h"
nsresult
txExpandedName::init(const nsAString& aQName, txNamespaceMap* aResolver,
bool aUseDefault)
{
const nsAFlatString& qName = PromiseFlatString(aQName);
const char16_t* colon;
bool valid = XMLUtils::isValidQName(qName, &colon);
if (!valid) {
return NS_ERROR_FAILURE;
}
if (colon) {
nsCOMPtr<nsIAtom> prefix = NS_Atomize(Substring(qName.get(), colon));
int32_t namespaceID = aResolver->lookupNamespace(prefix);
if (namespaceID == kNameSpaceID_Unknown)
return NS_ERROR_FAILURE;
mNamespaceID = namespaceID;
const char16_t *end;
qName.EndReading(end);
mLocalName = NS_Atomize(Substring(colon + 1, end));
}
else {
mNamespaceID = aUseDefault ? aResolver->lookupNamespace(nullptr) :
kNameSpaceID_None;
mLocalName = NS_Atomize(aQName);
}
return NS_OK;
}

View file

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TRANSFRMX_EXPANDEDNAME_H
#define TRANSFRMX_EXPANDEDNAME_H
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "mozilla/dom/NameSpaceConstants.h"
class txNamespaceMap;
class txExpandedName {
public:
txExpandedName() : mNamespaceID(kNameSpaceID_None)
{
}
txExpandedName(int32_t aNsID,
nsIAtom* aLocalName) : mNamespaceID(aNsID),
mLocalName(aLocalName)
{
}
txExpandedName(const txExpandedName& aOther) :
mNamespaceID(aOther.mNamespaceID),
mLocalName(aOther.mLocalName)
{
}
nsresult init(const nsAString& aQName, txNamespaceMap* aResolver,
bool aUseDefault);
void reset()
{
mNamespaceID = kNameSpaceID_None;
mLocalName = nullptr;
}
bool isNull()
{
return mNamespaceID == kNameSpaceID_None && !mLocalName;
}
txExpandedName& operator = (const txExpandedName& rhs)
{
mNamespaceID = rhs.mNamespaceID;
mLocalName = rhs.mLocalName;
return *this;
}
bool operator == (const txExpandedName& rhs) const
{
return ((mLocalName == rhs.mLocalName) &&
(mNamespaceID == rhs.mNamespaceID));
}
bool operator != (const txExpandedName& rhs) const
{
return ((mLocalName != rhs.mLocalName) ||
(mNamespaceID != rhs.mNamespaceID));
}
int32_t mNamespaceID;
nsCOMPtr<nsIAtom> mLocalName;
};
#endif

View file

@ -0,0 +1,104 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "txExpandedNameMap.h"
#include "txCore.h"
class txMapItemComparator
{
public:
bool Equals(const txExpandedNameMap_base::MapItem& aItem,
const txExpandedName& aKey) const {
return aItem.mNamespaceID == aKey.mNamespaceID &&
aItem.mLocalName == aKey.mLocalName;
}
};
/**
* Adds an item, if an item with this key already exists an error is
* returned
* @param aKey key for item to add
* @param aValue value of item to add
* @return errorcode
*/
nsresult txExpandedNameMap_base::addItem(const txExpandedName& aKey,
void* aValue)
{
size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
if (pos != mItems.NoIndex) {
return NS_ERROR_XSLT_ALREADY_SET;
}
MapItem* item = mItems.AppendElement();
NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
item->mNamespaceID = aKey.mNamespaceID;
item->mLocalName = aKey.mLocalName;
item->mValue = aValue;
return NS_OK;
}
/**
* Sets an item, if an item with this key already exists it is overwritten
* with the new value
* @param aKey key for item to set
* @param aValue value of item to set
* @return errorcode
*/
nsresult txExpandedNameMap_base::setItem(const txExpandedName& aKey,
void* aValue,
void** aOldValue)
{
*aOldValue = nullptr;
size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
if (pos != mItems.NoIndex) {
*aOldValue = mItems[pos].mValue;
mItems[pos].mValue = aValue;
return NS_OK;
}
MapItem* item = mItems.AppendElement();
NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
item->mNamespaceID = aKey.mNamespaceID;
item->mLocalName = aKey.mLocalName;
item->mValue = aValue;
return NS_OK;
}
/**
* Gets an item
* @param aKey key for item to get
* @return item with specified key, or null if no such item exists
*/
void* txExpandedNameMap_base::getItem(const txExpandedName& aKey) const
{
size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
if (pos != mItems.NoIndex) {
return mItems[pos].mValue;
}
return nullptr;
}
/**
* Removes an item, deleting it if the map owns the values
* @param aKey key for item to remove
* @return item with specified key, or null if it has been deleted
* or no such item exists
*/
void* txExpandedNameMap_base::removeItem(const txExpandedName& aKey)
{
void* value = nullptr;
size_t pos = mItems.IndexOf(aKey, 0, txMapItemComparator());
if (pos != mItems.NoIndex) {
value = mItems[pos].mValue;
mItems.RemoveElementAt(pos);
}
return value;
}

View file

@ -0,0 +1,203 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TRANSFRMX_EXPANDEDNAMEMAP_H
#define TRANSFRMX_EXPANDEDNAMEMAP_H
#include "nsAutoPtr.h"
#include "nsError.h"
#include "txExpandedName.h"
#include "nsTArray.h"
class txExpandedNameMap_base {
protected:
/**
* Adds an item, if an item with this key already exists an error is
* returned
* @param aKey key for item to add
* @param aValue value of item to add
* @return errorcode
*/
nsresult addItem(const txExpandedName& aKey, void* aValue);
/**
* Sets an item, if an item with this key already exists it is overwritten
* with the new value
* @param aKey key for item to set
* @param aValue value of item to set
* @return errorcode
*/
nsresult setItem(const txExpandedName& aKey, void* aValue,
void** aOldValue);
/**
* Gets an item
* @param aKey key for item to get
* @return item with specified key, or null if no such item exists
*/
void* getItem(const txExpandedName& aKey) const;
/**
* Removes an item, deleting it if the map owns the values
* @param aKey key for item to remove
* @return item with specified key, or null if it has been deleted
* or no such item exists
*/
void* removeItem(const txExpandedName& aKey);
/**
* Clears the items
*/
void clearItems()
{
mItems.Clear();
}
class iterator_base {
public:
explicit iterator_base(txExpandedNameMap_base& aMap)
: mMap(aMap),
mCurrentPos(uint32_t(-1))
{
}
bool next()
{
return ++mCurrentPos < mMap.mItems.Length();
}
const txExpandedName key()
{
NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
"invalid position in txExpandedNameMap::iterator");
return txExpandedName(mMap.mItems[mCurrentPos].mNamespaceID,
mMap.mItems[mCurrentPos].mLocalName);
}
protected:
void* itemValue()
{
NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
"invalid position in txExpandedNameMap::iterator");
return mMap.mItems[mCurrentPos].mValue;
}
private:
txExpandedNameMap_base& mMap;
uint32_t mCurrentPos;
};
friend class iterator_base;
friend class txMapItemComparator;
struct MapItem {
int32_t mNamespaceID;
nsCOMPtr<nsIAtom> mLocalName;
void* mValue;
};
nsTArray<MapItem> mItems;
};
template<class E>
class txExpandedNameMap : public txExpandedNameMap_base
{
public:
nsresult add(const txExpandedName& aKey, E* aValue)
{
return addItem(aKey, (void*)aValue);
}
nsresult set(const txExpandedName& aKey, E* aValue)
{
void* oldValue;
return setItem(aKey, (void*)aValue, &oldValue);
}
E* get(const txExpandedName& aKey) const
{
return (E*)getItem(aKey);
}
E* remove(const txExpandedName& aKey)
{
return (E*)removeItem(aKey);
}
void clear()
{
clearItems();
}
class iterator : public iterator_base
{
public:
explicit iterator(txExpandedNameMap& aMap)
: iterator_base(aMap)
{
}
E* value()
{
return (E*)itemValue();
}
};
};
template<class E>
class txOwningExpandedNameMap : public txExpandedNameMap_base
{
public:
~txOwningExpandedNameMap()
{
clear();
}
nsresult add(const txExpandedName& aKey, E* aValue)
{
return addItem(aKey, (void*)aValue);
}
nsresult set(const txExpandedName& aKey, E* aValue)
{
nsAutoPtr<E> oldValue;
return setItem(aKey, (void*)aValue, getter_Transfers(oldValue));
}
E* get(const txExpandedName& aKey) const
{
return (E*)getItem(aKey);
}
void remove(const txExpandedName& aKey)
{
delete (E*)removeItem(aKey);
}
void clear()
{
uint32_t i, len = mItems.Length();
for (i = 0; i < len; ++i) {
delete (E*)mItems[i].mValue;
}
clearItems();
}
class iterator : public iterator_base
{
public:
explicit iterator(txOwningExpandedNameMap& aMap)
: iterator_base(aMap)
{
}
E* value()
{
return (E*)itemValue();
}
};
};
#endif //TRANSFRMX_EXPANDEDNAMEMAP_H

278
dom/xslt/base/txList.cpp Normal file
View file

@ -0,0 +1,278 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "txList.h"
//----------------------------/
//- Implementation of txList -/
//----------------------------/
/**
* Default constructor for a txList;
**/
txList::txList() {
firstItem = 0;
lastItem = 0;
itemCount = 0;
} //-- txList;
/**
* txList destructor, cleans up ListItems, but will not delete the Object
* references
*/
txList::~txList() {
clear();
} //-- ~txList
nsresult txList::add(void* objPtr)
{
return insertBefore(objPtr, 0);
} //-- add
/**
* Returns the number of items in this txList
**/
int32_t List::getLength() {
return itemCount;
} //-- getLength
/**
* Inserts the given Object pointer as the item just after refItem.
* If refItem is a null pointer the Object will be inserted at the
* beginning of the txList (ie, insert after nothing).
* This method assumes refItem is a member of this list, and since this
* is a private method, I feel that's a valid assumption
**/
nsresult txList::insertAfter(void* objPtr, ListItem* refItem)
{
//-- if refItem == null insert at front
if (!refItem)
return insertBefore(objPtr, firstItem);
return insertBefore(objPtr, refItem->nextItem);
} //-- insertAfter
/**
* Inserts the given Object pointer as the item just before refItem.
* If refItem is a null pointer the Object will be inserted at the
* end of the txList (ie, insert before nothing).
* This method assumes refItem is a member of this list, and since this
* is a private method, I feel that's a valid assumption
**/
nsresult txList::insertBefore(void* objPtr, ListItem* refItem)
{
ListItem* item = new ListItem;
item->objPtr = objPtr;
item->nextItem = 0;
item->prevItem = 0;
//-- if refItem == null insert at end
if (!refItem) {
//-- add to back of list
if (lastItem) {
lastItem->nextItem = item;
item->prevItem = lastItem;
}
lastItem = item;
if (!firstItem)
firstItem = item;
}
else {
//-- insert before given item
item->nextItem = refItem;
item->prevItem = refItem->prevItem;
refItem->prevItem = item;
if (item->prevItem)
item->prevItem->nextItem = item;
else
firstItem = item;
}
// increase the item count
++itemCount;
return NS_OK;
} //-- insertBefore
txList::ListItem* txList::remove(ListItem* item) {
if (!item)
return item;
//-- adjust the previous item's next pointer
if (item->prevItem) {
item->prevItem->nextItem = item->nextItem;
}
//-- adjust the next item's previous pointer
if (item->nextItem) {
item->nextItem->prevItem = item->prevItem;
}
//-- adjust first and last items
if (item == firstItem)
firstItem = item->nextItem;
if (item == lastItem)
lastItem = item->prevItem;
//-- decrease Item count
--itemCount;
return item;
} //-- remove
void txList::clear()
{
ListItem* item = firstItem;
while (item) {
ListItem* tItem = item;
item = item->nextItem;
delete tItem;
}
firstItem = 0;
lastItem = 0;
itemCount = 0;
}
//------------------------------------/
//- Implementation of txListIterator -/
//------------------------------------/
/**
* Creates a new txListIterator for the given txList
* @param list, the txList to create an Iterator for
**/
txListIterator::txListIterator(txList* list) {
this->list = list;
currentItem = 0;
atEndOfList = false;
} //-- txListIterator
/**
* Adds the Object pointer to the txList pointed to by this txListIterator.
* The Object pointer is inserted as the next item in the txList
* based on the current position within the txList
* @param objPtr the Object pointer to add to the list
**/
nsresult txListIterator::addAfter(void* objPtr)
{
if (currentItem || !atEndOfList)
return list->insertAfter(objPtr, currentItem);
return list->insertBefore(objPtr, 0);
} //-- addAfter
/**
* Adds the Object pointer to the txList pointed to by this txListIterator.
* The Object pointer is inserted as the previous item in the txList
* based on the current position within the txList
* @param objPtr the Object pointer to add to the list
**/
nsresult txListIterator::addBefore(void* objPtr)
{
if (currentItem || atEndOfList)
return list->insertBefore(objPtr, currentItem);
return list->insertAfter(objPtr, 0);
} //-- addBefore
/**
* Returns true if a successful call to the next() method can be made
* @return true if a successful call to the next() method can be made,
* otherwise false
**/
bool txListIterator::hasNext() {
bool hasNext = false;
if (currentItem)
hasNext = (currentItem->nextItem != 0);
else if (!atEndOfList)
hasNext = (list->firstItem != 0);
return hasNext;
} //-- hasNext
/**
* Returns the next Object pointer in the list
**/
void* txListIterator::next() {
void* obj = 0;
if (currentItem)
currentItem = currentItem->nextItem;
else if (!atEndOfList)
currentItem = list->firstItem;
if (currentItem)
obj = currentItem->objPtr;
else
atEndOfList = true;
return obj;
} //-- next
/**
* Returns the previous Object in the list
**/
void* txListIterator::previous() {
void* obj = 0;
if (currentItem)
currentItem = currentItem->prevItem;
else if (atEndOfList)
currentItem = list->lastItem;
if (currentItem)
obj = currentItem->objPtr;
atEndOfList = false;
return obj;
} //-- previous
/**
* Returns the current Object
**/
void* txListIterator::current() {
if (currentItem)
return currentItem->objPtr;
return 0;
} //-- current
/**
* Removes the Object last returned by the next() or previous() methods;
* @return the removed Object pointer
**/
void* txListIterator::remove() {
void* obj = 0;
if (currentItem) {
obj = currentItem->objPtr;
txList::ListItem* item = currentItem;
previous(); //-- make previous item the current item
list->remove(item);
delete item;
}
return obj;
} //-- remove
/**
* Resets the current location within the txList to the beginning of the txList
**/
void txListIterator::reset() {
atEndOfList = false;
currentItem = 0;
} //-- reset
/**
* Move the iterator to right after the last element
**/
void txListIterator::resetToEnd() {
atEndOfList = true;
currentItem = 0;
} //-- moveToEnd

161
dom/xslt/base/txList.h Normal file
View file

@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TRANSFRMX_LIST_H
#define TRANSFRMX_LIST_H
#include "txCore.h"
class txListIterator;
/**
* Represents an ordered list of Object pointers. Modeled after a Java 2 List.
**/
class txList : public txObject {
friend class txListIterator;
public:
/**
* Creates an empty txList
**/
txList();
/**
* txList destructor, object references will not be deleted.
**/
~txList();
/**
* Returns the number of items in this txList
**/
int32_t getLength();
/**
* Returns true if there are no items in this txList
*/
inline bool isEmpty()
{
return itemCount == 0;
}
/**
* Adds the given Object to the list
**/
nsresult add(void* objPtr);
/*
* Removes all the objects from the list
*/
void clear();
protected:
struct ListItem {
ListItem* nextItem;
ListItem* prevItem;
void* objPtr;
};
/**
* Removes the given ListItem pointer from the list
**/
ListItem* remove(ListItem* sItem);
private:
txList(const txList& aOther); // not implemented
ListItem* firstItem;
ListItem* lastItem;
int32_t itemCount;
nsresult insertAfter(void* objPtr, ListItem* sItem);
nsresult insertBefore(void* objPtr, ListItem* sItem);
};
/**
* An Iterator for the txList Class
**/
class txListIterator {
public:
/**
* Creates a new txListIterator for the given txList
* @param list, the txList to create an Iterator for
**/
explicit txListIterator(txList* list);
/**
* Adds the Object pointer to the txList pointed to by this txListIterator.
* The Object pointer is inserted as the next item in the txList
* based on the current position within the txList
* @param objPtr the Object pointer to add to the list
**/
nsresult addAfter(void* objPtr);
/**
* Adds the Object pointer to the txList pointed to by this txListIterator.
* The Object pointer is inserted as the previous item in the txList
* based on the current position within the txList
* @param objPtr the Object pointer to add to the list
**/
nsresult addBefore(void* objPtr);
/**
* Returns true if a successful call to the next() method can be made
* @return true if a successful call to the next() method can be made,
* otherwise false
**/
bool hasNext();
/**
* Returns the next Object pointer from the list
**/
void* next();
/**
* Returns the previous Object pointer from the list
**/
void* previous();
/**
* Returns the current Object
**/
void* current();
/**
* Removes the Object last returned by the next() or previous() methods;
* @return the removed Object pointer
**/
void* remove();
/**
* Resets the current location within the txList to the beginning of the txList
**/
void reset();
/**
* Resets the current location within the txList to the end of the txList
**/
void resetToEnd();
private:
//-- points to the current list item
txList::ListItem* currentItem;
//-- points to the list to iterator over
txList* list;
//-- we've moved off the end of the list
bool atEndOfList;
};
typedef txList List;
#endif

24
dom/xslt/base/txLog.h Normal file
View file

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef txLog_h__
#define txLog_h__
#include "mozilla/Logging.h"
class txLog
{
public:
static mozilla::LazyLogModule xpath;
static mozilla::LazyLogModule xslt;
};
#define TX_LG_IMPL \
mozilla::LazyLogModule txLog::xpath("xpath"); \
mozilla::LazyLogModule txLog::xslt("xslt");
#define TX_LG_CREATE
#endif

View file

@ -0,0 +1,98 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "txNamespaceMap.h"
#include "nsGkAtoms.h"
#include "txXPathNode.h"
txNamespaceMap::txNamespaceMap()
{
}
txNamespaceMap::txNamespaceMap(const txNamespaceMap& aOther)
: mPrefixes(aOther.mPrefixes)
{
mNamespaces = aOther.mNamespaces; //bah! I want a copy-constructor!
}
nsresult
txNamespaceMap::mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI)
{
nsIAtom* prefix = aPrefix == nsGkAtoms::_empty ? nullptr : aPrefix;
int32_t nsId;
if (prefix && aNamespaceURI.IsEmpty()) {
// Remove the mapping
int32_t index = mPrefixes.IndexOf(prefix);
if (index >= 0) {
mPrefixes.RemoveObjectAt(index);
mNamespaces.RemoveElementAt(index);
}
return NS_OK;
}
if (aNamespaceURI.IsEmpty()) {
// Set default to empty namespace
nsId = kNameSpaceID_None;
}
else {
nsId = txNamespaceManager::getNamespaceID(aNamespaceURI);
NS_ENSURE_FALSE(nsId == kNameSpaceID_Unknown, NS_ERROR_FAILURE);
}
// Check if the mapping already exists
int32_t index = mPrefixes.IndexOf(prefix);
if (index >= 0) {
mNamespaces.ElementAt(index) = nsId;
return NS_OK;
}
// New mapping
if (!mPrefixes.AppendObject(prefix)) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (mNamespaces.AppendElement(nsId) == nullptr) {
mPrefixes.RemoveObjectAt(mPrefixes.Count() - 1);
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
int32_t
txNamespaceMap::lookupNamespace(nsIAtom* aPrefix)
{
if (aPrefix == nsGkAtoms::xml) {
return kNameSpaceID_XML;
}
nsIAtom* prefix = aPrefix == nsGkAtoms::_empty ? 0 : aPrefix;
int32_t index = mPrefixes.IndexOf(prefix);
if (index >= 0) {
return mNamespaces.SafeElementAt(index, kNameSpaceID_Unknown);
}
if (!prefix) {
return kNameSpaceID_None;
}
return kNameSpaceID_Unknown;
}
int32_t
txNamespaceMap::lookupNamespaceWithDefault(const nsAString& aPrefix)
{
nsCOMPtr<nsIAtom> prefix = NS_Atomize(aPrefix);
if (prefix != nsGkAtoms::_poundDefault) {
return lookupNamespace(prefix);
}
return lookupNamespace(nullptr);
}

View file

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TRANSFRMX_TXNAMESPACEMAP_H
#define TRANSFRMX_TXNAMESPACEMAP_H
#include "nsIAtom.h"
#include "nsCOMArray.h"
#include "nsTArray.h"
class txNamespaceMap
{
public:
txNamespaceMap();
txNamespaceMap(const txNamespaceMap& aOther);
nsrefcnt AddRef()
{
return ++mRefCnt;
}
nsrefcnt Release()
{
if (--mRefCnt == 0) {
mRefCnt = 1; //stabilize
delete this;
return 0;
}
return mRefCnt;
}
nsresult mapNamespace(nsIAtom* aPrefix, const nsAString& aNamespaceURI);
int32_t lookupNamespace(nsIAtom* aPrefix);
int32_t lookupNamespaceWithDefault(const nsAString& aPrefix);
private:
nsAutoRefCnt mRefCnt;
nsCOMArray<nsIAtom> mPrefixes;
nsTArray<int32_t> mNamespaces;
};
#endif //TRANSFRMX_TXNAMESPACEMAP_H

View file

@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef txOwningArray_h__
#define txOwningArray_h__
// Class acting like a nsTArray except that it deletes its objects
// on destruction. It does not however delete its objects on operations
// like RemoveElementsAt or on |array[i] = bar|.
template<class E>
class txOwningArray : public nsTArray<E*>
{
public:
typedef nsTArray<E*> base_type;
typedef typename base_type::elem_type elem_type;
~txOwningArray()
{
elem_type* iter = base_type::Elements();
elem_type* end = iter + base_type::Length();
for (; iter < end; ++iter) {
delete *iter;
}
}
};
#endif // txOwningArray_h__

122
dom/xslt/base/txStack.h Normal file
View file

@ -0,0 +1,122 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef txStack_h___
#define txStack_h___
#include "nsTArray.h"
class txStack : private nsTArray<void*>
{
public:
/**
* Returns the specified object from the top of this stack,
* without removing it from the stack.
*
* @return a pointer to the object that is the top of this stack.
*/
inline void* peek()
{
NS_ASSERTION(!isEmpty(), "peeking at empty stack");
return !isEmpty() ? ElementAt(Length() - 1) : nullptr;
}
/**
* Adds the specified object to the top of this stack.
*
* @param obj a pointer to the object that is to be added to the
* top of this stack.
*/
inline nsresult push(void* aObject)
{
return AppendElement(aObject) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/**
* Removes and returns the specified object from the top of this
* stack.
*
* @return a pointer to the object that was the top of this stack.
*/
inline void* pop()
{
void* object = nullptr;
NS_ASSERTION(!isEmpty(), "popping from empty stack");
if (!isEmpty())
{
const uint32_t count = Length() - 1;
object = ElementAt(count);
RemoveElementAt(count);
}
return object;
}
/**
* Returns true if there are no objects in the stack.
*
* @return true if there are no objects in the stack.
*/
inline bool isEmpty()
{
return IsEmpty();
}
/**
* Returns the number of elements in the Stack.
*
* @return the number of elements in the Stack.
*/
inline int32_t size()
{
return Length();
}
private:
friend class txStackIterator;
};
class txStackIterator
{
public:
/**
* Creates an iterator for the given stack.
*
* @param aStack the stack to create an iterator for.
*/
inline
explicit txStackIterator(txStack* aStack) : mStack(aStack),
mPosition(0)
{
}
/**
* Returns true if there is more objects on the stack.
*
* @return .
*/
inline bool hasNext()
{
return (mPosition < mStack->Length());
}
/**
* Returns the next object pointer from the stack.
*
* @return .
*/
inline void* next()
{
if (mPosition == mStack->Length()) {
return nullptr;
}
return mStack->ElementAt(mPosition++);
}
private:
txStack* mStack;
uint32_t mPosition;
};
#endif /* txStack_h___ */

View file

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef txStringUtils_h__
#define txStringUtils_h__
#include "nsAString.h"
#include "nsIAtom.h"
#include "nsUnicharUtils.h"
#include "nsContentUtils.h" // For ASCIIToLower().
typedef nsCaseInsensitiveStringComparator txCaseInsensitiveStringComparator;
/**
* Check equality between a string and an atom containing ASCII.
*/
inline bool
TX_StringEqualsAtom(const nsASingleFragmentString& aString, nsIAtom* aAtom)
{
return aAtom->Equals(aString);
}
inline already_AddRefed<nsIAtom>
TX_ToLowerCaseAtom(nsIAtom* aAtom)
{
nsAutoString str;
aAtom->ToString(str);
nsContentUtils::ASCIIToLower(str);
return NS_Atomize(str);
}
#endif // txStringUtils_h__

View file

@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "txURIUtils.h"
#include "nsNetUtil.h"
#include "nsIDocument.h"
#include "nsIHttpChannelInternal.h"
#include "nsIPrincipal.h"
#include "mozilla/LoadInfo.h"
using mozilla::net::LoadInfo;
/**
* URIUtils
* A set of utilities for handling URIs
**/
/**
* Resolves the given href argument, using the given documentBase
* if necessary.
* The new resolved href will be appended to the given dest String
**/
void URIUtils::resolveHref(const nsAString& href, const nsAString& base,
nsAString& dest) {
if (base.IsEmpty()) {
dest.Append(href);
return;
}
if (href.IsEmpty()) {
dest.Append(base);
return;
}
nsCOMPtr<nsIURI> pURL;
nsAutoString resultHref;
nsresult result = NS_NewURI(getter_AddRefs(pURL), base);
if (NS_SUCCEEDED(result)) {
NS_MakeAbsoluteURI(resultHref, href, pURL);
dest.Append(resultHref);
}
} //-- resolveHref
// static
void
URIUtils::ResetWithSource(nsIDocument *aNewDoc, nsINode *aSourceNode)
{
nsCOMPtr<nsIDocument> sourceDoc = aSourceNode->OwnerDoc();
nsIPrincipal* sourcePrincipal = sourceDoc->NodePrincipal();
// Copy the channel and loadgroup from the source document.
nsCOMPtr<nsILoadGroup> loadGroup = sourceDoc->GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel = sourceDoc->GetChannel();
if (!channel) {
// Need to synthesize one
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
sourceDoc->GetDocumentURI(),
sourceDoc,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER,
loadGroup,
nullptr, // aCallbacks
nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
if (NS_FAILED(rv)) {
return;
}
}
aNewDoc->Reset(channel, loadGroup);
aNewDoc->SetPrincipal(sourcePrincipal);
aNewDoc->SetBaseURI(sourceDoc->GetDocBaseURI());
// Copy charset
aNewDoc->SetDocumentCharacterSetSource(
sourceDoc->GetDocumentCharacterSetSource());
aNewDoc->SetDocumentCharacterSet(sourceDoc->GetDocumentCharacterSet());
}

View file

@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TRANSFRMX_URIUTILS_H
#define TRANSFRMX_URIUTILS_H
#include "txCore.h"
class nsIDocument;
class nsINode;
/**
* A utility class for URI handling
* Not yet finished, only handles file URI at this point
**/
class URIUtils {
public:
/**
* Reset the given document with the document of the source node
*/
static void ResetWithSource(nsIDocument *aNewDoc, nsINode *aSourceNode);
/**
* Resolves the given href argument, using the given documentBase
* if necessary.
* The new resolved href will be appended to the given dest String
**/
static void resolveHref(const nsAString& href, const nsAString& base,
nsAString& dest);
}; //-- URIUtils
/* */
#endif

View file

@ -0,0 +1,3 @@
<script>
var xpathResult = document.evaluate('', null, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
</script>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="111994.xsl" ?>
<root>
<item id="1001" name="name" />
</root>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="root">
<html><body><xsl:apply-templates select="item" /></body></html>
</xsl:template>
<xsl:template match="item">
<img>
<xsl:attribute name="src">
<xsl:value-of select="@name" />
</xsl:attribute>
</img>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="1205163.xsl"?>
<result>
<Title>Example</Title>
<Error>Error</Error>
</result>

View file

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Error"/>
</xsl:stylesheet>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="1243337.xsl" ?>
<root/>

View file

@ -0,0 +1,6 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="generate-id(5)"/>
<html><body/></html>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="182460-selects.xsl"?>
<fud/>

View file

@ -0,0 +1,5 @@
<html>
<body>
hi
</body>
</html>

View file

@ -0,0 +1,9 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XSL Crash</title>
</head>
<body>
<iframe src="182460-select.xml"></iframe>
<script type="text/javascript" src="data:text/javascript,/*no code*/"/>
</body>
</html>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="226425.xsl" ?>
<text></text>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html><body>
<xsl:apply-templates select="document('dontmatter')"/>
</body></html>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function boom()
{
var p = new XSLTProcessor();
p.setParameter("a", "b", {e: p});
}
boom();
</script>
</head>
<body>
</body>
</html>

View file

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#stylesheet"?>
<!DOCTYPE root [
<!ATTLIST xsl:stylesheet id ID #IMPLIED>
]>
<root>
<xsl:stylesheet id="stylesheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:attribute-set name="a">
<xsl:attribute name="b">c</xsl:attribute>
</xsl:attribute-set>
<xsl:template match="/">
<b>Please output something!</b>
</xsl:template>
<xsl:attribute-set name="a">
<xsl:attribute name="b">c</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
<doc id="foo">this</doc>
</root>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="485217.xsl"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item1 id="AAAAAAA" />
<item2 id="AAAAAAAAA" label="AAAAAAAAAAAA"/>
</root>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="label" match="item2" use="undeclaredfunc()"/>
<xsl:template match="root">
<xsl:for-each select="//item1">
<xsl:call-template name="item1" />
</xsl:for-each>
</xsl:template>
<xsl:template name="item1">
<xsl:for-each select="key('label', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')">
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,12 @@
<?xml-stylesheet type="application/xml" href="485286.xml"?>
<transform xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
<variable name="v">
<for-each select="/">
<value-of select="count(1)"/>
</for-each>
</variable>
<key name="k" match="/" use="$v"/>
<template match="/">
<value-of select="key('k', /..)"/>
</template>
</transform>

View file

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="#bug"?>
<!DOCTYPE doc [
<!ATTLIST xsl:transform
id ID #REQUIRED>
]>
<doc>
<xsl:transform id="bug"
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="k0" match="e1" use="key('k0', 'foobar')" />
<xsl:template id="t1" name="t1" match="key('k0', '1/2/2003')" />
</xsl:transform>
<e1 a1="foobar" a2="foobar"/>
</doc>

View file

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="#bug"?>
<!DOCTYPE doc [
<!ATTLIST xsl:transform
id ID #REQUIRED>
]>
<doc>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
id="bug">
<xsl:variable name="v0">
<xsl:for-each select="$v0" />
</xsl:variable>
<xsl:template name="t2" match="/">
<xsl:copy-of select="number($v0)" />
</xsl:template>
</xsl:transform>
<e1 />
</doc>

View file

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="#bug"?>
<!DOCTYPE doc [
<!ATTLIST xsl:transform
id ID #REQUIRED>
]>
<doc>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslstrings="http://exslt.org/strings"
version="2.0"
id="bug">
<xsl:variable name="v0" select="$v0" />
<xsl:template name="t2" match="/">
<xsl:param name="p0" select="exslstrings:tokenize('1234','foobar')" />
<xsl:copy-of select="round($v0)" />
</xsl:template>
</xsl:transform>
</doc>

View file

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xml" href="#bug"?>
<!DOCTYPE doc [
<!ATTLIST xsl:transform
id ID #REQUIRED>
]>
<doc>
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
id="bug">
<xsl:key name="k0" match="e2" use="name('foo')" />
<xsl:template name="t1" match="/">
<xsl:element name="e2" namespace="{//doc}" />
</xsl:template>
<xsl:template name="t2" match="key('k0', 'bar')" />
</xsl:transform>
<e2/>
</doc>

View file

@ -0,0 +1,28 @@
<html>
<head>
<script>
function main()
{
xml=document.implementation.createDocument('', '', null);
xml.appendChild(doc=xml.createElement('root'));
var p = new DOMParser();
text = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">';
text += '<xsl:template match="/">';
text += '<body>';
text += '<xsl:number value="2147483648" format="i"/>';
text += '</body>';
text += '</xsl:template>';
text += '</xsl:stylesheet>';
xsl=p.parseFromString(text, 'text/xml');
xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
d = xsltProcessor.transformToFragment(xml, document);
}
</script>
</head>
<body onload="main()">
</body>
</html>

View file

@ -0,0 +1,4 @@
<!DOCTYPE html>
<script>
(new XSLTProcessor).setParameter('', '', [{}, null]);
</script>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<script>
try {
var docType = document.implementation.createDocumentType(undefined, '', '');
var doc = document.implementation.createDocument('', '', null);
var xp = new XSLTProcessor;
xp.importStylesheet(doc);
xp.transformToDocument(docType);
}
catch (ex) {}
try {
docType = document.implementation.createDocumentType(undefined, '', '');
doc = document.implementation.createDocument('', '', null);
xp = new XSLTProcessor;
xp.importStylesheet(doc);
xp.transformToFragment(docType, document);
}
catch (ex) {}
</script>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<script>
function boom()
{
var frame = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
frame.onload = y;
frame.src = "data:text/plain,0";
document.body.appendChild(frame);
frameDoc = frame.contentDocument;
function y()
{
frameDoc.removeChild(frameDoc.documentElement);
var xp = new XSLTProcessor;
xp.importStylesheet(frameDoc);
try {
xp.transformToDocument(frameDoc.createTextNode('x'));
} catch(e) { }
document.documentElement.removeAttribute("class");
}
}
</script>
</head>
<body onload="boom();"></body>
</html>

View file

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#stylesheet"?>
<!DOCTYPE root [
<!ATTLIST xsl:stylesheet id ID #IMPLIED>
]>
<root>
<xsl:stylesheet id="stylesheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="var"><p>a</p></xsl:variable>
<xsl:template match="/"><xsl:copy-of select="$var" /></xsl:template>
</xsl:stylesheet>
</root>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="91332.xsl" ?>
<root>
<category name="Rectangles">
<list item="square" />
</category>
<quad id="square">
<desc>A square is ...</desc>
</quad>
</root>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="polyList" match="quad" use="@id" />
<xsl:template match="root">
<html><body><xsl:apply-templates select="category" /></body></html>
</xsl:template>
<xsl:template match="category">
<table><xsl:apply-templates select="list" /></table>
</xsl:template>
<xsl:template match="list">
<tr><td><xsl:apply-templates select="key('polyList',@item)" /></td></tr>
</xsl:template>
<xsl:template match="quad">
<b>Please output something!</b>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,20 @@
load 91332.xml
load 111994.xml
load 182460-table.xhtml
load 226425.xml
load 406106-1.html
load 483444.xml
load 485217.xml
load 485286.xml
load 527558_1.xml
load 528300.xml
load 528488.xml
load 528963.xml
load 545927.html
load 601543.html
load 602115.html
load 603844.html
load 667315.xml
load 1089049.html
load 1205163.xml
load 1243337.xml

31
dom/xslt/moz.build Normal file
View file

@ -0,0 +1,31 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIXSLTProcessor.idl',
'nsIXSLTProcessorPrivate.idl',
'txIEXSLTRegExFunctions.idl',
'txIFunctionEvaluationContext.idl',
'txINodeSet.idl',
'txIXPathObject.idl',
]
XPIDL_MODULE = 'content_xslt'
EXPORTS += [
'nsIDocumentTransformer.h',
]
DIRS += [
'base',
'xml',
'xpath',
'xslt',
]
if CONFIG['ENABLE_TESTS']:
JAR_MANIFESTS += ['tests/buster/jar.mn']
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']

View file

@ -0,0 +1,65 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsIDocumentTransformer_h__
#define nsIDocumentTransformer_h__
#include "nsISupports.h"
template<class> class nsCOMPtr;
class nsIContent;
class nsIDocument;
class nsIDOMNode;
class nsIURI;
class nsString;
template<class> class nsTArray;
#define NS_ITRANSFORMOBSERVER_IID \
{ 0x04b2d17c, 0xe98d, 0x45f5, \
{ 0x9a, 0x67, 0xb7, 0x01, 0x19, 0x59, 0x7d, 0xe7 } }
class nsITransformObserver : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITRANSFORMOBSERVER_IID)
NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) = 0;
NS_IMETHOD OnTransformDone(nsresult aResult,
nsIDocument *aResultDocument) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsITransformObserver, NS_ITRANSFORMOBSERVER_IID)
#define NS_IDOCUMENTTRANSFORMER_IID \
{ 0xf45e1ff8, 0x50f3, 0x4496, \
{ 0xb3, 0xa2, 0x0e, 0x03, 0xe8, 0x4a, 0x57, 0x11 } }
class nsIDocumentTransformer : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENTTRANSFORMER_IID)
NS_IMETHOD SetTransformObserver(nsITransformObserver* aObserver) = 0;
NS_IMETHOD LoadStyleSheet(nsIURI* aUri, nsIDocument* aLoaderDocument) = 0;
NS_IMETHOD SetSourceContentModel(nsIDocument* aDocument,
const nsTArray<nsCOMPtr<nsIContent>>& aSource) = 0;
NS_IMETHOD CancelLoads() = 0;
NS_IMETHOD AddXSLTParamNamespace(const nsString& aPrefix,
const nsString& aNamespace) = 0;
NS_IMETHOD AddXSLTParam(const nsString& aName,
const nsString& aNamespace,
const nsString& aValue,
const nsString& aSelect,
nsIDOMNode* aContextNode) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentTransformer,
NS_IDOCUMENTTRANSFORMER_IID)
#endif //nsIDocumentTransformer_h__

View file

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "domstubs.idl"
interface nsIVariant;
[scriptable, uuid(4a91aeb3-4100-43ee-a21e-9866268757c5)]
interface nsIXSLTProcessor : nsISupports
{
/**
* Import the stylesheet into this XSLTProcessor for transformations.
*
* @param style The root-node of a XSLT stylesheet. This can be either
* a document node or an element node. If a document node
* then the document can contain either a XSLT stylesheet
* or a LRE stylesheet.
* If the argument is an element node it must be the
* xsl:stylesheet (or xsl:transform) element of an XSLT
* stylesheet.
*/
void importStylesheet(in nsIDOMNode style);
/**
* Transforms the node source applying the stylesheet given by
* the importStylesheet() function. The owner document of the output node
* owns the returned document fragment.
*
* @param source The node to be transformed
* @param output This document is used to generate the output
* @return DocumentFragment The result of the transformation
*/
nsIDOMDocumentFragment transformToFragment(in nsIDOMNode source,
in nsIDOMDocument output);
/**
* Transforms the node source applying the stylesheet given by the
* importStylesheet() function.
*
* @param source The node to be transformed
* @return Document The result of the transformation
*/
nsIDOMDocument transformToDocument(in nsIDOMNode source);
/**
* Sets a parameter to be used in subsequent transformations with this
* nsIXSLTProcessor. If the parameter doesn't exist in the stylesheet the
* parameter will be ignored.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
* @param value The new value of the XSLT parameter
*
* @exception NS_ERROR_ILLEGAL_VALUE The datatype of value is
* not supported
*/
void setParameter(in DOMString namespaceURI,
in DOMString localName,
in nsIVariant value);
/**
* Gets a parameter if previously set by setParameter. Returns null
* otherwise.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
* @return nsIVariant The value of the XSLT parameter
*/
nsIVariant getParameter(in DOMString namespaceURI,
in DOMString localName);
/**
* Removes a parameter, if set. This will make the processor use the
* default-value for the parameter as specified in the stylesheet.
*
* @param namespaceURI The namespaceURI of the XSLT parameter
* @param localName The local name of the XSLT parameter
*/
void removeParameter(in DOMString namespaceURI,
in DOMString localName);
/**
* Removes all set parameters from this nsIXSLTProcessor. This will make
* the processor use the default-value for all parameters as specified in
* the stylesheet.
*/
void clearParameters();
/**
* Remove all parameters and stylesheets from this nsIXSLTProcessor.
*/
void reset();
};

View file

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, uuid(b8d727f7-67f4-4dc1-a318-ec0c87280816)]
interface nsIXSLTProcessorPrivate : nsISupports
{
/**
* Disables all loading of external documents, such as from
* <xsl:import> and document()
* Defaults to off and is *not* reset by calls to reset()
*/
const unsigned long DISABLE_ALL_LOADS = 1;
/**
* Flags for this processor. Defaults to 0. See individual flags above
* for documentation for effect of reset()
*/
attribute unsigned long flags;
};

View file

@ -0,0 +1,49 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const enablePrivilege = netscape.security.PrivilegeManager.enablePrivilege;
const IOSERVICE_CTRID = "@mozilla.org/network/io-service;1";
const nsIIOService = Components.interfaces.nsIIOService;
const SIS_CTRID = "@mozilla.org/scriptableinputstream;1";
const nsISIS = Components.interfaces.nsIScriptableInputStream;
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const STDURL_CTRID = "@mozilla.org/network/standard-url;1";
const nsIURI = Components.interfaces.nsIURI;
Components.utils.import("resource://gre/modules/NetUtil.jsm");
var gStop = false;
function loadFile(aUriSpec)
{
enablePrivilege('UniversalXPConnect');
var serv = Components.classes[IOSERVICE_CTRID].
getService(nsIIOService);
if (!serv) {
throw Components.results.ERR_FAILURE;
}
var chan = NetUtil.newChannel({
uri: aUriSpec,
loadUsingSystemPrincipal: true
});
var instream =
Components.classes[SIS_CTRID].createInstance(nsISIS);
instream.init(chan.open2());
return instream.read(instream.available());
}
function dump20(aVal)
{
const pads = ' ';
if (typeof(aVal)=='string')
out = aVal;
else if (typeof(aVal)=='number')
out = Number(aVal).toFixed(2);
else
out = new String(aVal);
dump(pads.substring(0, 20 - out.length));
dump(out);
}

View file

@ -0,0 +1,46 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var gParser = new DOMParser;
var gTimeout;
function Test(aTitle, aSourceURL, aStyleURL, aNumber, aObserver)
{
this.mTitle = aTitle;
this.mObserver = aObserver;
this.mTotal = aNumber;
this.mDone = 0;
var xmlcontent = loadFile(aSourceURL);
var xslcontent = loadFile(aStyleURL);
this.mSource = gParser.parseFromString(xmlcontent, 'application/xml');
this.mStyle = gParser.parseFromString(xslcontent, 'application/xml');
}
function runTest(aTitle, aSourceURL, aStyleURL, aNumber, aObserver)
{
test = new Test(aTitle, aSourceURL, aStyleURL, aNumber,
aObserver);
gTimeout = setTimeout(onNextTransform, 100, test, 0);
}
function onNextTransform(aTest, aNumber)
{
var proc = new XSLTProcessor;
var startTime = Date.now();
proc.importStylesheet(aTest.mStyle);
var res = proc.transformToDocument(aTest.mSource);
var endTime = Date.now();
aNumber++;
var progress = aNumber / aTest.mTotal * 100;
if (aTest.mObserver) {
aTest.mObserver.progress(aTest.mTitle, endTime - startTime,
progress);
}
if (aNumber < aTest.mTotal) {
gTimeout = setTimeout(onNextTransform, 100, aTest, aNumber);
} else if (aTest.mObserver) {
aTest.mObserver.done(aTest.mTitle);
}
}

View file

@ -0,0 +1,175 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var view =
{
configUrl: null,
testArray: null,
mCurrent: null,
browseForConfig: function()
{
enablePrivilege('UniversalXPConnect');
var fp = Components.classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);
fp.init(window,'XSLTMark Description File',nsIFilePicker.modeOpen);
fp.appendFilter('*.conf', '*.conf');
fp.appendFilters(nsIFilePicker.filterAll);
var res = fp.show();
if (res == nsIFilePicker.returnOK) {
this.configUrl = Components.classes[STDURL_CTRID].createInstance(nsIURI);
this.configUrl.spec = fp.fileURL.spec;
document.getElementById('config').setAttribute('value', this.configUrl.spec);
}
this.parseConfig();
return true;
},
parseConfig: function()
{
this.testArray = new Array();
var test;
if (!this.configUrl) {
return;
}
var content = loadFile(this.configUrl.spec);
var lines = content.split("\n");
var line, res;
var head = /^\[(.+)\]$/;
var instruct = /^(.+)=(.+)$/;
while (lines.length) {
line = lines.shift();
if (head.test(line)) {
test = new Object;
res = head.exec(line);
test['title'] = res[1];
this.testArray.push(test);
}
else if (line == '') {
test = undefined;
}
else {
res = instruct.exec(line);
test[res[1]] = res[2];
}
}
},
onLoad: function()
{
this.mCurrentStatus = document.getElementById('currentStatus');
this.mCurrentProgress = document.getElementById('currentProgress');
this.mTotalProgress = document.getElementById('totalProgress');
this.mOutput = document.getElementById('transformOutput');
this.mDetailOutput =
document.getElementById('transformDetailedOutput');
this.mDetail = true;
},
progress: function(aTitle, aTime, aProgress)
{
// dump20(aTitle);
// dump20(aTime);
// dump20(aProgress);
this.mCurrentProgress.value = aProgress;
this.displayDetailTime(aTime);
this.mTimes.push(aTime);
// dump("\n");
},
done: function(aTitle)
{
// dump(aTitle + " is finished.\n");
this.mCurrent++;
this.mCurrentProgress.value = 0;
this.displayTotalTime();
if (this.mCurrent >= this.testArray.length) {
this.mTotalProgress.value = 0;
this.mCurrentStatus.value = "done";
return;
}
this.mTotalProgress.value = this.mCurrent*100/this.testArray.length;
var test = this.testArray[this.mCurrent];
enablePrivilege('UniversalXPConnect');
this.displayTest(test.title);
runTest(test.title, this.configUrl.resolve(test.input),
this.configUrl.resolve(test.stylesheet),
test.iterations, this);
},
onStop: function()
{
clearTimeout(gTimeout);
this.mCurrentProgress.value = 0;
this.mTotalProgress.value = 0;
this.mCurrentStatus.value = "stopped";
},
displayTest: function(aTitle)
{
this.mTimes = new Array;
aTitle += "\t";
this.mCurrentStatus.value = aTitle;
this.mOutput.value += aTitle;
if (this.mDetail) {
this.mDetailOutput.value += aTitle;
}
},
displayDetailTime: function(aTime)
{
if (this.mDetail) {
this.mDetailOutput.value += aTime + " ms\t";
}
},
displayTotalTime: function()
{
var sum = 0;
for (k = 0; k < this.mTimes.length; k++) {
sum += this.mTimes[k];
}
var mean = sum / this.mTimes.length;
this.mOutput.value += Number(mean).toFixed(2) + " ms\t" + sum + " ms\t";
var variance = 0;
for (k = 0; k < this.mTimes.length; k++) {
var n = this.mTimes[k] - mean;
variance += n*n;
}
variance = Math.sqrt(variance/this.mTimes.length);
this.mOutput.value += Number(variance).toFixed(2)+"\n";
if (this.mDetail) {
this.mDetailOutput.value += "\n";
}
},
runBenchmark: function()
{
enablePrivilege('UniversalXPConnect');
if (!this.testArray) {
if (!this.configUrl) {
this.configUrl = Components.classes[STDURL_CTRID].createInstance(nsIURI);
this.configUrl.spec = document.getElementById('config').value;
}
this.parseConfig();
}
this.mCurrent = 0;
var test = this.testArray[this.mCurrent];
this.mOutput.value = '';
if (this.mDetail) {
this.mDetailOutput.value = '';
}
this.displayTest(test.title);
runTest(test.title, this.configUrl.resolve(test.input),
this.configUrl.resolve(test.stylesheet),
test.iterations, this);
return true;
}
}

View file

@ -0,0 +1,8 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
textbox.out {
white-space: pre;
}

View file

@ -0,0 +1,52 @@
<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="XSLTMark.css" type="text/css"?>
<window id="XSLTMarkHarness"
title="XSLTMark"
onload="view.onLoad()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical">
<script type="application/x-javascript" src="XSLTMark-static.js" />
<script type="application/x-javascript" src="XSLTMark-test.js" />
<script type="application/x-javascript" src="XSLTMark-view.js" />
<hbox>
<groupbox orient="horizontal">
<caption label="test description file" />
<label value=""/><!-- needed, otherwise groupbox fucks up :-( -->
<textbox id="config" persist="value" readonly="true"/>
<button label="browse..." oncommand="view.browseForConfig();" />
</groupbox>
<groupbox orient="horizontal">
<caption label="test control" />
<button label="run..."
oncommand="setTimeout('view.runBenchmark();', 0);" />
<button label="stop" oncommand="view.onStop();" />
</groupbox>
<groupbox orient="horizontal">
<caption label="options" />
<label value="responsiveness: "/>
<menulist label="sloppy">
<menupopup>
<menuitem label="sloppy" selected="true"/>
<menuitem label="bad"/>
</menupopup>
</menulist>
</groupbox>
</hbox>
<hbox>
<textbox id="currentStatus" readonly="true" flex="1"/>
<progressmeter id="currentProgress" mode="normal" value="0" flex="2"/>
<progressmeter id="totalProgress" mode="normal" value="0" flex="2"/>
</hbox>
<hbox flex="1">
<textbox id="transformOutput" class="out" readonly="true" multiline="true" flex="1"/>
</hbox>
<hbox flex="1">
<textbox id="transformDetailedOutput" class="out" readonly="true" multiline="true" flex="1"/>
</hbox>
</window>

View file

@ -0,0 +1,103 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// ----------------------
// DiffDOM(node1,node2)
// ----------------------
var isHTML = false;
function DiffDOM(node1, node2, aIsHTML)
{
isHTML = aIsHTML;
return DiffNodeAndChildren(node1, node2);
}
// namespace attributes in the second node are ignored
const nsreg = /^xmlns[|:\w]/;
// This function does the work of DiffDOM by recursively calling
// itself to explore the tree
function DiffNodeAndChildren(node1, node2)
{
if (!node1 && !node2)
return true;
if (!node1 || !node2)
return ErrorUp("One of the nodes is null", node1, node2);
if (node1.type!=node2.type)
return ErrorUp("Different node types", node1, node2);
var attributes = node2.attributes;
if (attributes && attributes.length) {
var item, name, ns, value, otherValue;
for (var index = 0; index < attributes.length; index++) {
item = attributes.item(index);
ns = item.namespaceURI;
if (ns) {
name = item.localName;
otherValue = node2.getAttributeNS(ns, name);
}
else {
name = item.nodeName;
otherValue = node2.getAttribute(name);
}
value = item.nodeValue;
if (!nsreg.test(name) && otherValue!=value) {
return ErrorUp("Different values for attribute", node1, node2);
}
}
}
else if (node1.attributes && node1.attributes.length) {
return ErrorUp("Different number of attributes", node1, node2);
}
if (isHTML) {
if (node1.nodeName.toLowerCase()!=node2.nodeName.toLowerCase())
return ErrorUp("Different node names", node1, node2);
}
else {
if (node1.nodeName!=node2.nodeName)
return ErrorUp("Different node names", node1, node2);
}
if (node1.nodeValue!=node2.nodeValue)
return ErrorUp("Different node values", node1, node2);
if (!isHTML)
if (node1.namespaceURI!=node2.namespaceURI)
return ErrorUp("Different namespace", node1, node2);
if (node1.hasChildNodes() != node2.hasChildNodes())
return ErrorUp("Different children", node1, node2);
if (node1.childNodes) {
if (node1.childNodes.length != node2.childNodes.length)
return ErrorUp("Different number of children", node1, node2);
for (var child = 0; child < node1.childNodes.length; child++) {
if (!DiffNodeAndChildren(node1.childNodes[child],
node2.childNodes[child])) {
return false;
}
}
}
return true;
}
function ErrorUp(errMsg, node1, node2)
{
dump("Error: "+errMsg+"\n");
if (node1) {
dump("Node 1: "+node1+", ");
if (node1.nodeType == Node.TEXT_NODE)
dump("nodeValue: "+node1.nodeValue+"\n");
else
dump("nodeName: "+node1.namespaceURI+":"+node1.nodeName+"\n");
}
if (node2) {
dump("Node 2: "+node2+", ");
if (node2.nodeType == Node.TEXT_NODE)
dump("nodeValue: "+node2.nodeValue+"\n");
else
dump("nodeName: "+node2.namespaceURI+":"+node2.nodeName+"\n");
}
return false;
}

View file

@ -0,0 +1,85 @@
// ----------------------
// DumpDOM(node)
//
// Call this function to dump the contents of the DOM starting at the specified node.
// Use node = document.documentElement to dump every element of the current document.
// Use node = top.window.document.documentElement to dump every element.
//
// 8-13-99 Updated to dump almost all attributes of every node. There are still some attributes
// that are purposely skipped to make it more readable.
// ----------------------
function DumpDOM(node)
{
dump("--------------------- DumpDOM ---------------------\n");
DumpNodeAndChildren(node, "");
dump("------------------- End DumpDOM -------------------\n");
}
// This function does the work of DumpDOM by recursively calling itself to explore the tree
function DumpNodeAndChildren(node, prefix)
{
dump(prefix + "<" + node.nodeName);
var attributes = node.attributes;
if ( attributes && attributes.length )
{
var item, name, value;
for ( var index = 0; index < attributes.length; index++ )
{
item = attributes.item(index);
name = item.nodeName;
value = item.nodeValue;
if ( (name == 'lazycontent' && value == 'true') ||
(name == 'xulcontentsgenerated' && value == 'true') ||
(name == 'id') ||
(name == 'instanceOf') )
{
// ignore these
}
else
{
dump(" " + name + "=\"" + value + "\"");
}
}
}
if ( node.nodeType == 1 )
{
// id
var text = node.getAttribute('id');
if ( text && text[0] != '$' )
dump(" id=\"" + text + "\"");
}
if ( node.nodeType == Node.TEXT_NODE )
dump(" = \"" + node.data + "\"");
dump(">\n");
// dump IFRAME && FRAME DOM
if ( node.nodeName == "IFRAME" || node.nodeName == "FRAME" )
{
if ( node.name )
{
var wind = top.frames[node.name];
if ( wind && wind.document && wind.document.documentElement )
{
dump(prefix + "----------- " + node.nodeName + " -----------\n");
DumpNodeAndChildren(wind.document.documentElement, prefix + " ");
dump(prefix + "--------- End " + node.nodeName + " ---------\n");
}
}
}
// children of nodes (other than frames)
else if ( node.childNodes )
{
for ( var child = 0; child < node.childNodes.length; child++ )
DumpNodeAndChildren(node.childNodes[child], prefix + " ");
}
}

View file

@ -0,0 +1,22 @@
The buster is a XUL interface to the conformance tests shipped as part of
Xalan. For information about Xalan, please see http://xml.apache.org/.
For your convenience we provide a packed distribution of all needed files
in http://www.axel.pike.org/mozilla/xalan.tar.gz. Please see the included
LICENSE.txt or http://xml.apache.org/dist/LICENSE.txt for terms of
distributing those files.
To use the buster, open buster.xul with an XSLT enabled Mozilla.
Open the rdf index file shipped with the test package into the
"Xalan index", and the available tests will show up as a tree.
Once you have selected the tests you're interested in, press the button
"run checked tests", and all the tests will be run.
You can save the results into an rdf, and load it for comparison and
regression hunting.
DiffDOM tries to find out, which tests failed, and will DumpDOM both the
result and the reference solution. Not all reference solutions load
properly, those need manual love.
Good luck and fun
Axel Hecht <axel@pike.org>

View file

@ -0,0 +1,81 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const kFileOutStreamCID = "@mozilla.org/network/file-output-stream;1";
const nsIFileOutputStream = Components.interfaces.nsIFileOutputStream;
var cmdFileController =
{
supportsCommand: function(aCommand)
{
switch(aCommand) {
case 'cmd_fl_save':
case 'cmd_fl_import':
return true;
default:
}
return false;
},
isCommandEnabled: function(aCommand)
{
return this.supportsCommand(aCommand);
},
doCommand: function(aCommand)
{
switch(aCommand) {
case 'cmd_fl_save':
var sink = new Object;
sink.write = function(aContent, aCount)
{
// replace NC:succ with NC:orig_succ,
// so the rdf stuff differs
var content = aContent.replace(/NC:succ/g,"NC:orig_succ");
content = content.replace(/NC:failCount/g,"NC:orig_failCount");
this.mSink.write(content, content.length);
return aCount;
};
var fp = doCreateRDFFP('Xalan results',
nsIFilePicker.modeSave);
var res = fp.show();
if (res == nsIFilePicker.returnOK ||
res == nsIFilePicker.returnReplace) {
var serial = doCreate(kRDFXMLSerializerID,
nsIRDFXMLSerializer);
serial.init(view.mResultDS);
serial.QueryInterface(nsIRDFXMLSource);
var fl = fp.file;
var fstream = doCreate(kFileOutStreamCID,
nsIFileOutputStream);
fstream.init(fl, 26, 420, 0);
sink.mSink = fstream;
serial.Serialize(sink);
}
break;
case 'cmd_fl_import':
var fp = doCreateRDFFP('Previous Xalan results',
nsIFilePicker.modeLoad);
var res = fp.show();
if (res == nsIFilePicker.returnOK) {
var fl = fp.file;
if (view.mPreviousResultDS) {
view.database.RemoveDataSource(view.mPreviousResultDS);
view.mPreviousResultDS = null;
}
view.mPreviousResultDS = kRDFSvc.GetDataSource(fp.fileURL.spec);
view.database.AddDataSource(view.mPreviousResultDS);
}
document.getElementById('obs_orig_success')
.setAttribute('hidden','false');
break;
default:
alert('Unknown Command'+aCommand);
}
}
};
registerController(cmdFileController);

View file

@ -0,0 +1,37 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var xalan_field;
function onLoad()
{
view.tree = document.getElementById('out');
view.boxObject = view.tree.boxObject;
{
view.mIframe = document.getElementById('hiddenHtml');
view.mIframe.webNavigation.allowPlugins = false;
view.mIframe.webNavigation.allowJavascript = false;
view.mIframe.webNavigation.allowMetaRedirects = false;
view.mIframe.webNavigation.allowImages = false;
}
view.database = view.tree.database;
view.builder = view.tree.builder.QueryInterface(nsIXULTemplateBuilder);
view.builder.QueryInterface(nsIXULTreeBuilder);
runItem.prototype.kDatabase = view.database;
xalan_field = document.getElementById("xalan_rdf");
var persistedUrl = xalan_field.getAttribute('url');
if (persistedUrl) {
view.xalan_url = persistedUrl;
xalan_field.value = persistedUrl;
}
view.setDataSource();
return true;
}
function onUnload()
{
if (xalan_field)
xalan_field.setAttribute('url', xalan_field.value);
}

View file

@ -0,0 +1,87 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// helper function to shortcut component creation
function doCreate(aContract, aInterface)
{
return Components.classes[aContract].createInstance(aInterface);
}
// for the items, loading a text file
const IOSERVICE_CTRID = "@mozilla.org/network/io-service;1";
const nsIIOService = Components.interfaces.nsIIOService;
const SIS_CTRID = "@mozilla.org/scriptableinputstream;1"
const nsISIS = Components.interfaces.nsIScriptableInputStream;
// rdf foo, onload handler
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
const kRDFInMemContractID =
"@mozilla.org/rdf/datasource;1?name=in-memory-datasource";
const kRDFContUtilsID = "@mozilla.org/rdf/container-utils;1";
const kRDFXMLSerializerID = "@mozilla.org/rdf/xml-serializer;1";
const kIOSvcContractID = "@mozilla.org/network/io-service;1";
const kStandardURL = Components.classes["@mozilla.org/network/standard-url;1"];
const nsIURL = Components.interfaces.nsIURL;
const nsIStandardURL = Components.interfaces.nsIStandardURL;
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const nsIXULTreeBuilder = Components.interfaces.nsIXULTreeBuilder;
const nsIXULTemplateBuilder = Components.interfaces.nsIXULTemplateBuilder;
const kIOSvc = Components.classes[kIOSvcContractID]
.getService(Components.interfaces.nsIIOService);
const nsIRDFService = Components.interfaces.nsIRDFService;
const nsIRDFDataSource = Components.interfaces.nsIRDFDataSource;
const nsIRDFRemoteDataSource = Components.interfaces.nsIRDFRemoteDataSource;
const nsIRDFPurgeableDataSource =
Components.interfaces.nsIRDFPurgeableDataSource;
const nsIRDFResource = Components.interfaces.nsIRDFResource;
const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral;
const nsIRDFInt = Components.interfaces.nsIRDFInt;
const nsIRDFContainerUtils = Components.interfaces.nsIRDFContainerUtils;
const nsIRDFXMLSerializer = Components.interfaces.nsIRDFXMLSerializer;
const nsIRDFXMLSource = Components.interfaces.nsIRDFXMLSource;
const kRDFSvc =
Components.classes[kRDFSvcContractID].getService(nsIRDFService);
const krTypeCat = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#category");
const krTypeFailCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#failCount");
const krTypeName = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#name");
const krTypeSucc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#succ");
const krTypeOrigSucc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_succ");
const krTypeOrigFailCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_failCount");
const krTypeOrigSuccCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_succCount");
const krTypePath = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#path");
const krTypeParent = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#parent");
const krTypePurp = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#purp");
const krTypeSuccCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#succCount");
const kGood = kRDFSvc.GetLiteral("yes");
const kBad = kRDFSvc.GetLiteral("no");
const kMixed = kRDFSvc.GetLiteral("+-");
const kContUtils = doCreate(kRDFContUtilsID, nsIRDFContainerUtils);
function doCreateRDFFP(aTitle, aMode)
{
var fp = doCreate("@mozilla.org/filepicker;1", nsIFilePicker);
fp.init(window, aTitle, aMode);
fp.appendFilter('*.rdf', '*.rdf');
fp.appendFilters(nsIFilePicker.filterAll);
return fp;
}
function goDoCommand(aCommand)
{
try {
var controller =
top.document.commandDispatcher.getControllerForCommand(aCommand);
if (controller && controller.isCommandEnabled(aCommand))
controller.doCommand(aCommand);
}
catch(e) {
dump("An error "+e+" occurred executing the "+aCommand+" command\n");
}
}
function registerController(aController)
{
top.controllers.appendController(aController);
}

View file

@ -0,0 +1,356 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/NetUtil.jsm");
var parser = new DOMParser();
var methodExpr = (new XPathEvaluator).createExpression("xsl:output/@method",
{
lookupNamespaceURI: function(aPrefix)
{
if (aPrefix == "xsl")
return "http://www.w3.org/1999/XSL/Transform";
return "";
}
});
const nsIWebProgListener = Components.interfaces.nsIWebProgressListener;
var runQueue =
{
mArray : new Array(),
push : function(aRunItem)
{
this.mArray.push(aRunItem);
},
observe : function(aSubject, aTopic, aData)
{
var item = this.mArray.shift();
if (item) {
item.run(this);
}
},
run : function()
{
this.observe(null,'','');
}
}
var itemCache =
{
mArray : new Array(),
getItem : function(aResource)
{
// Directory selected
if (kContUtils.IsSeq(runItem.prototype.kDatabase, aResource)) {
var aSeq = kContUtils.MakeSeq(runItem.prototype.kDatabase, aResource);
dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n");
var child, children = aSeq.GetElements();
var m = 0, first;
while (children.hasMoreElements()) {
m += 1;
child = children.getNext();
child.QueryInterface(nsIRDFResource);
if (!first)
first = itemCache.getItem(child);
else
itemCache.getItem(child);
}
return first;
}
if (aResource.Value in this.mArray) {
return this.mArray[aResource.Value];
}
var retItem = new runItem(aResource);
this.mArray[aResource.Value] = retItem;
runQueue.push(retItem);
return retItem;
},
rerunItem : function(aResource, aObserver)
{
var anItem = new runItem(aResource);
this.mArray[aResource.Value] = anItem;
anItem.run(aObserver);
},
observe : function(aSubject, aTopic, aData)
{
this.mRun += 1;
if (aTopic == "success") {
if (aData == "yes") {
this.mGood += 1;
}
else {
this.mFalse +=1;
}
}
}
}
function runItem(aResource)
{
this.mResource = aResource;
// Directory selected
if (kContUtils.IsSeq(this.kDatabase,this.mResource)) {
var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource);
dump("THIS SHOULDN'T HAPPEN\n");
var child, children = aSeq.GetElements();
var m = 0;
while (children.hasMoreElements()) {
m += 1;
child = children.getNext();
child.QueryInterface(nsIRDFResource);
itemCache.getItem(child);
}
}
}
runItem.prototype =
{
// RDF resource associated with this test
mResource : null,
// XML documents for the XSLT transformation
mSourceDoc : null,
mStyleDoc : null,
mResDoc : null,
// XML or plaintext document for the reference
mRefDoc : null,
// bitfield signaling the loaded documents
mLoaded : 0,
kSource : 1,
kStyle : 2,
kReference : 4,
// a observer, potential argument to run()
mObserver : null,
mSuccess : null,
mMethod : 'xml',
// XSLTProcessor, shared by the instances
kProcessor : new XSLTProcessor(),
kXalan : kStandardURL.createInstance(nsIURL),
kDatabase : null,
kObservers : new Array(),
run : function(aObserver)
{
if (aObserver && typeof(aObserver)=='function' ||
(typeof(aObserver)=='object' &&
typeof(aObserver.observe)=='function')) {
this.mObserver=aObserver;
}
var name = this.kDatabase.GetTarget(this.mResource, krTypeName, true);
if (name) {
var cat = this.kDatabase.GetTarget(this.mResource, krTypeCat, true);
var path = this.kDatabase.GetTarget(this.mResource, krTypePath, true);
cat = cat.QueryInterface(nsIRDFLiteral);
name = name.QueryInterface(nsIRDFLiteral);
path = path.QueryInterface(nsIRDFLiteral);
var xalan_fl = this.kXalan.resolve(cat.Value+"/"+path.Value);
var xalan_ref = this.kXalan.resolve(cat.Value+"-gold/"+path.Value);
this.mRefURL =
this.kXalan.resolve(cat.Value + "-gold/" + path.Value + ".out");
dump(name.Value+" links to "+xalan_fl+"\n");
}
// Directory selected
if (kContUtils.IsSeq(this.kDatabase,this.mResource)) {
return;
var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource);
dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n");
var child, children = aSeq.GetElements();
var m = 0;
while (children.hasMoreElements()) {
m += 1;
child = children.getNext();
child.QueryInterface(nsIRDFResource);
}
}
this.mSourceDoc = document.implementation.createDocument('', '', null);
this.mSourceDoc.addEventListener("load",this.onload(1),false);
this.mSourceDoc.load(xalan_fl+".xml");
this.mStyleDoc = document.implementation.createDocument('', '', null);
this.mStyleDoc.addEventListener("load",this.styleLoaded(),false);
this.mStyleDoc.load(xalan_fl+".xsl");
},
// nsIWebProgressListener
QueryInterface: function(aIID)
{
return this;
},
onStateChange: function(aProg, aRequest, aFlags, aStatus)
{
if ((aFlags & nsIWebProgListener.STATE_STOP) &&
(aFlags & nsIWebProgListener.STATE_IS_DOCUMENT)) {
aProg.removeProgressListener(this);
this.mRefDoc = document.getElementById('hiddenHtml').contentDocument;
this.fileLoaded(4);
}
},
onProgressChange: function(aProg, b,c,d,e,f)
{
},
onLocationChange: function(aProg, aRequest, aURI, aFlags)
{
},
onStatusChange: function(aProg, aRequest, aStatus, aMessage)
{
},
onSecurityChange: function(aWebProgress, aRequest, aState)
{
},
// onload handler helper
onload : function(file)
{
var self = this;
return function(e)
{
return self.fileLoaded(file);
};
},
styleLoaded : function()
{
var self = this;
return function(e)
{
return self.styleLoadedHelper();
};
},
styleLoadedHelper : function()
{
var method = methodExpr.evaluate(this.mStyleDoc.documentElement, 2,
null).stringValue;
var refContent;
if (!method) {
// implicit method, guess from result
refContent = this.loadTextFile(this.mRefURL);
if (refContent.match(/^\s*<html/gi)) {
method = 'html';
}
else {
method = 'xml';
}
}
this.mMethod = method;
switch (method) {
case 'xml':
if (!refContent) {
refContent = this.loadTextFile(this.mRefURL);
}
this.mRefDoc = parser.parseFromString(refContent, 'application/xml');
this.mLoaded += 4;
break;
case 'html':
view.loadHtml(this.mRefURL, this);
break;
case 'text':
if (!refContent) {
refContent = this.loadTextFile(this.mRefURL);
}
const ns = 'http://www.mozilla.org/TransforMiix';
const qn = 'transformiix:result';
this.mRefDoc =
document.implementation.createDocument(ns, qn, null);
var txt = this.mRefDoc.createTextNode(refContent);
this.mRefDoc.documentElement.appendChild(txt);
this.mLoaded += 4;
break;
default:
throw "unkown XSLT output method";
}
this.fileLoaded(2)
},
fileLoaded : function(mask)
{
this.mLoaded += mask;
if (this.mLoaded < 7) {
return;
}
this.doTransform();
},
doTransform : function()
{
this.kProcessor.reset();
try {
this.kProcessor.importStylesheet(this.mStyleDoc);
this.mResDoc =
this.kProcessor.transformToDocument(this.mSourceDoc);
this.mRefDoc.normalize();
isGood = DiffDOM(this.mResDoc.documentElement,
this.mRefDoc.documentElement,
this.mMethod == 'html');
} catch (e) {
isGood = false;
};
dump("This succeeded. "+isGood+"\n");
isGood = isGood.toString();
for (var i=0; i<this.kObservers.length; i++) {
var aObs = this.kObservers[i];
if (typeof(aObs)=='object' && typeof(aObs.observe)=='function') {
aObs.observe(this.mResource, 'success', isGood);
}
else if (typeof(aObs)=='function') {
aObs(this.mResource, 'success', isGood);
}
}
if (this.mObserver) {
if (typeof(this.mObserver)=='object') {
this.mObserver.observe(this.mResource, 'success', isGood);
}
else {
this.mObserver(this.mResource, 'success', isGood);
}
}
},
loadTextFile : function(url)
{
var chan = NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true
});
var instream = doCreate(SIS_CTRID, nsISIS);
instream.init(chan.open2());
return instream.read(instream.available());
}
}
runItem.prototype.kXalan.QueryInterface(nsIStandardURL);
var cmdTestController =
{
supportsCommand: function(aCommand)
{
switch(aCommand) {
case 'cmd_tst_run':
case 'cmd_tst_runall':
return true;
default:
}
return false;
},
isCommandEnabled: function(aCommand)
{
return this.supportsCommand(aCommand);
},
doCommand: function(aCommand)
{
switch(aCommand) {
case 'cmd_tst_run':
dump("cmd_tst_run\n");
break;
case 'cmd_tst_runall':
dump("cmd_tst_runall\n");
var tst_run = document.getElementById('cmd_tst_run');
tst_run.doCommand();
default:
}
}
};
registerController(cmdTestController);

View file

@ -0,0 +1,193 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var view =
{
onRun : function()
{
runQueue.mArray = new Array();
var sels = this.boxObject.view.selection,a=new Object(),b=new Object(),k;
var rowResource, name, path;
for (k=0;k<sels.getRangeCount();k++){
sels.getRangeAt(k,a,b);
for (var l=a.value;l<=b.value;l++) {
rowResource = this.builder.getResourceAtIndex(l);
itemCache.getItem(rowResource);
}
}
runQueue.run();
},
displayTest : function()
{
var current = this.boxObject.view.selection.currentIndex;
var rowResource = this.builder.getResourceAtIndex(current);
var item = itemCache.getItem(rowResource);
},
browseForRDF : function()
{
var fp = doCreateRDFFP('Xalan Description File',
nsIFilePicker.modeOpen);
var res = fp.show();
if (res == nsIFilePicker.returnOK) {
var furl = fp.fileURL;
this.setDataSource(fp.fileURL.spec);
}
},
dump_Good : function()
{
var enumi = this.mResultDS.GetSources(krTypeSucc, kGood, true);
var k = 0;
while (enumi.hasMoreElements()) {
k += 1;
dump(enumi.getNext().QueryInterface(nsIRDFResource).Value+"\n");
}
dump("found "+k+" good tests\n");
},
prune_ds : function()
{
if (this.mResultDS) {
this.mResultDS.QueryInterface(nsIRDFPurgeableDataSource).Sweep();
}
regressionStats.init()
itemCache.mArray = new Array();
},
setDataSource : function(aSpec)
{
var baseSpec;
if (aSpec) {
baseSpec = aSpec;
}
else {
baseSpec = document.getElementById("xalan_rdf").value;
}
if (this.mXalanDS && this.mXalanDS.URI == baseSpec) {
this.mXalanDS.QueryInterface(nsIRDFRemoteDataSource);
this.mXalanDS.Refresh(true);
}
else {
if (this.mXalanDS) {
this.database.RemoveDataSource(view.mXalanDS);
}
this.mXalanDS = kRDFSvc.GetDataSourceBlocking(baseSpec);
if (!this.mXalanDS) {
alert("Unable do load DataSource: "+baseSpec);
return;
}
this.database.AddDataSource(this.mXalanDS);
}
regressionStats.init();
if (!this.mResultDS) {
this.mResultDS = doCreate(kRDFInMemContractID,
nsIRDFDataSource);
this.database.AddDataSource(view.mResultDS);
if (!this.mResultDS) {
alert("Unable to create result InMemDatasource");
return;
}
}
this.builder.rebuild();
document.getElementById("xalan_rdf").value = baseSpec;
runItem.prototype.kXalan.init(runItem.prototype.kXalan.URLTYPE_STANDARD,
0, baseSpec, null, null);
},
loadHtml : function(aUrl, aListener)
{
const nsIIRequestor = Components.interfaces.nsIInterfaceRequestor;
const nsIWebProgress = Components.interfaces.nsIWebProgress;
var req = this.mIframe.webNavigation.QueryInterface(nsIIRequestor);
var prog = req.getInterface(nsIWebProgress);
prog.addProgressListener(aListener, nsIWebProgress.NOTIFY_ALL);
this.mIframe.webNavigation.loadURI(aUrl, 0,null,null,null);
},
fillItemContext : function()
{
var index = view.boxObject.view.selection.currentIndex;
var res = view.builder.getResourceAtIndex(index);
var purp = view.mXalanDS.GetTarget(res, krTypePurp, true);
return (purp != null);
}
}
regressionStats =
{
observe: function(aSubject, aTopic, aData)
{
if (aTopic != 'success') {
return;
}
var arc = (aData == "true") ? krTypeSuccCount : krTypeFailCount;
this.assertNewCount(aSubject, arc, 1);
},
init: function()
{
if (this.mRegressionDS) {
this.mRegressionDS.QueryInterface(nsIRDFPurgeableDataSource).Sweep();
}
else {
this.mRegressionDS =
doCreate(kRDFInMemContractID, nsIRDFDataSource);
view.database.AddDataSource(this.mRegressionDS);
}
},
getParent: function(aDS, aSource)
{
// parent chached?
var parent = this.mRegressionDS.GetTarget(aSource, krTypeParent, true);
if (!parent) {
var labels = view.mXalanDS.ArcLabelsIn(aSource);
while (labels.hasMoreElements()) {
var arc = labels.getNext().QueryInterface(nsIRDFResource);
if (arc.Value.match(this.mChildRE)) {
parent = view.mXalanDS.GetSource(arc, aSource, true);
// cache the parent
this.mRegressionDS.Assert(aSource, krTypeParent,
parent, true);
}
}
}
return parent;
},
assertNewCount: function(aSource, aArc, aIncrement)
{
var root = kRDFSvc.GetResource('urn:root');
var count = 0;
// parent chached?
var parent = this.getParent(view.XalanDS, aSource);
while (parent && !parent.EqualsNode(root)) {
var countRes = view.mResultDS.GetTarget(parent, aArc, true);
if (countRes) {
count = countRes.QueryInterface(nsIRDFInt).Value;
}
var newCountRes = kRDFSvc.GetIntLiteral(count + aIncrement);
if (!newCountRes) {
return;
}
if (countRes) {
view.mResultDS.Change(parent, aArc, countRes, newCountRes);
}
else {
view.mResultDS.Assert(parent, aArc, newCountRes, true);
}
parent = this.getParent(view.XalanDS, parent);
}
},
mRegressionDS: 0,
mChildRE: /http:\/\/www\.w3\.org\/1999\/02\/22-rdf-syntax-ns#_/
}
function rdfObserve(aSubject, aTopic, aData)
{
if (aTopic == "success") {
var target = (aData == "true") ? kGood : kBad;
view.mResultDS.Assert(aSubject, krTypeSucc, target, true);
regressionStats.observe(aSubject, aTopic, aData);
}
}
runItem.prototype.kObservers.push(rdfObserve);

View file

@ -0,0 +1,20 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
label.head {
padding: 5px;
font-size: medium;
font-weight: bold;
}
treechildren::-moz-tree-cell(success yes)
{
background-color: green ;
}
treechildren::-moz-tree-cell(success no)
{
background-color: red ;
}

View file

@ -0,0 +1,196 @@
<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="buster.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
<window id="XalanBuster"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="onLoad()" onunload="onUnload()"
title="Xalan testcase harness"
persist="width,height"
width="800"
height="600"
orient="vertical">
<script type="application/x-javascript" src="buster-statics.js" />
<script type="application/x-javascript" src="buster-test.js" />
<script type="application/x-javascript" src="buster-view.js" />
<script type="application/x-javascript" src="buster-handlers.js" />
<script type="application/x-javascript" src="result-view.js" />
<script type="application/x-javascript" src="buster-files.js" />
<script type="application/x-javascript" src="DumpDOM.js" />
<script type="application/x-javascript" src="DiffDOM.js" />
<commands id="busterKing">
<commandset id="buster_file_cmds">
<command id="cmd_fl_save" oncommand="goDoCommand('cmd_fl_save')" />
<command id="cmd_fl_import" oncommand="goDoCommand('cmd_fl_import')"/>
</commandset>
<commandset id="buster_test_cmds">
<command id="cmd_tst_run" oncommand="goDoCommand('cmd_tst_run')" />
<command id="cmd_tst_runall" oncommand="goDoCommand('cmd_tst_runall')" />
</commandset>
<commandset id="commands">
<command id="cmd_quit"/>
<command id="cmd_close" oncommand="window.close();"/>
</commandset>
</commands>
<keyset>
<key id="key_quit"/>
<key id="key_close"/>
</keyset>
<broadcasterset>
<broadcaster id="obs_orig_success" hidden="true"/>
<broadcaster id="not_yet" disabled="true"/>
</broadcasterset>
<menubar>
<menu id="menu_File" label="File" accesskey="f">
<menupopup id="menu_FilePopup">
<menuitem label="Save results ..." accesskey="s"
observes="cmd_fl_save"/>
<menuitem label="Import results ..." accesskey="i"
observes="cmd_fl_import"/>
<menuitem id="menu_close"/>
</menupopup>
</menu>
<menu id="busterTests" label="Tests" accesskey="t">
<menupopup id="tests-popup">
<menuitem label="run a test" accesskey="r"
observes="cmd_tst_run"/>
<menuitem label="run all tests" accesskey="a"
observes="cmd_tst_runall"/>
</menupopup>
</menu>
</menubar>
<popupset>
<popup id="itemcontext" onpopupshowing="return view.fillItemContext();">
<menuitem label="View Test" oncommand="onNewResultView(event)"/>
</popup>
</popupset>
<hbox>
<button label="check all" oncommand="check(true)" observes="not_yet"/>
<button label="uncheck all" oncommand="check(false)" observes="not_yet"/>
<button label="reset success" oncommand="view.prune_ds()" />
<button label="run checked tests" oncommand="view.onRun()" />
</hbox>
<hbox>
<label value="Xalan index: " class="head"/>
<textbox id="xalan_rdf" persist="url" crop="end" size="40"/>
<button label="browse..." oncommand="view.browseForRDF()" />
</hbox>
<hbox>
<groupbox orient="horizontal"><caption label="search" />
<button label="Search for " oncommand="select()" observes="not_yet"/>
<textbox style="width: 10em;" id="search-name" persist="value" /><label value=" in " />
<menulist id="search-field" persist="data" observes="not_yet">
<menupopup>
<menuitem value="1" label="Name" />
<menuitem value="2" label="Purpose" />
<menuitem value="3" label="Comment" />
</menupopup>
</menulist>
</groupbox>
<spacer flex="1" /></hbox>
<tree id="out" flex="1" flags="dont-build-content" hidecolumnpicker="true"
datasources="rdf:null" ref="urn:root" context="itemcontext">
<treecols>
<treecol id="NameColumn" flex="1" label="Name" sort="?name"
primary="true" />
<splitter class="tree-splitter" />
<treecol id="PurpsColumn" flex="2" label="Purpose" sort="?purp" />
<splitter class="tree-splitter" />
<treecol id="SuccessColumn" flex="0" label="Success" />
<splitter class="tree-splitter" observes="obs_orig_success" />
<treecol id="OrigSuccessColumn" flex="0" label="Previously"
observes="obs_orig_success" />
</treecols>
<template>
<rule>
<conditions>
<content uri="?uri" />
<member container="?uri" child="?subheading" />
<triple subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#purp"
object="?purp" />
</conditions>
<bindings>
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#name"
object="?name" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#succ"
object="?succ" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#orig_succ"
object="?orig_succ" />
</bindings>
<action>
<treechildren>
<treeitem uri="?subheading">
<treerow>
<treecell ref="NameColumn" label="?name" />
<treecell ref="PurpsColumn" label="?purp" />
<treecell ref="SuccessColumn" label="?succ"
properties="success ?succ"/>
<treecell ref="OrigSuccessColumn" label="?orig_succ"
properties="success ?orig_succ" />
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
<rule>
<conditions>
<content uri="?uri" />
<member container="?uri" child="?subheading" />
</conditions>
<bindings>
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#dir"
object="?dir" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#succCount"
object="?succ" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#failCount"
object="?fail" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#orig_succCount"
object="?orig_succ" />
<binding subject="?subheading"
predicate="http://home.netscape.com/NC-rdf#orig_failCount"
object="?orig_fail" />
</bindings>
<action>
<treechildren>
<treeitem uri="?subheading">
<treerow>
<treecell ref="NameColumn" label="?dir" />
<treecell ref="PurpsColumn" label="" />
<treecell ref="SuccessColumn" label="?succ / ?fail" />
<treecell ref="OrigSuccessColumn" label="?orig_succ / ?orig_fail" />
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
</template>
</tree>
<iframe style="visibility:hidden; height:0px;" id="hiddenHtml" />
</window>

View file

@ -0,0 +1,95 @@
use File::Spec;
my(@chunks, @list, $entry, $main_cats, $spacing);
@list = ('conf', 'perf');
foreach $entry (@list) {
$main_cats .= " <rdf:li><rdf:Description about=\"urn:x-buster:$entry\" nc:dir=\"$entry\" /></rdf:li>\n";
go_in($entry, '', $entry);
}
if ($ARGV[0]) {
open OUTPUT, ">$ARGV[0]";
}
else {
open OUTPUT, ">xalan.rdf";
};
select(OUTPUT);
print '<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:nc="http://home.netscape.com/NC-rdf#">
<rdf:Seq about="urn:root">
' . $main_cats . ' </rdf:Seq>
';
print join('',@chunks);
print '</rdf:RDF>
';
exit 0;
sub go_in {
my($current, $about, $cat) = @_;
my (@list, $entry, @subdirs, @files, @purps, $rdf);
chdir $current;
@list = <*>;
LOOP: foreach $entry (@list) {
next LOOP if $entry=~/^CVS$/;
if (! -d $entry) {
if ($entry=~/^($current.*)\.xsl$/) {
local $source = $entry;
$source=~s/xsl$/xml/;
next LOOP if ! -f $source;
$entry=~/^($current.*)\.xsl$/;
push(@files, $1);
local ($purp, $purp_open);
open STYLE, $entry;
$purp_open = 0;
while (<STYLE>) {
if (/<!--\s+purpose: (.+)\s*-->/i) {
$purp .= $1;
}
elsif (/<!--\s+purpose: (.+)\s*$/i) {
$purp_open = 1;
$purp .= $1;
}
elsif ($purp_open) {
if (/\s*(\s.+)\s*-->/) {
$purp_open = 0;
$purp .= $1;
}
elsif (/\s*(\s.+)\s*$/) {
$purp .= $1;
}
}
}
$purp=~s/"/'/g; $purp=~s/&/&amp;/g; $purp=~s/</&lt;/g;
$purp=~s/\r/ /g; $purp=~s/\s\s/ /g; $purp=~s/\s$//g;
push(@purps, $purp);
}
}
else {
push(@subdirs, $entry);
}
}
if (@subdirs > 0 || @files > 0) {
my $topic = $about.$current; $topic=~s/\///g;
$rdf = ' <rdf:Seq about="urn:x-buster:'.$topic."\">\n";
foreach $entry (@subdirs) {
if (go_in($entry, $about.$current.'/', $cat)) {
my $id = 'urn:x-buster:'.$about.$current.$entry; $id=~s/\///g;
$rdf .= " <rdf:li><rdf:Description about=\"$id\" nc:dir=\"$entry\" /></rdf:li>\n";
}
}
for (my $i=0; $i < @files; $i++) {
my $uri = $about.$current.'/'.$files[$i];
$uri=~s/[^\/]+\///;
my $id = $uri; $id=~s/\///g;
$rdf .= " <rdf:li><rdf:Description about=\"urn:x-buster:$files[$i]\" nc:name=\"$files[$i]\" nc:purp=\"$purps[$i]\" nc:path=\"$uri\" nc:category=\"$cat\" /></rdf:li>\n";
}
$rdf .= " </rdf:Seq>\n";
push(@chunks, $rdf);
}
chdir File::Spec->updir;
return (@subdirs > 0 || @files > 0);
}

View file

@ -0,0 +1,17 @@
const X_APP = "Buster";
const X_VER = "2.0"
const X_JAR_FILE = "xslt-qa.jar";
var err = initInstall("Install " + X_APP, X_APP, X_VER);
logComment("initInstall: " + err);
logComment( "Installation started ..." );
addFile("We're on our way ...", X_JAR_FILE, getFolder("chrome"), "");
registerChrome(CONTENT|DELAYED_CHROME, getFolder("chrome", X_JAR_FILE), "content/xslt-qa/");
err = getLastError();
if (err == SUCCESS) {
performInstall();
alert("Please restart Mozilla");
}
else {
cancelInstall();
}

View file

@ -0,0 +1,18 @@
xslt-qa.jar:
% content xslt-qa %content/xslt-qa/
% overlay chrome://communicator/content/tasksOverlay.xul chrome://xslt-qa/content/xslt-qa-overlay.xul
content/xslt-qa/xslt-qa-overlay.xul
content/xslt-qa/xslt-qa-overlay.js
content/xslt-qa/buster/buster.xul
content/xslt-qa/buster/buster.css
content/xslt-qa/buster/buster-statics.js
content/xslt-qa/buster/buster-handlers.js
content/xslt-qa/buster/buster-files.js
content/xslt-qa/buster/buster-test.js
content/xslt-qa/buster/buster-view.js
content/xslt-qa/buster/result-view.xul
content/xslt-qa/buster/result-inspector.xul
content/xslt-qa/buster/result-view.css
content/xslt-qa/buster/result-view.js
content/xslt-qa/buster/DumpDOM.js
content/xslt-qa/buster/DiffDOM.js

View file

@ -0,0 +1,37 @@
<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE window [
<!ENTITY % dtd1 SYSTEM "chrome://inspector/locale/inspector.dtd"> %dtd1;
<!ENTITY % dtd2 SYSTEM "chrome://inspector/content/util.dtd"> %dtd2;
]>
<?xul-overlay href="chrome://inspector/content/commandOverlay.xul"?>
<?xul-overlay href="chrome://inspector/content/keysetOverlay.xul"?>
<?xul-overlay href="chrome://inspector/content/popupOverlay.xul"?>
<?xml-stylesheet href="chrome://inspector/skin/inspectorWindow.css"?>
<window class="color-dialog"
title="&Inspector.title;"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://inspector/content/ViewerRegistry.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/utils.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/jsutil/xpcom/XPCU.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/jsutil/rdf/RDFU.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/jsutil/rdf/RDFArray.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/jsutil/events/ObserverManager.js"/>
<script type="application/x-javascript" src="chrome://inspector/content/jsutil/xul/FrameExchange.js"/>
<commandset id="cmdsGlobalCommands"/>
<keyset id="ksGlobalKeyset"/>
<popupset id="ppsViewerPopupset"/>
<domi-panelset id="bxPanelSet" flex="1" viewercommandset="cmdsGlobalCommands">
<domi-panel title="&bxDocPanel.title;" flex="1"/>
</domi-panelset>
</window>

View file

@ -0,0 +1,16 @@
label.heading {
font-size: medium;
font-weight: bold;
}
button.close {
font-size: small;
}
iframe {
padding-left: 10px;
}
vbox.hidden {
display: none;
}

View file

@ -0,0 +1,105 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function onNewResultView(event)
{
dump("onNewResultView\n");
const db = runItem.prototype.kDatabase;
const kXalan = runItem.prototype.kXalan;
var index = view.boxObject.view.selection.currentIndex;
var res = view.builder.getResourceAtIndex(index);
var name = db.GetTarget(res, krTypeName, true);
if (!name) {
return false;
}
var cat = db.GetTarget(res, krTypeCat, true);
var path = db.GetTarget(res, krTypePath, true);
cat = cat.QueryInterface(nsIRDFLiteral);
name = name.QueryInterface(nsIRDFLiteral);
path = path.QueryInterface(nsIRDFLiteral);
xalan_fl = kXalan.resolve(cat.Value+"/"+path.Value);
xalan_ref = kXalan.resolve(cat.Value+"-gold/"+path.Value);
var currentResultItem = new Object();
currentResultItem.testpath = xalan_fl;
currentResultItem.refpath = xalan_ref;
var currentRunItem = itemCache.getItem(res);
// XXX todo, keep a list of these windows, so that we can close them.
resultWin = window.openDialog('result-view.xul','_blank',
'chrome,resizable,dialog=no',
currentResultItem, currentRunItem);
return true;
}
var refInspector;
var resInspector;
function onResultViewLoad(event)
{
dump("onResultViewLoad\n");
aResultItem = window.arguments[0];
aRunItem = window.arguments[1];
var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
document.getElementById('src').webNavigation.loadURI('view-source:'+
aResultItem.testpath+'.xml', loadFlags, null, null, null);
document.getElementById('style').webNavigation.loadURI('view-source:'+
aResultItem.testpath+'.xsl', loadFlags, null, null, null);
if (aRunItem && aRunItem.mRefDoc && aRunItem.mResDoc) {
document.getElementById("refSourceBox").setAttribute("class", "hidden");
refInspector = new ObjectApp();
refInspector.initialize("refInsp", aRunItem.mRefDoc);
resInspector = new ObjectApp();
resInspector.initialize("resInsp", aRunItem.mResDoc);
}
else {
document.getElementById("inspectorBox").setAttribute("class", "hidden");
document.getElementById('ref').webNavigation.loadURI('view-source:'+
aResultItem.refpath+'.out', loadFlags, null, null, null);
}
return true;
}
function onResultViewUnload(event)
{
dump("onResultUnload\n");
}
function ObjectApp()
{
}
ObjectApp.prototype =
{
mDoc: null,
mPanelSet: null,
initialize: function(aId, aDoc)
{
this.mDoc = aDoc;
this.mPanelSet = document.getElementById(aId).contentDocument.getElementById("bxPanelSet");
this.mPanelSet.addObserver("panelsetready", this, false);
this.mPanelSet.initialize();
},
doViewerCommand: function(aCommand)
{
this.mPanelSet.execCommand(aCommand);
},
getViewer: function(aUID)
{
return this.mPanelSet.registry.getViewerByUID(aUID);
},
onEvent: function(aEvent)
{
switch (aEvent.type) {
case "panelsetready":
{
this.mPanelSet.getPanel(0).subject = this.mDoc;
}
}
}
};

View file

@ -0,0 +1,46 @@
<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xml-stylesheet href="result-view.css" type="text/css"?>
<window id="buster-result-view" title="Xalan testcase details"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical" persist="width height"
onload="onResultViewLoad()" onunload="onResultViewUnload()">
<script type="application/x-javascript" src="DumpDOM.js" />
<script type="application/x-javascript" src="buster-statics.js" />
<script type="application/x-javascript" src="buster-test.js" />
<script type="application/x-javascript" src="result-view.js" />
<hbox>
<button class="close" label="close this window"
oncommand="window.close()" />
</hbox>
<vbox flex="1">
<label class="heading" value="XML Source:" />
<iframe flex="1" id="src" />
</vbox>
<vbox flex="1">
<label class="heading" value="XSL Source:" />
<iframe flex="1" id="style" />
</vbox>
<vbox flex="1" id="refSourceBox">
<label class="heading" value="Reference Source:" />
<iframe flex="1" id="ref" />
</vbox>
<vbox flex="2" id="inspectorBox">
<hbox flex="1">
<vbox flex="1">
<label class="heading" value="Reference" />
<iframe flex="1" id="refInsp" src="result-inspector.xul" />
</vbox>
<vbox flex="1">
<label class="heading" value="Result" />
<iframe flex="1" id="resInsp" src="result-inspector.xul" />
</vbox>
</hbox>
</vbox>
</window>

View file

@ -0,0 +1,10 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function onStartBuster()
{
window.open('chrome://xslt-qa/content/buster/buster.xul',
'buster', 'chrome,resizable');
}

View file

@ -0,0 +1,12 @@
<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<overlay id="xsltToolsMenuID"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="xslt-qa-overlay.js" />
<menupopup id="toolsPopup">
<menuitem label="Xalan Tests" oncommand="onStartBuster()"/>
</menupopup>
</overlay>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="file_bug1135764.xsl"?>
<root/>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"
indent="yes"
version="5.0"
doctype-system="about:legacy-compat"/>
<xsl:template match="/">
<html>
<head>
</head>
<body>
Some text
</body>
</html>
</xsl:template>
</xsl:stylesheet>

View file

@ -0,0 +1,20 @@
[DEFAULT]
[test_bug1072116.html]
[test_bug319374.xhtml]
[test_bug427060.html]
[test_bug440974.html]
[test_bug453441.html]
[test_bug468208.html]
[test_bug511487.html]
[test_bug551412.html]
[test_bug551654.html]
[test_bug566629.html]
[test_bug566629.xhtml]
[test_bug603159.html]
[test_bug616774.html]
[test_bug667315.html]
[test_bug1135764.html]
support-files = file_bug1135764.xml file_bug1135764.xsl
[test_exslt_regex.html]
[test_parameter.html]

View file

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1072116
-->
<head>
<title>Test for Bug 1072116</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1072116">Mozilla Bug 1072116</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1072116 **/
var attr = document.createAttribute("c");
var xpathExpr = document.createExpression('a', null);
var status = false;
try {
xpathExpr.evaluate(attr, null, null, null, null);
} catch(e) {
status = true;
}
ok(status, "Still alive \\o/");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1135764
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1135764</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1135764 **/
SimpleTest.waitForExplicitFinish();
var counter = 0;
var startTimelineValue;
function waitATick() {
++counter;
if (counter == 1) {
frames[0].requestAnimationFrame(waitATick);
return;
}
ok(frames[0].document.timeline.currentTime !== startTimelineValue,
"The timeline in an XSLT-transformed document should still advance");
SimpleTest.finish();
}
addLoadEvent(function() {
SpecialPowers.pushPrefEnv(
{ "set": [[ "dom.animations-api.core.enabled", true]] },
function() {
var ifr = document.querySelector("iframe");
ifr.onload = function() {
startTimelineValue = frames[0].document.timeline.currentTime;
frames[0].requestAnimationFrame(waitATick);
}
ifr.src = "file_bug1135764.xml";
})
})
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1135764">Mozilla Bug 1135764</a>
<p id="display">
<iframe></iframe>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View file

@ -0,0 +1,109 @@
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xbl="http://www.mozilla.org/xbl">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=319374
-->
<head>
<title>Test for Bug 319374</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<xbl:bindings>
<xbl:binding id="test">
<xbl:content>
<span attr="attribute"><span></span></span><span> anon text </span><br/>
</xbl:content>
</xbl:binding>
</xbl:bindings>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=319374">Mozilla Bug 319374</a>
<p id="display"></p>
<div id="content"><span style="-moz-binding: url(#test)"/><span style="-moz-binding: url(#test)"/><span style="-moz-binding: url(#test)"/></div>
<pre id="test">
<script class="testbody" type="text/javascript">
<![CDATA[
/** Test for Bug 319374 **/
function testChangesInAnonymousTree() {
// Test 1: Make sure that modifying anonymous content doesn't
// cause non-anonymous XPath result to throw exceptions..
var counter = 0;
var error = null;
function getAnonymousNodes(e) {
return SpecialPowers.wrap(document).getAnonymousNodes(e);
}
try {
var xp = new XPathEvaluator();
var result = xp.evaluate("*",
document.getElementById('content'),
null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
var res = null;
while (res = result.iterateNext()) {
++counter;
var anon = getAnonymousNodes(res);
anon[0].removeChild(anon[0].firstChild); // Removing a child node
anon[0].removeAttribute("attr1"); // Removing an attribute
anon[1].firstChild.data = "anon text changed" // Modifying text data
}
} catch (e) {
error = e;
}
ok(!error, error);
ok(counter == 3, "XPathEvaluator should have found 3 elements.")
// Test 2: If the context node is in anonymous content, changing some
// other anonymous tree shouldn't cause XPath result to throw.
var anonAttr1 =
getAnonymousNodes(document.getElementById('content').
firstChild)[0].getAttributeNode('attr');
var anonAttr2 =
getAnonymousNodes(document.getElementById('content').
lastChild)[0].getAttributeNode('attr');
var resultAttr = null;
try {
var xp2 = SpecialPowers.wrap(xp).evaluate(".",
anonAttr1,
null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
// Attribute changing in a different anonymous tree.
anonAttr2.value = "foo";
resultAttr = xp2.iterateNext();
ok(SpecialPowers.compare(resultAttr, anonAttr1), "XPathEvaluator returned wrong attribute!")
} catch (e) {
ok(false, e);
}
// Test 3: If the anonymous tree in which context node is in is modified,
// XPath result should throw when iterateNext() is called.
resultAttr = null;
try {
var xp3 = xp.evaluate(".",
anonAttr1,
null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null);
// Attribute changing in the same anonymous tree.
anonAttr1.ownerElement.setAttribute("foo", "bar");
resultAttr = xp3.iterateNext();
ok(resultAttr == anonAttr1,
"XPathEvaluator should have thrown an exception!")
} catch (e) {
ok(true, e);
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(testChangesInAnonymousTree);
]]>
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=427060
-->
<head>
<title>Test for Bug 427060</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=427060">Mozilla Bug 427060</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 427060 **/
var xmldoc, xsltdoc;
xmldoc = new DOMParser().parseFromString('<opml version="1.0"><body></body></opml>', "text/xml");
xsltdoc = new DOMParser().parseFromString('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
<xsl:template match="/opml">\n\
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\
<head>\n\
<base target="_blank"></base>\n\
</head>\n\
<body></body>\n\
</html>\n\
</xsl:template>\n\
</xsl:stylesheet>', "text/xml");
var processor = new XSLTProcessor;
processor.importStylesheet(xsltdoc);
try
{
var result = processor.transformToDocument(xmldoc);
}
catch (e)
{
}
ok(result && result instanceof Document, "XSLT transform should have created a document");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=440974
-->
<head>
<title>Test for Bug 440974</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=440974">Mozilla Bug 440974</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 440974 **/
function isTxResult(node)
{
return node.namespaceURI == "http://www.mozilla.org/TransforMiix" &&
node.localName == "result";
}
var xmldoc, xsltdoc;
xmldoc = new DOMParser().parseFromString('<items><item><id>1</id></item><item><id>2</id></item><item><id>3</id></item></items>', "text/xml");
xsltdoc = new DOMParser().parseFromString('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
<xsl:output method="xml" />\n\
<xsl:template match="item"><foo id="{id}"/></xsl:template>\n\
</xsl:stylesheet>', "text/xml");
var processor = new XSLTProcessor;
processor.importStylesheet(xsltdoc);
var result = processor.transformToDocument(xmldoc);
var resultElements = Array.prototype.filter.call(result.getElementsByTagName('*'), isTxResult);
is(resultElements.length, 1, "there should be only one 'transformiix:result' element");
is(resultElements[0], result.documentElement, "the 'transformiix:result' element should be the document element");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=453441
-->
<head>
<title>Test for Bug 453441</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=453441">Mozilla Bug 453441</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 453441 **/
function tryImportStylesheet(xml, valid)
{
var processor = new XSLTProcessor;
var xsltdoc = new DOMParser().parseFromString(xml, "text/xml");
try
{
processor.importStylesheet(xsltdoc);
ok(valid, "should be able to parse this XSLT stylesheet");
}
catch (e)
{
ok(!valid, "should not be able to parse this XSLT stylesheet");
}
}
tryImportStylesheet(
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
<xsl:template match="/">\n\
<html xmlns="http://www.w3.org/1999/xhtml" xsl:version="1.0" />\n\
</xsl:template>\n\
</xsl:stylesheet>'
, true);
tryImportStylesheet(
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />'
, false);
tryImportStylesheet(
'<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />'
, false);
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=468208
-->
<head>
<title>Test for Bug 468208</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468208">Mozilla Bug 468208</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 468208 **/
var xslt =
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n\
<xsl:strip-space elements="color"/>\n\
</xsl:stylesheet>'
;
var xsltdoc = new DOMParser().parseFromString(xslt, "text/xml");
var processor = new XSLTProcessor;
processor.importStylesheet(xsltdoc);
ok(true, "XSLT shouldn't leak");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=511487
-->
<head>
<title>Test for Bug 511487</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=511487">Mozilla Bug 511487</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 511487 **/
var didTransform = false;
var processor = new XSLTProcessor();
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://www.w3.org/1999/xhtml">' +
'<xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />' +
'<xsl:template match="wml">' +
'<html xmlns="http://www.w3.org/1999/xhtml">' +
'<head>' +
'<title>XSLT test</title>' +
'</head>' +
'<body onload="window.alert(this)">' +
'</body>' +
'</html>' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data =
'<?xml version="1.0"?>' +
'<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">' +
'<wml><card><p>paragraph</p></card></wml>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
processor.importStylesheet(styleDoc);
try {
var transformedDocument = processor.transformToDocument(originalDoc);
didTransform = true;
} catch (e) {
ok(false, e);
}
ok(didTransform, "transformToDocument didn't succeed!");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,48 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=551412
-->
<head>
<title>Test for Bug 551412</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551412">Mozilla Bug 551412</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 551412 **/
var processor = new XSLTProcessor();
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'xmlns:exsl="http://exslt.org/common" ' +
'version="1.0">' +
'<xsl:output method="html"/>' +
'<xsl:variable name="rtf">1 <b>2</b> 3</xsl:variable>' +
'<xsl:template match="/">' +
'<xsl:copy-of select="exsl:node-set($rtf)"/>' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data =
'<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
processor.importStylesheet(styleDoc);
var fragment = processor.transformToFragment(originalDoc, document);
var content = document.getElementById("content");
content.appendChild(fragment);
is(content.innerHTML, "1 <b>2</b> 3",
"Result of transform should be '1 <b>2</b> 3'");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=551654
-->
<head>
<title>Test for Bug 551654</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=551654">Mozilla Bug 551654</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 551654 **/
var didTransform = false;
var processor = new XSLTProcessor();
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'xmlns:exsl="http://exslt.org/common" ' +
'version="1.0">' +
'<xsl:output method="html"/>' +
'<xsl:template match="/">' +
'<xsl:copy-of select="exsl:node-set(42)"/>' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data =
'<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
processor.importStylesheet(styleDoc);
var fragment = processor.transformToFragment(originalDoc, document);
is(fragment.firstChild.nodeType, Node.TEXT_NODE,
"Result of transform should be a textnode");
is(fragment.firstChild.nodeValue, "42",
"Result of transform should be a textnode with value '42'");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,70 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=566629
-->
<head>
<title>Test for Bug 566629</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=566629">Mozilla Bug 566629</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 566629 **/
var xsltdoc = new DOMParser().parseFromString(
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\
xmlns:xhtml="http://www.w3.org/1999/xhtml">\
<xsl:template match="/">\
<xsl:value-of select="count(//body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="count(//xhtml:body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="count(//xsl:body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="name(//body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="local-name(//body)"/>\
</xsl:template>\
</xsl:stylesheet>',
"text/xml");
var processor = new XSLTProcessor;
processor.importStylesheet(xsltdoc);
var result = processor.transformToFragment(document, document);
ok(result instanceof DocumentFragment, "returned a docfragment");
is(result.firstChild.nodeValue, "1,1,0,BODY,body",
"correct treatment of HTML elements in XSLT");
is(document.evaluate("count(//body)", document, null, XPathResult.ANY_TYPE, null).numberValue,
1, "namespace-less node-test");
is(document.evaluate("count(//a:body)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).numberValue,
1, "with-namespace node-test");
is(document.evaluate("count(//a:body)", document,
function() { return "foo" },
XPathResult.ANY_TYPE, null).numberValue,
0, "wrong-namespace node-test");
is(document.evaluate("//bODy", document, null, XPathResult.ANY_TYPE, null).iterateNext(),
document.body, "case insensitive matching");
is(document.evaluate("count(//a:bODy)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).numberValue,
0, "with-namespace but wrong casing node-test");
is(document.evaluate("name(//body)", document, null, XPathResult.ANY_TYPE, null).stringValue,
"BODY", "uppercase name() function");
is(document.evaluate("local-name(//body)", document, null, XPathResult.ANY_TYPE, null).stringValue,
"body", "lowercase local-name() function");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,73 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=566629
-->
<head>
<title>Test for Bug 566629</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=566629">Mozilla Bug 566629</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
<![CDATA[
/** Test for Bug 566629 **/
var xsltdoc = new DOMParser().parseFromString(
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\
xmlns:xhtml="http://www.w3.org/1999/xhtml">\
<xsl:template match="/">\
<xsl:value-of select="count(//body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="count(//xhtml:body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="count(//xsl:body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="name(//xhtml:body)"/>\
<xsl:text>,</xsl:text>\
<xsl:value-of select="local-name(//xhtml:body)"/>\
</xsl:template>\
</xsl:stylesheet>',
"text/xml");
var processor = new XSLTProcessor;
processor.importStylesheet(xsltdoc);
var result = processor.transformToFragment(document, document);
ok(result instanceof DocumentFragment, "returned a docfragment");
is(result.firstChild.nodeValue, "0,1,0,body,body",
"correct treatment of HTML elements in XSLT");
is(document.evaluate("count(//body)", document, null, XPathResult.ANY_TYPE, null).numberValue,
0, "namespace-less node-test");
is(document.evaluate("count(//a:body)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).numberValue,
1, "with-namespace node-test");
is(document.evaluate("count(//a:body)", document,
function() { return "foo" },
XPathResult.ANY_TYPE, null).numberValue,
0, "wrong-namespace node-test");
is(document.evaluate("count(//a:bODy)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).numberValue,
0, "with-namespace wrong-casing node-test");
is(document.evaluate("count(//bODy)", document, null, XPathResult.ANY_TYPE, null).numberValue,
0, "without-namespace wrong-casing node-test");
is(document.evaluate("name(//a:body)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).stringValue,
"body", "name()");
is(document.evaluate("local-name(//a:body)", document,
function() { return "http://www.w3.org/1999/xhtml" },
XPathResult.ANY_TYPE, null).stringValue,
"body", "local-name()");
]]>
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=603159
-->
<head>
<title>Test for Bug 603159</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=603159">Mozilla Bug 603159</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 603159 **/
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'xmlns:date="http://exslt.org/dates-and-times" '+
'version="1.0">' +
'<xsl:output method="html"/>' +
'<xsl:template match="/">' +
'<xsl:value-of select="date:date-time()" /> ' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data = '<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(styleDoc);
var fragment = processor.transformToFragment(originalDoc, document);
var content = document.getElementById("content");
content.appendChild(fragment);
// use Gecko's Date.parse to parse, then compare the milliseconds since epoch
var xslt_ms = Date.parse(content.innerHTML);
var now_ms = new Date().getTime();
var accepted_diff = 30 * 60 * 1000; // 30 minutes
var diff = Math.abs(now_ms - xslt_ms);
ok(diff < accepted_diff, "generated timestamp should be not more than "
+ accepted_diff + " ms before 'now', but the difference was: " + diff);
content.innerHTML = '';
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=616774-->
<head>
<title>Test for Bug 616774</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=616774">Mozilla Bug 616774</a>
<p id="display"></p>
<div id="content" style="display: none">
42
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 616774 **/
is(document.evaluate('- "8"', document, null, XPathResult.ANY_TYPE, null).numberValue, -8, "Negated string literal should evaluate to itself negated");
is(document.evaluate('- - "999"', document, null, XPathResult.ANY_TYPE, null).numberValue, 999, "String literal should evaluate to itself");
is(document.evaluate('- - id("content")', document, null, XPathResult.ANY_TYPE, null).numberValue, 42, "DOM element should evaluate to itself coerced to a number");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=667315
-->
<head>
<title>Test for Bug 667315</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=667315">Mozilla Bug 667315</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 667315 **/
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'version="1.0">' +
'<xsl:variable name="var">' +
'<html><p>a</p></html>' +
'</xsl:variable>' +
'<xsl:template match="/">' +
'<xsl:copy-of select="$var" />' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data = '<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(styleDoc);
var doc = processor.transformToDocument(originalDoc);
ok(doc instanceof HTMLDocument, "should have switched to html output method");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<!--
Test EXSLT Regular Expression Extension
http://www.exslt.org/regexp/index.html
-->
<head>
<title>Test for EXSLT Regular Expression Extensions</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
var tests = [
{ descr: "Testing regexp:test",
expr: "regexp:test('XSLT is great', 'XSLT', '')",
expResult: "true" },
{ descr: "Testing regexp:match",
expr: "regexp:match('XSLT is great', 'XSL.', '')[1]",
expResult: "XSLT" },
{ descr: "Testing regexp:replace",
expr: "regexp:replace('Food is great', 'Fo.d', '', 'XSLT')",
expResult: "XSLT is great" }
];
for (test of tests) {
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'xmlns:regexp="http://exslt.org/regular-expressions" '+
'version="1.0">' +
'<xsl:output method="html"/>' +
'<xsl:template match="/">' +
'<xsl:value-of select="'+test.expr+'" /> ' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data = '<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(styleDoc);
var fragment = processor.transformToFragment(originalDoc, document);
var content = document.getElementById("content");
content.appendChild(fragment);
is(content.innerHTML, test.expResult, test.descr);
content.innerHTML = '';
}
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for setParameter/getParameter</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script>
var processor = new XSLTProcessor();
processor.setParameter(null, "test", "hello");
is(processor.getParameter(null, "test"), "hello", "null namespace works");
processor.setParameter("foo", "bar", "foobar");
is(processor.getParameter("foo", "bar"), "foobar", "non-null namespace works");
processor.setParameter(null, "test", 123);
is(processor.getParameter(null, "test"), 123, "number value works");
processor.removeParameter(null, "test");
is(processor.getParameter(null, "test"), null, "removeParameter works");
is(processor.getParameter(null, "not-here"), null, "nonexistant parameter");
</script>
</pre>
</body>
</html>

View file

@ -0,0 +1,21 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface txIFunctionEvaluationContext;
interface txINodeSet;
[scriptable, uuid(c180e993-aced-4839-95a0-ecd5ff138be9)]
interface txIEXSLTRegExFunctions : nsISupports
{
txINodeSet match(in txIFunctionEvaluationContext aContext,
in DOMString aString, in DOMString aRegEx,
in DOMString aFlags);
DOMString replace(in DOMString aString, in DOMString aRegEx,
in DOMString aFlags, in DOMString aReplace);
boolean test(in DOMString aString, in DOMString aRegEx,
in DOMString aFlags);
};

View file

@ -0,0 +1,18 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMNode;
interface txINodeSet;
[scriptable, uuid(0ecbb00c-6a78-11d9-9791-000a95dc234c)]
interface txIFunctionEvaluationContext : nsISupports
{
readonly attribute uint32_t position;
readonly attribute uint32_t size;
readonly attribute nsIDOMNode contextNode;
readonly attribute nsISupports state;
};

16
dom/xslt/txINodeSet.idl Normal file
View file

@ -0,0 +1,16 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "domstubs.idl"
[scriptable, uuid(15d424c0-6b47-11d9-9791-000a95dc234c)]
interface txINodeSet : nsISupports
{
nsIDOMNode item(in unsigned long index);
double itemAsNumber(in unsigned long index);
DOMString itemAsString(in unsigned long index);
readonly attribute unsigned long length;
void add(in nsIDOMNode node);
};

View file

@ -0,0 +1,18 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{ C++
class txAExprResult;
%}
[ptr] native txAExprResultPtr(txAExprResult);
[scriptable, uuid(67706346-dece-4c9b-9fc2-57cf19071014)]
interface txIXPathObject : nsISupports
{
[noscript, notxpcom] txAExprResultPtr getResult();
};

19
dom/xslt/xml/moz.build Normal file
View file

@ -0,0 +1,19 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'txXMLParser.cpp',
'txXMLUtils.cpp',
]
LOCAL_INCLUDES += [
'../base',
'../xpath',
'../xslt',
'/dom/base',
]
FINAL_LIBRARY = 'xul'

Some files were not shown because too many files have changed in this diff Show more