VulpesOS/gaia/tv_apps/smart-system/js/browser_mixin.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

267 lines
7.3 KiB
JavaScript
Executable file

/* global layoutManager, AppWindow */
'use strict';
(function(window) {
/**
* @mixin BrowserMixin
*/
var BrowserMixin = {
reload: function bm_reload() {
if (this.browser.element) {
this.browser.element.reload();
}
},
/**
* A static timeout to make sure
* the next event don't happen too late.
*/
NEXTPAINT_TIMEOUT: 500,
/**
* Wait for a next paint event from mozbrowser iframe,
* The callback would be called in this.NEXTPAINT_TIMEOUT ms
* if the next paint event doesn't happen.
* The use case is for the moment just before we turn on
* the iframe visibility, so the TIMEOUT isn't too long.
*
* Note: for some reason we intend to use ensureFullRepaint now.
*
* @param {Function} callback The callback function to be invoked
* after we get next paint event.
*/
waitForNextPaint: function bm_waitForNextPaint(callback) {
if (!this.browser || !this.browser.element) {
if (callback) {
callback();
}
return;
}
var iframe = this.browser.element;
var nextPaintTimer;
var self = this;
var onNextPaint = function aw_onNextPaint() {
self.debug(' nextpainted.');
iframe.removeNextPaintListener(onNextPaint);
clearTimeout(nextPaintTimer);
callback();
};
nextPaintTimer = setTimeout(function ifNextPaintIsTooLate() {
self.debug(' nextpaint is timeouted.');
iframe.removeNextPaintListener(onNextPaint);
callback();
}, this.NEXTPAINT_TIMEOUT);
iframe.addNextPaintListener(onNextPaint);
},
/**
* get the screenshot of mozbrowser iframe.
* If it succeed, the blob would be stored in this._screenshotBlob.
* @param {Function} callback The callback function to be invoked
* after we get the screenshot.
*/
getScreenshot: function bm_getScreenshot(callback, width, height, timeout) {
if (!this.browser || !this.browser.element) {
if (callback) {
callback();
}
return;
}
var self = this;
var invoked = false;
var timer;
// First, let's check if we have a frontWindow, if so this is the one
// we will want a screenshot of!
if (this.frontWindow) {
this.frontWindow.getScreenshot(callback, width, height, timeout);
return;
}
if (timeout) {
timer = window.setTimeout(function() {
if (invoked) {
return;
}
self.debug('getScreenshot timeout!');
invoked = true;
callback();
}, timeout);
}
var req = this.iframe.getScreenshot(
width || this.width || layoutManager.width,
height || this.height || layoutManager.height);
req.onsuccess = function gotScreenshotFromFrame(evt) {
var result = evt.target.result;
if (!width) {
// Refresh _screenshotBlob when no width/height is specified.
self._screenshotBlob = result;
}
self.debug('getScreenshot succeed!');
if (invoked) {
return;
}
self.debug('get screenshot success!!!!');
invoked = true;
if (timer) {
window.clearTimeout(timer);
}
if (callback) {
callback(result);
}
};
req.onerror = function gotScreenshotFromFrameError(evt) {
self.debug('getScreenshot failed!');
if (invoked) {
return;
}
invoked = true;
if (timer) {
window.clearTimeout(timer);
}
if (callback) {
callback();
}
};
},
focus: function bm_focus() {
setTimeout(function() {
/**
* Bug 552255 blocks setting focus with handler of KeyboardEvent. See
* http://tinyurl.com/k4uu2rl for more information.
*
* To workaround it, we have to use setTimeout to run focus with another
* thread.
**/
if (this.browser && this.browser.element && this.isActive()) {
/**
* According to Bug 1113592 comment 9's finding, we have to blur the
* previous focused window to bypass the security check.
**/
if (document.activeElement) {
document.activeElement.blur();
}
this.browser.element.focus();
}
}.bind(this));
},
blur: function bm_blur() {
if (this.browser.element) {
this.browser.element.blur();
}
},
back: function bm_back() {
if (this.browser.element) {
this.browser.element.goBack();
}
},
forward: function bm_forward() {
if (this.browser.element) {
this.browser.element.goForward();
}
},
stop: function bm_stop() {
if (this.browser.element) {
this.browser.element.stop();
}
},
_setVisible: function bm__setVisible(visible) {
if (this.browser && this.browser.element &&
'setVisible' in this.browser.element) {
this.debug('setVisible on browser element:' + visible);
this.browser.element.setVisible(visible);
}
},
/**
* Set aria-hidden attribute on browser's element to handle its screen
* reader visibility.
* @type {Boolean} visible A flag indicating if the element should be screen
* reader visible.
*/
_setVisibleForScreenReader:
function bm__setVisibleForScreenReader(visible) {
if (this.browser && this.browser.element) {
this.debug('aria-hidden on browser element:' + !visible);
this.browser.element.setAttribute('aria-hidden', !visible);
}
},
/**
* Fire a DOM Request to detect the history has previous page or not.
* @param {Function} callback Called when DOM Request is done.
*/
canGoBack: function bm_cangoback(callback) {
var self = this;
if (this.browser.element) {
var r = this.browser.element.getCanGoBack();
r.onsuccess = function(evt) {
self._backable = evt.target.result;
if (callback) {
callback(evt.target.result);
}
};
r.onerror = function(evt) {
if (callback) {
callback();
}
};
} else {
if (callback) {
callback();
}
}
},
/**
* Fire a DOM Request to detect the history has next page or not.
* @param {Function} callback Called when DOM Request is done.
*/
canGoForward: function bm_cangoforward(callback) {
var self = this;
if (this.browser.element) {
var r = this.browser.element.getCanGoForward();
r.onsuccess = function(evt) {
self._forwardable = evt.target.result;
if (callback) {
callback(evt.target.result);
}
};
r.onerror = function(evt) {
if (callback) {
callback();
}
};
} else {
if (callback) {
callback();
}
}
},
/**
* Decide we are in out of process or not.
*/
isOOP: function bm_isOOP() {
return (this.browser_config && this.browser_config.oop);
}
};
window.BrowserMixin = BrowserMixin;
AppWindow.addMixin(BrowserMixin);
}(window));