Commit 0a191521 authored by Francois Beaufort's avatar Francois Beaufort Committed by Commit Bot

[WebNFC] Add data attribute to NDEFRecord

This CL adds the data attribute to NDEFRecord as specified in
https://github.com/w3c/web-nfc/pull/379

Bug: 520391
Change-Id: Icab2c69d6cec95540e6f8525354e86a6937aa4e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1871369Reviewed-by: default avatarRijubrata Bhaumik <rijubrata.bhaumik@intel.com>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Cr-Commit-Position: refs/heads/master@{#708167}
parent 3373f32d
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "services/device/public/mojom/nfc.mojom-blink.h" #include "services/device/public/mojom/nfc.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h" #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_data_view.h"
#include "third_party/blink/renderer/modules/nfc/ndef_record_init.h" #include "third_party/blink/renderer/modules/nfc/ndef_record_init.h"
#include "third_party/blink/renderer/modules/nfc/nfc_utils.h" #include "third_party/blink/renderer/modules/nfc/nfc_utils.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
...@@ -257,24 +258,24 @@ NDEFRecord::NDEFRecord(const String& record_type, ...@@ -257,24 +258,24 @@ NDEFRecord::NDEFRecord(const String& record_type,
WTF::Vector<uint8_t> data) WTF::Vector<uint8_t> data)
: record_type_(record_type), : record_type_(record_type),
media_type_(media_type), media_type_(media_type),
data_(std::move(data)) {} payload_data_(std::move(data)) {}
NDEFRecord::NDEFRecord(const String& text) NDEFRecord::NDEFRecord(const String& text)
: record_type_("text"), : record_type_("text"),
media_type_("text/plain;charset=UTF-8"), media_type_("text/plain;charset=UTF-8"),
data_(GetUTF8DataFromString(text)) {} payload_data_(GetUTF8DataFromString(text)) {}
NDEFRecord::NDEFRecord(DOMArrayBuffer* array_buffer) NDEFRecord::NDEFRecord(DOMArrayBuffer* array_buffer)
: record_type_("opaque"), media_type_("application/octet-stream") { : record_type_("opaque"), media_type_("application/octet-stream") {
data_.Append(static_cast<uint8_t*>(array_buffer->Data()), payload_data_.Append(static_cast<uint8_t*>(array_buffer->Data()),
array_buffer->ByteLength()); array_buffer->ByteLength());
} }
NDEFRecord::NDEFRecord(const device::mojom::blink::NDEFRecord& record) NDEFRecord::NDEFRecord(const device::mojom::blink::NDEFRecord& record)
: record_type_(record.record_type), : record_type_(record.record_type),
media_type_(record.media_type), media_type_(record.media_type),
id_(record.id), id_(record.id),
data_(record.data) {} payload_data_(record.data) {}
const String& NDEFRecord::recordType() const { const String& NDEFRecord::recordType() const {
return record_type_; return record_type_;
...@@ -288,6 +289,12 @@ const String& NDEFRecord::id() const { ...@@ -288,6 +289,12 @@ const String& NDEFRecord::id() const {
return id_; return id_;
} }
DOMDataView* NDEFRecord::data() const {
DOMArrayBuffer* dom_buffer =
DOMArrayBuffer::Create(payload_data_.data(), payload_data_.size());
return DOMDataView::Create(dom_buffer, 0, payload_data_.size());
}
String NDEFRecord::text() const { String NDEFRecord::text() const {
if (record_type_ == "empty") if (record_type_ == "empty")
return String(); return String();
...@@ -295,7 +302,8 @@ String NDEFRecord::text() const { ...@@ -295,7 +302,8 @@ String NDEFRecord::text() const {
// TODO(https://crbug.com/520391): Support utf-16 decoding for 'TEXT' record // TODO(https://crbug.com/520391): Support utf-16 decoding for 'TEXT' record
// as described at // as described at
// http://w3c.github.io/web-nfc/#dfn-convert-ndefrecord-payloaddata-bytes. // http://w3c.github.io/web-nfc/#dfn-convert-ndefrecord-payloaddata-bytes.
return String::FromUTF8WithLatin1Fallback(data_.data(), data_.size()); return String::FromUTF8WithLatin1Fallback(payload_data_.data(),
payload_data_.size());
} }
DOMArrayBuffer* NDEFRecord::arrayBuffer() const { DOMArrayBuffer* NDEFRecord::arrayBuffer() const {
...@@ -306,7 +314,7 @@ DOMArrayBuffer* NDEFRecord::arrayBuffer() const { ...@@ -306,7 +314,7 @@ DOMArrayBuffer* NDEFRecord::arrayBuffer() const {
DCHECK(record_type_ == "json" || record_type_ == "opaque" || DCHECK(record_type_ == "json" || record_type_ == "opaque" ||
!ValidateCustomRecordType(record_type_).IsNull()); !ValidateCustomRecordType(record_type_).IsNull());
return DOMArrayBuffer::Create(data_.data(), data_.size()); return DOMArrayBuffer::Create(payload_data_.data(), payload_data_.size());
} }
ScriptValue NDEFRecord::json(ScriptState* script_state, ScriptValue NDEFRecord::json(ScriptState* script_state,
...@@ -319,17 +327,18 @@ ScriptValue NDEFRecord::json(ScriptState* script_state, ...@@ -319,17 +327,18 @@ ScriptValue NDEFRecord::json(ScriptState* script_state,
!ValidateCustomRecordType(record_type_).IsNull()); !ValidateCustomRecordType(record_type_).IsNull());
ScriptState::Scope scope(script_state); ScriptState::Scope scope(script_state);
v8::Local<v8::Value> json_object = FromJSONString( v8::Local<v8::Value> json_object =
script_state->GetIsolate(), script_state->GetContext(), FromJSONString(script_state->GetIsolate(), script_state->GetContext(),
String::FromUTF8WithLatin1Fallback(data_.data(), data_.size()), String::FromUTF8WithLatin1Fallback(payload_data_.data(),
exception_state); payload_data_.size()),
exception_state);
if (exception_state.HadException()) if (exception_state.HadException())
return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue::CreateNull(script_state->GetIsolate());
return ScriptValue(script_state->GetIsolate(), json_object); return ScriptValue(script_state->GetIsolate(), json_object);
} }
const WTF::Vector<uint8_t>& NDEFRecord::data() const { const WTF::Vector<uint8_t>& NDEFRecord::payloadData() const {
return data_; return payload_data_;
} }
void NDEFRecord::Trace(blink::Visitor* visitor) { void NDEFRecord::Trace(blink::Visitor* visitor) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
namespace blink { namespace blink {
class DOMArrayBuffer; class DOMArrayBuffer;
class DOMDataView;
class ExceptionState; class ExceptionState;
class NDEFRecordInit; class NDEFRecordInit;
class ScriptState; class ScriptState;
...@@ -38,11 +39,12 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable { ...@@ -38,11 +39,12 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable {
const String& recordType() const; const String& recordType() const;
const String& mediaType() const; const String& mediaType() const;
const String& id() const; const String& id() const;
DOMDataView* data() const;
String text() const; String text() const;
DOMArrayBuffer* arrayBuffer() const; DOMArrayBuffer* arrayBuffer() const;
ScriptValue json(ScriptState*, ExceptionState&) const; ScriptValue json(ScriptState*, ExceptionState&) const;
const WTF::Vector<uint8_t>& data() const; const WTF::Vector<uint8_t>& payloadData() const;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
...@@ -52,7 +54,7 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable { ...@@ -52,7 +54,7 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable {
String id_; String id_;
// Holds the NDEFRecord.[[PayloadData]] bytes defined at // Holds the NDEFRecord.[[PayloadData]] bytes defined at
// https://w3c.github.io/web-nfc/#the-ndefrecord-interface. // https://w3c.github.io/web-nfc/#the-ndefrecord-interface.
WTF::Vector<uint8_t> data_; WTF::Vector<uint8_t> payload_data_;
}; };
} // namespace blink } // namespace blink
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
readonly attribute NDEFRecordType recordType; readonly attribute NDEFRecordType recordType;
readonly attribute USVString mediaType; readonly attribute USVString mediaType;
readonly attribute USVString id; readonly attribute USVString id;
readonly attribute DataView? data;
USVString? text(); USVString? text();
[NewObject] ArrayBuffer? arrayBuffer(); [NewObject] ArrayBuffer? arrayBuffer();
[CallWith=ScriptState, RaisesException] object? json(); [CallWith=ScriptState, RaisesException] object? json();
......
...@@ -31,7 +31,7 @@ namespace mojo { ...@@ -31,7 +31,7 @@ namespace mojo {
NDEFRecordPtr TypeConverter<NDEFRecordPtr, ::blink::NDEFRecord*>::Convert( NDEFRecordPtr TypeConverter<NDEFRecordPtr, ::blink::NDEFRecord*>::Convert(
const ::blink::NDEFRecord* record) { const ::blink::NDEFRecord* record) {
return NDEFRecord::New(record->recordType(), record->mediaType(), return NDEFRecord::New(record->recordType(), record->mediaType(),
record->id(), record->data()); record->id(), record->payloadData());
} }
NDEFMessagePtr TypeConverter<NDEFMessagePtr, ::blink::NDEFMessage*>::Convert( NDEFMessagePtr TypeConverter<NDEFMessagePtr, ::blink::NDEFMessage*>::Convert(
......
...@@ -23,6 +23,11 @@ ...@@ -23,6 +23,11 @@
assert_equals(message.records.length, 1, 'one text record'); assert_equals(message.records.length, 1, 'one text record');
assert_equals(message.records[0].recordType, 'text', 'messageType'); assert_equals(message.records[0].recordType, 'text', 'messageType');
assert_equals(message.records[0].mediaType, 'text/plain', 'mediaType'); assert_equals(message.records[0].mediaType, 'text/plain', 'mediaType');
assert_true(message.records[0].data instanceof DataView,
'data returns a DataView');
const decoder = new TextDecoder();
assert_equals(decoder.decode(message.records[0].data), test_text_data,
'data contains the same text content');
assert_true(typeof message.records[0].text() === 'string'); assert_true(typeof message.records[0].text() === 'string');
assert_equals(message.records[0].text(), test_text_data, assert_equals(message.records[0].text(), test_text_data,
'text() contains the same text content'); 'text() contains the same text content');
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
const record = new NDEFRecord(createTextRecord(test_text_data)); const record = new NDEFRecord(createTextRecord(test_text_data));
assert_equals(record.recordType, 'text', 'recordType'); assert_equals(record.recordType, 'text', 'recordType');
assert_equals(record.mediaType, 'text/plain', 'mediaType'); assert_equals(record.mediaType, 'text/plain', 'mediaType');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_text_data,
'data has the same content with the original dictionary');
assert_equals(record.text(), test_text_data, assert_equals(record.text(), test_text_data,
'text() has the same content with the original dictionary'); 'text() has the same content with the original dictionary');
}, 'NDEFRecord constructor with text record type'); }, 'NDEFRecord constructor with text record type');
...@@ -28,6 +31,9 @@ ...@@ -28,6 +31,9 @@
const record = new NDEFRecord(createUrlRecord(test_url_data)); const record = new NDEFRecord(createUrlRecord(test_url_data));
assert_equals(record.recordType, 'url', 'recordType'); assert_equals(record.recordType, 'url', 'recordType');
assert_equals(record.mediaType, 'text/plain', 'mediaType'); assert_equals(record.mediaType, 'text/plain', 'mediaType');
const decoder = new TextDecoder();
assert_equals(decoder.decode(record.data), test_url_data,
'data has the same content with the original dictionary');
assert_equals(record.text(), test_url_data, assert_equals(record.text(), test_url_data,
'text() has the same content with the original dictionary'); 'text() has the same content with the original dictionary');
}, 'NDEFRecord constructor with url record type'); }, 'NDEFRecord constructor with url record type');
...@@ -40,6 +46,8 @@ ...@@ -40,6 +46,8 @@
const record = new NDEFRecord(createOpaqueRecord(buffer)); const record = new NDEFRecord(createOpaqueRecord(buffer));
assert_equals(record.recordType, 'opaque', 'recordType'); assert_equals(record.recordType, 'opaque', 'recordType');
assert_equals(record.mediaType, 'application/octet-stream', 'mediaType'); assert_equals(record.mediaType, 'application/octet-stream', 'mediaType');
assert_array_equals(new Uint8Array(record.data.buffer), original_data,
'data has the same content with the original buffer');
const data_1 = record.arrayBuffer(); const data_1 = record.arrayBuffer();
assert_true(data_1 instanceof ArrayBuffer); assert_true(data_1 instanceof ArrayBuffer);
......
This is a testharness.js-based test. This is a testharness.js-based test.
Found 88 tests; 80 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. Found 88 tests; 81 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
PASS idl_test setup PASS idl_test setup
PASS idl_test validation PASS idl_test validation
PASS NDEFMessage interface: existence and properties of interface object PASS NDEFMessage interface: existence and properties of interface object
...@@ -21,7 +21,7 @@ PASS NDEFRecord interface: existence and properties of interface prototype objec ...@@ -21,7 +21,7 @@ PASS NDEFRecord interface: existence and properties of interface prototype objec
PASS NDEFRecord interface: attribute recordType PASS NDEFRecord interface: attribute recordType
PASS NDEFRecord interface: attribute mediaType PASS NDEFRecord interface: attribute mediaType
PASS NDEFRecord interface: attribute id PASS NDEFRecord interface: attribute id
FAIL NDEFRecord interface: attribute data assert_true: The prototype object must have a property "data" expected true got false PASS NDEFRecord interface: attribute data
FAIL NDEFRecord interface: attribute encoding assert_true: The prototype object must have a property "encoding" expected true got false FAIL NDEFRecord interface: attribute encoding assert_true: The prototype object must have a property "encoding" expected true got false
FAIL NDEFRecord interface: attribute lang assert_true: The prototype object must have a property "lang" expected true got false FAIL NDEFRecord interface: attribute lang assert_true: The prototype object must have a property "lang" expected true got false
PASS NDEFRecord interface: operation text() PASS NDEFRecord interface: operation text()
...@@ -33,7 +33,7 @@ PASS Stringification of new NDEFRecord({"recordType":"text","mediaType":"text/pl ...@@ -33,7 +33,7 @@ PASS Stringification of new NDEFRecord({"recordType":"text","mediaType":"text/pl
PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "recordType" with the proper type PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "recordType" with the proper type
PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "mediaType" with the proper type PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "mediaType" with the proper type
PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "id" with the proper type PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "id" with the proper type
FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "data" with the proper type assert_inherits: property "data" not found in prototype chain FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "data" with the proper type Unrecognized type DataView
FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "encoding" with the proper type assert_inherits: property "encoding" not found in prototype chain FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "encoding" with the proper type assert_inherits: property "encoding" not found in prototype chain
FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "lang" with the proper type assert_inherits: property "lang" not found in prototype chain FAIL NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "lang" with the proper type assert_inherits: property "lang" not found in prototype chain
PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "text()" with the proper type PASS NDEFRecord interface: new NDEFRecord({"recordType":"text","mediaType":"text/plain","data":"Hello World","id":"/custom/path"}); must inherit property "text()" with the proper type
......
...@@ -152,6 +152,8 @@ function assertWebNDEFMessagesEqual(message, expectedMessage) { ...@@ -152,6 +152,8 @@ function assertWebNDEFMessagesEqual(message, expectedMessage) {
assert_equals(record.mediaType, expectedRecord.mediaType); assert_equals(record.mediaType, expectedRecord.mediaType);
// Compares record data // Compares record data
assert_array_equals(new Uint8Array(record.data),
new Uint8Array(expectedRecord.data));
assert_equals(record.text(), expectedRecord.text()); assert_equals(record.text(), expectedRecord.text());
assert_array_equals(new Uint8Array(record.arrayBuffer()), assert_array_equals(new Uint8Array(record.arrayBuffer()),
new Uint8Array(expectedRecord.arrayBuffer())); new Uint8Array(expectedRecord.arrayBuffer()));
......
...@@ -5135,6 +5135,7 @@ interface NDEFReadingEvent : Event ...@@ -5135,6 +5135,7 @@ interface NDEFReadingEvent : Event
method constructor method constructor
interface NDEFRecord interface NDEFRecord
attribute @@toStringTag attribute @@toStringTag
getter data
getter id getter id
getter mediaType getter mediaType
getter recordType getter recordType
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment