Revert "[Trusted Types] Remove TrustedURL."

This reverts commit 005483fe14c968325e6c8735eb6077049ee997ef.

Reason for revert: <INSERT REASONING HERE>
../../third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc(8,10): fatal error: 'third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h' file not found
#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"

Original change's description:
> [Trusted Types] Remove TrustedURL.
> 
> The current Trusted Types spec no longer supports TrustedURL. This CL adapts
> to the spec.
> 
> Bug: 1002555
> Change-Id: I35c6d8a257046558f155b9f38289457b14dcb1d2
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1834142
> Commit-Queue: Daniel Vogelheim <vogelheim@chromium.org>
> Reviewed-by: Mike West <mkwst@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#706886}

TBR=vogelheim@chromium.org,mkwst@chromium.org

Change-Id: I9012ad7c3f9f01389ab1aa7a90d5beb7873eab2c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1002555
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1866974
Reviewed-by: Lan Wei <lanwei@chromium.org>
Commit-Queue: Lan Wei <lanwei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706979}
diff --git a/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
index 40e897c5..ce3c5bd 100644
--- a/third_party/blink/renderer/bindings/core/v8/BUILD.gn
+++ b/third_party/blink/renderer/bindings/core/v8/BUILD.gn
@@ -90,8 +90,8 @@
   "$bindings_core_v8_output_dir/string_or_string_sequence.h",
   "$bindings_core_v8_output_dir/string_or_trusted_html.cc",
   "$bindings_core_v8_output_dir/string_or_trusted_html.h",
-  "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url.cc",
-  "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h",
+  "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.cc",
+  "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.h",
   "$bindings_core_v8_output_dir/string_or_trusted_script.cc",
   "$bindings_core_v8_output_dir/string_or_trusted_script.h",
   "$bindings_core_v8_output_dir/string_or_trusted_script_url.cc",
@@ -100,6 +100,8 @@
   "$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.h",
   "$bindings_core_v8_output_dir/string_treat_null_as_empty_string_or_trusted_script.cc",
   "$bindings_core_v8_output_dir/string_treat_null_as_empty_string_or_trusted_script.h",
+  "$bindings_core_v8_output_dir/usv_string_or_trusted_url.cc",
+  "$bindings_core_v8_output_dir/usv_string_or_trusted_url.h",
   "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.cc",
   "$bindings_core_v8_output_dir/usv_string_sequence_sequence_or_usv_string_usv_string_record_or_usv_string.h",
   "$bindings_core_v8_output_dir/unrestricted_double_or_keyframe_animation_options.cc",
diff --git a/third_party/blink/renderer/core/core_idl_files.gni b/third_party/blink/renderer/core/core_idl_files.gni
index e66c145..c2180f4 100644
--- a/third_party/blink/renderer/core/core_idl_files.gni
+++ b/third_party/blink/renderer/core/core_idl_files.gni
@@ -142,6 +142,7 @@
                     "trustedtypes/trusted_script_url.idl",
                     "trustedtypes/trusted_type_policy.idl",
                     "trustedtypes/trusted_type_policy_factory.idl",
+                    "trustedtypes/trusted_url.idl",
                     "editing/selection.idl",
                     "events/animation_event.idl",
                     "events/animation_playback_event.idl",
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 78f81486..fe3647ab 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -67,6 +67,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_element_creation_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_element_creation_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
@@ -277,6 +278,7 @@
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
 #include "third_party/blink/renderer/core/timing/window_performance.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/core/xml/parser/xml_document_parser.h"
 #include "third_party/blink/renderer/core/xml_names.h"
 #include "third_party/blink/renderer/core/xmlns_names.h"
@@ -3862,7 +3864,7 @@
 }
 
 DOMWindow* Document::open(v8::Isolate* isolate,
-                          const String& url_string,
+                          const USVStringOrTrustedURL& string_or_url,
                           const AtomicString& name,
                           const AtomicString& features,
                           ExceptionState& exception_state) {
@@ -3872,7 +3874,7 @@
     return nullptr;
   }
 
-  return domWindow()->open(isolate, url_string, name, features,
+  return domWindow()->open(isolate, string_or_url, name, features,
                            exception_state);
 }
 
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 7b14d1e..ee2f801 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -189,6 +189,7 @@
 class TextAutosizer;
 class TransformSource;
 class TreeWalker;
+class USVStringOrTrustedURL;
 class V8NodeFilter;
 class ViewportData;
 class VisitedLinkState;
@@ -628,7 +629,7 @@
                  const AtomicString& replace,
                  ExceptionState&);
   DOMWindow* open(v8::Isolate*,
-                  const String& url_string,
+                  const USVStringOrTrustedURL& string_or_url,
                   const AtomicString& name,
                   const AtomicString& features,
                   ExceptionState&);
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl
index ec4b33c9..f49890f 100644
--- a/third_party/blink/renderer/core/dom/document.idl
+++ b/third_party/blink/renderer/core/dom/document.idl
@@ -116,7 +116,7 @@
 
     // dynamic markup insertion
     [CallWith=Isolate, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=DocumentOpenTwoArgs] Document open(optional DOMString type = "text/html", optional DOMString replace = "");
-    [CallWith=Isolate, RaisesException, MeasureAs=DocumentOpenThreeArgs] Window open(USVString url, DOMString name, DOMString features);
+    [CallWith=Isolate, RaisesException, MeasureAs=DocumentOpenThreeArgs] Window open(URLString url, DOMString name, DOMString features);
     [CEReactions, RaisesException] void close();
     [CallWith=Isolate, CEReactions, CustomElementCallbacks, RaisesException] void write(DOMString... text);
     [CallWith=Isolate, CEReactions, CustomElementCallbacks, RaisesException] void writeln(DOMString... text);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 71abe56..24b28a86 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -35,9 +35,10 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/scroll_into_view_options_or_boolean.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/animation/css/css_animations.h"
