void QV8Include::finished() { m_redirectCount++; if (m_redirectCount < INCLUDE_MAXIMUM_REDIRECT_RECURSION) { QVariant redirect = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirect.isValid()) { m_url = m_url.resolved(redirect.toUrl()); delete m_reply; QNetworkRequest request; request.setUrl(m_url); m_reply = m_network->get(request); QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); return; } } v8::HandleScope handle_scope; if (m_reply->error() == QNetworkReply::NoError) { QByteArray data = m_reply->readAll(); QString code = QString::fromUtf8(data); QDeclarativeScriptParser::extractPragmas(code); QDeclarativeContextData *importContext = new QDeclarativeContextData; importContext->isInternal = true; importContext->isJSContext = true; importContext->url = m_url; importContext->isPragmaLibraryContext = m_context->isPragmaLibraryContext; importContext->setParent(m_context, true); v8::Context::Scope ctxtscope(m_engine->context()); v8::TryCatch try_catch; v8::Local<v8::Script> script = m_engine->qmlModeCompile(code, m_url.toString()); if (!try_catch.HasCaught()) { m_engine->contextWrapper()->addSubContext(m_qmlglobal, script, importContext); script->Run(m_qmlglobal); } if (try_catch.HasCaught()) { m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Exception)); m_resultObject->Set(v8::String::New("exception"), try_catch.Exception()); } else { m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Ok)); } } else { m_resultObject->Set(v8::String::New("status"), v8::Integer::New(NetworkError)); } callback(m_engine, m_callbackFunction, m_resultObject); disconnect(); deleteLater(); }
QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentContext, QDeclarativeContextData *componentCreationContext, QDeclarativeCompiledData *component, int start, int count, ConstructionState *state, QList<QDeclarativeError> *errors) { QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(parentContext->engine); bool isRoot = !enginePriv->inBeginCreate; Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided QDeclarativeContextData *ctxt = new QDeclarativeContextData; ctxt->isInternal = true; ctxt->url = component->url; ctxt->imports = component->importCache; // Nested global imports if (componentCreationContext && start != -1) ctxt->importedScripts = componentCreationContext->importedScripts; component->importCache->addref(); ctxt->setParent(parentContext); enginePriv->inBeginCreate = true; QDeclarativeVME vme; QObject *rv = vme.run(ctxt, component, start, count); if (vme.isError()) { if(errors) *errors = vme.errors(); else state->errors = vme.errors(); } if (isRoot) { enginePriv->inBeginCreate = false; state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } return rv; }
QObject * QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings) { Q_Q(QDeclarativeComponent); if (!context) { qWarning("QDeclarativeComponent: Cannot create a component in a null context"); return 0; } if (!context->isValid()) { qWarning("QDeclarativeComponent: Cannot create a component in an invalid context"); return 0; } if (context->engine != engine) { qWarning("QDeclarativeComponent: Must create component in context from the same QDeclarativeEngine"); return 0; } if (state.completePending) { qWarning("QDeclarativeComponent: Cannot create new component instance before completing the previous"); return 0; } if (!q->isReady()) { qWarning("QDeclarativeComponent: Component is not ready"); return 0; } QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QDeclarativeContextData *ctxt = new QDeclarativeContextData; ctxt->isInternal = true; ctxt->url = cc->url; ctxt->imports = cc->importCache; // Nested global imports if (creationContext && start != -1) ctxt->importedScripts = creationContext->importedScripts; cc->importCache->addref(); ctxt->setParent(context); QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); if (rv && !context->isInternal && ep->isDebugging) context->asQDeclarativeContextPrivate()->instances.append(rv); return rv; }
/* Documented in qv8engine.cpp */ v8::Handle<v8::Value> QV8Include::include(const v8::Arguments &args) { if (args.Length() == 0) return v8::Undefined(); QV8Engine *engine = V8ENGINE(); QDeclarativeContextData *context = engine->callingContext(); if (!context || !context->isJSContext) V8THROW_ERROR("Qt.include(): Can only be called from JavaScript files"); QUrl url(context->resolvedUrl(QUrl(engine->toString(args[0]->ToString())))); v8::Local<v8::Function> callbackFunction; if (args.Length() >= 2 && args[1]->IsFunction()) callbackFunction = v8::Local<v8::Function>::Cast(args[1]); QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url); v8::Local<v8::Object> result; if (localFile.isEmpty()) { QV8Include *i = new QV8Include(url, engine, context, v8::Context::GetCallingQmlGlobal(), callbackFunction); result = v8::Local<v8::Object>::New(i->result()); } else { QFile f(localFile); if (f.open(QIODevice::ReadOnly)) { QByteArray data = f.readAll(); QString code = QString::fromUtf8(data); QDeclarativeScriptParser::extractPragmas(code); QDeclarativeContextData *importContext = new QDeclarativeContextData; importContext->isInternal = true; importContext->isJSContext = true; importContext->url = url; importContext->setParent(context, true); v8::TryCatch try_catch; v8::Local<v8::Script> script = engine->qmlModeCompile(code, url.toString()); if (!try_catch.HasCaught()) { v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal(); engine->contextWrapper()->addSubContext(qmlglobal, script, importContext); script->Run(qmlglobal); } if (try_catch.HasCaught()) { result = resultValue(Exception); result->Set(v8::String::New("exception"), try_catch.Exception()); } else { result = resultValue(Ok); } } else { result = resultValue(NetworkError); } callback(engine, callbackFunction, result); } if (result.IsEmpty()) return v8::Undefined(); else return result; }