Source/WebCore/ChangeLog

 12012-09-14 Alec Flett <alecflett@chromium.org>
 2
 3 IndexedDB: Use ScriptValue instead of SerializedScriptValue for get/openCursor
 4 https://bugs.webkit.org/show_bug.cgi?id=95409
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This reduces a bunch of serialization/deserialization when writing
 9 to objectstores with indexes.
 10
 11 No new tests, as this covers core functionality of IndexedDB, and
 12 almost every test would fail. Some likely tests that would fail
 13 fundamentally include:
 14
 15 storage/indexeddb/objectstore-basics.html
 16 storage/indexeddb/cursor-basics.html
 17 storage/indexeddb/index-basics.html
 18
 19 * Modules/indexeddb/IDBAny.cpp:
 20 (WebCore::IDBAny::scriptValue):
 21 (WebCore::IDBAny::integer):
 22 (WebCore):
 23 (WebCore::IDBAny::set):
 24 * Modules/indexeddb/IDBAny.h:
 25 (WebCore):
 26 (IDBAny):
 27 (WebCore::IDBAny::create):
 28 * Modules/indexeddb/IDBCursor.cpp:
 29 (WebCore::IDBCursor::setValueReady):
 30 * Modules/indexeddb/IDBCursor.h:
 31 (WebCore):
 32 (IDBCursor):
 33 * Modules/indexeddb/IDBDatabase.cpp:
 34 (WebCore::IDBDatabase::version):
 35 * Modules/indexeddb/IDBObjectStore.cpp:
 36 (WebCore):
 37 * Modules/indexeddb/IDBRequest.cpp:
 38 (WebCore::IDBRequest::setResultCursor):
 39 (WebCore::IDBRequest::onSuccess):
 40 (WebCore):
 41 (WebCore::IDBRequest::onSuccessInternal):
 42 (WebCore::IDBRequest::dispatchEvent):
 43 * Modules/indexeddb/IDBRequest.h:
 44 (IDBRequest):
 45 * Modules/indexeddb/IDBTransactionCallbacks.h:
 46 * bindings/v8/IDBBindingUtilities.cpp:
 47 (WebCore::deserializeIDBValue):
 48 (WebCore::injectIDBKeyIntoScriptValue):
 49 * bindings/v8/IDBBindingUtilities.h:
 50 (WebCore):
 51 * bindings/v8/custom/V8IDBAnyCustom.cpp:
 52 (WebCore::toV8):
 53
1542012-09-14 Andrey Kosyakov <caseq@chromium.org>
255
356 Web Inspector: reuse WebInspector.ProgressIndicator in Audits panel

Source/WebKit/chromium/ChangeLog

 12012-09-14 Alec Flett <alecflett@chromium.org>
 2
 3 IndexedDB: Use ScriptValue instead of SerializedScriptValue for get/openCursor
 4 https://bugs.webkit.org/show_bug.cgi?id=95409
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This removes a bunch of tests that have been migrated to
 9 LayoutTests, in https://bugs.webkit.org/show_bug.cgi?id=96818.
 10
 11 * tests/IDBBindingUtilitiesTest.cpp:
 12 (WebCore::checkKeyFromValueAndKeyPathInternal):
 13 (WebCore::checkKeyPathNullValue):
 14 (WebCore::injectKey):
 15 (WebCore::checkInjection):
 16 (WebCore::checkInjectionFails):
 17 (WebCore::checkKeyPathStringValue):
 18 (WebCore::checkKeyPathNumberValue):
 19 (WebCore::TEST):
 20 * tests/IDBKeyPathTest.cpp:
 21
1222012-09-14 Keishi Hattori <keishi@webkit.org>
223
324 Make time input lang attribute aware for testing

Source/WebCore/Modules/indexeddb/IDBAny.cpp

3434#include "IDBIndex.h"
3535#include "IDBKeyPath.h"
3636#include "IDBObjectStore.h"
37 #include "SerializedScriptValue.h"
3837
3938namespace WebCore {
4039

@@PassRefPtr<IDBTransaction> IDBAny::idbTransaction()
120119 return m_idbTransaction;
121120}
122121
123 PassRefPtr<SerializedScriptValue> IDBAny::serializedScriptValue()
 122ScriptValue IDBAny::scriptValue()
124123{
125  ASSERT(m_type == SerializedScriptValueType);
126  return m_serializedScriptValue;
 124 ASSERT(m_type == ScriptValueType);
 125 return m_scriptValue;
127126}
128127
129128const String& IDBAny::string()

@@const String& IDBAny::string()
132131 return m_string;
133132}
134133
 134int64_t IDBAny::integer()
 135{
 136 ASSERT(m_type == IntegerType);
 137 return m_integer;
 138}
 139
