@financial-times/n-myft-ui 28.0.7 → 28.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@
|
|
4
4
|
data-myft-ui="saved"
|
5
5
|
action="/myft/save/{{contentId}}"
|
6
6
|
data-js-action="/__myft/api/core/saved/content/{{contentId}}?method=put"
|
7
|
-
{{#
|
7
|
+
{{#if @root.flags.manageArticleLists}}data-myft-ui-save-new="manageArticleLists"{{/if}}>
|
8
8
|
{{> n-myft-ui/components/csrf-token/input}}
|
9
9
|
<div
|
10
10
|
class="n-myft-ui__announcement o-normalise-visually-hidden"
|
package/myft/ui/lists.js
CHANGED
@@ -179,8 +179,8 @@ function handleArticleSaved (contentId) {
|
|
179
179
|
function openCreateListAndAddArticleOverlay (contentId) {
|
180
180
|
return myFtClient.getAll('created', 'list')
|
181
181
|
.then(createdLists => createdLists.filter(list => !list.isRedirect))
|
182
|
-
.then(
|
183
|
-
return
|
182
|
+
.then(() => {
|
183
|
+
return showCreateListAndAddArticleOverlay(contentId);
|
184
184
|
});
|
185
185
|
}
|
186
186
|
|
@@ -192,8 +192,8 @@ function initialEventListeners () {
|
|
192
192
|
// Checks if the createListAndSaveArticle variant is active
|
193
193
|
// and will show the variant overlay if the user has no lists,
|
194
194
|
// otherwise it will show the classic overlay
|
195
|
-
const
|
196
|
-
if (
|
195
|
+
const createNewListDesign = event.currentTarget.querySelector('[data-myft-ui-save-new="manageArticleLists"]');
|
196
|
+
if (createNewListDesign) {
|
197
197
|
return openCreateListAndAddArticleOverlay(contentId);
|
198
198
|
}
|
199
199
|
|
@@ -5,20 +5,14 @@ import getToken from './lib/get-csrf-token';
|
|
5
5
|
|
6
6
|
const csrfToken = getToken();
|
7
7
|
|
8
|
-
let lists;
|
8
|
+
let lists = [];
|
9
|
+
let haveLoadedLists = false;
|
9
10
|
|
10
|
-
export default async function
|
11
|
-
try {
|
12
|
-
await openSaveArticleToListVariant (name, contentId);
|
13
|
-
} catch(error) {
|
14
|
-
handleError(error);
|
15
|
-
}
|
16
|
-
}
|
17
|
-
|
18
|
-
async function openSaveArticleToListVariant (name, contentId) {
|
11
|
+
export default async function openSaveArticleToListVariant (name, contentId) {
|
19
12
|
function createList (list) {
|
20
13
|
if(!list) {
|
21
|
-
|
14
|
+
if (!lists.length) attachDescription();
|
15
|
+
return contentElement.addEventListener('click', openFormHandler, { once: true });
|
22
16
|
}
|
23
17
|
|
24
18
|
myFtClient.add('user', null, 'created', 'list', uuid(), { name: list, token: csrfToken })
|
@@ -33,6 +27,10 @@ async function openSaveArticleToListVariant (name, contentId) {
|
|
33
27
|
triggerCreateListEvent(contentId);
|
34
28
|
contentElement.addEventListener('click', openFormHandler, { once: true });
|
35
29
|
});
|
30
|
+
})
|
31
|
+
.catch(() => {
|
32
|
+
if (!lists.length) attachDescription();
|
33
|
+
return contentElement.addEventListener('click', openFormHandler, { once: true });
|
36
34
|
});
|
37
35
|
}
|
38
36
|
|
@@ -66,8 +64,9 @@ async function openSaveArticleToListVariant (name, contentId) {
|
|
66
64
|
});
|
67
65
|
}
|
68
66
|
|
69
|
-
if (!
|
67
|
+
if (!haveLoadedLists) {
|
70
68
|
lists = await getLists(contentId);
|
69
|
+
haveLoadedLists = true;
|
71
70
|
}
|
72
71
|
|
73
72
|
const overlays = Overlay.getOverlays();
|
@@ -77,7 +76,7 @@ async function openSaveArticleToListVariant (name, contentId) {
|
|
77
76
|
}
|
78
77
|
|
79
78
|
const headingElement = HeadingElement();
|
80
|
-
let [contentElement, removeDescription] = ContentElement(!lists.length);
|
79
|
+
let [contentElement, removeDescription, attachDescription] = ContentElement(!lists.length);
|
81
80
|
|
82
81
|
const createListOverlay = new Overlay(name, {
|
83
82
|
html: contentElement,
|
@@ -87,36 +86,37 @@ async function openSaveArticleToListVariant (name, contentId) {
|
|
87
86
|
class: 'myft-ui-create-list-variant',
|
88
87
|
});
|
89
88
|
|
90
|
-
const realignListener = realignOverlay(window.scrollY);
|
91
|
-
|
92
89
|
function outsideClickHandler (e) {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
createListOverlay.close();
|
97
|
-
}
|
98
|
-
} catch(error) {
|
99
|
-
handleError(error);
|
90
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
91
|
+
if(createListOverlay.visible && (!overlayContent || !overlayContent.contains(e.target))) {
|
92
|
+
createListOverlay.close();
|
100
93
|
}
|
101
94
|
}
|
102
95
|
|
103
96
|
function openFormHandler () {
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
97
|
+
const formElement = FormElement(createList);
|
98
|
+
const overlayContent = document.querySelector('.o-overlay__content');
|
99
|
+
removeDescription();
|
100
|
+
overlayContent.insertAdjacentElement('beforeend', formElement);
|
101
|
+
formElement.elements[0].focus();
|
102
|
+
}
|
103
|
+
|
104
|
+
function getScrollHandler (target) {
|
105
|
+
return realignOverlay(window.scrollY, target);
|
106
|
+
}
|
107
|
+
|
108
|
+
function resizeHandler () {
|
109
|
+
positionOverlay(createListOverlay.wrapper);
|
113
110
|
}
|
114
111
|
|
115
112
|
createListOverlay.open();
|
113
|
+
|
114
|
+
const scrollHandler = getScrollHandler(createListOverlay.wrapper);
|
115
|
+
|
116
116
|
createListOverlay.wrapper.addEventListener('oOverlay.ready', (data) => {
|
117
|
-
|
117
|
+
positionOverlay(data.currentTarget);
|
118
118
|
|
119
|
-
if (lists
|
119
|
+
if (lists.length) {
|
120
120
|
const listElement = ListsElement(lists, addToList, removeFromList);
|
121
121
|
const overlayContent = document.querySelector('.o-overlay__content');
|
122
122
|
overlayContent.insertAdjacentElement('afterbegin', listElement);
|
@@ -125,12 +125,16 @@ async function openSaveArticleToListVariant (name, contentId) {
|
|
125
125
|
contentElement.addEventListener('click', openFormHandler, { once: true });
|
126
126
|
|
127
127
|
document.querySelector('.article-content').addEventListener('click', outsideClickHandler, { once: true });
|
128
|
+
|
129
|
+
window.addEventListener('scroll', scrollHandler);
|
130
|
+
|
131
|
+
window.addEventListener('oViewport.resize', resizeHandler);
|
128
132
|
});
|
129
133
|
|
130
|
-
|
134
|
+
createListOverlay.wrapper.addEventListener('oOverlay.destroy', () => {
|
135
|
+
window.removeEventListener('scroll', scrollHandler);
|
131
136
|
|
132
|
-
|
133
|
-
realignListener(createListOverlay.wrapper);
|
137
|
+
window.removeEventListener('oViewport.resize', resizeHandler);
|
134
138
|
});
|
135
139
|
}
|
136
140
|
|
@@ -157,16 +161,12 @@ function FormElement (createList) {
|
|
157
161
|
const formElement = stringToHTMLElement(formString);
|
158
162
|
|
159
163
|
function handleSubmit (event) {
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
formElement.remove();
|
167
|
-
} catch(error) {
|
168
|
-
handleError(error);
|
169
|
-
}
|
164
|
+
event.preventDefault();
|
165
|
+
event.stopPropagation();
|
166
|
+
const inputListName = formElement.querySelector('input[name="list-name"]');
|
167
|
+
createList(inputListName.value);
|
168
|
+
inputListName.value = '';
|
169
|
+
formElement.remove();
|
170
170
|
}
|
171
171
|
|
172
172
|
formElement.querySelector('button[type="submit"]').addEventListener('click', handleSubmit);
|
@@ -174,12 +174,14 @@ function FormElement (createList) {
|
|
174
174
|
return formElement;
|
175
175
|
}
|
176
176
|
|
177
|
-
function ContentElement (
|
177
|
+
function ContentElement (hasDescription) {
|
178
|
+
const description = '<p class="myft-ui-create-list-variant-add-description">Lists are a simple way to curate your content</p>';
|
179
|
+
|
178
180
|
const content = `
|
179
181
|
<div class="myft-ui-create-list-variant-footer">
|
180
182
|
<button class="myft-ui-create-list-variant-add">Add to a new list</button>
|
181
|
-
${
|
182
|
-
|
183
|
+
${hasDescription ? `
|
184
|
+
${description}
|
183
185
|
` : ''}
|
184
186
|
</div>
|
185
187
|
`;
|
@@ -193,7 +195,12 @@ function ContentElement (description) {
|
|
193
195
|
}
|
194
196
|
}
|
195
197
|
|
196
|
-
|
198
|
+
function attachDescription () {
|
199
|
+
const descriptionElement = stringToHTMLElement(description);
|
200
|
+
contentElement.insertAdjacentElement('beforeend', descriptionElement);
|
201
|
+
}
|
202
|
+
|
203
|
+
return [contentElement, removeDescription, attachDescription];
|
197
204
|
}
|
198
205
|
|
199
206
|
function HeadingElement () {
|
@@ -256,36 +263,41 @@ function ListCheckboxElement (addToList, removeFromList) {
|
|
256
263
|
};
|
257
264
|
}
|
258
265
|
|
259
|
-
function realignOverlay (originalScrollPosition) {
|
260
|
-
return function (
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
originalScrollPosition = currentScrollPosition;
|
267
|
-
|
268
|
-
target.style['min-width'] = '340px';
|
269
|
-
target.style['width'] = '100%';
|
270
|
-
target.style['margin-top'] = '-50px';
|
271
|
-
target.style['left'] = 0;
|
272
|
-
|
273
|
-
if (isMobile()) {
|
274
|
-
target.style['position'] = 'absolute';
|
275
|
-
target.style['margin-left'] = 0;
|
276
|
-
target.style['margin-top'] = 0;
|
277
|
-
target.style['top'] = calculateLargerScreenHalf(target) === 'ABOVE' ? '-120px' : '50px';
|
278
|
-
} else {
|
279
|
-
target.style['position'] = 'absolute';
|
280
|
-
target.style['margin-left'] = '45px';
|
281
|
-
target.style['top'] = '220px';
|
282
|
-
}
|
283
|
-
} catch (error) {
|
284
|
-
handleError(error);
|
266
|
+
function realignOverlay (originalScrollPosition, target) {
|
267
|
+
return function () {
|
268
|
+
const currentScrollPosition = window.scrollY;
|
269
|
+
|
270
|
+
if(Math.abs(currentScrollPosition - originalScrollPosition) < 120) {
|
271
|
+
return;
|
285
272
|
}
|
273
|
+
|
274
|
+
if (currentScrollPosition) {
|
275
|
+
originalScrollPosition = currentScrollPosition;;
|
276
|
+
}
|
277
|
+
|
278
|
+
positionOverlay(target);
|
286
279
|
};
|
287
280
|
}
|
288
281
|
|
282
|
+
function positionOverlay (target) {
|
283
|
+
target.style['min-width'] = '340px';
|
284
|
+
target.style['width'] = '100%';
|
285
|
+
target.style['margin-top'] = '-50px';
|
286
|
+
target.style['left'] = 0;
|
287
|
+
|
288
|
+
if (isMobile()) {
|
289
|
+
const shareNavComponent = document.querySelector('.share-nav__horizontal');
|
290
|
+
target.style['position'] = 'absolute';
|
291
|
+
target.style['margin-left'] = 0;
|
292
|
+
target.style['margin-top'] = 0;
|
293
|
+
target.style['top'] = calculateLargerScreenHalf(shareNavComponent) === 'ABOVE' ? '-120px' : '50px';
|
294
|
+
} else {
|
295
|
+
target.style['position'] = 'absolute';
|
296
|
+
target.style['margin-left'] = '45px';
|
297
|
+
target.style['top'] = '220px';
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
289
301
|
function isMobile () {
|
290
302
|
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
|
291
303
|
|
@@ -293,6 +305,10 @@ function isMobile () {
|
|
293
305
|
}
|
294
306
|
|
295
307
|
function calculateLargerScreenHalf (target) {
|
308
|
+
if (!target) {
|
309
|
+
return 'BELOW';
|
310
|
+
}
|
311
|
+
|
296
312
|
const vh = Math.min(document.documentElement.clientHeight || 0, window.innerHeight || 0);
|
297
313
|
|
298
314
|
const targetBox = target.getBoundingClientRect();
|
@@ -357,13 +373,3 @@ function triggerCreateListEvent (contentId) {
|
|
357
373
|
bubbles: true
|
358
374
|
}));
|
359
375
|
}
|
360
|
-
|
361
|
-
function handleError (error) {
|
362
|
-
document.body.dispatchEvent(new CustomEvent('oErrors.log', {
|
363
|
-
bubbles: true,
|
364
|
-
detail: {
|
365
|
-
error,
|
366
|
-
info: { component: 'professorLists' },
|
367
|
-
}
|
368
|
-
}));
|
369
|
-
}
|