mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1309630 - Use a request to stop transforming. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D134250
This commit is contained in:
parent
37df566280
commit
bc9819f41c
@ -395,7 +395,12 @@ txExecutionState::TemplateRule* txExecutionState::getCurrentTemplateRule() {
|
||||
return &mTemplateRules[mTemplateRules.Length() - 1];
|
||||
}
|
||||
|
||||
txInstruction* txExecutionState::getNextInstruction() {
|
||||
mozilla::Result<txInstruction*, nsresult>
|
||||
txExecutionState::getNextInstruction() {
|
||||
if (mStopProcessing) {
|
||||
return mozilla::Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
txInstruction* instr = mNextInstruction;
|
||||
if (instr) {
|
||||
mNextInstruction = instr->mNext.get();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "txStylesheet.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Result.h"
|
||||
|
||||
class txAOutputHandlerFactory;
|
||||
class txAXMLEventHandler;
|
||||
@ -115,13 +116,14 @@ class txExecutionState : public txIMatchContext {
|
||||
}
|
||||
|
||||
// state-modification functions
|
||||
txInstruction* getNextInstruction();
|
||||
mozilla::Result<txInstruction*, nsresult> getNextInstruction();
|
||||
nsresult runTemplate(txInstruction* aInstruction);
|
||||
nsresult runTemplate(txInstruction* aInstruction, txInstruction* aReturnTo);
|
||||
void gotoInstruction(txInstruction* aNext);
|
||||
void returnFromTemplate();
|
||||
nsresult bindVariable(const txExpandedName& aName, txAExprResult* aValue);
|
||||
void removeVariable(const txExpandedName& aName);
|
||||
void stopProcessing() { mStopProcessing = true; }
|
||||
|
||||
txAXMLEventHandler* mOutputHandler;
|
||||
txAXMLEventHandler* mResultHandler;
|
||||
@ -156,6 +158,7 @@ class txExecutionState : public txIMatchContext {
|
||||
txKeyHash mKeyHash;
|
||||
RefPtr<txResultRecycler> mRecycler;
|
||||
bool mDisableLoads;
|
||||
bool mStopProcessing = false;
|
||||
|
||||
static const int32_t kMaxRecursionDepth;
|
||||
};
|
||||
|
@ -538,6 +538,79 @@ already_AddRefed<Document> txMozillaXSLTProcessor::TransformToDocument(
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
class XSLTProcessRequest final : public nsIRequest {
|
||||
public:
|
||||
explicit XSLTProcessRequest(txExecutionState* aState) : mState(aState) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
|
||||
void Done() { mState = nullptr; }
|
||||
|
||||
private:
|
||||
~XSLTProcessRequest() {}
|
||||
txExecutionState* mState;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(XSLTProcessRequest, nsIRequest)
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::GetName(nsACString& aResult) {
|
||||
aResult.AssignLiteral("about:xslt-load-blocker");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::IsPending(bool* _retval) {
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::GetStatus(nsresult* status) {
|
||||
*status = NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::Cancel(nsresult status) {
|
||||
mState->stopProcessing();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::Suspend(void) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::Resume(void) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::GetLoadGroup(nsILoadGroup** aLoadGroup) {
|
||||
*aLoadGroup = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::SetLoadGroup(nsILoadGroup* aLoadGroup) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::GetLoadFlags(nsLoadFlags* aLoadFlags) {
|
||||
*aLoadFlags = nsIRequest::LOAD_NORMAL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
|
||||
return GetTRRModeImpl(aTRRMode);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XSLTProcessRequest::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
|
||||
return SetTRRModeImpl(aTRRMode);
|
||||
}
|
||||
|
||||
nsresult txMozillaXSLTProcessor::TransformToDoc(Document** aResult,
|
||||
bool aCreateDataDocument) {
|
||||
UniquePtr<txXPathNode> sourceNode(
|
||||
@ -548,10 +621,29 @@ nsresult txMozillaXSLTProcessor::TransformToDoc(Document** aResult,
|
||||
|
||||
txExecutionState es(mStylesheet, IsLoadDisabled());
|
||||
|
||||
Document* sourceDoc = mSource->OwnerDoc();
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = sourceDoc->GetDocumentLoadGroup();
|
||||
if (!loadGroup) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(mOwner);
|
||||
if (win && win->IsCurrentInnerWindow()) {
|
||||
Document* doc = win->GetDoc();
|
||||
if (doc) {
|
||||
loadGroup = doc->GetDocumentLoadGroup();
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadGroup) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<XSLTProcessRequest> xsltProcessRequest = new XSLTProcessRequest(&es);
|
||||
loadGroup->AddRequest(xsltProcessRequest, nullptr);
|
||||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// If aResult is non-null, we're a data document
|
||||
txToDocHandlerFactory handlerFactory(&es, mSource->OwnerDoc(), mObserver,
|
||||
txToDocHandlerFactory handlerFactory(&es, sourceDoc, mObserver,
|
||||
aCreateDataDocument);
|
||||
es.mOutputHandlerFactory = &handlerFactory;
|
||||
|
||||
@ -562,6 +654,9 @@ nsresult txMozillaXSLTProcessor::TransformToDoc(Document** aResult,
|
||||
rv = txXSLTProcessor::execute(es);
|
||||
}
|
||||
|
||||
xsltProcessRequest->Done();
|
||||
loadGroup->RemoveRequest(xsltProcessRequest, nullptr, NS_OK);
|
||||
|
||||
nsresult endRv = es.end(rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = endRv;
|
||||
|
@ -31,12 +31,20 @@ void txXSLTProcessor::shutdown() { txHandlerTable::shutdown(); }
|
||||
|
||||
/* static */
|
||||
nsresult txXSLTProcessor::execute(txExecutionState& aEs) {
|
||||
nsresult rv = NS_OK;
|
||||
txInstruction* instr;
|
||||
while ((instr = aEs.getNextInstruction())) {
|
||||
rv = instr->execute(aEs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsresult rv;
|
||||
do {
|
||||
mozilla::Result<txInstruction*, nsresult> result = aEs.getNextInstruction();
|
||||
if (result.isErr()) {
|
||||
return result.unwrapErr();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
txInstruction* instr = result.unwrap();
|
||||
if (!instr) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = instr->execute(aEs);
|
||||
} while (NS_SUCCEEDED(rv));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user