Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
}
// You can add more selectors for variables, interfaces, etc.
],
"no-bitwise": 2,
"no-prototype-builtins": "off",
"react/prop-types": "off",
"react/display-name": "off",
Expand Down
28 changes: 27 additions & 1 deletion src/app/content/highlights/components/Card.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import Card, { CardProps } from './Card';
import DisplayNote from './DisplayNote';
import EditCard from './EditCard';
import showConfirmation from './utils/showConfirmation';
import * as cardUtils from './cardUtils';
import { ConfirmationToastProvider } from '../../components/ConfirmationToast';
import ReactDOM from 'react-dom';


jest.mock('./DisplayNote', () => (jest as any).requireActual('react').forwardRef(
(props: any, ref: any) => <div ref={ref} mock-display-note {...props} />
));
Expand Down Expand Up @@ -134,7 +136,7 @@ describe('Card', () => {
expect(tree).toMatchSnapshot();
});

it('matches snapshot without data', () => {
it('matches snapshot without data and preferEnd', () => {
store.dispatch(receiveBook(formatBookData(book, mockCmsBook)));
store.dispatch(receivePage({...page, references: []}));
store.dispatch(focusHighlight(highlight.id));
Expand All @@ -146,6 +148,28 @@ describe('Card', () => {
bottom: 200,
top: 100,
});
jest.spyOn(cardUtils, 'getPreferEnd').mockReturnValue(true);
const component = renderer.create(<TestContainer store={store}>
<Card {...cardProps} container={container} />
</TestContainer>, {createNodeMock});

const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

it('matches snapshot without data and preferEnd as false', () => {
store.dispatch(receiveBook(formatBookData(book, mockCmsBook)));
store.dispatch(receivePage({...page, references: []}));
store.dispatch(focusHighlight(highlight.id));
store.dispatch(openToc()); // added for css coverage
store.dispatch(requestSearch('asd')); // added for css coverage
cardProps.highlightOffsets = undefined; // added for css coverage
const container = assertDocument().createElement('div');
highlight.range.getBoundingClientRect.mockReturnValue({
bottom: 200,
top: 100,
});
jest.spyOn(cardUtils, 'getPreferEnd').mockReturnValue(false);
const component = renderer.create(<TestContainer store={store}>
<Card {...cardProps} container={container} />
</TestContainer>, {createNodeMock});
Expand Down Expand Up @@ -436,6 +460,8 @@ describe('Card', () => {
pageId: '123',
}));

jest.spyOn(cardUtils, 'getPreferEnd').mockReturnValue(true);

const spyScrollIntoView = jest.spyOn(domUtils, 'scrollIntoView');

highlight.elements = [firstElement, secondElement];
Expand Down
5 changes: 4 additions & 1 deletion src/app/content/highlights/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import EditCard from './EditCard';
import scrollHighlightIntoView from './utils/scrollHighlightIntoView';
import showConfirmation from './utils/showConfirmation';
import { useConfirmationToastContext } from '../../components/ConfirmationToast';
import { getPreferEnd } from './cardUtils';

export interface CardProps {
page: ReturnType<typeof selectContent['bookAndPage']>['page'];
Expand All @@ -53,6 +54,7 @@ export interface CardProps {
highlightOffsets?: { top: number; bottom: number };
onHeightChange: (ref: React.RefObject<HTMLElement>) => void;
isHidden: boolean;
preferEnd: boolean;
}

type CardPropsWithBookAndPage = Omit<CardProps, 'book' | 'page'> & {
Expand Down Expand Up @@ -292,12 +294,13 @@ const StyledCard = styled(Card)`
// Styling is expensive and most Cards don't need to render
function PreCard(props: CardProps) {
const computedProps = useComputedProps(props);
const preferEnd = getPreferEnd();

if (!computedProps.annotation && (!props.isActive)) {
return null;
}
return (
<StyledCard {...props} />
<StyledCard {...props} preferEnd={preferEnd} />
);
}

Expand Down
27 changes: 20 additions & 7 deletions src/app/content/highlights/components/CardWrapper.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ describe('CardWrapper', () => {
.mockImplementation((_container: any, highlight: Highlight) => {
const top = highlightsPositionsInDocument[highlights.findIndex((search) => search.id === highlight.id)];
return {
bottom: top + 20,
bottom: top,
top,
};
});
Expand Down Expand Up @@ -554,11 +554,17 @@ describe('CardWrapper', () => {
</Provider>
);
});
const node = assertDocument().getRootNode();
const compareDocumentPositionMock = jest.fn().mockReturnValue(node.DOCUMENT_POSITION_FOLLOWING);

const selectionMock = {
isCollapsed: true,
anchorNode: {},
focusNode: {},
anchorNode: {
compareDocumentPosition: compareDocumentPositionMock,
},
focusNode: {
compareDocumentPosition: compareDocumentPositionMock,
},
};
const getSelectionSpy = jest.spyOn(window!, 'getSelection').mockReturnValue(selectionMock as any);

Expand All @@ -584,11 +590,13 @@ describe('CardWrapper', () => {
</Provider>
);
});
const node = assertDocument().getRootNode();

const selectionMock = {
isCollapsed: false,
anchorNode: {},
focusNode: {},
anchorNode: {
compareDocumentPosition: jest.fn().mockReturnValue(node.DOCUMENT_POSITION_FOLLOWING),
},
};
const getSelectionSpy = jest.spyOn(window!, 'getSelection').mockReturnValue(selectionMock as any);

Expand Down Expand Up @@ -778,7 +786,9 @@ describe('CardWrapper', () => {

const selectionMock = {
isCollapsed: true,
anchorNode: {},
anchorNode: {
compareDocumentPosition: jest.fn().mockReturnValue(0),
},
focusNode: {},
};
const getSelectionSpy = jest.spyOn(window!, 'getSelection').mockReturnValue(selectionMock as any);
Expand All @@ -803,9 +813,12 @@ describe('CardWrapper', () => {
unmount = rendered.unmount;
});

const node = assertDocument().getRootNode();
const selectionMock = {
isCollapsed: false,
anchorNode: {},
anchorNode: {
compareDocumentPosition: jest.fn().mockReturnValue(node.DOCUMENT_POSITION_FOLLOWING),
},
focusNode: {},
toString: () => 'some text',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ exports[`Card matches snapshot when focused without note 1`] = `
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 0px;
top: -110px;
}
}

Expand All @@ -55,7 +55,7 @@ exports[`Card matches snapshot when focused without note 1`] = `
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 0px;
top: -110px;
}
}

Expand Down Expand Up @@ -153,7 +153,7 @@ exports[`Card matches snapshot when passed data without note 1`] = `
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 0px;
top: -110px;
}
}

Expand All @@ -163,7 +163,7 @@ exports[`Card matches snapshot when passed data without note 1`] = `
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 0px;
top: -110px;
}
}

Expand Down Expand Up @@ -213,7 +213,7 @@ exports[`Card matches snapshot when passed data without note 1`] = `
</div>
`;

exports[`Card matches snapshot without data 1`] = `
exports[`Card matches snapshot without data and preferEnd 1`] = `
.c0 {
visibility: visible;
-webkit-animation: 600ms bcCCNc ease-out;
Expand Down Expand Up @@ -330,3 +330,121 @@ exports[`Card matches snapshot without data 1`] = `
/>
</div>
`;

exports[`Card matches snapshot without data and preferEnd as false 1`] = `
.c0 {
visibility: visible;
-webkit-animation: 600ms bcCCNc ease-out;
animation: 600ms bcCCNc ease-out;
display: block;
position: absolute;
padding: 0.8rem;
border-radius: 0.4rem;
box-shadow: 0 0 2px 0 rgba(0,0,0,0.14),0 2px 2px 0 rgba(0,0,0,0.12),0 1px 3px 0 rgba(0,0,0,0.2);
left: calc(50% + (82.5rem / 2) + 3rem);
right: unset;
top: 200px;
left: calc(50% + (82.5rem / 2) + 1rem);
-webkit-transition: opacity 0.3s,top 0.3s,left 0.3s;
transition: opacity 0.3s,top 0.3s,left 0.3s;
}

.c0 .c1 {
z-index: 1;
}

@media print {
.c0 {
display: none;
}
}

@media (max-width:106.25em) {
.c0 {
-webkit-animation: none;
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 100px;
}
}

@media (max-width:82.8125em) {
.c0 {
-webkit-animation: none;
animation: none;
left: calc(75vw - (82.5rem / 2) + 1rem);
right: unset;
top: 100px;
}
}

<div
data-testid="card"
onClick={[Function]}
>
<div
className="c0"
hasUnsavedHighlight={false}
highlight={
Object {
"addFocusedStyles": [MockFunction],
"content": "test highlight content",
"elements": Array [
<span />,
],
"focus": [MockFunction],
"getStyle": [MockFunction],
"id": "asdf",
"isAttached": [MockFunction],
"range": Object {
"commonAncestorContainer": null,
"getBoundingClientRect": [MockFunction] {
"calls": Array [
Array [],
Array [],
Array [],
],
"results": Array [
Object {
"type": "return",
"value": Object {
"bottom": 200,
"top": 100,
},
},
Object {
"type": "return",
"value": Object {
"bottom": 200,
"top": 100,
},
},
Object {
"type": "return",
"value": Object {
"bottom": 200,
"top": 100,
},
},
],
},
},
"serialize": [Function],
"setStyle": [MockFunction],
"sourceId": "testbook1-testpage1-uuid",
}
}
isActive={true}
locationFilterId="testbook1-testpage1-uuid"
mock-edit={true}
onBlur={[Function]}
onCancel={[Function]}
onCreate={[Function]}
onHeightChange={[Function]}
onRemove={[Function]}
pageId="testbook1-testpage1-uuid"
setAnnotationChangesPending={[Function]}
/>
</div>
`;
10 changes: 7 additions & 3 deletions src/app/content/highlights/components/cardStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '../constants';
import { HighlightData } from '../types';
import { CardProps } from './Card';
import { getHighlightBottomOffset } from './cardUtils';
import { getHighlightBottomOffset, getHighlightTopOffset } from './cardUtils';
import { WrapperProps } from './CardWrapper';
import { cardBorder } from './style';

Expand Down Expand Up @@ -51,8 +51,12 @@ const overlapDisplay = css`
left: calc(75vw - (${contentTextWidth}rem / 2) + ${cardFocusedContentMargin}rem);
right: unset;
top: ${props.highlightOffsets
? props.highlightOffsets.bottom
: getHighlightBottomOffset(props.container, props.highlight)}px;
? (props.preferEnd
? props.highlightOffsets.bottom
: props.highlightOffsets.top - 110)
: (props.preferEnd
? getHighlightBottomOffset(props.container, props.highlight)
: getHighlightTopOffset(props.container, props.highlight))}px;
`}
${(props: CardProps) => !props.isActive && css`
display: none;
Expand Down
Loading
Loading