135140void IDBAny::setNull()
136141{
137142 ASSERT(m_type == UndefinedType);

@@void IDBAny::set(PassRefPtr<IDBObjectStore> value)
201206 m_idbObjectStore = value;
202207}
203208
204 void IDBAny::set(PassRefPtr<SerializedScriptValue> value)
 209void IDBAny::set(const ScriptValue& value)
205210{
206211 ASSERT(m_type == UndefinedType);
207  m_type = SerializedScriptValueType;
208  m_serializedScriptValue = value;
 212 m_type = ScriptValueType;
 213 m_scriptValue = value;
209214}
210215
211216void IDBAny::set(const IDBKeyPath& value)

@@void IDBAny::set(const String& value)
236241 m_string = value;
237242}
238243
 244void IDBAny::set(int64_t value)
 245{
 246 ASSERT(m_type == UndefinedType);
 247 m_type = IntegerType;
 248 m_integer = value;
 249}
 250
239251} // namespace WebCore
240252
241253#endif

Source/WebCore/Modules/indexeddb/IDBAny.h

2828
2929#if ENABLE(INDEXED_DATABASE)
3030
 31#include "ScriptValue.h"
3132#include <wtf/PassRefPtr.h>
3233#include <wtf/RefCounted.h>
3334#include <wtf/RefPtr.h>

@@class IDBKey;
4546class IDBKeyPath;
4647class IDBObjectStore;
4748class IDBTransaction;
48 class SerializedScriptValue;
4949
5050class IDBAny : public RefCounted<IDBAny> {
5151public:

@@public:
5959 any->set(idbObject);
6060 return any.release();
6161 }
62  static PassRefPtr<IDBAny> create(const IDBKeyPath& keyPath)
 62 template<typename T>
 63 static PassRefPtr<IDBAny> create(const T& idbObject)
6364 {
6465 RefPtr<IDBAny> any = IDBAny::createInvalid();
65  any->set(keyPath);
 66 any->set(idbObject);
6667 return any.release();
6768 }
6869 template<typename T>

@@public:
7273 any->set(idbObject);
7374 return any.release();
7475 }
 76 static PassRefPtr<IDBAny> create(int64_t value)
 77 {
 78 RefPtr<IDBAny> any = IDBAny::createInvalid();
 79 any->set(value);
 80 return any.release();
 81 }
7582 ~IDBAny();
7683
7784 enum Type {

@@public:
8693 IDBKeyType,
8794 IDBObjectStoreType,
8895 IDBTransactionType,
89  SerializedScriptValueType,
 96 ScriptValueType,
 97 IntegerType,
9098 StringType,
9199 };
92100

@@public:
101109 PassRefPtr<IDBKey> idbKey();
102110 PassRefPtr<IDBObjectStore> idbObjectStore();
103111 PassRefPtr<IDBTransaction> idbTransaction();
104  PassRefPtr<SerializedScriptValue> serializedScriptValue();
 112 ScriptValue scriptValue();
 113 int64_t integer();
105114 const String& string();
106115
107116 // Set can only be called once.

@@public:
115124 void set(PassRefPtr<IDBKey>);
116125 void set(PassRefPtr<IDBObjectStore>);
117126 void set(PassRefPtr<IDBTransaction>);
118  void set(PassRefPtr<SerializedScriptValue>);
119127 void set(const IDBKeyPath&);
120128 void set(const String&);
 129 void set(const ScriptValue&);
 130 void set(int64_t);
121131
122132private:
123133 IDBAny();

@@private:
134144 RefPtr<IDBKey> m_idbKey;
135145 RefPtr<IDBObjectStore> m_idbObjectStore;
136146 RefPtr<IDBTransaction> m_idbTransaction;
137  RefPtr<SerializedScriptValue> m_serializedScriptValue;
 147 ScriptValue m_scriptValue;
138148 String m_string;
 149 int64_t m_integer;
139150};
140151
141152} // namespace WebCore

Source/WebCore/Modules/indexeddb/IDBCursor.cpp

3838#include "IDBTracing.h"
3939#include "IDBTransaction.h"
4040#include "ScriptExecutionContext.h"
41 #include "SerializedScriptValue.h"
4241
4342namespace WebCore {
4443

@@void IDBCursor::close()
260259 m_request.clear();
261260}
262261
263 void IDBCursor::setValueReady(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> prpValue)
 262void IDBCursor::setValueReady(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, ScriptValue& value)
