Skip to content
This repository was archived by the owner on Nov 6, 2024. It is now read-only.

Commit 747102e

Browse files
authored
Merge pull request #83 from Esri/feat/load-css
Feat/load css
2 parents 510a7c5 + 03caf39 commit 747102e

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [Unreleased]
66
### Added
7+
- added loadCss(url) to inject a stylesheet link
78
### Changed
89
- added GitHub issue and pull request templates
910
- added badges to README

README.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,25 @@ The code snippets below show how to load the ArcGIS API and its modules and then
3131

3232
### Loading Styles
3333

34-
Before you can use the ArcGIS API in your app, you'll need to load the styles. For example, if you're using the latest 4.x version (the default):
34+
Before you can use the ArcGIS API in your app, you'll need to load the styles that correspond to the version you are using. You can use the provided `loadCss(url)` function. For example:
3535

36-
```css
37-
/* esri styles */
36+
```js
37+
// load esri styles for version 4.6 using loadCss
38+
esriLoader.loadCss('https://js.arcgis.com/4.6/esri/css/main.css');
39+
```
40+
41+
Alternatively, you can manually load them by more traditional means such as adding `<link>` tags to your HTML, or `@import` statements to your CSS. For example:
42+
43+
```html
44+
<!-- load esri styles for version 4.6 via a link tag -->
45+
<link rel="stylesheet" href="https://js.arcgis.com/4.6/esri/css/main.css">
3846
@import url('https://js.arcgis.com/4.6/esri/css/main.css');
3947
```
4048

41-
If you're using a specific version other than the latest 4.x:
49+
or:
4250

4351
```css
44-
/* esri styles */
52+
/* load esri styles for version 3.23 via import */
4553
@import url('https://js.arcgis.com/3.23/esri/css/esri.css');
4654
```
4755

src/esri-loader.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
*/
1313
const isBrowser = typeof window !== 'undefined';
1414
const DEFAULT_URL = 'https://js.arcgis.com/4.6/';
15-
1615
// this is the url that is currently being, or already has loaded
1716
let _currentUrl;
1817

@@ -24,6 +23,13 @@ function createScript(url) {
2423
return script;
2524
}
2625

26+
function createStylesheetLink(url) {
27+
const link = document.createElement('link');
28+
link.rel = 'stylesheet';
29+
link.href = url;
30+
return link;
31+
}
32+
2733
// add a one-time load handler to script
2834
// and optionally add a one time error handler as well
2935
function handleScriptLoad(script, callback, errback?) {
@@ -60,6 +66,7 @@ function handleScriptError(script, callback) {
6066
// interfaces
6167
export interface ILoadScriptOptions {
6268
url?: string;
69+
// TODO: css?: string;
6370
dojoConfig?: { [propName: string]: any };
6471
}
6572

@@ -72,6 +79,11 @@ export const utils = {
7279
export function getScript() {
7380
return document.querySelector('script[data-esri-loader]') as HTMLScriptElement;
7481
}
82+
// TODO: export this function?
83+
// check if the css url has been injected or added manually
84+
function getCss(url) {
85+
return document.querySelector(`link[href*="${url}"]`) as HTMLLinkElement;
86+
}
7587

7688
// has ArcGIS API been loaded on the page yet?
7789
export function isLoaded() {
@@ -80,6 +92,17 @@ export function isLoaded() {
8092
return globalRequire && globalRequire.on;
8193
}
8294

95+
// lazy load the CSS needed for the ArcGIS API
96+
export function loadCss(url) {
97+
let link = getCss(url);
98+
if (!link) {
99+
// create & load the css library
100+
link = createStylesheetLink(url);
101+
document.head.appendChild(link);
102+
}
103+
return link;
104+
}
105+
83106
// load the ArcGIS API on the page
84107
export function loadScript(options: ILoadScriptOptions = {}): Promise<HTMLScriptElement> {
85108
// default options
@@ -95,7 +118,7 @@ export function loadScript(options: ILoadScriptOptions = {}): Promise<HTMLScript
95118
// b/c the latter will return the full url for relative paths
96119
const src = script.getAttribute('src');
97120
if (src !== options.url) {
98-
// potentailly trying to load a different version of the API
121+
// potentially trying to load a different version of the API
99122
reject(new Error(`The ArcGIS API for JavaScript is already loaded (${src}).`));
100123
} else {
101124
if (isLoaded()) {
@@ -109,7 +132,7 @@ export function loadScript(options: ILoadScriptOptions = {}): Promise<HTMLScript
109132
} else {
110133
if (isLoaded()) {
111134
// the API has been loaded by some other means
112-
// potentailly trying to load a different version of the API
135+
// potentially trying to load a different version of the API
113136
reject(new Error(`The ArcGIS API for JavaScript is already loaded.`));
114137
} else {
115138
// this is the first time attempting to load the API

test/esri-loader.spec.js

+39
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,45 @@ describe('esri-loader', function () {
3737
});
3838
});
3939

40+
describe('when loading the css', function () {
41+
describe('with a url', function () {
42+
var url = 'https://js.arcgis.com/4.6/esri/css/main.css';
43+
var link;
44+
beforeAll(function () {
45+
spyOn(document.head, 'appendChild').and.stub();
46+
spyOn(document, 'querySelector');
47+
link = esriLoader.loadCss(url);
48+
});
49+
it('should have checked if the link was already appended', function() {
50+
expect(document.querySelector.calls.argsFor(0)[0]).toEqual(`link[href*="${url}"]`);
51+
});
52+
it('should have set the href', function () {
53+
expect(link.href).toEqual(url);
54+
});
55+
it('should not have set the rel', function () {
56+
expect(link.rel).toEqual('stylesheet');
57+
});
58+
});
59+
describe('when called twice', function () {
60+
describe('when loading the same url', function () {
61+
var url = 'https://js.arcgis.com/4.6/esri/css/main.css';
62+
var link, link2;
63+
beforeAll(function () {
64+
spyOn(document.head, 'appendChild').and.stub();
65+
link = esriLoader.loadCss(url);
66+
spyOn(document, 'querySelector').and.returnValue(link);
67+
link2 = esriLoader.loadCss(url);
68+
});
69+
it('should return the link if it is already loaded', function () {
70+
expect(link2).toEqual(link);
71+
});
72+
it('should not have tried to append the link a second time', function () {
73+
expect(document.head.appendChild.calls.count()).toEqual(1);
74+
});
75+
});
76+
});
77+
});
78+
4079
describe('when loading the script', function () {
4180
describe('with defaults', function () {
4281
var scriptEl;

0 commit comments

Comments
 (0)