UNPKG

9.2 kBJavaScriptView Raw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 */
21
22var modulemapper = require('cordova/modulemapper');
23
24var browserWrap, popup, navigationButtonsDiv, navigationButtonsDivInner, backButton, forwardButton, closeButton;
25
26function attachNavigationEvents (element, callback) {
27 var onError = function () {
28 try {
29 callback({ type: 'loaderror', url: this.contentWindow.location.href }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
30 } catch (err) {
31 // blocked by CORS :\
32 callback({ type: 'loaderror', url: null }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
33 }
34 };
35
36 element.addEventListener('pageshow', function () {
37 try {
38 callback({ type: 'loadstart', url: this.contentWindow.location.href }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
39 } catch (err) {
40 // blocked by CORS :\
41 callback({ type: 'loadstart', url: null }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
42 }
43 });
44
45 element.addEventListener('load', function () {
46 try {
47 callback({ type: 'loadstop', url: this.contentWindow.location.href }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
48 } catch (err) {
49 // blocked by CORS :\
50 callback({ type: 'loadstop', url: null }, { keepCallback: true }); // eslint-disable-line standard/no-callback-literal
51 }
52 });
53
54 element.addEventListener('error', onError);
55 element.addEventListener('abort', onError);
56}
57
58var IAB = {
59 close: function (win, lose) {
60 if (browserWrap) {
61 // use the "open" function callback so that the exit event is fired properly
62 if (IAB._win) IAB._win({ type: 'exit' });
63
64 browserWrap.parentNode.removeChild(browserWrap);
65 browserWrap = null;
66 popup = null;
67 }
68 },
69
70 show: function (win, lose) {
71 if (browserWrap) {
72 browserWrap.style.display = 'block';
73 }
74 },
75
76 open: function (win, lose, args) {
77 var strUrl = args[0];
78 var target = args[1];
79 var features = args[2];
80
81 IAB._win = win;
82
83 if (target === '_self' || !target) {
84 window.location = strUrl;
85 } else if (target === '_system') {
86 modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, '_blank');
87 } else {
88 // "_blank" or anything else
89 if (!browserWrap) {
90 browserWrap = document.createElement('div');
91 browserWrap.style.position = 'absolute';
92 browserWrap.style.top = '0';
93 browserWrap.style.left = '0';
94 browserWrap.style.boxSizing = 'border-box';
95 browserWrap.style.borderWidth = '40px';
96 browserWrap.style.width = '100vw';
97 browserWrap.style.height = '100vh';
98 browserWrap.style.borderStyle = 'solid';
99 browserWrap.style.borderColor = 'rgba(0,0,0,0.25)';
100
101 browserWrap.onclick = function () {
102 setTimeout(function () {
103 IAB.close();
104 }, 0);
105 };
106
107 document.body.appendChild(browserWrap);
108 }
109
110 if (features.indexOf('hidden=yes') !== -1) {
111 browserWrap.style.display = 'none';
112 }
113
114 popup = document.createElement('iframe');
115 popup.style.borderWidth = '0px';
116 popup.style.width = '100%';
117
118 browserWrap.appendChild(popup);
119
120 if (features.indexOf('location=yes') !== -1 || features.indexOf('location') === -1) {
121 popup.style.height = 'calc(100% - 60px)';
122 popup.style.marginBottom = '-4px';
123
124 navigationButtonsDiv = document.createElement('div');
125 navigationButtonsDiv.style.height = '60px';
126 navigationButtonsDiv.style.backgroundColor = '#404040';
127 navigationButtonsDiv.style.zIndex = '999';
128 navigationButtonsDiv.onclick = function (e) {
129 e.cancelBubble = true;
130 };
131
132 navigationButtonsDivInner = document.createElement('div');
133 navigationButtonsDivInner.style.paddingTop = '10px';
134 navigationButtonsDivInner.style.height = '50px';
135 navigationButtonsDivInner.style.width = '160px';
136 navigationButtonsDivInner.style.margin = '0 auto';
137 navigationButtonsDivInner.style.backgroundColor = '#404040';
138 navigationButtonsDivInner.style.zIndex = '999';
139 navigationButtonsDivInner.onclick = function (e) {
140 e.cancelBubble = true;
141 };
142
143 backButton = document.createElement('button');
144 backButton.style.width = '40px';
145 backButton.style.height = '40px';
146 backButton.style.borderRadius = '40px';
147
148 backButton.innerHTML = '←';
149 backButton.addEventListener('click', function (e) {
150 if (popup.canGoBack) {
151 popup.goBack();
152 }
153 });
154
155 forwardButton = document.createElement('button');
156 forwardButton.style.marginLeft = '20px';
157 forwardButton.style.width = '40px';
158 forwardButton.style.height = '40px';
159 forwardButton.style.borderRadius = '40px';
160
161 forwardButton.innerHTML = '→';
162 forwardButton.addEventListener('click', function (e) {
163 if (popup.canGoForward) {
164 popup.goForward();
165 }
166 });
167
168 closeButton = document.createElement('button');
169 closeButton.style.marginLeft = '20px';
170 closeButton.style.width = '40px';
171 closeButton.style.height = '40px';
172 closeButton.style.borderRadius = '40px';
173
174 closeButton.innerHTML = '✖';
175 closeButton.addEventListener('click', function (e) {
176 setTimeout(function () {
177 IAB.close();
178 }, 0);
179 });
180
181 // iframe navigation is not yet supported
182 backButton.disabled = true;
183 forwardButton.disabled = true;
184
185 navigationButtonsDivInner.appendChild(backButton);
186 navigationButtonsDivInner.appendChild(forwardButton);
187 navigationButtonsDivInner.appendChild(closeButton);
188 navigationButtonsDiv.appendChild(navigationButtonsDivInner);
189
190 browserWrap.appendChild(navigationButtonsDiv);
191 } else {
192 popup.style.height = '100%';
193 }
194
195 // start listening for navigation events
196 attachNavigationEvents(popup, win);
197
198 popup.src = strUrl;
199 }
200 },
201
202 injectScriptCode: function (win, fail, args) {
203 var code = args[0];
204 var hasCallback = args[1];
205
206 if (browserWrap && popup) {
207 try {
208 popup.contentWindow.eval(code);
209 if (hasCallback) {
210 win([]);
211 }
212 } catch (e) {
213 console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e));
214 }
215 }
216 },
217
218 injectScriptFile: function (win, fail, args) {
219 var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented';
220 console.warn(msg);
221 if (fail) {
222 fail(msg);
223 }
224 },
225
226 injectStyleCode: function (win, fail, args) {
227 var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented';
228 console.warn(msg);
229 if (fail) {
230 fail(msg);
231 }
232 },
233
234 injectStyleFile: function (win, fail, args) {
235 var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented';
236 console.warn(msg);
237 if (fail) {
238 fail(msg);
239 }
240 }
241};
242
243module.exports = IAB;
244
245require('cordova/exec/proxy').add('InAppBrowser', module.exports);