1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | import util from '../util.js';
|
19 | import platform from '../platform.js';
|
20 | import pageAttributeExpression from '../page-attribute-expression.js';
|
21 |
|
22 | const internal = {};
|
23 |
|
24 | internal.config = {
|
25 | autoStatusBarFill: true,
|
26 | animationsDisabled: false,
|
27 | warningsDisabled: false
|
28 | };
|
29 |
|
30 | internal.nullElement = window.document.createElement('div');
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | internal.isEnabledAutoStatusBarFill = () => {
|
36 | return !!internal.config.autoStatusBarFill;
|
37 | };
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | internal.normalizePageHTML = html => ('' + html).trim();
|
44 |
|
45 | internal.waitDOMContentLoaded = callback => {
|
46 | if (window.document.readyState === 'loading' || window.document.readyState == 'uninitialized') {
|
47 | const wrappedCallback = () => {
|
48 | callback();
|
49 | window.document.removeEventListener('DOMContentLoaded', wrappedCallback);
|
50 | };
|
51 | window.document.addEventListener('DOMContentLoaded', wrappedCallback);
|
52 | } else {
|
53 | setImmediate(callback);
|
54 | }
|
55 | };
|
56 |
|
57 | internal.autoStatusBarFill = action => {
|
58 | const onReady = () => {
|
59 | if (internal.shouldFillStatusBar()) {
|
60 | action();
|
61 | }
|
62 | document.removeEventListener('deviceready', onReady);
|
63 | };
|
64 |
|
65 | if (typeof device === 'object') {
|
66 | document.addEventListener('deviceready', onReady);
|
67 | } else if (['complete', 'interactive'].indexOf(document.readyState) === -1) {
|
68 | internal.waitDOMContentLoaded(onReady);
|
69 | } else {
|
70 | onReady();
|
71 | }
|
72 | };
|
73 |
|
74 | internal.shouldFillStatusBar = () =>
|
75 | internal.isEnabledAutoStatusBarFill() && (platform.isWebView() && (platform.isIOS7above() || platform.isIPadOS())
|
76 | && !platform.isIPhoneX() || document.body.querySelector('.ons-status-bar-mock.ios'));
|
77 |
|
78 | internal.templateStore = {
|
79 | _storage: {},
|
80 |
|
81 | |
82 |
|
83 |
|
84 |
|
85 | get(key) {
|
86 | return internal.templateStore._storage[key] || null;
|
87 | },
|
88 |
|
89 | |
90 |
|
91 |
|
92 |
|
93 | set(key, template) {
|
94 | internal.templateStore._storage[key] = template;
|
95 | }
|
96 | };
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | internal.getTemplateHTMLAsync = function(page) {
|
103 | return new Promise((resolve, reject) => {
|
104 | internal.waitDOMContentLoaded(() => {
|
105 | const cache = internal.templateStore.get(page);
|
106 | if (cache) {
|
107 | if (cache instanceof DocumentFragment) {
|
108 | return resolve(cache);
|
109 | }
|
110 |
|
111 | const html = typeof cache === 'string' ? cache : cache[1];
|
112 | return resolve(internal.normalizePageHTML(html));
|
113 | }
|
114 |
|
115 | const local = window.document.getElementById(page);
|
116 | if (local) {
|
117 | const html = local.textContent || local.content;
|
118 | return resolve(html);
|
119 | }
|
120 |
|
121 | const xhr = new XMLHttpRequest();
|
122 | xhr.open('GET', page, true);
|
123 | xhr.onload = function() {
|
124 | const html = xhr.responseText;
|
125 | if (xhr.status >= 400 && xhr.status < 600) {
|
126 | reject(html);
|
127 | } else {
|
128 |
|
129 | const fragment = util.createFragment(html);
|
130 | util.arrayFrom(fragment.querySelectorAll('script')).forEach(el => {
|
131 | const script = document.createElement('script');
|
132 | script.type = el.type || 'text/javascript';
|
133 | script.appendChild(document.createTextNode(el.text || el.textContent || el.innerHTML));
|
134 | el.parentNode.replaceChild(script, el);
|
135 | });
|
136 |
|
137 | internal.templateStore.set(page, fragment);
|
138 | resolve(fragment);
|
139 | }
|
140 | };
|
141 | xhr.onerror = function() {
|
142 | util.throw(`Page template not found: ${page}`);
|
143 | };
|
144 | xhr.send(null);
|
145 | });
|
146 | });
|
147 | };
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 | internal.getPageHTMLAsync = function(page) {
|
154 | const pages = pageAttributeExpression.evaluate(page);
|
155 |
|
156 | const getPage = (page) => {
|
157 | if (typeof page !== 'string') {
|
158 | return Promise.reject('Must specify a page.');
|
159 | }
|
160 |
|
161 | return internal.getTemplateHTMLAsync(page)
|
162 | .catch(function(error) {
|
163 | if (pages.length === 0) {
|
164 | return Promise.reject(error);
|
165 | }
|
166 |
|
167 | return getPage(pages.shift());
|
168 | });
|
169 | };
|
170 |
|
171 | return getPage(pages.shift());
|
172 | };
|
173 |
|
174 | export default internal;
|