From 888d29c9c138ca3d698985f090ceb3db912ade0f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 22 Mar 2010 15:34:41 +1000 Subject: Deprecate inline Script {} blocks Inline blocks/includes have been replaced with an import syntax: import "foo.js" as Foo this gives better separation between QML and code. Imported script blocks also have a mandatory qualifier, which leads to better optimization potential. --- demos/declarative/calculator/calculator.js | 2 +- demos/declarative/calculator/calculator.qml | 4 +- demos/declarative/flickr/flickr-desktop.qml | 28 ++-- demos/declarative/flickr/mobile/GridDelegate.qml | 24 ++-- demos/declarative/flickr/mobile/TitleBar.qml | 14 +- .../photoviewer/PhotoViewerCore/PhotoDelegate.qml | 9 +- .../photoviewer/PhotoViewerCore/script/script.js | 2 + demos/declarative/photoviewer/photoviewer.qml | 2 - .../declarative/samegame/SamegameCore/samegame.js | 5 - demos/declarative/samegame/samegame.qml | 15 +- demos/declarative/snake/content/HighScoreModel.qml | 26 ++-- demos/declarative/snake/snake.qml | 27 ++-- .../webbrowser/content/FlickableWebView.qml | 24 ++-- .../webbrowser/content/fieldtext/FieldText.qml | 38 +++-- examples/declarative/dynamic/qml/PaletteItem.qml | 8 +- examples/declarative/sql/hello.qml | 35 +++-- examples/declarative/tic-tac-toe/tic-tac-toe.qml | 154 +-------------------- examples/declarative/webview/content/FieldText.qml | 38 +++-- .../declarative/webview/content/SpinSquare.qml | 2 +- src/declarative/qml/qdeclarativecompiler.cpp | 47 ++++++- src/declarative/qml/qdeclarativecomponent.cpp | 5 + src/declarative/qml/qdeclarativecomponent_p.h | 2 +- .../qml/qdeclarativecompositetypedata_p.h | 9 ++ .../qml/qdeclarativecompositetypemanager.cpp | 29 ++++ src/declarative/qml/qdeclarativecontext.cpp | 69 +++++++++ src/declarative/qml/qdeclarativecontext_p.h | 2 + .../qml/qdeclarativecontextscriptclass.cpp | 16 ++- src/declarative/qml/qdeclarativeengine.cpp | 6 +- src/declarative/qml/qdeclarativeengine_p.h | 8 +- src/declarative/qml/qdeclarativeinstruction.cpp | 3 + src/declarative/qml/qdeclarativeinstruction_p.h | 1 + src/declarative/qml/qdeclarativeparser_p.h | 9 ++ src/declarative/qml/qdeclarativescriptparser.cpp | 130 ++++++++++++++++- src/declarative/qml/qdeclarativescriptparser_p.h | 4 +- src/declarative/qml/qdeclarativetypenamecache.cpp | 15 ++ src/declarative/qml/qdeclarativetypenamecache_p.h | 4 +- src/declarative/qml/qdeclarativevme.cpp | 13 +- tools/qml/content/Browser.qml | 58 ++++---- 38 files changed, 521 insertions(+), 366 deletions(-) diff --git a/demos/declarative/calculator/calculator.js b/demos/declarative/calculator/calculator.js index cd6490a..f172daf 100644 --- a/demos/declarative/calculator/calculator.js +++ b/demos/declarative/calculator/calculator.js @@ -14,7 +14,7 @@ function disabled(op) { } } -function doOp(op) { +function doOperation(op) { if (disabled(op)) { return; } diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml index 66705e2..1644968 100644 --- a/demos/declarative/calculator/calculator.qml +++ b/demos/declarative/calculator/calculator.qml @@ -1,10 +1,12 @@ import Qt 4.6 +import "calculator.js" as CalcEngine Rectangle { width: 320; height: 270; color: palette.window + function doOp(operation) { CalcEngine.doOperation(operation); } + SystemPalette { id: palette } - Script { source: "calculator.js" } Column { x: 2; spacing: 10; diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index 99216cb..4de2202 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -31,21 +31,19 @@ Item { } } - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoDescription = description; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - wrapper.state = "Details"; - } - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoDescription = description; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + wrapper.state = "Details"; + } Rectangle { id: whiteRect; anchors.fill: parent; color: "white"; radius: 5 diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 291d874..767315c 100644 --- a/demos/declarative/flickr/mobile/GridDelegate.qml +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -5,19 +5,17 @@ Item { id: wrapper; width: 79; height: 79 - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - scaleMe.state = "Details"; - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + scaleMe.state = "Details"; } Item { diff --git a/demos/declarative/flickr/mobile/TitleBar.qml b/demos/declarative/flickr/mobile/TitleBar.qml index 0a06771..e92ba59 100644 --- a/demos/declarative/flickr/mobile/TitleBar.qml +++ b/demos/declarative/flickr/mobile/TitleBar.qml @@ -11,12 +11,10 @@ Item { id: container width: (parent.width * 2) - 55 ; height: parent.height - Script { - function accept() { - titleBar.state = "" - background.state = "" - rssModel.tags = editor.text - } + function accept() { + titleBar.state = "" + background.state = "" + rssModel.tags = editor.text } Text { @@ -32,7 +30,7 @@ Item { Button { id: tagButton; x: titleBar.width - 50; width: 45; height: 32; text: "..." - onClicked: if (titleBar.state == "Tags") accept(); else titleBar.state = "Tags" + onClicked: if (titleBar.state == "Tags") container.accept(); else titleBar.state = "Tags" anchors.verticalCenter: parent.verticalCenter } @@ -57,7 +55,7 @@ Item { Item { id: returnKey - Keys.onReturnPressed: accept() + Keys.onReturnPressed: container.accept() Keys.onEscapePressed: titleBar.state = "" } } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index 89fe3e8..ab36122 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import "script/script.js" as Script Package { Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z } @@ -28,9 +29,9 @@ Package { Rectangle { id: placeHolder - property int w: getWidth(content) - property int h: getHeight(content) - property double s: calculateScale(w, h, photoWrapper.width) + property int w: Script.getWidth(content) + property int h: Script.getHeight(content) + property double s: Script.calculateScale(w, h, photoWrapper.width) color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 width: w * s; height: h * s; visible: originalImage.status != Image.Ready @@ -42,7 +43,7 @@ Package { } BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready } Image { - id: originalImage; smooth: true; source: "http://" + getImagePath(content) + id: originalImage; smooth: true; source: "http://" + Script.getImagePath(content) fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height } Image { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js index ae24ea1..e8ef93a 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js +++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js @@ -1,3 +1,5 @@ +.pragma library + function getWidth(string) { return (string.match(/width=\"([0-9]+)\"/))[1] } diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 02134ac..5e4be4c 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -10,8 +10,6 @@ Rectangle { width: 800; height: 480; color: "#d5d6d8" - Script { source: "PhotoViewerCore/script/script.js" } - ListModel { id: photosModel ListElement { tag: "Flowers" } diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index 1214b79..a119a88 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -22,11 +22,6 @@ function timeStr(msecs) { return ret; } -function getTileSize() -{ - return tileSize; -} - function initBoard() { for(var i = 0; i 0) { @@ -74,9 +72,9 @@ ListModel { } function savePlayerScore(player,score) { - db().transaction( + __db().transaction( function(tx) { - ensureTables(tx); + __ensureTables(tx); tx.executeSql("INSERT INTO HighScores VALUES(?,?,?)", [game,score,player]); fillModel(); } @@ -88,7 +86,7 @@ ListModel { } function clearScores() { - db().transaction( + __db().transaction( function(tx) { tx.executeSql("DELETE FROM HighScores WHERE game=?", [game]); fillModel(); diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index 317c7de..68c2b78 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -1,13 +1,12 @@ import Qt 4.6 import "content" as Content +import "content/snake.js" as Logic Rectangle { id: screen; SystemPalette { id: activePalette } color: activePalette.window - Script { source: "content/snake.js" } - property int gridSize : 34 property int margin: 4 property int numRowsAvailable: Math.floor((height-32-2*margin)/gridSize) @@ -36,19 +35,19 @@ Rectangle { id: heartbeat; interval: heartbeatInterval; repeat: true - onTriggered: { move() } + onTriggered: { Logic.move() } } Timer { id: halfbeat; interval: halfbeatInterval; repeat: true running: heartbeat.running - onTriggered: { moveSkull() } + onTriggered: { Logic.moveSkull() } } Timer { interval: 700; - onTriggered: {startNewGame(); } + onTriggered: { Logic.startNewGame(); } } Timer { @@ -105,13 +104,13 @@ Rectangle { anchors.fill: parent onPressed: { if (!head || !heartbeat.running) { - startNewGame(); + Logic.startNewGame(); return; } if (direction == 0 || direction == 2) - scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); + Logic.scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); else - scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); + Logic.scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); } } } @@ -149,7 +148,7 @@ Rectangle { anchors.bottom: screen.bottom Content.Button { - id: btnA; text: "New Game"; onClicked: {startNewGame();} + id: btnA; text: "New Game"; onClicked: Logic.startNewGame(); anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } @@ -163,11 +162,11 @@ Rectangle { } focus: true - Keys.onSpacePressed: startNewGame(); - Keys.onLeftPressed: if (state == "starting" || direction != 1) scheduleDirection(3); - Keys.onRightPressed: if (state == "starting" || direction != 3) scheduleDirection(1); - Keys.onUpPressed: if (state == "starting" || direction != 2) scheduleDirection(0); - Keys.onDownPressed: if (state == "starting" || direction != 0) scheduleDirection(2); + Keys.onSpacePressed: Logic.startNewGame(); + Keys.onLeftPressed: if (state == "starting" || direction != 1) Logic.scheduleDirection(3); + Keys.onRightPressed: if (state == "starting" || direction != 3) Logic.scheduleDirection(1); + Keys.onUpPressed: if (state == "starting" || direction != 2) Logic.scheduleDirection(0); + Keys.onDownPressed: if (state == "starting" || direction != 0) Logic.scheduleDirection(2); states: [ State { diff --git a/demos/declarative/webbrowser/content/FlickableWebView.qml b/demos/declarative/webbrowser/content/FlickableWebView.qml index 30a5d78..759cff6 100644 --- a/demos/declarative/webbrowser/content/FlickableWebView.qml +++ b/demos/declarative/webbrowser/content/FlickableWebView.qml @@ -25,21 +25,19 @@ Flickable { pixelCacheSize: 4000000 transformOrigin: Item.TopLeft - Script { - function fixUrl(url) - { - if (url == "") return url - if (url[0] == "/") return "file://"+url - if (url.indexOf(":")<0) { - if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { - // Fall back to a search engine; hard-code Wikipedia - return "http://en.wikipedia.org/w/index.php?search="+url - } else { - return "http://"+url - } + function fixUrl(url) + { + if (url == "") return url + if (url[0] == "/") return "file://"+url + if (url.indexOf(":")<0) { + if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { + // Fall back to a search engine; hard-code Wikipedia + return "http://en.wikipedia.org/w/index.php?search="+url + } else { + return "http://"+url } - return url } + return url } url: fixUrl(webBrowser.urlString) diff --git a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml index d282209..1da9219 100644 --- a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml +++ b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/examples/declarative/dynamic/qml/PaletteItem.qml b/examples/declarative/dynamic/qml/PaletteItem.qml index 8a9a9ee..08bdc40 100644 --- a/examples/declarative/dynamic/qml/PaletteItem.qml +++ b/examples/declarative/dynamic/qml/PaletteItem.qml @@ -1,13 +1,13 @@ import Qt 4.6 +import "itemCreation.js" as Code GenericItem { id: itemButton property string file - Script { source: "itemCreation.js" } MouseArea { anchors.fill: parent; - onPressed: startDrag(mouse); - onPositionChanged: moveDrag(mouse); - onReleased: endDrag(mouse); + onPressed: Code.startDrag(mouse); + onPositionChanged: Code.moveDrag(mouse); + onReleased: Code.endDrag(mouse); } } diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml index 277dfeb..29e084c 100644 --- a/examples/declarative/sql/hello.qml +++ b/examples/declarative/sql/hello.qml @@ -1,30 +1,29 @@ import Qt 4.6 Text { - Script { - function findGreetings() { - var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); + function findGreetings() { + var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); - db.transaction( - function(tx) { - // Create the database if it doesn't already exist - tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); + db.transaction( + function(tx) { + // Create the database if it doesn't already exist + tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); - // Add (another) greeting row - tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); + // Add (another) greeting row + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); - // Show all added greetings - var rs = tx.executeSql('SELECT * FROM Greeting'); + // Show all added greetings + var rs = tx.executeSql('SELECT * FROM Greeting'); - var r = "" - for(var i = 0; i < rs.rows.length; i++) { - r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" - } - text = r + var r = "" + for(var i = 0; i < rs.rows.length; i++) { + r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" } - ) - } + text = r + } + ) } + text: "?" Component.onCompleted: findGreetings() } diff --git a/examples/declarative/tic-tac-toe/tic-tac-toe.qml b/examples/declarative/tic-tac-toe/tic-tac-toe.qml index ae187d2..4bb1e3f 100644 --- a/examples/declarative/tic-tac-toe/tic-tac-toe.qml +++ b/examples/declarative/tic-tac-toe/tic-tac-toe.qml @@ -1,5 +1,6 @@ import Qt 4.6 import "content" +import "tic-tac-toe.js" as Logic Item { id: game @@ -29,164 +30,17 @@ Item { height: board.height/3 onClicked: { if (!endtimer.running) { - if (!makeMove(index,"X")) - computerTurn() + if (!Logic.makeMove(index,"X")) + Logic.computerTurn() } } } } - Script { - function winner(board) - { - for (var i=0; i<3; ++i) { - if (board.children[i].state!="" - && board.children[i].state==board.children[i+3].state - && board.children[i].state==board.children[i+6].state) - return true - - if (board.children[i*3].state!="" - && board.children[i*3].state==board.children[i*3+1].state - && board.children[i*3].state==board.children[i*3+2].state) - return true - } - - if (board.children[0].state!="" - && board.children[0].state==board.children[4].state!="" - && board.children[0].state==board.children[8].state!="") - return true - - if (board.children[2].state!="" - && board.children[2].state==board.children[4].state!="" - && board.children[2].state==board.children[6].state!="") - return true - - return false - } - - function restart() - { - // No moves left - start again - for (var i=0; i<9; ++i) - board.children[i].state = "" - } - - function makeMove(pos,player) - { - board.children[pos].state = player - if (winner(board)) { - win(player + " wins") - return true - } else { - return false - } - } - - function computerTurn() - { - var r = Math.random(); - if(r < game.difficulty){ - smartAI(); - }else{ - randAI(); - } - } - - function smartAI() - { - function boardCopy(a){ - var ret = new Object; - ret.children = new Array(9); - for(var i = 0; i<9; i++){ - ret.children[i] = new Object; - ret.children[i].state = a.children[i].state; - } - return ret; - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "O"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "X"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - function thwart(a,b,c){//If they are at a, try b or c - if (board.children[a].state == "X") { - if (board.children[b].state == "") { - makeMove(b,"O") - return true - }else if (board.children[c].state == "") { - makeMove(c,"O") - return true - } - } - return false; - } - if(thwart(4,0,2)) return; - if(thwart(0,4,3)) return; - if(thwart(2,4,1)) return; - if(thwart(6,4,7)) return; - if(thwart(8,4,5)) return; - if(thwart(1,4,2)) return; - if(thwart(3,4,0)) return; - if(thwart(5,4,8)) return; - if(thwart(7,4,6)) return; - for(var i =0; i<9; i++){//Backup - if (board.children[i].state == "") { - makeMove(i,"O") - return - } - } - restart(); - } - - function randAI() - { - var open = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - open += 1; - } - if(open == 0){ - restart(); - return; - } - var openA = new Array(open);//JS doesn't have lists I can append to (i think) - var acc = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - openA[acc] = i; - acc += 1; - } - var choice = openA[Math.floor(Math.random() * open)]; - makeMove(choice, "O"); - } - - function win(s) - { - msg.text = s - msg.opacity = 1 - endtimer.running = true - } - } - Timer { id: endtimer interval: 1600 - onTriggered: { msg.opacity = 0; restart() } + onTriggered: { msg.opacity = 0; Logic.restart() } } } diff --git a/examples/declarative/webview/content/FieldText.qml b/examples/declarative/webview/content/FieldText.qml index d282209..1da9219 100644 --- a/examples/declarative/webview/content/FieldText.qml +++ b/examples/declarative/webview/content/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index 466c99e..b65a29d 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -15,7 +15,7 @@ Item { width: root.width height: width } - rotation: NumberAnimation { + NumberAnimation on rotation { from: 0 to: 360 repeat: true diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 103e918..28c2210 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -542,8 +542,8 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) on a successful compiler. */ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, - QDeclarativeCompositeTypeData *unit, - QDeclarativeCompiledData *out) + QDeclarativeCompositeTypeData *unit, + QDeclarativeCompiledData *out) { exceptions.clear(); @@ -633,6 +633,37 @@ void QDeclarativeCompiler::compileTree(Object *tree) init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); output->bytecode << init; + // Build global import scripts + QHash importedScripts; + QStringList importedScriptIndexes; + + for (int ii = 0; ii < unit->scripts.count(); ++ii) { + QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data); + Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode); + + if (!scriptCode.isEmpty()) { + Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier]; + + scriptBlock.codes.append(scriptCode); + scriptBlock.lineNumbers.append(1); + scriptBlock.files.append(unit->scripts.at(ii).resource->url); + scriptBlock.pragmas.append(pragmas); + } + } + + for (QHash::Iterator iter = importedScripts.begin(); + iter != importedScripts.end(); ++iter) { + + importedScriptIndexes.append(iter.key()); + + QDeclarativeInstruction import; + import.type = QDeclarativeInstruction::StoreImportedScript; + import.line = 0; + import.storeScript.value = output->scripts.count(); + output->scripts << *iter; + output->bytecode << import; + } + genObject(tree); QDeclarativeInstruction def; @@ -641,7 +672,13 @@ void QDeclarativeCompiler::compileTree(Object *tree) output->bytecode << def; output->imports = unit->imports; - output->importCache = output->imports.cache(engine); + + output->importCache = new QDeclarativeTypeNameCache(engine); + + for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) + output->importCache->add(importedScriptIndexes.at(ii), ii); + + output->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -1153,6 +1190,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script) { + qWarning().nospace() << qPrintable(output->url.toString()) << ":" << obj->location.start.line << ":" << obj->location.start.column << ": Script blocks have been deprecated. Support will be removed entirely shortly."; + Object::ScriptBlock scriptBlock; if (script->properties.count() == 1 && @@ -1184,6 +1223,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } @@ -1226,6 +1266,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index ec595e3..ec23458 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -612,6 +612,11 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons 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); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 649fce5..b44aeef 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -116,7 +116,7 @@ public: static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContextData *creationContext; + QDeclarativeGuardedContextData creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h index fb26af9..04d0c63 100644 --- a/src/declarative/qml/qdeclarativecompositetypedata_p.h +++ b/src/declarative/qml/qdeclarativecompositetypedata_p.h @@ -103,7 +103,16 @@ public: QDeclarativeCompositeTypeData *unit; }; + struct ScriptReference + { + ScriptReference(); + + QString qualifier; + QDeclarativeCompositeTypeResource *resource; + }; + QList types; + QList scripts; QList resources; // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index ebf1f40..c883805 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -126,6 +126,27 @@ QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine) { if (status == Complete && !compiledComponent) { + // Build script imports + foreach (const QDeclarativeScriptParser::Import &import, data.imports()) { + if (import.type == QDeclarativeScriptParser::Import::Script) { + QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString(); + + ScriptReference ref; + ref.qualifier = import.qualifier; + + for (int ii = 0; ii < resources.count(); ++ii) { + if (resources.at(ii)->url == url) { + ref.resource = resources.at(ii); + break; + } + } + + Q_ASSERT(ref.resource); + + scripts << ref; + } + } + compiledComponent = new QDeclarativeCompiledData(engine); compiledComponent->url = imports.baseUrl(); compiledComponent->name = compiledComponent->url.toString(); @@ -153,6 +174,11 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() { } +QDeclarativeCompositeTypeData::ScriptReference::ScriptReference() +: resource(0) +{ +} + QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) : engine(e), redirectCount(0) { @@ -514,6 +540,9 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { QDeclarativeDirComponents qmldircomponentsnetwork; + if (imp.type == QDeclarativeScriptParser::Import::Script) + continue; + if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 782c0d7..85896c4 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -606,6 +606,75 @@ void QDeclarativeContextData::addObject(QObject *o) contextObjects = data; } +void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) +{ + if (!engine) + return; + + Q_ASSERT(script.codes.count() == 1); + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + const QString &code = script.codes.at(0); + const QString &url = script.files.at(0); + const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas.at(0); + + Q_ASSERT(!url.isEmpty()); + + if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { + + QHash::Iterator iter = enginePriv->m_sharedScriptImports.find(url); + if (iter == enginePriv->m_sharedScriptImports.end()) { + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + iter = enginePriv->m_sharedScriptImports.insert(url, scope); + } + + importedScripts.append(*iter); + + } else { + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, 0)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + importedScripts.append(scope); + + } +} + void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) { diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index d74aa33..ecf3ec8 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -141,6 +141,8 @@ public: // Any script blocks that exist on this context QList scripts; + QList importedScripts; + void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script); void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); // Context base url diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 847d632..2559224 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -240,10 +240,19 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { - if (lastData->type) + if (lastData->type) { return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); - else - return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); + } else if (lastData->typeNamespace) { + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, + lastData->typeNamespace)); + } else { + int index = lastData->importedScriptIndex; + if (index < bindContext->importedScripts.count()) { + return Value(scriptEngine, bindContext->importedScripts.at(index)); + } else { + return Value(); + } + } } else if (lastPropertyIndex != -1) { @@ -266,7 +275,6 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } - return Value(scriptEngine, rv); } else { diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 5820961..0bedbeb 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1695,12 +1695,10 @@ static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, return cache; } -QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativeEngine *engine) const +void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const { const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - QDeclarativeTypeNameCache *cache = new QDeclarativeTypeNameCache(engine); - for (QHash::ConstIterator iter = d->set.begin(); iter != d->set.end(); ++iter) { @@ -1716,8 +1714,6 @@ QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativ } cacheForNamespace(engine, set, cache); - - return cache; } /* diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 4ab619e..6532d30 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -264,7 +264,7 @@ public: void setBaseUrl(const QUrl& url); QUrl baseUrl() const; - QDeclarativeTypeNameCache *cache(QDeclarativeEngine *) const; + void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; private: friend class QDeclarativeEnginePrivate; @@ -281,7 +281,9 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri, const QString& prefix, int vmaj, int vmin, + QDeclarativeScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -303,6 +305,8 @@ public: QHash m_qmlLists; QHash m_compositeTypes; + QHash m_sharedScriptImports; + QScriptValue scriptValueFromVariant(const QVariant &); QVariant scriptValueToVariant(const QScriptValue &); diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index a23ff75..9083ab3 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -144,6 +144,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreScript: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value; break; + case QDeclarativeInstruction::StoreImportedScript: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; + break; case QDeclarativeInstruction::StoreScriptString: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; break; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index ec32b35..877179d 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -119,6 +119,7 @@ public: StoreSignal, /* storeSignal */ StoreScript, /* storeScript */ + StoreImportedScript, /* storeScript */ StoreScriptString, /* storeScriptString */ // diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 9dfb86b..476b027 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -179,9 +179,16 @@ namespace QDeclarativeParser // Script blocks that were nested under this object struct ScriptBlock { + enum Pragma { + None = 0x00000000, + Shared = 0x00000001 + }; + Q_DECLARE_FLAGS(Pragmas, Pragma) + QStringList codes; QStringList files; QList lineNumbers; + QList pragmas; }; QList scripts; @@ -360,6 +367,8 @@ namespace QDeclarativeParser }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QDeclarativeParser::Variant) diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 2578ff4..49bd3b7 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -441,8 +441,14 @@ bool ProcessAST::visit(AST::UiImport *node) QDeclarativeScriptParser::Import import; if (node->fileName) { - import.type = QDeclarativeScriptParser::Import::File; uri = node->fileName->asString(); + + if (uri.endsWith(QLatin1String(".js"))) { + import.type = QDeclarativeScriptParser::Import::Script; + _parser->_refUrls << QUrl(uri); + } else { + import.type = QDeclarativeScriptParser::Import::File; + } } else { import.type = QDeclarativeScriptParser::Import::Library; uri = asString(node->importUri); @@ -451,6 +457,7 @@ bool ProcessAST::visit(AST::UiImport *node) AST::SourceLocation startLoc = node->importToken; AST::SourceLocation endLoc = node->semicolonToken; + // Qualifier if (node->importId) { import.qualifier = node->importId->asString(); if (!import.qualifier.at(0).isUpper()) { @@ -461,17 +468,43 @@ bool ProcessAST::visit(AST::UiImport *node) _parser->_errors << error; return false; } + + // Check for script qualifier clashes + bool isScript = import.type == QDeclarativeScriptParser::Import::Script; + for (int ii = 0; ii < _parser->_imports.count(); ++ii) { + const QDeclarativeScriptParser::Import &other = _parser->_imports.at(ii); + bool otherIsScript = other.type == QDeclarativeScriptParser::Import::Script; + + if ((isScript || otherIsScript) && import.qualifier == other.qualifier) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import qualifiers must be unique.")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; + } + } + + } else if (import.type == QDeclarativeScriptParser::Import::Script) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; } - if (node->versionToken.isValid()) + + if (node->versionToken.isValid()) { import.version = textAt(node->versionToken); - else if (import.type == QDeclarativeScriptParser::Import::Library) { + } else if (import.type == QDeclarativeScriptParser::Import::Library) { QDeclarativeError error; error.setDescription(QCoreApplication::translate("QDeclarativeParser","Library import requires a version")); error.setLine(node->importIdToken.startLine); error.setColumn(node->importIdToken.startColumn); _parser->_errors << error; return false; - } + } + import.location = location(startLoc, endLoc); import.uri = uri; @@ -934,6 +967,95 @@ QList QDeclarativeScriptParser::errors() const return _errors; } +/* +Searches for ".pragma " declarations within \a script. Currently supported pragmas +are: + library +*/ +QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extractPragmas(QString &script) +{ + QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None; + + const QChar forwardSlash(QLatin1Char('/')); + const QChar star(QLatin1Char('*')); + const QChar newline(QLatin1Char('\n')); + const QChar dot(QLatin1Char('.')); + const QChar semicolon(QLatin1Char(';')); + const QChar space(QLatin1Char(' ')); + const QString pragma(QLatin1String(".pragma ")); + + const QChar *pragmaData = pragma.constData(); + + const QChar *data = script.constData(); + const int length = script.count(); + for (int ii = 0; ii < length; ++ii) { + const QChar &c = data[ii]; + + if (c.isSpace()) + continue; + + if (c == forwardSlash) { + ++ii; + if (ii >= length) + return rv; + + const QChar &c = data[ii]; + if (c == forwardSlash) { + // Find next newline + while (ii < length && data[++ii] != newline) {}; + } else if (c == star) { + // Find next star + while (true) { + while (ii < length && data[++ii] != star) {}; + if (ii + 1 >= length) + return rv; + + if (data[ii + 1] == forwardSlash) { + ++ii; + break; + } + } + } else { + return rv; + } + } else if (c == dot) { + // Could be a pragma! + if (ii + pragma.length() >= length || + 0 != ::memcmp(data + ii, pragmaData, sizeof(QChar) * pragma.length())) + return rv; + + int pragmaStatementIdx = ii; + + ii += pragma.length(); + + while (ii < length && data[ii].isSpace()) { ++ii; } + + int startIdx = ii; + + while (ii < length && data[ii].isLetter()) { ++ii; } + + int endIdx = ii; + + if (ii != length && data[ii] != forwardSlash && !data[ii].isSpace() && data[ii] != semicolon) + return rv; + + QString p(data + startIdx, endIdx - startIdx); + + if (p == QLatin1String("library")) + rv |= QDeclarativeParser::Object::ScriptBlock::Shared; + else + return rv; + + for (int jj = pragmaStatementIdx; jj < endIdx; ++jj) script[jj] = space; + + } else { + return rv; + } + } + + return rv; +} + void QDeclarativeScriptParser::clear() { if (root) { diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h index b8f77d1..68f1840 100644 --- a/src/declarative/qml/qdeclarativescriptparser_p.h +++ b/src/declarative/qml/qdeclarativescriptparser_p.h @@ -75,7 +75,7 @@ public: public: Import() : type(Library) {} - enum Type { Library, File }; + enum Type { Library, File, Script }; Type type; QString uri; @@ -112,6 +112,8 @@ public: QList errors() const; + static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &); + // ### private: TypeReference *findOrCreateType(const QString &name); void setTree(QDeclarativeParser::Object *tree); diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp index f94f944..c4a8707 100644 --- a/src/declarative/qml/qdeclarativetypenamecache.cpp +++ b/src/declarative/qml/qdeclarativetypenamecache.cpp @@ -63,6 +63,21 @@ void QDeclarativeTypeNameCache::clear() engine = 0; } +void QDeclarativeTypeNameCache::add(const QString &name, int importedScriptIndex) +{ + if (stringCache.contains(name)) + return; + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + + RData *data = new RData; + // ### Use typename class + data->identifier = ep->objectClass->createPersistentIdentifier(name); + data->importedScriptIndex = importedScriptIndex; + stringCache.insert(name, data); + identifierCache.insert(data->identifier.identifier, data); +} + void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeType *type) { if (stringCache.contains(name)) diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h index eee5b77..3e24f5c 100644 --- a/src/declarative/qml/qdeclarativetypenamecache_p.h +++ b/src/declarative/qml/qdeclarativetypenamecache_p.h @@ -73,8 +73,10 @@ public: inline ~Data(); QDeclarativeType *type; QDeclarativeTypeNameCache *typeNamespace; + int importedScriptIndex; }; + void add(const QString &, int); void add(const QString &, QDeclarativeType *); void add(const QString &, QDeclarativeTypeNameCache *); @@ -97,7 +99,7 @@ private: }; QDeclarativeTypeNameCache::Data::Data() -: type(0), typeNamespace(0) +: type(0), typeNamespace(0), importedScriptIndex(-1) { } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index b3144a8..2338bc3 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -259,8 +259,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, - stack.isEmpty() ? 0 : stack.top()); + QDeclarativeComponent *qcomp = + new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); @@ -275,6 +276,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; + QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt; + stack.push(qcomp); ii += instr.createComponent.count; } @@ -581,6 +584,12 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, } break; + case QDeclarativeInstruction::StoreImportedScript: + { + ctxt->addImportedScript(scripts.at(instr.storeScript.value)); + } + break; + case QDeclarativeInstruction::StoreScriptString: { QObject *target = stack.top(); diff --git a/tools/qml/content/Browser.qml b/tools/qml/content/Browser.qml index 62996ef..391ded8 100644 --- a/tools/qml/content/Browser.qml +++ b/tools/qml/content/Browser.qml @@ -22,38 +22,36 @@ Rectangle { SystemPalette { id: palette } - Script { - function down(path) { - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitLeft"; - } else { - view = view1 - folders = folders1; - view2.state = "exitLeft"; - } - view.x = root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + function down(path) { + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitLeft"; + } else { + view = view1 + folders = folders1; + view2.state = "exitLeft"; } - function up() { - var path = folders.parentFolder; - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitRight"; - } else { - view = view1 - folders = folders1; - view2.state = "exitRight"; - } - view.x = -root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + view.x = root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; + } + function up() { + var path = folders.parentFolder; + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitRight"; + } else { + view = view1 + folders = folders1; + view2.state = "exitRight"; } + view.x = -root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; } Component { -- cgit v0.12