Niedzielski has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/392570 )

Change subject: Update: capture wiki link clicks and navigation
......................................................................

Update: capture wiki link clicks and navigation

Extract Link.onClick to link-on-click#onClick and use in ContentSection
so that visiting wiki pages only loads the minimal content needed
inline.

Bug: T177367
Change-Id: I5175d9473c128fce87820e9d11788db7b4dd6df1
---
M package.json
M src/common/components/content-section/content-section.tsx
A src/common/components/link-on-click.ts
M src/common/components/link.tsx
4 files changed, 58 insertions(+), 38 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/marvin refs/changes/70/392570/1

diff --git a/package.json b/package.json
index 2ff5df7..33ff1af 100644
--- a/package.json
+++ b/package.json
@@ -103,7 +103,7 @@
   "bundlesize": [
     {
       "path": "dist/public/index.*.js",
-      "maxSize": "3.1KB"
+      "maxSize": "3.2KB"
     },
     {
       "path": "dist/public/runtime.*.js",
diff --git a/src/common/components/content-section/content-section.tsx 
b/src/common/components/content-section/content-section.tsx
index a87ad83..601fa17 100644
--- a/src/common/components/content-section/content-section.tsx
+++ b/src/common/components/content-section/content-section.tsx
@@ -1,16 +1,25 @@
+import { History } from "history";
 import { h } from "preact";
 import { PageSection } from "../../models/page/page";
 import Content from "../content/content";
 import DynamicHeader from "../dynamic-header/dynamic-header";
+import { onClick } from "../link-on-click";
 import "./content-section.css";
 
 export interface Props {
   section: PageSection;
 }
 
-export default function ContentSection({ section }: Props): JSX.Element {
+export default function ContentSection(
+  { section }: Props,
+  context: { history?: History }
+): JSX.Element {
   return (
-    <section class="ContentSection" id={section.fragment}>
+    <section
+      onClick={event => onClick(context, event)}
+      class="ContentSection"
+      id={section.fragment}
+    >
       {section.titleHTML && ( // Omit empty headers such as the lead.
         <DynamicHeader class="ContentSection-header" level={section.level + 1}>
           <Content dangerouslySetInnerHTML={{ __html: section.titleHTML }} />
diff --git a/src/common/components/link-on-click.ts 
b/src/common/components/link-on-click.ts
new file mode 100644
index 0000000..85c6cc4
--- /dev/null
+++ b/src/common/components/link-on-click.ts
@@ -0,0 +1,43 @@
+import { History } from "history";
+
+function isModifiedEvent(event: MouseEvent): boolean {
+  return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
+}
+
+function isInternalLink(link: HTMLAnchorElement) {
+  // N.B. link.href is used because browsers will transform relative paths to
+  // the full path when set on the HTML anchor, which is what is used to check
+  // against the current origin.
+  return link.href && link.href.indexOf(window.location.origin) === 0;
+}
+
+// TODO: add unit tests
+export function onClick(
+  context: { history?: History },
+  event: MouseEvent
+): void {
+  // When set on an anchor, currentTarget is the anchor. When set on a parent 
to
+  // capture all clicks, currentTarget may be something else. Use target and
+  // walk the DOM inclusively upwards until an anchor is found.
+  const link = (event.target as HTMLElement).closest(
+    "a"
+  ) as HTMLAnchorElement | null;
+  if (
+    link &&
+    isInternalLink(link) &&
+    // onClick not prevented default
+    !event.defaultPrevented &&
+    // Ignore everything but left clicks
+    event.button === 0 &&
+    // Let browser handle "target=_blank" etc.
+    !link.target &&
+    // Ignore clicks with modifier keys
+    !isModifiedEvent(event) &&
+    // We have a context history
+    context.history
+  ) {
+    event.preventDefault();
+    const path = link.href.replace(window.location.origin, "");
+    context.history.push(path);
+  }
+}
diff --git a/src/common/components/link.tsx b/src/common/components/link.tsx
index 75ec31c..668fb96 100644
--- a/src/common/components/link.tsx
+++ b/src/common/components/link.tsx
@@ -1,13 +1,10 @@
-import { h } from "preact";
 import { History } from "history";
+import { h } from "preact";
 import { ChildrenProps, classOf, ClassProps } from "./preact-utils";
+import { onClick } from "./link-on-click";
 
 export interface Props extends ClassProps, ChildrenProps {
   href: string;
-}
-
-function isModifiedEvent(event: MouseEvent): boolean {
-  return event.metaKey || event.altKey || event.ctrlKey || event.shiftKey;
 }
 
 /**
@@ -22,36 +19,7 @@
     <a
       class={classOf("Link", props.class)}
       href={href}
-      onClick={event => {
-        const origin = window.location.origin;
-        // Use currentTarget as target may be other DOM elements inside the
-        // anchor element
-        const link = event.currentTarget as HTMLAnchorElement;
-        // TODO: Move all the logic to check if an event should be captured to 
a
-        // DOM utilities module and add unit tests
-        if (
-          // Check if the href is internal
-          //
-          // N.B. link.href is used because browsers will transform relative
-          // paths to the full path when set on the HTML anchor, which is what
-          // is used to check against the current origin
-          link.href &&
-          link.href.indexOf(origin) === 0 &&
-          // onClick not prevented default
-          !event.defaultPrevented &&
-          // Ignore everything but left clicks
-          event.button === 0 &&
-          // Let browser handle "target=_blank" etc.
-          !link.target &&
-          // Ignore clicks with modifier keys
-          !isModifiedEvent(event) &&
-          // We have a context history
-          context.history
-        ) {
-          event.preventDefault();
-          context.history.push(href);
-        }
-      }}
+      onClick={event => onClick(context, event)}
     >
       {children}
     </a>

-- 
To view, visit https://gerrit.wikimedia.org/r/392570
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5175d9473c128fce87820e9d11788db7b4dd6df1
Gerrit-PatchSet: 1
Gerrit-Project: marvin
Gerrit-Branch: master
Gerrit-Owner: Niedzielski <sniedziel...@wikimedia.org>
Gerrit-Reviewer: Sniedzielski <sniedziel...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to