Skip to content

Commit 70c08a3

Browse files
authored
Merge pull request #1208 from Patternslib/scrum-2726--i18ncache
feat(pat-date-picker): Cache the ajax call to retrieve i18n picker translations.
2 parents fa870d1 + 9050ddc commit 70c08a3

File tree

2 files changed

+97
-42
lines changed

2 files changed

+97
-42
lines changed

src/pat/date-picker/date-picker.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import logging from "../../core/logging";
55
import Parser from "../../core/parser";
66
import dom from "../../core/dom";
77
import events from "../../core/events";
8+
import store from "../../core/store";
89
import utils from "../../core/utils";
910

1011
const log = logging.getLogger("date-picker");
@@ -30,6 +31,9 @@ parser.addAlias("behaviour", "behavior");
3031
* "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]
3132
* } */
3233

34+
export const storage = store.session("pat-date-picker");
35+
36+
3337
export default Base.extend({
3438
name: "date-picker",
3539
trigger: ".pat-date-picker",
@@ -184,11 +188,18 @@ export default Base.extend({
184188
}
185189

186190
if (this.options.i18n) {
187-
try {
188-
const response = await fetch(this.options.i18n);
189-
config.i18n = await response.json();
190-
} catch {
191-
log.error(`date-picker could not load i18n for ${this.options.i18n}`);
191+
let i18n = storage.get(this.options.i18n);
192+
if (!i18n) {
193+
try {
194+
const response = await fetch(this.options.i18n);
195+
i18n = await response.json();
196+
storage.set(this.options.i18n, i18n);
197+
} catch {
198+
log.error(`date-picker could not load i18n for ${this.options.i18n}`);
199+
}
200+
}
201+
if (i18n) {
202+
config.i18n = i18n;
192203
}
193204
}
194205
this.pikaday = new Pikaday(config);

src/pat/date-picker/date-picker.test.js

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import $ from "jquery";
22
import events from "../../core/events";
3+
import { storage } from "./date-picker";
34
import pattern from "./date-picker";
45
import pattern_auto_submit from "../auto-submit/auto-submit";
56
import utils from "../../core/utils";
@@ -142,46 +143,89 @@ describe("pat-date-picker", function () {
142143
});
143144

144145
describe("5 - Date picker with i18n", function () {
145-
describe("with proper json URL", function () {
146-
it("properly localizes the months and weekdays", async () => {
147-
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
148-
document.body.innerHTML =
149-
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
150-
const el = document.querySelector("input[type=date]");
151-
pattern.init(el);
152-
await utils.timeout(1); // wait a tick for async to settle.
153-
const display_el = document.querySelector("time");
154-
display_el.click();
155-
156-
const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
157-
expect(month.textContent).toBe("Oktober");
158-
159-
global.fetch.mockClear();
160-
delete global.fetch;
161-
});
146+
it("with proper json URL properly localizes the months and weekdays", async () => {
147+
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
148+
document.body.innerHTML =
149+
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
150+
const el = document.querySelector("input[type=date]");
151+
pattern.init(el);
152+
await utils.timeout(1); // wait a tick for async to settle.
153+
const display_el = document.querySelector("time");
154+
display_el.click();
155+
156+
const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
157+
expect(month.textContent).toBe("Oktober");
158+
159+
// Clear the storage
160+
storage.clear();
161+
// Reset mock
162+
global.fetch.mockClear();
163+
delete global.fetch;
162164
});
163165

164-
describe("with bogus json URL", function () {
165-
it("falls back to default (english) month and weekday labels ", async () => {
166-
// Simulate failing getJSON call
167-
global.fetch = jest.fn().mockImplementation(() => {
168-
throw "error";
169-
});
170-
171-
document.body.innerHTML =
172-
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
173-
const el = document.querySelector("input[type=date]");
174-
pattern.init(el);
175-
await utils.timeout(1); // wait a tick for async to settle.
176-
const display_el = document.querySelector("time");
177-
display_el.click();
178-
179-
const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
180-
expect(month.textContent).toBe("October");
181-
182-
global.fetch.mockClear();
183-
delete global.fetch;
166+
it("stores i18n results", async () => {
167+
global.fetch = jest.fn().mockImplementation(mock_fetch_i18n);
168+
document.body.innerHTML = `
169+
<input
170+
type="date"
171+
class="pat-date-picker"
172+
value="2018-10-21"
173+
data-pat-date-picker="i18n:/path/to/i18njson"
174+
/>
175+
<input
176+
type="date"
177+
class="pat-date-picker"
178+
value="2018-10-22"
179+
data-pat-date-picker="i18n:/path/to/i18njson"
180+
/>
181+
`;
182+
const els = document.querySelectorAll("input[type=date]");
183+
pattern.init(els[0]);
184+
await utils.timeout(1); // wait a tick for async to settle.
185+
expect(global.fetch).toHaveBeenCalledTimes(1);
186+
187+
// Initializing the other pattern should not lead to another AJAX call.
188+
189+
// NOTE: in a real environment where multiple instances are
190+
// initialized at once on the same page, before the ajax call has
191+
// been completed, each instance will do an AJAX call. After that,
192+
// when navigating to other pages with other date picker instance
193+
// the cached value should be used and no more AJAX calls should be
194+
// made.
195+
196+
pattern.init(els[1]);
197+
await utils.timeout(1); // wait a tick for async to settle.
198+
expect(global.fetch).toHaveBeenCalledTimes(1);
199+
200+
// Clear the storage
201+
storage.clear();
202+
// Reset mock
203+
global.fetch.mockClear();
204+
delete global.fetch;
205+
});
206+
207+
it("with bogus json URL falls back to default (english) month and weekday labels ", async () => {
208+
// Simulate failing getJSON call
209+
global.fetch = jest.fn().mockImplementation(() => {
210+
throw "error";
184211
});
212+
213+
document.body.innerHTML =
214+
'<input type="date" class="pat-date-picker" value="2018-10-21" data-pat-date-picker="i18n:/path/to/i18njson" />';
215+
const el = document.querySelector("input[type=date]");
216+
console.log(document.body.innerHTML);
217+
pattern.init(el);
218+
await utils.timeout(1); // wait a tick for async to settle.
219+
console.log(document.body.innerHTML);
220+
const display_el = document.querySelector("time");
221+
display_el.click();
222+
223+
const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore
224+
expect(month.textContent).toBe("October");
225+
226+
// Reset mock
227+
global.fetch.mockClear();
228+
delete global.fetch;
185229
});
186230
});
187231

0 commit comments

Comments
 (0)