264263{
265264 m_currentKey = key;
266265 m_currentPrimaryKey = primaryKey;
267266
268  RefPtr<SerializedScriptValue> value = prpValue;
269267 if (!isKeyCursor()) {
270268 RefPtr<IDBObjectStore> objectStore = effectiveObjectStore();
271269 const IDBObjectStoreMetadata metadata = objectStore->metadata();
272270 if (metadata.autoIncrement && !metadata.keyPath.isNull()) {
273271#ifndef NDEBUG
274  RefPtr<IDBKey> expectedKey = createIDBKeyFromSerializedValueAndKeyPath(value, metadata.keyPath);
 272 RefPtr<IDBKey> expectedKey = createIDBKeyFromScriptValueAndKeyPath(value, metadata.keyPath);
275273 ASSERT(!expectedKey || expectedKey->isEqual(m_currentPrimaryKey.get()));
276274#endif
277  RefPtr<SerializedScriptValue> valueAfterInjection = injectIDBKeyIntoSerializedValue(m_currentPrimaryKey, value, metadata.keyPath);
278  ASSERT(valueAfterInjection);
 275 bool injected = injectIDBKeyIntoScriptValue(m_currentPrimaryKey, value, metadata.keyPath);
 276 ASSERT_UNUSED(injected, injected);
279277 // FIXME: There is no way to report errors here. Move this into onSuccessWithContinuation so that we can abort the transaction there. See: https://bugs.webkit.org/show_bug.cgi?id=92278
280  if (valueAfterInjection)
281  value = valueAfterInjection;
282278 }
283279 }
284  m_currentValue = IDBAny::create(value.release());
 280 m_currentValue = IDBAny::create(value);
285281
286282 m_gotValue = true;
287283 m_valueIsDirty = true;

Source/WebCore/Modules/indexeddb/IDBCursor.h

@@class IDBCallbacks;
4141class IDBCursorBackendInterface;
4242class IDBRequest;
4343class ScriptExecutionContext;
44 class SerializedScriptValue;
4544
4645typedef int ExceptionCode;
4746

@@public:
8281
8382 void postSuccessHandlerCallback();
8483 void close();
85  void setValueReady(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue>);
 84 void setValueReady(PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, ScriptValue&);
8685
8786 // The spec requires that the script object that wraps the value
8887 // be unchanged until the value changes as a result of the cursor

Source/WebCore/Modules/indexeddb/IDBDatabase.cpp

@@PassRefPtr<IDBAny> IDBDatabase::version() const
117117 int64_t intVersion = m_metadata.intVersion;
118118 if (intVersion == IDBDatabaseMetadata::NoIntVersion)
119119 return IDBAny::createString(m_metadata.version);
120  return IDBAny::create(SerializedScriptValue::numberValue(intVersion));
 120 return IDBAny::create(intVersion);
121121}
122122
123123PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec)

Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

@@private:
340340 RefPtr<IDBKey> primaryKey = cursor->primaryKey();
341341 RefPtr<IDBAny> valueAny = cursor->value();
342342
343  ASSERT(valueAny->type() == IDBAny::SerializedScriptValueType);
344  RefPtr<SerializedScriptValue> serializedValue = valueAny->serializedScriptValue();
345  ScriptValue value(deserializeIDBValue(context, serializedValue));
 343 ASSERT(valueAny->type() == IDBAny::ScriptValueType);
 344 ScriptValue value = valueAny->scriptValue();
346345
347346 IDBObjectStore::IndexKeys indexKeys;
348347 generateIndexKeysForValue(m_indexMetadata, value, &indexKeys);

Source/WebCore/Modules/indexeddb/IDBRequest.cpp

@@PassRefPtr<IDBCursor> IDBRequest::getResultCursor()
214214 return 0;
215215}
216216
217 void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> value)
 217void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, const ScriptValue& value)
218218{
219219 ASSERT(m_readyState == PENDING);
220220 m_cursorKey = key;

@@void IDBRequest::onSuccess(PassRefPtr<DOMStringList> domStringList)
276276 enqueueEvent(createSuccessEvent());
277277}
278278
279 void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> value)
 279void IDBRequest::onSuccess(PassRefPtr<IDBCursorBackendInterface> backend, PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> serializedValue)
280280{
281281 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)");
282282 if (!shouldEnqueueEvent())
283283 return;
284284
 285 ScriptValue value = deserializeIDBValue(scriptExecutionContext(), serializedValue);
285286 ASSERT(m_cursorType != IDBCursorBackendInterface::InvalidCursorType);
286287 RefPtr<IDBCursor> cursor;
287288 if (m_cursorType == IDBCursorBackendInterface::IndexKeyCursor)

@@void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey)
302303 if (idbKey && idbKey->isValid())
303304 m_result = IDBAny::create(idbKey);
304305 else
305  m_result = IDBAny::create(SerializedScriptValue::undefinedValue());
 306 m_result = IDBAny::createInvalid();
306307 enqueueEvent(createSuccessEvent());
307308}
308309

@@void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> serializedScriptVal
337338 if (!shouldEnqueueEvent())
338339 return;
339340
340  m_result = IDBAny::create(serializedScriptValue);
341  m_pendingCursor.clear();
342  enqueueEvent(createSuccessEvent());
 341 ScriptValue value = deserializeIDBValue(scriptExecutionContext(), serializedScriptValue);
 342 onSuccessInternal(value);
