This commit is contained in:
Kyle Huey 2011-11-01 10:31:53 -04:00
Родитель aa05c7a393 c718393931
Коммит 995d6910c7
117 изменённых файлов: 6150 добавлений и 1721 удалений

Просмотреть файл

@ -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&lt;\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&lt;\u201D.
errLtGt=Saw \u201C<>\u201D. Probable causes: Unescaped \u201C<\u201D (escape as \u201C&lt;\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&amp;\u201D.)
errNotSemicolonTerminated=Named character reference was not terminated by a semicolon. (Or \u201C&\u201D should have been escaped as \u201C&amp;\u201D.)
errNoNamedCharacterMatch=\u201C&\u201D did not start a character reference. (\u201C&\u201D probably should have been escaped as \u201C&amp;\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);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше