@financial-times/n-myft-ui 28.0.7 → 28.1.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -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
|
-
}
|