343343}
344344
345345#ifndef NDEBUG

@@void IDBRequest::onSuccess(PassRefPtr<SerializedScriptValue> prpSerializedScript
364364#ifndef NDEBUG
365365 ASSERT(keyPath == effectiveObjectStore(m_source)->keyPath());
366366#endif
367  RefPtr<SerializedScriptValue> value = prpSerializedScriptValue;
 367 ScriptValue value = deserializeIDBValue(scriptExecutionContext(), prpSerializedScriptValue);
368368
369369 RefPtr<IDBKey> primaryKey = prpPrimaryKey;
370370#ifndef NDEBUG
371  RefPtr<IDBKey> expectedKey = createIDBKeyFromSerializedValueAndKeyPath(value, keyPath);
 371 RefPtr<IDBKey> expectedKey = createIDBKeyFromScriptValueAndKeyPath(value, keyPath);
372372 ASSERT(!expectedKey || expectedKey->isEqual(primaryKey.get()));
373373#endif
374  RefPtr<SerializedScriptValue> valueAfterInjection = injectIDBKeyIntoSerializedValue(primaryKey, value, keyPath);
375  ASSERT(valueAfterInjection);
376  if (!valueAfterInjection) {
 374 bool injected = injectIDBKeyIntoScriptValue(primaryKey, value, keyPath);
 375 ASSERT(injected);
 376 if (!injected) {
377377 // Checks in put() ensure this should only happen if I/O error occurs.
378378 onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error inserting generated key into the object."));
379379 return;
380380 }
381  value = valueAfterInjection;
382  onSuccess(value.release());
 381 onSuccessInternal(value);
 382}
 383
 384void IDBRequest::onSuccessInternal(const ScriptValue& value)
 385{
 386 m_result = IDBAny::create(value);
 387 m_pendingCursor.clear();
 388 enqueueEvent(createSuccessEvent());
383389}
384390
385 void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> value)
 391void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue> serializedValue)
386392{
387393 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)");
388394 if (!shouldEnqueueEvent())
389395 return;
390396
 397 ScriptValue value = deserializeIDBValue(scriptExecutionContext(), serializedValue);
391398 ASSERT(m_pendingCursor);
392399 setResultCursor(m_pendingCursor.release(), key, primaryKey, value);
393400 enqueueEvent(createSuccessEvent());

