Skip to content

Commit

Permalink
Merge pull request #142 from GoogleChromeLabs/feat/rws-2
Browse files Browse the repository at this point in the history
Feature: Add RWS json generator form
  • Loading branch information
Sayed Taqui authored Sep 25, 2023
2 parents 892b7b8 + b5990c4 commit 641811a
Show file tree
Hide file tree
Showing 44 changed files with 2,688 additions and 87 deletions.
6 changes: 3 additions & 3 deletions data/PSInfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"topics": {
"name": "Topics",
"description": "Provide a way for advertising to reach users based on interests inferred from the sites or apps the user visits, without needing to know the specific sites or apps the user has visited",
"description": "Provide a way for advertising to reach users based on interests inferred from the sites or apps the user visits, without needing to know the specific sites or apps the user has visited.",
"proposal": "https://github.com/patcg-individual-drafts/topics",
"publicDiscussion": "https://github.com/patcg-individual-drafts/topics/issues",
"videoOverview": "https://youtu.be/hEBzWuXjeTQ",
Expand All @@ -33,15 +33,15 @@
},
"related-website-sets": {
"name": "Related Website Sets",
"description": "A new web platform mechanism that would allow a company that owns multiple sites to declare a collection of related domains as being in a Related Website Sets. Sites that are part of a Related Website Set would be able to access cookies across the set of included domains",
"description": "A new web platform mechanism that would allow a company that owns multiple sites to declare a collection of related domains as being in a Related Website Sets. Sites that are part of a Related Website Set would be able to access cookies across the set of included domains.",
"proposal": "https://github.com/WICG/first-party-sets",
"publicDiscussion": "https://github.com/WICG/first-party-sets/issues",
"videoOverview": "https://www.youtube.com/watch?v=cNJ8mZ-J3F8",
"devDocumentation": "https://developer.chrome.com/docs/privacy-sandbox/first-party-sets/"
},
"shared-storage": {
"name": "Shared Storage",
"description": "The Shared Storage API allows sites to store and access unpartitioned cross-site data as to prevent cross-site user tracking, browsers are partitioning all forms of storage (cookies, localStorage, caches, etc). However, there are a number of legitimate use cases that rely on unpartitioned storage which would be impossible without help from new web APIs. ",
"description": "The Shared Storage API allows sites to store and access unpartitioned cross-site data as to prevent cross-site user tracking, browsers are partitioning all forms of storage (cookies, localStorage, caches, etc). However, there are a number of legitimate use cases that rely on unpartitioned storage which would be impossible without help from new web APIs.",
"proposal": "https://github.com/WICG/shared-storage",
"publicDiscussion": "https://github.com/WICG/shared-storage/issues",
"videoOverview": "",
Expand Down
8 changes: 7 additions & 1 deletion packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@
"simple-cookie": "^1.0.15",
"use-context-selector": "^1.4.1",
"use-debounce": "^9.0.4",
"validate.js": "^0.13.1",
"react-copy-to-clipboard": "^5.1.0",
"victory": "^36.6.11",
"@cookie-analysis-tool/common":"*"
}
},
"devDependencies": {
"@types/react-copy-to-clipboard": "^5.0.4"

}
}
3 changes: 3 additions & 0 deletions packages/extension/src/icons/add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/extension/src/icons/cross.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/extension/src/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ export { default as RelatedWebsiteSetsIcon } from './related-website-sets.svg';
export { default as RelatedWebsiteSetsIconWhite } from './related-website-sets-white.svg';
export { default as AntiCovertTrackingIcon } from './anti-covert-tracking.svg';
export { default as AntiCovertTrackingIconWhite } from './anti-covert-tracking-white.svg';
export { default as Add } from './add.svg';
export { default as Cross } from './cross.svg';
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ import classNames from 'classnames';
import React from 'react';

interface ButtonProps {
text: string;
text: string | React.ReactNode;
name?: string;
onClick?: () => void;
loading?: boolean;
type?: 'button' | 'submit' | 'reset';
variant?: 'primary' | 'secondary' | 'danger';
}
const Button = ({
text,
name = 'button',
onClick = undefined,
type = 'button',
variant = 'primary',
Expand All @@ -36,15 +38,19 @@ const Button = ({
<button
data-test-id="button"
type={type}
name={name}
onClick={onClick ? onClick : undefined}
className={classNames('py-1 px-2 rounded font-medium', {
'text-white dark:bg-absolute-zero-crayola bg-absolute-zero-crayola hover:bg-ocean-boat-blue':
variant === 'primary',
'bg-transparent dark:bg-transparent dark:text-bright-gray text-raisin-black':
variant === 'secondary',
'text-white dark:text-white dark:bg-red-500 bg-red-500':
variant === 'danger',
})}
className={classNames(
'py-1 px-2 rounded font-medium flex items-center text-center',
{
'text-white dark:bg-baby-blue-eyes bg-sapphire hover:bg-tufts-blue dark:hover:bg-pale-cornflower-blue dark:text-raisin-black':
variant === 'primary',
'bg-transparent dark:bg-transparent dark:text-bright-gray text-raisin-black active:opacity-60 hover:opacity-80':
variant === 'secondary',
'text-white dark:text-white dark:bg-red-500 bg-red-500 hover:bg-red-600':
variant === 'danger',
}
)}
>
{text}
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import React, { useState } from 'react';
import type { PSInfo as PSInfoType } from '../../../../utils/fetchPSInfo';
import RenderLink from './renderLink';
import { ArrowRight } from '../../../../icons';
import Button from '../button';

/**
* @type {Array} LABELS - Array of objects containing the label and link label for each dropdown item.
Expand Down Expand Up @@ -80,24 +81,22 @@ const LearnMoreDropdown = ({
</ul>
</div>
)}
<div className="flex items-center justify-start pt-4 border-t border-gray-200 dark:border-gray-500">
<button
className="inline-flex items-center px-3 py-2 text-sm font-medium text-center rounded-lg dark:hover:bg-blue-700 text-white dark:bg-absolute-zero-crayola bg-absolute-zero-crayola hover:bg-ocean-boat-blue"
onClick={() => {
setIsOpen(!isOpen);
}}
>
{isOpen ? (
'Close'
) : (
<>
Learn more{' '}
<span className="w-4 h-4 ml-2">
<ArrowRight />
</span>
</>
)}
</button>
<div className="pt-4 border-t border-gray-200 dark:border-gray-500">
<Button
text={
isOpen ? (
'Close'
) : (
<>
Learn more{' '}
<span className="w-4 h-4 ml-2 inline-block">
<ArrowRight />
</span>
</>
)
}
onClick={() => setIsOpen(!isOpen)}
/>
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ const RenderLink = ({ label, link, linkLabel }: RenderLinkProps) => (
{link ? (
<li className="py-4">
<div className="flex items-center">
<div className="flex-1 min-w-0">
<div className="flex-1 min-w-0 flex flex-col gap-2">
<p className="text-sm font-medium text-gray-900 dark:text-bright-gray truncate capitalize">
{label}
</p>
<a
title={link}
href={link}
className="text-xs text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-500"
className="text-xs text-bright-navy-blue dark:text-jordy-blue hover:opacity-80"
target="_blank"
rel="noreferrer"
>
Expand Down
4 changes: 3 additions & 1 deletion packages/extension/src/view/devtools/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ const App: React.FC = () => {
/>
</Resizable>
<main className="h-full flex-1 overflow-auto">
<TabContent />
<div className="min-w-[20rem] h-full">
<TabContent />
</div>
</main>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import React, { useState } from 'react';
import InfoCard from '../../../../design-system/components/infoCard';
import { PSInfoKey } from '../../../../../utils/fetchPSInfo';
import { Button } from '../../../../design-system/components';
import RWSJsonGenerator from './jsonGenerator';
import Insights from './insights';

const RelatedWebsiteSets = () => {
Expand All @@ -34,22 +35,17 @@ const RelatedWebsiteSets = () => {
className="w-full h-full overflow-auto"
data-testid="related-website-sets-content"
>
{showForm ? (
<>Placeholder</>
) : (
<>
<InfoCard infoKey={PSInfoKey.RelatedWebsiteSets} />
<div className="text-raisin-black dark:text-bright-gray max-w-2xl dark:bg-davys-grey border border-gray-200 dark:border-quartz rounded-lg shadow p-6 m-3 flex flex-col gap-4 divide-y divide-gray-200 dark:divide-gray-500">
<Insights />
<div className="pt-3">
<Button
text="Generate RWS JSON Resources"
onClick={() => setShowForm(!showForm)}
/>
</div>
</div>
</>
)}
<InfoCard infoKey={PSInfoKey.RelatedWebsiteSets} />
<div className="text-raisin-black dark:text-bright-gray max-w-2xl dark:bg-davys-grey border border-gray-200 dark:border-quartz rounded-lg shadow p-6 m-3 flex flex-col gap-3 divide-y divide-gray-200 dark:divide-gray-500">
<Insights />
<RWSJsonGenerator open={showForm} />
<div className="pt-4">
<Button
text={showForm ? 'Close' : 'Generate RWS JSON Resources'}
onClick={() => setShowForm(!showForm)}
/>
</div>
</div>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,80 @@
/**
* External dependencies.
*/
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { getDomain } from 'tldts';

/**
* Internal dependencies
*/
import checkURLInRWS, {
type CheckURLInRWSOutputType,
} from './utils/checkURLInRWS';
import { getDomain } from 'tldts';
import SitesList from './sitesList';

const Insights = () => {
const [insightsData, setInsightsData] =
useState<CheckURLInRWSOutputType | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
(async () => {
const result = await checkURLInRWS();
const insightsListener = useCallback(async () => {
setLoading(true);
const result = await checkURLInRWS();

setInsightsData(result);
setLoading(false);
})();
setInsightsData(result);
setTimeout(() => setLoading(false), 1000);
}, []);

useEffect(() => {
insightsListener();
}, [insightsListener]);

useEffect(() => {
chrome.tabs.onUpdated.addListener(
(tabId: number, changeInfo: chrome.tabs.TabChangeInfo) => {
if (changeInfo.url) {
if (
tabId !== chrome.devtools.inspectedWindow.tabId ||
(tabId === chrome.devtools.inspectedWindow.tabId &&
getDomain(changeInfo.url) === insightsData?.domain)
) {
return;
}

insightsListener();
}
}
);

return () => {
chrome.tabs.onUpdated.removeListener(insightsListener);
};
}, [insightsData?.domain, insightsListener]);

const cctlds = useMemo(
() =>
Object.values(insightsData?.relatedWebsiteSet?.ccTLDs || {}).reduce(
(prev, current) => {
return prev.concat(current);
},
[]
),
[insightsData?.relatedWebsiteSet?.ccTLDs]
);

return (
<div>
{loading ? (
<p className="text-base">Loading...</p>
<div className="flex gap-2 items-center justify-start">
<p className="text-sm">Loading...</p>
<div className="w-6 h-6 rounded-full animate-spin border-t-transparent border-solid border-blue-700 border-2" />
</div>
) : (
<div>
{insightsData?.isURLInRWS ? (
<div>
<h4 className="text-lg font-semibold">
This site belongs to a Related Website Set
This site belongs to &quot;Related Website Sets&quot;
</h4>
<p className="text-sm">
Primary Domain:{' '}
Expand Down Expand Up @@ -86,10 +126,22 @@ const Insights = () => {
</p>
)}
</div>

<div className="flex flex-row gap-4 mt-4 overflow-auto">
<SitesList
title="Associated Sites"
sites={insightsData.relatedWebsiteSet?.associatedSites || []}
/>
<SitesList
title="Service Sites"
sites={insightsData.relatedWebsiteSet?.serviceSites || []}
/>
<SitesList title="ccTLDs" sites={cctlds} />
</div>
</div>
) : (
<h4 className="text-lg font-semibold">
This site does not belong to a Related Website Set
This site does not belong to &quot;Related Website Sets&quot;
</h4>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* External dependencies.
*/
import React from 'react';

interface SitesListProps {
title: string;
sites: string[];
}

const SitesList = ({ title, sites }: SitesListProps) => {
if (!sites.length) {
return null;
}

return (
<div className="p-3 flex-1 bg-anti-flash-white dark:bg-charleston-green rounded-md">
<h4 className="text-base font-medium text-davys-grey dark:text-anti-flash-white mb-1">
{title}
</h4>
<div className="overflow-auto">
<ul className="list-disc ml-4 max-h-40">
{sites.map((site) => (
<li key={site}>{site}</li>
))}
</ul>
</div>
</div>
);
};

export default SitesList;
Loading

0 comments on commit 641811a

Please sign in to comment.