fix(widgets): restore article list rendering and reference styles
This commit is contained in:
1 parent
4ea00f1322
commit
fc04bf65e6
18 files changed
+345
-97
No files matched your search
@@ -332,9 +332,25 @@ function addJumpControl(document, pager, { max = 20, value = '4' } = {}) {
|
||||
return { input, button };
|
||||
}
|
||||
|
||||
function createRuntime({ fetch, pages } = {}) {
|
||||
function postsMarkup(document, unveiled = false) {
|
||||
const root = document.createElement('div');
|
||||
root.className = 'widget-main-post style-list';
|
||||
const pager = document.createElement('div');
|
||||
pager.className = 'widget-ajaxpager ' + (unveiled ? 'lazyloaded' : 'lazyload');
|
||||
pager.setAttribute('data-widget-items', '');
|
||||
pager.setAttribute('data-widget-lazy', '');
|
||||
pager.setAttribute('data-widget', 'posts');
|
||||
pager.setAttribute('data-instance', 'aksrt_widget_posts-2');
|
||||
pager.setAttribute('data-page', '1');
|
||||
pager.setAttribute('aria-busy', 'true');
|
||||
pager.innerHTML = '<div class="post_ajax_loader is-loading"><div class="posts-item placeholder">Loading</div></div>';
|
||||
root.appendChild(pager);
|
||||
return { root };
|
||||
}
|
||||
|
||||
function createRuntime({ fetch, pages, posts = false, unveiled = false, restUrl = '/wp-json/aksrt/v1/widgets/', observe = false } = {}) {
|
||||
const document = new MiniDocument();
|
||||
const { root: widget, nav, tabOne, tabTwo } = tabMarkup(document);
|
||||
const { root: widget, nav, tabOne, tabTwo } = posts ? postsMarkup(document, unveiled) : tabMarkup(document);
|
||||
document.body.appendChild(widget);
|
||||
const autoFun = [];
|
||||
function jQuery() {
|
||||
@@ -344,7 +360,7 @@ function createRuntime({ fetch, pages } = {}) {
|
||||
};
|
||||
}
|
||||
const requests = [];
|
||||
const config = { restUrl: '/wp-json/aksrt/v1', i18n: { error: 'error', retry: 'retry' } };
|
||||
const config = { restUrl, i18n: { error: 'error', retry: 'retry' } };
|
||||
const fetchStub = (url) => {
|
||||
requests.push(url);
|
||||
if (fetch) return fetch(url);
|
||||
@@ -357,11 +373,18 @@ function createRuntime({ fetch, pages } = {}) {
|
||||
};
|
||||
return Promise.resolve({ ok: true, json: () => Promise.resolve(response) });
|
||||
};
|
||||
let notifyMutation;
|
||||
const Observer = observe ? class {
|
||||
constructor(callback) { notifyMutation = callback; }
|
||||
observe() {}
|
||||
} : undefined;
|
||||
const window = {
|
||||
aksrtWidgets: config,
|
||||
location: { href: 'https://example.test/' },
|
||||
matchMedia: () => ({ matches: false }),
|
||||
jQuery,
|
||||
};
|
||||
if (observe) window.MutationObserver = Observer;
|
||||
vm.runInNewContext(fs.readFileSync(path.join(root, 'assets/widgets/frontend.js'), 'utf8'), {
|
||||
window,
|
||||
document,
|
||||
@@ -373,9 +396,10 @@ function createRuntime({ fetch, pages } = {}) {
|
||||
Object,
|
||||
Math,
|
||||
encodeURIComponent,
|
||||
MutationObserver: undefined,
|
||||
URL,
|
||||
MutationObserver: Observer,
|
||||
});
|
||||
return { document, widget, nav, tabOne, tabTwo, requests, autoFun };
|
||||
return { document, widget, nav, tabOne, tabTwo, requests, autoFun, notifyMutation };
|
||||
}
|
||||
|
||||
const tick = () => new Promise((resolve) => setImmediate(resolve));
|
||||
@@ -677,3 +701,76 @@ test('jump input clamps pages to max and rejects invalid or current pages withou
|
||||
assert.equal(runtime.requests.length, 0, 'submitting the already selected page does not request again');
|
||||
assert.equal(runtime.document.activeElement, input, 'invalid and current page values return focus to the input');
|
||||
});
|
||||
|
||||
test('article widget waits for its own lazy reveal and fetches the first page once', async () => {
|
||||
const transport = pendingFetch();
|
||||
const runtime = createRuntime({ posts: true, fetch: transport.fetch });
|
||||
const pager = runtime.widget.querySelector('[data-widget-items]');
|
||||
assert.equal(runtime.requests.length, 0, 'offscreen widgets keep their placeholder without fetching');
|
||||
assert.ok(pager.querySelector('.post_ajax_loader.is-loading'));
|
||||
pager.querySelector('.placeholder').dispatch('lazybeforeunveil');
|
||||
assert.equal(runtime.requests.length, 0, 'a descendant image reveal does not load the pager');
|
||||
pager.dispatch('lazybeforeunveil');
|
||||
pager.dispatch('lazybeforeunveil');
|
||||
assert.deepEqual(pageRequests(runtime.requests), [1]);
|
||||
const url = new URL(runtime.requests[0]);
|
||||
assert.equal(url.pathname, '/wp-json/aksrt/v1/widgets/posts/items');
|
||||
assert.equal(url.searchParams.get('instance'), 'aksrt_widget_posts-2');
|
||||
transport.pending[0].resolve({ html: '<posts class="posts-item list ajax-item" data-post-id="first">First article</posts>', page: 1, paginate_html: '' });
|
||||
await tick();
|
||||
assert.ok(pager.querySelector('[data-post-id="first"]'));
|
||||
assert.equal(pager.dataset.loaded, '1');
|
||||
assert.equal(pager.getAttribute('aria-busy'), 'false');
|
||||
assert.equal(pager.querySelector('.post_ajax_loader').classList.contains('is-loading'), false);
|
||||
pager.dispatch('lazybeforeunveil');
|
||||
assert.equal(runtime.requests.length, 1, 'a completed first page is never fetched again by lazySizes');
|
||||
});
|
||||
|
||||
test('article widget loads when lazySizes unveiled it before the widget client initialized', async () => {
|
||||
const runtime = createRuntime({ posts: true, unveiled: true });
|
||||
assert.deepEqual(pageRequests(runtime.requests), [1]);
|
||||
await tick();
|
||||
const pager = runtime.widget.querySelector('[data-widget-items]');
|
||||
assert.equal(pager.dataset.loaded, '1');
|
||||
assert.ok(pager.querySelector('[data-post-id]'));
|
||||
});
|
||||
|
||||
test('article widget failure exposes a retry that replaces the initial skeleton', async () => {
|
||||
const transport = pendingFetch();
|
||||
const runtime = createRuntime({ posts: true, fetch: transport.fetch });
|
||||
const pager = runtime.widget.querySelector('[data-widget-items]');
|
||||
pager.dispatch('lazybeforeunveil');
|
||||
transport.pending[0].reject(new Error('offline'));
|
||||
await tick();
|
||||
assert.equal(pager.getAttribute('aria-busy'), 'false');
|
||||
assert.equal(pager.querySelector('.post_ajax_loader').classList.contains('is-loading'), false);
|
||||
pager.querySelector('[data-widget-retry]').click();
|
||||
assert.deepEqual(pageRequests(runtime.requests), [1, 1]);
|
||||
transport.pending[1].resolve({ html: '<posts class="posts-item card ajax-item" data-post-id="retried">Retried</posts>', page: 1, paginate_html: '' });
|
||||
await tick();
|
||||
assert.ok(pager.querySelector('[data-post-id="retried"]'));
|
||||
assert.equal(pager.querySelector('[data-widget-retry]'), null);
|
||||
});
|
||||
|
||||
test('article REST addresses preserve the route for plain WordPress permalinks', async () => {
|
||||
const runtime = createRuntime({ posts: true, unveiled: true, restUrl: 'https://example.test/blog/?rest_route=/aksrt/v1/widgets/' });
|
||||
const url = new URL(runtime.requests[0]);
|
||||
assert.equal(url.pathname, '/blog/');
|
||||
assert.equal(url.searchParams.get('rest_route'), '/aksrt/v1/widgets/posts/items');
|
||||
assert.equal(url.searchParams.get('instance'), 'aksrt_widget_posts-2');
|
||||
assert.equal(url.searchParams.get('page'), '1');
|
||||
await tick();
|
||||
assert.equal(runtime.widget.querySelector('[data-widget-items]').dataset.loaded, '1');
|
||||
});
|
||||
|
||||
test('a pager inserted as the mutation root still receives its lazy listener', async () => {
|
||||
const runtime = createRuntime({ observe: true });
|
||||
const pager = postsMarkup(runtime.document).root.querySelector('[data-widget-items]');
|
||||
pager.nodeType = 1;
|
||||
runtime.document.body.appendChild(pager);
|
||||
runtime.notifyMutation([{ addedNodes: [pager] }]);
|
||||
pager.dispatch('lazybeforeunveil');
|
||||
await tick();
|
||||
assert.deepEqual(pageRequests(runtime.requests), [1]);
|
||||
assert.equal(pager.dataset.loaded, '1');
|
||||
});
|
||||
Reference in new issue
Block a user