@@bool IDBRequest::dispatchEvent(PassRefPtr<Event> event)
456463 if (event->type() == eventNames().successEvent) {
457464 cursorToNotify = getResultCursor();
458465 if (cursorToNotify)
459  cursorToNotify->setValueReady(m_cursorKey.release(), m_cursorPrimaryKey.release(), m_cursorValue.release());
 466 cursorToNotify->setValueReady(m_cursorKey.release(), m_cursorPrimaryKey.release(), m_cursorValue);
460467 }
461468
462469 if (event->type() == eventNames().upgradeneededEvent) {

Source/WebCore/Modules/indexeddb/IDBRequest.h

@@protected:
113113 IDBRequest(ScriptExecutionContext*, PassRefPtr<IDBAny> source, IDBTransactionBackendInterface::TaskType, IDBTransaction*);
114114 void enqueueEvent(PassRefPtr<Event>);
115115 virtual bool shouldEnqueueEvent() const;
 116 void onSuccessInternal(const ScriptValue&);
116117
117118 RefPtr<IDBAny> m_result;
118119 unsigned short m_errorCode;

@@private:
131132 virtual EventTargetData* ensureEventTargetData();
132133
133134 PassRefPtr<IDBCursor> getResultCursor();
134  void setResultCursor(PassRefPtr<IDBCursor>, PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SerializedScriptValue>);
 135 void setResultCursor(PassRefPtr<IDBCursor>, PassRefPtr<IDBKey>, PassRefPtr<IDBKey> primaryKey, const ScriptValue&);
135136
136137 RefPtr<IDBAny> m_source;
137138 const IDBTransactionBackendInterface::TaskType m_taskType;

@@private:
146147 RefPtr<IDBCursor> m_pendingCursor;
147148 RefPtr<IDBKey> m_cursorKey;
148149 RefPtr<IDBKey> m_cursorPrimaryKey;
149  RefPtr<SerializedScriptValue> m_cursorValue;
 150 ScriptValue m_cursorValue;
150151 bool m_didFireUpgradeNeededEvent;
151152
152153 EventTargetData m_eventTargetData;

Source/WebCore/Modules/indexeddb/IDBTransactionCallbacks.h

3131
3232#if ENABLE(INDEXED_DATABASE)
3333
34 #include "SerializedScriptValue.h"
3534#include <wtf/RefCounted.h>
3635
3736namespace WebCore {

Source/WebCore/bindings/v8/IDBBindingUtilities.cpp

@@PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue& valu
209209 return createIDBKeyFromScriptValueAndKeyPath(value, keyPath.string());
210210}
211211
212 static PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const String& keyPath)
213 {
214  Vector<String> keyPathElements;
215  IDBKeyPathParseError error;
216  IDBParseKeyPath(keyPath, keyPathElements, error);
217  ASSERT(error == IDBKeyPathParseErrorNone);
218 
219  RefPtr<SerializedScriptValue> value = prpValue;
220 
221  v8::HandleScope handleScope;
222  v8::Context::Scope scope(V8PerIsolateData::current()->ensureAuxiliaryContext());
223 
224  v8::Handle<v8::Value> v8Value(value->deserialize());
225  v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size()));
226  if (v8Key.IsEmpty())
227  return 0;
228  return createIDBKeyFromValue(v8Key);
229 }
230 
231212// FIXME: The only reason this exists is because we need a v8::Context and scope inside a timer. Is there a better / more general way to do this?
232213ScriptValue deserializeIDBValue(ScriptExecutionContext* scriptContext, PassRefPtr<SerializedScriptValue> prpValue)
233214{
234215 v8::HandleScope handleScope;
235  v8::Context::Scope contextScope(toV8Context(scriptContext, UseCurrentWorld));
 216 v8::Context::Scope contextScope(scriptContext ? toV8Context(scriptContext, UseCurrentWorld) : V8PerIsolateData::current()->ensureAuxiliaryContext());
236217 return ScriptValue(prpValue->deserialize());
237218}
238219
239 PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> prpValue, const IDBKeyPath& keyPath)
240 {
241  IDB_TRACE("createIDBKeyFromSerializedValueAndKeyPath");
242  ASSERT(!keyPath.isNull());
243 
244  RefPtr<SerializedScriptValue> value = prpValue;
245 
246  if (keyPath.type() == IDBKeyPath::ArrayType) {
247  IDBKey::KeyArray result;
248  const Vector<String>& array = keyPath.array();
249  for (size_t i = 0; i < array.size(); ++i) {
250  RefPtr<IDBKey> key = createIDBKeyFromSerializedValueAndKeyPath(value, array[i]);
251  if (!key)
252  return 0;
253  result.append(key);
254  }
255  return IDBKey::createArray(result);
256  }
257 
258  ASSERT(keyPath.type() == IDBKeyPath::StringType);
259  return createIDBKeyFromSerializedValueAndKeyPath(value, keyPath.string());
260 }
261 
262 PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
 220bool injectIDBKeyIntoScriptValue(PassRefPtr<IDBKey> key, ScriptValue& value, const IDBKeyPath& keyPath)
263221{
264  IDB_TRACE("injectIDBKeyIntoSerializedValue");
 222 IDB_TRACE("injectIDBKeyIntoScriptValue");
265223
266224 ASSERT(keyPath.type() == IDBKeyPath::StringType);
267225 Vector<String> keyPathElements;

@@PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDB
275233 v8::HandleScope handleScope;
276234 v8::Context::Scope scope(V8PerIsolateData::current()->ensureAuxiliaryContext());
277235
278  v8::Handle<v8::Value> v8Value(value->deserialize());
 236 v8::Handle<v8::Value> v8Value(value.v8Value());
279237 v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1));
280238 if (parent.IsEmpty())
281  return 0;
 239 return false;
282240
283241 if (!set(parent, keyPathElements.last(), toV8(key.get())))
284  return 0;
 242 return false;
285243
286  return SerializedScriptValue::create(v8Value);
 244 return true;
287245}
288246
289247bool canInjectIDBKeyIntoScriptValue(const ScriptValue& scriptValue, const IDBKeyPath& keyPath)

Source/WebCore/bindings/v8/IDBBindingUtilities.h

@@class SerializedScriptValue;
4040
4141PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value>);
4242
43 // FIXME: remove the SerializedValue versions when their use is finally removed in https://bugs.webkit.org/show_bug.cgi?id=95409.
44 PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
45 PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
46 
 43bool injectIDBKeyIntoScriptValue(PassRefPtr<IDBKey>, ScriptValue&, const IDBKeyPath&);
4744PassRefPtr<IDBKey> createIDBKeyFromScriptValueAndKeyPath(const ScriptValue&, const IDBKeyPath&);
4845bool canInjectIDBKeyIntoScriptValue(const ScriptValue&, const IDBKeyPath&);
4946ScriptValue deserializeIDBValue(ScriptExecutionContext*, PassRefPtr<SerializedScriptValue>);

Source/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp

3131
3232#include "V8IDBAny.h"
3333
34 #include "SerializedScriptValue.h"
 34#include "ScriptValue.h"
