зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-i to m-c.
This commit is contained in:
Коммит
995d6910c7
|
@ -739,32 +739,56 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||
def killPid(self, pid):
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
if UNIXISH:
|
||||
def dumpScreen(self, utilityPath):
|
||||
self.haveDumpedScreen = True;
|
||||
|
||||
screentopng = os.path.join(utilityPath, "screentopng")
|
||||
try:
|
||||
dumper = self.Process([screentopng], bufsize=-1,
|
||||
stdout=subprocess.PIPE, close_fds=True)
|
||||
except OSError, err:
|
||||
self.log.info("Failed to start %s for screenshot: %s",
|
||||
screentopng, err.strerror)
|
||||
# Need to figure out what tool and whether it write to a file or stdout
|
||||
if UNIXISH:
|
||||
utility = [os.path.join(utilityPath, "screentopng")]
|
||||
imgoutput = 'stdout'
|
||||
elif IS_MAC:
|
||||
utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png']
|
||||
imgoutput = 'file'
|
||||
elif IS_WIN32:
|
||||
self.log.info("If you fixed bug 589668, you'd get a screenshot here")
|
||||
return
|
||||
|
||||
image = dumper.stdout.read()
|
||||
status = dumper.wait()
|
||||
if status != 0:
|
||||
self.log.info("screentopng exited with code %d", status)
|
||||
# Run the capture correctly for the type of capture
|
||||
try:
|
||||
if imgoutput == 'file':
|
||||
tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail_')
|
||||
os.close(tmpfd)
|
||||
dumper = self.Process(utility + [imgfilename])
|
||||
elif imgoutput == 'stdout':
|
||||
dumper = self.Process(utility, bufsize=-1,
|
||||
stdout=subprocess.PIPE, close_fds=True)
|
||||
except OSError, err:
|
||||
self.log.info("Failed to start %s for screenshot: %s",
|
||||
utility[0], err.strerror)
|
||||
return
|
||||
|
||||
# Check whether the capture utility ran successfully
|
||||
dumper_out, dumper_err = dumper.communicate()
|
||||
if dumper.returncode != 0:
|
||||
self.log.info("%s exited with code %d", utility, dumper.returncode)
|
||||
return
|
||||
|
||||
try:
|
||||
if imgoutput == 'stdout':
|
||||
image = dumper_out
|
||||
elif imgoutput == 'file':
|
||||
with open(imgfilename) as imgfile:
|
||||
image = imgfile.read()
|
||||
except IOError, err:
|
||||
self.log.info("Failed to read image from %s", imgoutput)
|
||||
|
||||
import base64
|
||||
encoded = base64.b64encode(image)
|
||||
self.log.info("SCREENSHOT: data:image/png;base64,%s", encoded)
|
||||
|
||||
def killAndGetStack(self, proc, utilityPath, debuggerInfo):
|
||||
"""Kill the process, preferrably in a way that gets us a stack trace."""
|
||||
if self.UNIXISH and not debuggerInfo and not self.haveDumpedScreen:
|
||||
if not debuggerInfo and not self.haveDumpedScreen:
|
||||
self.dumpScreen(utilityPath)
|
||||
|
||||
if self.CRASHREPORTER and not debuggerInfo:
|
||||
|
@ -820,7 +844,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||
if stackFixerFunction:
|
||||
line = stackFixerFunction(line)
|
||||
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
|
||||
if self.UNIXISH and not debuggerInfo and not self.haveDumpedScreen and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
|
||||
if not debuggerInfo and not self.haveDumpedScreen and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
|
||||
self.dumpScreen(utilityPath)
|
||||
|
||||
(line, didTimeout) = self.readWithTimeout(logsource, timeout)
|
||||
|
|
|
@ -2254,10 +2254,7 @@ case "$target" in
|
|||
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -o $@'
|
||||
MOZ_OPTIMIZE_FLAGS="-O3"
|
||||
_PEDANTIC=
|
||||
# Due to performance regressions, statically disable jemalloc on 10.5. See bug 414946.
|
||||
if test "$HAVE_64BIT_OS"; then
|
||||
MOZ_MEMORY=1
|
||||
fi
|
||||
MOZ_MEMORY=1
|
||||
CFLAGS="$CFLAGS -fno-common"
|
||||
CXXFLAGS="$CXXFLAGS -fno-common"
|
||||
DLL_SUFFIX=".dylib"
|
||||
|
|
|
@ -759,6 +759,7 @@ public:
|
|||
eFORMS_PROPERTIES,
|
||||
ePRINTING_PROPERTIES,
|
||||
eDOM_PROPERTIES,
|
||||
eHTMLPARSER_PROPERTIES,
|
||||
eSVG_PROPERTIES,
|
||||
eBRAND_PROPERTIES,
|
||||
eCOMMON_DIALOG_PROPERTIES,
|
||||
|
|
|
@ -126,8 +126,8 @@ class Element;
|
|||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x3d24831e, 0x2a2b, 0x42f4, \
|
||||
{ 0x9d, 0x98, 0x17, 0x60, 0x18, 0xab, 0x6e, 0xfb } }
|
||||
{ 0xc3e40e8e, 0x8b91, 0x424c, \
|
||||
{ 0xbe, 0x9c, 0x9c, 0xc1, 0x76, 0xa7, 0xf7, 0x24 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -737,14 +737,10 @@ public:
|
|||
virtual void RemoveFromNameTable(Element* aElement, nsIAtom* aName) = 0;
|
||||
|
||||
/**
|
||||
* Resets the current full-screen element to nsnull.
|
||||
*/
|
||||
virtual void ResetFullScreenElement() = 0;
|
||||
|
||||
/**
|
||||
* Returns the element which either is the full-screen element, or
|
||||
* contains the full-screen element if a child of this document contains
|
||||
* the fullscreen element.
|
||||
* Returns the element which either requested DOM full-screen mode, or
|
||||
* contains the element which requested DOM full-screen mode if the
|
||||
* requestee is in a subdocument. Note this element must be *in*
|
||||
* this document.
|
||||
*/
|
||||
virtual Element* GetFullScreenElement() = 0;
|
||||
|
||||
|
@ -760,14 +756,6 @@ public:
|
|||
*/
|
||||
virtual void CancelFullScreen() = 0;
|
||||
|
||||
/**
|
||||
* Updates the full-screen status on this document, setting the full-screen
|
||||
* mode to aIsFullScreen. This doesn't affect the window's full-screen mode,
|
||||
* this updates the document's internal state which determines whether the
|
||||
* document reports as being in full-screen mode.
|
||||
*/
|
||||
virtual void UpdateFullScreenStatus(bool aIsFullScreen) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if this document is in full-screen mode.
|
||||
*/
|
||||
|
@ -1510,6 +1498,13 @@ public:
|
|||
*/
|
||||
virtual Element* GetElementById(const nsAString& aElementId) = 0;
|
||||
|
||||
/**
|
||||
* This method returns _all_ the elements in this document which
|
||||
* have id aElementId, if there are any. Otherwise it returns null.
|
||||
* The entries of the nsSmallVoidArray are Element*
|
||||
*/
|
||||
virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const = 0;
|
||||
|
||||
/**
|
||||
* Lookup an image element using its associated ID, which is usually provided
|
||||
* by |-moz-element()|. Similar to GetElementById, with the difference that
|
||||
|
|
|
@ -68,7 +68,6 @@ NS_NewPreContentIterator(nsIContentIterator** aInstancePtrResult);
|
|||
#define ASSERT_IN_SYNC PR_BEGIN_MACRO PR_END_MACRO
|
||||
#endif
|
||||
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsBaseContentList::~nsBaseContentList()
|
||||
|
@ -77,11 +76,11 @@ nsBaseContentList::~nsBaseContentList()
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsBaseContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsBaseContentList)
|
||||
|
@ -113,7 +112,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBaseContentList)
|
|||
NS_IMETHODIMP
|
||||
nsBaseContentList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
*aLength = mElements.Count();
|
||||
*aLength = mElements.Length();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -135,7 +134,7 @@ nsBaseContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
|||
nsIContent*
|
||||
nsBaseContentList::GetNodeAt(PRUint32 aIndex)
|
||||
{
|
||||
return mElements.SafeObjectAt(aIndex);
|
||||
return mElements.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,23 +150,6 @@ nsBaseContentList::IndexOf(nsIContent* aContent)
|
|||
return IndexOf(aContent, true);
|
||||
}
|
||||
|
||||
void nsBaseContentList::AppendElement(nsIContent *aContent)
|
||||
{
|
||||
mElements.AppendObject(aContent);
|
||||
}
|
||||
|
||||
void nsBaseContentList::RemoveElement(nsIContent *aContent)
|
||||
{
|
||||
mElements.RemoveObject(aContent);
|
||||
}
|
||||
|
||||
void nsBaseContentList::InsertElementAt(nsIContent* aContent, PRInt32 aIndex)
|
||||
{
|
||||
NS_ASSERTION(aContent, "Element to insert must not be null");
|
||||
mElements.InsertObjectAt(aContent, aIndex);
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsSimpleContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSimpleContentList,
|
||||
nsBaseContentList)
|
||||
|
@ -533,7 +515,7 @@ nsContentList::Length(bool aDoFlush)
|
|||
{
|
||||
BringSelfUpToDate(aDoFlush);
|
||||
|
||||
return mElements.Count();
|
||||
return mElements.Length();
|
||||
}
|
||||
|
||||
nsIContent *
|
||||
|
@ -555,7 +537,7 @@ nsContentList::Item(PRUint32 aIndex, bool aDoFlush)
|
|||
NS_ASSERTION(!mRootNode || mState != LIST_DIRTY,
|
||||
"PopulateSelf left the list in a dirty (useless) state!");
|
||||
|
||||
return mElements.SafeObjectAt(aIndex);
|
||||
return mElements.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
nsIContent *
|
||||
|
@ -563,7 +545,7 @@ nsContentList::NamedItem(const nsAString& aName, bool aDoFlush)
|
|||
{
|
||||
BringSelfUpToDate(aDoFlush);
|
||||
|
||||
PRInt32 i, count = mElements.Count();
|
||||
PRUint32 i, count = mElements.Length();
|
||||
|
||||
// Typically IDs and names are atomized
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
|
||||
|
@ -677,7 +659,7 @@ nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
|
|||
}
|
||||
|
||||
if (Match(aElement)) {
|
||||
if (mElements.IndexOf(aElement) == -1) {
|
||||
if (mElements.IndexOf(aElement) == mElements.NoIndex) {
|
||||
// We match aElement now, and it's not in our list already. Just dirty
|
||||
// ourselves; this is simpler than trying to figure out where to insert
|
||||
// aElement.
|
||||
|
@ -688,7 +670,7 @@ nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
|
|||
// already not there, this is a no-op (though a potentially
|
||||
// expensive one). Either way, no change of mState is required
|
||||
// here.
|
||||
mElements.RemoveObject(aElement);
|
||||
mElements.RemoveElement(aElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,7 +704,7 @@ nsContentList::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
|||
PRInt32 count = aContainer->GetChildCount();
|
||||
|
||||
if (count > 0) {
|
||||
PRInt32 ourCount = mElements.Count();
|
||||
PRUint32 ourCount = mElements.Length();
|
||||
bool appendToList = false;
|
||||
if (ourCount == 0) {
|
||||
appendToList = true;
|
||||
|
@ -772,13 +754,13 @@ nsContentList::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
|||
cur;
|
||||
cur = cur->GetNextNode(aContainer)) {
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
mElements.AppendObject(cur);
|
||||
mElements.AppendElement(cur);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
mElements.AppendObject(cur);
|
||||
mElements.AppendElement(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -901,7 +883,7 @@ nsContentList::PopulateSelf(PRUint32 aNeededLength)
|
|||
|
||||
ASSERT_IN_SYNC;
|
||||
|
||||
PRUint32 count = mElements.Count();
|
||||
PRUint32 count = mElements.Length();
|
||||
NS_ASSERTION(mState != LIST_DIRTY || count == 0,
|
||||
"Reset() not called when setting state to LIST_DIRTY?");
|
||||
|
||||
|
@ -910,7 +892,7 @@ nsContentList::PopulateSelf(PRUint32 aNeededLength)
|
|||
|
||||
PRUint32 elementsToAppend = aNeededLength - count;
|
||||
#ifdef DEBUG
|
||||
PRUint32 invariant = elementsToAppend + mElements.Count();
|
||||
PRUint32 invariant = elementsToAppend + mElements.Length();
|
||||
#endif
|
||||
|
||||
if (mDeep) {
|
||||
|
@ -923,7 +905,8 @@ nsContentList::PopulateSelf(PRUint32 aNeededLength)
|
|||
break;
|
||||
}
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
mElements.AppendObject(cur->AsElement());
|
||||
// Append AsElement() to get nsIContent instead of nsINode
|
||||
mElements.AppendElement(cur->AsElement());
|
||||
--elementsToAppend;
|
||||
}
|
||||
} while (elementsToAppend);
|
||||
|
@ -932,13 +915,13 @@ nsContentList::PopulateSelf(PRUint32 aNeededLength)
|
|||
count ? mElements[count-1]->GetNextSibling() : mRootNode->GetFirstChild();
|
||||
for ( ; cur && elementsToAppend; cur = cur->GetNextSibling()) {
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
mElements.AppendObject(cur);
|
||||
mElements.AppendElement(cur);
|
||||
--elementsToAppend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(elementsToAppend + mElements.Count() == invariant,
|
||||
NS_ASSERTION(elementsToAppend + mElements.Length() == invariant,
|
||||
"Something is awry!");
|
||||
|
||||
if (elementsToAppend != 0)
|
||||
|
@ -1024,7 +1007,7 @@ nsContentList::AssertInSync()
|
|||
}
|
||||
|
||||
if (!mRootNode) {
|
||||
NS_ASSERTION(mElements.Count() == 0 && mState == LIST_DIRTY,
|
||||
NS_ASSERTION(mElements.Length() == 0 && mState == LIST_DIRTY,
|
||||
"Empty iterator isn't quite empty?");
|
||||
return;
|
||||
}
|
||||
|
@ -1046,9 +1029,9 @@ nsContentList::AssertInSync()
|
|||
iter->First();
|
||||
}
|
||||
|
||||
PRInt32 cnt = 0, index = 0;
|
||||
PRUint32 cnt = 0, index = 0;
|
||||
while (true) {
|
||||
if (cnt == mElements.Count() && mState == LIST_LAZY) {
|
||||
if (cnt == mElements.Length() && mState == LIST_LAZY) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1042,7 @@ nsContentList::AssertInSync()
|
|||
}
|
||||
|
||||
if (cur->IsElement() && Match(cur->AsElement())) {
|
||||
NS_ASSERTION(cnt < mElements.Count() && mElements[cnt] == cur,
|
||||
NS_ASSERTION(cnt < mElements.Length() && mElements[cnt] == cur,
|
||||
"Elements is out of sync");
|
||||
++cnt;
|
||||
}
|
||||
|
@ -1069,6 +1052,6 @@ nsContentList::AssertInSync()
|
|||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(cnt == mElements.Count(), "Too few elements");
|
||||
NS_ASSERTION(cnt == mElements.Length(), "Too few elements");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define nsContentList_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIHTMLCollection.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
|
@ -100,12 +100,15 @@ public:
|
|||
virtual PRInt32 IndexOf(nsIContent* aContent);
|
||||
|
||||
PRUint32 Length() const {
|
||||
return mElements.Count();
|
||||
return mElements.Length();
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsBaseContentList)
|
||||
|
||||
void AppendElement(nsIContent *aContent);
|
||||
void AppendElement(nsIContent *aContent)
|
||||
{
|
||||
mElements.AppendElement(aContent);
|
||||
}
|
||||
void MaybeAppendElement(nsIContent* aContent)
|
||||
{
|
||||
if (aContent)
|
||||
|
@ -118,9 +121,16 @@ public:
|
|||
* @param aContent Element to insert, must not be null
|
||||
* @param aIndex Index to insert the element at.
|
||||
*/
|
||||
void InsertElementAt(nsIContent* aContent, PRInt32 aIndex);
|
||||
void InsertElementAt(nsIContent* aContent, PRInt32 aIndex)
|
||||
{
|
||||
NS_ASSERTION(aContent, "Element to insert must not be null");
|
||||
mElements.InsertElementAt(aIndex, aContent);
|
||||
}
|
||||
|
||||
void RemoveElement(nsIContent *aContent);
|
||||
void RemoveElement(nsIContent *aContent)
|
||||
{
|
||||
mElements.RemoveElement(aContent);
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
mElements.Clear();
|
||||
|
@ -132,7 +142,7 @@ public:
|
|||
bool *triedToWrap) = 0;
|
||||
|
||||
protected:
|
||||
nsCOMArray<nsIContent> mElements;
|
||||
nsTArray< nsCOMPtr<nsIContent> > mElements;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2708,6 +2708,7 @@ static const char gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT][56] = {
|
|||
"chrome://global/locale/layout/HtmlForm.properties",
|
||||
"chrome://global/locale/printing.properties",
|
||||
"chrome://global/locale/dom/dom.properties",
|
||||
"chrome://global/locale/layout/htmlparser.properties",
|
||||
"chrome://global/locale/svg/svg.properties",
|
||||
"chrome://branding/locale/brand.properties",
|
||||
"chrome://global/locale/commonDialogs.properties"
|
||||
|
|
|
@ -214,6 +214,7 @@ using namespace mozilla::dom;
|
|||
|
||||
typedef nsTArray<Link*> LinkArray;
|
||||
|
||||
nsWeakPtr nsDocument::sFullScreenDoc = nsnull;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gDocumentLeakPRLog;
|
||||
|
@ -4036,6 +4037,17 @@ nsDocument::GetElementById(const nsAString& aElementId)
|
|||
return entry ? entry->GetIdElement() : nsnull;
|
||||
}
|
||||
|
||||
const nsSmallVoidArray*
|
||||
nsDocument::GetAllElementsForId(const nsAString& aElementId) const
|
||||
{
|
||||
if (aElementId.IsEmpty()) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aElementId);
|
||||
return entry ? entry->GetIdElements() : nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
|
||||
{
|
||||
|
@ -6000,7 +6012,7 @@ nsDocument::AdoptNode(nsIDOMNode *aAdoptedNode, nsIDOMNode **aResult)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsINode> adoptedNode = do_QueryInterface(aAdoptedNode);
|
||||
|
||||
|
||||
// Scope firing mutation events so that we don't carry any state that
|
||||
// might be stale
|
||||
{
|
||||
|
@ -8347,39 +8359,12 @@ nsIDocument::SizeOf() const
|
|||
return size;
|
||||
}
|
||||
|
||||
// Returns the root document in a document hierarchy.
|
||||
static nsIDocument*
|
||||
GetRootDocument(nsIDocument* aDoc)
|
||||
{
|
||||
if (!aDoc) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> shell = aDoc->GetShell();
|
||||
if (!shell) {
|
||||
return nsnull;
|
||||
}
|
||||
nsPresContext* ctx = shell->GetPresContext();
|
||||
if (!ctx) {
|
||||
return nsnull;
|
||||
}
|
||||
nsRootPresContext* rpc = ctx->GetRootPresContext();
|
||||
if (!rpc) {
|
||||
return nsnull;
|
||||
}
|
||||
return rpc->Document();
|
||||
}
|
||||
|
||||
class nsDispatchFullScreenChange : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsDispatchFullScreenChange(nsIDocument *aDoc)
|
||||
: mDoc(aDoc)
|
||||
{
|
||||
mTarget = aDoc->GetFullScreenElement();
|
||||
if (!mTarget) {
|
||||
mTarget = aDoc;
|
||||
}
|
||||
}
|
||||
nsDispatchFullScreenChange(nsIDocument *aDoc, nsINode* aElement)
|
||||
: mDoc(aDoc),
|
||||
mTarget(aElement ? aElement : aDoc) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
|
@ -8395,63 +8380,41 @@ public:
|
|||
nsCOMPtr<nsISupports> mTarget;
|
||||
};
|
||||
|
||||
void
|
||||
nsDocument::UpdateFullScreenStatus(bool aIsFullScreen)
|
||||
static void DispatchFullScreenChange(nsIDocument* aDocument, Element* aElement)
|
||||
{
|
||||
if (mIsFullScreen != aIsFullScreen) {
|
||||
nsCOMPtr<nsIRunnable> event(new nsDispatchFullScreenChange(this));
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
mIsFullScreen = aIsFullScreen;
|
||||
if (!mIsFullScreen) {
|
||||
// Full-screen is being turned off. Reset the full-screen element, to
|
||||
// save us from having to traverse the document hierarchy again in
|
||||
// MozCancelFullScreen().
|
||||
ResetFullScreenElement();
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> event(
|
||||
new nsDispatchFullScreenChange(aDocument, aElement));
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
||||
static bool
|
||||
UpdateFullScreenStatus(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
aDocument->UpdateFullScreenStatus(*static_cast<bool*>(aData));
|
||||
aDocument->EnumerateSubDocuments(UpdateFullScreenStatus, aData);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateFullScreenStatusInDocTree(nsIDocument* aDoc, bool aIsFullScreen)
|
||||
{
|
||||
nsIDocument* root = GetRootDocument(aDoc);
|
||||
if (root) {
|
||||
UpdateFullScreenStatus(root, static_cast<void*>(&aIsFullScreen));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ResetFullScreenElement()
|
||||
bool
|
||||
nsDocument::SetFullScreenState(Element* aElement, bool aIsFullScreen)
|
||||
{
|
||||
if (mFullScreenElement) {
|
||||
// Reset the ancestor and full-screen styles on the outgoing full-screen
|
||||
// element in the current document.
|
||||
nsEventStateManager::SetFullScreenState(mFullScreenElement, false);
|
||||
mFullScreenElement = nsnull;
|
||||
}
|
||||
mFullScreenElement = nsnull;
|
||||
}
|
||||
if (aElement) {
|
||||
nsEventStateManager::SetFullScreenState(aElement, aIsFullScreen);
|
||||
}
|
||||
mFullScreenElement = aElement;
|
||||
|
||||
static bool
|
||||
ResetFullScreenElement(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
aDocument->ResetFullScreenElement();
|
||||
aDocument->EnumerateSubDocuments(ResetFullScreenElement, aData);
|
||||
if (mIsFullScreen == aIsFullScreen) {
|
||||
return false;
|
||||
}
|
||||
mIsFullScreen = aIsFullScreen;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ResetFullScreenElementInDocTree(nsIDocument* aDoc)
|
||||
// Wrapper for the nsIDocument -> nsDocument cast required to call
|
||||
// nsDocument::SetFullScreenState().
|
||||
static bool
|
||||
SetFullScreenState(nsIDocument* aDoc, Element* aElement, bool aIsFullScreen)
|
||||
{
|
||||
nsIDocument* root = GetRootDocument(aDoc);
|
||||
if (root) {
|
||||
ResetFullScreenElement(root, nsnull);
|
||||
}
|
||||
return static_cast<nsDocument*>(aDoc)->
|
||||
SetFullScreenState(aElement, aIsFullScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -8464,20 +8427,57 @@ nsDocument::MozCancelFullScreen()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Runnable to set window full-screen mode. Used as a script runner
|
||||
// to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to
|
||||
// run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
|
||||
// (handled in chome code) which is unsafe to run if this is called in
|
||||
// nsGenericElement::UnbindFromTree().
|
||||
class nsSetWindowFullScreen : public nsRunnable {
|
||||
public:
|
||||
nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
: mDoc(aDoc), mValue(aValue) {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mDoc->GetWindow()) {
|
||||
mDoc->GetWindow()->SetFullScreen(mValue);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
bool mValue;
|
||||
};
|
||||
|
||||
static void
|
||||
SetWindowFullScreen(nsIDocument* aDoc, bool aValue)
|
||||
{
|
||||
nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue));
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::CancelFullScreen()
|
||||
{
|
||||
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
||||
!IsFullScreenDoc() ||
|
||||
!GetWindow()) {
|
||||
NS_ASSERTION(!IsFullScreenDoc() || sFullScreenDoc != nsnull,
|
||||
"Should have a full-screen doc when full-screen!");
|
||||
|
||||
if (!IsFullScreenDoc() || !GetWindow() || !sFullScreenDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable full-screen mode in all documents in this hierarchy.
|
||||
UpdateFullScreenStatusInDocTree(this, false);
|
||||
// Reset full-screen state in all full-screen documents.
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryReferent(sFullScreenDoc));
|
||||
while (doc != nsnull) {
|
||||
if (::SetFullScreenState(doc, nsnull, false)) {
|
||||
DispatchFullScreenChange(doc, nsnull);
|
||||
}
|
||||
doc = doc->GetParentDocument();
|
||||
}
|
||||
sFullScreenDoc = nsnull;
|
||||
|
||||
// Move the window out of full-screen mode.
|
||||
GetWindow()->SetFullScreen(false);
|
||||
SetWindowFullScreen(this, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -8485,7 +8485,38 @@ nsDocument::CancelFullScreen()
|
|||
bool
|
||||
nsDocument::IsFullScreenDoc()
|
||||
{
|
||||
return nsContentUtils::IsFullScreenApiEnabled() && mIsFullScreen;
|
||||
return mIsFullScreen;
|
||||
}
|
||||
|
||||
static nsIDocument*
|
||||
GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
|
||||
{
|
||||
nsIDocument* doc1 = aDoc1;
|
||||
nsIDocument* doc2 = aDoc2;
|
||||
|
||||
nsAutoTArray<nsIDocument*, 30> parents1, parents2;
|
||||
do {
|
||||
parents1.AppendElement(doc1);
|
||||
doc1 = doc1->GetParentDocument();
|
||||
} while (doc1);
|
||||
do {
|
||||
parents2.AppendElement(doc2);
|
||||
doc2 = doc2->GetParentDocument();
|
||||
} while (doc2);
|
||||
|
||||
PRUint32 pos1 = parents1.Length();
|
||||
PRUint32 pos2 = parents2.Length();
|
||||
nsIDocument* parent = nsnull;
|
||||
PRUint32 len;
|
||||
for (len = NS_MIN(pos1, pos2); len > 0; --len) {
|
||||
nsIDocument* child1 = parents1.ElementAt(--pos1);
|
||||
nsIDocument* child2 = parents2.ElementAt(--pos2);
|
||||
if (child1 != child2) {
|
||||
break;
|
||||
}
|
||||
parent = child1;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8495,61 +8526,78 @@ nsDocument::RequestFullScreen(Element* aElement)
|
|||
return;
|
||||
}
|
||||
|
||||
// Reset the full-screen elements of every document in this document
|
||||
// hierarchy.
|
||||
ResetFullScreenElementInDocTree(this);
|
||||
|
||||
if (aElement->IsInDoc()) {
|
||||
// Propagate up the document hierarchy, setting the full-screen element as
|
||||
// the element's container in ancestor documents. Note we don't propagate
|
||||
// down the document hierarchy, the full-screen element (or its container)
|
||||
// is not visible there.
|
||||
mFullScreenElement = aElement;
|
||||
// Set the full-screen state on the element, so the css-pseudo class
|
||||
// applies to the element.
|
||||
nsEventStateManager::SetFullScreenState(mFullScreenElement, true);
|
||||
nsIDocument* child = this;
|
||||
nsIDocument* parent;
|
||||
while (parent = child->GetParentDocument()) {
|
||||
Element* element = parent->FindContentForSubDocument(child);
|
||||
// Containing frames also need the css-pseudo class applied.
|
||||
nsEventStateManager::SetFullScreenState(element, true);
|
||||
static_cast<nsDocument*>(parent)->mFullScreenElement = element;
|
||||
child = parent;
|
||||
// Turn off full-screen state in all documents which were previously
|
||||
// full-screen but which shouldn't be after this request is granted.
|
||||
// Note commonAncestor will be null when in a separate browser window
|
||||
// to the requesting document.
|
||||
nsIDocument* commonAncestor = nsnull;
|
||||
nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
|
||||
if (fullScreenDoc) {
|
||||
commonAncestor = GetCommonAncestor(fullScreenDoc, this);
|
||||
}
|
||||
nsIDocument* doc = fullScreenDoc;
|
||||
while (doc != commonAncestor) {
|
||||
if (::SetFullScreenState(doc, nsnull, false)) {
|
||||
DispatchFullScreenChange(doc, nsnull);
|
||||
}
|
||||
doc = doc->GetParentDocument();
|
||||
}
|
||||
if (!commonAncestor && fullScreenDoc) {
|
||||
// Other doc is in another browser window. Move it out of full-screen.
|
||||
// Note that nsGlobalWindow::SetFullScreen() proxies to the root window
|
||||
// in its hierarchy, and does not operate on the a per-nsIDOMWindow basis.
|
||||
SetWindowFullScreen(fullScreenDoc, false);
|
||||
}
|
||||
|
||||
// Set all documents in hierarchy to full-screen mode.
|
||||
UpdateFullScreenStatusInDocTree(this, true);
|
||||
// Set the full-screen element. This sets the full-screen style on the
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
if (SetFullScreenState(aElement, true)) {
|
||||
DispatchFullScreenChange(this, aElement);
|
||||
}
|
||||
|
||||
// Propagate up the document hierarchy, setting the full-screen element as
|
||||
// the element's container in ancestor documents. This also sets the
|
||||
// appropriate css styles as well. Note we don't propagate down the
|
||||
// document hierarchy, the full-screen element (or its container) is not
|
||||
// visible there.
|
||||
nsIDocument* child = this;
|
||||
nsIDocument* parent;
|
||||
while ((parent = child->GetParentDocument())) {
|
||||
Element* element = parent->FindContentForSubDocument(child)->AsElement();
|
||||
if (::SetFullScreenState(parent, element, true)) {
|
||||
DispatchFullScreenChange(parent, element);
|
||||
}
|
||||
child = parent;
|
||||
}
|
||||
|
||||
// Make the window full-screen. Note we must make the state changes above
|
||||
// before making the window full-screen, as then the document reports as
|
||||
// being in full-screen mode when the Chrome "fullscreen" event fires,
|
||||
// enabling browser.js to distinguish between browser and dom full-screen
|
||||
// being in full-screen mode when the chrome "fullscreen" event fires,
|
||||
// enabling chrome to distinguish between browser and dom full-screen
|
||||
// modes.
|
||||
GetWindow()->SetFullScreen(true);
|
||||
SetWindowFullScreen(this, true);
|
||||
|
||||
// Remember this is the requesting full-screen document.
|
||||
sFullScreenDoc = do_GetWeakReference(static_cast<nsIDocument*>(this));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetMozFullScreenElement(nsIDOMHTMLElement **aFullScreenElement)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFullScreenElement);
|
||||
if (!nsContentUtils::IsFullScreenApiEnabled() || !IsFullScreenDoc()) {
|
||||
*aFullScreenElement = nsnull;
|
||||
return NS_OK;
|
||||
*aFullScreenElement = nsnull;
|
||||
if (IsFullScreenDoc()) {
|
||||
// Must have a full-screen element while in full-screen mode.
|
||||
NS_ENSURE_STATE(GetFullScreenElement());
|
||||
CallQueryInterface(GetFullScreenElement(), aFullScreenElement);
|
||||
}
|
||||
nsCOMPtr<nsIDOMHTMLElement> e(do_QueryInterface(GetFullScreenElement()));
|
||||
NS_IF_ADDREF(*aFullScreenElement = e);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Element*
|
||||
nsDocument::GetFullScreenElement()
|
||||
{
|
||||
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
||||
(mFullScreenElement && !mFullScreenElement->IsInDoc())) {
|
||||
return nsnull;
|
||||
}
|
||||
return mFullScreenElement;
|
||||
}
|
||||
|
||||
|
@ -8557,7 +8605,7 @@ NS_IMETHODIMP
|
|||
nsDocument::GetMozFullScreen(bool *aFullScreen)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFullScreen);
|
||||
*aFullScreen = nsContentUtils::IsFullScreenApiEnabled() && IsFullScreenDoc();
|
||||
*aFullScreen = IsFullScreenDoc();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,6 +171,12 @@ public:
|
|||
* id. Otherwise returns null.
|
||||
*/
|
||||
Element* GetIdElement();
|
||||
/**
|
||||
* Returns the list of all elements associated with this id.
|
||||
*/
|
||||
const nsSmallVoidArray* GetIdElements() const {
|
||||
return &mIdContentList;
|
||||
}
|
||||
/**
|
||||
* If this entry has a non-null image element set (using SetImageElement),
|
||||
* the image element will be returned, otherwise the same as GetIdElement().
|
||||
|
@ -244,7 +250,7 @@ private:
|
|||
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
|
||||
bool aImageOnly = false);
|
||||
|
||||
// empty if there are no elementswith this ID.
|
||||
// empty if there are no elements with this ID.
|
||||
// The elements are stored as weak pointers.
|
||||
nsSmallVoidArray mIdContentList;
|
||||
nsRefPtr<nsBaseContentList> mNameContentList;
|
||||
|
@ -926,6 +932,7 @@ public:
|
|||
const nsAString& aLocalName);
|
||||
|
||||
virtual Element *GetElementById(const nsAString& aElementId);
|
||||
virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const;
|
||||
|
||||
virtual Element *LookupImageElement(const nsAString& aElementId);
|
||||
|
||||
|
@ -940,13 +947,15 @@ public:
|
|||
|
||||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName);
|
||||
|
||||
virtual void ResetFullScreenElement();
|
||||
virtual Element* GetFullScreenElement();
|
||||
virtual void RequestFullScreen(Element* aElement);
|
||||
virtual void CancelFullScreen();
|
||||
virtual void UpdateFullScreenStatus(bool aIsFullScreen);
|
||||
virtual bool IsFullScreenDoc();
|
||||
|
||||
// Returns true if making this change results in a change in the full-screen
|
||||
// state of this document.
|
||||
bool SetFullScreenState(Element* aElement, bool aIsFullScreen);
|
||||
|
||||
// This method may fire a DOM event; if it does so it will happen
|
||||
// synchronously.
|
||||
void UpdateVisibilityState();
|
||||
|
@ -1066,6 +1075,10 @@ protected:
|
|||
// is a weak reference to avoid leaks due to circular references.
|
||||
nsWeakPtr mScopeObject;
|
||||
|
||||
// The document which requested (and was granted) full-screen. All ancestors
|
||||
// of this document will also be full-screen.
|
||||
static nsWeakPtr sFullScreenDoc;
|
||||
|
||||
nsRefPtr<nsEventListenerManager> mListenerManager;
|
||||
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
|
||||
nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
|
|
@ -3056,6 +3056,14 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsFullScreenAncestor(Element* aElement)
|
||||
{
|
||||
nsEventStates state = aElement->State();
|
||||
return state.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
|
||||
NS_EVENT_STATE_FULL_SCREEN);
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
|
@ -3067,6 +3075,11 @@ nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetCurrentDoc();
|
||||
|
||||
if (aNullParent) {
|
||||
if (IsFullScreenAncestor(this)) {
|
||||
// The element being removed is an ancestor of the full-screen element,
|
||||
// exit full-screen state.
|
||||
OwnerDoc()->CancelFullScreen();
|
||||
}
|
||||
if (GetParent()) {
|
||||
NS_RELEASE(mParent);
|
||||
} else {
|
||||
|
@ -5352,21 +5365,67 @@ ParseSelectorList(nsINode* aNode,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIContent*
|
||||
nsGenericElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
|
||||
nsresult *aResult)
|
||||
// Actually find elements matching aSelectorList (which must not be
|
||||
// null) and which are descendants of aRoot and put them in Alist. If
|
||||
// onlyFirstMatch, then stop once the first one is found.
|
||||
template<bool onlyFirstMatch, class T>
|
||||
inline static nsresult FindMatchingElements(nsINode* aRoot,
|
||||
const nsAString& aSelector,
|
||||
T &aList)
|
||||
{
|
||||
NS_PRECONDITION(aResult, "Null out param?");
|
||||
|
||||
nsAutoPtr<nsCSSSelectorList> selectorList;
|
||||
*aResult = ParseSelectorList(aRoot, aSelector,
|
||||
getter_Transfers(selectorList));
|
||||
NS_ENSURE_SUCCESS(*aResult, nsnull);
|
||||
nsresult rv = ParseSelectorList(aRoot, aSelector,
|
||||
getter_Transfers(selectorList));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(selectorList, NS_OK);
|
||||
|
||||
NS_ASSERTION(selectorList->mSelectors,
|
||||
"How can we not have any selectors?");
|
||||
|
||||
nsIDocument* doc = aRoot->OwnerDoc();
|
||||
TreeMatchContext matchingContext(false, nsRuleWalker::eRelevantLinkUnvisited,
|
||||
doc);
|
||||
|
||||
// Fast-path selectors involving IDs. We can only do this if aRoot
|
||||
// is in the document and the document is not in quirks mode, since
|
||||
// ID selectors are case-insensitive in quirks mode. Also, only do
|
||||
// this if selectorList only has one selector, because otherwise
|
||||
// ordering the elements correctly is a pain.
|
||||
NS_ASSERTION(aRoot->IsElement() || aRoot->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
"Unexpected root node");
|
||||
if (aRoot->IsInDoc() &&
|
||||
doc->GetCompatibilityMode() != eCompatibility_NavQuirks &&
|
||||
!selectorList->mNext &&
|
||||
selectorList->mSelectors->mIDList) {
|
||||
nsIAtom* id = selectorList->mSelectors->mIDList->mAtom;
|
||||
const nsSmallVoidArray* elements =
|
||||
doc->GetAllElementsForId(nsDependentAtomString(id));
|
||||
|
||||
// XXXbz: Should we fall back to the tree walk if aRoot is not the
|
||||
// document and |elements| is long, for some value of "long"?
|
||||
if (elements) {
|
||||
for (PRUint32 i = 0; i < elements->Count(); ++i) {
|
||||
Element *element = static_cast<Element*>(elements->ElementAt(i));
|
||||
if (!aRoot->IsElement() ||
|
||||
nsContentUtils::ContentIsDescendantOf(element, aRoot)) {
|
||||
// We have an element with the right id and it's a descendant
|
||||
// of aRoot. Make sure it really matches the selector.
|
||||
if (nsCSSRuleProcessor::SelectorListMatches(element, matchingContext,
|
||||
selectorList)) {
|
||||
aList.AppendElement(element);
|
||||
if (onlyFirstMatch) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No elements with this id, or none of them are our descendants,
|
||||
// or none of them match. We're done here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TreeMatchContext matchingContext(false,
|
||||
nsRuleWalker::eRelevantLinkUnvisited,
|
||||
aRoot->OwnerDoc());
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextNode(aRoot)) {
|
||||
|
@ -5374,11 +5433,36 @@ nsGenericElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
|
|||
nsCSSRuleProcessor::SelectorListMatches(cur->AsElement(),
|
||||
matchingContext,
|
||||
selectorList)) {
|
||||
return cur;
|
||||
aList.AppendElement(cur->AsElement());
|
||||
if (onlyFirstMatch) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ElementHolder {
|
||||
ElementHolder() : mElement(nsnull) {}
|
||||
void AppendElement(Element* aElement) {
|
||||
NS_ABORT_IF_FALSE(!mElement, "Should only get one element");
|
||||
mElement = aElement;
|
||||
}
|
||||
Element* mElement;
|
||||
};
|
||||
|
||||
/* static */
|
||||
nsIContent*
|
||||
nsGenericElement::doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
|
||||
nsresult *aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult, "Null out param?");
|
||||
|
||||
ElementHolder holder;
|
||||
*aResult = FindMatchingElements<true>(aRoot, aSelector, holder);
|
||||
|
||||
return holder.mElement;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -5393,25 +5477,7 @@ nsGenericElement::doQuerySelectorAll(nsINode* aRoot,
|
|||
NS_ENSURE_TRUE(contentList, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ADDREF(*aReturn = contentList);
|
||||
|
||||
nsAutoPtr<nsCSSSelectorList> selectorList;
|
||||
nsresult rv = ParseSelectorList(aRoot, aSelector,
|
||||
getter_Transfers(selectorList));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
TreeMatchContext matchingContext(false,
|
||||
nsRuleWalker::eRelevantLinkUnvisited,
|
||||
aRoot->OwnerDoc());
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextNode(aRoot)) {
|
||||
if (cur->IsElement() &&
|
||||
nsCSSRuleProcessor::SelectorListMatches(cur->AsElement(),
|
||||
matchingContext,
|
||||
selectorList)) {
|
||||
contentList->AppendElement(cur);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return FindMatchingElements<false>(aRoot, aSelector, *contentList);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -259,10 +259,7 @@ nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
|
|||
!JSVAL_IS_PRIMITIVE(argv[6]))
|
||||
{
|
||||
JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
|
||||
if (js_IsArrayBuffer(argv6)) {
|
||||
rv = self->ReadPixels_buf(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, js::ArrayBuffer::getArrayBuffer(argv6));
|
||||
} else if (js_IsTypedArray(argv6)) {
|
||||
if (js_IsTypedArray(argv6)) {
|
||||
rv = self->ReadPixels_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5,
|
||||
js::TypedArray::getTypedArray(argv6));
|
||||
|
@ -380,15 +377,11 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
|||
|
||||
JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
|
||||
|
||||
// then try to grab either a js::ArrayBuffer, js::TypedArray, or null
|
||||
// then try to grab either a js::TypedArray, or null
|
||||
if (argv8 == nsnull) {
|
||||
rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
nsnull);
|
||||
} else if (js_IsArrayBuffer(argv8)) {
|
||||
rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
js::ArrayBuffer::getArrayBuffer(argv8));
|
||||
rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
nsnull);
|
||||
} else if (js_IsTypedArray(argv8)) {
|
||||
rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
|
@ -503,12 +496,8 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
|
|||
GET_UINT32_ARG(argv7, 7);
|
||||
|
||||
JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);
|
||||
// try to grab either a js::ArrayBuffer or js::TypedArray
|
||||
if (js_IsArrayBuffer(argv8)) {
|
||||
rv = self->TexSubImage2D_buf(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
js::ArrayBuffer::getArrayBuffer(argv8));
|
||||
} else if (js_IsTypedArray(argv8)) {
|
||||
// try to grab a js::TypedArray
|
||||
if (js_IsTypedArray(argv8)) {
|
||||
rv = self->TexSubImage2D_array(argv0, argv1, argv2, argv3,
|
||||
argv4, argv5, argv6, argv7,
|
||||
js::TypedArray::getTypedArray(argv8));
|
||||
|
|
|
@ -811,19 +811,32 @@ WebGLContext::GetThebesSurface(gfxASurface **surface)
|
|||
|
||||
static PRUint8 gWebGLLayerUserData;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLContextUserData : public LayerUserData {
|
||||
public:
|
||||
WebGLContextUserData(nsHTMLCanvasElement *aContent)
|
||||
: mContent(aContent) {}
|
||||
|
||||
/** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
|
||||
* so it really is the right place to put actions that have to be performed upon compositing
|
||||
*/
|
||||
static void DidTransactionCallback(void* aData)
|
||||
{
|
||||
static_cast<WebGLContextUserData*>(aData)->mContent->MarkContextClean();
|
||||
WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
|
||||
nsHTMLCanvasElement *canvas = userdata->mContent;
|
||||
WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
|
||||
|
||||
context->mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
|
||||
canvas->MarkContextClean();
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsHTMLCanvasElement> mContent;
|
||||
};
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
already_AddRefed<layers::CanvasLayer>
|
||||
WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
||||
CanvasLayer *aOldLayer,
|
||||
|
@ -887,8 +900,6 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
mResetLayer = false;
|
||||
|
||||
mBackbufferClearingStatus = BackbufferClearingStatus::NotClearedSinceLastPresented;
|
||||
|
||||
return canvasLayer.forget().get();
|
||||
}
|
||||
|
||||
|
|
|
@ -344,6 +344,7 @@ class WebGLContext :
|
|||
{
|
||||
friend class WebGLMemoryReporter;
|
||||
friend class WebGLExtensionLoseContext;
|
||||
friend class WebGLContextUserData;
|
||||
|
||||
public:
|
||||
WebGLContext();
|
||||
|
@ -579,7 +580,7 @@ protected:
|
|||
int jsArrayType,
|
||||
int srcFormat, bool srcPremultiplied);
|
||||
nsresult ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type, void *data, PRUint32 byteLength);
|
||||
WebGLenum format, WebGLenum type, JSObject* pixels);
|
||||
nsresult TexParameter_base(WebGLenum target, WebGLenum pname,
|
||||
WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
|
||||
|
||||
|
|
|
@ -1534,6 +1534,11 @@ WebGLContext::BindFakeBlackTextures()
|
|||
return;
|
||||
|
||||
if (!mBlackTexturesAreInitialized) {
|
||||
GLuint bound2DTex = 0;
|
||||
GLuint boundCubeTex = 0;
|
||||
gl->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, (GLint*) &bound2DTex);
|
||||
gl->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, (GLint*) &boundCubeTex);
|
||||
|
||||
const PRUint8 black[] = {0, 0, 0, 255};
|
||||
|
||||
gl->fGenTextures(1, &mBlackTexture2D);
|
||||
|
@ -1548,9 +1553,9 @@ WebGLContext::BindFakeBlackTextures()
|
|||
0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, &black);
|
||||
}
|
||||
|
||||
// return the texture bindings to the 0 texture to prevent the user from modifying our black textures
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, 0);
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, 0);
|
||||
// Reset bound textures
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, bound2DTex);
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_CUBE_MAP, boundCubeTex);
|
||||
|
||||
mBlackTexturesAreInitialized = true;
|
||||
}
|
||||
|
@ -3340,7 +3345,7 @@ WebGLContext::ReadPixels(PRInt32)
|
|||
|
||||
nsresult
|
||||
WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type, void *data, PRUint32 byteLength)
|
||||
WebGLenum format, WebGLenum type, JSObject* pixels)
|
||||
{
|
||||
if (HTMLCanvasElement()->IsWriteOnly() && !nsContentUtils::IsCallerTrustedForRead()) {
|
||||
LogMessageIfVerbose("ReadPixels: Not allowed");
|
||||
|
@ -3350,53 +3355,86 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||
if (width < 0 || height < 0)
|
||||
return ErrorInvalidValue("ReadPixels: negative size passed");
|
||||
|
||||
// there's nothing to do in this case, since we won't read any pixels
|
||||
if (width == 0 || height == 0)
|
||||
return NS_OK;
|
||||
if (!pixels)
|
||||
return ErrorInvalidValue("ReadPixels: null array passed");
|
||||
|
||||
WebGLsizei boundWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
|
||||
WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
|
||||
|
||||
PRUint32 size = 0;
|
||||
bool badFormat = false, badType = false;
|
||||
void* data = JS_GetTypedArrayData(pixels);
|
||||
PRUint32 dataByteLen = JS_GetTypedArrayByteLength(pixels);
|
||||
int dataType = JS_GetTypedArrayType(pixels);
|
||||
|
||||
PRUint32 channels = 0;
|
||||
|
||||
// Check the format param
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGBA:
|
||||
size = 4;
|
||||
break;
|
||||
default:
|
||||
badFormat = true;
|
||||
break;
|
||||
case LOCAL_GL_ALPHA:
|
||||
channels = 1;
|
||||
break;
|
||||
case LOCAL_GL_RGB:
|
||||
channels = 3;
|
||||
break;
|
||||
case LOCAL_GL_RGBA:
|
||||
channels = 4;
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidEnum("readPixels: Bad format");
|
||||
}
|
||||
|
||||
PRUint32 bytesPerPixel = 0;
|
||||
int requiredDataType = 0;
|
||||
|
||||
// Check the type param
|
||||
switch (type) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
break;
|
||||
default:
|
||||
badType = true;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
bytesPerPixel = 1 * channels;
|
||||
requiredDataType = js::TypedArray::TYPE_UINT8;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
bytesPerPixel = 2;
|
||||
requiredDataType = js::TypedArray::TYPE_UINT16;
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidEnum("readPixels: Bad type");
|
||||
}
|
||||
|
||||
if (badFormat && badType)
|
||||
return ErrorInvalidOperation("readPixels: bad format and type");
|
||||
if (badFormat)
|
||||
return ErrorInvalidEnumInfo("readPixels: format", format);
|
||||
if (badType)
|
||||
return ErrorInvalidEnumInfo("ReadPixels: type", type);
|
||||
// Check the pixels param type
|
||||
if (dataType != requiredDataType)
|
||||
return ErrorInvalidOperation("readPixels: Mismatched type/pixels types");
|
||||
|
||||
// Check the pixels param size
|
||||
CheckedUint32 checked_neededByteLength =
|
||||
GetImageSize(height, width, size, mPixelStorePackAlignment);
|
||||
GetImageSize(height, width, bytesPerPixel, mPixelStorePackAlignment);
|
||||
|
||||
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
||||
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * bytesPerPixel;
|
||||
|
||||
CheckedUint32 checked_alignedRowSize =
|
||||
CheckedUint32 checked_alignedRowSize =
|
||||
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
|
||||
|
||||
if (!checked_neededByteLength.valid())
|
||||
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
||||
|
||||
if (checked_neededByteLength.value() > byteLength)
|
||||
if (checked_neededByteLength.value() > dataByteLen)
|
||||
return ErrorInvalidOperation("ReadPixels: buffer too small");
|
||||
|
||||
// Check the format and type params to assure they are an acceptable pair (as per spec)
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGBA: {
|
||||
switch (type) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidOperation("readPixels: Invalid format/type pair");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ErrorInvalidOperation("readPixels: Invalid format/type pair");
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
if (mBoundFramebuffer) {
|
||||
|
@ -3406,7 +3444,11 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||
} else {
|
||||
EnsureBackbufferClearedAsNeeded();
|
||||
}
|
||||
// Now that the errors are out of the way, on to actually reading
|
||||
|
||||
// If we won't be reading any pixels anyways, just skip the actual reading
|
||||
if (width == 0 || height == 0)
|
||||
return NS_OK;
|
||||
|
||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, boundWidth, boundHeight)) {
|
||||
// the easy case: we're not reading out-of-range pixels
|
||||
|
@ -3421,7 +3463,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||
|
||||
// zero the whole destination buffer. Too bad for the part that's going to be overwritten, we're not
|
||||
// 100% efficient here, but in practice this is a quite rare case anyway.
|
||||
memset(data, 0, byteLength);
|
||||
memset(data, 0, dataByteLen);
|
||||
|
||||
if ( x >= boundWidth
|
||||
|| x+width <= 0
|
||||
|
@ -3449,7 +3491,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||
|
||||
// now, same computation as above to find the size of the intermediate buffer to allocate for the subrect
|
||||
// no need to check again for integer overflow here, since we already know the sizes aren't greater than before
|
||||
PRUint32 subrect_plainRowSize = subrect_width * size;
|
||||
PRUint32 subrect_plainRowSize = subrect_width * bytesPerPixel;
|
||||
// There are checks above to ensure that this doesn't overflow.
|
||||
PRUint32 subrect_alignedRowSize =
|
||||
RoundedToNextMultipleOf(subrect_plainRowSize, mPixelStorePackAlignment).value();
|
||||
|
@ -3465,7 +3507,7 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
|||
GLint subrect_y_in_dest_buffer = subrect_y - y;
|
||||
memcpy(static_cast<GLubyte*>(data)
|
||||
+ checked_alignedRowSize.value() * (subrect_y_in_dest_buffer + y_inside_subrect)
|
||||
+ size * subrect_x_in_dest_buffer, // destination
|
||||
+ bytesPerPixel * subrect_x_in_dest_buffer, // destination
|
||||
subrect_data + subrect_alignedRowSize * y_inside_subrect, // source
|
||||
subrect_plainRowSize); // size
|
||||
}
|
||||
|
@ -3527,21 +3569,7 @@ WebGLContext::ReadPixels_array(WebGLint x, WebGLint y, WebGLsizei width, WebGLsi
|
|||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
return ReadPixels_base(x, y, width, height, format, type,
|
||||
pixels ? JS_GetTypedArrayData(pixels) : 0,
|
||||
pixels ? JS_GetTypedArrayByteLength(pixels) : 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::ReadPixels_buf(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type, JSObject *pixels)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
return ReadPixels_base(x, y, width, height, format, type,
|
||||
pixels ? JS_GetArrayBufferData(pixels) : 0,
|
||||
pixels ? JS_GetArrayBufferByteLength(pixels) : 0);
|
||||
return ReadPixels_base(x, y, width, height, format, type, pixels);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4910,22 +4938,6 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D_buf(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
|
||||
pixels ? JS_GetArrayBufferData(pixels) : 0,
|
||||
pixels ? JS_GetArrayBufferByteLength(pixels) : 0,
|
||||
-1,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D_array(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLint border,
|
||||
|
@ -4938,7 +4950,7 @@ WebGLContext::TexImage2D_array(WebGLenum target, WebGLint level, WebGLenum inter
|
|||
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
|
||||
pixels ? JS_GetTypedArrayData(pixels) : 0,
|
||||
pixels ? JS_GetTypedArrayByteLength(pixels) : 0,
|
||||
(int) JS_GetTypedArrayType(pixels),
|
||||
pixels ? (int)JS_GetTypedArrayType(pixels) : -1,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
|
@ -5106,26 +5118,6 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexSubImage2D_buf(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
WebGLsizei width, WebGLsizei height,
|
||||
WebGLenum format, WebGLenum type,
|
||||
JSObject *pixels)
|
||||
{
|
||||
if (mContextLost)
|
||||
return NS_OK;
|
||||
|
||||
if (!pixels)
|
||||
return ErrorInvalidValue("TexSubImage2D: pixels must not be null!");
|
||||
|
||||
return TexSubImage2D_base(target, level, xoffset, yoffset,
|
||||
width, height, 0, format, type,
|
||||
JS_GetArrayBufferData(pixels), JS_GetArrayBufferByteLength(pixels),
|
||||
-1,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexSubImage2D_array(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
|
|
|
@ -4,11 +4,7 @@ conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
|||
conformance/glsl/misc/shader-with-long-line.html
|
||||
conformance/misc/uninitialized-test.html
|
||||
conformance/programs/gl-get-active-attribute.html
|
||||
conformance/reading/read-pixels-test.html
|
||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||
conformance/textures/texture-mips.html
|
||||
conformance/uniforms/gl-uniform-bool.html
|
||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/uniformfArrayLen1.html
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
conformance/canvas/buffer-preserve-test.html
|
||||
conformance/context/context-attributes-alpha-depth-stencil-antialias.html
|
||||
conformance/context/premultiplyalpha-test.html
|
||||
conformance/glsl/misc/glsl-function-nodes.html
|
||||
conformance/glsl/misc/glsl-long-variable-names.html
|
||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||
conformance/glsl/misc/shader-with-long-line.html
|
||||
conformance/programs/program-test.html
|
||||
conformance/reading/read-pixels-test.html
|
||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||
conformance/state/gl-object-get-calls.html
|
||||
conformance/textures/tex-input-validation.html
|
||||
conformance/textures/texture-mips.html
|
||||
conformance/textures/texture-npot.html
|
||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/uniformfBadArgs.html
|
||||
conformance/more/functions/uniformiBadArgs.html
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
conformance/canvas/buffer-preserve-test.html
|
||||
conformance/context/premultiplyalpha-test.html
|
||||
conformance/glsl/functions/glsl-function-atan.html
|
||||
conformance/glsl/functions/glsl-function-atan-xy.html
|
||||
|
@ -6,9 +5,5 @@ conformance/glsl/functions/glsl-function-mod-gentype.html
|
|||
conformance/glsl/misc/glsl-long-variable-names.html
|
||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||
conformance/glsl/misc/shader-with-long-line.html
|
||||
conformance/reading/read-pixels-test.html
|
||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||
conformance/more/functions/copyTexImage2D.html
|
||||
conformance/more/functions/copyTexSubImage2D.html
|
||||
conformance/more/functions/uniformfArrayLen1.html
|
||||
|
|
|
@ -264,8 +264,10 @@ private:
|
|||
// Content is the full screen element, or a frame containing the
|
||||
// current full-screen element.
|
||||
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(34)
|
||||
// Content is an ancestor of the DOM full-screen element.
|
||||
#define NS_EVENT_STATE_FULL_SCREEN_ANCESTOR NS_DEFINE_EVENT_STATE_MACRO(35)
|
||||
// Handler for click to play plugin
|
||||
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
|
||||
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(36)
|
||||
|
||||
/**
|
||||
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
||||
|
@ -274,7 +276,7 @@ private:
|
|||
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
|
||||
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
|
||||
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
|
||||
NS_EVENT_STATE_FULL_SCREEN)
|
||||
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR)
|
||||
|
||||
#define INTRINSIC_STATES (~ESM_MANAGED_STATES)
|
||||
|
||||
|
|
|
@ -4445,12 +4445,22 @@ static nsIContent* FindCommonAncestor(nsIContent *aNode1, nsIContent *aNode2)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
static Element*
|
||||
GetParentElement(Element* aElement)
|
||||
{
|
||||
nsIContent* p = aElement->GetParent();
|
||||
return (p && p->IsElement()) ? p->AsElement() : nsnull;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsEventStateManager::SetFullScreenState(Element* aElement,
|
||||
bool aIsFullScreen)
|
||||
nsEventStateManager::SetFullScreenState(Element* aElement, bool aIsFullScreen)
|
||||
{
|
||||
DoStateChange(aElement, NS_EVENT_STATE_FULL_SCREEN, aIsFullScreen);
|
||||
Element* ancestor = aElement;
|
||||
while ((ancestor = GetParentElement(ancestor))) {
|
||||
DoStateChange(ancestor, NS_EVENT_STATE_FULL_SCREEN_ANCESTOR, aIsFullScreen);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -3403,7 +3403,8 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
// This stops the full-screen from being abused similar to the popups of old,
|
||||
// and it also makes it harder for bad guys' script to go full-screen and
|
||||
// spoof the browser chrome/window and phish logins etc.
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed()) {
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed() ||
|
||||
!IsInDoc()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3418,11 +3419,7 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
|
||||
doc->RequestFullScreen(this);
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(doc->GetWindow());
|
||||
NS_ENSURE_STATE(window);
|
||||
bool fullscreen;
|
||||
window->GetFullScreen(&fullscreen);
|
||||
NS_ASSERTION(fullscreen, "Windows should report fullscreen");
|
||||
domDocument->GetMozFullScreen(&fullscreen);
|
||||
NS_ASSERTION(fullscreen, "Document should report fullscreen");
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be in full screen state!");
|
||||
|
|
|
@ -282,6 +282,7 @@ _TEST_FILES = \
|
|||
file_fullscreen-api-keys.html \
|
||||
test_fullscreen-api.html \
|
||||
file_fullscreen-plugins.html \
|
||||
file_fullscreen-denied.html \
|
||||
test_li_attributes_reflection.html \
|
||||
test_ol_attributes_reflection.html \
|
||||
test_bug651956.html \
|
||||
|
|
|
@ -1,250 +1,116 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=545812
|
||||
|
||||
Test that restricted key pressed drop documents out of DOM full-screen mode.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
</head>
|
||||
<body onload="document.body.mozRequestFullScreen();">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
|
||||
// List of key codes, and whether they're restricted in full-screen mode.
|
||||
var keyList = [
|
||||
// Allowed: DOM_VK_CANCEL to DOM_VK_CAPS_LOCK, inclusive
|
||||
{ code: "VK_CANCEL", allowed: true},
|
||||
{ code: "VK_HELP", allowed: true},
|
||||
{ code: "VK_BACK_SPACE", allowed: true},
|
||||
{ code: "VK_TAB", allowed: true},
|
||||
{ code: "VK_CLEAR", allowed: true},
|
||||
{ code: "VK_RETURN", allowed: true},
|
||||
{ code: "VK_ENTER", allowed: true},
|
||||
{ code: "VK_SHIFT", allowed: true},
|
||||
{ code: "VK_CONTROL", allowed: true},
|
||||
{ code: "VK_ALT", allowed: true},
|
||||
{ code: "VK_PAUSE", allowed: true},
|
||||
{ code: "VK_CAPS_LOCK", allowed: true},
|
||||
|
||||
{ code: "VK_KANA", allowed: false},
|
||||
{ code: "VK_HANGUL", allowed: false},
|
||||
{ code: "VK_JUNJA", allowed: false},
|
||||
{ code: "VK_FINAL", allowed: false},
|
||||
{ code: "VK_HANJA", allowed: false},
|
||||
{ code: "VK_KANJI", allowed: false},
|
||||
{ code: "VK_ESCAPE", allowed: false},
|
||||
{ code: "VK_CONVERT", allowed: false},
|
||||
{ code: "VK_NONCONVERT", allowed: false},
|
||||
{ code: "VK_ACCEPT", allowed: false},
|
||||
{ code: "VK_MODECHANGE", allowed: false},
|
||||
|
||||
// Allowed: DOM_VK_SPACE to DOM_VK_DELETE, inclusive
|
||||
{ code: "VK_SPACE", allowed: true},
|
||||
{ code: "VK_PAGE_UP", allowed: true},
|
||||
{ code: "VK_PAGE_DOWN", allowed: true},
|
||||
{ code: "VK_END", allowed: true},
|
||||
{ code: "VK_HOME", allowed: true},
|
||||
{ code: "VK_LEFT", allowed: true},
|
||||
{ code: "VK_UP", allowed: true},
|
||||
{ code: "VK_RIGHT", allowed: true},
|
||||
{ code: "VK_DOWN", allowed: true},
|
||||
{ code: "VK_SELECT", allowed: true},
|
||||
{ code: "VK_PRINT", allowed: true},
|
||||
{ code: "VK_EXECUTE", allowed: true},
|
||||
{ code: "VK_PRINTSCREEN", allowed: true},
|
||||
{ code: "VK_INSERT", allowed: true},
|
||||
{ code: "VK_DELETE", allowed: true},
|
||||
|
||||
{ code: "VK_0", allowed: false},
|
||||
{ code: "VK_1", allowed: false},
|
||||
{ code: "VK_2", allowed: false},
|
||||
{ code: "VK_3", allowed: false},
|
||||
{ code: "VK_4", allowed: false},
|
||||
{ code: "VK_5", allowed: false},
|
||||
{ code: "VK_6", allowed: false},
|
||||
{ code: "VK_7", allowed: false},
|
||||
{ code: "VK_8", allowed: false},
|
||||
{ code: "VK_9", allowed: false},
|
||||
|
||||
// Allowed: DOM_VK_SPACE to DOM_VK_DELETE, inclusive
|
||||
{ code: "VK_SEMICOLON", allowed: true},
|
||||
{ code: "VK_EQUALS", allowed: true},
|
||||
|
||||
{ code: "VK_A", allowed: false},
|
||||
{ code: "VK_B", allowed: false},
|
||||
{ code: "VK_C", allowed: false},
|
||||
{ code: "VK_D", allowed: false},
|
||||
{ code: "VK_E", allowed: false},
|
||||
{ code: "VK_F", allowed: false},
|
||||
{ code: "VK_G", allowed: false},
|
||||
{ code: "VK_H", allowed: false},
|
||||
{ code: "VK_I", allowed: false},
|
||||
{ code: "VK_J", allowed: false},
|
||||
{ code: "VK_K", allowed: false},
|
||||
{ code: "VK_L", allowed: false},
|
||||
{ code: "VK_M", allowed: false},
|
||||
{ code: "VK_N", allowed: false},
|
||||
{ code: "VK_O", allowed: false},
|
||||
{ code: "VK_P", allowed: false},
|
||||
{ code: "VK_Q", allowed: false},
|
||||
{ code: "VK_R", allowed: false},
|
||||
{ code: "VK_S", allowed: false},
|
||||
{ code: "VK_T", allowed: false},
|
||||
{ code: "VK_U", allowed: false},
|
||||
{ code: "VK_V", allowed: false},
|
||||
{ code: "VK_W", allowed: false},
|
||||
{ code: "VK_X", allowed: false},
|
||||
{ code: "VK_Y", allowed: false},
|
||||
{ code: "VK_Z", allowed: false},
|
||||
{ code: "VK_CONTEXT_MENU", allowed: false},
|
||||
{ code: "VK_SLEEP", allowed: false},
|
||||
{ code: "VK_NUMPAD0", allowed: false},
|
||||
{ code: "VK_NUMPAD1", allowed: false},
|
||||
{ code: "VK_NUMPAD2", allowed: false},
|
||||
{ code: "VK_NUMPAD3", allowed: false},
|
||||
{ code: "VK_NUMPAD4", allowed: false},
|
||||
{ code: "VK_NUMPAD5", allowed: false},
|
||||
{ code: "VK_NUMPAD6", allowed: false},
|
||||
{ code: "VK_NUMPAD7", allowed: false},
|
||||
{ code: "VK_NUMPAD8", allowed: false},
|
||||
{ code: "VK_NUMPAD9", allowed: false},
|
||||
|
||||
// Allowed: DOM_VK_MULTIPLY to DOM_VK_META, inclusive
|
||||
{ code: "VK_MULTIPLY", allowed: true},
|
||||
{ code: "VK_ADD", allowed: true},
|
||||
{ code: "VK_SEPARATOR", allowed: true},
|
||||
{ code: "VK_SUBTRACT", allowed: true},
|
||||
{ code: "VK_DECIMAL", allowed: true},
|
||||
{ code: "VK_DIVIDE", allowed: true},
|
||||
{ code: "VK_F1", allowed: true},
|
||||
{ code: "VK_F2", allowed: true},
|
||||
{ code: "VK_F3", allowed: true},
|
||||
{ code: "VK_F4", allowed: true},
|
||||
{ code: "VK_F5", allowed: true},
|
||||
{ code: "VK_F6", allowed: true},
|
||||
{ code: "VK_F7", allowed: true},
|
||||
{ code: "VK_F8", allowed: true},
|
||||
{ code: "VK_F9", allowed: true},
|
||||
{ code: "VK_F10", allowed: true},
|
||||
{ code: "VK_F11", allowed: true},
|
||||
{ code: "VK_F12", allowed: true},
|
||||
{ code: "VK_F13", allowed: true},
|
||||
{ code: "VK_F14", allowed: true},
|
||||
{ code: "VK_F15", allowed: true},
|
||||
{ code: "VK_F16", allowed: true},
|
||||
{ code: "VK_F17", allowed: true},
|
||||
{ code: "VK_F18", allowed: true},
|
||||
{ code: "VK_F19", allowed: true},
|
||||
{ code: "VK_F20", allowed: true},
|
||||
{ code: "VK_F21", allowed: true},
|
||||
{ code: "VK_F22", allowed: true},
|
||||
{ code: "VK_F23", allowed: true},
|
||||
{ code: "VK_F24", allowed: true},
|
||||
{ code: "VK_NUM_LOCK", allowed: true},
|
||||
{ code: "VK_SCROLL_LOCK", allowed: true},
|
||||
{ code: "VK_COMMA", allowed: true},
|
||||
{ code: "VK_PERIOD", allowed: true},
|
||||
{ code: "VK_SLASH", allowed: true},
|
||||
{ code: "VK_BACK_QUOTE", allowed: true},
|
||||
{ code: "VK_OPEN_BRACKET", allowed: true},
|
||||
{ code: "VK_BACK_SLASH", allowed: true},
|
||||
{ code: "VK_CLOSE_BRACKET", allowed: true},
|
||||
{ code: "VK_QUOTE", allowed: true},
|
||||
{ code: "VK_META", allowed: true},
|
||||
];
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, msg);
|
||||
}
|
||||
|
||||
var gKeyTestIndex = 0;
|
||||
var gKeyName;
|
||||
var gKeyCode;
|
||||
var gKeyAllowed;
|
||||
var gKeyReceived = false;
|
||||
|
||||
function keyHandler(event) {
|
||||
event.preventDefault()
|
||||
gKeyReceived = true;
|
||||
}
|
||||
|
||||
function checkKeyEffect() {
|
||||
is(document.mozFullScreen, gKeyAllowed,
|
||||
(gKeyAllowed ? ("Should remain in full-screen mode for allowed key press " + gKeyName)
|
||||
: ("Should drop out of full-screen mode for restricted key press " + gKeyName)));
|
||||
|
||||
if (gKeyTestIndex < keyList.length) {
|
||||
setTimeout(testNextKey, 0);
|
||||
} else {
|
||||
opener.keysTestFinished();
|
||||
}
|
||||
}
|
||||
|
||||
function testTrustedKeyEvents() {
|
||||
document.body.focus();
|
||||
gKeyReceived = false;
|
||||
synthesizeKey(gKeyName, {});
|
||||
setTimeout(checkKeyEffect, 0);
|
||||
}
|
||||
|
||||
function testScriptInitiatedKeyEvents() {
|
||||
// Script initiated untrusted key events should not be blocked.
|
||||
document.body.focus();
|
||||
gKeyReceived = false;
|
||||
var evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keydown", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keypress", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keyup", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
ok(gKeyReceived, "dispatchEvent should dispatch events synchronously");
|
||||
ok(document.mozFullScreen,
|
||||
"Should remain in full-screen mode for script initiated key events for " + gKeyName);
|
||||
}
|
||||
|
||||
function testNextKey() {
|
||||
if (!document.mozFullScreen) {
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
ok(document.mozFullScreen, "Must be in full-screen mode");
|
||||
|
||||
gKeyName = keyList[gKeyTestIndex].code;
|
||||
gKeyCode = KeyEvent["DOM_" + gKeyName];
|
||||
gKeyAllowed = keyList[gKeyTestIndex].allowed;
|
||||
gKeyTestIndex++;
|
||||
|
||||
testScriptInitiatedKeyEvents();
|
||||
testTrustedKeyEvents();
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", keyHandler, true);
|
||||
window.addEventListener("keyup", keyHandler, true);
|
||||
window.addEventListener("keypress", keyHandler, true);
|
||||
setTimeout(testNextKey, 0);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=545812
|
||||
|
||||
Test that restricted key pressed drop documents out of DOM full-screen mode.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="document.body.mozRequestFullScreen();">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
|
||||
// List of key codes which should exit full-screen mode.
|
||||
var keyList = [
|
||||
{ code: "VK_ESCAPE", suppressed: true},
|
||||
{ code: "VK_F11", suppressed: false},
|
||||
];
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, msg);
|
||||
}
|
||||
|
||||
var gKeyTestIndex = 0;
|
||||
var gKeyName;
|
||||
var gKeyCode;
|
||||
var gKeySuppressed;
|
||||
var gKeyReceived = false;
|
||||
|
||||
function keyHandler(event) {
|
||||
gKeyReceived = true;
|
||||
}
|
||||
|
||||
function checkKeyEffect() {
|
||||
is(gKeySuppressed, !gKeyReceived, "Should not receive key events for " + gKeyName);
|
||||
is(document.mozFullScreen, false, "Should exit full-screen mode for " + gKeyName + " press");
|
||||
if (gKeyTestIndex < keyList.length) {
|
||||
setTimeout(testNextKey, 0);
|
||||
} else {
|
||||
document.mozCancelFullScreen();
|
||||
opener.nextTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testTrustedKeyEvents() {
|
||||
document.body.focus();
|
||||
gKeyReceived = false;
|
||||
synthesizeKey(gKeyName, {});
|
||||
setTimeout(checkKeyEffect, 0);
|
||||
}
|
||||
|
||||
function testScriptInitiatedKeyEvents() {
|
||||
// Script initiated untrusted key events should not cause full-screen exit.
|
||||
document.body.focus();
|
||||
gKeyReceived = false;
|
||||
var evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keydown", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keypress", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
evt = document.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keyup", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
document.body.dispatchEvent(evt);
|
||||
|
||||
ok(gKeyReceived, "dispatchEvent should dispatch events synchronously");
|
||||
ok(document.mozFullScreen,
|
||||
"Should remain in full-screen mode for script initiated key events for " + gKeyName);
|
||||
}
|
||||
|
||||
function testNextKey() {
|
||||
if (!document.mozFullScreen) {
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
ok(document.mozFullScreen, "Must be in full-screen mode");
|
||||
|
||||
gKeyName = keyList[gKeyTestIndex].code;
|
||||
gKeyCode = KeyEvent["DOM_" + gKeyName];
|
||||
gKeySuppressed = keyList[gKeyTestIndex].suppressed;
|
||||
gKeyTestIndex++;
|
||||
|
||||
testScriptInitiatedKeyEvents();
|
||||
testTrustedKeyEvents();
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", keyHandler, true);
|
||||
window.addEventListener("keyup", keyHandler, true);
|
||||
window.addEventListener("keypress", keyHandler, true);
|
||||
setTimeout(testNextKey, 0);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=545812
|
||||
|
@ -10,12 +10,12 @@ Test DOM full-screen API.
|
|||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<style>
|
||||
body:-moz-full-screen, div:-moz-full-screen {
|
||||
background-color: red;
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="document.body.mozRequestFullScreen();">
|
||||
<body onload="fullScreenElement().mozRequestFullScreen();">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
@ -32,14 +32,16 @@ function is(a, b, msg) {
|
|||
/*
|
||||
<html>
|
||||
<body onload='document.body.mozRequestFullScreen();'>
|
||||
<iframe id='inner-frame'></iframe>
|
||||
</body>
|
||||
</html>
|
||||
*/
|
||||
var iframeContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D'document.body.mozRequestFullScreen()%3B'>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>";
|
||||
var iframeContents = "data:text/html;charset=utf-8,<html><body onload%3D'document.body.mozRequestFullScreen()%3B'><iframe id%3D'inner-frame'><%2Fiframe><%2Fbody><%2Fhtml>";
|
||||
|
||||
var iframe = null;
|
||||
var outOfDocElement = null;
|
||||
var inDocElement = null;
|
||||
var container = null;
|
||||
var button = null;
|
||||
|
||||
var fullScreenChangeCount = 0;
|
||||
|
@ -52,19 +54,33 @@ function setRequireTrustedContext(value) {
|
|||
opener.SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", value);
|
||||
}
|
||||
|
||||
function fullScreenElement() {
|
||||
return document.getElementById('full-screen-element');
|
||||
}
|
||||
|
||||
function fullScreenChange(event) {
|
||||
switch (fullScreenChangeCount) {
|
||||
case 0: {
|
||||
ok(document.mozFullScreen, "Should be in full-screen mode (first time)");
|
||||
is(event.target, document.body, "Event target should be full-screen element");
|
||||
is(document.mozFullScreenElement, document.body,
|
||||
"Full-screen element should be body element.");
|
||||
document.mozCancelFullScreen();
|
||||
is(event.target, fullScreenElement(), "Event target should be full-screen element");
|
||||
is(document.mozFullScreenElement, fullScreenElement(),
|
||||
"Full-screen element should be div element.");
|
||||
ok(document.mozFullScreenElement.mozMatchesSelector(":-moz-full-screen"),
|
||||
"FSE should match :-moz-full-screen");
|
||||
var fse = fullScreenElement();
|
||||
fse.parentNode.removeChild(fse);
|
||||
is(document.mozFullScreenElement, null,
|
||||
"Full-screen element should be null after removing.");
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode when we remove full-screen element");
|
||||
document.body.appendChild(fse);
|
||||
ok(!document.mozFullScreen, "Should not return to full-screen mode when re-adding former FSE");
|
||||
is(document.mozFullScreenElement, null,
|
||||
"Full-screen element should still be null after re-adding former FSE.");
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode (first time)");
|
||||
is(event.target, document.body, "Event target should be full-screen element");
|
||||
is(event.target, document, "Event target should be document when we exit via removing from doc");
|
||||
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
|
||||
iframe = document.createElement("iframe");
|
||||
iframe.mozAllowFullScreen = true;
|
||||
|
@ -78,55 +94,71 @@ function fullScreenChange(event) {
|
|||
"Event target should be full-screen element container");
|
||||
is(document.mozFullScreenElement, iframe,
|
||||
"Full-screen element should be iframe element.");
|
||||
document.mozCancelFullScreen();
|
||||
var fse = fullScreenElement();
|
||||
fse.mozRequestFullScreen();
|
||||
ok(document.mozFullScreen, "Should still be full-screen mode after re-requesting.");
|
||||
is(document.mozFullScreenElement, fse, "Full-screen element should have switched to requestee.");
|
||||
var _innerFrame = iframe.contentDocument.getElementById("inner-frame");
|
||||
_innerFrame.contentDocument.body.appendChild(fse);
|
||||
ok(!document.mozFullScreen, "Should exit full-screen after transplanting FSE");
|
||||
is(document.mozFullScreenElement, null, "Full-screen element transplanted, should be null.");
|
||||
is(iframe.contentDocument.mozFullScreenElement, null, "Full-screen element in outer frame should be null.");
|
||||
is(_innerFrame.contentDocument.mozFullScreenElement, null, "Full-screen element in inner frame should be null.");
|
||||
ok(!iframe.contentDocument.mozFullScreen, "Outer frame should not acquire full-screen status.");
|
||||
ok(!_innerFrame.contentDocument.mozFullScreen, "Inner frame should not acquire full-screen status.");
|
||||
|
||||
document.body.appendChild(fse);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (second time)");
|
||||
is(event.target, iframe,
|
||||
is(event.target, document,
|
||||
"Event target should be full-screen element container");
|
||||
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
|
||||
document.body.removeChild(iframe);
|
||||
iframe = null;
|
||||
outOfDocElement = document.createElement("div");
|
||||
outOfDocElement.mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Requests for full-screen from not-in-doc elements should fail.");
|
||||
|
||||
container = document.createElement("div");
|
||||
inDocElement = document.createElement("div");
|
||||
container.appendChild(inDocElement);
|
||||
fullScreenElement().appendChild(container);
|
||||
|
||||
inDocElement.mozRequestFullScreen();
|
||||
ok(document.mozFullScreen, "Should grant request to return to full-screen mode (third time)");
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
ok(document.mozFullScreen, "Should be back in full-screen mode (third time)");
|
||||
is(event.target, document, "Event target should be document");
|
||||
is(document.mozFullScreenElement, null,
|
||||
"Should not have a full-screen element when element not in document requests full-screen.");
|
||||
|
||||
// Set another element to be the full-screen element. It should immediately
|
||||
// become the current full-screen element.
|
||||
inDocElement = document.createElement("div");
|
||||
document.body.appendChild(inDocElement);
|
||||
inDocElement.mozRequestFullScreen();
|
||||
|
||||
ok(document.mozFullScreen, "Should remain in full-screen mode (third and a half time)");
|
||||
ok(document.mozFullScreen, "Should still be in full-screen mode (third time)");
|
||||
is(event.target, inDocElement, "Event target should be inDocElement");
|
||||
is(document.mozFullScreenElement, inDocElement,
|
||||
"Full-screen element should be in doc again.");
|
||||
|
||||
// Remove full-screen element from document before exiting full screen.
|
||||
document.body.removeChild(inDocElement);
|
||||
ok(document.mozFullScreen,
|
||||
"Should remain in full-screen mode after removing full-screen element from document");
|
||||
"FSE should be inDocElement.");
|
||||
|
||||
var n = container;
|
||||
do {
|
||||
ok(n.mozMatchesSelector(":-moz-full-screen-ancestor"), "Ancestor " + n + " should match :-moz-full-screen-ancestor")
|
||||
n = n.parentNode;
|
||||
} while (n && n.mozMatchesSelector);
|
||||
|
||||
// Remove full-screen ancestor element from document, verify it stops being reported as current FSE.
|
||||
container.parentNode.removeChild(container);
|
||||
ok(!document.mozFullScreen,
|
||||
"Should exit full-screen mode after removing full-screen element ancestor from document");
|
||||
is(document.mozFullScreenElement, null,
|
||||
"Should not have a full-screen element again.");
|
||||
|
||||
document.mozCancelFullScreen();
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (third time)");
|
||||
setRequireTrustedContext(true);
|
||||
document.body.mozRequestFullScreen();
|
||||
fullScreenElement().mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Should still be in normal mode, because calling context isn't trusted.");
|
||||
|
||||
button = document.createElement("button");
|
||||
button.onclick = function(){document.body.mozRequestFullScreen();}
|
||||
document.body.appendChild(button);
|
||||
button.onclick = function(){fullScreenElement().mozRequestFullScreen();}
|
||||
fullScreenElement().appendChild(button);
|
||||
sendMouseClick(button);
|
||||
break;
|
||||
}
|
||||
|
@ -142,24 +174,24 @@ function fullScreenChange(event) {
|
|||
case 7: {
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode (last time).");
|
||||
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", false);
|
||||
is(document.mozFullScreenEnabled, false, "document.mozFullScreenEnabled should be false if full-screen-api.enabled is false");
|
||||
document.body.mozRequestFullScreen();
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", false);
|
||||
is(document.mozFullScreenEnabled, false, "document.mozFullScreenEnabled should be false if full-screen-api.enabled is false");
|
||||
fullScreenElement().mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Should still be in normal mode, because pref is not enabled.");
|
||||
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
is(document.mozFullScreenEnabled, true, "document.mozFullScreenEnabled should be true if full-screen-api.enabled is true");
|
||||
|
||||
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
is(document.mozFullScreenEnabled, true, "document.mozFullScreenEnabled should be true if full-screen-api.enabled is true");
|
||||
|
||||
iframe = document.createElement("iframe");
|
||||
document.body.appendChild(iframe);
|
||||
fullScreenElement().appendChild(iframe);
|
||||
iframe.src = iframeContents;
|
||||
ok(!document.mozFullScreen, "Should still be in normal mode, because iframe did not have mozallowfullscreen attribute.");
|
||||
document.body.removeChild(iframe);
|
||||
iframe = null;
|
||||
fullScreenElement().removeChild(iframe);
|
||||
iframe = null;
|
||||
|
||||
// Set timeout for calling finish(), so that any pending "mozfullscreenchange" events
|
||||
// would have a chance to fire.
|
||||
setTimeout(function(){opener.apiTestFinished();}, 0);
|
||||
setTimeout(function(){opener.nextTest();}, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -173,5 +205,6 @@ document.addEventListener("mozfullscreenchange", fullScreenChange, false);
|
|||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="full-screen-element"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=545812
|
||||
|
||||
Test DOM full-screen API.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="run();">
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, msg);
|
||||
}
|
||||
|
||||
/*
|
||||
<html>
|
||||
<body onload='document.body.mozRequestFullScreen();'>
|
||||
</body>
|
||||
</html>
|
||||
*/
|
||||
var requestFullScreenContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D'document.body.mozRequestFullScreen()%3B'>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>";
|
||||
|
||||
|
||||
var gotFullScreenChange = false;
|
||||
|
||||
function run() {
|
||||
document.addEventListener("mozfullscreenchange",
|
||||
function() {
|
||||
ok(false, "Should never receive a mozfullscreenchange event in the main window.");
|
||||
gotFullScreenChange = true;
|
||||
},
|
||||
false);
|
||||
|
||||
// Request full-screen from a non trusted context (this script isn't a user
|
||||
// generated event!).
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", true);
|
||||
document.body.mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Should not grant request in non-truested context");
|
||||
|
||||
// Test requesting full-screen mode in a long-running user-generated event handler.
|
||||
// The request in the key handler should not be granted.
|
||||
window.addEventListener("keypress", keyHandler, false);
|
||||
synthesizeKey("VK_A", {});
|
||||
}
|
||||
|
||||
function keyHandler(event) {
|
||||
window.removeEventListener("keypress", keyHandler, false);
|
||||
|
||||
// Busy loop until 2s has passed. We should then be past the 1 second threshold, and so
|
||||
// our request for full-screen mode should be rejected.
|
||||
var end = (new Date()).getTime() + 2000;
|
||||
while ((new Date()).getTime() < end) {
|
||||
; // Wait...
|
||||
}
|
||||
document.body.mozRequestFullScreen();
|
||||
ok(!document.mozFullScreen, "Should not grant request in long-running event handler.");
|
||||
|
||||
// Disable the requirement for trusted contexts only, so the tests are easier
|
||||
// to write.
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
||||
|
||||
// Create an iframe without a mozallowfullscreen sttribute, whose contents requests
|
||||
// full-screen. The request should be denied.
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = requestFullScreenContents;
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
setTimeout(
|
||||
function() {
|
||||
ok(!gotFullScreenChange, "Should not ever grant a fullscreen request in this doc.");
|
||||
opener.nextTest();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="full-screen-element"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -119,7 +119,7 @@ function macFullScreenChange(event) {
|
|||
}
|
||||
case 1: {
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode after calling document.mozCancelFullScreen().");
|
||||
opener.pluginTestFinished();
|
||||
opener.nextTest();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -164,7 +164,7 @@ function fullScreenChange(event) {
|
|||
}
|
||||
case 5: {
|
||||
ok(!document.mozFullScreen, "Should have left full-screen mode after adding windowed plugin created before going full-screen to document");
|
||||
opener.pluginTestFinished();
|
||||
opener.nextTest();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -1,106 +1,68 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<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" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=545812">Mozilla Bug 545812</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
var testWindow = null;
|
||||
|
||||
/*
|
||||
<html>
|
||||
<body onload='document.body.mozRequestFullScreen();'>
|
||||
</body>
|
||||
</html>
|
||||
*/
|
||||
var requestFullScreenContents = "data:text/html;charset=utf-8,<html>%0D%0A <body onload%3D'document.body.mozRequestFullScreen()%3B'>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>";
|
||||
|
||||
var prevTrusted = false;
|
||||
var prevEnabled = false;
|
||||
|
||||
function run() {
|
||||
document.addEventListener("mozfullscreenchange",
|
||||
function(){ok(false, "Should never receive a mozfullscreenchange event in the main window.");},
|
||||
false);
|
||||
|
||||
// Ensure the full-screen api is enabled, and will be disabled on test exit.
|
||||
prevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
|
||||
// Test requesting full-screen mode in a long-running user-generated event handler.
|
||||
// The request in the key handler should not be granted.
|
||||
window.addEventListener("keypress", keyHandler, false);
|
||||
synthesizeKey("VK_A", {});
|
||||
}
|
||||
|
||||
function keyHandler(event) {
|
||||
window.removeEventListener("keypress", keyHandler, false);
|
||||
|
||||
// Busy loop until 2s has passed. We should then be past the 1 second threshold, and so
|
||||
// our request for full-screen mode should be rejected.
|
||||
var end = (new Date()).getTime() + 2000;
|
||||
while ((new Date()).getTime() < end) {
|
||||
; // Wait...
|
||||
}
|
||||
document.body.mozRequestFullScreen();
|
||||
|
||||
prevTrusted = SpecialPowers.getBoolPref("full-screen-api.allow-trusted-requests-only");
|
||||
|
||||
// Request full-screen from a non trusted context (this script isn't a user
|
||||
// generated event!). We should not receive a "mozfullscreenchange" event.
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", true);
|
||||
document.body.mozRequestFullScreen();
|
||||
|
||||
// Disable the requirement for trusted contexts only, so the tests are easier
|
||||
// to write.
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
||||
|
||||
// Load an iframe whose contents requests full-screen. This request should
|
||||
// fail, and we should never receive a "mozfullscreenchange" event, because the
|
||||
// iframe doesn't have a mozallowfullscreen attribute.
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = requestFullScreenContents;
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Run the tests which go full-screen in a new window, as mochitests normally
|
||||
// run in an iframe, which by default will not have the mozallowfullscreen
|
||||
// attribute set, so full-screen won't work.
|
||||
testWindow = window.open("file_fullscreen-api.html", "", "width=500,height=500");
|
||||
}
|
||||
|
||||
function apiTestFinished() {
|
||||
testWindow.close();
|
||||
testWindow = window.open("file_fullscreen-api-keys.html", "", "width=500,height=500");
|
||||
}
|
||||
|
||||
function keysTestFinished() {
|
||||
testWindow.close();
|
||||
testWindow = window.open("file_fullscreen-plugins.html", "", "width=500,height=500");
|
||||
}
|
||||
|
||||
function pluginTestFinished() {
|
||||
testWindow.close();
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", prevEnabled);
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", prevTrusted);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(run);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 545812</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<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" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=545812">Mozilla Bug 545812</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Tests for Bug 545812 **/
|
||||
|
||||
// Ensure the full-screen api is enabled, and will be disabled on test exit.
|
||||
var prevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
|
||||
// Disable the requirement for trusted contexts only, so the tests are easier
|
||||
// to write.
|
||||
var prevTrusted = SpecialPowers.getBoolPref("full-screen-api.allow-trusted-requests-only");
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
||||
|
||||
// Run the tests which go full-screen in new windows, as mochitests normally
|
||||
// run in an iframe, which by default will not have the mozallowfullscreen
|
||||
// attribute set, so full-screen won't work.
|
||||
var gTestWindows = [
|
||||
"file_fullscreen-denied.html",
|
||||
"file_fullscreen-api.html",
|
||||
"file_fullscreen-api-keys.html",
|
||||
"file_fullscreen-plugins.html"
|
||||
];
|
||||
|
||||
var testWindow = null;
|
||||
var gTestIndex = 0;
|
||||
|
||||
function nextTest() {
|
||||
if (testWindow) {
|
||||
testWindow.close();
|
||||
}
|
||||
if (gTestIndex < gTestWindows.length) {
|
||||
testWindow = window.open(gTestWindows[gTestIndex], "", "width=500,height=500");
|
||||
gTestIndex++;
|
||||
} else {
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", prevEnabled);
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", prevTrusted);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(nextTest);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -161,6 +161,8 @@ const PRInt32 kBackward = 1;
|
|||
|
||||
//#define DEBUG_charset
|
||||
|
||||
#define NS_USE_NEW_VIEW_SOURCE 1
|
||||
|
||||
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
||||
|
||||
PRUint32 nsHTMLDocument::gWyciwygSessionCnt = 0;
|
||||
|
@ -576,7 +578,8 @@ nsHTMLDocument::StartAutodetection(nsIDocShell *aDocShell, nsACString& aCharset,
|
|||
if (mIsRegularHTML &&
|
||||
nsHtml5Module::sEnabled &&
|
||||
aCommand &&
|
||||
!nsCRT::strcmp(aCommand, "view")) {
|
||||
(!nsCRT::strcmp(aCommand, "view") ||
|
||||
!nsCRT::strcmp(aCommand, "view-source"))) {
|
||||
return; // the HTML5 parser uses chardet directly
|
||||
}
|
||||
nsCOMPtr <nsIParserFilter> cdetflt;
|
||||
|
@ -649,7 +652,10 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
bool aReset,
|
||||
nsIContentSink* aSink)
|
||||
{
|
||||
bool loadAsHtml5 = nsHtml5Module::sEnabled;
|
||||
bool viewSource = aCommand && !nsCRT::strcmp(aCommand, "view-source") &&
|
||||
NS_USE_NEW_VIEW_SOURCE;
|
||||
bool loadAsHtml5 = nsHtml5Module::sEnabled || viewSource;
|
||||
|
||||
if (aSink) {
|
||||
loadAsHtml5 = false;
|
||||
}
|
||||
|
@ -657,8 +663,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
nsCAutoString contentType;
|
||||
aChannel->GetContentType(contentType);
|
||||
|
||||
if (contentType.Equals("application/xhtml+xml") &&
|
||||
(!aCommand || nsCRT::strcmp(aCommand, "view-source") != 0)) {
|
||||
if (contentType.Equals("application/xhtml+xml") && !viewSource) {
|
||||
// We're parsing XHTML as XML, remember that.
|
||||
|
||||
mIsRegularHTML = false;
|
||||
|
@ -672,15 +677,13 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (loadAsHtml5 &&
|
||||
!(contentType.EqualsLiteral("text/html") &&
|
||||
aCommand &&
|
||||
!nsCRT::strcmp(aCommand, "view"))) {
|
||||
if (loadAsHtml5 && !viewSource && !(contentType.EqualsLiteral("text/html") &&
|
||||
aCommand && !nsCRT::strcmp(aCommand, "view"))) {
|
||||
loadAsHtml5 = false;
|
||||
}
|
||||
|
||||
// TODO: Proper about:blank treatment is bug 543435
|
||||
if (loadAsHtml5) {
|
||||
if (loadAsHtml5 && !viewSource) {
|
||||
// mDocumentURI hasn't been set, yet, so get the URI from the channel
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aChannel->GetOriginalURI(getter_AddRefs(uri));
|
||||
|
@ -728,7 +731,9 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
if (needsParser) {
|
||||
if (loadAsHtml5) {
|
||||
mParser = nsHtml5Module::NewHtml5Parser();
|
||||
mParser->MarkAsNotScriptCreated();
|
||||
mParser->MarkAsNotScriptCreated((viewSource &&
|
||||
!contentType.EqualsLiteral("text/html")) ?
|
||||
"view-source-xml": aCommand);
|
||||
} else {
|
||||
mParser = do_CreateInstance(kCParserCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -66,6 +66,7 @@ nsSHEntry::nsSHEntry()
|
|||
, mID(gEntryID++)
|
||||
, mScrollPositionX(0)
|
||||
, mScrollPositionY(0)
|
||||
, mParent(nsnull)
|
||||
, mURIWasModified(false)
|
||||
{
|
||||
mShared = new nsSHEntryShared();
|
||||
|
@ -81,6 +82,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
|||
, mID(other.mID)
|
||||
, mScrollPositionX(0) // XXX why not copy?
|
||||
, mScrollPositionY(0) // XXX why not copy?
|
||||
, mParent(other.mParent)
|
||||
, mURIWasModified(other.mURIWasModified)
|
||||
, mStateData(other.mStateData)
|
||||
{
|
||||
|
@ -417,7 +419,7 @@ NS_IMETHODIMP
|
|||
nsSHEntry::GetParent(nsISHEntry ** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mShared->mParent;
|
||||
*aResult = mParent;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -430,7 +432,7 @@ nsSHEntry::SetParent(nsISHEntry * aParent)
|
|||
*
|
||||
* XXX this method should not be scriptable if this is the case!!
|
||||
*/
|
||||
mShared->mParent = aParent;
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ private:
|
|||
PRUint32 mID;
|
||||
PRInt32 mScrollPositionX;
|
||||
PRInt32 mScrollPositionY;
|
||||
nsISHEntry* mParent;
|
||||
nsCOMArray<nsISHEntry> mChildren;
|
||||
bool mURIWasModified;
|
||||
nsCOMPtr<nsIStructuredCloneContainer> mStateData;
|
||||
|
|
|
@ -93,7 +93,6 @@ nsSHEntryShared::Shutdown()
|
|||
|
||||
nsSHEntryShared::nsSHEntryShared()
|
||||
: mDocShellID(0)
|
||||
, mParent(nsnull)
|
||||
, mIsFrameNavigation(false)
|
||||
, mSaveLayoutState(true)
|
||||
, mSticky(true)
|
||||
|
@ -136,7 +135,6 @@ nsSHEntryShared::Duplicate(nsSHEntryShared *aEntry)
|
|||
newEntry->mDocShellID = aEntry->mDocShellID;
|
||||
newEntry->mChildShells.AppendObjects(aEntry->mChildShells);
|
||||
newEntry->mOwner = aEntry->mOwner;
|
||||
newEntry->mParent = aEntry->mParent;
|
||||
newEntry->mContentType.Assign(aEntry->mContentType);
|
||||
newEntry->mIsFrameNavigation = aEntry->mIsFrameNavigation;
|
||||
newEntry->mSaveLayoutState = aEntry->mSaveLayoutState;
|
||||
|
|
|
@ -99,7 +99,6 @@ class nsSHEntryShared : public nsIBFCacheEntry,
|
|||
PRUint64 mDocShellID;
|
||||
nsCOMArray<nsIDocShellTreeItem> mChildShells;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsISHEntry* mParent;
|
||||
nsCString mContentType;
|
||||
bool mIsFrameNavigation;
|
||||
bool mSaveLayoutState;
|
||||
|
|
|
@ -735,8 +735,6 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
|||
void readPixels([optional] in long dummy);
|
||||
[noscript] void readPixels_array(in WebGLint x, in WebGLint y, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
[noscript] void readPixels_buf(in WebGLint x, in WebGLint y, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
|
||||
//void glReleaseShaderCompiler();
|
||||
|
||||
|
@ -755,9 +753,6 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
|||
void stencilOpSeparate(in WebGLenum face, in WebGLenum fail, in WebGLenum zfail, in WebGLenum zpass);
|
||||
|
||||
void texImage2D([optional] in long dummy);
|
||||
[noscript] void texImage2D_buf(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
[noscript] void texImage2D_array(in WebGLenum target, in WebGLint level, in WebGLenum internalformat,
|
||||
in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLint border, in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
|
@ -770,9 +765,6 @@ interface nsIDOMWebGLRenderingContext : nsISupports
|
|||
in WebGLenum format, in WebGLenum type, in nsIDOMElement element);
|
||||
|
||||
void texSubImage2D([optional] in long dummy);
|
||||
[noscript] void texSubImage2D_buf(in WebGLenum target, in WebGLint level,
|
||||
in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
[noscript] void texSubImage2D_array(in WebGLenum target, in WebGLint level,
|
||||
in WebGLint xoffset, in WebGLint yoffset, in WebGLsizei width, in WebGLsizei height,
|
||||
in WebGLenum format, in WebGLenum type, in WebGLJSObjectPtr pixels);
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is HTML parser error reporting code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Henri Sivonen <hsivonen@iki.fi>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# The bulk of the messages in this file are derived from
|
||||
# http://hg.mozilla.org/projects/htmlparser/file/1f633cef7de7/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
|
||||
# which is available under the MIT license.
|
||||
|
||||
# Tokenizer errors
|
||||
errGarbageAfterLtSlash=Garbage after \u201C</\u201D.
|
||||
errLtSlashGt=Saw \u201C</>\u201D. Probable causes: Unescaped \u201C<\u201D (escape as \u201C<\u201D) or mistyped end tag.
|
||||
errCharRefLacksSemicolon=Character reference was not terminated by a semicolon.
|
||||
errNoDigitsInNCR=No digits in numeric character reference.
|
||||
errGtInSystemId=\u201C>\u201D in system identifier.
|
||||
errGtInPublicId=\u201C>\u201D in public identifier.
|
||||
errNamelessDoctype=Nameless doctype.
|
||||
errConsecutiveHyphens=Consecutive hyphens did not terminate a comment. \u201C--\u201D is not permitted inside a comment, but e.g. \u201C- -\u201D is.
|
||||
errPrematureEndOfComment=Premature end of comment. Use \u201C-->\u201D to end a comment properly.
|
||||
errBogusComment=Bogus comment.
|
||||
errUnquotedAttributeLt=\u201C<\u201D in an unquoted attribute value. Probable cause: Missing \u201C>\u201D immediately before.
|
||||
errUnquotedAttributeGrave=\u201C`\u201D in an unquoted attribute value. Probable cause: Using the wrong character as a quote.
|
||||
errUnquotedAttributeQuote=Quote in an unquoted attribute value. Probable causes: Attributes running together or a URL query string in an unquoted attribute value.
|
||||
errUnquotedAttributeEquals=\u201C=\u201D in an unquoted attribute value. Probable causes: Attributes running together or a URL query string in an unquoted attribute value.
|
||||
errSlashNotFollowedByGt=A slash was not immediate followed by \u201C>\u201D.
|
||||
errNoSpaceBetweenAttributes=No space between attributes.
|
||||
errUnquotedAttributeStartLt=\u201C<\u201D at the start of an unquoted attribute value. Probable cause: Missing \u201C>\u201D immediately before
|
||||
errUnquotedAttributeStartGrave=\u201C`\u201D at the start of an unquoted attribute value. Probable cause: Using the wrong character as a quote.
|
||||
errUnquotedAttributeStartEquals=\u201C=\u201D at the start of an unquoted attribute value. Probable cause: Stray duplicate equals sign.
|
||||
errAttributeValueMissing=Attribute value missing.
|
||||
errBadCharBeforeAttributeNameLt=Saw \u201C<\u201D when expecting an attribute name. Probable cause: Missing \u201C>\u201D immediately before.
|
||||
errEqualsSignBeforeAttributeName=Saw \u201C=\u201D when expecting an attribute name. Probable cause: Attribute name missing.
|
||||
errBadCharAfterLt=Bad character after \u201C<\u201D. Probable cause: Unescaped \u201C<\u201D. Try escaping it as \u201C<\u201D.
|
||||
errLtGt=Saw \u201C<>\u201D. Probable causes: Unescaped \u201C<\u201D (escape as \u201C<\u201D) or mistyped start tag.
|
||||
errProcessingInstruction=Saw \u201C<?\u201D. Probable cause: Attempt to use an XML processing instruction in HTML. (XML processing instructions are not supported in HTML.)
|
||||
errUnescapedAmpersandInterpretedAsCharacterReference=The string following \u201C&\u201D was interpreted as a character reference. (\u201C&\u201D probably should have been escaped as \u201C&\u201D.)
|
||||
errNotSemicolonTerminated=Named character reference was not terminated by a semicolon. (Or \u201C&\u201D should have been escaped as \u201C&\u201D.)
|
||||
errNoNamedCharacterMatch=\u201C&\u201D did not start a character reference. (\u201C&\u201D probably should have been escaped as \u201C&\u201D.)
|
||||
errQuoteBeforeAttributeName=Saw a quote when expecting an attribute name. Probable cause: \u201C=\u201D missing immediately before.
|
||||
errLtInAttributeName=\u201C<\u201D in attribute name. Probable cause: \u201C>\u201D missing immediately before.
|
||||
errQuoteInAttributeName=Quote in attribute name. Probable cause: Matching quote missing somewhere earlier.
|
||||
errExpectedPublicId=Expected a public identifier but the doctype ended.
|
||||
errBogusDoctype=Bogus doctype.
|
||||
maybeErrAttributesOnEndTag=End tag had attributes.
|
||||
maybeErrSlashInEndTag=Stray \u201C/\u201D at the end of an end tag.
|
||||
errNcrNonCharacter=Character reference expands to a non-character.
|
||||
errAstralNonCharacter=Character reference expands to an astral non-character.
|
||||
errNcrSurrogate=Character reference expands to a surrogate.
|
||||
errNcrControlChar=Character reference expands to a control character.
|
||||
errNcrCr=A numeric character reference expanded to carriage return.
|
||||
errNcrInC1Range=A numeric character reference expanded to the C1 controls range.
|
||||
errEofInPublicId=End of file inside public identifier.
|
||||
errEofInComment=End of file inside comment.
|
||||
errEofInDoctype=End of file inside doctype.
|
||||
errEofInAttributeValue=End of file reached when inside an attribute value. Ignoring tag.
|
||||
errEofInAttributeName=End of file occurred in an attribute name. Ignoring tag.
|
||||
errEofWithoutGt=Saw end of file without the previous tag ending with \u201C>\u201D. Ignoring tag.
|
||||
errEofInTagName=End of file seen when looking for tag name. Ignoring tag.
|
||||
errEofInEndTag=End of file inside end tag. Ignoring tag.
|
||||
errEofAfterLt=End of file after \u201C<\u201D.
|
||||
errNcrOutOfRange=Character reference outside the permissible Unicode range.
|
||||
errNcrUnassigned=Character reference expands to a permanently unassigned code point.
|
||||
errDuplicateAttribute=Duplicate attribute.
|
||||
errEofInSystemId=End of file inside system identifier.
|
||||
errExpectedSystemId=Expected a system identifier but the doctype ended.
|
||||
errMissingSpaceBeforeDoctypeName=Missing space before doctype name.
|
||||
errHyphenHyphenBang=\u201C--!\u201D found in comment.
|
||||
errNcrControlChar=Character reference expands to a control character.
|
||||
errNcrZero=Character reference expands to zero.
|
||||
errNoSpaceBetweenDoctypeSystemKeywordAndQuote=No space between the doctype \u201CSYSTEM\u201D keyword and the quote.
|
||||
errNoSpaceBetweenPublicAndSystemIds=No space between the doctype public and system identifiers.
|
||||
errNoSpaceBetweenDoctypePublicKeywordAndQuote=No space between the doctype \u201CPUBLIC\u201D keyword and the quote.
|
||||
|
||||
# Tree builder errors
|
||||
errStrayStartTag=Stray end tag \u201C%1$S\u201D.
|
||||
errStrayEndTag=Stray end tag \u201C%1$S\u201D.
|
||||
errUnclosedElements=End tag \u201C%1$S\u201D seen, but there were open elements.
|
||||
errUnclosedElementsImplied=End tag \u201C%1$S\u201D implied, but there were open elements.
|
||||
errUnclosedElementsCell=A table cell was implicitly closed, but there were open elements.
|
||||
errStrayDoctype=Stray doctype.
|
||||
errAlmostStandardsDoctype=Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.
|
||||
errQuirkyDoctype=Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.
|
||||
errNonSpaceInTrailer=Non-space character in page trailer.
|
||||
errNonSpaceAfterFrameset=Non-space after \u201Cframeset\u201D.
|
||||
errNonSpaceInFrameset=Non-space in \u201Cframeset\u201D.
|
||||
errNonSpaceAfterBody=Non-space character after body.
|
||||
errNonSpaceInColgroupInFragment=Non-space in \u201Ccolgroup\u201D when parsing fragment.
|
||||
errNonSpaceInNoscriptInHead=Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D.
|
||||
errFooBetweenHeadAndBody=\u201C%1$S\u201D element between \u201Chead\u201D and \u201Cbody\u201D.
|
||||
errStartTagWithoutDoctype=Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.
|
||||
errNoSelectInTableScope=No \u201Cselect\u201D in table scope.
|
||||
errStartSelectWhereEndSelectExpected=\u201Cselect\u201D start tag where end tag expected.
|
||||
errStartTagWithSelectOpen=\u201C%1$S\u201D start tag with \u201Cselect\u201D open.
|
||||
errBadStartTagInHead=Bad start tag in \u201C%1$S\u201D in \u201Chead\u201D.
|
||||
errImage=Saw a start tag \u201Cimage\u201D.
|
||||
errIsindex=\u201Cisindex\u201D seen.
|
||||
errFooSeenWhenFooOpen=An \u201C%1$S\u201D start tag seen but an element of the same type was already open.
|
||||
errHeadingWhenHeadingOpen=Heading cannot be a child of another heading.
|
||||
errFramesetStart=\u201Cframeset\u201D start tag seen.
|
||||
errNoCellToClose=No cell to close.
|
||||
errStartTagInTable=Start tag \u201C%1$S\u201D seen in \u201Ctable\u201D.
|
||||
errFormWhenFormOpen=Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.
|
||||
errTableSeenWhileTableOpen=Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.
|
||||
errStartTagInTableBody=\u201C%1$S\u201D start tag in table body.
|
||||
errEndTagSeenWithoutDoctype=End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.
|
||||
errEndTagAfterBody=Saw an end tag after \u201Cbody\u201D had been closed.
|
||||
errEndTagSeenWithSelectOpen=\u201C%1$S\u201D end tag with \u201Cselect\u201D open.
|
||||
errGarbageInColgroup=Garbage in \u201Ccolgroup\u201D fragment.
|
||||
errEndTagBr=End tag \u201Cbr\u201D.
|
||||
errNoElementToCloseButEndTagSeen=No \u201C%1$S\u201D element in scope but a \u201C%1$S\u201D end tag seen.
|
||||
errHtmlStartTagInForeignContext=HTML start tag \u201C%1$S\u201D in a foreign namespace context.
|
||||
errTableClosedWhileCaptionOpen=\u201Ctable\u201D closed but \u201Ccaption\u201D was still open.
|
||||
errNoTableRowToClose=No table row to close.
|
||||
errNonSpaceInTable=Misplaced non-space characters insided a table.
|
||||
errUnclosedChildrenInRuby=Unclosed children in \u201Cruby\u201D.
|
||||
errStartTagSeenWithoutRuby=Start tag \u201C%1$S\u201D seen without a \u201Cruby\u201D element being open.
|
||||
errSelfClosing=Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
|
||||
errNoCheckUnclosedElementsOnStack=Unclosed elements on stack.
|
||||
errEndTagDidNotMatchCurrentOpenElement=End tag \u201C%1$S\u201D did not match the name of the current open element (\u201C%2$S\u201D).
|
||||
errEndTagViolatesNestingRules=End tag \u201C%1$S\u201D violates nesting rules.
|
|
@ -18,6 +18,7 @@
|
|||
locale/@AB_CD@/global/dom/dom.properties (%chrome/dom/dom.properties)
|
||||
locale/@AB_CD@/global/svg/svg.properties (%chrome/svg/svg.properties)
|
||||
locale/@AB_CD@/global/layout/MediaDocument.properties (%chrome/layout/MediaDocument.properties)
|
||||
locale/@AB_CD@/global/layout/htmlparser.properties (%chrome/layout/htmlparser.properties)
|
||||
locale/@AB_CD@/global/layout/xmlparser.properties (%chrome/layout/xmlparser.properties)
|
||||
locale/@AB_CD@/global/layout/HtmlForm.properties (%chrome/layout/HtmlForm.properties)
|
||||
locale/@AB_CD@/global/security/caps.properties (%chrome/security/caps.properties)
|
||||
|
|
|
@ -45,6 +45,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
test_dom_fullscreen_warning.xul \
|
||||
dom_fullscreen_warning.xul \
|
||||
test_fullscreen.xul \
|
||||
fullscreen.xul \
|
||||
test_fullscreen_preventdefault.xul \
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
Test that "MozShowFullScreenWarning" is dispatched to chrome on restricted keypress.
|
||||
-->
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="start();">
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
// List of key codes, and whether they should cause a warning in full-screen mode.
|
||||
var keyList = [
|
||||
// Allowed: DOM_VK_CANCEL to DOM_VK_CAPS_LOCK, inclusive
|
||||
{ code: "VK_CANCEL", warn: false},
|
||||
{ code: "VK_HELP", warn: false},
|
||||
{ code: "VK_BACK_SPACE", warn: false},
|
||||
{ code: "VK_TAB", warn: false},
|
||||
{ code: "VK_CLEAR", warn: false},
|
||||
{ code: "VK_RETURN", warn: false},
|
||||
{ code: "VK_ENTER", warn: false},
|
||||
{ code: "VK_SHIFT", warn: false},
|
||||
{ code: "VK_CONTROL", warn: false},
|
||||
{ code: "VK_ALT", warn: false},
|
||||
{ code: "VK_PAUSE", warn: false},
|
||||
{ code: "VK_CAPS_LOCK", warn: false},
|
||||
|
||||
{ code: "VK_KANA", warn: true},
|
||||
{ code: "VK_HANGUL", warn: true},
|
||||
{ code: "VK_JUNJA", warn: true},
|
||||
{ code: "VK_FINAL", warn: true},
|
||||
{ code: "VK_HANJA", warn: true},
|
||||
{ code: "VK_KANJI", warn: true},
|
||||
{ code: "VK_ESCAPE", warn: false, exit: true},
|
||||
{ code: "VK_CONVERT", warn: true},
|
||||
{ code: "VK_NONCONVERT", warn: true},
|
||||
{ code: "VK_ACCEPT", warn: true},
|
||||
{ code: "VK_MODECHANGE", warn: true},
|
||||
|
||||
// Allowed: DOM_VK_SPACE to DOM_VK_DELETE, inclusive
|
||||
{ code: "VK_SPACE", warn: false},
|
||||
{ code: "VK_PAGE_UP", warn: false},
|
||||
{ code: "VK_PAGE_DOWN", warn: false},
|
||||
{ code: "VK_END", warn: false},
|
||||
{ code: "VK_HOME", warn: false},
|
||||
{ code: "VK_LEFT", warn: false},
|
||||
{ code: "VK_UP", warn: false},
|
||||
{ code: "VK_RIGHT", warn: false},
|
||||
{ code: "VK_DOWN", warn: false},
|
||||
{ code: "VK_SELECT", warn: false},
|
||||
{ code: "VK_PRINT", warn: false},
|
||||
{ code: "VK_EXECUTE", warn: false},
|
||||
{ code: "VK_PRINTSCREEN", warn: false},
|
||||
{ code: "VK_INSERT", warn: false},
|
||||
{ code: "VK_DELETE", warn: false},
|
||||
|
||||
{ code: "VK_0", warn: true},
|
||||
{ code: "VK_1", warn: true},
|
||||
{ code: "VK_2", warn: true},
|
||||
{ code: "VK_3", warn: true},
|
||||
{ code: "VK_4", warn: true},
|
||||
{ code: "VK_5", warn: true},
|
||||
{ code: "VK_6", warn: true},
|
||||
{ code: "VK_7", warn: true},
|
||||
{ code: "VK_8", warn: true},
|
||||
{ code: "VK_9", warn: true},
|
||||
|
||||
// Allowed: DOM_VK_SPACE to DOM_VK_DELETE, inclusive
|
||||
{ code: "VK_SEMICOLON", warn: false},
|
||||
{ code: "VK_EQUALS", warn: false},
|
||||
|
||||
{ code: "VK_A", warn: true},
|
||||
{ code: "VK_B", warn: true},
|
||||
{ code: "VK_C", warn: true},
|
||||
{ code: "VK_D", warn: true},
|
||||
{ code: "VK_E", warn: true},
|
||||
{ code: "VK_F", warn: true},
|
||||
{ code: "VK_G", warn: true},
|
||||
{ code: "VK_H", warn: true},
|
||||
{ code: "VK_I", warn: true},
|
||||
{ code: "VK_J", warn: true},
|
||||
{ code: "VK_K", warn: true},
|
||||
{ code: "VK_L", warn: true},
|
||||
{ code: "VK_M", warn: true},
|
||||
{ code: "VK_N", warn: true},
|
||||
{ code: "VK_O", warn: true},
|
||||
{ code: "VK_P", warn: true},
|
||||
{ code: "VK_Q", warn: true},
|
||||
{ code: "VK_R", warn: true},
|
||||
{ code: "VK_S", warn: true},
|
||||
{ code: "VK_T", warn: true},
|
||||
{ code: "VK_U", warn: true},
|
||||
{ code: "VK_V", warn: true},
|
||||
{ code: "VK_W", warn: true},
|
||||
{ code: "VK_X", warn: true},
|
||||
{ code: "VK_Y", warn: true},
|
||||
{ code: "VK_Z", warn: true},
|
||||
{ code: "VK_CONTEXT_MENU", warn: true},
|
||||
{ code: "VK_SLEEP", warn: true},
|
||||
{ code: "VK_NUMPAD0", warn: true},
|
||||
{ code: "VK_NUMPAD1", warn: true},
|
||||
{ code: "VK_NUMPAD2", warn: true},
|
||||
{ code: "VK_NUMPAD3", warn: true},
|
||||
{ code: "VK_NUMPAD4", warn: true},
|
||||
{ code: "VK_NUMPAD5", warn: true},
|
||||
{ code: "VK_NUMPAD6", warn: true},
|
||||
{ code: "VK_NUMPAD7", warn: true},
|
||||
{ code: "VK_NUMPAD8", warn: true},
|
||||
{ code: "VK_NUMPAD9", warn: true},
|
||||
|
||||
// Allowed: DOM_VK_MULTIPLY to DOM_VK_META, inclusive
|
||||
{ code: "VK_MULTIPLY", warn: false},
|
||||
{ code: "VK_ADD", warn: false},
|
||||
{ code: "VK_SEPARATOR", warn: false},
|
||||
{ code: "VK_SUBTRACT", warn: false},
|
||||
{ code: "VK_DECIMAL", warn: false},
|
||||
{ code: "VK_DIVIDE", warn: false},
|
||||
{ code: "VK_F1", warn: false},
|
||||
{ code: "VK_F2", warn: false},
|
||||
{ code: "VK_F3", warn: false},
|
||||
{ code: "VK_F4", warn: false},
|
||||
{ code: "VK_F5", warn: false},
|
||||
{ code: "VK_F6", warn: false},
|
||||
{ code: "VK_F7", warn: false},
|
||||
{ code: "VK_F8", warn: false},
|
||||
{ code: "VK_F9", warn: false},
|
||||
{ code: "VK_F10", warn: false},
|
||||
{ code: "VK_F11", warn: false}, // F11 exit full-screen handler is in browser.js, so won't cause exit here.
|
||||
{ code: "VK_F12", warn: false},
|
||||
{ code: "VK_F13", warn: false},
|
||||
{ code: "VK_F14", warn: false},
|
||||
{ code: "VK_F15", warn: false},
|
||||
{ code: "VK_F16", warn: false},
|
||||
{ code: "VK_F17", warn: false},
|
||||
{ code: "VK_F18", warn: false},
|
||||
{ code: "VK_F19", warn: false},
|
||||
{ code: "VK_F20", warn: false},
|
||||
{ code: "VK_F21", warn: false},
|
||||
{ code: "VK_F22", warn: false},
|
||||
{ code: "VK_F23", warn: false},
|
||||
{ code: "VK_F24", warn: false},
|
||||
{ code: "VK_NUM_LOCK", warn: false},
|
||||
{ code: "VK_SCROLL_LOCK", warn: false},
|
||||
{ code: "VK_COMMA", warn: false},
|
||||
{ code: "VK_PERIOD", warn: false},
|
||||
{ code: "VK_SLASH", warn: false},
|
||||
{ code: "VK_BACK_QUOTE", warn: false},
|
||||
{ code: "VK_OPEN_BRACKET", warn: false},
|
||||
{ code: "VK_BACK_SLASH", warn: false},
|
||||
{ code: "VK_CLOSE_BRACKET", warn: false},
|
||||
{ code: "VK_QUOTE", warn: false},
|
||||
{ code: "VK_META", warn: false},
|
||||
];
|
||||
|
||||
function ok(condition, msg) {
|
||||
window.opener.wrappedJSObject.ok(condition, msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
window.opener.wrappedJSObject.is(a, b, msg);
|
||||
}
|
||||
|
||||
var gKeyTestIndex = 0;
|
||||
var gKeyName;
|
||||
var gKeyCode;
|
||||
var gWarningEventReceived = false;
|
||||
var gExpectWarning;
|
||||
var gExpectExit;
|
||||
var gBrowser;
|
||||
|
||||
function checkKeyEffect() {
|
||||
is(gBrowser.contentDocument.mozFullScreen, !gExpectExit,
|
||||
(gExpectExit ? ("Should exit full-screen for " + gKeyName + " press ")
|
||||
: ("Should remain in full-screen for " + gKeyName + " press")));
|
||||
is(gWarningEventReceived, gExpectWarning, "Should " + (gExpectWarning ? "" : "not ") +
|
||||
"receive MozShowFullScreenWarning for " + gKeyName + " press");
|
||||
if (gKeyTestIndex < keyList.length) {
|
||||
setTimeout(startNextTest, 0);
|
||||
} else {
|
||||
gBrowser.contentDocument.mozCancelFullScreen();
|
||||
window.opener.wrappedJSObject.done();
|
||||
}
|
||||
}
|
||||
|
||||
function testTrustedKeyEvents() {
|
||||
gBrowser.contentWindow.focus();
|
||||
gWarningEventReceived = false;
|
||||
synthesizeKey(gKeyName, {});
|
||||
setTimeout(checkKeyEffect, 0);
|
||||
}
|
||||
|
||||
function testScriptInitiatedKeyEvents() {
|
||||
// Script initiated untrusted key events should not cause the warning to show.
|
||||
gBrowser.contentWindow.focus();
|
||||
gWarningEventReceived = false;
|
||||
var evt = gBrowser.contentDocument.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keydown", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
gBrowser.contentDocument.body.dispatchEvent(evt);
|
||||
|
||||
evt = gBrowser.contentDocument.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keypress", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
gBrowser.contentDocument.body.dispatchEvent(evt);
|
||||
|
||||
evt = gBrowser.contentDocument.createEvent("KeyEvents");
|
||||
evt.initKeyEvent("keyup", true, true, window,
|
||||
false, false, false, false,
|
||||
gKeyCode, 0);
|
||||
gBrowser.contentDocument.body.dispatchEvent(evt);
|
||||
|
||||
setTimeout(checkScriptInitiatedEvents, 0);
|
||||
}
|
||||
|
||||
function checkScriptInitiatedEvents() {
|
||||
is(gWarningEventReceived, false, "Should not receive MozShowFullScreenWarning on synthesized key events.");
|
||||
ok(gBrowser.contentDocument.mozFullScreen,
|
||||
"Should remain in full-screen mode for script initiated key events for " + gKeyName);
|
||||
testTrustedKeyEvents();
|
||||
}
|
||||
|
||||
function testNextKey() {
|
||||
ok(gBrowser.contentDocument.mozFullScreen, "Must be in full-screen mode");
|
||||
|
||||
gKeyName = keyList[gKeyTestIndex].code;
|
||||
gKeyCode = KeyEvent["DOM_" + gKeyName];
|
||||
gExpectWarning = keyList[gKeyTestIndex].warn;
|
||||
gExpectExit = (keyList[gKeyTestIndex].exit != undefined) ?
|
||||
keyList[gKeyTestIndex].exit : false;
|
||||
gKeyTestIndex++;
|
||||
|
||||
testScriptInitiatedKeyEvents();
|
||||
}
|
||||
|
||||
function startNextTest() {
|
||||
if (!gBrowser.contentDocument.mozFullScreen) {
|
||||
gBrowser.contentDocument.body.mozRequestFullScreen();
|
||||
}
|
||||
// mozRequestFullScreen is async...
|
||||
setTimeout(testNextKey, 0);
|
||||
}
|
||||
|
||||
function keyHandler(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
window.addEventListener("MozShowFullScreenWarning", function(){ gWarningEventReceived = true; }, true);
|
||||
|
||||
window.addEventListener("keydown", keyHandler, true);
|
||||
window.addEventListener("keyup", keyHandler, true);
|
||||
window.addEventListener("keypress", keyHandler, true);
|
||||
|
||||
function start() {
|
||||
gBrowser = document.getElementById("browser");
|
||||
gBrowser.contentDocument.body.mozRequestFullScreen();
|
||||
setTimeout(startNextTest, 0);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<browser type="content" id="browser" width="400" height="400"/>
|
||||
|
||||
</window>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
Test that "MozShowFullScreenWarning" is dispatched to chrome on restricted keypress.
|
||||
-->
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="400" height="400">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Ensure the full-screen api is enabled, and will be disabled on test exit.
|
||||
var gPrevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
|
||||
var gPrevTrusted = SpecialPowers.getBoolPref("full-screen-api.allow-trusted-requests-only");
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false);
|
||||
|
||||
|
||||
newwindow = window.open("dom_fullscreen_warning.xul", "_blank","chrome,resizable=yes,width=400,height=400");
|
||||
|
||||
function done()
|
||||
{
|
||||
newwindow.close();
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", gPrevEnabled);
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", gPrevTrusted);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
|
||||
|
||||
</window>
|
|
@ -645,6 +645,7 @@ LayerManagerOGL::FPSState::DrawFPS(GLContext* context, CopyProgram* copyprog)
|
|||
context->fEnable(LOCAL_GL_BLEND);
|
||||
context->fBlendFunc(LOCAL_GL_ONE, LOCAL_GL_SRC_COLOR);
|
||||
|
||||
context->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
context->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
|
||||
|
||||
copyprog->Activate();
|
||||
|
|
|
@ -497,6 +497,20 @@ CreateOffscreenPBufferContext(const gfxIntSize& aSize,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
// If we ask for any of these to be on/off and we get the opposite, we stop
|
||||
// creating a pbuffer and instead create an FBO.
|
||||
GLint alphaBits, depthBits, stencilBits;
|
||||
[pbFormat getValues: &alphaBits forAttribute: NSOpenGLPFAAlphaSize forVirtualScreen: 0];
|
||||
[pbFormat getValues: &depthBits forAttribute: NSOpenGLPFADepthSize forVirtualScreen: 0];
|
||||
[pbFormat getValues: &stencilBits forAttribute: NSOpenGLPFAStencilSize forVirtualScreen: 0];
|
||||
if ((alphaBits && !aFormat.alpha) || (!alphaBits && aFormat.alpha) ||
|
||||
(depthBits && !aFormat.alpha) || (!depthBits && aFormat.depth) ||
|
||||
(stencilBits && !aFormat.stencil) || (!stencilBits && aFormat.stencil))
|
||||
{
|
||||
[pbFormat release];
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NSOpenGLPixelBuffer *pb = [[NSOpenGLPixelBuffer alloc]
|
||||
initWithTextureTarget:LOCAL_GL_TEXTURE_2D
|
||||
textureInternalFormat:(aFormat.alpha ? LOCAL_GL_RGBA : LOCAL_GL_RGB)
|
||||
|
|
|
@ -87,7 +87,7 @@ nsPlatformCharset::InitGetCharset(nsACString &oString)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult)
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -129,10 +129,8 @@ nsLanguageAtomService::GetLocaleLanguage(nsresult *aError)
|
|||
if (NS_FAILED(res))
|
||||
break;
|
||||
|
||||
nsAutoString category;
|
||||
category.AssignWithConversion(NSILOCALE_MESSAGE);
|
||||
nsAutoString loc;
|
||||
res = locale->GetCategory(category, loc);
|
||||
res = locale->GetCategory(NS_LITERAL_STRING(NSILOCALE_MESSAGE), loc);
|
||||
if (NS_FAILED(res))
|
||||
break;
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ nsLocaleService::nsLocaleService(void)
|
|||
posix_locale_category[i],
|
||||
UNI_MBS_STRING_POINTER,
|
||||
(void **)&lc_temp);
|
||||
category.AssignWithConversion(LocaleList[i]);
|
||||
category.AssignASCII(LocaleList[i]);
|
||||
nsresult result;
|
||||
if (lc_temp != nsnull)
|
||||
result = os2Converter->GetXPLocale(lc_temp, xpLocale);
|
||||
|
@ -300,7 +300,7 @@ nsLocaleService::NewLocale(const nsAString &aLocale, nsILocale **_retval)
|
|||
if (!resultLocale) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (PRInt32 i = 0; i < LocaleListLength; i++) {
|
||||
nsString category; category.AssignWithConversion(LocaleList[i]);
|
||||
NS_ConvertASCIItoUTF16 category(LocaleList[i]);
|
||||
result = resultLocale->AddCategory(category, aLocale);
|
||||
if (NS_FAILED(result)) return result;
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
|
||||
nsresult MapToCharset(nsAString& inANSICodePage, nsACString& outCharset);
|
||||
nsresult InitGetCharset(nsACString& oString);
|
||||
nsresult ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult);
|
||||
nsresult ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult);
|
||||
nsresult VerifyCharset(nsCString &aCharset);
|
||||
};
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ nsPlatformCharset::InitGetCharset(nsACString &oString)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult)
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACS
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult)
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ nsPlatformCharset::nsPlatformCharset()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult)
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult)
|
||||
{
|
||||
if (!(locale.IsEmpty())) {
|
||||
nsCAutoString platformLocaleKey;
|
||||
|
@ -84,7 +84,7 @@ nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale
|
|||
platformLocaleKey.AssignLiteral("locale.");
|
||||
platformLocaleKey.Append(OSTYPE);
|
||||
platformLocaleKey.AppendLiteral(".");
|
||||
platformLocaleKey.AppendWithConversion(locale);
|
||||
platformLocaleKey.Append(locale);
|
||||
|
||||
nsresult res = nsUConvPropertySearch::SearchPropertyValue(kUnixCharsets,
|
||||
ArrayLength(kUnixCharsets), platformLocaleKey, oResult);
|
||||
|
@ -93,7 +93,7 @@ nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale
|
|||
}
|
||||
nsCAutoString localeKey;
|
||||
localeKey.AssignLiteral("locale.all.");
|
||||
localeKey.AppendWithConversion(locale);
|
||||
localeKey.Append(locale);
|
||||
res = nsUConvPropertySearch::SearchPropertyValue(kUnixCharsets,
|
||||
ArrayLength(kUnixCharsets), localeKey, oResult);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
|
@ -160,7 +160,7 @@ nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACS
|
|||
// convert from locale to charset
|
||||
// using the deprecated locale to charset mapping
|
||||
//
|
||||
nsAutoString localeStr(localeName);
|
||||
NS_LossyConvertUTF16toASCII localeStr(localeName);
|
||||
nsresult res = ConvertLocaleToCharsetUsingDeprecatedConfig(localeStr, oResult);
|
||||
if (NS_SUCCEEDED(res))
|
||||
return res;
|
||||
|
@ -201,8 +201,8 @@ nsPlatformCharset::InitGetCharset(nsACString &oString)
|
|||
// try falling back on a deprecated (locale based) name
|
||||
//
|
||||
char* locale = setlocale(LC_CTYPE, nsnull);
|
||||
nsAutoString localeStr;
|
||||
localeStr.AssignWithConversion(locale);
|
||||
nsCAutoString localeStr;
|
||||
localeStr.Assign(locale);
|
||||
res = ConvertLocaleToCharsetUsingDeprecatedConfig(localeStr, oString);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
return res; // succeeded
|
||||
|
|
|
@ -129,7 +129,7 @@ nsPlatformCharset::InitGetCharset(nsACString &oString)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsAString& locale, nsACString& oResult)
|
||||
nsPlatformCharset::ConvertLocaleToCharsetUsingDeprecatedConfig(nsACString& locale, nsACString& oResult)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ nsresult testCharsetConverterManager()
|
|||
|
||||
#define CREATE_DECODER(_charset) \
|
||||
nsIUnicodeDecoder * dec; \
|
||||
nsAutoString str;str.AssignWithConversion(_charset); \
|
||||
nsAutoString str;str.AssignASCII(_charset); \
|
||||
nsresult res = ccMan->GetUnicodeDecoder(&str,&dec); \
|
||||
if (NS_FAILED(res)) { \
|
||||
printf("ERROR at GetUnicodeDecoder() code=0x%x.\n",res); \
|
||||
|
@ -116,7 +116,7 @@ nsresult testCharsetConverterManager()
|
|||
|
||||
#define CREATE_ENCODER(_charset) \
|
||||
nsIUnicodeEncoder * enc; \
|
||||
nsAutoString str; str.AssignWithConversion(_charset); \
|
||||
nsAutoString str; str.AssignASCII(_charset); \
|
||||
nsresult res = ccMan->GetUnicodeEncoder(&str,&enc); \
|
||||
if (NS_FAILED(res)) { \
|
||||
printf("ERROR at GetUnicodeEncoder() code=0x%x.\n",res); \
|
||||
|
|
|
@ -190,7 +190,7 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
|
|||
jsdouble delta;
|
||||
now = JS_Now();
|
||||
ll_delta = now - pdata->lastCallStart;
|
||||
delta = (JSFloat64) ll_delta;
|
||||
delta = ll_delta;
|
||||
delta /= 1000.0;
|
||||
pdata->totalExecutionTime += delta;
|
||||
/* minExecutionTime starts as 0, so we need to overwrite
|
||||
|
@ -214,7 +214,7 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
|
|||
* running time as 'delta'. */
|
||||
ll_delta = now - jsdc->lastReturnTime;
|
||||
pdata->runningTime += ll_delta;
|
||||
delta = (JSFloat64) pdata->runningTime;
|
||||
delta = pdata->runningTime;
|
||||
delta /= 1000.0;
|
||||
}
|
||||
|
||||
|
|
|
@ -351,10 +351,10 @@ void ARMAssembler::dataTransferN(bool isLoad, bool isSigned, int size, RegisterI
|
|||
void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset)
|
||||
{
|
||||
if (offset >= 0) {
|
||||
if (offset <= 0xfff)
|
||||
if (offset <= 0xfff) {
|
||||
// LDR rd, [rb, +offset]
|
||||
dtr_u(isLoad, srcDst, base, offset);
|
||||
else if (offset <= 0xfffff) {
|
||||
} else if (offset <= 0xfffff) {
|
||||
// Add upper bits of offset to the base, and store the result into the temp register.
|
||||
add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | getOp2RotLSL(12));
|
||||
// Load using the lower bits of the register.
|
||||
|
@ -367,15 +367,14 @@ void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID bas
|
|||
}
|
||||
} else {
|
||||
// Negative offsets.
|
||||
offset = -offset;
|
||||
if (offset <= 0xfff)
|
||||
dtr_d(isLoad, srcDst, base, offset);
|
||||
else if (offset <= 0xfffff) {
|
||||
sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | getOp2RotLSL(12));
|
||||
dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
|
||||
if (offset >= -0xfff) {
|
||||
dtr_d(isLoad, srcDst, base, -offset);
|
||||
} else if (offset >= -0xfffff) {
|
||||
sub_r(ARMRegisters::S0, base, OP2_IMM | (-offset >> 12) | getOp2RotLSL(12));
|
||||
dtr_d(isLoad, srcDst, ARMRegisters::S0, (-offset & 0xfff));
|
||||
} else {
|
||||
moveImm(offset, ARMRegisters::S0);
|
||||
dtr_dr(isLoad, srcDst, base, ARMRegisters::S0);
|
||||
dtr_ur(isLoad, srcDst, base, ARMRegisters::S0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,26 +401,24 @@ void ARMAssembler::dataTransfer8(bool isLoad, RegisterID srcDst, RegisterID base
|
|||
dtrb_ur(isLoad, srcDst, base, ARMRegisters::S0);
|
||||
}
|
||||
} else {
|
||||
offset = -offset;
|
||||
if (offset <= 0xfff) {
|
||||
if (offset >= -0xfff) {
|
||||
if (isSigned)
|
||||
mem_imm_off(isLoad, true, 8, false, srcDst, base, offset);
|
||||
mem_imm_off(isLoad, true, 8, false, srcDst, base, -offset);
|
||||
else
|
||||
dtrb_d(isLoad, srcDst, base, offset);
|
||||
}
|
||||
else if (offset <= 0xfffff) {
|
||||
sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | getOp2RotLSL(12));
|
||||
dtrb_d(isLoad, srcDst, base, -offset);
|
||||
} else if (offset >= -0xfffff) {
|
||||
sub_r(ARMRegisters::S0, base, OP2_IMM | (-offset >> 12) | getOp2RotLSL(12));
|
||||
if (isSigned)
|
||||
mem_imm_off(isLoad, true, 8, false, srcDst, ARMRegisters::S0, (offset & 0xfff));
|
||||
mem_imm_off(isLoad, true, 8, false, srcDst, ARMRegisters::S0, (-offset & 0xfff));
|
||||
else
|
||||
dtrb_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff));
|
||||
dtrb_d(isLoad, srcDst, ARMRegisters::S0, (-offset & 0xfff));
|
||||
|
||||
} else {
|
||||
moveImm(offset, ARMRegisters::S0);
|
||||
if (isSigned)
|
||||
mem_reg_off(isLoad, true, 8, false, srcDst, base, ARMRegisters::S0);
|
||||
mem_reg_off(isLoad, true, 8, true, srcDst, base, ARMRegisters::S0);
|
||||
else
|
||||
dtrb_dr(isLoad, srcDst, base, ARMRegisters::S0);
|
||||
dtrb_ur(isLoad, srcDst, base, ARMRegisters::S0);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
for (var i = 0; i <= 0xFFFF; i++) {
|
||||
assertEq(String.fromCharCode(i).charCodeAt(0), i);
|
||||
}
|
|
@ -50,5 +50,4 @@ typedef JSIntn intN;
|
|||
typedef JSUintn uintN;
|
||||
typedef JSUword jsuword;
|
||||
typedef JSWord jsword;
|
||||
typedef float float32;
|
||||
#endif /* jscompat_h___ */
|
||||
|
|
|
@ -178,6 +178,43 @@ MarkChildren(JSTracer *trc, JSScript *script);
|
|||
void
|
||||
MarkChildren(JSTracer *trc, JSXML *xml);
|
||||
|
||||
/*
|
||||
* Use function overloading to decide which function should be called based on
|
||||
* the type of the object. The static type is used at compile time to link to
|
||||
* the corresponding Mark/IsMarked function.
|
||||
*/
|
||||
inline void
|
||||
Mark(JSTracer *trc, const js::Value &v, const char *name)
|
||||
{
|
||||
MarkValue(trc, v, name);
|
||||
}
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, JSObject *o, const char *name)
|
||||
{
|
||||
MarkObject(trc, *o, name);
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(JSContext *cx, const js::Value &v)
|
||||
{
|
||||
if (v.isMarkable())
|
||||
return !IsAboutToBeFinalized(cx, v.toGCThing());
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(JSContext *cx, JSObject *o)
|
||||
{
|
||||
return !IsAboutToBeFinalized(cx, o);
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(JSContext *cx, Cell *cell)
|
||||
{
|
||||
return !IsAboutToBeFinalized(cx, cell);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,4 @@ typedef JSInt16 int16;
|
|||
typedef JSInt8 int8;
|
||||
#endif /* AIX && HAVE_SYS_INTTYPES_H */
|
||||
|
||||
typedef JSFloat64 float64;
|
||||
|
||||
#endif /* !defined(PROTYPES_H) */
|
||||
|
|
|
@ -96,7 +96,7 @@ JS_BEGIN_EXTERN_C
|
|||
/* Scalar typedefs. */
|
||||
typedef JSInt32 jsint;
|
||||
typedef JSUint32 jsuint;
|
||||
typedef float64 jsdouble;
|
||||
typedef double jsdouble;
|
||||
typedef JSInt32 jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */
|
||||
|
||||
#ifdef WIN32
|
||||
|
|
|
@ -2938,8 +2938,8 @@ js_String(JSContext *cx, uintN argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
str_fromCharCode(JSContext *cx, uintN argc, Value *vp)
|
||||
JSBool
|
||||
js::str_fromCharCode(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
Value *argv = JS_ARGV(cx, vp);
|
||||
JS_ASSERT(argc <= StackSpace::ARGS_LENGTH_MAX);
|
||||
|
@ -2974,6 +2974,7 @@ str_fromCharCode(JSContext *cx, uintN argc, Value *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef JS_TRACER
|
||||
static JSString* FASTCALL
|
||||
String_fromCharCode(JSContext* cx, int32 i)
|
||||
|
@ -2990,7 +2991,7 @@ JS_DEFINE_TRCINFO_1(str_fromCharCode,
|
|||
(2, (static, STRING_RETRY, String_fromCharCode, CONTEXT, INT32, 1, nanojit::ACCSET_NONE)))
|
||||
|
||||
static JSFunctionSpec string_static_methods[] = {
|
||||
JS_TN("fromCharCode", str_fromCharCode, 1, 0, &str_fromCharCode_trcinfo),
|
||||
JS_TN("fromCharCode", js::str_fromCharCode, 1, 0, &str_fromCharCode_trcinfo),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result);
|
|||
extern bool
|
||||
StringEqualsAscii(JSLinearString *str, const char *asciiBytes);
|
||||
|
||||
} /* namespacejs */
|
||||
} /* namespace js */
|
||||
|
||||
extern size_t
|
||||
js_strlen(const jschar *s);
|
||||
|
@ -275,16 +275,17 @@ DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars,
|
|||
size_t charsLength, char *bytes, size_t *length,
|
||||
FlationCoding fc = NormalEncoding);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* The String.prototype.replace fast-native entry point is exported for joined
|
||||
* function optimization in js{interp,tracer}.cpp.
|
||||
*/
|
||||
namespace js {
|
||||
extern JSBool
|
||||
str_replace(JSContext *cx, uintN argc, js::Value *vp);
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
str_fromCharCode(JSContext *cx, uintN argc, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_str_toString(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
|
|
@ -340,13 +340,6 @@ JS_BEGIN_EXTERN_C
|
|||
typedef int JSIntn;
|
||||
typedef unsigned int JSUintn;
|
||||
|
||||
/************************************************************************
|
||||
** TYPES: JSFloat64
|
||||
** DESCRIPTION:
|
||||
** NSPR's floating point type is always 64 bits.
|
||||
************************************************************************/
|
||||
typedef double JSFloat64;
|
||||
|
||||
/************************************************************************
|
||||
** TYPES: JSSize
|
||||
** DESCRIPTION:
|
||||
|
|
|
@ -776,6 +776,8 @@ private:
|
|||
|
||||
enum GetCharMode { GetChar, GetCharCode };
|
||||
CompileStatus compileGetChar(FrameEntry *thisValue, FrameEntry *arg, GetCharMode mode);
|
||||
|
||||
CompileStatus compileStringFromCode(FrameEntry *arg);
|
||||
|
||||
void prepareStubCall(Uses uses);
|
||||
Call emitStubCall(void *ptr, DataLabelPtr *pinline);
|
||||
|
|
|
@ -408,6 +408,39 @@ mjit::Compiler::compileGetChar(FrameEntry *thisValue, FrameEntry *arg, GetCharMo
|
|||
return Compile_Okay;
|
||||
}
|
||||
|
||||
CompileStatus
|
||||
mjit::Compiler::compileStringFromCode(FrameEntry *arg)
|
||||
{
|
||||
/* Load Char-Code into argReg */
|
||||
RegisterID argReg;
|
||||
if (arg->isConstant()) {
|
||||
argReg = frame.allocReg();
|
||||
masm.move(Imm32(arg->getValue().toInt32()), argReg);
|
||||
} else {
|
||||
argReg = frame.copyDataIntoReg(arg);
|
||||
}
|
||||
|
||||
/* Slow path if there's no unit string for this character. */
|
||||
Jump notUnitString = masm.branch32(Assembler::AboveOrEqual, argReg,
|
||||
Imm32(StaticStrings::UNIT_STATIC_LIMIT));
|
||||
stubcc.linkExit(notUnitString, Uses(3));
|
||||
|
||||
/* Load unit string in reg. */
|
||||
masm.lshiftPtr(Imm32(sizeof(JSAtom *) == 4 ? 2 : 3), argReg);
|
||||
masm.addPtr(ImmPtr(&cx->runtime->staticStrings.unitStaticTable), argReg);
|
||||
masm.loadPtr(Address(argReg), argReg);
|
||||
|
||||
stubcc.leave();
|
||||
stubcc.masm.move(Imm32(1), Registers::ArgReg1);
|
||||
OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
|
||||
|
||||
frame.popn(3);
|
||||
frame.pushTypedPayload(JSVAL_TYPE_STRING, argReg);
|
||||
|
||||
stubcc.rejoin(Changes(1));
|
||||
return Compile_Okay;
|
||||
}
|
||||
|
||||
CompileStatus
|
||||
mjit::Compiler::compileArrayPush(FrameEntry *thisValue, FrameEntry *arg)
|
||||
{
|
||||
|
@ -872,6 +905,10 @@ mjit::Compiler::inlineNativeFunction(uint32 argc, bool callingNew)
|
|||
thisType == JSVAL_TYPE_STRING && type == JSVAL_TYPE_STRING) {
|
||||
return compileGetChar(thisValue, arg, GetChar);
|
||||
}
|
||||
if (native == js::str_fromCharCode && argType == JSVAL_TYPE_INT32 &&
|
||||
type == JSVAL_TYPE_STRING) {
|
||||
return compileStringFromCode(arg);
|
||||
}
|
||||
if (native == js::array_push &&
|
||||
thisType == JSVAL_TYPE_OBJECT && type == JSVAL_TYPE_INT32) {
|
||||
/*
|
||||
|
|
|
@ -202,6 +202,7 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include "Layers.h"
|
||||
#include "nsPLDOMEvent.h"
|
||||
|
||||
#ifdef NS_FUNCTION_TIMER
|
||||
#define NS_TIME_FUNCTION_DECLARE_DOCURL \
|
||||
|
@ -6344,17 +6345,38 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
|||
switch (aEvent->message) {
|
||||
case NS_KEY_PRESS:
|
||||
case NS_KEY_DOWN:
|
||||
case NS_KEY_UP:
|
||||
if (IsFullScreenAndRestrictedKeyEvent(mCurrentEventContent, aEvent) &&
|
||||
aEvent->message == NS_KEY_DOWN) {
|
||||
// We're in DOM full-screen mode, and a key with a restricted key
|
||||
// code has been pressed. Exit full-screen mode.
|
||||
NS_DispatchToCurrentThread(
|
||||
NS_NewRunnableMethod(mCurrentEventContent->OwnerDoc(),
|
||||
&nsIDocument::CancelFullScreen));
|
||||
case NS_KEY_UP: {
|
||||
nsIDocument *doc = mCurrentEventContent ?
|
||||
mCurrentEventContent->OwnerDoc() : nsnull;
|
||||
if (doc &&
|
||||
doc->IsFullScreenDoc() &&
|
||||
static_cast<const nsKeyEvent*>(aEvent)->keyCode == NS_VK_ESCAPE) {
|
||||
// Prevent default action on ESC key press when exiting
|
||||
// DOM full-screen mode. This prevents the browser ESC key
|
||||
// handler from stopping all loads in the document, which
|
||||
// would cause <video> loads to stop.
|
||||
aEvent->flags |= (NS_EVENT_FLAG_NO_DEFAULT |
|
||||
NS_EVENT_FLAG_ONLY_CHROME_DISPATCH);
|
||||
|
||||
if (aEvent->message == NS_KEY_UP) {
|
||||
// ESC key released while in DOM full-screen mode.
|
||||
// Exit full-screen mode.
|
||||
NS_DispatchToCurrentThread(
|
||||
NS_NewRunnableMethod(mCurrentEventContent->OwnerDoc(),
|
||||
&nsIDocument::CancelFullScreen));
|
||||
}
|
||||
} else if (IsFullScreenAndRestrictedKeyEvent(mCurrentEventContent, aEvent)) {
|
||||
// Restricted key press while in DOM full-screen mode. Dispatch
|
||||
// an event to chrome so it knows to show a warning message
|
||||
// informing the user how to exit full-screen.
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(doc, NS_LITERAL_STRING("MozShowFullScreenWarning"),
|
||||
true, true);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
// Else not full-screen mode or key code is unrestricted, fall
|
||||
// through to normal handling.
|
||||
}
|
||||
case NS_MOUSE_BUTTON_DOWN:
|
||||
case NS_MOUSE_BUTTON_UP:
|
||||
isHandlingUserInput = true;
|
||||
|
|
|
@ -144,6 +144,10 @@ CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate",
|
|||
// any containing frames.
|
||||
CSS_STATE_PSEUDO_CLASS(mozFullScreen, ":-moz-full-screen", NS_EVENT_STATE_FULL_SCREEN)
|
||||
|
||||
// Matches any element which is an ancestor of the DOM full-screen element,
|
||||
// or an ancestor of a containing frame of the full-screen element.
|
||||
CSS_STATE_PSEUDO_CLASS(mozFullScreenAncestor, ":-moz-full-screen-ancestor", NS_EVENT_STATE_FULL_SCREEN_ANCESTOR)
|
||||
|
||||
// Matches if the element is focused and should show a focus ring
|
||||
CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", NS_EVENT_STATE_FOCUSRING)
|
||||
|
||||
|
|
|
@ -241,17 +241,40 @@
|
|||
}
|
||||
|
||||
*|*:-moz-full-screen {
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
z-index:2147483647;
|
||||
background:black;
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 2147483647 !important;
|
||||
background: black;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
/* If there is a full-screen element that is not the root then
|
||||
we should hide the viewport scrollbar. */
|
||||
*|*:root:-moz-full-screen-ancestor {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
*|*:-moz-full-screen-ancestor {
|
||||
/* Ancestors of a full-screen element should not induce stacking contexts
|
||||
that would prevent the full-screen element from being on top. */
|
||||
z-index:auto !important;
|
||||
/* Ancestors of a full-screen element should not be partially transparent,
|
||||
since that would apply to the full-screen element and make the page visible
|
||||
behind it. It would also create a pseudo-stacking-context that would let content
|
||||
draw on top of the full-screen element. */
|
||||
opacity:1 !important;
|
||||
/* Ancestors of a full-screen element should not apply SVG masking, clipping, or
|
||||
filtering, since that would affect the full-screen element and create a pseudo-
|
||||
stacking context. */
|
||||
mask:none !important;
|
||||
clip:none !important;
|
||||
filter:none !important;
|
||||
}
|
||||
|
||||
/* XML parse error reporting */
|
||||
|
||||
parsererror|parsererror {
|
||||
|
|
|
@ -100,7 +100,7 @@ pre {
|
|||
color: steelblue;
|
||||
font-style: italic;
|
||||
}
|
||||
span:not(.error) {
|
||||
span:not(.error), a:not(.error) {
|
||||
unicode-bidi: embed;
|
||||
}
|
||||
.error,
|
||||
|
|
|
@ -5942,7 +5942,8 @@ MALLOC_OUT:
|
|||
* - With the 10.7 SDK, jemalloc causes the browser to hang (bug 670175).
|
||||
*/
|
||||
|
||||
osx_use_jemalloc = (default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION);
|
||||
osx_use_jemalloc = (default_zone->version == LEOPARD_MALLOC_ZONE_T_VERSION ||
|
||||
default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION);
|
||||
|
||||
/* Allow us dynamically turn off jemalloc for testing. */
|
||||
if (getenv("NO_MAC_JEMALLOC"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource1.h"
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -29,7 +29,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource1.h\0"
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
|
|
|
@ -107,6 +107,7 @@ CPPSRCS = \
|
|||
nsHtml5Speculation.cpp \
|
||||
nsHtml5SpeculativeLoad.cpp \
|
||||
nsHtml5SVGLoadDispatcher.cpp \
|
||||
nsHtml5Highlighter.cpp \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
|
|
@ -216,6 +216,10 @@ public class Tokenizer implements Locator {
|
|||
|
||||
public static final int SCRIPT_DATA_DOUBLE_ESCAPE_END = 72;
|
||||
|
||||
public static final int PROCESSING_INSTRUCTION = 73;
|
||||
|
||||
public static final int PROCESSING_INSTRUCTION_QUESTION_MARK = 74;
|
||||
|
||||
/**
|
||||
* Magic value for UTF-16 operations.
|
||||
*/
|
||||
|
@ -505,6 +509,8 @@ public class Tokenizer implements Locator {
|
|||
|
||||
private Interner interner;
|
||||
|
||||
// CPPONLY: private boolean viewingXmlSource;
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
protected LocatorImpl ampersandLocation;
|
||||
|
@ -531,7 +537,9 @@ public class Tokenizer implements Locator {
|
|||
* @param tokenHandler
|
||||
* the handler for receiving tokens
|
||||
*/
|
||||
public Tokenizer(TokenHandler tokenHandler) {
|
||||
public Tokenizer(TokenHandler tokenHandler
|
||||
// CPPONLY: , boolean viewingXmlSource
|
||||
) {
|
||||
this.tokenHandler = tokenHandler;
|
||||
this.encodingDeclarationHandler = null;
|
||||
// [NOCPP[
|
||||
|
@ -545,6 +553,7 @@ public class Tokenizer implements Locator {
|
|||
this.publicIdentifier = null;
|
||||
this.systemIdentifier = null;
|
||||
this.attributes = null;
|
||||
// CPPONLY: this.viewingXmlSource = viewingXmlSource;
|
||||
}
|
||||
|
||||
public void setInterner(Interner interner) {
|
||||
|
@ -557,6 +566,10 @@ public class Tokenizer implements Locator {
|
|||
|
||||
}
|
||||
|
||||
// CPPONLY: boolean isViewingXmlSource() {
|
||||
// CPPONLY: return viewingXmlSource;
|
||||
// CPPONLY: }
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
/**
|
||||
|
@ -1118,10 +1131,16 @@ public class Tokenizer implements Locator {
|
|||
* switched to the PCDATA state.
|
||||
*/
|
||||
maybeErrAttributesOnEndTag(attrs);
|
||||
// CPPONLY: if (!viewingXmlSource) {
|
||||
tokenHandler.endTag(tagName);
|
||||
// CPPONLY: }
|
||||
Portability.delete(attributes);
|
||||
} else {
|
||||
// CPPONLY: if (viewingXmlSource) {
|
||||
// CPPONLY: Portability.delete(attributes);
|
||||
// CPPONLY: } else {
|
||||
tokenHandler.startTag(tagName, attrs, selfClosing);
|
||||
// CPPONLY: }
|
||||
}
|
||||
tagName.release();
|
||||
tagName = null;
|
||||
|
@ -1220,6 +1239,9 @@ public class Tokenizer implements Locator {
|
|||
if (attributeName != null) {
|
||||
String val = longStrBufToString(); // Ownership transferred to
|
||||
// HtmlAttributes
|
||||
// CPPONLY: if (mViewSource) {
|
||||
// CPPONLY: mViewSource.MaybeLinkifyAttributeValue(attributeName, val);
|
||||
// CPPONLY: }
|
||||
// [NOCPP[
|
||||
if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata
|
||||
&& attributeName.isCaseFolded()) {
|
||||
|
@ -1316,8 +1338,17 @@ public class Tokenizer implements Locator {
|
|||
* meaning. (The rest of the array is garbage and should not be
|
||||
* examined.)
|
||||
*/
|
||||
// CPPONLY: if (mViewSource) {
|
||||
// CPPONLY: mViewSource.SetBuffer(buffer);
|
||||
// CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
|
||||
// CPPONLY: mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1);
|
||||
// CPPONLY: } else {
|
||||
// CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
|
||||
// CPPONLY: }
|
||||
// [NOCPP[
|
||||
pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState,
|
||||
buffer.getEnd());
|
||||
// ]NOCPP]
|
||||
if (pos == buffer.getEnd()) {
|
||||
// exiting due to end of buffer
|
||||
buffer.setStart(pos);
|
||||
|
@ -1522,6 +1553,13 @@ public class Tokenizer implements Locator {
|
|||
state = transition(state, Tokenizer.CLOSE_TAG_OPEN, reconsume, pos);
|
||||
continue stateloop;
|
||||
case '?':
|
||||
// CPPONLY: if (viewingXmlSource) {
|
||||
// CPPONLY: state = transition(state,
|
||||
// CPPONLY: Tokenizer.PROCESSING_INSTRUCTION,
|
||||
// CPPONLY: reconsume,
|
||||
// CPPONLY: pos);
|
||||
// CPPONLY: continue stateloop;
|
||||
// CPPONLY: }
|
||||
/*
|
||||
* U+003F QUESTION MARK (?) Parse error.
|
||||
*/
|
||||
|
@ -3149,6 +3187,7 @@ public class Tokenizer implements Locator {
|
|||
* second column of the named character references
|
||||
* table).
|
||||
*/
|
||||
// CPPONLY: completedNamedCharacterReference();
|
||||
@Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
|
||||
if (
|
||||
// [NOCPP[
|
||||
|
@ -5703,6 +5742,41 @@ public class Tokenizer implements Locator {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case PROCESSING_INSTRUCTION:
|
||||
processinginstructionloop: for (;;) {
|
||||
if (++pos == endPos) {
|
||||
break stateloop;
|
||||
}
|
||||
c = checkChar(buf, pos);
|
||||
switch (c) {
|
||||
case '?':
|
||||
state = transition(
|
||||
state,
|
||||
Tokenizer.PROCESSING_INSTRUCTION_QUESTION_MARK,
|
||||
reconsume, pos);
|
||||
break processinginstructionloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
case PROCESSING_INSTRUCTION_QUESTION_MARK:
|
||||
if (++pos == endPos) {
|
||||
break stateloop;
|
||||
}
|
||||
c = checkChar(buf, pos);
|
||||
switch (c) {
|
||||
case '>':
|
||||
state = transition(state, Tokenizer.DATA,
|
||||
reconsume, pos);
|
||||
continue stateloop;
|
||||
default:
|
||||
state = transition(state,
|
||||
Tokenizer.PROCESSING_INSTRUCTION,
|
||||
reconsume, pos);
|
||||
continue stateloop;
|
||||
}
|
||||
// END HOTSPOT WORKAROUND
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -31,6 +31,8 @@ HTML5_ATOM(noframes, "noframes")
|
|||
HTML5_ATOM(noscript, "noscript")
|
||||
HTML5_ATOM(plaintext, "plaintext")
|
||||
HTML5_ATOM(script, "script")
|
||||
HTML5_ATOM(svg, "svg")
|
||||
HTML5_ATOM(table, "table")
|
||||
HTML5_ATOM(caption, "caption")
|
||||
HTML5_ATOM(p, "p")
|
||||
HTML5_ATOM(address, "address")
|
||||
|
@ -42,7 +44,6 @@ HTML5_ATOM(option, "option")
|
|||
HTML5_ATOM(ruby, "ruby")
|
||||
HTML5_ATOM(select, "select")
|
||||
HTML5_ATOM(optgroup, "optgroup")
|
||||
HTML5_ATOM(table, "table")
|
||||
HTML5_ATOM(frameset, "frameset")
|
||||
HTML5_ATOM(button, "button")
|
||||
HTML5_ATOM(ul, "ul")
|
||||
|
@ -771,7 +772,6 @@ HTML5_ATOM(pre, "pre")
|
|||
HTML5_ATOM(rem, "rem")
|
||||
HTML5_ATOM(sub, "sub")
|
||||
HTML5_ATOM(sec, "sec")
|
||||
HTML5_ATOM(svg, "svg")
|
||||
HTML5_ATOM(sum, "sum")
|
||||
HTML5_ATOM(sin, "sin")
|
||||
HTML5_ATOM(sep, "sep")
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -0,0 +1,849 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is HTML5 View Source code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henri Sivonen <hsivonen@iki.fi>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHtml5Highlighter.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
#include "nsHtml5AttributeName.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// The old code had a limit of 16 tokens. 1300 is a number picked my measuring
|
||||
// the size of 16 tokens on cnn.com.
|
||||
#define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sComment[] =
|
||||
{ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sCdata[] =
|
||||
{ 'c', 'd', 'a', 't', 'a', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sEntity[] =
|
||||
{ 'e', 'n', 't', 'i', 't', 'y', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sEndTag[] =
|
||||
{ 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sStartTag[] =
|
||||
{ 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sAttributeName[] =
|
||||
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sAttributeValue[] =
|
||||
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
|
||||
'v', 'a', 'l', 'u', 'e', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sDoctype[] =
|
||||
{ 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
|
||||
|
||||
PRUnichar nsHtml5Highlighter::sPi[] =
|
||||
{ 'p', 'i', 0 };
|
||||
|
||||
nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
|
||||
: mState(NS_HTML5TOKENIZER_DATA)
|
||||
, mCStart(PR_INT32_MAX)
|
||||
, mPos(0)
|
||||
, mLineNumber(1)
|
||||
, mUnicharsInThisPre(0)
|
||||
, mInlinesOpen(0)
|
||||
, mInCharacters(false)
|
||||
, mBuffer(nsnull)
|
||||
, mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
|
||||
true))
|
||||
, mWrapLongLines(Preferences::GetBool("view_source.wrap_long_lines", true))
|
||||
, mTabSize(Preferences::GetInt("view_source.tab_size", 4))
|
||||
, mOpSink(aOpSink)
|
||||
, mCurrentRun(nsnull)
|
||||
, mAmpersand(nsnull)
|
||||
, mSlash(nsnull)
|
||||
, mHandles(new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH])
|
||||
, mHandlesUsed(0)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
nsHtml5Highlighter::~nsHtml5Highlighter()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::Start()
|
||||
{
|
||||
// Doctype
|
||||
mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
|
||||
|
||||
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
|
||||
|
||||
nsIContent** root = CreateElement(nsHtml5Atoms::html, nsnull);
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
|
||||
mStack.AppendElement(root);
|
||||
|
||||
Push(nsGkAtoms::head, nsnull);
|
||||
|
||||
Push(nsGkAtoms::title, nsnull);
|
||||
// XUL will add the "Source of: " prefix.
|
||||
AppendCharacters(mURL.get(), 0, mURL.Length());
|
||||
Pop(); // title
|
||||
|
||||
nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
|
||||
nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet"));
|
||||
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel);
|
||||
nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
|
||||
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type);
|
||||
nsString* href = new nsString(
|
||||
NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
|
||||
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href);
|
||||
Push(nsGkAtoms::link, linkAttrs);
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
|
||||
|
||||
Pop(); // link
|
||||
|
||||
Pop(); // head
|
||||
|
||||
nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
|
||||
nsString* id = new nsString(NS_LITERAL_STRING("viewsource"));
|
||||
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id);
|
||||
|
||||
if (mWrapLongLines) {
|
||||
nsString* klass = new nsString(NS_LITERAL_STRING("wrap"));
|
||||
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass);
|
||||
}
|
||||
|
||||
if (mTabSize > 0) {
|
||||
nsString* style = new nsString(NS_LITERAL_STRING("-moz-tab-size: "));
|
||||
style->AppendInt(mTabSize);
|
||||
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, style);
|
||||
}
|
||||
|
||||
Push(nsGkAtoms::body, bodyAttrs);
|
||||
|
||||
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
|
||||
nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
|
||||
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId);
|
||||
Push(nsGkAtoms::pre, preAttrs);
|
||||
|
||||
StartCharacters();
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
|
||||
{
|
||||
mPos = aPos;
|
||||
switch (mState) {
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA:
|
||||
case NS_HTML5TOKENIZER_RAWTEXT:
|
||||
case NS_HTML5TOKENIZER_RCDATA:
|
||||
case NS_HTML5TOKENIZER_DATA:
|
||||
// We can transition on < and on &. Either way, we don't yet know the
|
||||
// role of the token, so open a span without class.
|
||||
if (aState == NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE) {
|
||||
StartSpan();
|
||||
// Start another span for highlighting the ampersand
|
||||
StartSpan();
|
||||
mAmpersand = CurrentNode();
|
||||
} else {
|
||||
EndCharacters();
|
||||
StartSpan();
|
||||
mCurrentRun = CurrentNode();
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_TAG_OPEN:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_TAG_NAME:
|
||||
StartSpan(sStartTag);
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_DATA:
|
||||
FinishTag(); // DATA
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION:
|
||||
AddClass(sPi);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_TAG_NAME:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
|
||||
StartSpan(sAttributeName);
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
|
||||
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
|
||||
FlushCurrent();
|
||||
StartA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
|
||||
StartA();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
|
||||
StartSpan();
|
||||
StartSpan(); // for ampersand itself
|
||||
mAmpersand = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Impossible transition.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
EndSpanOrA(); // end the slash highlight
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
|
||||
StartSpan();
|
||||
StartSpan(); // for ampersand itself
|
||||
mAmpersand = CurrentNode();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
|
||||
StartSpan(sAttributeName);
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// most comment states are omitted, because they don't matter to
|
||||
// highlighting
|
||||
case NS_HTML5TOKENIZER_COMMENT_END:
|
||||
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
|
||||
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
|
||||
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
|
||||
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
|
||||
if (aState == NS_HTML5TOKENIZER_DATA) {
|
||||
AddClass(sComment);
|
||||
FinishTag();
|
||||
}
|
||||
break;
|
||||
// most cdata states are omitted, because they don't matter to
|
||||
// highlighting
|
||||
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
|
||||
if (aState == NS_HTML5TOKENIZER_DATA) {
|
||||
AddClass(sCdata);
|
||||
FinishTag();
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
|
||||
EndSpanOrA(); // the span for the ampersand
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_CONSUME_NCR:
|
||||
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
|
||||
break;
|
||||
default:
|
||||
// not actually a character reference
|
||||
EndSpanOrA();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
|
||||
if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
|
||||
break;
|
||||
}
|
||||
// not actually a character reference
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
|
||||
if (!aReconsume) {
|
||||
FlushCurrent();
|
||||
}
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
|
||||
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE:
|
||||
AddClass(sEntity);
|
||||
FlushCurrent();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME:
|
||||
AddClass(sEntity);
|
||||
break;
|
||||
}
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_DATA:
|
||||
FinishTag();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_TAG_NAME:
|
||||
StartSpan(sEndTag);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN:
|
||||
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
|
||||
FlushCurrent();
|
||||
StartSpan(); // don't know if it is "end-tag" yet :-(
|
||||
break;
|
||||
}
|
||||
EndSpanOrA();
|
||||
StartCharacters();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
|
||||
switch (aState) {
|
||||
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
||||
AddClass(sEndTag);
|
||||
EndSpanOrA();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
||||
AddClass(sEndTag);
|
||||
EndSpanOrA();
|
||||
StartSpan(); // for highlighting the slash
|
||||
mSlash = CurrentNode();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_DATA: // yes, as a result of emitting the token
|
||||
AddClass(sEndTag);
|
||||
FinishTag();
|
||||
break;
|
||||
default:
|
||||
FinishTag();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
|
||||
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
|
||||
break;
|
||||
}
|
||||
FinishTag();
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH:
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
|
||||
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
|
||||
if (aState == NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
|
||||
EndCharacters();
|
||||
StartSpan();
|
||||
}
|
||||
break;
|
||||
// Lots of double escape states omitted, because they don't highlight.
|
||||
// Likewise, only doctype states that can emit the doctype are of
|
||||
// interest. Otherwise, the transition out of bogus comment deals.
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
|
||||
if (aState == NS_HTML5TOKENIZER_DATA) {
|
||||
AddClass(sDoctype);
|
||||
FinishTag();
|
||||
}
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK:
|
||||
if (aState == NS_HTML5TOKENIZER_DATA) {
|
||||
FinishTag();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mState = aState;
|
||||
return aState;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::End()
|
||||
{
|
||||
switch (mState) {
|
||||
case NS_HTML5TOKENIZER_COMMENT_END:
|
||||
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
|
||||
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
|
||||
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
|
||||
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
|
||||
AddClass(sComment);
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
|
||||
AddClass(sCdata);
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
|
||||
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
|
||||
// XXX need tokenizer help here
|
||||
break;
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
|
||||
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
|
||||
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
|
||||
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
|
||||
AddClass(sDoctype);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpStreamEnded);
|
||||
FlushOps();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
|
||||
{
|
||||
NS_PRECONDITION(!mBuffer, "Old buffer still here!");
|
||||
mBuffer = aBuffer;
|
||||
mCStart = aBuffer->getStart();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::DropBuffer(PRInt32 aPos)
|
||||
{
|
||||
NS_PRECONDITION(mBuffer, "No buffer to drop!");
|
||||
mPos = aPos;
|
||||
FlushChars();
|
||||
mBuffer = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::StartSpan()
|
||||
{
|
||||
FlushChars();
|
||||
Push(nsGkAtoms::span, nsnull);
|
||||
++mInlinesOpen;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::StartSpan(const PRUnichar* aClass)
|
||||
{
|
||||
StartSpan();
|
||||
AddClass(aClass);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::EndSpanOrA()
|
||||
{
|
||||
FlushChars();
|
||||
Pop();
|
||||
--mInlinesOpen;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::StartCharacters()
|
||||
{
|
||||
NS_PRECONDITION(!mInCharacters, "Already in characters!");
|
||||
FlushChars();
|
||||
Push(nsGkAtoms::span, nsnull);
|
||||
mCurrentRun = CurrentNode();
|
||||
mInCharacters = true;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::EndCharacters()
|
||||
{
|
||||
NS_PRECONDITION(mInCharacters, "Not in characters!");
|
||||
FlushChars();
|
||||
Pop();
|
||||
mInCharacters = false;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::StartA()
|
||||
{
|
||||
FlushChars();
|
||||
Push(nsGkAtoms::a, nsnull);
|
||||
AddClass(sAttributeValue);
|
||||
++mInlinesOpen;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::FinishTag()
|
||||
{
|
||||
while (mInlinesOpen > 1) {
|
||||
EndSpanOrA();
|
||||
}
|
||||
FlushCurrent(); // >
|
||||
EndSpanOrA(); // DATA
|
||||
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
|
||||
StartCharacters();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::FlushChars()
|
||||
{
|
||||
if (mCStart < mPos) {
|
||||
PRUnichar* buf = mBuffer->getBuffer();
|
||||
PRInt32 i = mCStart;
|
||||
while (i < mPos) {
|
||||
PRUnichar c = buf[i];
|
||||
switch (c) {
|
||||
case '\r':
|
||||
// The input this code sees has been normalized so that there are
|
||||
// CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
|
||||
// to show consistent LF line breaks to layout. It is OK to mutate
|
||||
// the input data, because there are no reparses in the View Source
|
||||
// case, so we won't need the original data in the buffer anymore.
|
||||
buf[i] = '\n';
|
||||
// fall through
|
||||
case '\n': {
|
||||
++i;
|
||||
if (mCStart < i) {
|
||||
PRInt32 len = i - mCStart;
|
||||
AppendCharacters(buf, mCStart, len);
|
||||
mCStart = i;
|
||||
mUnicharsInThisPre += len;
|
||||
}
|
||||
++mLineNumber;
|
||||
if (mUnicharsInThisPre > NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD &&
|
||||
!mInlinesOpen && mInCharacters) {
|
||||
mUnicharsInThisPre = 0;
|
||||
// Split the pre. See bug 86355.
|
||||
Pop(); // span
|
||||
Pop(); // pre
|
||||
Push(nsGkAtoms::pre, nsnull);
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
|
||||
Push(nsGkAtoms::span, nsnull);
|
||||
break;
|
||||
}
|
||||
Push(nsGkAtoms::span, nsnull);
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
|
||||
Pop();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mCStart < mPos) {
|
||||
PRInt32 len = mPos - mCStart;
|
||||
AppendCharacters(buf, mCStart, len);
|
||||
mCStart = mPos;
|
||||
mUnicharsInThisPre += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::FlushCurrent()
|
||||
{
|
||||
mPos++;
|
||||
FlushChars();
|
||||
}
|
||||
|
||||
bool
|
||||
nsHtml5Highlighter::FlushOps()
|
||||
{
|
||||
bool hasOps = !mOpQueue.IsEmpty();
|
||||
if (hasOps) {
|
||||
mOpSink->MoveOpsFrom(mOpQueue);
|
||||
}
|
||||
return hasOps;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
|
||||
nsString* aValue)
|
||||
{
|
||||
if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
|
||||
nsHtml5AttributeName::ATTR_SRC == aName ||
|
||||
nsHtml5AttributeName::ATTR_ACTION == aName ||
|
||||
nsHtml5AttributeName::ATTR_CITE == aName ||
|
||||
nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
|
||||
nsHtml5AttributeName::ATTR_LONGDESC == aName ||
|
||||
nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
|
||||
nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
|
||||
return;
|
||||
}
|
||||
AddViewSourceHref(*aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::CompletedNamedCharacterReference()
|
||||
{
|
||||
AddClass(sEntity);
|
||||
}
|
||||
|
||||
nsIContent**
|
||||
nsHtml5Highlighter::AllocateContentHandle()
|
||||
{
|
||||
if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
|
||||
mOldHandles.AppendElement(mHandles.forget());
|
||||
mHandles = new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH];
|
||||
mHandlesUsed = 0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mHandles[mHandlesUsed] = (nsIContent*)0xC0DEDBAD;
|
||||
#endif
|
||||
return &mHandles[mHandlesUsed++];
|
||||
}
|
||||
|
||||
nsIContent**
|
||||
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes)
|
||||
{
|
||||
NS_PRECONDITION(aName, "Got null name.");
|
||||
nsIContent** content = AllocateContentHandle();
|
||||
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
|
||||
aName,
|
||||
aAttributes,
|
||||
content,
|
||||
true);
|
||||
return content;
|
||||
}
|
||||
|
||||
nsIContent**
|
||||
nsHtml5Highlighter::CurrentNode()
|
||||
{
|
||||
NS_PRECONDITION(mStack.Length() >= 1, "Must have something on stack.");
|
||||
return mStack[mStack.Length() - 1];
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::Push(nsIAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes)
|
||||
{
|
||||
NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
|
||||
nsIContent** elt = CreateElement(aName, aAttributes); // Don't inline below!
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
|
||||
mStack.AppendElement(elt);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::Pop()
|
||||
{
|
||||
NS_PRECONDITION(mStack.Length() >= 2, "Popping when stack too short.");
|
||||
mStack.RemoveElementAt(mStack.Length() - 1);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AppendCharacters(const PRUnichar* aBuffer,
|
||||
PRInt32 aStart,
|
||||
PRInt32 aLength)
|
||||
{
|
||||
NS_PRECONDITION(aBuffer, "Null buffer");
|
||||
|
||||
PRUnichar* bufferCopy = new PRUnichar[aLength];
|
||||
memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(PRUnichar));
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAppendText,
|
||||
bufferCopy,
|
||||
aLength,
|
||||
CurrentNode());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddClass(const PRUnichar* aClass)
|
||||
{
|
||||
mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
|
||||
{
|
||||
PRUnichar* bufferCopy = new PRUnichar[aValue.Length() + 1];
|
||||
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(PRUnichar));
|
||||
bufferCopy[aValue.Length()] = 0;
|
||||
|
||||
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
|
||||
bufferCopy,
|
||||
aValue.Length(),
|
||||
CurrentNode());
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
|
||||
{
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(CurrentNode(), aMsgId);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
|
||||
{
|
||||
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
||||
nsIAtom* aName)
|
||||
{
|
||||
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId, aName);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aOther)
|
||||
{
|
||||
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId)
|
||||
{
|
||||
NS_PRECONDITION(mAmpersand, "Adding error to ampersand without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mAmpersand, aMsgId);
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId)
|
||||
{
|
||||
NS_PRECONDITION(mSlash, "Adding error to slash without one!");
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(mSlash, aMsgId);
|
||||
}
|
|
@ -0,0 +1,459 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is HTML5 View Source code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henri Sivonen <hsivonen@iki.fi>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef nsHtml5Highlighter_h_
|
||||
#define nsHtml5Highlighter_h_
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5UTF16Buffer.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsAHtml5TreeOpSink.h"
|
||||
|
||||
#define NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH 512
|
||||
|
||||
/**
|
||||
* A state machine for generating HTML for display in View Source based on
|
||||
* the transitions the tokenizer makes on the source being viewed.
|
||||
*/
|
||||
class nsHtml5Highlighter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param aOpSink the sink for the tree ops generated by this highlighter
|
||||
*/
|
||||
nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink);
|
||||
|
||||
/**
|
||||
* The destructor.
|
||||
*/
|
||||
~nsHtml5Highlighter();
|
||||
|
||||
/**
|
||||
* Starts the generated document.
|
||||
*/
|
||||
void Start();
|
||||
|
||||
/**
|
||||
* Report a tokenizer state transition.
|
||||
*
|
||||
* @param aState the state being transitioned to
|
||||
* @param aReconsume whether this is a reconsuming transition
|
||||
* @param aPos the tokenizer's current position into the buffer
|
||||
*/
|
||||
PRInt32 Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos);
|
||||
|
||||
/**
|
||||
* Report end of file.
|
||||
*/
|
||||
void End();
|
||||
|
||||
/**
|
||||
* Set the current buffer being tokenized
|
||||
*/
|
||||
void SetBuffer(nsHtml5UTF16Buffer* aBuffer);
|
||||
|
||||
/**
|
||||
* Let go of the buffer being tokenized but first, flush text from it.
|
||||
*
|
||||
* @param aPos the first UTF-16 code unit not to flush
|
||||
*/
|
||||
void DropBuffer(PRInt32 aPos);
|
||||
|
||||
/**
|
||||
* Flush the tree ops into the sink.
|
||||
*
|
||||
* @return true if there were ops to flush
|
||||
*/
|
||||
bool FlushOps();
|
||||
|
||||
/**
|
||||
* Linkify the current attribute value if the attribute name is one of
|
||||
* known URL attributes. (When executing tree ops, javascript: URLs will
|
||||
* not be linkified, though.)
|
||||
*
|
||||
* @param aName the name of the attribute
|
||||
* @param aValue the value of the attribute
|
||||
*/
|
||||
void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
|
||||
nsString* aValue);
|
||||
|
||||
/**
|
||||
* Inform the highlighter that the tokenizer successfully completed a
|
||||
* named character reference.
|
||||
*/
|
||||
void CompletedNamedCharacterReference();
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that's currently on top of
|
||||
* mStack.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
*/
|
||||
void AddErrorToCurrentNode(const char* aMsgId);
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that corresponds to the most
|
||||
* recently opened markup declaration/tag span, character reference or
|
||||
* run of text.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
*/
|
||||
void AddErrorToCurrentRun(const char* aMsgId);
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that corresponds to the most
|
||||
* recently opened markup declaration/tag span, character reference or
|
||||
* run of text with one atom to use when formatting the message.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
* @param aName the atom
|
||||
*/
|
||||
void AddErrorToCurrentRun(const char* aMsgId, nsIAtom* aName);
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that corresponds to the most
|
||||
* recently opened markup declaration/tag span, character reference or
|
||||
* run of text with two atoms to use when formatting the message.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
* @param aName the first atom
|
||||
* @param aOther the second atom
|
||||
*/
|
||||
void AddErrorToCurrentRun(const char* aMsgId,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aOther);
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that corresponds to the most
|
||||
* recent potentially character reference-starting ampersand.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
*/
|
||||
void AddErrorToCurrentAmpersand(const char* aMsgId);
|
||||
|
||||
/**
|
||||
* Adds an error annotation to the node that corresponds to the most
|
||||
* recent potentially self-closing slash.
|
||||
*
|
||||
* @param aMsgId the id of the message in the property file
|
||||
*/
|
||||
void AddErrorToCurrentSlash(const char* aMsgId);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Starts a span with no class.
|
||||
*/
|
||||
void StartSpan();
|
||||
|
||||
/**
|
||||
* Starts a <span> and sets the class attribute on it.
|
||||
*
|
||||
* @param aClass the class to set (MUST be a static string that does not
|
||||
* need to be released!)
|
||||
*/
|
||||
void StartSpan(const PRUnichar* aClass);
|
||||
|
||||
/**
|
||||
* End the current <span> or <a> in the highlighter output.
|
||||
*/
|
||||
void EndSpanOrA();
|
||||
|
||||
/**
|
||||
* Starts a wrapper around a run of characters.
|
||||
*/
|
||||
void StartCharacters();
|
||||
|
||||
/**
|
||||
* Ends a wrapper around a run of characters.
|
||||
*/
|
||||
void EndCharacters();
|
||||
|
||||
/**
|
||||
* Starts an <a>.
|
||||
*/
|
||||
void StartA();
|
||||
|
||||
/**
|
||||
* Flushes characters up to but not including the current one.
|
||||
*/
|
||||
void FlushChars();
|
||||
|
||||
/**
|
||||
* Flushes characters up to and including the current one.
|
||||
*/
|
||||
void FlushCurrent();
|
||||
|
||||
/**
|
||||
* Finishes highlighting a tag in the input data by closing the open
|
||||
* <span> and <a> elements in the highlighter output and then starts
|
||||
* another <span> for potentially highlighting characters potentially
|
||||
* appearing next.
|
||||
*/
|
||||
void FinishTag();
|
||||
|
||||
/**
|
||||
* Adds a class attribute to the current node.
|
||||
*
|
||||
* @param aClass the class to set (MUST be a static string that does not
|
||||
* need to be released!)
|
||||
*/
|
||||
void AddClass(const PRUnichar* aClass);
|
||||
|
||||
/**
|
||||
* Allocates a handle for an element.
|
||||
*
|
||||
* See the documentation for nsHtml5TreeBuilder::AllocateContentHandle()
|
||||
* in nsHtml5TreeBuilderHSupplement.h.
|
||||
*
|
||||
* @return the handle
|
||||
*/
|
||||
nsIContent** AllocateContentHandle();
|
||||
|
||||
/**
|
||||
* Enqueues an element creation tree operation.
|
||||
*
|
||||
* @param aName the name of the element
|
||||
* @param aAttributes the attribute holder (ownership will be taken) or
|
||||
* nsnull for no attributes
|
||||
* @return the handle for the element that will be created
|
||||
*/
|
||||
nsIContent** CreateElement(nsIAtom* aName,
|
||||
nsHtml5HtmlAttributes* aAttributes);
|
||||
|
||||
/**
|
||||
* Gets the handle for the current node. May be called only after the
|
||||
* root element has been set.
|
||||
*
|
||||
* @return the handle for the current node
|
||||
*/
|
||||
nsIContent** CurrentNode();
|
||||
|
||||
/**
|
||||
* Create an element and push it (its handle) on the stack.
|
||||
*
|
||||
* @param aName the name of the element
|
||||
* @param aAttributes the attribute holder (ownership will be taken) or
|
||||
* nsnull for no attributes
|
||||
*/
|
||||
void Push(nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes);
|
||||
|
||||
/**
|
||||
* Pops the current node off the stack.
|
||||
*/
|
||||
void Pop();
|
||||
|
||||
/**
|
||||
* Appends text content to the current node.
|
||||
*
|
||||
* @param aBuffer the buffer to copy from
|
||||
* @param aStart the index of the first code unit to copy
|
||||
* @param aLength the number of code units to copy
|
||||
*/
|
||||
void AppendCharacters(const PRUnichar* aBuffer,
|
||||
PRInt32 aStart,
|
||||
PRInt32 aLength);
|
||||
|
||||
/**
|
||||
* Enqueues a tree op for adding an href attribute with the view-source:
|
||||
* URL scheme to the current node.
|
||||
*
|
||||
* @param aValue the (potentially relative) URL to link to
|
||||
*/
|
||||
void AddViewSourceHref(const nsString& aValue);
|
||||
|
||||
/**
|
||||
* The state we are transitioning away from.
|
||||
*/
|
||||
PRInt32 mState;
|
||||
|
||||
/**
|
||||
* The index of the first UTF-16 code unit in mBuffer that hasn't been
|
||||
* flushed yet.
|
||||
*/
|
||||
PRInt32 mCStart;
|
||||
|
||||
/**
|
||||
* The position of the code unit in mBuffer that caused the current
|
||||
* transition.
|
||||
*/
|
||||
PRInt32 mPos;
|
||||
|
||||
/**
|
||||
* The current line number.
|
||||
*/
|
||||
PRInt32 mLineNumber;
|
||||
|
||||
/**
|
||||
* The number of PRUnichars flushed since the start of the current pre
|
||||
* block.
|
||||
*/
|
||||
PRInt32 mUnicharsInThisPre;
|
||||
|
||||
/**
|
||||
* The number of inline elements open inside the <pre> excluding the
|
||||
* span potentially wrapping a run of characters.
|
||||
*/
|
||||
PRInt32 mInlinesOpen;
|
||||
|
||||
/**
|
||||
* Whether there's a span wrapping a run of characters (excluding CDATA
|
||||
* section) open.
|
||||
*/
|
||||
bool mInCharacters;
|
||||
|
||||
/**
|
||||
* The current buffer being tokenized.
|
||||
*/
|
||||
nsHtml5UTF16Buffer* mBuffer;
|
||||
|
||||
/**
|
||||
* The URL of the document to be shown in the page title.
|
||||
*/
|
||||
nsString mURL;
|
||||
|
||||
/**
|
||||
* Whether to highlight syntax visibly initially.
|
||||
*/
|
||||
bool mSyntaxHighlight;
|
||||
|
||||
/**
|
||||
* Whether to wrap long lines.
|
||||
*/
|
||||
bool mWrapLongLines;
|
||||
|
||||
/**
|
||||
* The tab size pref.
|
||||
*/
|
||||
PRInt32 mTabSize;
|
||||
|
||||
/**
|
||||
* The outgoing tree op queue.
|
||||
*/
|
||||
nsTArray<nsHtml5TreeOperation> mOpQueue;
|
||||
|
||||
/**
|
||||
* The tree op stage for the tree op executor.
|
||||
*/
|
||||
nsAHtml5TreeOpSink* mOpSink;
|
||||
|
||||
/**
|
||||
* The most recently opened markup declaration/tag or run of characters.
|
||||
*/
|
||||
nsIContent** mCurrentRun;
|
||||
|
||||
/**
|
||||
* The most recent ampersand in a place where character references were
|
||||
* allowed.
|
||||
*/
|
||||
nsIContent** mAmpersand;
|
||||
|
||||
/**
|
||||
* The most recent slash that might become a self-closing slash.
|
||||
*/
|
||||
nsIContent** mSlash;
|
||||
|
||||
/**
|
||||
* Memory for element handles.
|
||||
*/
|
||||
nsAutoArrayPtr<nsIContent*> mHandles;
|
||||
|
||||
/**
|
||||
* Number of handles used in mHandles
|
||||
*/
|
||||
PRInt32 mHandlesUsed;
|
||||
|
||||
/**
|
||||
* A holder for old contents of mHandles
|
||||
*/
|
||||
nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
|
||||
|
||||
/**
|
||||
* The element stack.
|
||||
*/
|
||||
nsTArray<nsIContent**> mStack;
|
||||
|
||||
/**
|
||||
* The string "comment"
|
||||
*/
|
||||
static PRUnichar sComment[];
|
||||
|
||||
/**
|
||||
* The string "cdata"
|
||||
*/
|
||||
static PRUnichar sCdata[];
|
||||
|
||||
/**
|
||||
* The string "start-tag"
|
||||
*/
|
||||
static PRUnichar sStartTag[];
|
||||
|
||||
/**
|
||||
* The string "attribute-name"
|
||||
*/
|
||||
static PRUnichar sAttributeName[];
|
||||
|
||||
/**
|
||||
* The string "attribute-value"
|
||||
*/
|
||||
static PRUnichar sAttributeValue[];
|
||||
|
||||
/**
|
||||
* The string "end-tag"
|
||||
*/
|
||||
static PRUnichar sEndTag[];
|
||||
|
||||
/**
|
||||
* The string "doctype"
|
||||
*/
|
||||
static PRUnichar sDoctype[];
|
||||
|
||||
/**
|
||||
* The string "entity"
|
||||
*/
|
||||
static PRUnichar sEntity[];
|
||||
|
||||
/**
|
||||
* The string "pi"
|
||||
*/
|
||||
static PRUnichar sPi[];
|
||||
};
|
||||
|
||||
#endif // nsHtml5Highlighter_h_
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -90,7 +90,7 @@ nsHtml5Parser::nsHtml5Parser()
|
|||
, mLastBuffer(mFirstBuffer)
|
||||
, mExecutor(new nsHtml5TreeOpExecutor())
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nsnull))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
|
||||
, mRootContextLineNumber(1)
|
||||
{
|
||||
mAtomTable.Init(); // we aren't checking for OOM anyway...
|
||||
|
@ -128,7 +128,8 @@ nsHtml5Parser::GetCommand(nsCString& aCommand)
|
|||
NS_IMETHODIMP_(void)
|
||||
nsHtml5Parser::SetCommand(const char* aCommand)
|
||||
{
|
||||
NS_ASSERTION(!strcmp(aCommand, "view"), "Parser command was not view");
|
||||
NS_ASSERTION(!strcmp(aCommand, "view") || !strcmp(aCommand, "view-source"),
|
||||
"Parser command was not view");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
|
@ -493,7 +494,7 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|||
mDocWriteSpeculativeTreeBuilder->setScriptingEnabled(
|
||||
mTreeBuilder->isScriptingEnabled());
|
||||
mDocWriteSpeculativeTokenizer =
|
||||
new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder);
|
||||
new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false);
|
||||
mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable);
|
||||
mDocWriteSpeculativeTokenizer->start();
|
||||
}
|
||||
|
@ -698,10 +699,22 @@ nsHtml5Parser::EndEvaluatingParserInsertedScript()
|
|||
}
|
||||
|
||||
void
|
||||
nsHtml5Parser::MarkAsNotScriptCreated()
|
||||
nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
|
||||
{
|
||||
NS_PRECONDITION(!mStreamParser, "Must not call this twice.");
|
||||
mStreamParser = new nsHtml5StreamParser(mExecutor, this);
|
||||
eParserMode mode = NORMAL;
|
||||
if (!nsCRT::strcmp(aCommand, "view-source")) {
|
||||
mode = VIEW_SOURCE_HTML;
|
||||
} else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
|
||||
mode = VIEW_SOURCE_XML;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
NS_ASSERTION(!nsCRT::strcmp(aCommand, "view"),
|
||||
"Unsupported parser command!");
|
||||
}
|
||||
#endif
|
||||
mStreamParser = new nsHtml5StreamParser(mExecutor, this, mode);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -246,8 +246,11 @@ class nsHtml5Parser : public nsIParser,
|
|||
/**
|
||||
* Marks the HTML5 parser as not a script-created parser: Prepares the
|
||||
* parser to be able to read a stream.
|
||||
*
|
||||
* @param aCommand the parser command (Yeah, this is bad API design. Let's
|
||||
* make this better when retiring nsIParser)
|
||||
*/
|
||||
virtual void MarkAsNotScriptCreated();
|
||||
virtual void MarkAsNotScriptCreated(const char* aCommand);
|
||||
|
||||
/**
|
||||
* True if this is a script-created HTML5 parser.
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
#include "nsHtml5RefPtr.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsHtml5Highlighter.h"
|
||||
#include "expat_config.h"
|
||||
#include "expat.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -174,13 +177,17 @@ class nsHtml5LoadFlusher : public nsRunnable
|
|||
};
|
||||
|
||||
nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
||||
nsHtml5Parser* aOwner)
|
||||
nsHtml5Parser* aOwner,
|
||||
eParserMode aMode)
|
||||
: mFirstBuffer(nsnull) // Will be filled when starting
|
||||
, mLastBuffer(nsnull) // Will be filled when starting
|
||||
, mExecutor(aExecutor)
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor->GetStage(),
|
||||
mExecutor->GetStage()))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder((aMode == VIEW_SOURCE_HTML ||
|
||||
aMode == VIEW_SOURCE_XML) ?
|
||||
nsnull : mExecutor->GetStage(),
|
||||
aMode == NORMAL ?
|
||||
mExecutor->GetStage() : nsnull))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, aMode == VIEW_SOURCE_XML))
|
||||
, mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex")
|
||||
, mOwner(aOwner)
|
||||
, mSpeculationMutex("nsHtml5StreamParser mSpeculationMutex")
|
||||
|
@ -189,6 +196,7 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
|||
, mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor))
|
||||
, mLoadFlusher(new nsHtml5LoadFlusher(aExecutor))
|
||||
, mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
|
||||
, mMode(aMode)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
mFlushTimer->SetTarget(mThread);
|
||||
|
@ -199,6 +207,13 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
|||
mTokenizer->setInterner(&mAtomTable);
|
||||
mTokenizer->setEncodingDeclarationHandler(this);
|
||||
|
||||
if (aMode == VIEW_SOURCE_HTML || aMode == VIEW_SOURCE_XML) {
|
||||
nsHtml5Highlighter* highlighter =
|
||||
new nsHtml5Highlighter(mExecutor->GetStage());
|
||||
mTokenizer->EnableViewSource(highlighter); // takes ownership
|
||||
mTreeBuilder->EnableViewSource(highlighter); // doesn't own
|
||||
}
|
||||
|
||||
// Chardet instantiation adapted from nsDOMFile.
|
||||
// Chardet is initialized here even if it turns out to be useless
|
||||
// to make the chardet refcount its observer (nsHtml5StreamParser)
|
||||
|
@ -390,6 +405,76 @@ nsHtml5StreamParser::SniffBOMlessUTF16BasicLatin(const PRUint8* aFromSegment,
|
|||
mFeedChardet = false;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5StreamParser::MaybeSetEncodingFromExpat(const PRUnichar* aEncoding)
|
||||
{
|
||||
nsDependentString utf16(aEncoding);
|
||||
nsCAutoString utf8;
|
||||
CopyUTF16toUTF8(utf16, utf8);
|
||||
if (PreferredForInternalEncodingDecl(utf8)) {
|
||||
mCharset.Assign(utf8);
|
||||
mCharsetSource = kCharsetFromMetaTag; // closest for XML
|
||||
}
|
||||
}
|
||||
|
||||
// A separate user data struct is used instead of passing the
|
||||
// nsHtml5StreamParser instance as user data in order to avoid including
|
||||
// expat.h in nsHtml5StreamParser.h. Doing that would cause naming conflicts.
|
||||
// Using a separate user data struct also avoids bloating nsHtml5StreamParser
|
||||
// by one pointer.
|
||||
struct UserData {
|
||||
XML_Parser mExpat;
|
||||
nsHtml5StreamParser* mStreamParser;
|
||||
};
|
||||
|
||||
// Using no-namespace handler callbacks to avoid including expat.h in
|
||||
// nsHtml5StreamParser.h, since doing so would cause naming conclicts.
|
||||
static void
|
||||
HandleXMLDeclaration(void* aUserData,
|
||||
const XML_Char* aVersion,
|
||||
const XML_Char* aEncoding,
|
||||
int aStandalone)
|
||||
{
|
||||
UserData* ud = static_cast<UserData*>(aUserData);
|
||||
ud->mStreamParser->MaybeSetEncodingFromExpat(
|
||||
reinterpret_cast<const PRUnichar*>(aEncoding));
|
||||
XML_StopParser(ud->mExpat, false);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleStartElement(void* aUserData,
|
||||
const XML_Char* aName,
|
||||
const XML_Char **aAtts)
|
||||
{
|
||||
UserData* ud = static_cast<UserData*>(aUserData);
|
||||
XML_StopParser(ud->mExpat, false);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleEndElement(void* aUserData,
|
||||
const XML_Char* aName)
|
||||
{
|
||||
UserData* ud = static_cast<UserData*>(aUserData);
|
||||
XML_StopParser(ud->mExpat, false);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleComment(void* aUserData,
|
||||
const XML_Char* aName)
|
||||
{
|
||||
UserData* ud = static_cast<UserData*>(aUserData);
|
||||
XML_StopParser(ud->mExpat, false);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleProcessingInstruction(void* aUserData,
|
||||
const XML_Char* aTarget,
|
||||
const XML_Char* aData)
|
||||
{
|
||||
UserData* ud = static_cast<UserData*>(aUserData);
|
||||
XML_StopParser(ud->mExpat, false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHtml5StreamParser::FinalizeSniffing(const PRUint8* aFromSegment, // can be null
|
||||
PRUint32 aCount,
|
||||
|
@ -397,6 +482,78 @@ nsHtml5StreamParser::FinalizeSniffing(const PRUint8* aFromSegment, // can be nul
|
|||
PRUint32 aCountToSniffingLimit)
|
||||
{
|
||||
NS_ASSERTION(IsParserThread(), "Wrong thread!");
|
||||
NS_ASSERTION(mCharsetSource < kCharsetFromMetaTag,
|
||||
"Should not finalize sniffing when already confident.");
|
||||
if (mMode == VIEW_SOURCE_XML) {
|
||||
static const XML_Memory_Handling_Suite memsuite =
|
||||
{
|
||||
(void *(*)(size_t))moz_xmalloc,
|
||||
(void *(*)(void *, size_t))moz_xrealloc,
|
||||
moz_free
|
||||
};
|
||||
|
||||
static const PRUnichar kExpatSeparator[] = { 0xFFFF, '\0' };
|
||||
|
||||
static const PRUnichar kISO88591[] =
|
||||
{ 'I', 'S', 'O', '-', '8', '8', '5', '9', '-', '1', '\0' };
|
||||
|
||||
UserData ud;
|
||||
ud.mStreamParser = this;
|
||||
|
||||
// If we got this far, the stream didn't have a BOM. UTF-16-encoded XML
|
||||
// documents MUST begin with a BOM. We don't support EBCDIC and such.
|
||||
// Thus, at this point, what we have is garbage or something encoded using
|
||||
// a rough ASCII superset. ISO-8859-1 allows us to decode ASCII bytes
|
||||
// without throwing errors when bytes have the most significant bit set
|
||||
// and without triggering expat's unknown encoding code paths. This is
|
||||
// enough to be able to use expat to parse the XML declaration in order
|
||||
// to extract the encoding name from it.
|
||||
ud.mExpat = XML_ParserCreate_MM(kISO88591, &memsuite, kExpatSeparator);
|
||||
XML_SetXmlDeclHandler(ud.mExpat, HandleXMLDeclaration);
|
||||
XML_SetElementHandler(ud.mExpat, HandleStartElement, HandleEndElement);
|
||||
XML_SetCommentHandler(ud.mExpat, HandleComment);
|
||||
XML_SetProcessingInstructionHandler(ud.mExpat, HandleProcessingInstruction);
|
||||
XML_SetUserData(ud.mExpat, static_cast<void*>(&ud));
|
||||
|
||||
XML_Status status = XML_STATUS_OK;
|
||||
|
||||
// aFromSegment points to the data obtained from the current network
|
||||
// event. mSniffingBuffer (if it exists) contains the data obtained before
|
||||
// the current event. Thus, mSniffingLenth bytes of mSniffingBuffer
|
||||
// followed by aCountToSniffingLimit bytes from aFromSegment are the
|
||||
// first 1024 bytes of the file (or the file as a whole if the file is
|
||||
// 1024 bytes long or shorter). Thus, we parse both buffers, but if the
|
||||
// first call succeeds already, we skip parsing the second buffer.
|
||||
if (mSniffingBuffer) {
|
||||
status = XML_Parse(ud.mExpat,
|
||||
reinterpret_cast<const char*>(mSniffingBuffer.get()),
|
||||
mSniffingLength,
|
||||
false);
|
||||
}
|
||||
if (status == XML_STATUS_OK &&
|
||||
mCharsetSource < kCharsetFromMetaTag &&
|
||||
aFromSegment) {
|
||||
status = XML_Parse(ud.mExpat,
|
||||
reinterpret_cast<const char*>(aFromSegment),
|
||||
aCountToSniffingLimit,
|
||||
false);
|
||||
}
|
||||
XML_ParserFree(ud.mExpat);
|
||||
|
||||
if (mCharsetSource < kCharsetFromMetaTag) {
|
||||
// Failed to get an encoding from the XML declaration. XML defaults
|
||||
// confidently to UTF-8 in this case.
|
||||
// It is also possible that the document has an XML declaration that is
|
||||
// longer than 1024 bytes, but that case is not worth worrying about.
|
||||
mCharset.AssignLiteral("UTF-8");
|
||||
mCharsetSource = kCharsetFromMetaTag; // means confident
|
||||
}
|
||||
|
||||
return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment,
|
||||
aCount,
|
||||
aWriteCount);
|
||||
}
|
||||
|
||||
// meta scan failed.
|
||||
if (mCharsetSource >= kCharsetFromHintPrevDoc) {
|
||||
mFeedChardet = false;
|
||||
|
@ -524,39 +681,52 @@ nsHtml5StreamParser::SniffStreamBytes(const PRUint8* aFromSegment,
|
|||
}
|
||||
// if we get here, there either was no BOM or the BOM sniffing isn't complete yet
|
||||
|
||||
if (!mMetaScanner) {
|
||||
if (!mMetaScanner && (mMode == NORMAL || mMode == VIEW_SOURCE_HTML)) {
|
||||
mMetaScanner = new nsHtml5MetaScanner();
|
||||
}
|
||||
|
||||
if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
|
||||
// this is the last buffer
|
||||
PRUint32 countToSniffingLimit = NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
|
||||
nsHtml5ByteReadable readable(aFromSegment, aFromSegment + countToSniffingLimit);
|
||||
PRUint32 countToSniffingLimit =
|
||||
NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
|
||||
if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
|
||||
nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
|
||||
countToSniffingLimit);
|
||||
mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
|
||||
if (mUnicodeDecoder) {
|
||||
mUnicodeDecoder->SetInputErrorBehavior(
|
||||
nsIUnicodeDecoder::kOnError_Recover);
|
||||
// meta scan successful
|
||||
mCharsetSource = kCharsetFromMetaPrescan;
|
||||
mFeedChardet = false;
|
||||
mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
|
||||
mMetaScanner = nsnull;
|
||||
return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount,
|
||||
aWriteCount);
|
||||
}
|
||||
}
|
||||
return FinalizeSniffing(aFromSegment, aCount, aWriteCount,
|
||||
countToSniffingLimit);
|
||||
}
|
||||
|
||||
// not the last buffer
|
||||
if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
|
||||
nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
|
||||
mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
|
||||
if (mUnicodeDecoder) {
|
||||
mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
|
||||
// meta scan successful
|
||||
mUnicodeDecoder->SetInputErrorBehavior(
|
||||
nsIUnicodeDecoder::kOnError_Recover);
|
||||
mCharsetSource = kCharsetFromMetaPrescan;
|
||||
mFeedChardet = false;
|
||||
mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
|
||||
mMetaScanner = nsnull;
|
||||
return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
|
||||
return WriteSniffingBufferAndCurrentSegment(aFromSegment,
|
||||
aCount,
|
||||
aWriteCount);
|
||||
}
|
||||
return FinalizeSniffing(aFromSegment, aCount, aWriteCount, countToSniffingLimit);
|
||||
}
|
||||
|
||||
// not the last buffer
|
||||
nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
|
||||
mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
|
||||
if (mUnicodeDecoder) {
|
||||
// meta scan successful
|
||||
mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
|
||||
mCharsetSource = kCharsetFromMetaPrescan;
|
||||
mFeedChardet = false;
|
||||
mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
|
||||
mMetaScanner = nsnull;
|
||||
return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
|
||||
}
|
||||
if (!mSniffingBuffer) {
|
||||
const mozilla::fallible_t fallible = mozilla::fallible_t();
|
||||
mSniffingBuffer = new (fallible)
|
||||
|
@ -685,6 +855,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
|
||||
mStreamState = STREAM_BEING_READ;
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->StartViewSource();
|
||||
}
|
||||
// For View Source, the parser should run with scripts "enabled" if a normal
|
||||
// load would have scripts enabled.
|
||||
bool scriptingEnabled = mExecutor->IsScriptEnabled();
|
||||
mOwner->StartTokenizer(scriptingEnabled);
|
||||
mTreeBuilder->setScriptingEnabled(scriptingEnabled);
|
||||
|
@ -713,7 +888,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mReparseForbidden = false;
|
||||
// The line below means that the encoding can end up being wrong if
|
||||
// a view-source URL is loaded without having the encoding hint from a
|
||||
// previous normal load in the history.
|
||||
mReparseForbidden = !(mMode == NORMAL);
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mRequest, &rv));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString method;
|
||||
|
@ -920,22 +1099,9 @@ nsHtml5StreamParser::OnDataAvailable(nsIRequest* aRequest,
|
|||
}
|
||||
|
||||
bool
|
||||
nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
|
||||
nsHtml5StreamParser::PreferredForInternalEncodingDecl(nsACString& aEncoding)
|
||||
{
|
||||
// This code needs to stay in sync with
|
||||
// nsHtml5MetaScanner::tryCharset. Unfortunately, the
|
||||
// trickery with member fields there leads to some copy-paste reuse. :-(
|
||||
NS_ASSERTION(IsParserThread(), "Wrong thread!");
|
||||
if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mReparseForbidden) {
|
||||
return false; // not reparsing even if we wanted to
|
||||
}
|
||||
|
||||
nsCAutoString newEncoding;
|
||||
CopyUTF16toUTF8(*aEncoding, newEncoding);
|
||||
nsCAutoString newEncoding(aEncoding);
|
||||
newEncoding.Trim(" \t\r\n\f");
|
||||
if (newEncoding.LowerCaseEqualsLiteral("utf-16") ||
|
||||
newEncoding.LowerCaseEqualsLiteral("utf-16be") ||
|
||||
|
@ -982,11 +1148,36 @@ nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
|
|||
// Not a rough ASCII superset
|
||||
return false;
|
||||
}
|
||||
aEncoding.Assign(preferred);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
|
||||
{
|
||||
// This code needs to stay in sync with
|
||||
// nsHtml5MetaScanner::tryCharset. Unfortunately, the
|
||||
// trickery with member fields there leads to some copy-paste reuse. :-(
|
||||
NS_ASSERTION(IsParserThread(), "Wrong thread!");
|
||||
if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mReparseForbidden) {
|
||||
return false; // not reparsing even if we wanted to
|
||||
}
|
||||
|
||||
nsCAutoString newEncoding;
|
||||
CopyUTF16toUTF8(*aEncoding, newEncoding);
|
||||
|
||||
if (!PreferredForInternalEncodingDecl(newEncoding)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid having the chardet ask for another restart after this restart
|
||||
// request.
|
||||
mFeedChardet = false;
|
||||
mTreeBuilder->NeedsCharsetSwitchTo(preferred, kCharsetFromMetaTag);
|
||||
mTreeBuilder->NeedsCharsetSwitchTo(newEncoding, kCharsetFromMetaTag);
|
||||
FlushTreeOpsAndDisarmTimer();
|
||||
Interrupt();
|
||||
// the tree op executor will cause the stream parser to terminate
|
||||
|
@ -1007,6 +1198,9 @@ nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer()
|
|||
mFlushTimer->Cancel();
|
||||
mFlushTimerArmed = false;
|
||||
}
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
|
@ -1049,6 +1243,9 @@ nsHtml5StreamParser::ParseAvailableData()
|
|||
mAtEOF = true;
|
||||
mTokenizer->eof();
|
||||
mTreeBuilder->StreamEnded();
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->EndViewSource();
|
||||
}
|
||||
FlushTreeOpsAndDisarmTimer();
|
||||
return; // no more data and not expecting more
|
||||
default:
|
||||
|
@ -1069,7 +1266,7 @@ nsHtml5StreamParser::ParseAvailableData()
|
|||
// Terminate, but that never happens together with script.
|
||||
// Can't assert that here, though, because it's possible that the main
|
||||
// thread has called Terminate() while this thread was parsing.
|
||||
if (mTreeBuilder->HasScript()) {
|
||||
if (mMode == NORMAL && mTreeBuilder->HasScript()) {
|
||||
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
|
||||
nsHtml5Speculation* speculation =
|
||||
new nsHtml5Speculation(mFirstBuffer,
|
||||
|
@ -1114,6 +1311,8 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
|
|||
bool aLastWasCR)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!(mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML),
|
||||
"ContinueAfterScripts called in view source mode!");
|
||||
if (mExecutor->IsBroken()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1329,11 +1528,20 @@ nsHtml5StreamParser::TimerFlush()
|
|||
return;
|
||||
}
|
||||
|
||||
// we aren't speculating and we don't know when new data is
|
||||
// going to arrive. Send data to the main thread.
|
||||
if (mTreeBuilder->Flush(true)) {
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTreeBuilder->Flush(); // delete useless ops
|
||||
if (mTokenizer->FlushViewSource()) {
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we aren't speculating and we don't know when new data is
|
||||
// going to arrive. Send data to the main thread.
|
||||
if (mTreeBuilder->Flush(true)) {
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,28 @@ class nsHtml5Parser;
|
|||
#define NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE 1024
|
||||
#define NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE 1024
|
||||
|
||||
enum eParserMode {
|
||||
/**
|
||||
* Parse a document normally as HTML.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* View document as HTML source.
|
||||
*/
|
||||
VIEW_SOURCE_HTML,
|
||||
|
||||
/**
|
||||
* View document as XML source
|
||||
*/
|
||||
VIEW_SOURCE_XML,
|
||||
|
||||
/**
|
||||
* View document as plain text
|
||||
*/
|
||||
PLAIN_TEXT
|
||||
};
|
||||
|
||||
enum eBomState {
|
||||
/**
|
||||
* BOM sniffing hasn't started.
|
||||
|
@ -118,7 +140,8 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
static void InitializeStatics();
|
||||
|
||||
nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
||||
nsHtml5Parser* aOwner);
|
||||
nsHtml5Parser* aOwner,
|
||||
eParserMode aMode);
|
||||
|
||||
virtual ~nsHtml5StreamParser();
|
||||
|
||||
|
@ -185,6 +208,12 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
|
||||
void DropTimer();
|
||||
|
||||
/**
|
||||
* Sets mCharset and mCharsetSource appropriately for the XML View Source
|
||||
* case if aEncoding names a supported rough ASCII superset.
|
||||
*/
|
||||
void MaybeSetEncodingFromExpat(const PRUnichar* aEncoding);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -326,6 +355,16 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
nsresult SetupDecodingFromBom(const char* aCharsetName,
|
||||
const char* aDecoderCharsetName);
|
||||
|
||||
/**
|
||||
* Become confident or resolve and encoding name to its preferred form.
|
||||
* @param aEncoding the value of an internal encoding decl. Acts as an
|
||||
* out param, too, when the method returns true.
|
||||
* @return true if the parser needs to start using the new value of
|
||||
* aEncoding and false if the parser became confident or if
|
||||
* the encoding name did not specify a usable encoding
|
||||
*/
|
||||
bool PreferredForInternalEncodingDecl(nsACString& aEncoding);
|
||||
|
||||
/**
|
||||
* Callback for mFlushTimer.
|
||||
*/
|
||||
|
@ -495,6 +534,11 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
*/
|
||||
bool mFlushTimerEverFired;
|
||||
|
||||
/**
|
||||
* Whether the parser is doing a normal parse, view source or plain text.
|
||||
*/
|
||||
eParserMode mMode;
|
||||
|
||||
/**
|
||||
* The pref html5.flushtimer.initialdelay: Time in milliseconds between
|
||||
* the time a network buffer is seen and the timer firing when the
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -35,9 +35,7 @@
|
|||
#include "nsIAtom.h"
|
||||
#include "nsHtml5AtomTable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
|
@ -45,10 +43,10 @@
|
|||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
#include "nsHtml5Highlighter.h"
|
||||
#include "nsHtml5TokenizerLoopPolicies.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
||||
|
@ -140,10 +138,12 @@ class nsHtml5Tokenizer
|
|||
private:
|
||||
PRInt32 line;
|
||||
nsHtml5AtomTable* interner;
|
||||
bool viewingXmlSource;
|
||||
public:
|
||||
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler);
|
||||
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
|
||||
void setInterner(nsHtml5AtomTable* interner);
|
||||
void initLocation(nsString* newPublicId, nsString* newSystemId);
|
||||
bool isViewingXmlSource();
|
||||
void setStateAndEndTagExpectation(PRInt32 specialTokenizerState, nsIAtom* endTagExpectation);
|
||||
void setStateAndEndTagExpectation(PRInt32 specialTokenizerState, nsHtml5ElementName* endTagExpectation);
|
||||
private:
|
||||
|
@ -193,7 +193,7 @@ class nsHtml5Tokenizer
|
|||
|
||||
inline void adjustDoubleHyphenAndAppendToLongStrBufAndErr(PRUnichar c)
|
||||
{
|
||||
|
||||
errConsecutiveHyphens();
|
||||
appendLongStrBuf(c);
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ class nsHtml5Tokenizer
|
|||
void start();
|
||||
bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
|
||||
private:
|
||||
PRInt32 stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* buf, bool reconsume, PRInt32 returnState, PRInt32 endPos);
|
||||
template<class P> PRInt32 stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* buf, bool reconsume, PRInt32 returnState, PRInt32 endPos);
|
||||
void initDoctypeFields();
|
||||
inline void adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn()
|
||||
{
|
||||
|
@ -291,6 +291,8 @@ class nsHtml5Tokenizer
|
|||
~nsHtml5Tokenizer();
|
||||
static void initializeStatics();
|
||||
static void releaseStatics();
|
||||
|
||||
#include "nsHtml5TokenizerHSupplement.h"
|
||||
};
|
||||
|
||||
#define NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK ~1
|
||||
|
@ -367,6 +369,8 @@ class nsHtml5Tokenizer
|
|||
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH 70
|
||||
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH 71
|
||||
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END 72
|
||||
#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION 73
|
||||
#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK 74
|
||||
#define NS_HTML5TOKENIZER_LEAD_OFFSET (0xD800 - (0x10000 >> 10))
|
||||
#define NS_HTML5TOKENIZER_BUFFER_GROW_BY 1024
|
||||
|
||||
|
|
|
@ -0,0 +1,555 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is HTML5 View Source code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henri Sivonen <hsivonen@iki.fi>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
|
||||
{
|
||||
mViewSource = aHighlighter;
|
||||
}
|
||||
|
||||
bool
|
||||
nsHtml5Tokenizer::FlushViewSource()
|
||||
{
|
||||
return mViewSource->FlushOps();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::StartViewSource()
|
||||
{
|
||||
mViewSource->Start();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::EndViewSource()
|
||||
{
|
||||
mViewSource->End();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errWarnLtSlashInRcdata()
|
||||
{
|
||||
}
|
||||
|
||||
// The null checks below annotated NS_LIKELY are not actually necessary.
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errUnquotedAttributeValOrNull(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
|
||||
return;
|
||||
case '`':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
|
||||
return;
|
||||
case '\'':
|
||||
case '"':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
|
||||
return;
|
||||
case '=':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
switch (c) {
|
||||
case '=':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
|
||||
return;
|
||||
case '<':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
|
||||
return;
|
||||
case '`':
|
||||
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
if (c == '<') {
|
||||
mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
|
||||
} else if (c == '=') {
|
||||
errEqualsSignBeforeAttributeName();
|
||||
} else if (c != 0xFFFD) {
|
||||
errQuoteBeforeAttributeName(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errBadCharAfterLt(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
if (c == '<') {
|
||||
mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
|
||||
} else if (c != 0xFFFD) {
|
||||
mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
|
||||
{
|
||||
if (mViewSource && attrs->getLength() != 0) {
|
||||
/*
|
||||
* When an end tag token is emitted with attributes, that is a parse
|
||||
* error.
|
||||
*/
|
||||
mViewSource->AddErrorToCurrentRun("maybeErrAttributesOnEndTag");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::maybeErrSlashInEndTag(bool selfClosing)
|
||||
{
|
||||
if (mViewSource && selfClosing && endTag) {
|
||||
mViewSource->AddErrorToCurrentSlash("maybeErrSlashInEndTag");
|
||||
}
|
||||
}
|
||||
|
||||
PRUnichar
|
||||
nsHtml5Tokenizer::errNcrNonCharacter(PRUnichar ch)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errAstralNonCharacter(int ch)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errAstralNonCharacter");
|
||||
}
|
||||
}
|
||||
|
||||
PRUnichar
|
||||
nsHtml5Tokenizer::errNcrControlChar(PRUnichar ch)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errGarbageAfterLtSlash()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errLtSlashGt()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errLtSlashGt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errCharRefLacksSemicolon()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoDigitsInNCR()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errGtInSystemId()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errGtInSystemId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errGtInPublicId()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errGtInPublicId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNamelessDoctype()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errConsecutiveHyphens()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errPrematureEndOfComment()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errBogusComment()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errBogusComment");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errSlashNotFollowedByGt()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errAttributeValueMissing()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errLtGt()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errLtGt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errProcessingInstruction()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNotSemicolonTerminated()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoNamedCharacterMatch()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errQuoteBeforeAttributeName(PRUnichar c)
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errExpectedPublicId()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errBogusDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errBogusDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrSurrogate()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrSurrogate");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrCr()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrCr");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrInC1Range()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrInC1Range");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInPublicId()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInPublicId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInComment()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInComment");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInAttributeValue()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInAttributeValue");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInAttributeName()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInAttributeName");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofWithoutGt()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofWithoutGt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInTagName()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInTagName");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInEndTag()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInEndTag");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofAfterLt()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofAfterLt");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrOutOfRange()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrOutOfRange");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrUnassigned()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrUnassigned");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errDuplicateAttribute()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errDuplicateAttribute");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errEofInSystemId()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEofInSystemId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errExpectedSystemId()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errHyphenHyphenBang()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrControlChar()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNcrZero()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNcrZero");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
|
||||
{
|
||||
if (NS_LIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is HTML5 View Source code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henri Sivonen <hsivonen@iki.fi>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
nsAutoPtr<nsHtml5Highlighter> mViewSource;
|
||||
|
||||
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
||||
|
||||
bool FlushViewSource();
|
||||
|
||||
void StartViewSource();
|
||||
|
||||
void EndViewSource();
|
||||
|
||||
void errGarbageAfterLtSlash();
|
||||
|
||||
void errLtSlashGt();
|
||||
|
||||
void errWarnLtSlashInRcdata();
|
||||
|
||||
void errCharRefLacksSemicolon();
|
||||
|
||||
void errNoDigitsInNCR();
|
||||
|
||||
void errGtInSystemId();
|
||||
|
||||
void errGtInPublicId();
|
||||
|
||||
void errNamelessDoctype();
|
||||
|
||||
void errConsecutiveHyphens();
|
||||
|
||||
void errPrematureEndOfComment();
|
||||
|
||||
void errBogusComment();
|
||||
|
||||
void errUnquotedAttributeValOrNull(PRUnichar c);
|
||||
|
||||
void errSlashNotFollowedByGt();
|
||||
|
||||
void errNoSpaceBetweenAttributes();
|
||||
|
||||
void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(PRUnichar c);
|
||||
|
||||
void errAttributeValueMissing();
|
||||
|
||||
void errBadCharBeforeAttributeNameOrNull(PRUnichar c);
|
||||
|
||||
void errEqualsSignBeforeAttributeName();
|
||||
|
||||
void errBadCharAfterLt(PRUnichar c);
|
||||
|
||||
void errLtGt();
|
||||
|
||||
void errProcessingInstruction();
|
||||
|
||||
void errUnescapedAmpersandInterpretedAsCharacterReference();
|
||||
|
||||
void errNotSemicolonTerminated();
|
||||
|
||||
void errNoNamedCharacterMatch();
|
||||
|
||||
void errQuoteBeforeAttributeName(PRUnichar c);
|
||||
|
||||
void errQuoteOrLtInAttributeNameOrNull(PRUnichar c);
|
||||
|
||||
void errExpectedPublicId();
|
||||
|
||||
void errBogusDoctype();
|
||||
|
||||
void maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs);
|
||||
|
||||
void maybeErrSlashInEndTag(bool selfClosing);
|
||||
|
||||
PRUnichar errNcrNonCharacter(PRUnichar ch);
|
||||
|
||||
void errAstralNonCharacter(PRInt32 ch);
|
||||
|
||||
void errNcrSurrogate();
|
||||
|
||||
PRUnichar errNcrControlChar(PRUnichar ch);
|
||||
|
||||
void errNcrCr();
|
||||
|
||||
void errNcrInC1Range();
|
||||
|
||||
void errEofInPublicId();
|
||||
|
||||
void errEofInComment();
|
||||
|
||||
void errEofInDoctype();
|
||||
|
||||
void errEofInAttributeValue();
|
||||
|
||||
void errEofInAttributeName();
|
||||
|
||||
void errEofWithoutGt();
|
||||
|
||||
void errEofInTagName();
|
||||
|
||||
void errEofInEndTag();
|
||||
|
||||
void errEofAfterLt();
|
||||
|
||||
void errNcrOutOfRange();
|
||||
|
||||
void errNcrUnassigned();
|
||||
|
||||
void errDuplicateAttribute();
|
||||
|
||||
void errEofInSystemId();
|
||||
|
||||
void errExpectedSystemId();
|
||||
|
||||
void errMissingSpaceBeforeDoctypeName();
|
||||
|
||||
void errHyphenHyphenBang();
|
||||
|
||||
void errNcrControlChar();
|
||||
|
||||
void errNcrZero();
|
||||
|
||||
void errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
|
||||
|
||||
void errNoSpaceBetweenPublicAndSystemIds();
|
||||
|
||||
void errNoSpaceBetweenDoctypePublicKeywordAndQuote();
|
|
@ -0,0 +1,76 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is HTML5 View Source code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henri Sivonen <hsivonen@iki.fi>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsHtml5TokenizerLoopPolicies_h_
|
||||
#define nsHtml5TokenizerLoopPolicies_h_
|
||||
|
||||
/**
|
||||
* This policy does not report tokenizer transitions anywhere. To be used
|
||||
* when _not_ viewing source.
|
||||
*/
|
||||
struct nsHtml5SilentPolicy
|
||||
{
|
||||
static const bool reportErrors = false;
|
||||
static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
|
||||
PRInt32 aState,
|
||||
bool aReconsume,
|
||||
PRInt32 aPos) {
|
||||
return aState;
|
||||
}
|
||||
static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This policy reports the tokenizer transitions to a highlighter. To be used
|
||||
* when viewing source.
|
||||
*/
|
||||
struct nsHtml5ViewSourcePolicy
|
||||
{
|
||||
static const bool reportErrors = true;
|
||||
static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
|
||||
PRInt32 aState,
|
||||
bool aReconsume,
|
||||
PRInt32 aPos) {
|
||||
return aHighlighter->Transition(aState, aReconsume, aPos);
|
||||
}
|
||||
static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter) {
|
||||
aHighlighter->CompletedNamedCharacterReference();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // nsHtml5TokenizerLoopPolicies_h_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -45,7 +45,6 @@
|
|||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5Parser.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
|
@ -53,6 +52,7 @@
|
|||
#include "nsHtml5TreeOpExecutor.h"
|
||||
#include "nsHtml5StreamParser.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Highlighter.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
|
|||
, contextNode(nsnull)
|
||||
, formPointer(nsnull)
|
||||
, headPointer(nsnull)
|
||||
, mViewSource(nsnull)
|
||||
, mOpSink(aOpSink)
|
||||
, mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
|
||||
, mHandlesUsed(0)
|
||||
|
@ -644,8 +645,13 @@ void
|
|||
nsHtml5TreeBuilder::SetDocumentCharset(nsACString& aCharset,
|
||||
PRInt32 aCharsetSource)
|
||||
{
|
||||
mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(aCharset,
|
||||
aCharsetSource);
|
||||
if (mSpeculativeLoadStage) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
|
||||
aCharset, aCharsetSource);
|
||||
} else {
|
||||
mOpQueue.AppendElement()->Init(
|
||||
eTreeOpSetDocumentCharset, aCharset, aCharsetSource);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -702,3 +708,396 @@ nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
|
|||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(m);
|
||||
}
|
||||
|
||||
// Error reporting
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
|
||||
{
|
||||
mViewSource = aHighlighter;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStrayStartTag", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errUnclosedElements(PRInt32 aIndex, nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
|
||||
aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errUnclosedElementsCell(PRInt32 aIndex)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStrayDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStrayDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errAlmostStandardsDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errQuirkyDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceInTrailer()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceInFrameset()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceAfterBody()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartTagWithoutDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNoSelectInTableScope()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun(
|
||||
"errStartSelectWhereEndSelectExpected");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errBadStartTagInHead", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errImage()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errImage");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errIsindex()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errIsindex");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errFramesetStart()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errFramesetStart");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNoCellToClose()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNoCellToClose");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errFormWhenFormOpen()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagAfterBody()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
|
||||
aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errGarbageInColgroup()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagBr()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndTagBr");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun(
|
||||
"errNoElementToCloseButEndTagSeen", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
|
||||
aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNoTableRowToClose()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNonSpaceInTable()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
|
||||
aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errSelfClosing()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentSlash("errSelfClosing");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun(
|
||||
"errNoCheckUnclosedElementsOnStack");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
|
||||
nsIAtom* aOther)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun(
|
||||
"errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
|
||||
{
|
||||
if (NS_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
|
||||
|
||||
private:
|
||||
|
||||
nsHtml5Highlighter* mViewSource;
|
||||
nsTArray<nsHtml5TreeOperation> mOpQueue;
|
||||
nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
|
||||
nsAHtml5TreeOpSink* mOpSink;
|
||||
|
@ -58,6 +58,29 @@
|
|||
*/
|
||||
void documentMode(nsHtml5DocumentMode m);
|
||||
|
||||
/**
|
||||
* Using nsIContent** instead of nsIContent* is the parser deals with DOM
|
||||
* nodes in a way that works off the main thread. Non-main-thread code
|
||||
* can't refcount or otherwise touch nsIContent objects in any way.
|
||||
* Yet, the off-the-main-thread code needs to have a way to hold onto a
|
||||
* particular node and repeatedly operate on the same node.
|
||||
*
|
||||
* The way this works is that the off-the-main-thread code has an
|
||||
* nsIContent** for each DOM node and a given nsIContent** is only ever
|
||||
* actually dereferenced into an actual nsIContent* on the main thread.
|
||||
* When the off-the-main-thread code requests a new node, it gets an
|
||||
* nsIContent** immediately and a tree op is enqueued for later allocating
|
||||
* an actual nsIContent object and writing a pointer to it into the memory
|
||||
* location pointed to by the nsIContent**.
|
||||
*
|
||||
* Since tree ops are in a queue, the node creating tree op will always
|
||||
* run before tree ops that try to further operate on the node that the
|
||||
* nsIContent** is a handle to.
|
||||
*
|
||||
* On-the-main-thread parts of the parser use the same mechanism in order
|
||||
* to avoid having to have duplicate code paths for on-the-main-thread and
|
||||
* off-the-main-thread tree builder instances.)
|
||||
*/
|
||||
nsIContent** AllocateContentHandle();
|
||||
|
||||
void accumulateCharactersForced(const PRUnichar* aBuf, PRInt32 aStart, PRInt32 aLength)
|
||||
|
@ -96,4 +119,100 @@
|
|||
|
||||
void DropHandles();
|
||||
|
||||
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
||||
|
||||
void errStrayStartTag(nsIAtom* aName);
|
||||
|
||||
void errStrayEndTag(nsIAtom* aName);
|
||||
|
||||
void errUnclosedElements(PRInt32 aIndex, nsIAtom* aName);
|
||||
|
||||
void errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName);
|
||||
|
||||
void errUnclosedElementsCell(PRInt32 aIndex);
|
||||
|
||||
void errStrayDoctype();
|
||||
|
||||
void errAlmostStandardsDoctype();
|
||||
|
||||
void errQuirkyDoctype();
|
||||
|
||||
void errNonSpaceInTrailer();
|
||||
|
||||
void errNonSpaceAfterFrameset();
|
||||
|
||||
void errNonSpaceInFrameset();
|
||||
|
||||
void errNonSpaceAfterBody();
|
||||
|
||||
void errNonSpaceInColgroupInFragment();
|
||||
|
||||
void errNonSpaceInNoscriptInHead();
|
||||
|
||||
void errFooBetweenHeadAndBody(nsIAtom* aName);
|
||||
|
||||
void errStartTagWithoutDoctype();
|
||||
|
||||
void errNoSelectInTableScope();
|
||||
|
||||
void errStartSelectWhereEndSelectExpected();
|
||||
|
||||
void errStartTagWithSelectOpen(nsIAtom* aName);
|
||||
|
||||
void errBadStartTagInHead(nsIAtom* aName);
|
||||
|
||||
void errImage();
|
||||
|
||||
void errIsindex();
|
||||
|
||||
void errFooSeenWhenFooOpen(nsIAtom* aName);
|
||||
|
||||
void errHeadingWhenHeadingOpen();
|
||||
|
||||
void errFramesetStart();
|
||||
|
||||
void errNoCellToClose();
|
||||
|
||||
void errStartTagInTable(nsIAtom* aName);
|
||||
|
||||
void errFormWhenFormOpen();
|
||||
|
||||
void errTableSeenWhileTableOpen();
|
||||
|
||||
void errStartTagInTableBody(nsIAtom* aName);
|
||||
|
||||
void errEndTagSeenWithoutDoctype();
|
||||
|
||||
void errEndTagAfterBody();
|
||||
|
||||
void errEndTagSeenWithSelectOpen(nsIAtom* aName);
|
||||
|
||||
void errGarbageInColgroup();
|
||||
|
||||
void errEndTagBr();
|
||||
|
||||
void errNoElementToCloseButEndTagSeen(nsIAtom* aName);
|
||||
|
||||
void errHtmlStartTagInForeignContext(nsIAtom* aName);
|
||||
|
||||
void errTableClosedWhileCaptionOpen();
|
||||
|
||||
void errNoTableRowToClose();
|
||||
|
||||
void errNonSpaceInTable();
|
||||
|
||||
void errUnclosedChildrenInRuby();
|
||||
|
||||
void errStartTagSeenWithoutRuby(nsIAtom* aName);
|
||||
|
||||
void errSelfClosing();
|
||||
|
||||
void errNoCheckUnclosedElementsOnStack();
|
||||
|
||||
void errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName, nsIAtom* aOther);
|
||||
|
||||
void errEndTagViolatesNestingRules(nsIAtom* aName);
|
||||
|
||||
void errEndWithUnclosedElements(nsIAtom* aName);
|
||||
|
||||
void MarkAsBroken();
|
||||
|
|
|
@ -893,6 +893,26 @@ nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* a
|
|||
GetParser()->InitializeDocWriteParserState(aState, aLine);
|
||||
}
|
||||
|
||||
nsIURI*
|
||||
nsHtml5TreeOpExecutor::GetViewSourceBaseURI()
|
||||
{
|
||||
if (!mViewSourceBaseURI) {
|
||||
nsCOMPtr<nsIURI> orig = mDocument->GetOriginalURI();
|
||||
bool isViewSource;
|
||||
orig->SchemeIs("view-source", &isViewSource);
|
||||
if (isViewSource) {
|
||||
nsCOMPtr<nsINestedURI> nested = do_QueryInterface(orig);
|
||||
NS_ASSERTION(nested, "URI with scheme view-source didn't QI to nested!");
|
||||
nested->GetInnerURI(getter_AddRefs(mViewSourceBaseURI));
|
||||
} else {
|
||||
// Fail gracefully if the base URL isn't a view-source: URL.
|
||||
// Not sure if this can ever happen.
|
||||
mViewSourceBaseURI = orig;
|
||||
}
|
||||
}
|
||||
return mViewSourceBaseURI;
|
||||
}
|
||||
|
||||
// Speculative loading
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
|
|
|
@ -112,6 +112,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
|||
|
||||
nsCOMPtr<nsIURI> mSpeculationBaseURI;
|
||||
|
||||
nsCOMPtr<nsIURI> mViewSourceBaseURI;
|
||||
|
||||
/**
|
||||
* Whether the parser has started
|
||||
*/
|
||||
|
@ -416,6 +418,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsIURI* GetViewSourceBaseURI();
|
||||
|
||||
void PreloadScript(const nsAString& aURL,
|
||||
const nsAString& aCharset,
|
||||
const nsAString& aType);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче