[renderblocking] Add a new class to get link preload finish callbacks

In the existing code, LinkLoader is the only class that receives
callbacks when a link preload/modulepreload finishes. This patch moves
the logic into a new class PendingLinkPreload. The purposes are:

1. The new class will allow link header preloads to also receive
   callbacks when finishing, so that we can enable render-blocking on
   link headers. This will be implemented in crrev.com/c/3551557.

2. Moves the place where render-blocking starts from
   LinkLoader::LoadLink() (which may or may not actually start a fetch)
   to PreloadHelper::Preload/ModulePreloadIfNeeded(), right before
   where we actually start the preload. This fixes a bug that an invalid
   preload link with `blocking="render"` infinitely blocks rendering,
   for which we don't start a fetch so their finish callbacks will
   never be fired, which means the old implementation never unblocks
   rendering on them. This is verified by the new test
   invalid-render-blocking-preload-link.html.

The most important code changes to review are in:
- link_loader.h/cc
- pending_link_preload.h/cc
- preload_helper.h/cc

Bug: 1271296
Change-Id: I8f183b2b0f26c550e76319cda70d890b1d52f247
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3547303
Reviewed-by: Mason Freed <masonf@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#987234}
diff --git a/html/dom/render-blocking/invalid-render-blocking-preload-link.html b/html/dom/render-blocking/invalid-render-blocking-preload-link.html
new file mode 100644
index 0000000..a640f72
--- /dev/null
+++ b/html/dom/render-blocking/invalid-render-blocking-preload-link.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>An invalid preload link should not block rendering</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/preload/resources/preload_helper.js"></script>
+<link rel="preload" as="invalid" blocking="render"
+      href="/fonts/Ahem.ttf?pipe=trickle(d1)">
+<script>
+promise_test(async () => {
+  // requestAnimationFrame() should be eventually run, and the invalid preload
+  // link should not be loaded.
+  await new Promise(resolve => requestAnimationFrame(resolve));
+  verifyNumberOfResourceTimingEntries('/fonts/Ahem.ttf?pipe=trickle(d1)', 0);
+});
+</script>