3535#include "V8Binding.h"
3636#include "V8DOMStringList.h"
3737#include "V8IDBCursor.h"

@@v8::Handle<v8::Value> toV8(IDBAny* impl, v8::Handle<v8::Object> creationContext,
7373 return toV8(impl->idbObjectStore(), creationContext, isolate);
7474 case IDBAny::IDBTransactionType:
7575 return toV8(impl->idbTransaction(), creationContext, isolate);
76  case IDBAny::SerializedScriptValueType:
77  return impl->serializedScriptValue()->deserialize(0, isolate);
 76 case IDBAny::ScriptValueType:
 77 return impl->scriptValue().v8Value();
7878 case IDBAny::StringType:
7979 return v8String(impl->string(), isolate);
 80 case IDBAny::IntegerType:
 81 return v8::Number::New(impl->integer());
8082 }
8183
8284 ASSERT_NOT_REACHED();

Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp

2727#include "IDBBindingUtilities.h"
2828#include "IDBKey.h"
2929#include "IDBKeyPath.h"
30 #include "SerializedScriptValue.h"
3130#include "V8PerIsolateData.h"
3231#include "V8Utilities.h"
3332

@@using namespace WebCore;
4039
4140namespace {
4241
43 PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(SerializedScriptValue* value, const String& keyPath)
 42PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(const ScriptValue& value, const String& keyPath)
4443{
4544 IDBKeyPath idbKeyPath(keyPath);
4645 EXPECT_TRUE(idbKeyPath.isValid());
47  return createIDBKeyFromSerializedValueAndKeyPath(value, idbKeyPath);
 46
 47 return createIDBKeyFromScriptValueAndKeyPath(value, idbKeyPath);
4848}
4949
50 void checkKeyPathNullValue(SerializedScriptValue* value, const String& keyPath)
 50void checkKeyPathNullValue(const ScriptValue& value, const String& keyPath)
5151{
5252 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
5353 ASSERT_FALSE(idbKey.get());
5454}
5555
56 PassRefPtr<SerializedScriptValue> injectKey(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
 56bool injectKey(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath)
5757{
5858 IDBKeyPath idbKeyPath(keyPath);
5959 EXPECT_TRUE(idbKeyPath.isValid());
60  return injectIDBKeyIntoSerializedValue(key, value, idbKeyPath);
 60 return injectIDBKeyIntoScriptValue(key, value, idbKeyPath);
6161}
6262
63 void checkInjection(PassRefPtr<IDBKey> prpKey, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
 63void checkInjection(PassRefPtr<IDBKey> prpKey, ScriptValue& value, const String& keyPath)
6464{
6565 RefPtr<IDBKey> key = prpKey;
66  RefPtr<SerializedScriptValue> newValue = injectKey(key, value, keyPath);
67  ASSERT_TRUE(newValue);
68  RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(newValue.get(), keyPath);
 66 bool result = injectKey(key, value, keyPath);
 67 ASSERT_TRUE(result);
 68 RefPtr<IDBKey> extractedKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
6969 EXPECT_TRUE(key->isEqual(extractedKey.get()));
7070}
7171
72 void checkInjectionFails(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
 72void checkInjectionFails(PassRefPtr<IDBKey> key, ScriptValue& value, const String& keyPath)
7373{
7474 EXPECT_FALSE(injectKey(key, value, keyPath));
7575}
7676
77 void checkKeyPathStringValue(SerializedScriptValue* value, const String& keyPath, const String& expected)
 77void checkKeyPathStringValue(const ScriptValue& value, const String& keyPath, const String& expected)
7878{
7979 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
8080 ASSERT_TRUE(idbKey.get());

@@void checkKeyPathStringValue(SerializedScriptValue* value, const String& keyPath
8282 ASSERT_TRUE(expected == idbKey->string());
8383}
8484
85 void checkKeyPathNumberValue(SerializedScriptValue* value, const String& keyPath, int expected)
 85void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, int expected)
8686{
8787 RefPtr<IDBKey> idbKey = checkKeyFromValueAndKeyPathInternal(value, keyPath);
8888 ASSERT_TRUE(idbKey.get());

@@TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue)
9898 v8::Local<v8::Object> object = v8::Object::New();
9999 object->Set(v8::String::New("foo"), v8::String::New("zoo"));
100100
101  RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
 101 ScriptValue scriptValue(object);
102102
103  checkKeyPathStringValue(serializedScriptValue.get(), "foo", "zoo");
104  checkKeyPathNullValue(serializedScriptValue.get(), "bar");
 103 checkKeyPathStringValue(scriptValue, "foo", "zoo");
 104 checkKeyPathNullValue(scriptValue, "bar");
105105}
106106
107107TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue)

@@TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue)
112112 v8::Local<v8::Object> object = v8::Object::New();
113113 object->Set(v8::String::New("foo"), v8::Number::New(456));
114114
115  RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
 115 ScriptValue scriptValue(object);
116116
117  checkKeyPathNumberValue(serializedScriptValue.get(), "foo", 456);
118  checkKeyPathNullValue(serializedScriptValue.get(), "bar");
 117 checkKeyPathNumberValue(scriptValue, "foo", 456);
 118 checkKeyPathNullValue(scriptValue, "bar");
119119}
120120
121121TEST(IDBKeyFromValueAndKeyPathTest, SubProperty)