@@ -2167,7 +2168,8 @@
 
 void Element::setAttribute(
     const AtomicString& local_name,
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& string_or_TT,
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
+        string_or_TT,
     ExceptionState& exception_state) {
   if (!Document::IsValidName(local_name)) {
     exception_state.ThrowDOMException(
@@ -2253,6 +2255,16 @@
   }
 }
 
+void Element::setAttribute(const QualifiedName& name,
+                           const USVStringOrTrustedURL& stringOrURL,
+                           ExceptionState& exception_state) {
+  String valueString =
+      GetStringFromTrustedURL(stringOrURL, &GetDocument(), exception_state);
+  if (!exception_state.HadException()) {
+    setAttribute(name, AtomicString(valueString));
+  }
+}
+
 ALWAYS_INLINE void Element::SetAttributeInternal(
     wtf_size_t index,
     const QualifiedName& name,
@@ -3865,7 +3877,8 @@
 void Element::setAttributeNS(
     const AtomicString& namespace_uri,
     const AtomicString& qualified_name,
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL& string_or_TT,
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
+        string_or_TT,
     ExceptionState& exception_state) {
   QualifiedName parsed_name = g_any_name;
   if (!ParseAttributeName(parsed_name, namespace_uri, qualified_name,
@@ -5286,6 +5299,18 @@
   result.SetString(url.GetString());
 }
 
+void Element::GetURLAttribute(const QualifiedName& name,
+                              USVStringOrTrustedURL& result) const {
+  String url = GetURLAttribute(name);
+  result.SetUSVString(url);
+}
+
+void Element::FastGetAttribute(const QualifiedName& name,
+                               USVStringOrTrustedURL& result) const {
+  String attr = FastGetAttribute(name);
+  result.SetUSVString(attr);
+}
+
 void Element::FastGetAttribute(const QualifiedName& name,
                                StringOrTrustedHTML& result) const {
   String html = FastGetAttribute(name);
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index cd12ff6..fc0f084 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -85,11 +85,12 @@
 class ShadowRootInit;
 class SpaceSplitString;
 class StringOrTrustedHTML;
-class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL;
+class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL;
 class StringOrTrustedScript;
 class StringOrTrustedScriptURL;
 class StylePropertyMap;
 class StylePropertyMapReadOnly;
+class USVStringOrTrustedURL;
 class V0CustomElementDefinition;
 
 enum class CSSPropertyID;
@@ -241,9 +242,10 @@
   void setAttribute(const AtomicString& name, const AtomicString& value);
 
   // Trusted Types variant for explicit setAttribute() use.
-  void setAttribute(const AtomicString&,
-                    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
-                    ExceptionState&);
+  void setAttribute(
+      const AtomicString&,
+      const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&,
+      ExceptionState&);
 
   // Returns attributes that should be checked against Trusted Types
   virtual const AttrNameToTrustedType& GetCheckedAttributeTypes() const;
@@ -263,6 +265,11 @@
                     const StringOrTrustedScriptURL&,
                     ExceptionState&);
 
+  // Trusted Type URL variant
+  void setAttribute(const QualifiedName&,
+                    const USVStringOrTrustedURL&,
+                    ExceptionState&);
+
   static bool ParseAttributeName(QualifiedName&,
                                  const AtomicString& namespace_uri,
                                  const AtomicString& qualified_name,
@@ -270,7 +277,7 @@
   void setAttributeNS(
       const AtomicString& namespace_uri,
       const AtomicString& qualified_name,
-      const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
+      const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&,
       ExceptionState&);
 
   bool toggleAttribute(const AtomicString&, ExceptionState&);
@@ -636,6 +643,8 @@
 
   KURL GetURLAttribute(const QualifiedName&) const;
   void GetURLAttribute(const QualifiedName&, StringOrTrustedScriptURL&) const;
+  void GetURLAttribute(const QualifiedName&, USVStringOrTrustedURL&) const;
+  void FastGetAttribute(const QualifiedName&, USVStringOrTrustedURL&) const;
   void FastGetAttribute(const QualifiedName&, StringOrTrustedHTML&) const;
 
   KURL GetNonEmptyURLAttribute(const QualifiedName&) const;
diff --git a/third_party/blink/renderer/core/execution_context/agent_metrics_collector_test.cc b/third_party/blink/renderer/core/execution_context/agent_metrics_collector_test.cc
index e76d54a..bbe63d4 100644
--- a/third_party/blink/renderer/core/execution_context/agent_metrics_collector_test.cc
+++ b/third_party/blink/renderer/core/execution_context/agent_metrics_collector_test.cc
@@ -6,12 +6,14 @@
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/default_tick_clock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/location.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/testing/histogram_tester.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index 665766a..4c25b573 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -82,6 +82,7 @@
 #include "third_party/blink/public/web/web_view_client.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
 #include "third_party/blink/renderer/core/clipboard/data_transfer.h"
@@ -146,6 +147,7 @@
 #include "third_party/blink/renderer/core/testing/scoped_fake_plugin_registry.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
 #include "third_party/blink/renderer/platform/cursor.h"
 #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h"
@@ -9611,15 +9613,20 @@
   ScriptState::Scope entered_context_scope(script_state);
   v8::Context::BackupIncumbentScope incumbent_context_scope(
       script_state->GetContext());
-  main_window->open(script_state->GetIsolate(), destination, "frame1", "",
-                    exception_state);
+  main_window->open(script_state->GetIsolate(),
+                    USVStringOrTrustedURL::FromTrustedURL(
+                        MakeGarbageCollected<TrustedURL>(destination)),
+                    "frame1", "", exception_state);
   ASSERT_FALSE(remote_client.LastRequest().IsNull());
   EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(KURL(destination)));
 
   // Pointing a named frame to an empty URL should just return a reference to
   // the frame's window without navigating it.
-  DOMWindow* result = main_window->open(script_state->GetIsolate(), "",
-                                        "frame1", "", exception_state);
+  DOMWindow* result =
+      main_window->open(script_state->GetIsolate(),
+                        USVStringOrTrustedURL::FromTrustedURL(
+                            MakeGarbageCollected<TrustedURL>("")),
+                        "frame1", "", exception_state);
   EXPECT_EQ(remote_client.LastRequest().Url(), WebURL(KURL(destination)));
   EXPECT_EQ(result, WebFrame::ToCoreFrame(*remote_frame)->DomWindow());
 
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 9795e55..9cd3e52 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"
 #include "third_party/blink/renderer/core/accessibility/ax_context.h"
@@ -1439,7 +1440,7 @@
 }
 
 DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
-                                const String& url_string,
+                                const USVStringOrTrustedURL& string_or_url,
                                 const AtomicString& target,
                                 const String& features,
                                 ExceptionState& exception_state) {
@@ -1457,6 +1458,11 @@
     return nullptr;
   }
 
+  const String& url_string =
+      GetStringFromTrustedURL(string_or_url, document_, exception_state);
+  if (exception_state.HadException())
+    return nullptr;
+
   if (!IsCurrentlyDisplayedInFrame())
     return nullptr;
   if (!incumbent_window->GetFrame())
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 80f0b4e..96a0092 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -71,6 +71,7 @@
 class SourceLocation;
 class StyleMedia;
 class TrustedTypePolicyFactory;
+class USVStringOrTrustedURL;
 class V8FrameRequestCallback;
 class V8IdleRequestCallback;
 class V8VoidFunction;
@@ -264,7 +265,7 @@
   Element* frameElement() const;
 
   DOMWindow* open(v8::Isolate*,
-                  const String& url_string,
+                  const USVStringOrTrustedURL& string_or_url,
                   const AtomicString& target,
                   const String& features,
                   ExceptionState&);
diff --git a/third_party/blink/renderer/core/frame/location.cc b/third_party/blink/renderer/core/frame/location.cc
index 1d21eaa..3acc96e 100644
--- a/third_party/blink/renderer/core/frame/location.cc
+++ b/third_party/blink/renderer/core/frame/location.cc
@@ -29,7 +29,7 @@
 #include "third_party/blink/renderer/core/frame/location.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/dom_window.h"
@@ -37,6 +37,7 @@
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
 #include "third_party/blink/renderer/core/loader/frame_loader.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
 #include "third_party/blink/renderer/core/url/dom_url_utils_read_only.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_dom_activity_logger.h"
@@ -66,8 +67,8 @@
   return url;
 }
 
-String Location::href() const {
-  return Url().StrippedForUseAsHref();
+void Location::href(USVStringOrTrustedURL& result) const {
+  result.SetUSVString(Url().StrippedForUseAsHref());
 }
 
 String Location::protocol() const {
@@ -115,7 +116,10 @@
 }
 
 String Location::toString() const {
-  return href();
+  USVStringOrTrustedURL result;
+  href(result);
+  DCHECK(result.IsUSVString());
+  return result.GetAsUSVString();
 }
 
 String Location::hash() const {
@@ -123,11 +127,17 @@
 }
 
 void Location::setHref(v8::Isolate* isolate,
-                       const String& url_string,
+                       const USVStringOrTrustedURL& string_or_url,
                        ExceptionState& exception_state) {
   LocalDOMWindow* incumbent_window = IncumbentDOMWindow(isolate);
   LocalDOMWindow* entered_window = EnteredDOMWindow(isolate);
-  SetLocation(url_string, incumbent_window, entered_window, &exception_state);
+
+  const String& url = GetStringFromTrustedURL(
+      string_or_url, incumbent_window->document(), exception_state);
+  if (exception_state.HadException())
+    return;
+
+  SetLocation(url, incumbent_window, entered_window, &exception_state);
 }
 
 void Location::setProtocol(v8::Isolate* isolate,
@@ -209,19 +219,31 @@
 }
 
 void Location::assign(v8::Isolate* isolate,
-                      const String& url_string,
+                      const USVStringOrTrustedURL& string_or_url,
                       ExceptionState& exception_state) {
   LocalDOMWindow* incumbent_window = IncumbentDOMWindow(isolate);
   LocalDOMWindow* entered_window = EnteredDOMWindow(isolate);
-  SetLocation(url_string, incumbent_window, entered_window, &exception_state);
+
+  const String& url = GetStringFromTrustedURL(
+      string_or_url, incumbent_window->document(), exception_state);
+  if (exception_state.HadException())
+    return;
+
+  SetLocation(url, incumbent_window, entered_window, &exception_state);
 }
 
 void Location::replace(v8::Isolate* isolate,
-                       const String& url_string,
+                       const USVStringOrTrustedURL& string_or_url,
                        ExceptionState& exception_state) {
   LocalDOMWindow* incumbent_window = IncumbentDOMWindow(isolate);
   LocalDOMWindow* entered_window = EnteredDOMWindow(isolate);
-  SetLocation(url_string, incumbent_window, entered_window, &exception_state,
+
+  const String& url = GetStringFromTrustedURL(
+      string_or_url, incumbent_window->document(), exception_state);
+  if (exception_state.HadException())
+    return;
+
+  SetLocation(url, incumbent_window, entered_window, &exception_state,
               SetLocationPolicy::kReplaceThisFrame);
 }
 
diff --git a/third_party/blink/renderer/core/frame/location.h b/third_party/blink/renderer/core/frame/location.h
index 5708dec..12b6870b 100644
--- a/third_party/blink/renderer/core/frame/location.h
+++ b/third_party/blink/renderer/core/frame/location.h
@@ -43,6 +43,7 @@
 class ExceptionState;
 class KURL;
 class LocalDOMWindow;
+class USVStringOrTrustedURL;
 
 // This class corresponds to the Location interface. Location is the only
 // interface besides Window that is accessible cross-origin and must handle
@@ -57,11 +58,11 @@
 
   DOMWindow* DomWindow() const { return dom_window_.Get(); }
 
-  void setHref(v8::Isolate*, const String&, ExceptionState&);
-  String href() const;
+  void setHref(v8::Isolate*, const USVStringOrTrustedURL&, ExceptionState&);
+  void href(USVStringOrTrustedURL&) const;
 
-  void assign(v8::Isolate*, const String&, ExceptionState&);
-  void replace(v8::Isolate*, const String&, ExceptionState&);
+  void assign(v8::Isolate*, const USVStringOrTrustedURL&, ExceptionState&);
+  void replace(v8::Isolate*, const USVStringOrTrustedURL&, ExceptionState&);
   void reload();
 
   void setProtocol(v8::Isolate*, const String&, ExceptionState&);
diff --git a/third_party/blink/renderer/core/frame/location.idl b/third_party/blink/renderer/core/frame/location.idl
index dd303cec..bfcda81 100644
--- a/third_party/blink/renderer/core/frame/location.idl
+++ b/third_party/blink/renderer/core/frame/location.idl
@@ -32,7 +32,7 @@
     CheckSecurity=Receiver,
     Exposed=Window
 ] interface Location {
-    [CallWith=Isolate, RaisesException, Unforgeable] void assign(USVString url);
+    [CallWith=Isolate, RaisesException, Unforgeable] void assign(URLString url);
 
     // |replace|, and *writing* |href| do not require a security check, as they
     // *change* the page, and thus these do not change any property of an
@@ -40,13 +40,13 @@
     // However, *reading* |href|, or accessing any component, is a security
     // problem, since that allows tracking navigation.
     // https://html.spec.whatwg.org/C/#crossoriginproperties-(-o-)
-    [CallWith=Isolate, CrossOrigin, RaisesException, Unforgeable] void replace(USVString url);
+    [CallWith=Isolate, CrossOrigin, RaisesException, Unforgeable] void replace(URLString url);
     [Unforgeable] void reload();
 
     // TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject].
     [Unforgeable] readonly attribute DOMStringList ancestorOrigins;
 
-    [Affects=Nothing, SetterCallWith=Isolate, CrossOrigin=Setter, RaisesException=Setter, Unforgeable] attribute USVString href;
+    [Affects=Nothing, SetterCallWith=Isolate, CrossOrigin=Setter, RaisesException=Setter, Unforgeable] attribute URLString href;
     // TODO(yukishiino): Use [Unforgeable] stringifier instead of toString.
     [Unforgeable] DOMString toString();
     [MeasureAs=LocationOrigin, Unforgeable] readonly attribute USVString origin;
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl
index 7805477..0e43da8f 100644
--- a/third_party/blink/renderer/core/frame/window.idl
+++ b/third_party/blink/renderer/core/frame/window.idl
@@ -63,7 +63,7 @@
     [CrossOrigin, Custom=Setter] attribute Window opener;
     [Replaceable, CrossOrigin] readonly attribute Window? parent;
     [CheckSecurity=ReturnValue, Custom=Getter] readonly attribute Element? frameElement;
-    [CallWith=Isolate, RaisesException] Window? open(optional USVString url="", optional DOMString target = "_blank", optional [TreatNullAs=EmptyString] DOMString features = "");
+    [CallWith=Isolate, RaisesException] Window? open(optional URLString url="", optional DOMString target = "_blank", optional [TreatNullAs=EmptyString] DOMString features = "");
 
     // indexed properties
     // https://html.spec.whatwg.org/C/browsers.html#windowproxy-getownproperty
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.cc b/third_party/blink/renderer/core/html/forms/html_button_element.cc
index e4c3beb..5e2afac3 100644
--- a/third_party/blink/renderer/core/html/forms/html_button_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_button_element.cc
@@ -43,6 +43,13 @@
       type_(SUBMIT),
       is_activated_submit_(false) {}
 
+const AttrNameToTrustedType& HTMLButtonElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"formaction", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLButtonElement::setType(const AtomicString& type) {
   setAttribute(kTypeAttr, type);
 }
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.h b/third_party/blink/renderer/core/html/forms/html_button_element.h
index ec16b1f..0aaf454 100644
--- a/third_party/blink/renderer/core/html/forms/html_button_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_button_element.h
@@ -34,6 +34,8 @@
  public:
   explicit HTMLButtonElement(Document&);
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   void setType(const AtomicString&);
 
   const AtomicString& Value() const;
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.idl b/third_party/blink/renderer/core/html/forms/html_button_element.idl
index b72d250..ab21763b 100644
--- a/third_party/blink/renderer/core/html/forms/html_button_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_button_element.idl
@@ -25,7 +25,7 @@
 ] interface HTMLButtonElement : HTMLElement {
     [CEReactions, Reflect] attribute boolean disabled;
     [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form;
-    [CEReactions] attribute USVString formAction;
+    [CEReactions, RaisesException=Setter] attribute URLString formAction;
     [CEReactions] attribute DOMString formEnctype;
     [CEReactions] attribute DOMString formMethod;
     [CEReactions, Reflect] attribute boolean formNoValidate;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
index acc3d40..aa18e64 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -24,6 +24,7 @@
 
 #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
@@ -59,16 +60,19 @@
   HTMLElement::Trace(visitor);
 }
 
-String HTMLFormControlElement::formAction() const {
+void HTMLFormControlElement::formAction(USVStringOrTrustedURL& result) const {
   const AtomicString& action = FastGetAttribute(kFormactionAttr);
   if (action.IsEmpty()) {
-    return GetDocument().Url();
+    result.SetUSVString(GetDocument().Url());
+    return;
   }
-  return GetDocument().CompleteURL(StripLeadingAndTrailingHTMLSpaces(action));
+  result.SetUSVString(
+      GetDocument().CompleteURL(StripLeadingAndTrailingHTMLSpaces(action)));
 }
 
-void HTMLFormControlElement::setFormAction(const AtomicString& value) {
-  setAttribute(kFormactionAttr, value);
+void HTMLFormControlElement::setFormAction(const USVStringOrTrustedURL& value,
+                                           ExceptionState& exception_state) {
+  setAttribute(kFormactionAttr, value, exception_state);
 }
 
 String HTMLFormControlElement::formEnctype() const {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/third_party/blink/renderer/core/html/forms/html_form_control_element.h
index a4f9716..dd72657 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.h
@@ -49,8 +49,8 @@
   ~HTMLFormControlElement() override;
   void Trace(Visitor*) override;
 
-  String formAction() const;
-  void setFormAction(const AtomicString&);
+  void formAction(USVStringOrTrustedURL&) const;
+  void setFormAction(const USVStringOrTrustedURL&, ExceptionState&);
   String formEnctype() const;
   void setFormEnctype(const AtomicString&);
   String formMethod() const;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc
index 98908f03..2340e4bc 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/radio_node_list_or_element.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element_traversal.h"
@@ -97,6 +98,12 @@
   HTMLElement::Trace(visitor);
 }
 
+const AttrNameToTrustedType& HTMLFormElement::GetCheckedAttributeTypes() const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"action", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 bool HTMLFormElement::MatchesValidityPseudoClasses() const {
   return true;
 }
@@ -716,8 +723,13 @@
   return action_url.GetString();
 }
 
-void HTMLFormElement::setAction(const AtomicString& value) {
-  setAttribute(kActionAttr, value);
+void HTMLFormElement::action(USVStringOrTrustedURL& result) const {
+  result.SetUSVString(action());
+}
+
+void HTMLFormElement::setAction(const USVStringOrTrustedURL& value,
+                                ExceptionState& exception_state) {
+  setAttribute(kActionAttr, value, exception_state);
 }
 
 void HTMLFormElement::setEnctype(const AtomicString& value) {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.h b/third_party/blink/renderer/core/html/forms/html_form_element.h
index 3375fb2..ae78e4f5 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.h
@@ -48,6 +48,8 @@
   ~HTMLFormElement() override;
   void Trace(Visitor*) override;
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   HTMLFormControlsCollection* elements();
   void GetNamedElements(const AtomicString&, HeapVector<Member<Element>>&);
 
@@ -55,7 +57,8 @@
   HTMLElement* item(unsigned index);
 
   String action() const;
-  void setAction(const AtomicString&);
+  void action(USVStringOrTrustedURL&) const;
+  void setAction(const USVStringOrTrustedURL&, ExceptionState&);
 
   String enctype() const { return attributes_.EncodingType(); }
   void setEnctype(const AtomicString&);
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.idl b/third_party/blink/renderer/core/html/forms/html_form_element.idl
index 4a5986bc..9d7b6360 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_form_element.idl
@@ -26,7 +26,7 @@
     OverrideBuiltins
 ] interface HTMLFormElement : HTMLElement {
     [CEReactions, Reflect=accept_charset] attribute DOMString acceptCharset;
-    [CEReactions, URL] attribute USVString action;
+    [CEReactions, URL, RaisesException=Setter] attribute URLString action;
     [CEReactions, Reflect, ReflectOnly=("on","off"), ReflectMissing="on", ReflectInvalid="on"] attribute DOMString autocomplete;
     [CEReactions, CustomElementCallbacks] attribute DOMString enctype;
     [CEReactions, CustomElementCallbacks] attribute DOMString encoding;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 3927456..107d2dc 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -141,6 +141,14 @@
   TextControlElement::Trace(visitor);
 }
 
+const AttrNameToTrustedType& HTMLInputElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"formaction", SpecificTrustedType::kTrustedURL},
+                        {"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 bool HTMLInputElement::HasPendingActivity() const {
   return ImageLoader() && ImageLoader()->HasPendingActivity();
 }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 6a2ddc79..0795e67 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -59,6 +59,9 @@
   ~HTMLInputElement() override;
   void Trace(Visitor*) override;
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   bool HasPendingActivity() const final;
 
   DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange, kWebkitspeechchange)
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.idl b/third_party/blink/renderer/core/html/forms/html_input_element.idl
index d30385b..fe03008 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.idl
@@ -39,7 +39,7 @@
     // The 'files' attribute is intentionally not readonly.
     // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22682
     attribute FileList? files;
-    [CEReactions] attribute DOMString formAction;
+    [CEReactions, RaisesException=Setter] attribute URLString formAction;
     [CEReactions, CustomElementCallbacks] attribute DOMString formEnctype;
     [CEReactions, CustomElementCallbacks] attribute DOMString formMethod;
     [CEReactions, Reflect] attribute boolean formNoValidate;
@@ -58,7 +58,7 @@
     [CEReactions, Reflect] attribute boolean readOnly;
     [CEReactions, Reflect] attribute boolean required;
     [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute unsigned long size;
-    [CEReactions, Reflect, URL] attribute DOMString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions, Reflect] attribute DOMString step;
     [CEReactions, CustomElementCallbacks] attribute DOMString type;
     [CEReactions, Reflect=value, CustomElementCallbacks] attribute DOMString defaultValue;
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index e9a0bc7d..a284d4bb 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -28,6 +28,7 @@
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_prescient_networking.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
@@ -46,6 +47,8 @@
 #include "third_party/blink/renderer/core/loader/ping_loader.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
@@ -211,6 +214,13 @@
   HTMLElement::SetActive(active);
 }
 
+const AttrNameToTrustedType& HTMLAnchorElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"href", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLAnchorElement::AttributeChanged(
     const AttributeModificationParams& params) {
   HTMLElement::AttributeChanged(params);
@@ -298,6 +308,11 @@
   setAttribute(kHrefAttr, value);
 }
 
+void HTMLAnchorElement::setHref(const USVStringOrTrustedURL& stringOrTrustedURL,
+                                ExceptionState& exception_state) {
+  setAttribute(kHrefAttr, stringOrTrustedURL, exception_state);
+}
+
 KURL HTMLAnchorElement::Url() const {
   return Href();
 }
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.h b/third_party/blink/renderer/core/html/html_anchor_element.h
index f978027e..402055f 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.h
+++ b/third_party/blink/renderer/core/html/html_anchor_element.h
@@ -58,6 +58,9 @@
   kRelationNoOpener = 0x00040000,
 };
 
+class ExceptionState;
+class USVStringOrTrustedURL;
+
 class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
   DEFINE_WRAPPERTYPEINFO();
 
@@ -66,8 +69,12 @@
   HTMLAnchorElement(const QualifiedName&, Document&);
   ~HTMLAnchorElement() override;
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   KURL Href() const;
   void SetHref(const AtomicString&);
+  void setHref(const USVStringOrTrustedURL&, ExceptionState&);
 
   const AtomicString& GetName() const;
 
diff --git a/third_party/blink/renderer/core/html/html_base_element.cc b/third_party/blink/renderer/core/html/html_base_element.cc
index e3e89b8..699ed554 100644
--- a/third_party/blink/renderer/core/html/html_base_element.cc
+++ b/third_party/blink/renderer/core/html/html_base_element.cc
@@ -22,11 +22,13 @@
 
 #include "third_party/blink/renderer/core/html/html_base_element.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/attribute.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
 #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
 #include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 
 namespace blink {
 
@@ -35,6 +37,12 @@
 HTMLBaseElement::HTMLBaseElement(Document& document)
     : HTMLElement(kBaseTag, document) {}
 
+const AttrNameToTrustedType& HTMLBaseElement::GetCheckedAttributeTypes() const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"href", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLBaseElement::ParseAttribute(
     const AttributeModificationParams& params) {
   if (params.name == kHrefAttr || params.name == kTargetAttr)
@@ -62,6 +70,10 @@
          HTMLElement::IsURLAttribute(attribute);
 }
 
+void HTMLBaseElement::href(USVStringOrTrustedURL& result) const {
+  result.SetUSVString(href());
+}
+
 KURL HTMLBaseElement::href() const {
   // This does not use the GetURLAttribute function because that will resolve
   // relative to the document's base URL; base elements like this one can be
@@ -86,8 +98,9 @@
   return url;
 }
 
-void HTMLBaseElement::setHref(const AtomicString& url_string) {
-  setAttribute(kHrefAttr, url_string);
+void HTMLBaseElement::setHref(const USVStringOrTrustedURL& stringOrUrl,
+                              ExceptionState& exception_state) {
+  setAttribute(kHrefAttr, stringOrUrl, exception_state);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_base_element.h b/third_party/blink/renderer/core/html/html_base_element.h
index e79523a..c7a4207 100644
--- a/third_party/blink/renderer/core/html/html_base_element.h
+++ b/third_party/blink/renderer/core/html/html_base_element.h
@@ -27,14 +27,21 @@
 
 namespace blink {
 
+class ExceptionState;
+class USVStringOrTrustedURL;
+
 class HTMLBaseElement final : public HTMLElement {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
   explicit HTMLBaseElement(Document&);
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   KURL href() const;
-  void setHref(const AtomicString&);
+  void href(USVStringOrTrustedURL&) const;
+  void setHref(const USVStringOrTrustedURL&, ExceptionState&);
 
  private:
   bool IsURLAttribute(const Attribute&) const override;
diff --git a/third_party/blink/renderer/core/html/html_base_element.idl b/third_party/blink/renderer/core/html/html_base_element.idl
index c9ec787..40e2384 100644
--- a/third_party/blink/renderer/core/html/html_base_element.idl
+++ b/third_party/blink/renderer/core/html/html_base_element.idl
@@ -22,6 +22,6 @@
     Exposed=Window,
     HTMLConstructor
 ] interface HTMLBaseElement : HTMLElement {
-    [CEReactions] attribute USVString href;
+    [CEReactions, RaisesException=Setter] attribute URLString href;
     [CEReactions, Reflect] attribute DOMString target;
 };
diff --git a/third_party/blink/renderer/core/html/html_frame_element.cc b/third_party/blink/renderer/core/html/html_frame_element.cc
index bba19e5..16afe15 100644
--- a/third_party/blink/renderer/core/html/html_frame_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_element.cc
@@ -38,6 +38,13 @@
       frame_border_(true),
       frame_border_set_(false) {}
 
+const AttrNameToTrustedType& HTMLFrameElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 bool HTMLFrameElement::LayoutObjectIsNeeded(const ComputedStyle&) const {
   // For compatibility, frames render even when display: none is set.
   return ContentFrame();
diff --git a/third_party/blink/renderer/core/html/html_frame_element.h b/third_party/blink/renderer/core/html/html_frame_element.h
index f51994b..895c4a2e 100644
--- a/third_party/blink/renderer/core/html/html_frame_element.h
+++ b/third_party/blink/renderer/core/html/html_frame_element.h
@@ -37,6 +37,9 @@
  public:
   explicit HTMLFrameElement(Document&);
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   bool HasFrameBorder() const { return frame_border_; }
 
   bool NoResize() const;
diff --git a/third_party/blink/renderer/core/html/html_frame_element.idl b/third_party/blink/renderer/core/html/html_frame_element.idl
index 9de00a3..5a52b78 100644
--- a/third_party/blink/renderer/core/html/html_frame_element.idl
+++ b/third_party/blink/renderer/core/html/html_frame_element.idl
@@ -26,7 +26,7 @@
 ] interface HTMLFrameElement : HTMLElement {
     [CEReactions, Reflect] attribute DOMString name;
     [CEReactions, Reflect] attribute DOMString scrolling;
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions, Reflect] attribute DOMString frameBorder;
     [CEReactions, Reflect, URL] attribute USVString longDesc;
     [CEReactions, Reflect] attribute boolean noResize;
diff --git a/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl b/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
index 61d0a03..e46519a9 100644
--- a/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
+++ b/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl
@@ -6,7 +6,7 @@
 
 interface mixin HTMLHyperlinkElementUtils {
 
-    [CEReactions] stringifier attribute USVString href;
+    [CEReactions, RaisesException=Setter] stringifier attribute URLString href;
     readonly attribute USVString origin;
 
     [CEReactions] attribute USVString protocol;
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc
index 1b1443d4..ec01780 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.cc
+++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -64,7 +64,8 @@
 const AttrNameToTrustedType& HTMLIFrameElement::GetCheckedAttributeTypes()
     const {
   DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
-                      ({{"srcdoc", SpecificTrustedType::kTrustedHTML}}));
+                      ({{"src", SpecificTrustedType::kTrustedURL},
+                        {"srcdoc", SpecificTrustedType::kTrustedHTML}}));
   return attribute_map;
 }
 
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.idl b/third_party/blink/renderer/core/html/html_iframe_element.idl
index ef2f5e2..026dd50 100644
--- a/third_party/blink/renderer/core/html/html_iframe_element.idl
+++ b/third_party/blink/renderer/core/html/html_iframe_element.idl
@@ -20,14 +20,14 @@
 
 // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#htmliframeelement
 
-// The `HTMLString` references below are from Trusted Types:
+// The `HTMLString` and `URLString` references below are from Trusted Types:
 // https://github.com/WICG/trusted-types/, which is still WIP.
 // https://crbug.com/739170.
 [
     Exposed=Window,
     HTMLConstructor
 ] interface HTMLIFrameElement : HTMLElement {
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions, Reflect, RaisesException=Setter] attribute HTMLString srcdoc;
     [CEReactions, Reflect] attribute DOMString name;
     [PutForwards=value] readonly attribute DOMTokenList sandbox;
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index fb6ce59..c7732687 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -62,6 +62,7 @@
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/style/content_data.h"
 #include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/network/mime/content_type.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -125,6 +126,13 @@
   HTMLElement::Trace(visitor);
 }
 
+const AttrNameToTrustedType& HTMLImageElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLImageElement::NotifyViewportChanged() {
   // Re-selecting the source URL in order to pick a more fitting resource
   // And update the image's intrinsic dimensions when the viewport changes.
diff --git a/third_party/blink/renderer/core/html/html_image_element.h b/third_party/blink/renderer/core/html/html_image_element.h
index 83876cf0..0ae4d630 100644
--- a/third_party/blink/renderer/core/html/html_image_element.h
+++ b/third_party/blink/renderer/core/html/html_image_element.h
@@ -58,6 +58,9 @@
  public:
   class ViewportChangeListener;
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   static HTMLImageElement* CreateForJSConstructor(Document&);
   static HTMLImageElement* CreateForJSConstructor(Document&, unsigned width);
   static HTMLImageElement* CreateForJSConstructor(Document&,
diff --git a/third_party/blink/renderer/core/html/html_image_element.idl b/third_party/blink/renderer/core/html/html_image_element.idl
index 794e413..5a1efad 100644
--- a/third_party/blink/renderer/core/html/html_image_element.idl
+++ b/third_party/blink/renderer/core/html/html_image_element.idl
@@ -28,7 +28,7 @@
     NamedConstructor=Image(optional unsigned long width, optional unsigned long height)
 ] interface HTMLImageElement : HTMLElement {
     [CEReactions, Reflect] attribute DOMString alt;
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions, Reflect] attribute DOMString srcset;
     [CEReactions, Reflect] attribute DOMString sizes;
     [CEReactions, Reflect, ReflectOnly=("anonymous","use-credentials"), ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString? crossOrigin;
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc
index 88c893f..a5239718 100644
--- a/third_party/blink/renderer/core/html/html_link_element.cc
+++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -64,6 +64,12 @@
 
 HTMLLinkElement::~HTMLLinkElement() = default;
 
+const AttrNameToTrustedType& HTMLLinkElement::GetCheckedAttributeTypes() const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"href", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLLinkElement::ParseAttribute(
     const AttributeModificationParams& params) {
   const QualifiedName& name = params.name;
diff --git a/third_party/blink/renderer/core/html/html_link_element.h b/third_party/blink/renderer/core/html/html_link_element.h
index fc24de7..480e26e 100644
--- a/third_party/blink/renderer/core/html/html_link_element.h
+++ b/third_party/blink/renderer/core/html/html_link_element.h
@@ -55,6 +55,9 @@
   HTMLLinkElement(Document&, const CreateElementFlags);
   ~HTMLLinkElement() override;
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   KURL Href() const;
   const AtomicString& Rel() const;
   String Media() const { return media_; }
diff --git a/third_party/blink/renderer/core/html/html_link_element.idl b/third_party/blink/renderer/core/html/html_link_element.idl
index f890890..c2841765 100644
--- a/third_party/blink/renderer/core/html/html_link_element.idl
+++ b/third_party/blink/renderer/core/html/html_link_element.idl
@@ -27,7 +27,7 @@
     // FIXME: The disabled attribute has been removed from the spec:
     // https://www.w3.org/Bugs/Public/show_bug.cgi?id=14703
     [Reflect, Measure] attribute boolean disabled;
-    [Reflect, URL] attribute USVString href;
+    [Reflect, URL, RaisesException=Setter] attribute URLString href;
     [CEReactions, Reflect, ReflectOnly=("anonymous","use-credentials"), ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString? crossOrigin;
     [CEReactions, Reflect] attribute DOMString rel;
     [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
diff --git a/third_party/blink/renderer/core/html/html_source_element.cc b/third_party/blink/renderer/core/html/html_source_element.cc
index a8739e5..ff29f8c 100644
--- a/third_party/blink/renderer/core/html/html_source_element.cc
+++ b/third_party/blink/renderer/core/html/html_source_element.cc
@@ -34,6 +34,7 @@
 #include "third_party/blink/renderer/core/html/html_picture_element.h"
 #include "third_party/blink/renderer/core/html/media/html_media_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
 #define SOURCE_LOG_LEVEL 3
@@ -68,6 +69,13 @@
 
 HTMLSourceElement::~HTMLSourceElement() = default;
 
+const AttrNameToTrustedType& HTMLSourceElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 void HTMLSourceElement::CreateMediaQueryList(const AtomicString& media) {
   RemoveMediaQueryListListener();
   if (media.IsEmpty()) {
diff --git a/third_party/blink/renderer/core/html/html_source_element.h b/third_party/blink/renderer/core/html/html_source_element.h
index 578e2ee..e606983 100644
--- a/third_party/blink/renderer/core/html/html_source_element.h
+++ b/third_party/blink/renderer/core/html/html_source_element.h
@@ -42,6 +42,9 @@
   explicit HTMLSourceElement(Document&);
   ~HTMLSourceElement() override;
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   const AtomicString& type() const;
   void setType(const AtomicString&);
 
diff --git a/third_party/blink/renderer/core/html/html_source_element.idl b/third_party/blink/renderer/core/html/html_source_element.idl
index 1e122bb..6ab643a 100644
--- a/third_party/blink/renderer/core/html/html_source_element.idl
+++ b/third_party/blink/renderer/core/html/html_source_element.idl
@@ -28,7 +28,7 @@
     Exposed=Window,
     HTMLConstructor
 ] interface HTMLSourceElement : HTMLElement {
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions] attribute DOMString type;
 
     // https://html.spec.whatwg.org/C/#the-source-element-when-used-with-the-picture-element
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index 89690a3..c513a75 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -415,6 +415,13 @@
   return result;
 }
 
+const AttrNameToTrustedType& HTMLMediaElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 bool HTMLMediaElement::IsHLSURL(const KURL& url) {
   // Keep the same logic as in media_codec_util.h.
   if (url.IsNull() || url.IsEmpty())
@@ -779,6 +786,11 @@
   setAttribute(kSrcAttr, url);
 }
 
+void HTMLMediaElement::SetSrc(const USVStringOrTrustedURL& stringOrURL,
+                              ExceptionState& exception_state) {
+  setAttribute(kSrcAttr, stringOrURL, exception_state);
+}
+
 void HTMLMediaElement::SetSrcObject(MediaStreamDescriptor* src_object) {
   DVLOG(1) << "setSrcObject(" << (void*)this << ")";
   src_object_ = src_object;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index ae90be44..d84c16a08 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -93,6 +93,9 @@
   USING_PRE_FINALIZER(HTMLMediaElement, Dispose);
 
  public:
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   bool IsMediaElement() const override { return true; }
 
   static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&);
@@ -139,6 +142,7 @@
 
   // network state
   void SetSrc(const AtomicString&);
+  void SetSrc(const USVStringOrTrustedURL&, ExceptionState&);
   const KURL& currentSrc() const { return current_src_; }
 
   // Return the URL to be used for downloading the media.
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.idl b/third_party/blink/renderer/core/html/media/html_media_element.idl
index 1cb595f5..af598785 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.idl
+++ b/third_party/blink/renderer/core/html/media/html_media_element.idl
@@ -36,7 +36,7 @@
     readonly attribute MediaError? error;
 
     // network state
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     // FIXME: attribute MediaProvider? srcObject; crbug.com/387740
     readonly attribute DOMString currentSrc;
     [CEReactions, Reflect, ReflectOnly=("anonymous","use-credentials"), ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString? crossOrigin;
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.idl b/third_party/blink/renderer/core/html/portal/html_portal_element.idl
index 5c2ba00..e0d56846 100644
--- a/third_party/blink/renderer/core/html/portal/html_portal_element.idl
+++ b/third_party/blink/renderer/core/html/portal/html_portal_element.idl
@@ -6,7 +6,7 @@
 
 [Exposed=Window, HTMLConstructor, RuntimeEnabled=Portals]
 interface HTMLPortalElement : HTMLElement {
-  [CEReactions, Reflect, URL] attribute USVString src;
+  [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
   [CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
 
   [CallWith=ScriptState, RaisesException] Promise<void> activate(optional PortalActivateOptions options);
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.cc b/third_party/blink/renderer/core/html/track/html_track_element.cc
index f31f4b3..36fb6fc 100644
--- a/third_party/blink/renderer/core/html/track/html_track_element.cc
+++ b/third_party/blink/renderer/core/html/track/html_track_element.cc
@@ -60,6 +60,13 @@
 
 HTMLTrackElement::~HTMLTrackElement() = default;
 
+const AttrNameToTrustedType& HTMLTrackElement::GetCheckedAttributeTypes()
+    const {
+  DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map,
+                      ({{"src", SpecificTrustedType::kTrustedURL}}));
+  return attribute_map;
+}
+
 Node::InsertionNotificationRequest HTMLTrackElement::InsertedInto(
     ContainerNode& insertion_point) {
   DVLOG(TRACK_LOG_LEVEL) << "insertedInto";
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.h b/third_party/blink/renderer/core/html/track/html_track_element.h
index 4e66620..e63090ead 100644
--- a/third_party/blink/renderer/core/html/track/html_track_element.h
+++ b/third_party/blink/renderer/core/html/track/html_track_element.h
@@ -44,6 +44,9 @@
  public:
   explicit HTMLTrackElement(Document&);
 
+  // Returns attributes that should be checked against Trusted Types
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   const AtomicString& kind();
   void setKind(const AtomicString&);
 
diff --git a/third_party/blink/renderer/core/html/track/html_track_element.idl b/third_party/blink/renderer/core/html/track/html_track_element.idl
index ff4c807dc..a6d3296 100644
--- a/third_party/blink/renderer/core/html/track/html_track_element.idl
+++ b/third_party/blink/renderer/core/html/track/html_track_element.idl
@@ -30,7 +30,7 @@
     HTMLConstructor
 ] interface HTMLTrackElement : HTMLElement {
     [CEReactions] attribute DOMString kind;
-    [CEReactions, Reflect, URL] attribute USVString src;
+    [CEReactions, Reflect, URL, RaisesException=Setter] attribute URLString src;
     [CEReactions, Reflect] attribute DOMString srclang;
     [CEReactions, Reflect] attribute DOMString label;
     [CEReactions, Reflect] attribute boolean default;
diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
index aa00bcf..449abe763 100644
--- a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor_test.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/core/scroll/scrollable_area.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 
 namespace blink {
@@ -898,9 +899,10 @@
   ScriptState* script_state =
       ToScriptStateForMainWorld(main_window->GetFrame());
   ScriptState::Scope entered_context_scope(script_state);
-  LocalDOMWindow* child_window = To<LocalDOMWindow>(
-      main_window->open(script_state->GetIsolate(), destination, "frame1", "",
-                        ASSERT_NO_EXCEPTION));
+  auto url = USVStringOrTrustedURL::FromTrustedURL(
+      MakeGarbageCollected<TrustedURL>(destination));
+  LocalDOMWindow* child_window = To<LocalDOMWindow>(main_window->open(
+      script_state->GetIsolate(), url, "frame1", "", ASSERT_NO_EXCEPTION));
   ASSERT_TRUE(child_window);
 
   RunPendingTasks();
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index 314bd14..d21c530d 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1264,6 +1264,10 @@
   is_scheduled_ = true;
 }
 
+const AttrNameToTrustedType& SVGSMILElement::GetCheckedAttributeTypes() const {
+  return SVGURIReference::GetCheckedAttributeTypes();
+}
+
 void SVGSMILElement::Trace(blink::Visitor* visitor) {
   visitor->Trace(target_element_);
   visitor->Trace(target_id_observer_);
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
index dbf83e6..11ea52a4 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -124,6 +124,8 @@
 
   virtual bool IsSVGDiscardElement() const { return false; }
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override;
+
   void Trace(blink::Visitor*) override;
 
  protected:
diff --git a/third_party/blink/renderer/core/svg/svg_a_element.h b/third_party/blink/renderer/core/svg/svg_a_element.h
index 0302bca..19cfd753 100644
--- a/third_party/blink/renderer/core/svg/svg_a_element.h
+++ b/third_party/blink/renderer/core/svg/svg_a_element.h
@@ -38,6 +38,10 @@
 
   explicit SVGAElement(Document&);
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.h b/third_party/blink/renderer/core/svg/svg_fe_image_element.h
index 9d38de5e..a2991133 100644
--- a/third_party/blink/renderer/core/svg/svg_fe_image_element.h
+++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.h
@@ -48,6 +48,10 @@
     return preserve_aspect_ratio_.Get();
   }
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Dispose();
 
   void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/svg/svg_filter_element.h b/third_party/blink/renderer/core/svg/svg_filter_element.h
index 02c1c25..46c123b 100644
--- a/third_party/blink/renderer/core/svg/svg_filter_element.h
+++ b/third_party/blink/renderer/core/svg/svg_filter_element.h
@@ -68,6 +68,10 @@
   // Get the associated SVGResource object, if any.
   LocalSVGResource* AssociatedResource() const;
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
  private:
   void SvgAttributeChanged(const QualifiedName&) override;
   void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/blink/renderer/core/svg/svg_gradient_element.h b/third_party/blink/renderer/core/svg/svg_gradient_element.h
index bd9f7a3..ba5f6ee 100644
--- a/third_party/blink/renderer/core/svg/svg_gradient_element.h
+++ b/third_party/blink/renderer/core/svg/svg_gradient_element.h
@@ -64,6 +64,10 @@
   const SVGGradientElement* ReferencedElement() const;
   void CollectCommonAttributes(GradientAttributes&) const;
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  protected:
diff --git a/third_party/blink/renderer/core/svg/svg_image_element.h b/third_party/blink/renderer/core/svg/svg_image_element.h
index 7c7c3ee0..b5e3a36 100644
--- a/third_party/blink/renderer/core/svg/svg_image_element.h
+++ b/third_party/blink/renderer/core/svg/svg_image_element.h
@@ -78,6 +78,10 @@
     GetImageLoader().SetImageForTest(content);
   }
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
  private:
   bool IsStructurallyExternal() const override {
     return !HrefString().IsNull();
diff --git a/third_party/blink/renderer/core/svg/svg_mpath_element.h b/third_party/blink/renderer/core/svg/svg_mpath_element.h
index ee6fa88..59e2871 100644
--- a/third_party/blink/renderer/core/svg/svg_mpath_element.h
+++ b/third_party/blink/renderer/core/svg/svg_mpath_element.h
@@ -39,6 +39,10 @@
 
   void TargetPathChanged();
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/blink/renderer/core/svg/svg_pattern_element.h b/third_party/blink/renderer/core/svg/svg_pattern_element.h
index 45b7af1..1a4e2cbf 100644
--- a/third_party/blink/renderer/core/svg/svg_pattern_element.h
+++ b/third_party/blink/renderer/core/svg/svg_pattern_element.h
@@ -80,6 +80,10 @@
 
   const SVGPatternElement* ReferencedElement() const;
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/blink/renderer/core/svg/svg_text_path_element.h b/third_party/blink/renderer/core/svg/svg_text_path_element.h
index 0576602..17c7f3c8 100644
--- a/third_party/blink/renderer/core/svg/svg_text_path_element.h
+++ b/third_party/blink/renderer/core/svg/svg_text_path_element.h
@@ -66,6 +66,10 @@
     return spacing_.Get();
   }
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/blink/renderer/core/svg/svg_uri_reference.cc b/third_party/blink/renderer/core/svg/svg_uri_reference.cc
index 99471e10..47221fbc 100644
--- a/third_party/blink/renderer/core/svg/svg_uri_reference.cc
+++ b/third_party/blink/renderer/core/svg/svg_uri_reference.cc
@@ -151,4 +151,13 @@
   observer = nullptr;
 }
 
+const AttrNameToTrustedType& SVGURIReference::GetCheckedAttributeTypes() {
+  DEFINE_STATIC_LOCAL(
+      AttrNameToTrustedType, attribute_map,
+      ({
+          {svg_names::kHrefAttr.LocalName(), SpecificTrustedType::kTrustedURL},
+      }));
+  return attribute_map;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_uri_reference.h b/third_party/blink/renderer/core/svg/svg_uri_reference.h
index a98cf44..8d24052 100644
--- a/third_party/blink/renderer/core/svg/svg_uri_reference.h
+++ b/third_party/blink/renderer/core/svg/svg_uri_reference.h
@@ -81,6 +81,8 @@
   // JS API
   SVGAnimatedHref* href() const { return href_.Get(); }
 
+  static const AttrNameToTrustedType& GetCheckedAttributeTypes();
+
   void Trace(blink::Visitor*) override;
 
  protected:
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.h b/third_party/blink/renderer/core/svg/svg_use_element.h
index 3209a63..136f541 100644
--- a/third_party/blink/renderer/core/svg/svg_use_element.h
+++ b/third_party/blink/renderer/core/svg/svg_use_element.h
@@ -61,6 +61,10 @@
   void DispatchPendingEvent();
   Path ToClipPath() const;
 
+  const AttrNameToTrustedType& GetCheckedAttributeTypes() const override {
+    return SVGURIReference::GetCheckedAttributeTypes();
+  }
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/blink/renderer/core/trustedtypes/BUILD.gn b/third_party/blink/renderer/core/trustedtypes/BUILD.gn
index 196ce74be..c0fdf30 100644
--- a/third_party/blink/renderer/core/trustedtypes/BUILD.gn
+++ b/third_party/blink/renderer/core/trustedtypes/BUILD.gn
@@ -18,5 +18,7 @@
     "trusted_type_policy_factory.h",
     "trusted_types_util.cc",
     "trusted_types_util.h",
+    "trusted_url.cc",
+    "trusted_url.h",
   ]
 }
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
index cc197c6..c172c1f 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/to_v8.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -37,6 +38,12 @@
   return CreateScriptURL(script_state->GetIsolate(), input, exception_state);
 }
 
+TrustedURL* TrustedTypePolicy::createURL(ScriptState* script_state,
+                                         const String& input,
+                                         ExceptionState& exception_state) {
+  return CreateURL(script_state->GetIsolate(), input, exception_state);
+}
+
 TrustedHTML* TrustedTypePolicy::CreateHTML(v8::Isolate* isolate,
                                            const String& input,
                                            ExceptionState& exception_state) {
@@ -98,6 +105,25 @@
   return MakeGarbageCollected<TrustedScriptURL>(script_url);
 }
 
+TrustedURL* TrustedTypePolicy::CreateURL(v8::Isolate* isolate,
+                                         const String& input,
+                                         ExceptionState& exception_state) {
+  if (!policy_options_->createURL()) {
+    exception_state.ThrowTypeError(
+        "Policy " + name_ +
+        "'s TrustedTypePolicyOptions did not specify a 'createURL' member.");
+    return nullptr;
+  }
+  v8::TryCatch try_catch(isolate);
+  String url;
+  if (!policy_options_->createURL()->Invoke(nullptr, input).To(&url)) {
+    DCHECK(try_catch.HasCaught());
+    exception_state.RethrowV8Exception(try_catch.Exception());
+    return nullptr;
+  }
+  return MakeGarbageCollected<TrustedURL>(url);
+}
+
 String TrustedTypePolicy::name() const {
   return name_;
 }
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
index dff1663..17b014d 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h
@@ -17,6 +17,7 @@
 class TrustedHTML;
 class TrustedScript;
 class TrustedScriptURL;
+class TrustedURL;
 
 class CORE_EXPORT TrustedTypePolicy final : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
@@ -29,6 +30,7 @@
   TrustedScriptURL* CreateScriptURL(v8::Isolate*,
                                     const String&,
                                     ExceptionState&);
+  TrustedURL* CreateURL(v8::Isolate*, const String&, ExceptionState&);
 
   // IDL generates calls with ScriptState*, which contains the Isolate*.
   // These methods all call the Isolate* variant.
@@ -37,6 +39,7 @@
   TrustedScriptURL* createScriptURL(ScriptState*,
                                     const String&,
                                     ExceptionState&);
+  TrustedURL* createURL(ScriptState*, const String&, ExceptionState&);
 
   String name() const;
 
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
index f1767d8..60f712be 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl
@@ -4,7 +4,7 @@
 
 // https://github.com/wicg/trusted-types
 
-typedef (DOMString or TrustedHTML or TrustedScript or TrustedScriptURL) TrustedString;
+typedef (DOMString or TrustedHTML or TrustedScript or TrustedScriptURL or TrustedURL) TrustedString;
 
 [
     Exposed=Window,
@@ -14,4 +14,5 @@
     [CallWith=ScriptState, RaisesException, Unforgeable] TrustedHTML createHTML(DOMString input);
     [CallWith=ScriptState, RaisesException, Unforgeable] TrustedScript createScript(DOMString input);
     [CallWith=ScriptState, RaisesException, Unforgeable] TrustedScriptURL createScriptURL(DOMString input);
+    [CallWith=ScriptState, RaisesException, Unforgeable] TrustedURL createURL(DOMString input);
 };
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
index a143e40..a746409e 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_trusted_html.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_trusted_url.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -110,6 +111,14 @@
          wrapper_type_info->Equals(V8TrustedScriptURL::GetWrapperTypeInfo());
 }
 
+bool TrustedTypePolicyFactory::isURL(ScriptState* script_state,
+                                     const ScriptValue& script_value) {
+  const WrapperTypeInfo* wrapper_type_info =
+      GetWrapperTypeInfoFromScriptValue(script_state, script_value);
+  return wrapper_type_info &&
+         wrapper_type_info->Equals(V8TrustedURL::GetWrapperTypeInfo());
+}
+
 TrustedHTML* TrustedTypePolicyFactory::emptyHTML() const {
   return empty_html_.Get();
 }
@@ -127,8 +136,20 @@
   bool is_not_property : 1;
   bool is_not_attribute : 1;
 } kTypeTable[] = {
+    {"a", "href", nullptr, SpecificTrustedType::kTrustedURL},
+    {"area", "href", nullptr, SpecificTrustedType::kTrustedURL},
+    {"audio", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"base", "href", nullptr, SpecificTrustedType::kTrustedURL},
+    {"button", "formAction", nullptr, SpecificTrustedType::kTrustedURL},
     {"embed", "src", nullptr, SpecificTrustedType::kTrustedScriptURL},
+    {"form", "action", nullptr, SpecificTrustedType::kTrustedURL},
+    {"frame", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"iframe", "src", nullptr, SpecificTrustedType::kTrustedURL},
     {"iframe", "srcdoc", nullptr, SpecificTrustedType::kTrustedHTML},
+    {"img", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"input", "formAction", nullptr, SpecificTrustedType::kTrustedURL},
+    {"input", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"link", "href", nullptr, SpecificTrustedType::kTrustedURL},
     {"object", "codeBase", nullptr, SpecificTrustedType::kTrustedScriptURL},
     {"object", "data", nullptr, SpecificTrustedType::kTrustedScriptURL},
     {"script", "innerText", nullptr, SpecificTrustedType::kTrustedScript, false,
@@ -138,6 +159,9 @@
      true},
     {"script", "textContent", nullptr, SpecificTrustedType::kTrustedScript,
      false, true},
+    {"source", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"track", "src", nullptr, SpecificTrustedType::kTrustedURL},
+    {"video", "src", nullptr, SpecificTrustedType::kTrustedURL},
     {"*", "innerHTML", nullptr, SpecificTrustedType::kTrustedHTML, false, true},
     {"*", "outerHTML", nullptr, SpecificTrustedType::kTrustedHTML, false, true},
     {"*", "on*", nullptr, SpecificTrustedType::kTrustedScript, true, false},
@@ -178,6 +202,8 @@
       return "TrustedScript";
     case SpecificTrustedType::kTrustedScriptURL:
       return "TrustedScriptURL";
+    case SpecificTrustedType::kTrustedURL:
+      return "TrustedURL";
     case SpecificTrustedType::kNone:
       return String();
   }
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
index 751bd3b..c8f95b1 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
@@ -15,6 +15,7 @@
     [CallWith=ScriptState, Unforgeable] boolean isHTML(any checkedObject);
     [CallWith=ScriptState, Unforgeable] boolean isScript(any checkedObject);
     [CallWith=ScriptState, Unforgeable] boolean isScriptURL(any checkedObject);
+    [CallWith=ScriptState, Unforgeable] boolean isURL(any checkedObject);
     [Unforgeable] readonly attribute TrustedHTML emptyHTML;
 
     // Trusted Types metadata, following the proposal in:
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
index 067574ff..8791c6b4 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.cc
@@ -7,9 +7,10 @@
 #include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node.h"
@@ -20,6 +21,7 @@
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
@@ -35,9 +37,11 @@
   kAnyTrustedTypeAssignment,
   kTrustedHTMLAssignment,
   kTrustedScriptAssignment,
+  kTrustedURLAssignment,
   kTrustedScriptURLAssignment,
   kTrustedHTMLAssignmentAndDefaultPolicyFailed,
   kTrustedScriptAssignmentAndDefaultPolicyFailed,
+  kTrustedURLAssignmentAndDefaultPolicyFailed,
   kTrustedScriptURLAssignmentAndDefaultPolicyFailed,
   kTextNodeScriptAssignment,
   kTextNodeScriptAssignmentAndDefaultPolicyFailed,
@@ -51,6 +55,8 @@
       return "This document requires 'TrustedHTML' assignment.";
     case kTrustedScriptAssignment:
       return "This document requires 'TrustedScript' assignment.";
+    case kTrustedURLAssignment:
+      return "This document requires 'TrustedURL' assignment.";
     case kTrustedScriptURLAssignment:
       return "This document requires 'TrustedScriptURL' assignment.";
     case kTrustedHTMLAssignmentAndDefaultPolicyFailed:
@@ -59,6 +65,9 @@
     case kTrustedScriptAssignmentAndDefaultPolicyFailed:
       return "This document requires 'TrustedScript' assignment and the "
              "'default' policy failed to execute.";
+    case kTrustedURLAssignmentAndDefaultPolicyFailed:
+      return "This document requires 'TrustedURL' assignment and the 'default' "
+             "policy failed to execute.";
     case kTrustedScriptURLAssignmentAndDefaultPolicyFailed:
       return "This document requires 'TrustedScriptURL' assignment and the "
              "'default' policy failed to execute.";
@@ -145,7 +154,7 @@
 }
 
 String GetStringFromTrustedType(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
         string_or_trusted_type,
     const ExecutionContext* execution_context,
     ExceptionState& exception_state) {
@@ -165,12 +174,14 @@
     return string_or_trusted_type.GetAsTrustedScript()->toString();
   if (string_or_trusted_type.IsTrustedScriptURL())
     return string_or_trusted_type.GetAsTrustedScriptURL()->toString();
+  if (string_or_trusted_type.IsTrustedURL())
+    return string_or_trusted_type.GetAsTrustedURL()->toString();
 
   return string_or_trusted_type.GetAsString();
 }
 
 String GetStringFromTrustedTypeWithoutCheck(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
         string_or_trusted_type) {
   if (string_or_trusted_type.IsTrustedHTML())
     return string_or_trusted_type.GetAsTrustedHTML()->toString();
@@ -178,6 +189,8 @@
     return string_or_trusted_type.GetAsTrustedScript()->toString();
   if (string_or_trusted_type.IsTrustedScriptURL())
     return string_or_trusted_type.GetAsTrustedScriptURL()->toString();
+  if (string_or_trusted_type.IsTrustedURL())
+    return string_or_trusted_type.GetAsTrustedURL()->toString();
   if (string_or_trusted_type.IsString())
     return string_or_trusted_type.GetAsString();
 
@@ -185,7 +198,7 @@
 }
 
 String GetStringFromSpecificTrustedType(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
         string_or_trusted_type,
     SpecificTrustedType specific_trusted_type,
     const ExecutionContext* execution_context,
@@ -226,6 +239,17 @@
       return GetStringFromTrustedScriptURL(string_or_trusted_script_url,
                                            execution_context, exception_state);
     }
+    case SpecificTrustedType::kTrustedURL: {
+      USVStringOrTrustedURL string_or_trusted_url =
+          string_or_trusted_type.IsTrustedURL()
+              ? USVStringOrTrustedURL::FromTrustedURL(
+                    string_or_trusted_type.GetAsTrustedURL())
+              : USVStringOrTrustedURL::FromUSVString(
+                    GetStringFromTrustedTypeWithoutCheck(
+                        string_or_trusted_type));
+      return GetStringFromTrustedURL(string_or_trusted_url, execution_context,
+                                     exception_state);
+    }
   }
 }
 
@@ -383,6 +407,49 @@
   return result->toString();
 }
 
+String GetStringFromTrustedURL(USVStringOrTrustedURL string_or_trusted_url,
+                               const ExecutionContext* execution_context,
+                               ExceptionState& exception_state) {
+  DCHECK(!string_or_trusted_url.IsNull());
+  if (string_or_trusted_url.IsTrustedURL()) {
+    return string_or_trusted_url.GetAsTrustedURL()->toString();
+  }
+
+  DCHECK(string_or_trusted_url.IsUSVString());
+  String string = string_or_trusted_url.GetAsUSVString();
+
+  bool require_trusted_type = RequireTrustedTypesCheck(execution_context);
+  if (!require_trusted_type) {
+    return string;
+  }
+
+  TrustedTypePolicy* default_policy = GetDefaultPolicy(execution_context);
+  if (!default_policy) {
+    if (TrustedTypeFail(kTrustedURLAssignment, execution_context,
+                        exception_state, string)) {
+      return g_empty_string;
+    }
+    return string;
+  }
+
+  TrustedURL* result = default_policy->CreateURL(
+      execution_context->GetIsolate(), string, exception_state);
+  if (exception_state.HadException()) {
+    return g_empty_string;
+  }
+
+  if (result->toString().IsNull()) {
+    if (TrustedTypeFail(kTrustedURLAssignmentAndDefaultPolicyFailed,
+                        execution_context, exception_state, string)) {
+      return g_empty_string;
+    } else {
+      return string;
+    }
+  }
+
+  return result->toString();
+}
+
 Node* TrustedTypesCheckForHTMLScriptElement(Node* child,
                                             Document* doc,
                                             ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
index bf9d5dbd..fc84a0b4 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util.h
@@ -15,27 +15,29 @@
 class ExceptionState;
 class Node;
 class StringOrTrustedHTML;
-class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL;
+class StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL;
 class StringOrTrustedScript;
 class StringOrTrustedScriptURL;
+class USVStringOrTrustedURL;
 
 enum class SpecificTrustedType {
   kNone,
   kTrustedHTML,
   kTrustedScript,
   kTrustedScriptURL,
+  kTrustedURL,
 };
 
 String CORE_EXPORT GetStringFromTrustedType(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&,
     const ExecutionContext*,
     ExceptionState&);
 
 String CORE_EXPORT GetStringFromTrustedTypeWithoutCheck(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&);
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&);
 
 String CORE_EXPORT GetStringFromSpecificTrustedType(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&,
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&,
     SpecificTrustedType,
     const ExecutionContext*,
     ExceptionState&);
@@ -60,6 +62,10 @@
                                                  const ExecutionContext*,
                                                  ExceptionState&);
 
+String CORE_EXPORT GetStringFromTrustedURL(USVStringOrTrustedURL,
+                                           const ExecutionContext*,
+                                           ExceptionState&);
+
 // For <script> elements, we need to treat insertion of DOM text nodes
 // as equivalent to string assignment. This checks the child-node to be
 // inserted and runs all of the Trusted Types checks if it's a text node.
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
index 29619bd4..fa08769e 100644
--- a/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_types_util_test.cc
@@ -7,9 +7,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html.h"
-#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_trusted_script_url.h"
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
@@ -17,6 +18,7 @@
 #include "third_party/blink/renderer/core/trustedtypes/trusted_html.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
 
@@ -24,7 +26,7 @@
 
 // Functions for checking throwing cases.
 void GetStringFromTrustedTypeThrows(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
         string_or_trusted_type) {
   auto* document = MakeGarbageCollected<Document>();
   document->GetContentSecurityPolicy()->DidReceiveHeader(
@@ -90,9 +92,28 @@
   exception_state.ClearException();
 }
 
+void GetStringFromTrustedURLThrows(
+    const USVStringOrTrustedURL& string_or_trusted_url) {
+  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+  Document& document = dummy_page_holder->GetDocument();
+  document.GetContentSecurityPolicy()->DidReceiveHeader(
+      "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
+      kContentSecurityPolicyHeaderSourceMeta);
+  document.SetRequireTrustedTypesForTesting();
+  document.GetContentSecurityPolicy()->RequireTrustedTypes();
+  V8TestingScope scope;
+  DummyExceptionStateForTesting exception_state;
+  ASSERT_FALSE(exception_state.HadException());
+  String s = GetStringFromTrustedURL(string_or_trusted_url, &document,
+                                     exception_state);
+  EXPECT_TRUE(exception_state.HadException());
+  EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>());
+  exception_state.ClearException();
+}
+
 // Functions for checking non-throwing cases.
 void GetStringFromTrustedTypeWorks(
-    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL&
+    const StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL&
         string_or_trusted_type,
     String expected) {
   auto* document = MakeGarbageCollected<Document>();
@@ -150,63 +171,105 @@
   ASSERT_EQ(s, expected);
 }
 
+void GetStringFromTrustedURLWorks(
+    const USVStringOrTrustedURL& string_or_trusted_url,
+    String expected) {
+  auto dummy_page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
+  Document& document = dummy_page_holder->GetDocument();
+  document.GetContentSecurityPolicy()->DidReceiveHeader(
+      "trusted-types *", kContentSecurityPolicyHeaderTypeEnforce,
+      kContentSecurityPolicyHeaderSourceMeta);
+  V8TestingScope scope;
+  DummyExceptionStateForTesting exception_state;
+  String s = GetStringFromTrustedURL(string_or_trusted_url, &document,
+                                     exception_state);
+  ASSERT_EQ(s, expected);
+}
+
 // GetStringFromTrustedType() tests
 TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedHTML) {
   auto* html = MakeGarbageCollected<TrustedHTML>("A string");
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedHTML(
-          html);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedHTML(html);
   GetStringFromTrustedTypeWorks(trusted_value, "A string");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScript) {
   auto* script = MakeGarbageCollected<TrustedScript>("A string");
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedScript(
-          script);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedScript(script);
   GetStringFromTrustedTypeWorks(trusted_value, "A string");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScriptURL) {
   String url_address = "http://www.example.com/";
   auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
-          FromTrustedScriptURL(script_url);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedScriptURL(script_url);
   GetStringFromTrustedTypeWorks(trusted_value, "http://www.example.com/");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedScriptURL_Relative) {
   String url_address = "relative/url.html";
   auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
-          FromTrustedScriptURL(script_url);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedScriptURL(script_url);
+  GetStringFromTrustedTypeWorks(trusted_value, "relative/url.html");
+}
+
+TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedURL) {
+  String url_address = "http://www.example.com/";
+  auto* url = MakeGarbageCollected<TrustedURL>(url_address);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedURL(url);
+  GetStringFromTrustedTypeWorks(trusted_value, "http://www.example.com/");
+}
+
+TEST(TrustedTypesUtilTest, GetStringFromTrustedType_TrustedURL_Relative) {
+  String url_address = "relative/url.html";
+  auto* url = MakeGarbageCollected<TrustedURL>(url_address);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedURL(url);
   GetStringFromTrustedTypeWorks(trusted_value, "relative/url.html");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedType_String) {
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL string_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromString(
-          "A string");
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      string_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromString("A string");
   GetStringFromTrustedTypeThrows(string_value);
 }
 
 // GetStringFromTrustedTypeWithoutCheck() tests
 TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_TrustedHTML) {
   auto* html = MakeGarbageCollected<TrustedHTML>("A string");
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedHTML(
-          html);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedHTML(html);
   String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
   ASSERT_EQ(s, "A string");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_TrustedScript) {
   auto* script = MakeGarbageCollected<TrustedScript>("A string");
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromTrustedScript(
-          script);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedScript(script);
   String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
   ASSERT_EQ(s, "A string");
 }
@@ -215,24 +278,37 @@
      GetStringFromTrustedTypeWithoutCheck_TrustedScriptURL) {
   String url_address = "http://www.example.com/";
   auto* script_url = MakeGarbageCollected<TrustedScriptURL>(url_address);
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL trusted_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::
-          FromTrustedScriptURL(script_url);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedScriptURL(script_url);
+  String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
+  ASSERT_EQ(s, "http://www.example.com/");
+}
+
+TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_TrustedURL) {
+  String url_address = "http://www.example.com/";
+  auto* url = MakeGarbageCollected<TrustedURL>(url_address);
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      trusted_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromTrustedURL(url);
   String s = GetStringFromTrustedTypeWithoutCheck(trusted_value);
   ASSERT_EQ(s, "http://www.example.com/");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_String) {
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL string_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL::FromString(
-          "A string");
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL
+      string_value =
+          StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL::
+              FromString("A string");
   String s = GetStringFromTrustedTypeWithoutCheck(string_value);
   ASSERT_EQ(s, "A string");
 }
 
 TEST(TrustedTypesUtilTest, GetStringFromTrustedTypeWithoutCheck_Null) {
-  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL null_value =
-      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURL();
+  StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL null_value =
+      StringOrTrustedHTMLOrTrustedScriptOrTrustedScriptURLOrTrustedURL();
   String s = GetStringFromTrustedTypeWithoutCheck(null_value);
   ASSERT_EQ(s, "");
 }
