nsresult txStylesheet::doneCompiling() { nsresult rv = NS_OK; // Collect all importframes into a single ordered list txListIterator frameIter(&mImportFrames); rv = frameIter.addAfter(mRootFrame); NS_ENSURE_SUCCESS(rv, rv); mRootFrame = nullptr; frameIter.next(); rv = addFrames(frameIter); NS_ENSURE_SUCCESS(rv, rv); // Loop through importframes in decreasing-precedence-order and process // all items frameIter.reset(); ImportFrame* frame; while ((frame = static_cast<ImportFrame*>(frameIter.next()))) { nsTArray<txStripSpaceTest*> frameStripSpaceTests; txListIterator itemIter(&frame->mToplevelItems); itemIter.resetToEnd(); txToplevelItem* item; while ((item = static_cast<txToplevelItem*>(itemIter.previous()))) { switch (item->getType()) { case txToplevelItem::attributeSet: { rv = addAttributeSet(static_cast<txAttributeSetItem*> (item)); NS_ENSURE_SUCCESS(rv, rv); break; } case txToplevelItem::dummy: case txToplevelItem::import: { break; } case txToplevelItem::output: { mOutputFormat.merge(static_cast<txOutputItem*>(item)->mFormat); break; } case txToplevelItem::stripSpace: { rv = addStripSpace(static_cast<txStripSpaceItem*>(item), frameStripSpaceTests); NS_ENSURE_SUCCESS(rv, rv); break; } case txToplevelItem::templ: { rv = addTemplate(static_cast<txTemplateItem*>(item), frame); NS_ENSURE_SUCCESS(rv, rv); break; } case txToplevelItem::variable: { rv = addGlobalVariable(static_cast<txVariableItem*> (item)); NS_ENSURE_SUCCESS(rv, rv); break; } } delete item; itemIter.remove(); //remove() moves to the previous itemIter.next(); } if (!mStripSpaceTests.AppendElements(frameStripSpaceTests)) { return NS_ERROR_OUT_OF_MEMORY; } frameStripSpaceTests.Clear(); } if (!mDecimalFormats.get(txExpandedName())) { nsAutoPtr<txDecimalFormat> format(new txDecimalFormat); NS_ENSURE_TRUE(format, NS_ERROR_OUT_OF_MEMORY); rv = mDecimalFormats.add(txExpandedName(), format); NS_ENSURE_SUCCESS(rv, rv); format.forget(); } return NS_OK; }
nsresult txPushNullTemplateRule::execute(txExecutionState& aEs) { aEs.pushTemplateRule(nullptr, txExpandedName(), nullptr); return NS_OK; }
nsresult txExecutionState::getVariable(int32_t aNamespace, nsIAtom* aLName, txAExprResult*& aResult) { nsresult rv = NS_OK; txExpandedName name(aNamespace, aLName); // look for a local variable if (mLocalVariables) { mLocalVariables->getVariable(name, &aResult); if (aResult) { return NS_OK; } } // look for an evaluated global variable mGlobalVariableValues.getVariable(name, &aResult); if (aResult) { if (aResult == mGlobalVarPlaceholderValue) { // XXX ErrorReport: cyclic variable-value NS_RELEASE(aResult); return NS_ERROR_XSLT_BAD_RECURSION; } return NS_OK; } // Is there perchance a global variable not evaluated yet? txStylesheet::GlobalVariable* var = mStylesheet->getGlobalVariable(name); if (!var) { // XXX ErrorReport: variable doesn't exist in this scope return NS_ERROR_FAILURE; } NS_ASSERTION((var->mExpr && !var->mFirstInstruction) || (!var->mExpr && var->mFirstInstruction), "global variable should have either instruction or expression"); // Is this a stylesheet parameter that has a value? if (var->mIsParam && mGlobalParams) { txIGlobalParameter* param = mGlobalParams->get(name); if (param) { rv = param->getValue(&aResult); NS_ENSURE_SUCCESS(rv, rv); rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { NS_RELEASE(aResult); return rv; } return NS_OK; } } // Insert a placeholdervalue to protect against recursion rv = mGlobalVariableValues.bindVariable(name, mGlobalVarPlaceholderValue); NS_ENSURE_SUCCESS(rv, rv); // evaluate the global variable pushEvalContext(mInitialEvalContext); if (var->mExpr) { txVariableMap* oldVars = mLocalVariables; mLocalVariables = nullptr; rv = var->mExpr->evaluate(getEvalContext(), &aResult); mLocalVariables = oldVars; if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } } else { nsAutoPtr<txRtfHandler> rtfHandler(new txRtfHandler); rv = pushResultHandler(rtfHandler); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } rtfHandler.forget(); txInstruction* prevInstr = mNextInstruction; // set return to nullptr to stop execution mNextInstruction = nullptr; rv = runTemplate(var->mFirstInstruction); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } pushTemplateRule(nullptr, txExpandedName(), nullptr); rv = txXSLTProcessor::execute(*this); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } popTemplateRule(); mNextInstruction = prevInstr; rtfHandler = (txRtfHandler*)popResultHandler(); rv = rtfHandler->getAsRTF(&aResult); if (NS_FAILED(rv)) { popAndDeleteEvalContextUntil(mInitialEvalContext); return rv; } } popEvalContext(); // Remove the placeholder and insert the calculated value mGlobalVariableValues.removeVariable(name); rv = mGlobalVariableValues.bindVariable(name, aResult); if (NS_FAILED(rv)) { NS_RELEASE(aResult); return rv; } return NS_OK; }
nsresult txPushNullTemplateRule::execute(txExecutionState& aEs) { return aEs.pushTemplateRule(nsnull, txExpandedName(), nsnull); }