@@TEST(IDBKeyFromValueAndKeyPathTest, SubProperty)
128128 subProperty->Set(v8::String::New("bar"), v8::String::New("zee"));
129129 object->Set(v8::String::New("foo"), subProperty);
130130
131  RefPtr<SerializedScriptValue> serializedScriptValue = SerializedScriptValue::create(object);
 131 ScriptValue scriptValue(object);
132132
133  checkKeyPathStringValue(serializedScriptValue.get(), "foo.bar", "zee");
134  checkKeyPathNullValue(serializedScriptValue.get(), "bar");
 133 checkKeyPathStringValue(scriptValue, "foo.bar", "zee");
 134 checkKeyPathNullValue(scriptValue, "bar");
135135}
136136
137137TEST(InjectIDBKeyTest, TopLevelPropertyStringValue)

@@TEST(InjectIDBKeyTest, TopLevelPropertyStringValue)
142142 v8::Local<v8::Object> object = v8::Object::New();
143143 object->Set(v8::String::New("foo"), v8::String::New("zoo"));
144144
145  checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "bar");
146  checkInjection(IDBKey::createNumber(1234), SerializedScriptValue::create(object), "bar");
 145 ScriptValue foozoo(object);
 146 checkInjection(IDBKey::createString("myNewKey"), foozoo, "bar");
 147 checkInjection(IDBKey::createNumber(1234), foozoo, "bar");
147148
148  checkInjectionFails(IDBKey::createString("key"), SerializedScriptValue::create(object), "foo.bar");
 149 checkInjectionFails(IDBKey::createString("key"), foozoo, "foo.bar");
149150}
150151
151152TEST(InjectIDBKeyTest, SubProperty)

@@TEST(InjectIDBKeyTest, SubProperty)
158159 subProperty->Set(v8::String::New("bar"), v8::String::New("zee"));
159160 object->Set(v8::String::New("foo"), subProperty);
160161
161  checkInjection(IDBKey::createString("myNewKey"), SerializedScriptValue::create(object), "foo.baz");
162  checkInjection(IDBKey::createNumber(789), SerializedScriptValue::create(object), "foo.baz");
163  checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "foo.baz");
164  checkInjection(IDBKey::createDate(4567), SerializedScriptValue::create(object), "bar");
165  checkInjection(IDBKey::createArray(IDBKey::KeyArray()), SerializedScriptValue::create(object), "foo.baz");
166  checkInjection(IDBKey::createArray(IDBKey::KeyArray()), SerializedScriptValue::create(object), "bar");
 162 ScriptValue scriptObject(object);
 163 checkInjection(IDBKey::createString("myNewKey"), scriptObject, "foo.baz");
 164 checkInjection(IDBKey::createNumber(789), scriptObject, "foo.baz");
 165 checkInjection(IDBKey::createDate(4567), scriptObject, "foo.baz");
 166 checkInjection(IDBKey::createDate(4567), scriptObject, "bar");
 167 checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "foo.baz");
 168 checkInjection(IDBKey::createArray(IDBKey::KeyArray()), scriptObject, "bar");
167169
168  checkInjectionFails(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.bar.baz");
169  checkInjection(IDBKey::createString("zoo"), SerializedScriptValue::create(object), "foo.xyz.foo");
 170 checkInjectionFails(IDBKey::createString("zoo"), scriptObject, "foo.bar.baz");
 171 checkInjection(IDBKey::createString("zoo"), scriptObject, "foo.xyz.foo");
170172}
171173
172174} // namespace

Source/WebKit/chromium/tests/IDBKeyPathTest.cpp