@@ -279,4 +355,19 @@
       StringOrTrustedScriptURL::FromString("A string");
   GetStringFromTrustedScriptURLThrows(string_value);
 }
+
+// GetStringFromTrustedURL tests
+TEST(TrustedTypesUtilTest, GetStringFromTrustedURL_TrustedURL) {
+  String url_address = "http://www.example.com/";
+  auto* url = MakeGarbageCollected<TrustedURL>(url_address);
+  USVStringOrTrustedURL trusted_value =
+      USVStringOrTrustedURL::FromTrustedURL(url);
+  GetStringFromTrustedURLWorks(trusted_value, "http://www.example.com/");
+}
+
+TEST(TrustedTypesUtilTest, GetStringFromTrustedURL_String) {
+  USVStringOrTrustedURL string_value =
+      USVStringOrTrustedURL::FromUSVString("A string");
+  GetStringFromTrustedURLThrows(string_value);
+}
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_url.cc b/third_party/blink/renderer/core/trustedtypes/trusted_url.cc
new file mode 100644
index 0000000..b8b46e3
--- /dev/null
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_url.cc
@@ -0,0 +1,15 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
+
+namespace blink {
+
+TrustedURL::TrustedURL(const String& url) : url_(url) {}
+
+String TrustedURL::toString() const {
+  return url_;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_url.h b/third_party/blink/renderer/core/trustedtypes/trusted_url.h
new file mode 100644
index 0000000..755f1b29
--- /dev/null
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_url.h
@@ -0,0 +1,29 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_URL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_URL_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class CORE_EXPORT TrustedURL final : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  explicit TrustedURL(const String& url);
+
+  // TrustedURL.idl
+  String toString() const;
+
+ private:
+  const String url_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_TRUSTEDTYPES_TRUSTED_URL_H_
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_url.idl b/third_party/blink/renderer/core/trustedtypes/trusted_url.idl
new file mode 100644
index 0000000..b611563
--- /dev/null
+++ b/third_party/blink/renderer/core/trustedtypes/trusted_url.idl
@@ -0,0 +1,14 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/wicg/trusted-types
+
+typedef (USVString or TrustedURL) URLString;
+
+[
+    Exposed=Window,
+    RuntimeEnabled=TrustedDOMTypes
+] interface TrustedURL {
+    stringifier;
+};
diff --git a/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc b/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
index 5a08967..ad8b1027 100644
--- a/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
+++ b/third_party/blink/renderer/core/url/dom_url_utils_read_only.cc
@@ -26,18 +26,24 @@
 
 #include "third_party/blink/renderer/core/url/dom_url_utils_read_only.h"
 
+#include "third_party/blink/renderer/bindings/core/v8/usv_string_or_trusted_url.h"
+#include "third_party/blink/renderer/core/trustedtypes/trusted_url.h"
 #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 
 namespace blink {
 
-String DOMURLUtilsReadOnly::href() {
+String DOMURLUtilsReadOnly::href(ExceptionState&) {
   const KURL& kurl = Url();
   if (kurl.IsNull())
     return Input();
   return kurl.GetString();
 }
 
+void DOMURLUtilsReadOnly::href(USVStringOrTrustedURL& result) {
+  result.SetUSVString(href());
+}
+
 String DOMURLUtilsReadOnly::origin(const KURL& kurl) {
   if (kurl.IsNull())
     return "";
diff --git a/third_party/blink/renderer/core/url/dom_url_utils_read_only.h b/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
index 7ca57a57..ef99f711 100644
--- a/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
+++ b/third_party/blink/renderer/core/url/dom_url_utils_read_only.h
@@ -28,18 +28,23 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_URL_DOM_URL_UTILS_READ_ONLY_H_
 
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 
 namespace blink {
 
+class ExceptionState;
+class USVStringOrTrustedURL;
+
 class CORE_EXPORT DOMURLUtilsReadOnly {
  public:
   virtual KURL Url() const = 0;
   virtual String Input() const = 0;
   virtual ~DOMURLUtilsReadOnly() = default;
 
-  String href();
+  void href(USVStringOrTrustedURL&);
+  String href(ExceptionState& = ASSERT_NO_EXCEPTION);
 
   static String origin(const KURL&);
   String origin() { return origin(Url()); }
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl b/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl
index be58b63..6ff45e7 100644
--- a/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl
+++ b/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl
@@ -3,6 +3,7 @@
 typedef (DOMString or TrustedHTML) HTMLString;
 typedef (DOMString or TrustedScript) ScriptString;
 typedef (DOMString or TrustedScriptURL) ScriptURLString;
+typedef (USVString or TrustedURL) URLString;
 
 [Exposed=(Window, Worker)]
 interface TrustedHTML {
@@ -20,6 +21,11 @@
 };
 
 [Exposed=(Window, Worker)]
+interface TrustedURL {
+    stringifier;
+};
+
+[Exposed=(Window, Worker)]
 interface TrustedTypePolicyFactory {
     [Unforgeable] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions);
     // All the policy object names that have been created
@@ -32,12 +38,14 @@
     [Unforgeable] TrustedHTML createHTML(DOMString input);
     [Unforgeable] TrustedScript createScript(DOMString input);
     [Unforgeable] TrustedScriptURL createScriptURL(DOMString input);
+    [Unforgeable] TrustedURL createURL(DOMString input);
 };
 
 dictionary TrustedTypePolicyOptions {
    CreateHTMLCallback createHTML;
    CreateScriptCallback createScript;
    CreateURLCallback createScriptURL;
+   CreateURLCallback createURL;
 };
 
 callback CreateHTMLCallback = DOMString (DOMString input);
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttribute.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttribute.tentative.html
index cd66179..a284b2f 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttribute.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttribute.tentative.html
@@ -6,6 +6,29 @@
 </head>
 <body>
 <script>
+  // TrustedURL Assignments
+  let testCases = [
+    [ 'a', 'href' ],
+    [ 'area', 'href' ],
+    [ 'base', 'href' ],
+    [ 'frame', 'src' ],
+    [ 'iframe', 'src' ],
+    [ 'img', 'src' ],
+    [ 'input', 'src' ],
+    [ 'link', 'href' ],
+    [ 'video', 'src' ],
+    [ 'object', 'data' ],
+    [ 'object', 'codeBase' ],
+    [ 'source', 'src' ],
+    [ 'track', 'src' ]
+  ];
+
+  testCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_url_explicit_set(window, c, t, c[0], c[1], RESULTS.URL);
+    }, c[0] + "." + c[1] + " assigned via policy (successful URL transformation)");
+  });
+
   // TrustedScriptURL Assignments
   let scriptTestCases = [
     [ 'embed', 'src' ],
@@ -31,8 +54,8 @@
 
   // Other attributes can be assigned with TrustedTypes or strings or null values
   test(t => {
-    assert_element_accepts_trusted_script_url_explicit_set(window, 'scriptsrc1', t, 'script', 'src', RESULTS.SCRIPTURL);
-  }, "script.src assigned via policy (successful script transformation)");
+    assert_element_accepts_trusted_url_explicit_set(window, 'arel', t, 'a', 'rel', RESULTS.URL);
+  }, "a.rel assigned via policy (successful URL transformation)");
 
   test(t => {
     assert_element_accepts_non_trusted_type_explicit_set('a', 'rel', 'A string', 'A string');
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html
index 67e8236..374e6a9 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Element-setAttributeNS.tentative.html
@@ -18,8 +18,10 @@
       assert_element_accepts_trusted_script_url_set_ns(window, '2', t, 'a', 'b', RESULTS.SCRIPTURL);
     }, "Element.setAttributeNS assigned via policy (successful ScriptURL transformation)");
 
-// TODO: Is there any non-URL, namespaced accessor left?
-/*
+    test(t => {
+      assert_element_accepts_trusted_url_set_ns(window, '3', t, 'a', 'b', RESULTS.URL);
+    }, "Element.setAttributeNS assigned via policy (successful URL transformation)");
+
     test(t => {
       let p = createURL_policy(window, '5');
       let url = p.createURL(INPUTS.URL);
@@ -29,6 +31,5 @@
       let attr_node = elem.getAttributeNodeNS("http://www.w3.org/1999/xlink", "href");
       assert_equals(attr_node.value + "", RESULTS.URL);
     }, "Element.setAttributeNS accepts a URL on <svg:image xlink:href/>");
-*/
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/HTMLElement-generic.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/HTMLElement-generic.tentative.html
index 3ec6cfa60..d1fafa7 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/HTMLElement-generic.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/HTMLElement-generic.tentative.html
@@ -7,6 +7,28 @@
 <body>
 <script>
   var testnb = 0;
+  // TrustedURL Assignments
+  const URLTestCases = [
+    [ 'a', 'href' ],
+    [ 'area', 'href' ],
+    [ 'base', 'href' ],
+    [ 'frame', 'src' ],
+    [ 'iframe', 'src' ],
+    [ 'img', 'src' ],
+    [ 'input', 'src' ],
+    [ 'link', 'href' ],
+    [ 'video', 'src' ],
+    [ 'object', 'data' ],
+    [ 'object', 'codeBase' ],
+    [ 'source', 'src' ],
+    [ 'track', 'src' ]
+  ];
+
+  URLTestCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_url(window, ++testnb, t, c[0], c[1], RESULTS.URL);
+    }, c[0] + "." + c[1] + " assigned via policy (successful URL transformation)");
+  });
 
   // TrustedScriptURL Assignments
   const scriptURLTestCases = [
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Location-assign.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Location-assign.tentative.html
new file mode 100644
index 0000000..62f98e9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Location-assign.tentative.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/helper.sub.js"></script>
+<body>
+<script>
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.assign(url);
+    assert_equals("" + url, location.href, "location href");
+  }, "location.assign via policy (successful URL transformation).");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Location-href.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Location-href.tentative.html
new file mode 100644
index 0000000..bacadf6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Location-href.tentative.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/helper.sub.js"></script>
+<body>
+<script>
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.href = url;
+    assert_equals("" + url, location.href, "location href");
+  }, "location.href assigned via policy (successful URL transformation).");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Location-replace.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Location-replace.tentative.html
new file mode 100644
index 0000000..4fb53d02
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Location-replace.tentative.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/helper.sub.js"></script>
+<body>
+<script>
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.replace(url);
+    assert_equals("" + url, location.href, "location href");
+  }, "location.replace via policy (successful URL transformation).");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicy-createXXX.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicy-createXXX.tentative.html
index 34fbf558..73ed8c7 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicy-createXXX.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicy-createXXX.tentative.html
@@ -12,8 +12,10 @@
       createScript: s => s
     });
     assert_throws(new TypeError(), _ => { p1.createScriptURL("foo"); });
+    assert_throws(new TypeError(), _ => { p1.createURL("foo"); });
 
     const p2 = trustedTypes.createPolicy("policyURLAndScriptURL", {
+      createURL: s => s,
       createScriptURL: s => s
     });
     assert_throws(new TypeError(), _ => { p2.createHTML("foo"); });
@@ -24,18 +26,23 @@
     const noopPolicy = {
       createHTML: (s) => s,
       createScriptURL: (s) => s,
+      createURL: (s) => s,
       createScript: (s) => s,
     };
     policy = trustedTypes.createPolicy(Math.random(), noopPolicy, true);
     let el = document.createElement("div");
 
-    el.title = policy.createHTML(INPUTS.SCRIPTURL);
-    assert_equals(el.title, INPUTS.SCRIPTURL);
+    el.title = policy.createHTML(INPUTS.URL);
+    assert_equals(el.title, INPUTS.URL);
+
+    el.title = policy.createURL(INPUTS.HTML);
+    assert_equals(el.title, INPUTS.HTML);
   }, "Attributes without type constraints will work as before.");
 
   test(t => {
     const policy = trustedTypes.createPolicy("nullpolicy", null);
     assert_throws(new TypeError(), _ => { policy.createScriptURL("foo"); });
+    assert_throws(new TypeError(), _ => { policy.createURL("foo"); });
     assert_throws(new TypeError(), _ => { policy.createHTML("foo"); });
     assert_throws(new TypeError(), _ => { policy.createScript("foo"); });
   }, "trustedTypes.createPolicy(.., null) creates empty policy.");
@@ -88,6 +95,7 @@
   const testCases = [
     [TrustedHTML, "createHTML", "whatever", stringTestCases],
     [TrustedScript, "createScript", "whatever", stringTestCases],
+    [TrustedURL, "createURL", INPUTS.SCRIPTURL, urlTestCases],
     [TrustedScriptURL, "createScriptURL", INPUTS.SCRIPTURL, urlTestCases],
   ];
 
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html
index 8608bcc..05c7301 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-createPolicy-createXYZTests.tentative.html
@@ -224,4 +224,79 @@
       p.createURL(INPUTS.URL);
     });
   }, "createScriptURL defined - calling undefined callbacks throws");
+
+
+  //URL tests
+  function createURLTest(policyName, policy, expectedURL, t) {
+    let p = window.trustedTypes.createPolicy(policyName, policy);
+    let url = p.createURL(INPUTS.URL);
+    assert_true(url instanceof TrustedURL);
+    assert_true(trustedTypes.isURL(url));
+    assert_equals(url + "", expectedURL);
+  }
+
+  test(t => {
+    createURLTest('TestPolicyURL1', { createURL: s => s }, INPUTS.URL, t);
+  }, "url = identity function");
+
+  test(t => {
+    createURLTest('TestPolicyURL2', { createURL: s => null }, "", t);
+  }, "url = null");
+
+  var URLstr = '#x';
+  test(t => {
+    createURLTest('TestPolicyURL3', { createURL: s => s + URLstr }, INPUTS.URL + URLstr, t);
+  }, "url = string + global string");
+
+  var URLx = 'global';
+  test(t => {
+    createURLTest('TestPolicyURL4', { createURL: s => { URLx = s; return s; } }, INPUTS.URL, t);
+    assert_equals(URLx, INPUTS.URL);
+  }, "url = identity function, global string changed");
+
+  test(t => {
+    let p = window.trustedTypes.createPolicy('TestPolicyURL5', {
+      createURL: s => { throw new Error(); }
+    });
+    assert_throws(new Error(), _ => {
+      p.createURL(INPUTS.URL);
+    });
+  }, "url = callback that throws");
+
+  function getURL(s) {
+    return s + this.bar;
+  }
+
+  var obj = {
+    "bar": "#x"
+  }
+
+  test(t => {
+    createURLTest('TestPolicyURL6', { createURL: getURL.bind(obj) }, INPUTS.URL + "#x", t);
+  }, "url = this bound to an object");
+
+  var bar = "#x";
+  test(t => {
+    createURLTest('TestPolicyURL7', { createURL: s => getURL(s) }, INPUTS.URL + bar, t);
+  }, "url = this without bind");
+
+  test(t => {
+    let p = window.trustedTypes.createPolicy('TestPolicyURL8', null);
+    assert_throws(new TypeError(), _ => {
+      p.createURL(INPUTS.URL);
+    });
+  }, "url - calling undefined callback throws");
+
+  test(t => {
+    let p = window.trustedTypes.createPolicy('TestPolicyURL9', { createURL: createURLJS });
+    assert_throws(new TypeError(), _ => {
+      p.createHTML(INPUTS.HTML);
+    });
+    assert_throws(new TypeError(), _ => {
+      p.createScript(INPUTS.SCRIPT);
+    });
+    assert_throws(new TypeError(), _ => {
+      p.createScriptURL(INPUTS.SCRIPTURL);
+    });
+  }, "createURL defined - calling undefined callbacks throws");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-getPropertyType.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-getPropertyType.tentative.html
index 0e5a0f5..f9ba8f27 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-getPropertyType.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-getPropertyType.tentative.html
@@ -8,11 +8,10 @@
 <div id="target"></div>
 <script>
   test(t => {
-    assert_equals(trustedTypes.getPropertyType("script", "text"), "TrustedScript");
-    assert_equals(trustedTypes.getPropertyType("script", "src"), "TrustedScriptURL");
-    assert_equals(trustedTypes.getPropertyType("script", "id"), null);
-    assert_equals(trustedTypes.getPropertyType("script", "b"), null);
-  }, "sanity check trustedTypes.getPropertyType for the HTML script element.");
+    assert_equals(trustedTypes.getPropertyType("a", "href"), "TrustedURL");
+    assert_equals(trustedTypes.getPropertyType("a", "id"), null);
+    assert_equals(trustedTypes.getPropertyType("a", "b"), null);
+  }, "sanity check trustedTypes.getPropertyType for the HTML a element.");
 
   test(t => {
     assert_equals(trustedTypes.getAttributeType("img", "onerror"), "TrustedScript");
@@ -29,9 +28,11 @@
   test(t => {
     // returns the proper type for attribute-related properties
     assert_equals(trustedTypes.getPropertyType("script", "src"), "TrustedScriptURL");
+    assert_equals(trustedTypes.getPropertyType("img", "src"), "TrustedURL");
 
     // is case insensitive for tag names
     assert_equals(trustedTypes.getPropertyType("SCRIPT", "src"), "TrustedScriptURL");
+    assert_equals(trustedTypes.getPropertyType("ImG", "src"), "TrustedURL");
 
     // is case sensitive for property names
     assert_equals(trustedTypes.getPropertyType("script", "sRc"), null);
@@ -52,6 +53,7 @@
   test(t => {
     // returns the proper type
     assert_equals(trustedTypes.getAttributeType('script', 'src'), 'TrustedScriptURL');
+    assert_equals(trustedTypes.getAttributeType('img', 'src'), 'TrustedURL');
 
     // ignores attributes from unknown namespaces
     assert_equals(trustedTypes.getAttributeType(
@@ -59,9 +61,11 @@
 
     // is case insensitive for element names
     assert_equals(trustedTypes.getAttributeType('SCRIPT', 'src'), 'TrustedScriptURL');
+    assert_equals(trustedTypes.getAttributeType('imG', 'src'), 'TrustedURL');
 
     // is case insensitive for the attribute names
     assert_equals(trustedTypes.getAttributeType('script', 'SRC'), 'TrustedScriptURL');
+    assert_equals(trustedTypes.getAttributeType('imG', 'srC'), 'TrustedURL');
 
     // supports the inline event handlers
     assert_equals(trustedTypes.getAttributeType('img', 'onerror'), 'TrustedScript');
@@ -78,6 +82,7 @@
 
     // Spot testing some values.
     assert_equals(map["script"].attributes.src, "TrustedScriptURL");
+    assert_equals(map["img"].attributes.src, "TrustedURL");
     assert_equals(map["*"].properties.innerHTML, "TrustedHTML");
     assert_equals(map["foo"], undefined);
 
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html
index c620451..efaac5d 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-isXXX.tentative.html
@@ -10,6 +10,7 @@
   const noopPolicy = {
     'createHTML': (s) => s,
     'createScriptURL': (s) => s,
+    'createURL': (s) => s,
     'createScript': (s) => s,
   };
 
@@ -64,6 +65,23 @@
     assert_false(trustedTypes.isScriptURL(script3));
   }, 'TrustedTypePolicyFactory.isScriptURL requires the object to be created via policy.');
 
+  // isURL tests
+  test(t => {
+    const p = trustedTypes.createPolicy('url', noopPolicy);
+    let url = p.createURL(INPUTS.URL);
+
+    assert_true(trustedTypes.isURL(url));
+    let url2 = Object.create(url);
+
+    // instanceof can pass, but we rely on isScript
+    assert_true(url2 instanceof TrustedURL);
+    assert_false(trustedTypes.isURL(url2));
+
+    let url3 = Object.assign({}, url, {toString: () => 'fake'});
+
+    assert_false(trustedTypes.isURL(url3));
+  }, 'TrustedTypePolicyFactory.isURL requires the object to be created via policy.');
+
   // Test non-object parameters.
   test(t => {
     assert_false(trustedTypes.isHTML(null));
@@ -76,6 +94,11 @@
     assert_false(trustedTypes.isScript(0.5));
     assert_false(trustedTypes.isScript('test'));
     assert_false(trustedTypes.isScript({}));
+    assert_false(trustedTypes.isURL(null));
+    assert_false(trustedTypes.isURL(123));
+    assert_false(trustedTypes.isURL(0.5));
+    assert_false(trustedTypes.isURL('test'));
+    assert_false(trustedTypes.isURL({}));
     assert_false(trustedTypes.isScriptURL(null));
     assert_false(trustedTypes.isScriptURL(123));
     assert_false(trustedTypes.isScriptURL(0.5));
@@ -103,19 +126,30 @@
     assert_false(trustedTypes.isScriptURL({}));
   }, 'TrustedTypePolicyFactory.isScriptURL cannot be redefined.');
 
+  test(t => {
+    try { trustedTypes.isURL = () => 'fake'; } catch { }
+    assert_false(trustedTypes.isURL({}));
+  }, 'TrustedTypePolicyFactory.isURL cannot be redefined.');
+
   // Redefinition tests, via Object.defineProperty.
   test(t => {
-    try { Object.defineProperty(trustedTypes, 'isHTML', () => 'fake'); } catch { }
+    try { Object.defineProperty(TrustedTypes, 'isHTML', () => 'fake'); } catch { }
     assert_false(trustedTypes.isHTML({}));
   }, 'TrustedTypePolicyFactory.IsHTML cannot be redefined via defineProperty.');
 
   test(t => {
-    try { Object.defineProperty(trustedTypes, 'isScript', () => 'fake'); } catch { }
+    try { Object.defineProperty(TrustedTypes, 'isScript', () => 'fake'); } catch { }
     assert_false(trustedTypes.isScript({}));
   }, 'TrustedTypePolicyFactory.isScript cannot be redefined via definePropert.');
 
   test(t => {
-    try { Object.defineProperty(trustedTypes, 'isScriptURL', () => 'fake'); } catch { }
+    try { Object.defineProperty(TrustedTypes, 'isScriptURL', () => 'fake'); } catch { }
     assert_false(trustedTypes.isScriptURL({}));
   }, 'TrustedTypePolicyFactory.isScriptURL cannot be redefined via definePropert.');
+
+  test(t => {
+    try { Object.defineProperty(TrustedTypes, 'isURL', () => 'fake'); } catch { }
+    assert_false(trustedTypes.isURL({}));
+  }, 'TrustedTypePolicyFactory.isURL cannot be redefined via definePropert.');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-metadata.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-metadata.tentative.html
index da7d1b4..70f77b1b 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-metadata.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/TrustedTypePolicyFactory-metadata.tentative.html
@@ -8,15 +8,18 @@
 <body>
 <div id="target"></div>
 <script>
+
   const policy = trustedTypes.createPolicy("anythinggoes", {
     "createHTML": x => x,
     "createScript": x => x,
+    "createURL": x => x,
     "createScriptURL": x => x,
   });
 
   const create_value = {
     "TrustedHTML": policy.createHTML("hello"),
     "TrustedScript": policy.createScript("x => x + x"),
+    "TrustedURL": policy.createURL("https://url.invalid/"),
     "TrustedScriptURL": policy.createScriptURL("https://url.invalid/blubb.js"),
     null: "empty",
   };
@@ -31,7 +34,8 @@
   // Also add several event handlers (onclick).
   let elements = ['madeup', 'b'];
   let properties = ['madeup', 'id', "onerror", "onclick"];
-  const types = [null, "TrustedHTML", "TrustedScript", "TrustedScriptURL"];
+  const types = [null, "TrustedHTML", "TrustedScript", "TrustedScriptURL",
+                 "TrustedURL"];
 
   // We'll wrap construction of the elements/properties list in a test, mainly
   // so we'll get decent error messages when it might fail.
@@ -108,11 +112,6 @@
               // return and hence skip the result comparison.
               case "outerHTML":
                 return;
-              // URL-typed accessors
-              case "src":
-                if (elem == "iframe")
-                  return;
-                break;
               // Properties starting with "on" are usually error handlers,
               // which will parse their input as a function. In this case,
               // also skip the result comparison.
@@ -143,5 +142,6 @@
       }
     }
   }
+
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/Window-open.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/Window-open.tentative.html
new file mode 100644
index 0000000..172d566e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/Window-open.tentative.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/helper.sub.js"></script>
+<body>
+<script>
+  // helper functions for the tests
+  function testWindowOpen(t, win, testNumber) {
+    let p = createURL_policy(window, testNumber);
+    let url = p.createURL(INPUTS.URL);
+    let child_window = win.open(url, "", "");
+    child_window.onload = t.step_func_done(_ => {
+      assert_equals(child_window.location.href, "" + url);
+      child_window.close();
+    });
+  }
+
+  test(t => {
+    testWindowOpen(t, window, 1);
+  }, "window.open via policy (successful URL transformation).");
+
+  test(t => {
+    testWindowOpen(t, document, 2);
+  }, "document.open via policy (successful URL transformation).");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html
index 1d6f3f6..3cae5d29 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttribute.tentative.html
@@ -11,6 +11,33 @@
 <script>
   const nullPolicy = trustedTypes.createPolicy('NullPolicy', {createScript: s => s});
 
+  // TrustedURL Assignments
+  const URLTestCases = [
+    [ 'a', 'href' ],
+    [ 'area', 'href' ],
+    [ 'base', 'href' ],
+    [ 'button', 'formAction' ],
+    [ 'form', 'action' ],
+    [ 'frame', 'src' ],
+    [ 'iframe', 'src' ],
+    [ 'img', 'src' ],
+    [ 'input', 'formAction' ],
+    [ 'input', 'src' ],
+    [ 'link', 'href' ],
+    [ 'video', 'src' ],
+    [ 'source', 'src' ],
+    [ 'track', 'src' ]
+  ];
+
+  URLTestCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_url_explicit_set(window, c, t, c[0], c[1], RESULTS.URL);
+      assert_throws_no_trusted_type_explicit_set(c[0], c[1], 'A string');
+      assert_throws_no_trusted_type_explicit_set(c[0], c[1], null);
+      assert_throws_no_trusted_type_explicit_set(c[0], c[1], nullPolicy.createScript('script'));
+    }, c[0] + "." + c[1] + " accepts only TrustedURL");
+  });
+
   // TrustedScriptURL Assignments
   const scriptURLTestCases = [
     [ 'embed', 'src' ],
@@ -56,17 +83,24 @@
   });
 
   test(t => {
-    let el = document.createElement('script');
+    let el = document.createElement('iframe');
 
     assert_throws(new TypeError(), _ => {
       el.setAttribute('SrC', INPUTS.URL);
     });
 
     assert_equals(el.src, '');
-  }, "`Script.prototype.setAttribute.SrC = string` throws.");
+  }, "`Element.prototype.setAttribute.SrC = string` throws.");
 
   // After default policy creation string and null assignments implicitly call createXYZ
-  let p = window.trustedTypes.createPolicy("default", { createScriptURL: createScriptURLJS, createHTML: createHTMLJS, createScript: createScriptJS }, true);
+  let p = window.trustedTypes.createPolicy("default", { createURL: createURLJS, createScriptURL: createScriptURLJS, createHTML: createHTMLJS, createScript: createScriptJS }, true);
+  URLTestCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_type(c[0], c[1], INPUTS.URL, RESULTS.URL);
+      assert_element_accepts_trusted_type(c[0], c[1], null, window.location.toString().replace(/[^\/]*$/, "null"));
+    }, c[0] + "." + c[1] + " accepts string and null after default policy was created.");
+  });
+
   scriptURLTestCases.forEach(c => {
     test(t => {
       assert_element_accepts_trusted_type(c[0], c[1], INPUTS.SCRIPTURL, RESULTS.SCRIPTURL);
@@ -90,6 +124,10 @@
 
   // Other attributes can be assigned with TrustedTypes or strings or null values
   test(t => {
+    assert_element_accepts_trusted_url_explicit_set(window, 'arel', t, 'a', 'rel', RESULTS.URL);
+  }, "a.rel assigned via policy (successful URL transformation)");
+
+  test(t => {
     assert_element_accepts_non_trusted_type_explicit_set('a', 'rel', 'A string', 'A string');
   }, "a.rel accepts strings");
 
@@ -98,14 +136,14 @@
   }, "a.rel accepts null");
 
   test(t => {
-    let embed = document.createElement('embed');
-    let script = document.createElement('script');
+    let div = document.createElement('div');
+    let span = document.createElement('span');
 
-    embed.setAttribute('src', INPUTS.SCRIPTURL);
-    let attr = embed.getAttributeNode('src');
-    embed.removeAttributeNode(attr);
-    script.setAttributeNode(attr);
+    div.setAttribute('src', INPUTS.URL);
+    let attr = div.getAttributeNode('src');
+    div.removeAttributeNode(attr);
+    span.setAttributeNode(attr);
 
-    assert_equals(script.getAttribute('src'), RESULTS.SCRIPTURL);
-  }, "`script.src = setAttributeNode(embed.src)` with string works.");
+    assert_equals(span.getAttribute('src'), INPUTS.URL);
+  }, "`span.src = setAttributeNode(div.src)` with string works.");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html
index 5754521..76a639a 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Element-setAttributeNS.tentative.html
@@ -21,6 +21,10 @@
       assert_element_accepts_trusted_script_url_set_ns(window, '2', t, 'a', 'b', RESULTS.SCRIPTURL);
     }, "Element.setAttributeNS assigned via policy (successful ScriptURL transformation)");
 
+    test(t => {
+      assert_element_accepts_trusted_url_set_ns(window, '3', t, 'a', 'b', RESULTS.URL);
+    }, "Element.setAttributeNS assigned via policy (successful URL transformation)");
+
     // Unknown, namespaced attributes should not be TT checked:
     test(t => {
       assert_element_accepts_non_trusted_type_set_ns('a', 'b', 'A string', 'A string');
@@ -31,12 +35,84 @@
     }, "Element.setAttributeNS accepts null for non-specced accessor");
 
     // Setup trusted values for use in subsequent tests.
+    const url = createURL_policy(window, '4').createURL(INPUTS.URL);
     const script_url = createScriptURL_policy(window, '5').createScriptURL(INPUTS.ScriptURL);
     const html = createHTML_policy(window, '6').createHTML(INPUTS.HTML);
     const script = createScript_policy(window, '7').createScript(INPUTS.Script);
 
+    // SVG elements that use xlink:href (SVGURIReference) and that expect
+    // TrustedURL.
+    // There a number of affected elements, and there are several ways to set
+    // a namespaced attribute. Let's iterate over all combinations.
     const xlink = "http://www.w3.org/1999/xlink";
     const svg = "http://www.w3.org/2000/svg";
+    const elems = [ "a", "animate", "animateMotion", "animateTransform",
+                    "discard", "feImage", "filter", "image", "linearGradient",
+                    "mpath", "pattern", "radialGradient", "set", "textPath",
+                    "use" ];
+
+    // There are multiple ways to set a namespaced attribute. Let's encapsulate
+    // each in a function.
+    const variants = {
+      "setAttributeNS with prefix": (element_name, value) => {
+        let elem = document.createElementNS(svg, element_name);
+        elem.setAttributeNS(xlink, "xlink:href", value);
+        return elem;
+      },
+      "setAttributeNS without prefix": (element_name, value) => {
+        let elem = document.createElementNS(svg, element_name);
+        elem.setAttributeNS(xlink, "href", value);
+        return elem;
+      },
+      "setAttribute with prefix": (element_name, value) => {
+        let elem = document.createElementNS(svg, element_name);
+        // Create the namespaced attribute with setAttributeNS. Then refer
+        // to it with the prefix in setAttribute. This test will break
+        // if either setAttributeNS or setAttribtue functionality it broken.
+        elem.setAttributeNS(xlink, "xlink:href", url);
+        elem.setAttribute("xlink:href", value);
+        return elem;
+      }
+    };
+    for (const e of elems) {
+      for (const variant in variants) {
+        // Assigning a TrustedURL works.
+        test(t => {
+          let elem = variants[variant](e, url);
+          assert_equals("" + RESULTS.URL,
+                        elem.getAttributeNodeNS(xlink, "href").value);
+        }, "Assigning TrustedURL to <svg:" + e + "> works via " + variant);
+
+        // Assigning things that ought to not work.
+        const values = ["abc", null, script_url, html, script];
+        values.forEach((value, index) => {
+          test(t => {
+            assert_throws(new TypeError(), _ => { variants[variant](e, value); });
+          }, "Blocking non-TrustedURL assignment to <svg:" + e + "> via " +
+             variant + " value no " + index);
+        });
+      }
+    }
+
+    // Test 'synchronization' of 'xlink:href'.
+    test(t => {
+      // ..setAttribute("xlink:href") will behave differently, depending on
+      // whether the element already has an attribute by that name. Make sure
+      // that Trusted Type handling respects that difference.
+
+      // Case 1: "xlink:href" on an empty element: This is an unknown attribute
+      // not processed by SVG, and string assignment should work.
+      let elem1 = document.createElementNS(svg, "a");
+      elem1.setAttribute("xlink:href", "abc");
+
+      // Case 2: "xlink:href", after a namespaced attribute has been set: Now
+      // this mirrors the SVG attribute, and string assignment should fail.
+      let elem2 = document.createElementNS(svg, "a");
+      elem2.setAttributeNS(xlink, "xlink:href", url);
+      assert_throws(new TypeError(), _ => {
+        elem2.setAttribute("xlink:href", "abc");
+      });
+    }, "Test synchronized, namespaced attributes.");
 
     // svg:script xlink:href=... expects a TrustedScriptURL.
     // Assigning a TrustedScriptURL works.
@@ -50,7 +126,7 @@
     // Assigning things that ought to not work.
     test(t => {
       let elem = document.createElementNS(svg, "script");
-      const values = [ "abc", null, html, script ];
+      const values = [ "abc", null, url, html, script ];
       for (const v of values) {
         assert_throws(new TypeError(), _ => {
           elem.setAttributeNS(xlink, "href", v);
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative-expected.txt
index a0a879cc..ab07bc3 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative-expected.txt
@@ -1,10 +1,38 @@
 This is a testharness.js-based test.
+PASS a.href accepts only TrustedURL
+PASS area.href accepts only TrustedURL
+PASS base.href accepts only TrustedURL
+PASS button.formAction accepts only TrustedURL
+PASS form.action accepts only TrustedURL
+PASS frame.src accepts only TrustedURL
+PASS iframe.src accepts only TrustedURL
+PASS img.src accepts only TrustedURL
+PASS input.formAction accepts only TrustedURL
+PASS input.src accepts only TrustedURL
+PASS link.href accepts only TrustedURL
+PASS video.src accepts only TrustedURL
+PASS source.src accepts only TrustedURL
+PASS track.src accepts only TrustedURL
 PASS embed.src accepts only TrustedScriptURL
 PASS object.codeBase accepts only TrustedScriptURL
 PASS object.data accepts only TrustedScriptURL
 PASS script.src accepts only TrustedScriptURL
 PASS div.innerHTML accepts only TrustedHTML
 PASS iframe.srcdoc accepts only TrustedHTML
+PASS a.href accepts string and null after default policy was created
+PASS area.href accepts string and null after default policy was created
+PASS base.href accepts string and null after default policy was created
+PASS button.formAction accepts string and null after default policy was created
+PASS form.action accepts string and null after default policy was created
+PASS frame.src accepts string and null after default policy was created
+PASS iframe.src accepts string and null after default policy was created
+PASS img.src accepts string and null after default policy was created
+PASS input.formAction accepts string and null after default policy was created
+PASS input.src accepts string and null after default policy was created
+PASS link.href accepts string and null after default policy was created
+PASS video.src accepts string and null after default policy was created
+PASS source.src accepts string and null after default policy was created
+PASS track.src accepts string and null after default policy was created
 PASS embed.src accepts string and null after default policy was created
 PASS object.codeBase accepts string and null after default policy was created
 PASS object.data accepts string and null after default policy was created
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html
index 84ff83bc..89d1216 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-HTMLElement-generic.tentative.html
@@ -10,6 +10,32 @@
 <body>
 <script>
   var testnb = 0;
+  // TrustedURL Assignments
+  const URLTestCases = [
+    [ 'a', 'href' ],
+    [ 'area', 'href' ],
+    [ 'base', 'href' ],
+    [ 'button', 'formAction' ],
+    [ 'form', 'action' ],
+    [ 'frame', 'src' ],
+    [ 'iframe', 'src' ],
+    [ 'img', 'src' ],
+    [ 'input', 'formAction' ],
+    [ 'input', 'src' ],
+    [ 'link', 'href' ],
+    [ 'video', 'src' ],
+    [ 'source', 'src' ],
+    [ 'track', 'src' ]
+  ];
+
+  URLTestCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_url(window, ++testnb, t, c[0], c[1], RESULTS.URL);
+      assert_throws_no_trusted_type(c[0], c[1], 'A string');
+      assert_throws_no_trusted_type(c[0], c[1], null);
+    }, c[0] + "." + c[1] + " accepts only TrustedURL");
+  });
+
   // TrustedScriptURL Assignments
   const scriptURLTestCases = [
     [ 'embed', 'src' ],
@@ -43,7 +69,14 @@
   });
 
   // After default policy creation string and null assignments implicitly call createHTML
