Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
267 lines
7.3 KiB
JavaScript
Executable file
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));
|