@@TEST(IDBKeyPathTest, InvalidKeyPath5)
127127 checkKeyPath(keyPath, expected, 3);
128128}
129129
130 TEST(IDBKeyPathTest, Extract)
131 {
132  IDBKeyPath keyPath("foo");
133  RefPtr<IDBKey> stringZooKey(IDBKey::createString("zoo"));
134  RefPtr<IDBKey> invalidKey(IDBKey::createInvalid());
135  RefPtr<SerializedScriptValue> ssv;
136  RefPtr<IDBKey> result;
137 
138  // keypath: "foo", value: {foo: "zoo"}, expected: "zoo"
139  UChar dataFooZoo[] = {0x0353, 0x6f66, 0x536f, 0x7a03, 0x6f6f, 0x017b};
140  ssv = SerializedScriptValue::createFromWire(String(dataFooZoo, WTF_ARRAY_LENGTH(dataFooZoo)));
141  result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
142  EXPECT_TRUE(stringZooKey->isEqual(result.get()));
143 
144  // keypath: "foo", value: {foo: null}, expected: invalid
145  UChar dataFooNull[] = {0x0353, 0x6f66, 0x306f, 0x017b};
146  ssv = SerializedScriptValue::createFromWire(String(dataFooNull, WTF_ARRAY_LENGTH(dataFooNull)));
147  result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
148  EXPECT_FALSE(result->isValid());
149 
150  // keypath: "foo", value: {}, expected: null
151  UChar dataObject[] = {0x017b};
152  ssv = SerializedScriptValue::createFromWire(String(dataObject, WTF_ARRAY_LENGTH(dataObject)));
153  result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
154  EXPECT_EQ(0, result.get());
155 
156  // keypath: "foo", value: null, expected: null
157  ssv = SerializedScriptValue::nullValue();
158  result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
159  EXPECT_EQ(0, result.get());
160 }
161 
162 TEST(IDBKeyPathTest, IDBKeyPathPropertyNotAvailable)
163 {
164  IDBKeyPath keyPath("PropertyNotAvailable");
165  RefPtr<SerializedScriptValue> ssv;
166  // {foo: "zoo", bar: null}
167  UChar data[] = {0x0353, 0x6f66, 0x536f, 0x7a03, 0x6f6f, 0x0353, 0x6162,
168  0x3072, 0x027b};
169  ssv = SerializedScriptValue::createFromWire(String(data, WTF_ARRAY_LENGTH(data)));
170  RefPtr<IDBKey> result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
171  EXPECT_EQ(0, result.get());
172 
173  // null
174  ssv = SerializedScriptValue::nullValue();
175  result = createIDBKeyFromSerializedValueAndKeyPath(ssv, keyPath);
176  EXPECT_EQ(0, result.get());
177 }
178 
179 TEST(IDBKeyPathTest, InjectIDBKey)
180 {
181  // {foo: 'zoo'}
182  const UChar initialData[] = {0x0353, 0x6f66, 0x536f, 0x7a03, 0x6f6f, 0x017b};
183  RefPtr<SerializedScriptValue> value = SerializedScriptValue::createFromWire(String(initialData, WTF_ARRAY_LENGTH(initialData)));
184 
185  RefPtr<IDBKey> key = IDBKey::createString("myNewKey");
186  IDBKeyPath keyPath("bar");
187 
188  // {foo: 'zoo', bar: 'myNewKey'}
189  const UChar expectedData[] = {0x01ff, 0x003f, 0x3f6f, 0x5301, 0x6603,
190  0x6f6f, 0x013f, 0x0353, 0x6f7a, 0x3f6f,
191  0x5301, 0x6203, 0x7261, 0x013f, 0x0853,
192  0x796d, 0x654e, 0x4b77, 0x7965, 0x027b};
193  RefPtr<SerializedScriptValue> expectedValue =
194  SerializedScriptValue::createFromWire(String(expectedData, WTF_ARRAY_LENGTH(expectedData)));
195  RefPtr<SerializedScriptValue> result = injectIDBKeyIntoSerializedValue(key, value, keyPath);
196  EXPECT_EQ(expectedValue->toWireString(), result->toWireString());
197 
198  // Should fail - can't apply properties to string value of key foo
199  keyPath = IDBKeyPath("foo.bad.path");
200  result = injectIDBKeyIntoSerializedValue(key, value, keyPath);
201  EXPECT_EQ(0, result.get());
202 
203  // {foo: 'zoo', bar: {baz: 'myNewKey'}}
204  const UChar expectedData2[] = {0x01ff, 0x003f, 0x3f6f, 0x5301, 0x6603,
205  0x6f6f, 0x013f, 0x0353, 0x6f7a, 0x3f6f,
206  0x5301, 0x6203, 0x7261, 0x013f, 0x3f6f,
207  0x5302, 0x6203, 0x7a61, 0x023f, 0x0853,
208  0x796d, 0x654e, 0x4b77, 0x7965, 0x017b,
209  0x027b};
210  RefPtr<SerializedScriptValue> expectedValue2 = SerializedScriptValue::createFromWire(String(expectedData2, WTF_ARRAY_LENGTH(expectedData2)));
211  keyPath = IDBKeyPath("bar.baz");
212  result = injectIDBKeyIntoSerializedValue(key, value, keyPath);
213  EXPECT_EQ(expectedValue2->toWireString(), result->toWireString());
214 }
215 
216130} // namespace
217131
218132#endif // ENABLE(INDEXED_DATABASE)