-  let p = window.trustedTypes.createPolicy("default", { createScriptURL: createScriptURLJS, createHTML: createHTMLJS }, true);
+  let p = window.trustedTypes.createPolicy("default", { createURL: createURLJS, createScriptURL: createScriptURLJS, createHTML: createHTMLJS }, true);
+
+  URLTestCases.forEach(c => {
+    test(t => {
+      assert_element_accepts_trusted_type(c[0], c[1], INPUTS.URL, RESULTS.URL);
+      assert_element_accepts_trusted_type(c[0], c[1], null, window.location.toString().replace(/[^\/]*$/, "null"));
+    }, c[0] + "." + c[1] + " accepts string and null after default policy was created");
+  });
 
   scriptURLTestCases.forEach(c => {
     test(t => {
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-assign.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-assign.tentative.html
new file mode 100644
index 0000000..8e89d0d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-assign.tentative.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="support/helper.sub.js"></script>
+
+  <meta http-equiv="Content-Security-Policy" content="trusted-types *">
+</head>
+<body>
+<script>
+  // TrustedURL assignments do not throw.
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.assign(url);
+    assert_equals("" + url, location.href, "location href");
+  }, "location.assign via policy (successful URL transformation).");
+
+  // String assignments throw.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.assign("A string");
+    });
+    assert_equals(location.href, href);
+  }, "`location.assign = string` throws");
+
+  // Null assignment throws.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.assign(null);
+    });
+    assert_equals(location.href, href);
+  }, "`location.assign = null` throws");
+
+  // Create default policy. Applies to all subsequent tests.
+  let p = window.trustedTypes.createPolicy("default",
+      { createURL: createLocationURLJS }, true);
+
+  // After default policy creation string assignment implicitly calls createURL.
+  test(t => {
+    location.assign("abcdefg");
+    assert_true(location.href.endsWith("#abcdefg"));
+  }, "`location.assign = string` via default policy (successful URL transformation).");
+
+  // After default policy creation null assignment implicitly calls createURL.
+  test(t => {
+    location.assign(null);
+    assert_true(location.href.endsWith("#null"));
+  }, "`location.assign = null` via default policy does not throw.");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-href.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-href.tentative.html
new file mode 100644
index 0000000..998ee21
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-href.tentative.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="support/helper.sub.js"></script>
+
+  <meta http-equiv="Content-Security-Policy" content="trusted-types *">
+</head>
+<body>
+<script>
+  // TrustedURL assignments do not throw.
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.href = url;
+    assert_equals("" + url, location.href, "location href");
+  }, "location.href assigned via policy (successful URL transformation).");
+
+  // String assignments throw.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.href = 'A string';
+    });
+    assert_equals(location.href, href);
+  }, "`location.href = string` throws");
+
+  // Null assignment throws.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.href = null;
+    });
+    assert_equals(location.href, href);
+  }, "`location.href = null` throws");
+
+  // Create default policy. Applies to all subsequent tests.
+  let p = window.trustedTypes.createPolicy("default",
+      { createURL: createLocationURLJS }, true);
+
+  // After default policy creation string assignment implicitly calls createURL.
+  test(t => {
+    location.href = "xxxx";
+    assert_true(location.href.endsWith("#xxxx"));
+  }, "`location.href = string` via default policy (successful URL transformation).");
+
+  // After default policy creation null assignment implicitly calls createURL.
+  test(t => {
+    location.href = null;
+    assert_true(location.href.endsWith("#null"));
+  }, "`location.href = null` assigned via default policy does not throw.");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-replace.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-replace.tentative.html
new file mode 100644
index 0000000..e85bb646
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Location-replace.tentative.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="support/helper.sub.js"></script>
+
+  <meta http-equiv="Content-Security-Policy" content="trusted-types *">
+</head>
+<body>
+<script>
+  // TrustedURL replacements do not throw.
+  test(t => {
+    let p = createURL_policy(window, 1);
+    let url = p.createURL(location.href + "#xxx");
+    location.replace(url);
+    assert_equals("" + url, location.href, "location href");
+  }, "location.replace via policy (successful URL transformation).");
+
+  // String replacements throw.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.replace("A string");
+    });
+    assert_equals(location.href, href);
+  }, "`location.replace = string` throws");
+
+  // Null replacement throws.
+  test(t => {
+    let href = location.href;
+    assert_throws(new TypeError(), _ => {
+      location.replace(null);
+    });
+    assert_equals(location.href, href);
+  }, "`location.replace = null` throws");
+
+  // Create default policy. Applies to all subsequent tests.
+  let p = window.trustedTypes.createPolicy("default",
+      { createURL: createLocationURLJS }, true);
+
+  // After default policy creation string assignment implicitly calls createURL.
+  test(t => {
+    location.replace("potato");
+    assert_true(location.href.endsWith("#potato"));
+  }, "`location.replace = string` via default policy (successful URL transformation).");
+
+  // After default policy creation null assignment implicitly calls createURL.
+  test(t => {
+    location.replace(null);
+    assert_true(location.href.endsWith("#null"));
+  }, "`location.replace = null` via default policy (successful URL transformation).");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Window-open.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Window-open.tentative.html
new file mode 100644
index 0000000..e9c1c79
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/block-string-assignment-to-Window-open.tentative.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="support/helper.sub.js"></script>
+
+  <meta http-equiv="Content-Security-Policy" content="trusted-types *">
+</head>
+<body>
+<script>
+  var testnb = 0;
+  // helper functions for the tests
+  function testWindowOpen(t, win, nb) {
+    let p = createURL_policy(window, nb);
+    let url = p.createURL(INPUTS.URL);
+    let child_window = win.open(url, "", "");
+    t.add_cleanup(_ => child_window.close());
+    child_window.onload = t.step_func_done(_ => {
+      assert_equals(child_window.location.href, "" + url);
+    });
+  }
+
+  function testWindowThrows(t, url, win, nb) {
+    let p = createURL_policy(window, nb);
+    assert_throws(new TypeError(), _ => {
+      let child_window = win.open(url, "", "");
+    });
+  }
+
+  function testWindowDoesntThrow(t, url, expected, win) {
+    let child_window = win.open(url, "", "");
+    t.add_cleanup(_ => child_window.close());
+    child_window.onload = t.step_func_done(_ => {
+      assert_equals(child_window.location.href, expected);
+    });
+  }
+
+  // TrustedURL assignments do not throw.
+  test(t => {
+    testWindowOpen(t, window, ++testnb);
+  }, "window.open via policy (successful URL transformation).");
+
+  test(t => {
+    testWindowOpen(t, document, ++testnb);
+  }, "document.open via policy (successful URL transformation).");
+
+  // String assignments throw.
+  test(t => {
+    testWindowThrows(t, 'A string', window, ++testnb);
+  }, "`window.open(string)` throws.");
+
+  test(t => {
+    testWindowThrows(t, 'A string', document, ++testnb);
+  }, "`document.open(string)` throws.");
+
+  // Null assignment throws.
+  test(t => {
+    testWindowThrows(t, null, window, ++testnb);
+  }, "`window.open(null)` throws.");
+
+  test(t => {
+    testWindowThrows(t, null, document, ++testnb);
+  }, "`document.open(null)` throws.");
+
+  // After default policy creation string assignment implicitly calls createURL.
+  let p = window.trustedTypes.createPolicy("default", { createURL: createURLJS }, true);
+  test(t => {
+    testWindowDoesntThrow(t, INPUTS.URL, RESULTS.URL, window);
+  }, "'window.open(string)' assigned via default policy (successful URL transformation).");
+
+  test(t => {
+    testWindowDoesntThrow(t, INPUTS.URL, RESULTS.URL, document);
+  }, "'document.open(string)' assigned via default policy (successful URL transformation).");
+
+  test(t => {
+    testWindowDoesntThrow(t, null, "null", window);
+  }, "'window.open(null)' assigned via default policy does not throw.");
+
+  test(t => {
+    testWindowDoesntThrow(t, null, "null", document);
+  }, "'document.open(null)' assigned via default policy does not throw.");
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html
index ba23d7a3..1a54fd62 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.tentative.html
@@ -39,6 +39,7 @@
 }, "Count SecurityPolicyViolation events.");
 
 const testCases = [
+  [ "a", "href"],
   [ "script", "src" ],
   [ "div", "innerHTML" ],
   [ "script", "text" ],
@@ -70,6 +71,7 @@
 }
 
 trustedTypes.createPolicy("default", {
+  createURL: policy,
   createScriptURL: policy,
   createHTML: policy,
   createScript: policy
@@ -103,6 +105,6 @@
 });
 
 // Trigger the exit condition in the "Count" promise test above.
-try { document.createElement("script").text = "done"; } catch (e) {}
+try { document.createElement("a").href = "done"; } catch (e) {}
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html
index 955cdfaa..672eccf 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.tentative.html
@@ -39,6 +39,7 @@
 }, "Count SecurityPolicyViolation events.");
 
 const testCases = [
+  [ "a", "href"],
   [ "script", "src" ],
   [ "div", "innerHTML" ],
   [ "script", "text" ],
@@ -70,6 +71,7 @@
 }
 
 trustedTypes.createPolicy("default", {
+  createURL: policy,
   createScriptURL: policy,
   createHTML: policy,
   createScript: policy
@@ -103,6 +105,6 @@
 });
 
 // Trigger the exit condition in the "Count" promise test above.
-try { document.createElement("script").text = "done"; } catch (e) {}
+try { document.createElement("a").href = "done"; } catch (e) {}
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.window.js b/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.window.js
index 7be9615..4c1ee6e0 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.window.js
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.window.js
@@ -11,6 +11,7 @@
         TrustedHTML: ['window.trustedTypes.createPolicy("SomeName1", { createHTML: s => s }).createHTML("A string")'],
         TrustedScript: ['window.trustedTypes.createPolicy("SomeName2", { createScript: s => s }).createScript("A string")'],
         TrustedScriptURL: ['window.trustedTypes.createPolicy("SomeName3", { createScriptURL: s => s }).createScriptURL("A string")'],
+        TrustedURL: ['window.trustedTypes.createPolicy("SomeName4", { createURL: s => s }).createURL("A string")']
       });
     },
     'Trusted Types'
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/support/helper.sub.js b/third_party/blink/web_tests/external/wpt/trusted-types/support/helper.sub.js
index d13ad567..d63ff54 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/support/helper.sub.js
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/support/helper.sub.js
@@ -2,12 +2,14 @@
   HTML: "Hi, I want to be transformed!",
   SCRIPT: "Hi, I want to be transformed!",
   SCRIPTURL: "http://this.is.a.scripturl.test/",
+  URL: "http://hello.i.am.an.url/"
 };
 
 const RESULTS = {
   HTML: "Quack, I want to be a duck!",
   SCRIPT: "Meow, I want to be a cat!",
   SCRIPTURL: "http://this.is.a.successful.test/",
+  URL: "http://hooray.i.am.successfully.transformed/"
 };
 
 function createHTMLJS(html) {
@@ -24,6 +26,19 @@
   return scripturl.replace("scripturl", "successful");
 }
 
+function createURLJS(url) {
+  return url.replace("hello", "hooray")
+      .replace("an.url", "successfully.transformed");
+}
+
+// When testing location.href (& friends), we have the problem that assigning
+// to the new location will navigate away from the test. To fix this, we'll
+// have a policy that will just stick the argument into the fragment identifier
+// of the current location.href.
+function createLocationURLJS(value) {
+  return location.href.replace(/#.*/g, "") + "#" + value;
+}
+
 function createHTML_policy(win, c) {
   return win.trustedTypes.createPolicy('SomeHTMLPolicyName' + c, { createHTML: createHTMLJS });
 }
@@ -36,6 +51,10 @@
   return win.trustedTypes.createPolicy('SomeScriptURLPolicyName' + c, { createScriptURL: createScriptURLJS });
 }
 
+function createURL_policy(win, c) {
+  return win.trustedTypes.createPolicy('SomeURLPolicyName' + c, { createURL: createURLJS });
+}
+
 function assert_element_accepts_trusted_html(win, c, t, tag, attribute, expected) {
   let p = createHTML_policy(win, c);
   let html = p.createHTML(INPUTS.HTML);
@@ -54,6 +73,12 @@
   assert_element_accepts_trusted_type(tag, attribute, scripturl, expected);
 }
 
+function assert_element_accepts_trusted_url(win, c, t, tag, attribute, expected) {
+  let p = createURL_policy(win, c);
+  let url = p.createURL(INPUTS.URL);
+  assert_element_accepts_trusted_type(tag, attribute, url, expected);
+}
+
 function assert_element_accepts_trusted_type(tag, attribute, value, expected) {
   let elem = document.createElement(tag);
   elem[attribute] = value;
@@ -87,6 +112,12 @@
   assert_element_accepts_trusted_type_explicit_set(tag, attribute, scripturl, expected);
 }
 
+function assert_element_accepts_trusted_url_explicit_set(win, c, t, tag, attribute, expected) {
+  let p = createURL_policy(win, c);
+  let url = p.createURL(INPUTS.URL);
+  assert_element_accepts_trusted_type_explicit_set(tag, attribute, url, expected);
+}
+
 function assert_element_accepts_trusted_type_explicit_set(tag, attribute, value, expected) {
   let elem = document.createElement(tag);
   elem.setAttribute(attribute, value);
@@ -132,6 +163,12 @@
   assert_element_accepts_trusted_type_set_ns(tag, attribute, scripturl, expected);
 }
 
+function assert_element_accepts_trusted_url_set_ns(win, c, t, tag, attribute, expected) {
+  let p = createURL_policy(win, c);
+  let url = p.createURL(INPUTS.URL);
+  assert_element_accepts_trusted_type_set_ns(tag, attribute, url, expected);
+}
+
 function assert_element_accepts_trusted_type_set_ns(tag, attribute, value, expected) {
   let elem = document.createElement(tag);
   elem.setAttributeNS(namespace, attribute, value);
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-report-only.tentative.https.html b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-report-only.tentative.https.html
index bf0a1eb..1a17d529 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-report-only.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-report-only.tentative.https.html
@@ -7,14 +7,14 @@
 <body>
 
   <!-- Some elements for the tests to act on. -->
+  <a id="anchor" href="#">anchor</a>
   <div id="div"></div>
   <script id="script-src" src=""></script>
   <script id="script"></script>
-  <script id="script2"></script>
 
   <script>
   // CSP insists the "trusted-types: ..." directives are deliverd as headers
-  // (rather than as "meta http-equiv" tags). This test assumes the following
+  // (rather than as "<meta http-equiv" tags). This test assumes the following
   // headers are set in the .headers file:
   //
   //   Content-Security-Policy-Report-Only: trusted-types ...; report-uri ...
@@ -39,16 +39,17 @@
   const policy = trustedTypes.createPolicy("two", {
     createHTML: id,
     createScriptURL: id,
+    createURL: id,
     createScript: id,
   });
-/*
+
+
   promise_test(t => {
     let p = expect_violation("trusted-types two");
-    document.getElementById("script").src = "#abc";
-    assert_true(document.getElementById("script").src.endsWith("#abc"));
+    document.getElementById("anchor").href = "#abc";
+    assert_true(document.getElementById("anchor").href.endsWith("#abc"));
     return p;
-  }, "Trusted Type violation report-only: assign string to script url");
-*/
+  }, "Trusted Type violation report-only: assign string to url");
 
   promise_test(t => {
     let p = expect_violation("trusted-types two");
@@ -73,7 +74,7 @@
 
   promise_test(t => {
     let p = expect_violation("trusted-types two");
-    document.getElementById("script").src = "#def";
+    document.getElementById("anchor").href = "#def";
     return p.then(report => {
       assert_equals(report.documentURI, "" + window.location);
       assert_equals(report.disposition, "report");
@@ -82,5 +83,7 @@
       assert_true(report.originalPolicy.startsWith("trusted-types two;"));
     });
   }, "Trusted Type violation report: check report contents");
+
   </script>
+
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-reporting.tentative.https.html b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-reporting.tentative.https.html
index 10a951fa..6a79fec0 100644
--- a/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-reporting.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/trusted-types/trusted-types-reporting.tentative.https.html
@@ -77,6 +77,7 @@
   const a_policy = {
     createHTML: id,
     createScriptURL: id,
+    createURL: id,
     createScript: id,
   };
 
@@ -126,9 +127,9 @@
 
   promise_test(t => {
     let p = promise_violation("trusted-types two")();
-    expect_throws(_ => document.getElementById("script").src = url);
+    expect_throws(_ => document.getElementById("anchor").href = url);
     return p;
-  }, "Trusted Type violation report: assign string to script url");
+  }, "Trusted Type violation report: assign string to url");
 
   promise_test(t => {
     let p = promise_violation("trusted-types two")();
@@ -138,10 +139,10 @@
 
   promise_test(t => {
     let p = promise_flush()();
-    document.getElementById("script").text = policy_one.createScript("2+2;");
+    document.getElementById("anchor").href = policy_one.createURL("#");
     flush();
     return p;
-  }, "Trusted Type violation report: assign trusted script to script; no report");
+  }, "Trusted Type violation report: assign trusted URL to url; no report");
 
   promise_test(t => {
     let p = promise_flush()();
@@ -164,10 +165,10 @@
     let p = Promise.resolve()
         .then(promise_violation("trusted-types two"))
         .then(expect_blocked_uri("trusted-types-sink"))
-        .then(expect_sample("HTMLScriptElement.src"));
-      expect_throws(_ => { document.getElementById("script").src = "" });
+        .then(expect_sample("HTMLAnchorElement.href"));
+      expect_throws(_ => { document.getElementById("anchor").href = "" });
     return p;
-  }, "Trusted Type violation report: sample for script.src assignment");
+  }, "Trusted Type violation report: sample for .href assignment");
 
   promise_test(t => {
     let p = Promise.resolve()
@@ -209,24 +210,24 @@
   // refer to the DOM elements being modified, so that Custom Elements cannot
   // "mask" the underlying DOM mechanism (for reporting).
   if (customElements) {
-    class CustomScript extends HTMLScriptElement {};
-    customElements.define("custom-script", CustomScript, { extends: "script" });
+    class CustomLink extends HTMLAnchorElement {};
+    customElements.define("custom-link", CustomLink, { extends: "a" });
 
     promise_test(t => {
       let p = Promise.resolve()
           .then(promise_violation("trusted-types one"))
           .then(expect_blocked_uri("trusted-types-sink"))
-          .then(expect_sample("HTMLScriptElement.src"))
+          .then(expect_sample("HTMLAnchorElement.href"))
           .then(expect_sample("abc"));
-      expect_throws(_ => document.getElementById("customscript").src = "abc");
+      expect_throws(_ => document.getElementById("customlink").href = "abc");
       return p;
     }, "Trusted Type violation report: sample for custom element assignment");
   }
-
   </script>
 
   <!-- Some elements for the tests to act on. -->
+  <a id="anchor" href="">anchor</a>
   <div id="div"></div>
   <script id="script"></script>
-  <script id="customscript" is="custom-script" src="a"></script>
+  <a id="customlink" is="custom-link" href="a"></a>
 </body>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index e3b3b80..a39302d 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -8139,6 +8139,10 @@
     method getAttributeType
     method getPropertyType
     method getTypeMapping
+interface TrustedURL
+    attribute @@toStringTag
+    method constructor
+    method toString
 interface UIEvent : Event
     attribute @@toStringTag
     getter detail