diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index 09a775c169e..e06cbce65ef 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart @@ -30324,8 +30324,8 @@ class RtcPeerConnection extends EventTarget { var completer = new Completer(); _setLocalDescription(description, () { completer.complete(); - }, (error) { - completer.completeError(error); + }, (exception) { + completer.completeError(exception); }); return completer.future; } @@ -30344,8 +30344,8 @@ class RtcPeerConnection extends EventTarget { var completer = new Completer(); _setRemoteDescription(description, () { completer.complete(); - }, (error) { - completer.completeError(error); + }, (exception) { + completer.completeError(exception); }); return completer.future; } @@ -37965,19 +37965,6 @@ class Window extends EventTarget @DocsEditable() void _moveTo(int x, int y) native; - /// *Deprecated.* - @DomName('Window.openDatabase') - @DocsEditable() - @SupportedBrowser(SupportedBrowser.CHROME) - @SupportedBrowser(SupportedBrowser.SAFARI) - @Experimental() - // http://www.w3.org/TR/webdatabase/ - @Experimental() // deprecated - @Creates('SqlDatabase') - SqlDatabase openDatabase( - String name, String version, String displayName, int estimatedSize, - [DatabaseCallback creationCallback]) native; - @DomName('Window.postMessage') @DocsEditable() void postMessage(/*any*/ message, String targetOrigin, @@ -38921,6 +38908,28 @@ class Window extends EventTarget _moveTo(p.x, p.y); } + @JSName('openDatabase') + @DomName('Window.openDatabase') + SqlDatabase _openDatabase( + String name, String version, String displayName, int estimatedSize, + [DatabaseCallback creationCallback]) native; + + @JSName('openDatabase') + @DomName('Window.openDatabase') + @DocsEditable() + @SupportedBrowser(SupportedBrowser.CHROME) + @SupportedBrowser(SupportedBrowser.SAFARI) + @Experimental() + @Creates('SqlDatabase') + SqlDatabase openDatabase( + String name, String version, String displayName, int estimatedSize) { + var db = _openDatabase(name, version, displayName, estimatedSize); + + applyExtension('Database', db); + + return db; + } + @DomName('Window.pageXOffset') @DocsEditable() int get pageXOffset => JS('num', '#.pageXOffset', this).round(); diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart index 69af259d4f5..12ccfcd98bf 100644 --- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart +++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart @@ -23,6 +23,7 @@ import 'dart:_interceptors' show Interceptor; import 'dart:_js_helper' show + applyExtension, convertDartClosureToJS, Creates, JSName, @@ -123,11 +124,26 @@ class SqlDatabase extends Interceptor { [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) native; + @JSName('transaction') @DomName('Database.transaction') @DocsEditable() - void transaction(SqlTransactionCallback callback, + void _transaction(SqlTransactionCallback callback, [SqlTransactionErrorCallback errorCallback, VoidCallback successCallback]) native; + + @JSName('transaction') + @DomName('Database.transaction') + @DocsEditable() + Future transaction() { + var completer = new Completer(); + _transaction((value) { + applyExtension('SQLTransaction', value); + completer.complete(value); + }, (error) { + completer.completeError(error); + }); + return completer.future; + } } // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a @@ -304,10 +320,26 @@ class SqlTransaction extends Interceptor { throw new UnsupportedError("Not supported"); } + @JSName('executeSql') @DomName('SQLTransaction.executeSql') @DocsEditable() - void executeSql(String sqlStatement, + void _executeSql(String sqlStatement, [List arguments, SqlStatementCallback callback, SqlStatementErrorCallback errorCallback]) native; + + @JSName('executeSql') + @DomName('SQLTransaction.executeSql') + @DocsEditable() + Future executeSql(String sqlStatement, [List arguments]) { + var completer = new Completer(); + _executeSql(sqlStatement, arguments, (transaction, resultSet) { + applyExtension('SQLResultSet', resultSet); + applyExtension('SQLResultSetRowList', resultSet.rows); + completer.complete(resultSet); + }, (transaction, error) { + completer.completeError(error); + }); + return completer.future; + } } diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart index fa882c24475..fed6b9ed58c 100644 --- a/tests/html/websql_test.dart +++ b/tests/html/websql_test.dart @@ -3,131 +3,126 @@ library WebDBTest; import 'dart:async'; import 'dart:html'; import 'dart:web_sql'; + import 'package:unittest/unittest.dart'; import 'package:unittest/html_individual_config.dart'; - -Future transaction(SqlDatabase db) { - final completer = new Completer.sync(); - - db.transaction((SqlTransaction transaction) { - completer.complete(transaction); - }, (SqlError error) { - completer.completeError(error); - }); - - return completer.future; -} +import 'package:async_helper/async_helper.dart'; Future createTable( - SqlTransaction transaction, String tableName, String columnName) { - final completer = new Completer.sync(); - - final sql = 'CREATE TABLE $tableName ($columnName)'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + SqlTransaction transaction, String tableName, String columnName) async { + return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []); } -Future insert( - SqlTransaction transaction, String tableName, String columnName, value) { - final completer = new Completer.sync(); - +Future insertTable(SqlTransaction transaction, String tableName, + String columnName, value) async { final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)'; - transaction.executeSql(sql, [value], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, [value]); } -Future queryTable(SqlTransaction transaction, String tableName) { - final completer = new Completer.sync(); - +Future queryTable( + SqlTransaction transaction, String tableName) async { final sql = 'SELECT * FROM $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, []); } Future dropTable(SqlTransaction transaction, String tableName, - [bool ignoreFailure = false]) { - final completer = new Completer.sync(); - - final sql = 'DROP TABLE $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - if (ignoreFailure) { - completer.complete(null); - } else { - completer.completeError(error); - } - }); - - return completer.future; + [bool ignoreFailure = false]) async { + try { + var result = await transaction.executeSql('DROP TABLE $tableName', []); + return result; + } catch (error) { + if (!ignoreFailure) throw error; + } } -main() { +final tableName = 'test_table'; +final columnName = 'test_data'; + +SqlDatabase db; +SqlTransaction tx; + +Future setup() async { + if (SqlDatabase.supported) { + db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(db, isNotNull, reason: 'Unable to open database'); + + tx = await db.transaction(); + expect(tx, isNotNull, reason: "Transaction not ready"); + } +} + +main() async { useHtmlIndividualConfiguration(); - group('supported', () { + await setup(); + + group('Database', () { test('supported', () { expect(SqlDatabase.supported, true); }); }); - group('functional', () { - test('unsupported throws', () { - var expectation = SqlDatabase.supported ? returnsNormally : throws; - expect(() { - window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); - }, expectation); - }); - test('Web Database', () { - // Skip if not supported. - if (!SqlDatabase.supported) { - return new Future.value(); + group('Database', () { + test('Open/Transaction', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + + // Should not succeed table doesn't exist to be dropped. + try { + await dropTable(tx, tableName); + expect(false, true, reason: "dropTable should fail"); + } catch (error) { + expect(error.message, + "could not prepare statement (1 no such table: test_table)"); } + }); - final tableName = 'test_table'; - final columnName = 'test_data'; + test('create', () async { + if (!SqlDatabase.supported) return; - final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet createResult = + await createTable(tx, tableName, columnName); + expect(createResult.insertId, 0); + } catch (error) { + expect(false, true, reason: "createTable failed - ${error.message}"); + } + }); - expect(db, isNotNull, reason: 'Unable to open database'); + test('insert', () async { + if (!SqlDatabase.supported) return; - var tx; - return transaction(db).then((transaction) { - tx = transaction; - }).then((_) { - // Attempt to clear out any tables which may be lurking from previous - // runs. - return dropTable(tx, tableName, true); - }).then((_) { - return createTable(tx, tableName, columnName); - }).then((_) { - return insert(tx, tableName, columnName, 'Some text data'); - }).then((_) { - return queryTable(tx, tableName); - }).then((resultSet) { - expect(resultSet.rows.length, 1); - var row = resultSet.rows.item(0); - expect(row.containsKey(columnName), isTrue); - expect(row[columnName], 'Some text data'); - expect(resultSet.rows[0], row); - }).then((_) { - return dropTable(tx, tableName); - }); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet insertResult = + await insertTable(tx, tableName, columnName, 'Some text data'); + expect(insertResult.insertId, 1); + expect(insertResult.rowsAffected, 1); + } catch (error) { + expect(false, true, reason: "insert failed - ${error.message}"); + } + }); + + test('query', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet queryResult = await queryTable(tx, tableName); + expect(queryResult.rows.length, 1); + expect(queryResult.rows[0]['test_data'], "Some text data"); + } catch (error) { + expect(false, true, reason: "queryTable failed - ${error.message}"); + } + }); + + test('cleanup', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + await dropTable(tx, tableName, true); }); }); } diff --git a/tests/lib_2/html/websql_test.dart b/tests/lib_2/html/websql_test.dart index a066ea53634..a03dd220e1b 100644 --- a/tests/lib_2/html/websql_test.dart +++ b/tests/lib_2/html/websql_test.dart @@ -5,127 +5,124 @@ import 'dart:html'; import 'dart:web_sql'; import 'package:unittest/unittest.dart'; - -Future transaction(SqlDatabase db) { - final completer = new Completer.sync(); - - db.transaction((SqlTransaction transaction) { - completer.complete(transaction); - }, (SqlError error) { - completer.completeError(error); - }); - - return completer.future; -} +import 'package:unittest/html_config.dart'; +import 'package:async_helper/async_helper.dart'; Future createTable( - SqlTransaction transaction, String tableName, String columnName) { - final completer = new Completer.sync(); - - final sql = 'CREATE TABLE $tableName ($columnName)'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + SqlTransaction transaction, String tableName, String columnName) async { + return transaction.executeSql('CREATE TABLE $tableName ($columnName)', []); } -Future insert( - SqlTransaction transaction, String tableName, String columnName, value) { - final completer = new Completer.sync(); - +Future insertTable(SqlTransaction transaction, String tableName, + String columnName, value) async { final sql = 'INSERT INTO $tableName ($columnName) VALUES (?)'; - transaction.executeSql(sql, [value], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, [value]); } -Future queryTable(SqlTransaction transaction, String tableName) { - final completer = new Completer.sync(); - +Future queryTable( + SqlTransaction transaction, String tableName) async { final sql = 'SELECT * FROM $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - completer.completeError(error); - }); - - return completer.future; + return transaction.executeSql(sql, []); } Future dropTable(SqlTransaction transaction, String tableName, - [bool ignoreFailure = false]) { - final completer = new Completer.sync(); - - final sql = 'DROP TABLE $tableName'; - transaction.executeSql(sql, [], (SqlTransaction tx, SqlResultSet rs) { - completer.complete(rs); - }, (SqlTransaction tx, SqlError error) { - if (ignoreFailure) { - completer.complete(null); - } else { - completer.completeError(error); - } - }); - - return completer.future; + [bool ignoreFailure = false]) async { + try { + var result = await transaction.executeSql('DROP TABLE $tableName', []); + return result; + } catch (error) { + if (!ignoreFailure) throw error; + } } -main() { - group('supported', () { +final tableName = 'test_table'; +final columnName = 'test_data'; + +SqlDatabase db; +SqlTransaction tx; + +Future setup() async { + if (SqlDatabase.supported) { + db = await window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(db, isNotNull, reason: 'Unable to open database'); + + tx = await db.transaction(); + expect(tx, isNotNull, reason: "Transaction not ready"); + } +} + +main() async { + useHtmlConfiguration(); + + await setup(); + + group('Database', () { test('supported', () { expect(SqlDatabase.supported, true); }); }); - group('functional', () { - test('unsupported throws', () { - var expectation = SqlDatabase.supported ? returnsNormally : throws; - expect(() { - window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); - }, expectation); - }); - test('Web Database', () { - // Skip if not supported. - if (!SqlDatabase.supported) { - return new Future.value(); + group('Database', () { + test('Open/Transaction', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + + // Should not succeed table doesn't exist to be dropped. + try { + await dropTable(tx, tableName); + expect(false, true, reason: "dropTable should fail"); + } catch (error) { + expect(error.message, + "could not prepare statement (1 no such table: test_table)"); } + }); - final tableName = 'test_table'; - final columnName = 'test_data'; + test('create', () async { + if (!SqlDatabase.supported) return; - final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet createResult = + await createTable(tx, tableName, columnName); + expect(createResult.insertId, 0); + } catch (error) { + expect(false, true, reason: "createTable failed - ${error.message}"); + } + }); - expect(db, isNotNull, reason: 'Unable to open database'); + test('insert', () async { + if (!SqlDatabase.supported) return; - var tx; - return transaction(db).then((transaction) { - tx = transaction; - }).then((_) { - // Attempt to clear out any tables which may be lurking from previous - // runs. - return dropTable(tx, tableName, true); - }).then((_) { - return createTable(tx, tableName, columnName); - }).then((_) { - return insert(tx, tableName, columnName, 'Some text data'); - }).then((_) { - return queryTable(tx, tableName); - }).then((resultSet) { - expect(resultSet.rows.length, 1); - var row = resultSet.rows.item(0); - expect(row.containsKey(columnName), isTrue); - expect(row[columnName], 'Some text data'); - expect(resultSet.rows[0], row); - }).then((_) { - return dropTable(tx, tableName); - }); + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet insertResult = + await insertTable(tx, tableName, columnName, 'Some text data'); + expect(insertResult.insertId, 1); + expect(insertResult.rowsAffected, 1); + } catch (error) { + expect(false, true, reason: "insert failed - ${error.message}"); + } + }); + + test('query', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + try { + SqlResultSet queryResult = await queryTable(tx, tableName); + expect(queryResult.rows.length, 1); + expect(queryResult.rows[0]['test_data'], "Some text data"); + } catch (error) { + expect(false, true, reason: "queryTable failed - ${error.message}"); + } + }); + + test('cleanup', () async { + if (!SqlDatabase.supported) return; + + expect(tx, isNotNull, reason: "Transaction not ready"); + await dropTable(tx, tableName, true); }); }); } diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status index 9ad5f8ffd45..e1fbe36acbc 100644 --- a/tests/lib_2/lib_2_dartdevc.status +++ b/tests/lib_2/lib_2_dartdevc.status @@ -29,7 +29,6 @@ html/no_linked_scripts_htmltest: Skip # Issue 29919 html/scripts_htmltest: Skip # Issue 29919 html/transferables_test: CompileTimeError # Issue 30975 html/two_scripts_htmltest: Skip # Issue 29919 -html/websql_test: Pass, RuntimeError # Issue 31036 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538) js/null_test: RuntimeError # Issue 30652 math/double_pow_test: RuntimeError # Issue 29922 diff --git a/tools/dom/dom.json b/tools/dom/dom.json index 52e3ab75115..ca035996dbc 100644 --- a/tools/dom/dom.json +++ b/tools/dom/dom.json @@ -22037,8 +22037,7 @@ "open": {}, "openDatabase": { "comment": "http://www.w3.org/TR/webdatabase/", - "dart_action": "experimental", - "support_level": "deprecated" + "support_level": "experimental" }, "opener": {}, "orientation": { diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl index 77f0680a7e0..489c47dbb40 100644 --- a/tools/dom/idl/dart/dart.idl +++ b/tools/dom/idl/dart/dart.idl @@ -304,6 +304,8 @@ interface Window : EventTarget { [DartSuppress] void scroll(long x, long y); [DartSuppress] void scroll(long x, long y, Dictionary scrollOptions); [RaisesException] void scroll(long x, long y, optional Dictionary scrollOptions); + + [DartSuppress] Database openDatabase(DOMString name, DOMString version, DOMString displayName, unsigned long estimatedSize, optional DatabaseCallback creationCallback); }; [DartSupplemental] diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py index 10647b0ae69..9a793a10461 100644 --- a/tools/dom/scripts/htmldartgenerator.py +++ b/tools/dom/scripts/htmldartgenerator.py @@ -672,12 +672,51 @@ class HtmlDartGenerator(object): callback_info = GetCallbackInfo( self._database.GetInterface(info.callback_args[0].type_id)) + # If more than one callback then the second argument is the error callback. + # Some error callbacks have 2 args (e.g., executeSql) where the second arg + # is the error - this is the argument we want. + error_callback = "" + if len(info.callback_args) > 1: + error_callback_info = GetCallbackInfo( + self._database.GetInterface(info.callback_args[1].type_id)) + error_callbackNames = [] + for paramInfo in error_callback_info.param_infos: + error_callbackNames.append(paramInfo.name) + errorCallbackVariables = ", ".join(error_callbackNames) + errorName = error_callback_info.param_infos[-1].name + error_callback = (',\n %s(%s) { completer.completeError(%s); }' % + (('%s : ' % info.callback_args[1].name + if info.requires_named_arguments and + info.callback_args[1].is_optional else ''), + errorCallbackVariables, errorName)) + extensions = GetDDC_Extension(self._interface, info.declared_name) if extensions: ddc_extensions = "\n".join(extensions); else: ddc_extensions = '' + # Some callbacks have more than one parameters. If so use all of + # those parameters. However, if more than one argument use the + # type of the last argument to be returned e.g., executeSql the callback + # is (transaction, resultSet) and only the resultSet is returned SqlResultSet. + callbackArgsLen = len(callback_info.param_infos) + future_generic = '' + callbackVariables = '' + completerVariable = '' + if callbackArgsLen == 1: + callbackVariables = 'value' + completerVariable = callbackVariables + if callback_info.param_infos[0].type_id: + future_generic = '<%s>' % self._DartType(callback_info.param_infos[0].type_id) + elif callbackArgsLen > 1: + callbackNames = [] + for paramInfo in callback_info.param_infos: + callbackNames.append(paramInfo.name) + callbackVariables = ",".join(callbackNames) + completerVariable = callbackNames[-1] + future_generic = '<%s>' % self._DartType(callback_info.param_infos[-1].type_id) + param_list = info.ParametersAsArgumentList() metadata = '' if '_RenamingAnnotation' in dir(self): @@ -690,7 +729,7 @@ class HtmlDartGenerator(object): ' $ORIGINAL_FUNCTION($PARAMS_LIST\n' ' $NAMED_PARAM($VARIABLE_NAME) { ' '$DDC_EXTENSION\n' - 'completer.complete($VARIABLE_NAME); }' + 'completer.complete($COMPLETER_NAME); }' '$ERROR_CALLBACK);\n' ' return completer.future;\n' ' }\n', @@ -704,17 +743,12 @@ class HtmlDartGenerator(object): NAMED_PARAM=('%s : ' % info.callback_args[0].name if info.requires_named_arguments and info.callback_args[0].is_optional else ''), - VARIABLE_NAME= '' if len(callback_info.param_infos) == 0 else 'value', + VARIABLE_NAME=callbackVariables, + COMPLETER_NAME=completerVariable, DDC_EXTENSION=ddc_extensions, - ERROR_CALLBACK=('' if len(info.callback_args) == 1 else - (',\n %s(error) { completer.completeError(error); }' % - ('%s : ' % info.callback_args[1].name - if info.requires_named_arguments and - info.callback_args[1].is_optional else ''))), - FUTURE_GENERIC = ('' if len(callback_info.param_infos) == 0 or - not callback_info.param_infos[0].type_id else - '<%s>' % self._DartType(callback_info.param_infos[0].type_id)), - ORIGINAL_FUNCTION = html_name) + ERROR_CALLBACK=error_callback, + FUTURE_GENERIC=future_generic, + ORIGINAL_FUNCTION=html_name) def EmitHelpers(self, base_class): if not self._members_emitter: diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py index ad6b9b238a5..86e8c56650d 100644 --- a/tools/dom/scripts/htmlrenamer.py +++ b/tools/dom/scripts/htmlrenamer.py @@ -173,6 +173,7 @@ for interface in _removed_html_interfaces: convert_to_future_members = monitored.Set( 'htmlrenamer.converted_to_future_members', [ + 'Database.transaction', 'DataTransferItem.getAsString', 'DirectoryEntry.getDirectory', 'DirectoryEntry.getFile', @@ -190,6 +191,7 @@ convert_to_future_members = monitored.Set( 'Notification.requestPermission', 'RTCPeerConnection.setLocalDescription', 'RTCPeerConnection.setRemoteDescription', + 'SQLTransaction.executeSql', 'StorageInfo.requestQuota', 'StorageQuota.requestQuota', 'Window.webkitRequestFileSystem', @@ -213,6 +215,17 @@ ddc_extensions = monitored.Dict('ddcextensions.ddc_extensions', { 'applyExtension(\'Blob\', value);' ] }, + 'Database': { + 'transaction': [ + 'applyExtension(\'SQLTransaction\', value);' + ], + }, + 'SQLTransaction': { + 'executeSql': [ + 'applyExtension(\'SQLResultSet\', resultSet);' + 'applyExtension(\'SQLResultSetRowList\', resultSet.rows);' + ], + }, 'Window': { 'webkitRequestFileSystem':[ 'applyExtension(\'DOMFileSystem\', value);', diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate index 164e7133d3e..85a580be44e 100644 --- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate +++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate @@ -19,8 +19,8 @@ import 'dart:collection' hide LinkedList, LinkedListEntry; import 'dart:_internal' show FixedLengthListMixin; import 'dart:html'; import 'dart:html_common'; -import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName, Native, - JavaScriptIndexingBehavior; +import 'dart:_js_helper' show applyExtension, convertDartClosureToJS, Creates, + JSName, Native, JavaScriptIndexingBehavior; import 'dart:_foreign_helper' show JS; import 'dart:_interceptors' show Interceptor; diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate index d01250e56fc..9d439261aa4 100644 --- a/tools/dom/templates/html/impl/impl_Window.darttemplate +++ b/tools/dom/templates/html/impl/impl_Window.darttemplate @@ -227,6 +227,28 @@ $!MEMBERS _moveTo(p.x, p.y); } + @JSName('openDatabase') + @DomName('Window.openDatabase') + SqlDatabase _openDatabase( + String name, String version, String displayName, int estimatedSize, + [DatabaseCallback creationCallback]) native; + + @JSName('openDatabase') + @DomName('Window.openDatabase') + @DocsEditable() + @SupportedBrowser(SupportedBrowser.CHROME) + @SupportedBrowser(SupportedBrowser.SAFARI) + @Experimental() + @Creates('SqlDatabase') + SqlDatabase openDatabase( + String name, String version, String displayName, int estimatedSize) { + var db = _openDatabase(name, version, displayName, estimatedSize); + + applyExtension('Database', db); + + return db; + } + @DomName('Window.pageXOffset') @DocsEditable() int get pageXOffset => JS('num', '#.pageXOffset', this).round();