зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to m-c. a=merge
This commit is contained in:
Коммит
0ace9ac204
|
@ -1,11 +1,21 @@
|
|||
const TEST_PAGE = "http://mochi.test:8888/browser/browser/base/content/test/general/file_double_close_tab.html";
|
||||
|
||||
let expectingDialog = false;
|
||||
let wantToClose = true;
|
||||
let resolveDialogPromise;
|
||||
function onTabModalDialogLoaded(node) {
|
||||
ok(expectingDialog, "Should be expecting this dialog.");
|
||||
expectingDialog = false;
|
||||
// This accepts the dialog, closing it
|
||||
node.Dialog.ui.button0.click();
|
||||
if (wantToClose) {
|
||||
// This accepts the dialog, closing it
|
||||
node.Dialog.ui.button0.click();
|
||||
} else {
|
||||
// This keeps the page open
|
||||
node.Dialog.ui.button1.click();
|
||||
}
|
||||
if (resolveDialogPromise) {
|
||||
resolveDialogPromise();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,4 +51,25 @@ add_task(function* closeWindowWithMultipleTabsIncludingOneBeforeUnload() {
|
|||
yield windowClosedPromise;
|
||||
ok(!expectingDialog, "There should have been a dialog.");
|
||||
ok(newWin.closed, "Window should be closed.");
|
||||
Services.prefs.clearUserPref("browser.tabs.warnOnClose");
|
||||
});
|
||||
|
||||
add_task(function* closeWindoWithSingleTabTwice() {
|
||||
let newWin = yield promiseOpenAndLoadWindow({}, true);
|
||||
let firstTab = newWin.gBrowser.selectedTab;
|
||||
yield promiseTabLoadEvent(firstTab, TEST_PAGE);
|
||||
let windowClosedPromise = promiseWindowWillBeClosed(newWin);
|
||||
expectingDialog = true;
|
||||
wantToClose = false;
|
||||
let firstDialogShownPromise = new Promise((resolve, reject) => { resolveDialogPromise = resolve; });
|
||||
document.getAnonymousElementByAttribute(firstTab, "anonid", "close-button").click();
|
||||
yield firstDialogShownPromise;
|
||||
info("Got initial dialog, now trying again");
|
||||
expectingDialog = true;
|
||||
wantToClose = true;
|
||||
resolveDialogPromise = null;
|
||||
document.getAnonymousElementByAttribute(firstTab, "anonid", "close-button").click();
|
||||
yield windowClosedPromise;
|
||||
ok(!expectingDialog, "There should have been a dialog.");
|
||||
ok(newWin.closed, "Window should be closed.");
|
||||
});
|
||||
|
|
|
@ -108,7 +108,9 @@ loop.conversation = (function(mozL10n) {
|
|||
callback(null, navigator.mozLoop.getLoopPref("ot.guid"));
|
||||
},
|
||||
set: function(guid, callback) {
|
||||
navigator.mozLoop.setLoopPref("ot.guid", guid);
|
||||
// See nsIPrefBranch
|
||||
const PREF_STRING = 32;
|
||||
navigator.mozLoop.setLoopPref("ot.guid", guid, PREF_STRING);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -108,7 +108,9 @@ loop.conversation = (function(mozL10n) {
|
|||
callback(null, navigator.mozLoop.getLoopPref("ot.guid"));
|
||||
},
|
||||
set: function(guid, callback) {
|
||||
navigator.mozLoop.setLoopPref("ot.guid", guid);
|
||||
// See nsIPrefBranch
|
||||
const PREF_STRING = 32;
|
||||
navigator.mozLoop.setLoopPref("ot.guid", guid, PREF_STRING);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -32,7 +32,9 @@ loop.store.FxOSActiveRoomStore = (function() {
|
|||
roomState: ROOM_STATES.INIT,
|
||||
audioMuted: false,
|
||||
videoMuted: false,
|
||||
failureReason: undefined
|
||||
failureReason: undefined,
|
||||
localVideoDimensions: {},
|
||||
remoteVideoDimensions: {}
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -580,9 +580,6 @@ BrowserGlue.prototype = {
|
|||
if (Services.prefs.getBoolPref("dom.identity.enabled")) {
|
||||
SignInToWebsiteUX.init();
|
||||
}
|
||||
#endif
|
||||
#ifdef NIGHTLY_BUILD
|
||||
ShumwayUtils.init();
|
||||
#endif
|
||||
webrtcUI.init();
|
||||
AboutHome.init();
|
||||
|
@ -756,6 +753,12 @@ BrowserGlue.prototype = {
|
|||
// With older versions of the extension installed, this load will fail
|
||||
// passively.
|
||||
aWindow.messageManager.loadFrameScript("resource://pdf.js/pdfjschildbootstrap.js", true);
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Registering Shumway bootstrap script the child processes.
|
||||
aWindow.messageManager.loadFrameScript("chrome://shumway/content/bootstrap-content.js", true);
|
||||
// Initializing Shumway (shall be run after child script registration).
|
||||
ShumwayUtils.init();
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
// For windows seven, initialize the jump list module.
|
||||
const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
|
||||
|
|
|
@ -272,42 +272,6 @@ function promiseIsURIVisited(aURI) {
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for all pending async statements on the default connection.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When all pending async statements finished.
|
||||
* @rejects Never.
|
||||
*
|
||||
* @note The result is achieved by asynchronously executing a query requiring
|
||||
* a write lock. Since all statements on the same connection are
|
||||
* serialized, the end of this write operation means that all writes are
|
||||
* complete. Note that WAL makes so that writers don't block readers, but
|
||||
* this is a problem only across different connections.
|
||||
*/
|
||||
function promiseAsyncUpdates()
|
||||
{
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let db = DBConn();
|
||||
let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
|
||||
begin.executeAsync();
|
||||
begin.finalize();
|
||||
|
||||
let commit = db.createAsyncStatement("COMMIT");
|
||||
commit.executeAsync({
|
||||
handleResult: function () {},
|
||||
handleError: function () {},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
commit.finalize();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function promiseBookmarksNotification(notification, conditionFn) {
|
||||
info(`Waiting for ${notification}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ function waitForImportAndSmartBookmarks(aCallback) {
|
|||
Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
|
||||
// Delay to test eventual smart bookmarks creation.
|
||||
do_execute_soon(function () {
|
||||
promiseAsyncUpdates().then(aCallback);
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(aCallback);
|
||||
});
|
||||
}, "bookmarks-restore-success", false);
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ function waitForImportAndSmartBookmarks(aCallback) {
|
|||
Services.obs.removeObserver(waitImport, "bookmarks-restore-success");
|
||||
// Delay to test eventual smart bookmarks creation.
|
||||
do_execute_soon(function () {
|
||||
promiseAsyncUpdates().then(aCallback);
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(aCallback);
|
||||
});
|
||||
}, "bookmarks-restore-success", false);
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
content shumway chrome/
|
||||
resource shumway content/
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var EXPORTED_SYMBOLS = ['RtmpUtils'];
|
||||
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
|
||||
var RtmpUtils = {
|
||||
get isRtmpEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref('shumway.rtmp.enabled');
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
createSocket: function (sandbox, params) {
|
||||
var host = params.host, port = params.port, ssl = params.ssl;
|
||||
|
||||
var baseSocket = Cc["@mozilla.org/tcp-socket;1"].createInstance(Ci.nsIDOMTCPSocket);
|
||||
var socket = baseSocket.open(host, port, {useSecureTransport: ssl, binaryType: 'arraybuffer'});
|
||||
if (!socket) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var wrapperOnOpen = null, wrapperOnData = null, wrapperOnDrain = null;
|
||||
var wrapperOnError = null, wrapperOnClose = null;
|
||||
socket.onopen = function () {
|
||||
if (wrapperOnOpen) {
|
||||
wrapperOnOpen.call(wrapper, new sandbox.Object());
|
||||
}
|
||||
};
|
||||
socket.ondata = function (e) {
|
||||
if (wrapperOnData) {
|
||||
var wrappedE = new sandbox.Object();
|
||||
wrappedE.data = Components.utils.cloneInto(e.data, sandbox);
|
||||
wrapperOnData.call(wrapper, wrappedE);
|
||||
}
|
||||
};
|
||||
socket.ondrain = function () {
|
||||
if (wrapperOnDrain) {
|
||||
wrapperOnDrain.call(wrapper, new sandbox.Object());
|
||||
}
|
||||
};
|
||||
socket.onerror = function (e) {
|
||||
if (wrapperOnError) {
|
||||
var wrappedE = new sandbox.Object();
|
||||
wrappedE.data = Components.utils.cloneInto(e.data, sandbox);
|
||||
wrapperOnError.call(wrapper, wrappedE);
|
||||
}
|
||||
};
|
||||
socket.onclose = function () {
|
||||
if (wrapperOnClose) {
|
||||
wrapperOnClose.call(wrapper, new sandbox.Object());
|
||||
}
|
||||
};
|
||||
|
||||
var wrapper = new sandbox.Object();
|
||||
var waived = Components.utils.waiveXrays(wrapper);
|
||||
Object.defineProperties(waived, {
|
||||
onopen: {
|
||||
get: function () { return wrapperOnOpen; },
|
||||
set: function (value) { wrapperOnOpen = value; },
|
||||
enumerable: true
|
||||
},
|
||||
ondata: {
|
||||
get: function () { return wrapperOnData; },
|
||||
set: function (value) { wrapperOnData = value; },
|
||||
enumerable: true
|
||||
},
|
||||
ondrain: {
|
||||
get: function () { return wrapperOnDrain; },
|
||||
set: function (value) { wrapperOnDrain = value; },
|
||||
enumerable: true
|
||||
},
|
||||
onerror: {
|
||||
get: function () { return wrapperOnError; },
|
||||
set: function (value) { wrapperOnError = value; },
|
||||
enumerable: true
|
||||
},
|
||||
onclose: {
|
||||
get: function () { return wrapperOnClose; },
|
||||
set: function (value) { wrapperOnClose = value; },
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
send: {
|
||||
value: function (buffer, offset, count) {
|
||||
return socket.send(buffer, offset, count);
|
||||
}
|
||||
},
|
||||
|
||||
close: {
|
||||
value: function () {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
createXHR: function (sandbox) {
|
||||
var xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
var wrapperOnLoad = null, wrapperOnError = null;
|
||||
xhr.onload = function () {
|
||||
if (wrapperOnLoad) {
|
||||
wrapperOnLoad.call(wrapper, new sandbox.Object());
|
||||
}
|
||||
};
|
||||
xhr.onerror = function () {
|
||||
if (wrappedOnError) {
|
||||
wrappedOnError.call(wrapper, new sandbox.Object());
|
||||
}
|
||||
};
|
||||
|
||||
var wrapper = new sandbox.Object();
|
||||
var waived = Components.utils.waiveXrays(wrapper);
|
||||
Object.defineProperties(waived, {
|
||||
status: {
|
||||
get: function () { return xhr.status; },
|
||||
enumerable: true
|
||||
},
|
||||
response: {
|
||||
get: function () { return Components.utils.cloneInto(xhr.response, sandbox); },
|
||||
enumerable: true
|
||||
},
|
||||
responseType: {
|
||||
get: function () { return xhr.responseType; },
|
||||
set: function (value) {
|
||||
if (value !== 'arraybuffer') {
|
||||
throw new Error('Invalid responseType.');
|
||||
}
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
onload: {
|
||||
get: function () { return wrapperOnLoad; },
|
||||
set: function (value) { wrapperOnLoad = value; },
|
||||
enumerable: true
|
||||
},
|
||||
onerror: {
|
||||
get: function () { return wrapperOnError; },
|
||||
set: function (value) { wrapperOnError = value; },
|
||||
enumerable: true
|
||||
},
|
||||
open: {
|
||||
value: function (method, path, async) {
|
||||
if (method !== 'POST' || !path || (async !== undefined && !async)) {
|
||||
throw new Error('invalid open() arguments');
|
||||
}
|
||||
// TODO check path
|
||||
xhr.open('POST', path, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.setRequestHeader('Content-Type', 'application/x-fcs');
|
||||
}
|
||||
},
|
||||
setRequestHeader: {
|
||||
value: function (header, value) {
|
||||
if (header !== 'Content-Type' || value !== 'application/x-fcs') {
|
||||
throw new Error('invalid setRequestHeader() arguments');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
send: {
|
||||
value: function (data) {
|
||||
xhr.send(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
return wrapper;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var EXPORTED_SYMBOLS = ['SpecialInflate', 'SpecialInflateUtils'];
|
||||
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
|
||||
function SimpleStreamListener() {
|
||||
this.binaryStream = Cc['@mozilla.org/binaryinputstream;1']
|
||||
.createInstance(Ci.nsIBinaryInputStream);
|
||||
this.onData = null;
|
||||
this.buffer = null;
|
||||
}
|
||||
SimpleStreamListener.prototype = {
|
||||
QueryInterface: function (iid) {
|
||||
if (iid.equals(Ci.nsIStreamListener) ||
|
||||
iid.equals(Ci.nsIRequestObserver) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
onStartRequest: function (aRequest, aContext) {
|
||||
return Cr.NS_OK;
|
||||
},
|
||||
onStopRequest: function (aRequest, aContext, sStatusCode) {
|
||||
return Cr.NS_OK;
|
||||
},
|
||||
onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
|
||||
this.binaryStream.setInputStream(aInputStream);
|
||||
if (!this.buffer || aCount > this.buffer.byteLength) {
|
||||
this.buffer = new ArrayBuffer(aCount);
|
||||
}
|
||||
this.binaryStream.readArrayBuffer(aCount, this.buffer);
|
||||
this.onData(new Uint8Array(this.buffer, 0, aCount));
|
||||
return Cr.NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
function SpecialInflate() {
|
||||
var listener = new SimpleStreamListener();
|
||||
listener.onData = function (data) {
|
||||
this.onData(data);
|
||||
}.bind(this);
|
||||
|
||||
var converterService = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService);
|
||||
var converter = converterService.asyncConvertData("deflate", "uncompressed", listener, null);
|
||||
converter.onStartRequest(null, null);
|
||||
this.converter = converter;
|
||||
|
||||
var binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
|
||||
var pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
|
||||
pipe.init(true, true, 0, 0xFFFFFFFF, null);
|
||||
binaryStream.setOutputStream(pipe.outputStream);
|
||||
this.binaryStream = binaryStream;
|
||||
|
||||
this.pipeInputStream = pipe.inputStream;
|
||||
|
||||
this.onData = null;
|
||||
}
|
||||
SpecialInflate.prototype = {
|
||||
push: function (data) {
|
||||
this.binaryStream.writeByteArray(data, data.length);
|
||||
this.converter.onDataAvailable(null, null, this.pipeInputStream, 0, data.length);
|
||||
},
|
||||
close: function () {
|
||||
this.binaryStream.close();
|
||||
this.converter.onStopRequest(null, null, Cr.NS_OK);
|
||||
}
|
||||
};
|
||||
|
||||
var SpecialInflateUtils = {
|
||||
get isSpecialInflateEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref('shumway.specialInflate');
|
||||
} catch (ex) {
|
||||
return false; // TODO true;
|
||||
}
|
||||
},
|
||||
|
||||
createWrappedSpecialInflate: function (sandbox) {
|
||||
var wrapped = new SpecialInflate();
|
||||
var wrapperOnData = null;
|
||||
wrapped.onData = function(data) {
|
||||
if (wrapperOnData) {
|
||||
wrapperOnData.call(wrapper, Components.utils.cloneInto(data, sandbox));
|
||||
}
|
||||
};
|
||||
// We will return object created in the sandbox/content, with some exposed
|
||||
// properties/methods, so we can send data between wrapped object and
|
||||
// and sandbox/content.
|
||||
var wrapper = new sandbox.Object();
|
||||
var waived = Components.utils.waiveXrays(wrapper);
|
||||
Object.defineProperties(waived, {
|
||||
onData: {
|
||||
get: function () { return wrapperOnData; },
|
||||
set: function (value) { wrapperOnData = value; },
|
||||
enumerable: true
|
||||
},
|
||||
push: {
|
||||
value: function (data) {
|
||||
// Uint8Array is expected in the data parameter.
|
||||
// SpecialInflate.push() fails with other argument types.
|
||||
return wrapped.push(data);
|
||||
}
|
||||
},
|
||||
close: {
|
||||
value: function () {
|
||||
return wrapped.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
return wrapper;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function contentScriptClosure() {
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cm = Components.manager;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
// we need to use closure here -- we are running in the global context
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
var isRemote = Services.appinfo.processType ===
|
||||
Services.appinfo.PROCESS_TYPE_CONTENT;
|
||||
var isStarted = false;
|
||||
|
||||
function startup() {
|
||||
if (isStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
isStarted = true;
|
||||
Cu.import('resource://shumway/ShumwayBootstrapUtils.jsm');
|
||||
ShumwayBootstrapUtils.register();
|
||||
}
|
||||
|
||||
function shutdown() {
|
||||
if (!isStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
isStarted = false;
|
||||
ShumwayBootstrapUtils.unregister();
|
||||
Cu.unload('resource://shumway/ShumwayBootstrapUtils.jsm');
|
||||
}
|
||||
|
||||
|
||||
function updateSettings() {
|
||||
let mm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
var results = mm.sendSyncMessage('Shumway:Chrome:isEnabled');
|
||||
var isEnabled = results.some(function (item) {
|
||||
return item;
|
||||
});
|
||||
|
||||
if (isEnabled) {
|
||||
startup();
|
||||
} else {
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
if (isRemote) {
|
||||
addMessageListener('Shumway:Child:refreshSettings', updateSettings);
|
||||
updateSettings();
|
||||
|
||||
addMessageListener('Shumway:Child:shutdown', function shutdownListener(e) {
|
||||
removeMessageListener('Shumway:Child:refreshSettings', updateSettings);
|
||||
removeMessageListener('Shumway:Child:shutdown', shutdownListener);
|
||||
|
||||
shutdown();
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
Components.utils.import('chrome://shumway/content/SpecialInflate.jsm');
|
||||
Components.utils.import('chrome://shumway/content/RtmpUtils.jsm');
|
||||
|
||||
var externalInterfaceWrapper = {
|
||||
callback: function (call) {
|
||||
if (!shumwayComAdapter.onExternalCallback) {
|
||||
return undefined;
|
||||
}
|
||||
return shumwayComAdapter.onExternalCallback(
|
||||
Components.utils.cloneInto(JSON.parse(call), content));
|
||||
}
|
||||
};
|
||||
|
||||
// The object allows resending of external interface, clipboard and other
|
||||
// control messages between unprivileged content and ShumwayStreamConverter.
|
||||
var shumwayComAdapter;
|
||||
|
||||
function sendMessage(action, data, sync, callbackCookie) {
|
||||
var detail = {action: action, data: data, sync: sync};
|
||||
if (callbackCookie !== undefined) {
|
||||
detail.callback = true;
|
||||
detail.cookie = callbackCookie;
|
||||
}
|
||||
if (!sync) {
|
||||
sendAsyncMessage('Shumway:message', detail);
|
||||
return;
|
||||
}
|
||||
var result = sendSyncMessage('Shumway:message', detail);
|
||||
return Components.utils.cloneInto(result, content);
|
||||
}
|
||||
|
||||
addMessageListener('Shumway:init', function (message) {
|
||||
sendAsyncMessage('Shumway:running', {}, {
|
||||
externalInterface: externalInterfaceWrapper
|
||||
});
|
||||
|
||||
// Exposing ShumwayCom object/adapter to the unprivileged content -- setting
|
||||
// up Xray wrappers.
|
||||
shumwayComAdapter = Components.utils.createObjectIn(content, {defineAs: 'ShumwayCom'});
|
||||
Components.utils.exportFunction(sendMessage, shumwayComAdapter, {defineAs: 'sendMessage'});
|
||||
Object.defineProperties(shumwayComAdapter, {
|
||||
onLoadFileCallback: { value: null, writable: true },
|
||||
onExternalCallback: { value: null, writable: true },
|
||||
onMessageCallback: { value: null, writable: true }
|
||||
});
|
||||
Components.utils.makeObjectPropsNormal(shumwayComAdapter);
|
||||
|
||||
// Exposing createSpecialInflate function for DEFLATE stream decoding using
|
||||
// Gecko API.
|
||||
if (SpecialInflateUtils.isSpecialInflateEnabled) {
|
||||
Components.utils.exportFunction(function () {
|
||||
return SpecialInflateUtils.createWrappedSpecialInflate(content);
|
||||
}, content, {defineAs: 'createSpecialInflate'});
|
||||
}
|
||||
|
||||
if (RtmpUtils.isRtmpEnabled) {
|
||||
Components.utils.exportFunction(function (params) {
|
||||
return RtmpUtils.createSocket(content, params);
|
||||
}, content, {defineAs: 'createRtmpSocket'});
|
||||
Components.utils.exportFunction(function () {
|
||||
return RtmpUtils.createXHR(content);
|
||||
}, content, {defineAs: 'createRtmpXHR'});
|
||||
}
|
||||
|
||||
content.wrappedJSObject.runViewer();
|
||||
});
|
||||
|
||||
addMessageListener('Shumway:loadFile', function (message) {
|
||||
if (!shumwayComAdapter.onLoadFileCallback) {
|
||||
return;
|
||||
}
|
||||
shumwayComAdapter.onLoadFileCallback(Components.utils.cloneInto(message.data, content));
|
||||
});
|
||||
|
||||
addMessageListener('Shumway:messageCallback', function (message) {
|
||||
if (!shumwayComAdapter.onMessageCallback) {
|
||||
return;
|
||||
}
|
||||
shumwayComAdapter.onMessageCallback(message.data.cookie,
|
||||
Components.utils.cloneInto(message.data.response, content));
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2013 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
iframe {
|
||||
position:fixed !important;
|
||||
left:0;top:0;bottom:0;right:0;
|
||||
overflow: hidden;
|
||||
line-height: 0;
|
||||
border: 0px none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe id="viewer" src="resource://shumway/web/viewer.html" width="100%" height="100%" mozbrowser remote="true"></iframe>
|
||||
<script src="chrome://shumway/content/viewerWrapper.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
window.notifyShumwayMessage = function (detail) { };
|
||||
window.onExternalCallback = null;
|
||||
window.onMessageCallback = null;
|
||||
window.onLoadFileCallback = null;
|
||||
|
||||
var viewer = document.getElementById('viewer'), onLoaded;
|
||||
var promise = new Promise(function (resolve) {
|
||||
onLoaded = resolve;
|
||||
});
|
||||
viewer.addEventListener('load', function () {
|
||||
onLoaded(false);
|
||||
});
|
||||
viewer.addEventListener('mozbrowserloadend', function () {
|
||||
onLoaded(true);
|
||||
});
|
||||
|
||||
Components.utils.import('chrome://shumway/content/SpecialInflate.jsm');
|
||||
Components.utils.import('chrome://shumway/content/RtmpUtils.jsm');
|
||||
|
||||
function runViewer() {
|
||||
function handler() {
|
||||
function sendMessage(action, data, sync, callbackCookie) {
|
||||
var detail = {action: action, data: data, sync: sync};
|
||||
if (callbackCookie !== undefined) {
|
||||
detail.callback = true;
|
||||
detail.cookie = callbackCookie;
|
||||
}
|
||||
var result = window.notifyShumwayMessage(detail);
|
||||
return Components.utils.cloneInto(result, childWindow);
|
||||
}
|
||||
|
||||
var childWindow = viewer.contentWindow.wrappedJSObject;
|
||||
|
||||
// Exposing ShumwayCom object/adapter to the unprivileged content -- setting
|
||||
// up Xray wrappers. This allows resending of external interface, clipboard
|
||||
// and other control messages between unprivileged content and
|
||||
// ShumwayStreamConverter.
|
||||
var shumwayComAdapter = Components.utils.createObjectIn(childWindow, {defineAs: 'ShumwayCom'});
|
||||
Components.utils.exportFunction(sendMessage, shumwayComAdapter, {defineAs: 'sendMessage'});
|
||||
Object.defineProperties(shumwayComAdapter, {
|
||||
onLoadFileCallback: { value: null, writable: true },
|
||||
onExternalCallback: { value: null, writable: true },
|
||||
onMessageCallback: { value: null, writable: true }
|
||||
});
|
||||
Components.utils.makeObjectPropsNormal(shumwayComAdapter);
|
||||
|
||||
// Exposing createSpecialInflate function for DEFLATE stream decoding using
|
||||
// Gecko API.
|
||||
if (SpecialInflateUtils.isSpecialInflateEnabled) {
|
||||
Components.utils.exportFunction(function () {
|
||||
return SpecialInflateUtils.createWrappedSpecialInflate(childWindow);
|
||||
}, childWindow, {defineAs: 'createSpecialInflate'});
|
||||
}
|
||||
|
||||
if (RtmpUtils.isRtmpEnabled) {
|
||||
Components.utils.exportFunction(function (params) {
|
||||
return RtmpUtils.createSocket(childWindow, params);
|
||||
}, childWindow, {defineAs: 'createRtmpSocket'});
|
||||
Components.utils.exportFunction(function () {
|
||||
return RtmpUtils.createXHR(childWindow);
|
||||
}, childWindow, {defineAs: 'createRtmpXHR'});
|
||||
}
|
||||
|
||||
window.onExternalCallback = function (call) {
|
||||
return shumwayComAdapter.onExternalCallback(Components.utils.cloneInto(call, childWindow));
|
||||
};
|
||||
|
||||
window.onMessageCallback = function (response) {
|
||||
shumwayComAdapter.onMessageCallback(Components.utils.cloneInto(response, childWindow));
|
||||
};
|
||||
|
||||
window.onLoadFileCallback = function (args) {
|
||||
shumwayComAdapter.onLoadFileCallback(Components.utils.cloneInto(args, childWindow));
|
||||
};
|
||||
|
||||
childWindow.runViewer();
|
||||
}
|
||||
|
||||
function handlerOOP() {
|
||||
var frameLoader = viewer.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
|
||||
var messageManager = frameLoader.messageManager;
|
||||
messageManager.loadFrameScript('chrome://shumway/content/content.js', false);
|
||||
|
||||
var externalInterface;
|
||||
|
||||
messageManager.addMessageListener('Shumway:running', function (message) {
|
||||
externalInterface = message.objects.externalInterface;
|
||||
});
|
||||
|
||||
messageManager.addMessageListener('Shumway:message', function (message) {
|
||||
var detail = {
|
||||
action: message.data.action,
|
||||
data: message.data.data,
|
||||
sync: message.data.sync
|
||||
};
|
||||
if (message.data.callback) {
|
||||
detail.callback = true;
|
||||
detail.cookie = message.data.cookie;
|
||||
}
|
||||
|
||||
return window.notifyShumwayMessage(detail);
|
||||
});
|
||||
|
||||
window.onExternalCallback = function (call) {
|
||||
return externalInterface.callback(JSON.stringify(call));
|
||||
};
|
||||
|
||||
window.onMessageCallback = function (response) {
|
||||
messageManager.sendAsyncMessage('Shumway:messageCallback', {
|
||||
cookie: response.cookie,
|
||||
response: response.response
|
||||
});
|
||||
};
|
||||
|
||||
window.onLoadFileCallback = function (args) {
|
||||
messageManager.sendAsyncMessage('Shumway:loadFile', args);
|
||||
};
|
||||
|
||||
messageManager.sendAsyncMessage('Shumway:init', {});
|
||||
}
|
||||
|
||||
promise.then(function (oop) {
|
||||
if (oop) {
|
||||
handlerOOP();
|
||||
} else {
|
||||
handler();
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['ShumwayBootstrapUtils'];
|
||||
|
||||
const PREF_PREFIX = 'shumway.';
|
||||
const PREF_IGNORE_CTP = PREF_PREFIX + 'ignoreCTP';
|
||||
const SWF_CONTENT_TYPE = 'application/x-shockwave-flash';
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cm = Components.manager;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
Cu.import('resource://shumway/ShumwayStreamConverter.jsm');
|
||||
|
||||
let Ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let registerOverlayPreview = 'registerPlayPreviewMimeType' in Ph;
|
||||
|
||||
function getBoolPref(pref, def) {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
} catch (ex) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
function log(str) {
|
||||
dump(str + '\n');
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a factory.
|
||||
function Factory() {}
|
||||
Factory.prototype = {
|
||||
register: function register(targetConstructor) {
|
||||
var proto = targetConstructor.prototype;
|
||||
this._classID = proto.classID;
|
||||
|
||||
var factory = XPCOMUtils._getFactory(targetConstructor);
|
||||
this._factory = factory;
|
||||
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(proto.classID, proto.classDescription,
|
||||
proto.contractID, factory);
|
||||
},
|
||||
|
||||
unregister: function unregister() {
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.unregisterFactory(this._classID, this._factory);
|
||||
}
|
||||
};
|
||||
|
||||
let converterFactory = new Factory();
|
||||
let overlayConverterFactory = new Factory();
|
||||
|
||||
var ShumwayBootstrapUtils = {
|
||||
register: function () {
|
||||
// Register the components.
|
||||
converterFactory.register(ShumwayStreamConverter);
|
||||
overlayConverterFactory.register(ShumwayStreamOverlayConverter);
|
||||
|
||||
if (registerOverlayPreview) {
|
||||
var ignoreCTP = getBoolPref(PREF_IGNORE_CTP, true);
|
||||
Ph.registerPlayPreviewMimeType(SWF_CONTENT_TYPE, ignoreCTP);
|
||||
}
|
||||
},
|
||||
|
||||
unregister: function () {
|
||||
// Remove the contract/component.
|
||||
converterFactory.unregister();
|
||||
overlayConverterFactory.unregister();
|
||||
|
||||
if (registerOverlayPreview) {
|
||||
Ph.unregisterPlayPreviewMimeType(SWF_CONTENT_TYPE);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -184,9 +184,17 @@ function fetchPolicyFile(url, cache, callback) {
|
|||
xhr.send(null);
|
||||
}
|
||||
|
||||
function isContentWindowPrivate(win) {
|
||||
if (!('isContentWindowPrivate' in PrivateBrowsingUtils)) {
|
||||
return PrivateBrowsingUtils.isWindowPrivate(win);
|
||||
}
|
||||
return PrivateBrowsingUtils.isContentWindowPrivate(win);
|
||||
}
|
||||
|
||||
function isShumwayEnabledFor(actions) {
|
||||
// disabled for PrivateBrowsing windows
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(actions.window)) {
|
||||
if (isContentWindowPrivate(actions.window) &&
|
||||
!getBoolPref('shumway.enableForPrivate', false)) {
|
||||
return false;
|
||||
}
|
||||
// disabled if embed tag specifies shumwaymode (for testing purpose)
|
||||
|
@ -212,13 +220,15 @@ function isShumwayEnabledFor(actions) {
|
|||
function getVersionInfo() {
|
||||
var deferred = Promise.defer();
|
||||
var versionInfo = {
|
||||
geckoMstone : 'unknown',
|
||||
version: 'unknown',
|
||||
geckoBuildID: 'unknown',
|
||||
shumwayVersion: 'unknown'
|
||||
};
|
||||
try {
|
||||
versionInfo.geckoMstone = Services.prefs.getCharPref('gecko.mstone');
|
||||
versionInfo.geckoBuildID = Services.prefs.getCharPref('gecko.buildID');
|
||||
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Components.interfaces.nsIXULAppInfo);
|
||||
versionInfo.geckoVersion = appInfo.version;
|
||||
versionInfo.geckoBuildID = appInfo.appBuildID;
|
||||
} catch (e) {
|
||||
log('Error encountered while getting platform version info:', e);
|
||||
}
|
||||
|
@ -275,11 +285,11 @@ ChromeActions.prototype = {
|
|||
return getBoolPref(data.pref, data.def);
|
||||
},
|
||||
getCompilerSettings: function getCompilerSettings() {
|
||||
return JSON.stringify({
|
||||
return {
|
||||
appCompiler: getBoolPref('shumway.appCompiler', true),
|
||||
sysCompiler: getBoolPref('shumway.sysCompiler', false),
|
||||
verifier: getBoolPref('shumway.verifier', true)
|
||||
});
|
||||
};
|
||||
},
|
||||
addProfilerMarker: function (marker) {
|
||||
if ('nsIProfiler' in Ci) {
|
||||
|
@ -288,14 +298,14 @@ ChromeActions.prototype = {
|
|||
}
|
||||
},
|
||||
getPluginParams: function getPluginParams() {
|
||||
return JSON.stringify({
|
||||
return {
|
||||
url: this.url,
|
||||
baseUrl : this.baseUrl,
|
||||
movieParams: this.movieParams,
|
||||
objectParams: this.objectParams,
|
||||
isOverlay: this.isOverlay,
|
||||
isPausedAtStart: this.isPausedAtStart
|
||||
});
|
||||
};
|
||||
},
|
||||
_canDownloadFile: function canDownloadFile(data, callback) {
|
||||
var url = data.url, checkPolicyFile = data.checkPolicyFile;
|
||||
|
@ -352,6 +362,13 @@ ChromeActions.prototype = {
|
|||
}.bind(this));
|
||||
},
|
||||
loadFile: function loadFile(data) {
|
||||
function notifyLoadFileListener(data) {
|
||||
if (!win.wrappedJSObject.onLoadFileCallback) {
|
||||
return;
|
||||
}
|
||||
win.wrappedJSObject.onLoadFileCallback(data);
|
||||
}
|
||||
|
||||
var url = data.url;
|
||||
var checkPolicyFile = data.checkPolicyFile;
|
||||
var sessionId = data.sessionId;
|
||||
|
@ -381,8 +398,8 @@ ChromeActions.prototype = {
|
|||
xhr.onprogress = function (e) {
|
||||
var position = e.loaded;
|
||||
var data = new Uint8Array(xhr.response);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "progress",
|
||||
array: data, loaded: e.loaded, total: e.total}, "*");
|
||||
notifyLoadFileListener({callback:"loadFile", sessionId: sessionId,
|
||||
topic: "progress", array: data, loaded: e.loaded, total: e.total});
|
||||
lastPosition = position;
|
||||
if (limit && e.total >= limit) {
|
||||
xhr.abort();
|
||||
|
@ -391,16 +408,15 @@ ChromeActions.prototype = {
|
|||
xhr.onreadystatechange = function(event) {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "error",
|
||||
error: xhr.statusText}, "*");
|
||||
notifyLoadFileListener({callback:"loadFile", sessionId: sessionId, topic: "error", error: xhr.statusText});
|
||||
}
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "close"}, "*");
|
||||
notifyLoadFileListener({callback:"loadFile", sessionId: sessionId, topic: "close"});
|
||||
}
|
||||
};
|
||||
if (mimeType)
|
||||
xhr.setRequestHeader("Content-Type", mimeType);
|
||||
xhr.send(postData);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "open"}, "*");
|
||||
notifyLoadFileListener({callback:"loadFile", sessionId: sessionId, topic: "open"});
|
||||
};
|
||||
|
||||
this._canDownloadFile({url: url, checkPolicyFile: checkPolicyFile}, function (data) {
|
||||
|
@ -408,28 +424,65 @@ ChromeActions.prototype = {
|
|||
performXHR();
|
||||
} else {
|
||||
log("data access id prohibited to " + url + " from " + baseUrl);
|
||||
win.postMessage({callback:"loadFile", sessionId: sessionId, topic: "error",
|
||||
error: "only original swf file or file from the same origin loading supported"}, "*");
|
||||
notifyLoadFileListener({callback:"loadFile", sessionId: sessionId, topic: "error",
|
||||
error: "only original swf file or file from the same origin loading supported"});
|
||||
}
|
||||
});
|
||||
},
|
||||
navigateTo: function (data) {
|
||||
var embedTag = this.embedTag.wrappedJSObject;
|
||||
var window = embedTag ? embedTag.ownerDocument.defaultView : this.window;
|
||||
window.open(data.url, data.target || '_self');
|
||||
},
|
||||
fallback: function(automatic) {
|
||||
automatic = !!automatic;
|
||||
fallbackToNativePlugin(this.window, !automatic, automatic);
|
||||
},
|
||||
setClipboard: function (data) {
|
||||
userInput: function() {
|
||||
var win = this.window;
|
||||
var winUtils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
if (winUtils.isHandlingUserInput) {
|
||||
this.lastUserInput = Date.now();
|
||||
}
|
||||
},
|
||||
isUserInputInProgress: function () {
|
||||
// TODO userInput does not work for OOP
|
||||
if (!getBoolPref('shumway.userInputSecurity', true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We don't trust our Shumway non-privileged code just yet to verify the
|
||||
// user input -- using monitorUserInput function below to track that.
|
||||
if (typeof data !== 'string' ||
|
||||
(Date.now() - this.lastUserInput) > MAX_USER_INPUT_TIMEOUT) {
|
||||
return;
|
||||
// user input -- using userInput function above to track that.
|
||||
if ((Date.now() - this.lastUserInput) > MAX_USER_INPUT_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
// TODO other security checks?
|
||||
return true;
|
||||
},
|
||||
setClipboard: function (data) {
|
||||
if (typeof data !== 'string' || !this.isUserInputInProgress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Ci.nsIClipboardHelper);
|
||||
clipboard.copyString(data);
|
||||
},
|
||||
setFullscreen: function (enabled) {
|
||||
enabled = !!enabled;
|
||||
|
||||
if (!this.isUserInputInProgress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var target = this.embedTag || this.document.body;
|
||||
if (enabled) {
|
||||
target.mozRequestFullScreen();
|
||||
} else {
|
||||
target.ownerDocument.mozCancelFullScreen();
|
||||
}
|
||||
},
|
||||
endActivation: function () {
|
||||
if (ActivationQueue.currentNonActive === this) {
|
||||
ActivationQueue.activateNext();
|
||||
|
@ -487,20 +540,15 @@ ChromeActions.prototype = {
|
|||
getVersionInfo().then(function (versions) {
|
||||
params.versions = versions;
|
||||
}).then(function () {
|
||||
params.ffbuild = encodeURIComponent(params.versions.geckoMstone +
|
||||
' (' + params.versions.geckoBuildID + ')');
|
||||
params.shubuild = encodeURIComponent(params.versions.shumwayVersion);
|
||||
params.exceptions = encodeURIComponent(exceptions);
|
||||
var comment = '%2B%2B%2B This bug was initially via the problem reporting functionality in ' +
|
||||
'Shumway %2B%2B%2B%0A%0A' +
|
||||
'Please add any further information that you deem helpful here:%0A%0A%0A' +
|
||||
'----------------------%0A%0A' +
|
||||
'Technical Information:%0A' +
|
||||
'Firefox version: ' + params.ffbuild + '%0A' +
|
||||
'Shumway version: ' + params.shubuild;
|
||||
url = url.split('{comment}').join(comment);
|
||||
//this.window.openDialog('chrome://browser/content', '_blank', 'all,dialog=no', url);
|
||||
dump(111);
|
||||
var ffbuild = params.versions.geckoVersion + ' (' + params.versions.geckoBuildID + ')';
|
||||
//params.exceptions = encodeURIComponent(exceptions);
|
||||
var comment = '+++ Initially filed via the problem reporting functionality in Shumway +++\n' +
|
||||
'Please add any further information that you deem helpful here:\n\n\n\n' +
|
||||
'----------------------\n\n' +
|
||||
'Technical Information:\n' +
|
||||
'Firefox version: ' + ffbuild + '\n' +
|
||||
'Shumway version: ' + params.versions.shumwayVersion;
|
||||
url = url.split('{comment}').join(encodeURIComponent(comment));
|
||||
this.window.open(url);
|
||||
}.bind(this));
|
||||
},
|
||||
|
@ -517,8 +565,7 @@ ChromeActions.prototype = {
|
|||
return;
|
||||
|
||||
this.externalComInitialized = true;
|
||||
var eventTarget = this.window.document;
|
||||
initExternalCom(parentWindow, embedTag, eventTarget);
|
||||
initExternalCom(parentWindow, embedTag, this.window);
|
||||
return;
|
||||
case 'getId':
|
||||
return embedTag.id;
|
||||
|
@ -537,33 +584,15 @@ ChromeActions.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function monitorUserInput(actions) {
|
||||
function notifyUserInput() {
|
||||
var win = actions.window;
|
||||
var winUtils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
if (winUtils.isHandlingUserInput) {
|
||||
actions.lastUserInput = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
var document = actions.document;
|
||||
document.addEventListener('mousedown', notifyUserInput, false);
|
||||
document.addEventListener('mouseup', notifyUserInput, false);
|
||||
document.addEventListener('keydown', notifyUserInput, false);
|
||||
document.addEventListener('keyup', notifyUserInput, false);
|
||||
}
|
||||
|
||||
// Event listener to trigger chrome privedged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
// Receive an event and synchronously or asynchronously responds.
|
||||
RequestListener.prototype.receive = function(event) {
|
||||
var message = event.target;
|
||||
var action = event.detail.action;
|
||||
var data = event.detail.data;
|
||||
var sync = event.detail.sync;
|
||||
RequestListener.prototype.receive = function(detail) {
|
||||
var action = detail.action;
|
||||
var data = detail.data;
|
||||
var sync = detail.sync;
|
||||
var actions = this.actions;
|
||||
if (!(action in actions)) {
|
||||
log('Unknown action: ' + action);
|
||||
|
@ -571,30 +600,23 @@ RequestListener.prototype.receive = function(event) {
|
|||
}
|
||||
if (sync) {
|
||||
var response = actions[action].call(this.actions, data);
|
||||
event.detail.response = response;
|
||||
} else {
|
||||
var response;
|
||||
if (event.detail.callback) {
|
||||
var cookie = event.detail.cookie;
|
||||
response = function sendResponse(response) {
|
||||
var doc = actions.document;
|
||||
try {
|
||||
var listener = doc.createEvent('CustomEvent');
|
||||
listener.initCustomEvent('shumway.response', true, false,
|
||||
makeContentReadable({
|
||||
response: response,
|
||||
cookie: cookie
|
||||
}, doc.defaultView));
|
||||
|
||||
return message.dispatchEvent(listener);
|
||||
} catch (e) {
|
||||
// doc is no longer accessible because the requestor is already
|
||||
// gone. unloaded content cannot receive the response anyway.
|
||||
}
|
||||
};
|
||||
}
|
||||
actions[action].call(this.actions, data, response);
|
||||
return response === undefined ? undefined : JSON.stringify(response);
|
||||
}
|
||||
|
||||
var responseCallback;
|
||||
if (detail.callback) {
|
||||
var cookie = detail.cookie;
|
||||
response = function sendResponse(response) {
|
||||
var win = actions.window;
|
||||
if (win.wrappedJSObject.onMessageCallback) {
|
||||
win.wrappedJSObject.onMessageCallback({
|
||||
response: response === undefined ? undefined : JSON.stringify(response),
|
||||
cookie: cookie
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
actions[action].call(this.actions, data, responseCallback);
|
||||
};
|
||||
|
||||
var ActivationQueue = {
|
||||
|
@ -696,7 +718,7 @@ var ActivationQueue = {
|
|||
}
|
||||
};
|
||||
|
||||
function activateShumwayScripts(window, preview) {
|
||||
function activateShumwayScripts(window, requestListener) {
|
||||
function loadScripts(scripts, callback) {
|
||||
function loadScript(i) {
|
||||
if (i >= scripts.length) {
|
||||
|
@ -717,14 +739,12 @@ function activateShumwayScripts(window, preview) {
|
|||
}
|
||||
|
||||
function initScripts() {
|
||||
loadScripts(['resource://shumway/shumway.gfx.js',
|
||||
'resource://shumway/web/viewer.js'], function () {
|
||||
window.wrappedJSObject.runViewer();
|
||||
});
|
||||
window.wrappedJSObject.notifyShumwayMessage = function () {
|
||||
return requestListener.receive.apply(requestListener, arguments);
|
||||
};
|
||||
window.wrappedJSObject.runViewer();
|
||||
}
|
||||
|
||||
window.wrappedJSObject.SHUMWAY_ROOT = "resource://shumway/";
|
||||
|
||||
if (window.document.readyState === "interactive" ||
|
||||
window.document.readyState === "complete") {
|
||||
initScripts();
|
||||
|
@ -733,7 +753,7 @@ function activateShumwayScripts(window, preview) {
|
|||
}
|
||||
}
|
||||
|
||||
function initExternalCom(wrappedWindow, wrappedObject, targetDocument) {
|
||||
function initExternalCom(wrappedWindow, wrappedObject, targetWindow) {
|
||||
if (!wrappedWindow.__flash__initialized) {
|
||||
wrappedWindow.__flash__initialized = true;
|
||||
wrappedWindow.__flash__toXML = function __flash__toXML(obj) {
|
||||
|
@ -777,18 +797,15 @@ function initExternalCom(wrappedWindow, wrappedObject, targetDocument) {
|
|||
}
|
||||
wrappedObject.__flash__registerCallback = function (functionName) {
|
||||
wrappedWindow.console.log('__flash__registerCallback: ' + functionName);
|
||||
this[functionName] = function () {
|
||||
Components.utils.exportFunction(function () {
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
wrappedWindow.console.log('__flash__callIn: ' + functionName);
|
||||
var e = targetDocument.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.remote', true, false, makeContentReadable({
|
||||
functionName: functionName,
|
||||
args: args,
|
||||
result: undefined
|
||||
}, targetDocument.defaultView));
|
||||
targetDocument.dispatchEvent(e);
|
||||
return e.detail.result;
|
||||
};
|
||||
var result;
|
||||
if (targetWindow.wrappedJSObject.onExternalCallback) {
|
||||
result = targetWindow.wrappedJSObject.onExternalCallback({functionName: functionName, args: args});
|
||||
}
|
||||
return wrappedWindow.eval(result);
|
||||
}, this, { defineAs: functionName });
|
||||
};
|
||||
wrappedObject.__flash__unregisterCallback = function (functionName) {
|
||||
wrappedWindow.console.log('__flash__unregisterCallback: ' + functionName);
|
||||
|
@ -849,6 +866,12 @@ ShumwayStreamConverterBase.prototype = {
|
|||
}
|
||||
|
||||
if (isOverlay) {
|
||||
// HACK For Facebook, CSS embed tag rescaling -- iframe (our overlay)
|
||||
// has no styling in document. Shall removed with jsplugins.
|
||||
for (var child = window.frameElement; child !== element; child = child.parentNode) {
|
||||
child.setAttribute('style', 'max-width: 100%; max-height: 100%');
|
||||
}
|
||||
|
||||
// Checking if overlay is a proper PlayPreview overlay.
|
||||
for (var i = 0; i < element.children.length; i++) {
|
||||
if (element.children[i] === containerElement) {
|
||||
|
@ -860,7 +883,7 @@ ShumwayStreamConverterBase.prototype = {
|
|||
|
||||
if (element) {
|
||||
// Getting absolute URL from the EMBED tag
|
||||
url = element.srcURI.spec;
|
||||
url = element.srcURI && element.srcURI.spec;
|
||||
|
||||
pageUrl = element.ownerDocument.location.href; // proper page url?
|
||||
|
||||
|
@ -961,14 +984,8 @@ ShumwayStreamConverterBase.prototype = {
|
|||
|
||||
var originalURI = aRequest.URI;
|
||||
|
||||
// checking if the plug-in shall be run in simple mode
|
||||
var isSimpleMode = originalURI.spec === EXPECTED_PLAYPREVIEW_URI_PREFIX &&
|
||||
getBoolPref('shumway.simpleMode', false);
|
||||
|
||||
// Create a new channel that loads the viewer as a resource.
|
||||
var viewerUrl = isSimpleMode ?
|
||||
'resource://shumway/web/simple.html' :
|
||||
'resource://shumway/web/viewer.html';
|
||||
// Create a new channel that loads the viewer as a chrome resource.
|
||||
var viewerUrl = 'chrome://shumway/content/viewer.wrapper.html';
|
||||
var channel = Services.io.newChannel(viewerUrl, null, null);
|
||||
|
||||
var converter = this;
|
||||
|
@ -1008,17 +1025,13 @@ ShumwayStreamConverterBase.prototype = {
|
|||
ShumwayTelemetry.onPageIndex(0);
|
||||
}
|
||||
|
||||
actions.activationCallback = function(domWindow, isSimpleMode) {
|
||||
delete this.activationCallback;
|
||||
activateShumwayScripts(domWindow, isSimpleMode);
|
||||
}.bind(actions, domWindow, isSimpleMode);
|
||||
ActivationQueue.enqueue(actions);
|
||||
|
||||
let requestListener = new RequestListener(actions);
|
||||
domWindow.addEventListener('shumway.message', function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
monitorUserInput(actions);
|
||||
|
||||
actions.activationCallback = function(domWindow, requestListener) {
|
||||
delete this.activationCallback;
|
||||
activateShumwayScripts(domWindow, requestListener);
|
||||
}.bind(actions, domWindow, requestListener);
|
||||
ActivationQueue.enqueue(actions);
|
||||
|
||||
listener.onStopRequest(aRequest, context, statusCode);
|
||||
}
|
||||
|
@ -1028,12 +1041,11 @@ ShumwayStreamConverterBase.prototype = {
|
|||
channel.originalURI = aRequest.URI;
|
||||
channel.loadGroup = aRequest.loadGroup;
|
||||
|
||||
// We can use resource principal when data is fetched by the chrome
|
||||
// e.g. useful for NoScript
|
||||
// We can use all powerful principal: we are opening chrome:// web page,
|
||||
// which will need lots of permission.
|
||||
var securityManager = Cc['@mozilla.org/scriptsecuritymanager;1']
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
var uri = Services.io.newURI(viewerUrl, null, null);
|
||||
var resourcePrincipal = securityManager.getNoAppCodebasePrincipal(uri);
|
||||
var resourcePrincipal = securityManager.getSystemPrincipal();
|
||||
aRequest.owner = resourcePrincipal;
|
||||
channel.asyncOpen(proxy, aContext);
|
||||
},
|
||||
|
|
|
@ -15,12 +15,8 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["ShumwayUtils"];
|
||||
|
||||
const RESOURCE_NAME = 'shumway';
|
||||
const EXT_PREFIX = 'shumway@research.mozilla.org';
|
||||
const SWF_CONTENT_TYPE = 'application/x-shockwave-flash';
|
||||
const PREF_PREFIX = 'shumway.';
|
||||
const PREF_DISABLED = PREF_PREFIX + 'disabled';
|
||||
const PREF_IGNORE_CTP = PREF_PREFIX + 'ignoreCTP';
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
|
@ -30,14 +26,6 @@ let Cu = Components.utils;
|
|||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'pluginHost',
|
||||
'@mozilla.org/plugin/host;1',
|
||||
'nsIPluginHost');
|
||||
|
||||
function getBoolPref(pref, def) {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
|
@ -50,31 +38,6 @@ function log(str) {
|
|||
dump(str + '\n');
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a factory.
|
||||
function Factory() {}
|
||||
Factory.prototype = {
|
||||
register: function register(targetConstructor) {
|
||||
var proto = targetConstructor.prototype;
|
||||
this._classID = proto.classID;
|
||||
|
||||
var factory = XPCOMUtils._getFactory(targetConstructor);
|
||||
this._factory = factory;
|
||||
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(proto.classID, proto.classDescription,
|
||||
proto.contractID, factory);
|
||||
},
|
||||
|
||||
unregister: function unregister() {
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.unregisterFactory(this._classID, this._factory);
|
||||
this._factory = null;
|
||||
}
|
||||
};
|
||||
|
||||
let converterFactory = new Factory();
|
||||
let overlayConverterFactory = new Factory();
|
||||
|
||||
let ShumwayUtils = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
_registered: false,
|
||||
|
@ -85,6 +48,10 @@ let ShumwayUtils = {
|
|||
else
|
||||
this._ensureUnregistered();
|
||||
|
||||
Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster)
|
||||
.addMessageListener('Shumway:Chrome:isEnabled', this);
|
||||
|
||||
// Listen for when shumway is completely disabled.
|
||||
Services.prefs.addObserver(PREF_DISABLED, this, false);
|
||||
},
|
||||
|
@ -96,6 +63,13 @@ let ShumwayUtils = {
|
|||
else
|
||||
this._ensureUnregistered();
|
||||
},
|
||||
|
||||
receiveMessage: function(message) {
|
||||
switch (message.name) {
|
||||
case 'Shumway:Chrome:isEnabled':
|
||||
return this.enabled;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* shumway is only enabled if the global switch enabling is true.
|
||||
|
@ -110,17 +84,16 @@ let ShumwayUtils = {
|
|||
return;
|
||||
|
||||
// Load the component and register it.
|
||||
Cu.import('resource://shumway/ShumwayStreamConverter.jsm');
|
||||
converterFactory.register(ShumwayStreamConverter);
|
||||
overlayConverterFactory.register(ShumwayStreamOverlayConverter);
|
||||
|
||||
var ignoreCTP = getBoolPref(PREF_IGNORE_CTP, true);
|
||||
|
||||
Svc.pluginHost.registerPlayPreviewMimeType(SWF_CONTENT_TYPE, ignoreCTP);
|
||||
Cu.import('resource://shumway/ShumwayBootstrapUtils.jsm');
|
||||
ShumwayBootstrapUtils.register();
|
||||
|
||||
this._registered = true;
|
||||
|
||||
log('Shumway is registered');
|
||||
|
||||
let globalMM = Cc['@mozilla.org/globalmessagemanager;1']
|
||||
.getService(Ci.nsIFrameScriptLoader);
|
||||
globalMM.broadcastAsyncMessage('Shumway:Child:refreshSettings');
|
||||
},
|
||||
|
||||
_ensureUnregistered: function _ensureUnregistered() {
|
||||
|
@ -128,14 +101,15 @@ let ShumwayUtils = {
|
|||
return;
|
||||
|
||||
// Remove the contract/component.
|
||||
converterFactory.unregister();
|
||||
overlayConverterFactory.unregister();
|
||||
Cu.unload('resource://shumway/ShumwayStreamConverter.jsm');
|
||||
|
||||
Svc.pluginHost.unregisterPlayPreviewMimeType(SWF_CONTENT_TYPE);
|
||||
ShumwayBootstrapUtils.unregister();
|
||||
Cu.unload('resource://shumway/ShumwayBootstrapUtils.jsm');
|
||||
|
||||
this._registered = false;
|
||||
|
||||
log('Shumway is unregistered');
|
||||
|
||||
let globalMM = Cc['@mozilla.org/globalmessagemanager;1']
|
||||
.getService(Ci.nsIFrameScriptLoader);
|
||||
globalMM.broadcastAsyncMessage('Shumway:Child:refreshSettings');
|
||||
}
|
||||
};
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
out vec4 FragmentColor;
|
||||
|
||||
uniform float offset[5] = float[]( 0.0, 1.0, 2.0, 3.0, 4.0 );
|
||||
uniform float weight[5] = float[]( 0.2270270270, 0.1945945946, 0.1216216216,
|
||||
0.0540540541, 0.0162162162 );
|
||||
|
||||
void main(void)
|
||||
{
|
||||
FragmentColor = texture2D( uSampler, vec2(vCoordinate) * weight[0];
|
||||
for (int i=1; i<5; i++) {
|
||||
FragmentColor +=
|
||||
texture2D( uSampler, ( vec2(gl_FragCoord)+vec2(0.0, offset[i]) )/1024.0 )
|
||||
* weight[i];
|
||||
FragmentColor +=
|
||||
texture2D( uSampler, ( vec2(gl_FragCoord)-vec2(0.0, offset[i]) )/1024.0 )
|
||||
* weight[i];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
const int sampleRadius = 16;
|
||||
const int samples = sampleRadius * 2 + 1;
|
||||
float dy = 1.0 / 512.0;
|
||||
vec4 sample = vec4(0, 0, 0, 0);
|
||||
for (int i = -sampleRadius; i <= sampleRadius; i++) {
|
||||
sample += texture2D(uSampler, vCoordinate + vec2(0, float(i) * dy));
|
||||
}
|
||||
gl_FragColor = sample / float(samples);
|
||||
// gl_FragColor = texture2D(uSampler, vCoordinate);
|
||||
}
|
||||
*/
|
||||
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
vec4 sum = vec4(0.0);
|
||||
float blur = 1.0 / 512.0 * 1.0;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 4.0 * blur, vCoordinate.y)) * 0.05;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 3.0 * blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 2.0 * blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x, vCoordinate.y)) * 0.16;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 2.0 * blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 3.0 * blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 4.0 * blur, vCoordinate.y)) * 0.05;
|
||||
gl_FragColor = sum;
|
||||
// gl_FragColor = texture2D(uSampler, vCoordinate);
|
||||
}
|
||||
|
||||
/*
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
vec4 sum = vec4(0.0);
|
||||
float blur = 0.1;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 4.0 * blur, vCoordinate.y)) * 0.05;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 3.0 * blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 2.0 * blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x, vCoordinate.y)) * 0.16;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 2.0 * blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 3.0 * blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 4.0 * blur, vCoordinate.y)) * 0.05;
|
||||
gl_FragColor = sum;
|
||||
// gl_FragColor = texture2D(uSampler, vCoordinate);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(uSampler, vCoordinate);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
precision mediump float;
|
||||
varying vec2 vCoordinate;
|
||||
varying float vColor;
|
||||
uniform float blur;
|
||||
uniform sampler2D uSampler;
|
||||
void main(void) {
|
||||
vec4 sum = vec4(0.0);
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 4.0*blur, vCoordinate.y)) * 0.05;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 3.0*blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - 2.0*blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x - blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x, vCoordinate.y)) * 0.16;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + blur, vCoordinate.y)) * 0.15;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 2.0*blur, vCoordinate.y)) * 0.12;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 3.0*blur, vCoordinate.y)) * 0.09;
|
||||
sum += texture2D(uSampler, vec2(vCoordinate.x + 4.0*blur, vCoordinate.y)) * 0.05;
|
||||
gl_FragColor = sum;
|
||||
}
|
||||
|
||||
*/
|
|
@ -1,16 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
const int sampleRadius = 8;
|
||||
const int samples = sampleRadius * 2 + 1;
|
||||
float dx = 0.01;
|
||||
vec4 sample = vec4(0, 0, 0, 0);
|
||||
for (int i = -sampleRadius; i <= sampleRadius; i++) {
|
||||
sample += texture2D(uSampler, vCoordinate + vec2(0, float(i) * dy));
|
||||
}
|
||||
gl_FragColor = sample / float(samples);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
uniform vec2 uResolution;
|
||||
uniform mat3 uTransformMatrix;
|
||||
uniform float uZ;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec4 aColor;
|
||||
attribute vec2 aCoordinate;
|
||||
|
||||
varying vec4 vColor;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
vec2 position = ((uTransformMatrix * vec3(aPosition, 1.0)).xy / uResolution) * 2.0 - 1.0;
|
||||
position *= vec2(1.0, -1.0);
|
||||
// position *= vec2(40.0, -4.0);
|
||||
gl_Position = vec4(vec3(position, uZ), 1.0);
|
||||
vColor = aColor;
|
||||
vCoordinate = aCoordinate;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
uniform vec4 uColor;
|
||||
varying vec2 vTextureCoordinate;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = uColor;
|
||||
gl_FragColor = vec4(vTextureCoordinate.x, vTextureCoordinate.y, 0, 0.5);
|
||||
|
||||
float u = vTextureCoordinate.x;
|
||||
float v = vTextureCoordinate.y;
|
||||
float r = u * u - v;
|
||||
if (r < 0.0) {
|
||||
gl_FragColor = vec4(1, 0, 0, 1);
|
||||
} else {
|
||||
gl_FragColor = vec4(1, 0, 0, 0.2);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vColor;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
uniform vec2 uResolution;
|
||||
uniform mat3 uTransformMatrix;
|
||||
uniform float uZ;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec4 aColor;
|
||||
|
||||
varying vec4 vColor;
|
||||
|
||||
void main() {
|
||||
vec2 position = ((uTransformMatrix * vec3(aPosition, 1.0)).xy / uResolution) * 2.0 - 1.0;
|
||||
position *= vec2(1.0, -1.0);
|
||||
gl_Position = vec4(vec3(position, uZ), 1.0);
|
||||
vColor = aColor;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uSampler;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
// gl_FragColor = vColor;
|
||||
// gl_FragColor = vec4(vTextureCoordinate.x, vTextureCoordinate.y, 0, 0.5);
|
||||
// gl_FragColor = gl_FragColor; // + texture2D(uSampler, vCoordinate);
|
||||
gl_FragColor = texture2D(uSampler, vCoordinate);
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
uniform vec2 uResolution;
|
||||
uniform mat3 uTransformMatrix;
|
||||
uniform float uZ;
|
||||
|
||||
attribute vec2 aPosition;
|
||||
attribute vec4 aColor;
|
||||
attribute vec2 aCoordinate;
|
||||
|
||||
varying vec4 vColor;
|
||||
varying vec2 vCoordinate;
|
||||
|
||||
void main() {
|
||||
vec2 position = ((uTransformMatrix * vec3(aPosition, 1.0)).xy / uResolution) * 2.0 - 1.0;
|
||||
position *= vec2(1.0, -1.0);
|
||||
// position *= vec2(40.0, -4.0);
|
||||
gl_Position = vec4(vec3(position, uZ), 1.0);
|
||||
vColor = aColor;
|
||||
vCoordinate = aCoordinate;
|
||||
}
|
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,2 +1,2 @@
|
|||
0.9.2970
|
||||
22f884f
|
||||
0.9.3693
|
||||
217e2e2
|
||||
|
|
|
@ -35,7 +35,7 @@ limitations under the License.
|
|||
display: none;
|
||||
}
|
||||
|
||||
#stageContainer {
|
||||
#easelContainer {
|
||||
position:fixed !important;
|
||||
left:0;top:0;bottom:0;right:0;
|
||||
overflow: hidden;
|
||||
|
@ -49,7 +49,7 @@ limitations under the License.
|
|||
#overlay.enabled {
|
||||
display: block;
|
||||
position:fixed;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ limitations under the License.
|
|||
width: 70px; height: 16px;
|
||||
padding: 8px 4px 4px;
|
||||
color: white;
|
||||
background-color: rgba(0, 0, 0, 0.62);
|
||||
background-color: rgba(218, 56, 7, 0.63);
|
||||
font: bold 10px sans-serif;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
|
@ -100,7 +100,7 @@ limitations under the License.
|
|||
|
||||
<body contextmenu="shumwayMenu">
|
||||
<iframe id="playerWindow" width="9" height="9" src=""></iframe>
|
||||
<div id="stageContainer"></div>
|
||||
<div id="easelContainer"></div>
|
||||
<section>
|
||||
<div id="overlay">
|
||||
<a id="fallback" href="#">Shumway <span class="icon">×</span></a>
|
||||
|
@ -114,5 +114,8 @@ limitations under the License.
|
|||
<menuitem label="About Shumway" id="aboutMenu"></menuitem>
|
||||
</menu>
|
||||
</section>
|
||||
|
||||
<script src='resource://shumway/shumway.gfx.js'></script>
|
||||
<script src='resource://shumway/web/viewer.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -27,11 +27,8 @@ var FirefoxCom = (function FirefoxComClosure() {
|
|||
* @return {*} The response.
|
||||
*/
|
||||
requestSync: function(action, data) {
|
||||
var e = document.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: true});
|
||||
document.dispatchEvent(e);
|
||||
return e.detail.response;
|
||||
var result = String(ShumwayCom.sendMessage(action, data, true, undefined));
|
||||
return result !== 'undefined' ? JSON.parse(result) : undefined;
|
||||
},
|
||||
/**
|
||||
* Creates an event that the extension is listening for and will
|
||||
|
@ -42,38 +39,45 @@ var FirefoxCom = (function FirefoxComClosure() {
|
|||
* with one data argument.
|
||||
*/
|
||||
request: function(action, data, callback) {
|
||||
var e = document.createEvent('CustomEvent');
|
||||
e.initCustomEvent('shumway.message', true, false,
|
||||
{action: action, data: data, sync: false});
|
||||
var cookie = undefined;
|
||||
if (callback) {
|
||||
if ('nextId' in FirefoxCom.request) {
|
||||
FirefoxCom.request.nextId = 1;
|
||||
cookie = "requestId" + (this._nextRequestId++);
|
||||
|
||||
if (!ShumwayCom.onMessageCallback) {
|
||||
ShumwayCom.onMessageCallback = this._notifyMessageCallback.bind(this);
|
||||
}
|
||||
var cookie = "requestId" + (FirefoxCom.request.nextId++);
|
||||
e.detail.cookie = cookie;
|
||||
e.detail.callback = true;
|
||||
|
||||
document.addEventListener('shumway.response', function listener(event) {
|
||||
if (cookie !== event.detail.cookie)
|
||||
return;
|
||||
|
||||
document.removeEventListener('shumway.response', listener, false);
|
||||
|
||||
var response = event.detail.response;
|
||||
return callback(response);
|
||||
}, false);
|
||||
this._requestCallbacks[cookie] = callback;
|
||||
}
|
||||
return document.dispatchEvent(e);
|
||||
ShumwayCom.sendMessage(action, data, false, cookie);
|
||||
},
|
||||
_notifyMessageCallback: function (cookie, response) {
|
||||
var callback = this._requestCallbacks[cookie];
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
delete this._requestCallbacks[cookie];
|
||||
callback(response !== 'undefined' ? JSON.parse(response) : undefined);
|
||||
},
|
||||
_nextRequestId: 1,
|
||||
_requestCallbacks: Object.create(null),
|
||||
initJS: function (callback) {
|
||||
FirefoxCom.request('externalCom', {action: 'init'});
|
||||
document.addEventListener('shumway.remote', function (e) {
|
||||
e.detail.result = callback(e.detail.functionName, e.detail.args);
|
||||
}, false);
|
||||
ShumwayCom.onExternalCallback = function (call) {
|
||||
return callback(call.functionName, call.args);
|
||||
};
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function notifyUserInput() {
|
||||
ShumwayCom.sendMessage('userInput', null, true, undefined);
|
||||
}
|
||||
|
||||
document.addEventListener('mousedown', notifyUserInput, true);
|
||||
document.addEventListener('mouseup', notifyUserInput, true);
|
||||
document.addEventListener('keydown', notifyUserInput, true);
|
||||
document.addEventListener('keyup', notifyUserInput, true);
|
||||
|
||||
function fallback() {
|
||||
FirefoxCom.requestSync('fallback', null)
|
||||
}
|
||||
|
@ -82,13 +86,14 @@ window.print = function(msg) {
|
|||
console.log(msg);
|
||||
};
|
||||
|
||||
var SHUMWAY_ROOT = "resource://shumway/";
|
||||
|
||||
var viewerPlayerglobalInfo = {
|
||||
abcs: SHUMWAY_ROOT + "playerglobal/playerglobal.abcs",
|
||||
catalog: SHUMWAY_ROOT + "playerglobal/playerglobal.json"
|
||||
};
|
||||
|
||||
var builtinPath = SHUMWAY_ROOT + "avm2/generated/builtin/builtin.abc";
|
||||
var avm1Path = SHUMWAY_ROOT + "avm2/generated/avm1lib/avm1lib.abc";
|
||||
|
||||
var playerWindow;
|
||||
var playerWindowLoaded = new Promise(function(resolve) {
|
||||
|
@ -101,7 +106,14 @@ var playerWindowLoaded = new Promise(function(resolve) {
|
|||
});
|
||||
|
||||
function runViewer() {
|
||||
var flashParams = JSON.parse(FirefoxCom.requestSync('getPluginParams', null));
|
||||
ShumwayCom.onLoadFileCallback = function (data) {
|
||||
playerWindow.postMessage({
|
||||
type: "loadFileResponse",
|
||||
args: data
|
||||
}, '*');
|
||||
};
|
||||
|
||||
var flashParams = FirefoxCom.requestSync('getPluginParams', null);
|
||||
|
||||
movieUrl = flashParams.url;
|
||||
if (!movieUrl) {
|
||||
|
@ -112,6 +124,7 @@ function runViewer() {
|
|||
|
||||
movieParams = flashParams.movieParams;
|
||||
objectParams = flashParams.objectParams;
|
||||
var baseUrl = flashParams.baseUrl;
|
||||
var isOverlay = flashParams.isOverlay;
|
||||
pauseExecution = flashParams.isPausedAtStart;
|
||||
|
||||
|
@ -125,7 +138,7 @@ function runViewer() {
|
|||
}
|
||||
|
||||
playerWindowLoaded.then(function () {
|
||||
parseSwf(movieUrl, movieParams, objectParams);
|
||||
parseSwf(movieUrl, baseUrl, movieParams, objectParams);
|
||||
});
|
||||
|
||||
if (isOverlay) {
|
||||
|
@ -193,12 +206,6 @@ var movieUrl, movieParams, objectParams;
|
|||
window.addEventListener("message", function handlerMessage(e) {
|
||||
var args = e.data;
|
||||
switch (args.callback) {
|
||||
case 'loadFile':
|
||||
playerWindow.postMessage({
|
||||
type: "loadFileResponse",
|
||||
args: args
|
||||
}, '*');
|
||||
break;
|
||||
case 'loadFileRequest':
|
||||
FirefoxCom.request('loadFile', args.data, null);
|
||||
break;
|
||||
|
@ -208,6 +215,9 @@ window.addEventListener("message", function handlerMessage(e) {
|
|||
case 'setClipboard':
|
||||
FirefoxCom.request('setClipboard', args.data, null);
|
||||
break;
|
||||
case 'navigateTo':
|
||||
FirefoxCom.request('navigateTo', args.data, null);
|
||||
break;
|
||||
case 'started':
|
||||
document.body.classList.add('started');
|
||||
break;
|
||||
|
@ -232,13 +242,11 @@ function processExternalCommand(command) {
|
|||
}
|
||||
}
|
||||
|
||||
function parseSwf(url, movieParams, objectParams) {
|
||||
var compilerSettings = JSON.parse(
|
||||
FirefoxCom.requestSync('getCompilerSettings', null));
|
||||
function parseSwf(url, baseUrl, movieParams, objectParams) {
|
||||
var compilerSettings = FirefoxCom.requestSync('getCompilerSettings', null);
|
||||
|
||||
// init misc preferences
|
||||
var turboMode = FirefoxCom.requestSync('getBoolPref', {pref: 'shumway.turboMode', def: false});
|
||||
Shumway.GFX.backend.value = FirefoxCom.requestSync('getBoolPref', {pref: 'shumway.webgl', def: false}) ? 1 : 0;
|
||||
Shumway.GFX.hud.value = FirefoxCom.requestSync('getBoolPref', {pref: 'shumway.hud', def: false});
|
||||
//forceHidpi.value = FirefoxCom.requestSync('getBoolPref', {pref: 'shumway.force_hidpi', def: false});
|
||||
//dummyAnimation.value = FirefoxCom.requestSync('getBoolPref', {pref: 'shumway.dummyMode', def: false});
|
||||
|
@ -249,22 +257,23 @@ function parseSwf(url, movieParams, objectParams) {
|
|||
FirefoxCom.request('endActivation', null);
|
||||
}
|
||||
|
||||
var bgcolor;
|
||||
var backgroundColor;
|
||||
if (objectParams) {
|
||||
var m;
|
||||
if (objectParams.bgcolor && (m = /#([0-9A-F]{6})/i.exec(objectParams.bgcolor))) {
|
||||
var hexColor = parseInt(m[1], 16);
|
||||
bgcolor = hexColor << 8 | 0xff;
|
||||
backgroundColor = hexColor << 8 | 0xff;
|
||||
}
|
||||
if (objectParams.wmode === 'transparent') {
|
||||
bgcolor = 0;
|
||||
backgroundColor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var easel = createEasel(bgcolor);
|
||||
var easel = createEasel(backgroundColor);
|
||||
easelHost = new Shumway.GFX.Window.WindowEaselHost(easel, playerWindow, window);
|
||||
easelHost.processExternalCommand = processExternalCommand;
|
||||
|
||||
var displayParameters = easel.getDisplayParameters();
|
||||
var data = {
|
||||
type: 'runSwf',
|
||||
settings: Shumway.Settings.getSettings(),
|
||||
|
@ -272,21 +281,21 @@ function parseSwf(url, movieParams, objectParams) {
|
|||
compilerSettings: compilerSettings,
|
||||
movieParams: movieParams,
|
||||
objectParams: objectParams,
|
||||
displayParameters: displayParameters,
|
||||
turboMode: turboMode,
|
||||
bgcolor: bgcolor,
|
||||
bgcolor: backgroundColor,
|
||||
url: url,
|
||||
baseUrl: url
|
||||
baseUrl: baseUrl || url
|
||||
}
|
||||
};
|
||||
playerWindow.postMessage(data, '*');
|
||||
}
|
||||
|
||||
function createEasel(bgcolor) {
|
||||
function createEasel(backgroundColor) {
|
||||
var Stage = Shumway.GFX.Stage;
|
||||
var Easel = Shumway.GFX.Easel;
|
||||
var Canvas2DStageRenderer = Shumway.GFX.Canvas2DStageRenderer;
|
||||
var Canvas2DRenderer = Shumway.GFX.Canvas2DRenderer;
|
||||
|
||||
Shumway.GFX.WebGL.SHADER_ROOT = SHUMWAY_ROOT + "gfx/gl/shaders/";
|
||||
var backend = Shumway.GFX.backend.value | 0;
|
||||
return new Easel(document.getElementById("stageContainer"), backend, false, bgcolor);
|
||||
return new Easel(document.getElementById("easelContainer"), false, backgroundColor);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ var viewerPlayerglobalInfo = {
|
|||
|
||||
var avm2Root = SHUMWAY_ROOT + "avm2/";
|
||||
var builtinPath = avm2Root + "generated/builtin/builtin.abc";
|
||||
var avm1Path = avm2Root + "generated/avm1lib/avm1lib.abc";
|
||||
|
||||
window.print = function(msg) {
|
||||
console.log(msg);
|
||||
|
@ -38,29 +37,32 @@ function runSwfPlayer(flashParams) {
|
|||
var appMode = compilerSettings.appCompiler ? EXECUTION_MODE.COMPILE : EXECUTION_MODE.INTERPRET;
|
||||
var asyncLoading = true;
|
||||
var baseUrl = flashParams.baseUrl;
|
||||
var movieParams = flashParams.movieParams;
|
||||
var objectParams = flashParams.objectParams;
|
||||
var movieUrl = flashParams.url;
|
||||
|
||||
Shumway.frameRateOption.value = flashParams.turboMode ? 60 : -1;
|
||||
Shumway.AVM2.Verifier.enabled.value = compilerSettings.verifier;
|
||||
|
||||
Shumway.createAVM2(builtinPath, viewerPlayerglobalInfo, avm1Path, sysMode, appMode, function (avm2) {
|
||||
Shumway.createAVM2(builtinPath, viewerPlayerglobalInfo, sysMode, appMode, function (avm2) {
|
||||
function runSWF(file) {
|
||||
var player = new Shumway.Player.Window.WindowPlayer(window, window.parent);
|
||||
player.defaultStageColor = flashParams.bgcolor;
|
||||
player.movieParams = flashParams.movieParams;
|
||||
player.stageAlign = (objectParams && (objectParams.salign || objectParams.align)) || '';
|
||||
player.stageScale = (objectParams && objectParams.scale) || 'showall';
|
||||
player.displayParameters = flashParams.displayParameters;
|
||||
|
||||
Shumway.ExternalInterfaceService.instance = player.createExternalInterfaceService();
|
||||
|
||||
player.load(file);
|
||||
}
|
||||
file = Shumway.FileLoadingService.instance.setBaseUrl(baseUrl);
|
||||
Shumway.FileLoadingService.instance.setBaseUrl(baseUrl);
|
||||
if (asyncLoading) {
|
||||
runSWF(movieUrl);
|
||||
} else {
|
||||
new Shumway.BinaryFileReader(movieUrl).readAll(null, function(buffer, error) {
|
||||
if (!buffer) {
|
||||
throw "Unable to open the file " + file + ": " + error;
|
||||
throw "Unable to open the file " + movieUrl + ": " + error;
|
||||
}
|
||||
runSWF(movieUrl, buffer);
|
||||
});
|
||||
|
@ -129,32 +131,34 @@ function setupServices() {
|
|||
};
|
||||
},
|
||||
setBaseUrl: function (url) {
|
||||
var baseUrl;
|
||||
if (typeof URL !== 'undefined') {
|
||||
baseUrl = new URL(url, document.location.href).href;
|
||||
} else {
|
||||
var a = document.createElement('a');
|
||||
a.href = url || '#';
|
||||
a.setAttribute('style', 'display: none;');
|
||||
document.body.appendChild(a);
|
||||
baseUrl = a.href;
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
Shumway.FileLoadingService.instance.baseUrl = baseUrl;
|
||||
return baseUrl;
|
||||
Shumway.FileLoadingService.instance.baseUrl = url;
|
||||
},
|
||||
resolveUrl: function (url) {
|
||||
if (url.indexOf('://') >= 0) return url;
|
||||
|
||||
var base = Shumway.FileLoadingService.instance.baseUrl;
|
||||
base = base.lastIndexOf('/') >= 0 ? base.substring(0, base.lastIndexOf('/') + 1) : '';
|
||||
if (url.indexOf('/') === 0) {
|
||||
var m = /^[^:]+:\/\/[^\/]+/.exec(base);
|
||||
if (m) base = m[0];
|
||||
}
|
||||
return base + url;
|
||||
return new URL(url, Shumway.FileLoadingService.instance.baseUrl).href;
|
||||
},
|
||||
navigateTo: function (url, target) {
|
||||
window.parent.postMessage({
|
||||
callback: 'navigateTo',
|
||||
data: {
|
||||
url: this.resolveUrl(url),
|
||||
target: target
|
||||
}
|
||||
}, '*');
|
||||
}
|
||||
};
|
||||
|
||||
// Using SpecialInflate when chrome code provides it.
|
||||
if (parent.createSpecialInflate) {
|
||||
window.SpecialInflate = function () {
|
||||
return parent.createSpecialInflate();
|
||||
};
|
||||
}
|
||||
|
||||
// Using createRtmpXHR/createRtmpSocket when chrome code provides it.
|
||||
if (parent.createRtmpXHR) {
|
||||
window.createRtmpSocket = parent.createRtmpSocket;
|
||||
window.createRtmpXHR = parent.createRtmpXHR;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('message', function onWindowMessage(e) {
|
||||
|
|
|
@ -58,6 +58,11 @@ filefield + button {
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
#advancedPrefs {
|
||||
margin-right: 0; /*override margin from normal preferences.css */
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog
|
||||
*/
|
||||
|
|
|
@ -202,10 +202,6 @@ description > html|a {
|
|||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
#advancedPrefs {
|
||||
padding-bottom: 0; /* no padding needed in inContent prefs */
|
||||
}
|
||||
|
||||
#tabsElement {
|
||||
-moz-margin-end: 4px; /* add the 4px end-margin of other elements */
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#defaultEngine {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
#defaultEngine > .menulist-label-box > .menulist-icon {
|
||||
height: 16px;
|
||||
}
|
||||
|
@ -12,7 +16,7 @@
|
|||
}
|
||||
|
||||
#engineList {
|
||||
margin: .5em 6px;
|
||||
margin: .5em 0;
|
||||
}
|
||||
|
||||
#engineList treechildren::-moz-tree-image(engineShown, checked) {
|
||||
|
@ -51,3 +55,9 @@
|
|||
#addEnginesBox {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#removeEngineButton,
|
||||
#restoreDefaultSearchEngines {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ filefield + button {
|
|||
-moz-margin-start: -4px;
|
||||
}
|
||||
|
||||
#advancedPrefs {
|
||||
padding-bottom: 0; /* override padding from normal preferences.css */
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog
|
||||
*/
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PanZoomController;
|
||||
import org.mozilla.gecko.gfx.PointUtils;
|
||||
import org.mozilla.gecko.mozglue.DirectBufferAllocator;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.mozglue.DirectBufferAllocator;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -28,8 +33,11 @@ import android.widget.FrameLayout;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChangedListener,
|
||||
LayerView.OnZoomedViewListener, GeckoEventListener {
|
||||
LayerView.ZoomedViewListener, GeckoEventListener {
|
||||
private static final String LOGTAG = "Gecko" + ZoomedView.class.getSimpleName();
|
||||
|
||||
private static final int ZOOM_FACTOR = 2;
|
||||
|
@ -40,27 +48,26 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
|
||||
private ImageView zoomedImageView;
|
||||
private LayerView layerView;
|
||||
private MotionEvent actionDownEvent;
|
||||
private int viewWidth;
|
||||
private int viewHeight;
|
||||
private int xLastPosition;
|
||||
private int yLastPosition;
|
||||
private Point lastPosition;
|
||||
private boolean shouldSetVisibleOnUpdate;
|
||||
private PointF returnValue;
|
||||
|
||||
private boolean stopUpdateView;
|
||||
|
||||
private int lastOrientation = 0;
|
||||
private int lastOrientation;
|
||||
|
||||
private ByteBuffer buffer;
|
||||
private Runnable requestRenderRunnable;
|
||||
private long startTimeReRender = 0;
|
||||
private long lastStartTimeReRender = 0;
|
||||
private long startTimeReRender;
|
||||
private long lastStartTimeReRender;
|
||||
|
||||
private class ZoomedViewTouchListener implements View.OnTouchListener {
|
||||
private float originRawX;
|
||||
private float originRawY;
|
||||
private int touchState;
|
||||
private boolean dragged;
|
||||
private MotionEvent actionDownEvent;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
|
@ -71,13 +78,13 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (moveZoomedView(event)) {
|
||||
touchState = MotionEvent.ACTION_MOVE;
|
||||
dragged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (touchState == MotionEvent.ACTION_MOVE) {
|
||||
touchState = -1;
|
||||
if (dragged) {
|
||||
dragged = false;
|
||||
} else {
|
||||
layerView.dispatchTouchEvent(actionDownEvent);
|
||||
actionDownEvent.recycle();
|
||||
|
@ -91,7 +98,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
break;
|
||||
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touchState = -1;
|
||||
dragged = false;
|
||||
originRawX = event.getRawX();
|
||||
originRawY = event.getRawY();
|
||||
PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(event.getX(), event.getY());
|
||||
|
@ -105,8 +112,8 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
|
||||
private boolean moveZoomedView(MotionEvent event) {
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ZoomedView.this.getLayoutParams();
|
||||
if ((touchState != MotionEvent.ACTION_MOVE) && (Math.abs((int) (event.getRawX() - originRawX)) < 1)
|
||||
&& (Math.abs((int) (event.getRawY() - originRawY)) < 1)) {
|
||||
if ((!dragged) && (Math.abs((int) (event.getRawX() - originRawX)) < PanZoomController.CLICK_THRESHOLD)
|
||||
&& (Math.abs((int) (event.getRawY() - originRawY)) < PanZoomController.CLICK_THRESHOLD)) {
|
||||
// When the user just touches the screen ACTION_MOVE can be detected for a very small delta on position.
|
||||
// In this case, the move is ignored if the delta is lower than 1 unit.
|
||||
return false;
|
||||
|
@ -236,10 +243,6 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
}
|
||||
|
||||
private void moveZoomedView(ImmutableViewportMetrics metrics, float newLeftMargin, float newTopMargin) {
|
||||
if (layerView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final float parentWidth = metrics.getWidth();
|
||||
final float parentHeight = metrics.getHeight();
|
||||
RelativeLayout.LayoutParams newLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
|
@ -253,7 +256,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
|
||||
if (newTopMargin < topMarginMin) {
|
||||
newLayoutParams.topMargin = topMarginMin;
|
||||
} else if (newTopMargin + viewHeight >= parentHeight) {
|
||||
} else if (newTopMargin + viewHeight > parentHeight) {
|
||||
newLayoutParams.topMargin = (int) (parentHeight - viewHeight);
|
||||
}
|
||||
|
||||
|
@ -265,8 +268,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
|
||||
setLayoutParams(newLayoutParams);
|
||||
PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(0, 0);
|
||||
xLastPosition = Math.round(convertedPosition.x);
|
||||
yLastPosition = Math.round(convertedPosition.y);
|
||||
lastPosition = PointUtils.round(convertedPosition);
|
||||
requestZoomedViewRender();
|
||||
}
|
||||
|
||||
|
@ -282,7 +284,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
}
|
||||
}
|
||||
|
||||
public void refreshZoomedViewSize(ImmutableViewportMetrics viewport) {
|
||||
private void refreshZoomedViewSize(ImmutableViewportMetrics viewport) {
|
||||
if (layerView == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -292,27 +294,24 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
moveZoomedView(viewport, params.leftMargin, params.topMargin);
|
||||
}
|
||||
|
||||
public void setCapturedSize(ImmutableViewportMetrics metrics) {
|
||||
if (layerView == null) {
|
||||
return;
|
||||
}
|
||||
private void setCapturedSize(ImmutableViewportMetrics metrics) {
|
||||
float parentMinSize = Math.min(metrics.getWidth(), metrics.getHeight());
|
||||
viewWidth = (int) (parentMinSize * W_CAPTURED_VIEW_IN_PERCENT / (ZOOM_FACTOR * 100.0)) * ZOOM_FACTOR;
|
||||
viewHeight = (int) (parentMinSize * H_CAPTURED_VIEW_IN_PERCENT / (ZOOM_FACTOR * 100.0)) * ZOOM_FACTOR;
|
||||
}
|
||||
|
||||
public void shouldBlockUpdate(boolean shouldBlockUpdate) {
|
||||
private void shouldBlockUpdate(boolean shouldBlockUpdate) {
|
||||
stopUpdateView = shouldBlockUpdate;
|
||||
}
|
||||
|
||||
public Bitmap.Config getBitmapConfig() {
|
||||
private Bitmap.Config getBitmapConfig() {
|
||||
return (GeckoAppShell.getScreenDepth() == 24) ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
|
||||
}
|
||||
|
||||
public void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, final int topFromGecko) {
|
||||
private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, final int topFromGecko) {
|
||||
if (layerView == null) {
|
||||
layerView = aLayerView;
|
||||
layerView.addOnZoomedViewListener(this);
|
||||
layerView.addZoomedViewListener(this);
|
||||
layerView.setOnMetricsChangedZoomedViewportListener(this);
|
||||
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
|
||||
setCapturedSize(metrics);
|
||||
|
@ -322,13 +321,13 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
moveUsingGeckoPosition(leftFromGecko, topFromGecko);
|
||||
}
|
||||
|
||||
public void stopZoomDisplay() {
|
||||
private void stopZoomDisplay() {
|
||||
shouldSetVisibleOnUpdate = false;
|
||||
this.setVisibility(View.GONE);
|
||||
ThreadUtils.removeCallbacksFromUiThread(requestRenderRunnable);
|
||||
if (layerView != null) {
|
||||
layerView.setOnMetricsChangedZoomedViewportListener(null);
|
||||
layerView.removeOnZoomedViewListener(this);
|
||||
layerView.removeZoomedViewListener(this);
|
||||
layerView = null;
|
||||
}
|
||||
}
|
||||
|
@ -362,9 +361,6 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
}
|
||||
|
||||
private void moveUsingGeckoPosition(int leftFromGecko, int topFromGecko) {
|
||||
if (layerView == null) {
|
||||
return;
|
||||
}
|
||||
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
|
||||
PointF convertedPosition = getZoomedViewTopLeftPositionFromTouchPosition((leftFromGecko * metrics.zoomFactor),
|
||||
(topFromGecko * metrics.zoomFactor));
|
||||
|
@ -379,9 +375,6 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (layerView == null) {
|
||||
return;
|
||||
}
|
||||
shouldBlockUpdate(false);
|
||||
refreshZoomedViewSize(viewport);
|
||||
}
|
||||
|
@ -477,11 +470,11 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
|
|||
PointF origin = metrics.getOrigin();
|
||||
PointF offset = metrics.getMarginOffset();
|
||||
|
||||
final int xPos = (int) (origin.x - offset.x) + xLastPosition;
|
||||
final int yPos = (int) (origin.y - offset.y) + yLastPosition;
|
||||
final int xPos = (int) (origin.x - offset.x) + lastPosition.x;
|
||||
final int yPos = (int) (origin.y - offset.y) + lastPosition.y;
|
||||
|
||||
GeckoEvent e = GeckoEvent.createZoomedViewEvent(tabId, xPos, yPos, viewWidth,
|
||||
viewHeight, (float) (2.0 * metrics.zoomFactor), buffer);
|
||||
viewHeight, ZOOM_FACTOR * metrics.zoomFactor, buffer);
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -915,10 +915,10 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
@Override
|
||||
public void panZoomStopped() {
|
||||
if (mDynamicToolbarViewportChangeListener != null) {
|
||||
mDynamicToolbarViewportChangeListener.onPanZoomStopped();
|
||||
mDynamicToolbarViewportChangeListener.onPanZoomStopped();
|
||||
}
|
||||
if (mZoomedViewViewportChangeListener != null) {
|
||||
mZoomedViewViewportChangeListener.onPanZoomStopped();
|
||||
mZoomedViewViewportChangeListener.onPanZoomStopped();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,9 +96,9 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
private int mSampleHandle;
|
||||
private int mTMatrixHandle;
|
||||
|
||||
private List<LayerView.OnZoomedViewListener> mZoomedViewListeners;
|
||||
private float mViewLeft = 0.0f;
|
||||
private float mViewTop = 0.0f;
|
||||
private List<LayerView.ZoomedViewListener> mZoomedViewListeners;
|
||||
private float mLastViewLeft;
|
||||
private float mLastViewTop;
|
||||
|
||||
// column-major matrix applied to each vertex to shift the viewport from
|
||||
// one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by
|
||||
|
@ -168,7 +168,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
mCoordBuffer = mCoordByteBuffer.asFloatBuffer();
|
||||
|
||||
Tabs.registerOnTabsChangedListener(this);
|
||||
mZoomedViewListeners = new ArrayList<LayerView.OnZoomedViewListener>();
|
||||
mZoomedViewListeners = new ArrayList<LayerView.ZoomedViewListener>();
|
||||
}
|
||||
|
||||
private Bitmap expandCanvasToPowerOfTwo(Bitmap image, IntSize size) {
|
||||
|
@ -598,7 +598,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
|
||||
}
|
||||
|
||||
public void maybeRequestZoomedViewRender(RenderContext context){
|
||||
private void maybeRequestZoomedViewRender(RenderContext context) {
|
||||
// Concurrently update of mZoomedViewListeners should not be an issue here
|
||||
// because the following line is just a short-circuit
|
||||
if (mZoomedViewListeners.size() == 0) {
|
||||
|
@ -612,13 +612,13 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
final float viewTop = context.viewport.top - context.offset.y;
|
||||
boolean shouldWaitToRender = false;
|
||||
|
||||
if (Math.abs(mViewLeft - viewLeft) > MAX_SCROLL_SPEED_TO_REQUEST_ZOOM_RENDER ||
|
||||
Math.abs(mViewTop - viewTop) > MAX_SCROLL_SPEED_TO_REQUEST_ZOOM_RENDER) {
|
||||
if (Math.abs(mLastViewLeft - viewLeft) > MAX_SCROLL_SPEED_TO_REQUEST_ZOOM_RENDER ||
|
||||
Math.abs(mLastViewTop - viewTop) > MAX_SCROLL_SPEED_TO_REQUEST_ZOOM_RENDER) {
|
||||
shouldWaitToRender = true;
|
||||
}
|
||||
|
||||
mViewLeft = viewLeft;
|
||||
mViewTop = viewTop;
|
||||
mLastViewLeft = viewLeft;
|
||||
mLastViewTop = viewTop;
|
||||
|
||||
if (shouldWaitToRender) {
|
||||
return;
|
||||
|
@ -627,7 +627,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (LayerView.OnZoomedViewListener listener : mZoomedViewListeners) {
|
||||
for (LayerView.ZoomedViewListener listener : mZoomedViewListeners) {
|
||||
listener.requestZoomedViewRender();
|
||||
}
|
||||
}
|
||||
|
@ -697,19 +697,20 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
|||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (LayerView.OnZoomedViewListener listener : mZoomedViewListeners) {
|
||||
for (LayerView.ZoomedViewListener listener : mZoomedViewListeners) {
|
||||
data.position(0);
|
||||
listener.updateView(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addOnZoomedViewListener(LayerView.OnZoomedViewListener listener) {
|
||||
public void addZoomedViewListener(LayerView.ZoomedViewListener listener) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
mZoomedViewListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeOnZoomedViewListener(LayerView.OnZoomedViewListener listener) {
|
||||
public void removeZoomedViewListener(LayerView.ZoomedViewListener listener) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
mZoomedViewListeners.remove(listener);
|
||||
}
|
||||
|
|
|
@ -532,17 +532,16 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
|
|||
}
|
||||
}
|
||||
|
||||
//This method is called on the Gecko main thread.
|
||||
@WrapElementForJNI(allowMultithread = true, stubName = "updateZoomedView")
|
||||
public static void updateZoomedView(ByteBuffer data) {
|
||||
data.position(0);
|
||||
LayerView layerView = GeckoAppShell.getLayerView();
|
||||
if (layerView != null) {
|
||||
LayerRenderer layerRenderer = layerView.getRenderer();
|
||||
if (layerRenderer != null){
|
||||
if (layerRenderer != null) {
|
||||
layerRenderer.updateZoomedView(data);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
@ -687,17 +686,17 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
|
|||
|
||||
// Public hooks for zoomed view
|
||||
|
||||
public interface OnZoomedViewListener {
|
||||
public interface ZoomedViewListener {
|
||||
public void requestZoomedViewRender();
|
||||
public void updateView(ByteBuffer data);
|
||||
}
|
||||
|
||||
public void addOnZoomedViewListener(OnZoomedViewListener listener) {
|
||||
mRenderer.addOnZoomedViewListener(listener);
|
||||
public void addZoomedViewListener(ZoomedViewListener listener) {
|
||||
mRenderer.addZoomedViewListener(listener);
|
||||
}
|
||||
|
||||
public void removeOnZoomedViewListener(OnZoomedViewListener listener) {
|
||||
mRenderer.removeOnZoomedViewListener(listener);
|
||||
public void removeZoomedViewListener(ZoomedViewListener listener) {
|
||||
mRenderer.removeZoomedViewListener(listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -91,5 +91,39 @@ this.PlacesTestUtils = Object.freeze({
|
|||
});
|
||||
|
||||
return Promise.all([expirationFinished, PlacesUtils.history.clear()]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Waits for all pending async statements on the default connection.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When all pending async statements finished.
|
||||
* @rejects Never.
|
||||
*
|
||||
* @note The result is achieved by asynchronously executing a query requiring
|
||||
* a write lock. Since all statements on the same connection are
|
||||
* serialized, the end of this write operation means that all writes are
|
||||
* complete. Note that WAL makes so that writers don't block readers, but
|
||||
* this is a problem only across different connections.
|
||||
*/
|
||||
promiseAsyncUpdates() {
|
||||
return new Promise(resolve => {
|
||||
let db = PlacesUtils.history.DBConnection;
|
||||
let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
|
||||
begin.executeAsync();
|
||||
begin.finalize();
|
||||
|
||||
let commit = db.createAsyncStatement("COMMIT");
|
||||
commit.executeAsync({
|
||||
handleResult: function () {},
|
||||
handleError: function () {},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
commit.finalize();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -277,7 +277,7 @@ function run_test() {
|
|||
// At this point frecency could still be updating due to latest pages
|
||||
// updates. This is not a problem in real life, but autocomplete tests
|
||||
// should return reliable resultsets, thus we have to wait.
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
}).then(function () ensure_results(search, expected),
|
||||
do_report_unexpected_exception);
|
||||
|
|
|
@ -12,7 +12,7 @@ added or removed and also the maintenance task to fix wrong counts.
|
|||
const T_URI = NetUtil.newURI("https://www.mozilla.org/firefox/nightly/firstrun/");
|
||||
|
||||
function* getForeignCountForURL(conn, url) {
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
url = url instanceof Ci.nsIURI ? url.spec : url;
|
||||
let rows = yield conn.executeCached(
|
||||
"SELECT foreign_count FROM moz_places WHERE url = :t_url ", { t_url: url });
|
||||
|
|
|
@ -56,7 +56,7 @@ add_task(function* test_eraseEverything() {
|
|||
PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(toolbarBookmarkInFolder.guid)),
|
||||
"testanno1", "testvalue1", 0, 0);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
Assert.ok(frecencyForUrl("http://example.com/") > frecencyForExample);
|
||||
Assert.ok(frecencyForUrl("http://example.com/") > frecencyForMozilla);
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ add_task(function* create_bookmark_frecency() {
|
|||
title: "a bookmark" });
|
||||
checkBookmarkObject(bm);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
Assert.ok(frecencyForUrl(bm.url) > 0, "Check frecency has been updated")
|
||||
});
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ add_test(function test_addBookmarkWithKeyword()
|
|||
check_bookmark_keyword(itemId, "keyword");
|
||||
check_uri_keyword(URIS[0], "keyword");
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
check_orphans();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -94,7 +94,7 @@ add_test(function test_addBookmarkToURIHavingKeyword()
|
|||
check_bookmark_keyword(itemId, null);
|
||||
check_uri_keyword(URIS[0], "keyword");
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
check_orphans();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -120,7 +120,7 @@ add_test(function test_addSameKeywordToOtherURI()
|
|||
check_uri_keyword(URIS[1], "keyword");
|
||||
check_uri_keyword(URIS[0], "keyword");
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
check_orphans();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -143,7 +143,7 @@ add_test(function test_removeBookmarkWithKeyword()
|
|||
check_uri_keyword(URIS[1], "keyword");
|
||||
check_uri_keyword(URIS[0], "keyword");
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
check_orphans();
|
||||
run_next_test();
|
||||
});
|
||||
|
@ -157,7 +157,7 @@ add_test(function test_removeFolderWithKeywordedBookmarks()
|
|||
check_uri_keyword(URIS[1], null);
|
||||
check_uri_keyword(URIS[0], null);
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
check_orphans();
|
||||
run_next_test();
|
||||
});
|
||||
|
|
|
@ -55,7 +55,7 @@ function errorListener() {
|
|||
"Docshell URI is the original URI.");
|
||||
|
||||
// Global history does not record URI of a failed request.
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
gAsyncHistory.isURIVisited(kUniqueURI, errorAsyncListener);
|
||||
});
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ function reloadListener() {
|
|||
"Document URI is not the offline-error page, but the original URI.");
|
||||
|
||||
// Check if global history remembers the successfully-requested URI.
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
gAsyncHistory.isURIVisited(kUniqueURI, reloadAsyncListener);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,43 +18,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
/**
|
||||
* Waits for all pending async statements on the default connection.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When all pending async statements finished.
|
||||
* @rejects Never.
|
||||
*
|
||||
* @note The result is achieved by asynchronously executing a query requiring
|
||||
* a write lock. Since all statements on the same connection are
|
||||
* serialized, the end of this write operation means that all writes are
|
||||
* complete. Note that WAL makes so that writers don't block readers, but
|
||||
* this is a problem only across different connections.
|
||||
*/
|
||||
function promiseAsyncUpdates()
|
||||
{
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
|
||||
begin.executeAsync();
|
||||
begin.finalize();
|
||||
|
||||
let commit = db.createAsyncStatement("COMMIT");
|
||||
commit.executeAsync({
|
||||
handleResult: function() {},
|
||||
handleError: function() {},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
commit.finalize();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a moz_places field value for a url.
|
||||
*
|
||||
|
|
|
@ -69,7 +69,7 @@ add_test(function test_query_result_favicon_changed_on_child()
|
|||
// operation, and then for the main thread to process any pending
|
||||
// notifications that came from the asynchronous thread, before we can be
|
||||
// sure that nodeIconChanged was not invoked in the meantime.
|
||||
promiseAsyncUpdates().then(function QRFCOC_asyncUpdates() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(function QRFCOC_asyncUpdates() {
|
||||
do_execute_soon(function QRFCOC_soon() {
|
||||
result.removeObserver(resultObserver);
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ add_task(function test_replaceFaviconData_replaceExisting() {
|
|||
iconsvc.replaceFaviconData(
|
||||
firstFavicon.uri, secondFavicon.data, secondFavicon.data.length,
|
||||
secondFavicon.mimetype);
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
checkFaviconDataForPage(
|
||||
pageURI, secondFavicon.mimetype, secondFavicon.data,
|
||||
function test_replaceFaviconData_overrideDefaultFavicon_secondCallback() {
|
||||
|
|
|
@ -598,42 +598,6 @@ function is_time_ordered(before, after) {
|
|||
return after - before > -skew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for all pending async statements on the default connection.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When all pending async statements finished.
|
||||
* @rejects Never.
|
||||
*
|
||||
* @note The result is achieved by asynchronously executing a query requiring
|
||||
* a write lock. Since all statements on the same connection are
|
||||
* serialized, the end of this write operation means that all writes are
|
||||
* complete. Note that WAL makes so that writers don't block readers, but
|
||||
* this is a problem only across different connections.
|
||||
*/
|
||||
function promiseAsyncUpdates()
|
||||
{
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let db = DBConn();
|
||||
let begin = db.createAsyncStatement("BEGIN EXCLUSIVE");
|
||||
begin.executeAsync();
|
||||
begin.finalize();
|
||||
|
||||
let commit = db.createAsyncStatement("COMMIT");
|
||||
commit.executeAsync({
|
||||
handleResult: function () {},
|
||||
handleError: function () {},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
commit.finalize();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdowns Places, invoking the callback when the connection has been closed.
|
||||
*
|
||||
|
|
|
@ -166,8 +166,8 @@ function run_test() {
|
|||
// updates.
|
||||
// This is not a problem in real life, but autocomplete tests should
|
||||
// return reliable resultsets, thus we have to wait.
|
||||
promiseAsyncUpdates().then(function () ensure_results(searchString,
|
||||
expectedValue));
|
||||
PlacesTestUtils.promiseAsyncUpdates()
|
||||
.then(() => ensure_results(searchString, expectedValue));
|
||||
})
|
||||
}, this);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ add_task(function* test_moz_hosts() {
|
|||
yield db.execute("SELECT host, frecency, typed, prefix FROM moz_hosts");
|
||||
|
||||
// moz_hosts is populated asynchronously, so we need to wait.
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// check the number of entries in moz_hosts equals the number of
|
||||
// unique rev_host in moz_places
|
||||
|
|
|
@ -283,7 +283,7 @@ add_task(function test_add_visits_to_database()
|
|||
add_task(function test_redirects()
|
||||
{
|
||||
// Frecency and hidden are updated asynchronously, wait for them.
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// This array will be used by cartProd to generate a matrix of all possible
|
||||
// combinations.
|
||||
|
|
|
@ -1266,7 +1266,7 @@ add_task(function test_sorting()
|
|||
{
|
||||
for (let [, test] in Iterator(tests)) {
|
||||
yield test.setup();
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
test.check();
|
||||
// sorting reversed, usually SORT_BY have ASC and DESC
|
||||
test.check_reverse();
|
||||
|
|
|
@ -101,7 +101,7 @@ function* check_autocomplete(test) {
|
|||
// updates.
|
||||
// This is not a problem in real life, but autocomplete tests should
|
||||
// return reliable resultsets, thus we have to wait.
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches and confirms results.
|
||||
let input = new AutoCompleteInput(["unifiedcomplete"]);
|
||||
|
|
|
@ -52,7 +52,7 @@ add_task(function* test_searchEngine_autoFill() {
|
|||
}
|
||||
yield promiseAddVisits(visits);
|
||||
addBookmark({ uri: uri, title: "Example bookmark" });
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
ok(frecencyForUrl(uri) > 10000, "Added URI should have expected high frecency");
|
||||
|
||||
do_print("Check search domain is autoFilled even if there's an higher frecency match");
|
||||
|
|
|
@ -216,7 +216,7 @@ add_task(function test_frecency()
|
|||
// DEBUG
|
||||
//results.every(function(el) { dump("result: " + el[1] + ": " + el[0].spec + " (" + el[2] + ")\n"); return true; })
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
|
|
|
@ -53,7 +53,7 @@ function run_test() {
|
|||
// 2. run the test-suite
|
||||
Task.spawn(function() {
|
||||
yield validate();
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Test exporting a Places canonical json file.
|
||||
// 1. export to bookmarks.exported.json
|
||||
|
@ -73,7 +73,7 @@ function run_test() {
|
|||
yield validate();
|
||||
LOG("validated import");
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -21,14 +21,14 @@ add_task(function changeuri_unvisited_bookmark()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id, uri("http://example.com/2"));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
|
||||
do_check_eq(frecencyForUrl(TEST_URI), 0);
|
||||
|
@ -47,18 +47,18 @@ add_task(function changeuri_visited_bookmark()
|
|||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
yield promiseAddVisits(TEST_URI);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id, uri("http://example.com/2"));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
@ -82,14 +82,14 @@ add_task(function changeuri_bookmark_still_bookmarked()
|
|||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark 2 title");
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.changeBookmarkURI(id1, uri("http://example.com/2"));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI still bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
|
|
@ -40,7 +40,7 @@ add_test(function test_keywordRemovedOnUniqueItemRemoval() {
|
|||
// remove bookmark
|
||||
bmsvc.removeItem(bookmarkId);
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
// Check that keyword has been removed from the database.
|
||||
// The removal is asynchronous.
|
||||
var sql = "SELECT id FROM moz_keywords WHERE keyword = ?1";
|
||||
|
@ -77,7 +77,7 @@ add_test(function test_keywordNotRemovedOnNonUniqueItemRemoval() {
|
|||
// remove first bookmark
|
||||
bmsvc.removeItem(bookmarkId1);
|
||||
|
||||
promiseAsyncUpdates().then(function() {
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
// check that keyword is still there
|
||||
var sql = "SELECT id FROM moz_keywords WHERE keyword = ?1";
|
||||
var stmt = mDBConn.createStatement(sql);
|
||||
|
|
|
@ -388,7 +388,7 @@ add_task(function* test_non_addable_uri_errors() {
|
|||
do_check_eq(place.resultCode, Cr.NS_ERROR_INVALID_ARG);
|
||||
do_check_false(yield promiseIsURIVisited(place.info.uri));
|
||||
}
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_duplicate_guid_errors() {
|
||||
|
@ -426,7 +426,7 @@ add_task(function* test_duplicate_guid_errors() {
|
|||
do_check_eq(badPlaceInfo.resultCode, Cr.NS_ERROR_STORAGE_CONSTRAINT);
|
||||
do_check_false(yield promiseIsURIVisited(badPlaceInfo.info.uri));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_invalid_referrerURI_ignored() {
|
||||
|
@ -462,7 +462,7 @@ add_task(function* test_invalid_referrerURI_ignored() {
|
|||
do_check_eq(stmt.row.from_visit, 0);
|
||||
stmt.finalize();
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_nonnsIURI_referrerURI_ignored() {
|
||||
|
@ -494,7 +494,7 @@ add_task(function* test_nonnsIURI_referrerURI_ignored() {
|
|||
do_check_eq(stmt.row.from_visit, 0);
|
||||
stmt.finalize();
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_old_referrer_ignored() {
|
||||
|
@ -553,7 +553,7 @@ add_task(function* test_old_referrer_ignored() {
|
|||
do_check_eq(stmt.row.count, 1);
|
||||
stmt.finalize();
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_place_id_ignored() {
|
||||
|
@ -593,7 +593,7 @@ add_task(function* test_place_id_ignored() {
|
|||
do_check_neq(placeInfo.placeId, placeId);
|
||||
do_check_true(yield promiseIsURIVisited(badPlace.uri));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_handleCompletion_called_when_complete() {
|
||||
|
@ -634,7 +634,7 @@ add_task(function* test_handleCompletion_called_when_complete() {
|
|||
|
||||
do_check_eq(callbackCountSuccess, EXPECTED_COUNT_SUCCESS);
|
||||
do_check_eq(callbackCountFailure, EXPECTED_COUNT_FAILURE);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_add_visit() {
|
||||
|
@ -695,7 +695,7 @@ add_task(function* test_add_visit() {
|
|||
|
||||
// If we have had all of our callbacks, continue running tests.
|
||||
if (++callbackCount == place.visits.length) {
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -778,7 +778,7 @@ add_task(function* test_properties_saved() {
|
|||
|
||||
// If we have had all of our callbacks, continue running tests.
|
||||
if (++callbackCount == places.length) {
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -803,7 +803,7 @@ add_task(function* test_guid_saved() {
|
|||
do_check_true(yield promiseIsURIVisited(uri));
|
||||
do_check_eq(placeInfo.guid, place.guid);
|
||||
do_check_guid_for_uri(uri, place.guid);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_referrer_saved() {
|
||||
|
@ -853,7 +853,7 @@ add_task(function* test_referrer_saved() {
|
|||
do_check_eq(stmt.row.count, 1);
|
||||
stmt.finalize();
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -881,7 +881,7 @@ add_task(function* test_guid_change_saved() {
|
|||
}
|
||||
do_check_guid_for_uri(place.uri, place.guid);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_title_change_saved() {
|
||||
|
@ -927,7 +927,7 @@ add_task(function* test_title_change_saved() {
|
|||
}
|
||||
do_check_title_for_uri(place.uri, place.title);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_no_title_does_not_clear_title() {
|
||||
|
@ -955,7 +955,7 @@ add_task(function* test_no_title_does_not_clear_title() {
|
|||
}
|
||||
do_check_title_for_uri(place.uri, TITLE);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_title_change_notifies() {
|
||||
|
@ -1011,7 +1011,7 @@ add_task(function* test_title_change_notifies() {
|
|||
}
|
||||
|
||||
yield promiseTitleChangedObserver(place);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function* test_visit_notifies() {
|
||||
|
@ -1059,7 +1059,7 @@ add_task(function* test_visit_notifies() {
|
|||
}
|
||||
|
||||
yield promiseVisitObserver(place);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
// test with empty mozIVisitInfoCallback object
|
||||
|
@ -1089,7 +1089,7 @@ add_task(function* test_callbacks_not_supplied() {
|
|||
});
|
||||
|
||||
PlacesUtils.asyncHistory.updatePlaces(places, {});
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
// Test that we don't wrongly overwrite typed and hidden when adding new visits.
|
||||
|
|
|
@ -99,11 +99,11 @@ add_task(function* setup() {
|
|||
// 2. run the test-suite
|
||||
// Note: we do not empty the db before this import to catch bugs like 380999
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileOld, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
remove_all_bookmarks();
|
||||
});
|
||||
|
||||
|
@ -113,10 +113,10 @@ add_task(function* test_import_new()
|
|||
// 1. import bookmarks.exported.html
|
||||
// 2. run the test-suite
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
yield testImportedBookmarks();
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
remove_all_bookmarks();
|
||||
});
|
||||
|
@ -135,7 +135,7 @@ add_task(function* test_emptytitle_export()
|
|||
// 9. empty bookmarks db and continue
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
const NOTITLE_URL = "http://notitle.mozilla.org/";
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
|
@ -145,11 +145,11 @@ add_task(function* test_emptytitle_export()
|
|||
test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL });
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
remove_all_bookmarks();
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
|
@ -157,7 +157,7 @@ add_task(function* test_emptytitle_export()
|
|||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
remove_all_bookmarks();
|
||||
});
|
||||
|
||||
|
@ -179,7 +179,7 @@ add_task(function* test_import_chromefavicon()
|
|||
const CHROME_FAVICON_URI_2 = NetUtil.newURI("chrome://global/skin/icons/error-16.png");
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
PAGE_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
|
@ -204,7 +204,7 @@ add_task(function* test_import_chromefavicon()
|
|||
{ title: "Test", url: PAGE_URI.spec, icon: base64Icon });
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Change the favicon to check it's really imported again later.
|
||||
deferred = Promise.defer();
|
||||
|
@ -217,7 +217,7 @@ add_task(function* test_import_chromefavicon()
|
|||
remove_all_bookmarks();
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
|
||||
// Cleanup.
|
||||
|
@ -225,7 +225,7 @@ add_task(function* test_import_chromefavicon()
|
|||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
remove_all_bookmarks();
|
||||
});
|
||||
|
||||
|
@ -240,14 +240,14 @@ add_task(function* test_import_ontop()
|
|||
// 4. run the test-suite
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
remove_all_bookmarks();
|
||||
});
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ add_task(function test_import_bookmarks() {
|
|||
let bookmarksFile = OS.Path.join(do_get_cwd().path, "bookmarks.json");
|
||||
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksFile, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
|
@ -86,24 +86,24 @@ add_task(function test_export_bookmarks() {
|
|||
bookmarksExportedFile = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"bookmarks.exported.json");
|
||||
yield BookmarkJSONUtils.exportToFile(bookmarksExportedFile);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
});
|
||||
|
||||
add_task(function test_import_exported_bookmarks() {
|
||||
remove_all_bookmarks();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
add_task(function test_import_ontop() {
|
||||
remove_all_bookmarks();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkJSONUtils.exportToFile(bookmarksExportedFile);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield BookmarkJSONUtils.importFromFile(bookmarksExportedFile, true);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
yield testImportedBookmarks();
|
||||
});
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ AutoCompleteInput.prototype = {
|
|||
|
||||
function ensure_results(uris, searchTerm)
|
||||
{
|
||||
promiseAsyncUpdates().then(function () ensure_results_internal(uris,
|
||||
searchTerm));
|
||||
PlacesTestUtils.promiseAsyncUpdates()
|
||||
.then(() => ensure_results_internal(uris, searchTerm));
|
||||
}
|
||||
|
||||
function ensure_results_internal(uris, searchTerm)
|
||||
|
|
|
@ -15,13 +15,13 @@ add_task(function ()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"A title");
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
||||
// Removing the bookmark should leave an orphan page with zero frecency.
|
||||
// Note this would usually be expired later by expiration.
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_check_eq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
// Now add a valid visit to the page, frecency should increase.
|
||||
|
|
|
@ -91,7 +91,7 @@ add_task(function* test_history_clear()
|
|||
{ uri: uri("http://frecency.mozilla.org/"),
|
||||
transition: TRANSITION_LINK },
|
||||
]);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Clear history and wait for the onClearHistory notification.
|
||||
let promiseWaitClearHistory = promiseOnClearHistoryObserved();
|
||||
|
@ -102,7 +102,7 @@ add_task(function* test_history_clear()
|
|||
do_check_eq(0, PlacesUtils.history.hasHistoryEntries);
|
||||
|
||||
yield promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Check that frecency for not cleared items (bookmarks) has been converted
|
||||
// to -MAX(visit_count, 1), so we will be able to recalculate frecency
|
||||
|
|
|
@ -151,7 +151,7 @@ add_test(function check_history_query() {
|
|||
do_check_eq(resultObserver.closedContainer, resultObserver.openedContainer);
|
||||
result.removeObserver(resultObserver);
|
||||
resultObserver.reset();
|
||||
promiseAsyncUpdates().then(run_next_test);
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -219,7 +219,7 @@ add_test(function check_bookmarks_query() {
|
|||
do_check_eq(resultObserver.closedContainer, resultObserver.openedContainer);
|
||||
result.removeObserver(resultObserver);
|
||||
resultObserver.reset();
|
||||
promiseAsyncUpdates().then(run_next_test);
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(run_next_test);
|
||||
});
|
||||
|
||||
add_test(function check_mixed_query() {
|
||||
|
@ -252,5 +252,5 @@ add_test(function check_mixed_query() {
|
|||
do_check_eq(resultObserver.closedContainer, resultObserver.openedContainer);
|
||||
result.removeObserver(resultObserver);
|
||||
resultObserver.reset();
|
||||
promiseAsyncUpdates().then(run_next_test);
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(run_next_test);
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ add_task(function remove_visits_outside_unbookmarked_uri() {
|
|||
|
||||
do_print("Remove visits using timerange outside the URI's visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
@ -49,7 +49,7 @@ add_task(function remove_visits_outside_unbookmarked_uri() {
|
|||
do_print("asyncHistory.isURIVisited should return true.");
|
||||
do_check_true(yield promiseIsURIVisited(TEST_URI));
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
do_print("Frecency should be positive.")
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
||||
|
@ -70,11 +70,11 @@ add_task(function remove_visits_outside_bookmarked_uri() {
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Remove visits using timerange outside the URI's visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
@ -95,7 +95,7 @@ add_task(function remove_visits_outside_bookmarked_uri() {
|
|||
|
||||
do_print("asyncHistory.isURIVisited should return true.");
|
||||
do_check_true(yield promiseIsURIVisited(TEST_URI));
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Frecency should be positive.")
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
@ -115,7 +115,7 @@ add_task(function remove_visits_unbookmarked_uri() {
|
|||
|
||||
do_print("Remove the 5 most recent visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 4, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
@ -136,7 +136,7 @@ add_task(function remove_visits_unbookmarked_uri() {
|
|||
|
||||
do_print("asyncHistory.isURIVisited should return true.");
|
||||
do_check_true(yield promiseIsURIVisited(TEST_URI));
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Frecency should be positive.")
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
@ -158,11 +158,11 @@ add_task(function remove_visits_bookmarked_uri() {
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Remove the 5 most recent visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 4, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
@ -183,7 +183,7 @@ add_task(function remove_visits_bookmarked_uri() {
|
|||
|
||||
do_print("asyncHistory.isURIVisited should return true.");
|
||||
do_check_true(yield promiseIsURIVisited(TEST_URI));
|
||||
yield promiseAsyncUpdates()
|
||||
yield PlacesTestUtils.promiseAsyncUpdates()
|
||||
|
||||
do_print("Frecency should be positive.")
|
||||
do_check_true(frecencyForUrl(TEST_URI) > 0);
|
||||
|
@ -203,7 +203,7 @@ add_task(function remove_all_visits_unbookmarked_uri() {
|
|||
|
||||
do_print("Remove all visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should no longer exist in moz_places.");
|
||||
do_check_false(page_in_database(TEST_URI.spec));
|
||||
|
@ -235,7 +235,7 @@ add_task(function remove_all_visits_unbookmarked_place_uri() {
|
|||
|
||||
do_print("Remove all visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(PLACE_URI.spec));
|
||||
|
@ -252,7 +252,7 @@ add_task(function remove_all_visits_unbookmarked_place_uri() {
|
|||
|
||||
do_print("asyncHistory.isURIVisited should return false.");
|
||||
do_check_false(yield promiseIsURIVisited(PLACE_URI));
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Frecency should be zero.")
|
||||
do_check_eq(frecencyForUrl(PLACE_URI.spec), 0);
|
||||
|
@ -274,11 +274,11 @@ add_task(function remove_all_visits_bookmarked_uri() {
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Remove all visits.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
@ -298,7 +298,7 @@ add_task(function remove_all_visits_bookmarked_uri() {
|
|||
|
||||
do_print("nsINavBookmarksService.isBookmarked should return true.");
|
||||
do_check_true(PlacesUtils.bookmarks.isBookmarked(TEST_URI));
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("Frecency should be negative.")
|
||||
do_check_true(frecencyForUrl(TEST_URI) < 0);
|
||||
|
@ -317,7 +317,7 @@ add_task(function remove_all_visits_bookmarked_uri() {
|
|||
|
||||
do_print("Remove newer visit.");
|
||||
PlacesUtils.history.removeVisitsByTimeframe(NOW - 10, NOW);
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
do_print("URI should still exist in moz_places.");
|
||||
do_check_true(page_in_database(TEST_URI.spec));
|
||||
|
|
|
@ -59,7 +59,7 @@ add_task(function test_execute()
|
|||
.getService(Ci.nsIObserver)
|
||||
.observe(null, "gather-telemetry", null);
|
||||
|
||||
yield promiseAsyncUpdates();
|
||||
yield PlacesTestUtils.promiseAsyncUpdates();
|
||||
|
||||
// Test expiration probes.
|
||||
for (let i = 0; i < 2; i++) {
|
||||
|
|
|
@ -21,15 +21,13 @@ add_test(function removed_bookmark()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Unvisited URI no longer bookmarked => frecency should = 0");
|
||||
do_check_eq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
|
@ -48,16 +46,14 @@ add_test(function removed_but_visited_bookmark()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
promiseAddVisits(TEST_URI).then(function () {
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
|
@ -81,15 +77,13 @@ add_test(function remove_bookmark_still_bookmarked()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark 2 title");
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.removeItem(id1);
|
||||
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("URI still bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
|
@ -108,16 +102,14 @@ add_test(function cleared_parent_of_visited_bookmark()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark title");
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
promiseAddVisits(TEST_URI).then(function () {
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("*Visited* URI no longer bookmarked => frecency should != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
|
@ -143,15 +135,13 @@ add_test(function cleared_parent_of_bookmark_still_bookmarked()
|
|||
TEST_URI,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"bookmark 2 title");
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
do_print("Bookmarked => frecency of URI should be != 0");
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
|
||||
promiseAsyncUpdates().then(function ()
|
||||
{
|
||||
PlacesTestUtils.promiseAsyncUpdates().then(() => {
|
||||
// URI still bookmarked => frecency should != 0.
|
||||
do_check_neq(frecencyForUrl(TEST_URI), 0);
|
||||
|
||||
|
|
|
@ -28,9 +28,11 @@ function closeWindow(aClose, aPromptFunction)
|
|||
if (typeof(aPromptFunction) == "function" && !aPromptFunction())
|
||||
return false;
|
||||
|
||||
if (aClose)
|
||||
if (aClose) {
|
||||
window.close();
|
||||
|
||||
return window.closed;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@
|
|||
}
|
||||
|
||||
#header-utils-btn {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.png");
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities");
|
||||
-moz-margin-end: 18px;
|
||||
}
|
||||
|
||||
|
|
Двоичные данные
toolkit/themes/osx/mozapps/extensions/utilities.png
Двоичные данные
toolkit/themes/osx/mozapps/extensions/utilities.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 3.4 KiB |
|
@ -32,7 +32,7 @@ toolkit.jar:
|
|||
skin/classic/mozapps/extensions/rating-won.png (extensions/rating-won.png)
|
||||
skin/classic/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png)
|
||||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/utilities.svg (../../shared/extensions/utilities.svg)
|
||||
skin/classic/mozapps/extensions/toolbarbutton-dropmarker.png (extensions/toolbarbutton-dropmarker.png)
|
||||
skin/classic/mozapps/extensions/heart.png (extensions/heart.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0"
|
||||
y="0"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16">
|
||||
<style>
|
||||
use:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
use {
|
||||
fill: #424f5a;
|
||||
}
|
||||
use[id$="-native"] {
|
||||
fill: GrayText;
|
||||
}
|
||||
</style>
|
||||
<defs style="display: none;">
|
||||
<path id="utilities-shape" d="m11.5,13.9l-.6-1.5c.3-.2 .5-.4 .8-.6 .2-.2 .4-.5 .6-.7l1.5,.6c.3,.1 .6,0 .7-.3l.4-1c.1-.3 0-.6-.3-.7l-1.5-.6c.1-.6 .1-1.3 0-2l1.5-.6c.3-.1 .4-.4 .3-.7l-.4-1c-.1-.3-.4-.4-.7-.3l-1.5,.6c-.2-.3-.4-.5-.6-.8-.2-.1-.5-.3-.7-.5l.6-1.5c.1-.3 0-.6-.3-.7l-.9-.4c-.3-.1-.6,0-.7,.3l-.6,1.5c-.6-.1-1.3-.1-2,0l-.6-1.5c-.1-.3-.4-.4-.7-.3l-1,.4c-.2,.1-.3,.4-.2,.6l.6,1.5c-.3,.3-.5,.5-.8,.7-.2,.3-.4,.5-.6,.8l-1.5-.7c-.3-.1-.6,0-.7,.3l-.4,.9c-.1,.3 0,.6 .3,.7l1.5,.7c-.1,.6-.1,1.3 0,1.9l-1.5,.6c-.3,.1-.4,.4-.3,.7l.4,1c.1,.3 .4,.4 .7,.3l1.5-.6c.2,.3 .4,.5 .6,.8 .2,.2 .5,.4 .7,.6l-.6,1.5c-.1,.3 0,.6 .3,.7l1,.4c.3,.1 .6,0 .7-.3l.6-1.5c.6,.1 1.3,.1 2,0l.6,1.5c.1,.3 .4,.4 .7,.3l1-.4c.1-.1 .3-.4 .1-.7zm-5.1-4.2c-.9-.9-.9-2.4 0-3.3 .9-.9 2.4-.9 3.3,0 .9,.9 .9,2.4 0,3.3-.9,.9-2.4,.9-3.3,0z"/>
|
||||
</defs>
|
||||
<use id="utilities" xlink:href="#utilities-shape"/>
|
||||
<use id="utilities-native" xlink:href="#utilities-shape"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -332,10 +332,16 @@
|
|||
}
|
||||
|
||||
#header-utils-btn {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.png");
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities");
|
||||
-moz-margin-end: 16px;
|
||||
}
|
||||
|
||||
@media not all and (-moz-windows-default-theme) {
|
||||
#header-utils-btn {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities-native");
|
||||
}
|
||||
}
|
||||
|
||||
.view-header {
|
||||
background-color: rgba(251, 252, 253, 0.25);
|
||||
padding: 4px;
|
||||
|
|
Двоичные данные
toolkit/themes/windows/mozapps/extensions/utilities.png
Двоичные данные
toolkit/themes/windows/mozapps/extensions/utilities.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 848 B |
|
@ -40,7 +40,7 @@ toolkit.jar:
|
|||
skin/classic/mozapps/extensions/rating-won.png (extensions/rating-won.png)
|
||||
skin/classic/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png)
|
||||
skin/classic/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/mozapps/extensions/utilities.svg (../../shared/extensions/utilities.svg)
|
||||
skin/classic/mozapps/extensions/heart.png (extensions/heart.png)
|
||||
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/mozapps/extensions/stripes-warning.png (extensions/stripes-warning.png)
|
||||
|
@ -122,7 +122,7 @@ toolkit.jar:
|
|||
skin/classic/aero/mozapps/extensions/rating-won.png (extensions/rating-won.png)
|
||||
skin/classic/aero/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png)
|
||||
skin/classic/aero/mozapps/extensions/cancel.png (extensions/cancel.png)
|
||||
skin/classic/aero/mozapps/extensions/utilities.png (extensions/utilities.png)
|
||||
skin/classic/aero/mozapps/extensions/utilities.svg (../../shared/extensions/utilities.svg)
|
||||
skin/classic/aero/mozapps/extensions/heart.png (extensions/heart.png)
|
||||
skin/classic/aero/mozapps/extensions/navigation.png (extensions/navigation.png)
|
||||
skin/classic/aero/mozapps/extensions/stripes-warning.png (extensions/stripes-warning.png)
|
||||
|
|
|
@ -1705,88 +1705,86 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
|
|||
}
|
||||
|
||||
static float
|
||||
GetScaleFactor(nsPresContext* mPresContext) {
|
||||
nsIPresShell* presShell = mPresContext->PresShell();
|
||||
LayoutDeviceToLayerScale cumulativeResolution(presShell->GetCumulativeResolution().width);
|
||||
return cumulativeResolution.scale;
|
||||
GetScaleFactor(nsPresContext* aPresContext) {
|
||||
nsIPresShell* presShell = aPresContext->PresShell();
|
||||
LayoutDeviceToLayerScale cumulativeResolution(presShell->GetCumulativeResolution().width);
|
||||
return cumulativeResolution.scale;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AndroidBridge::CaptureZoomedView (nsIDOMWindow *window, nsIntRect zoomedViewRect, Object::Param buffer,
|
||||
AndroidBridge::CaptureZoomedView(nsIDOMWindow *window, nsIntRect zoomedViewRect, Object::Param buffer,
|
||||
float zoomFactor) {
|
||||
nsresult rv;
|
||||
struct timeval timeStart;
|
||||
gettimeofday (&timeStart, NULL);
|
||||
nsresult rv;
|
||||
|
||||
if (!buffer)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!buffer)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr < nsIDOMWindowUtils > utils = do_GetInterface (window);
|
||||
if (!utils)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr <nsIDOMWindowUtils> utils = do_GetInterface(window);
|
||||
if (!utils)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
JNIEnv* env = GetJNIEnv ();
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame (env, 0);
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
nsCOMPtr < nsPIDOMWindow > win = do_QueryInterface (window);
|
||||
if (!win) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr < nsPresContext > presContext;
|
||||
nsCOMPtr <nsPIDOMWindow> win = do_QueryInterface(window);
|
||||
if (!win) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr <nsPresContext> presContext;
|
||||
|
||||
nsIDocShell* docshell = win->GetDocShell ();
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
|
||||
if (docshell) {
|
||||
docshell->GetPresContext (getter_AddRefs (presContext));
|
||||
}
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
|
||||
if (!presContext) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr < nsIPresShell > presShell = presContext->PresShell ();
|
||||
if (!presContext) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr <nsIPresShell> presShell = presContext->PresShell();
|
||||
|
||||
float scaleFactor = GetScaleFactor(presContext) ;
|
||||
float scaleFactor = GetScaleFactor(presContext) ;
|
||||
|
||||
nscolor bgColor = NS_RGB (255, 255, 255);
|
||||
uint32_t renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING | nsIPresShell::RENDER_DOCUMENT_RELATIVE);
|
||||
nsRect r (presContext->DevPixelsToAppUnits(zoomedViewRect.x / scaleFactor),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.y / scaleFactor ),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.width / scaleFactor ),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.height / scaleFactor ));
|
||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||
uint32_t renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING | nsIPresShell::RENDER_DOCUMENT_RELATIVE);
|
||||
nsRect r(presContext->DevPixelsToAppUnits(zoomedViewRect.x / scaleFactor),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.y / scaleFactor ),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.width / scaleFactor ),
|
||||
presContext->DevPixelsToAppUnits(zoomedViewRect.height / scaleFactor ));
|
||||
|
||||
bool is24bit = (GetScreenDepth () == 24);
|
||||
SurfaceFormat format = is24bit ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::R5G6B5;
|
||||
gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format);
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(iFormat, zoomedViewRect.width);
|
||||
bool is24bit = (GetScreenDepth() == 24);
|
||||
SurfaceFormat format = is24bit ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::R5G6B5;
|
||||
gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format);
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(iFormat, zoomedViewRect.width);
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*> (env->GetDirectBufferAddress (buffer.Get()));
|
||||
if (!data) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
uint8_t* data = static_cast<uint8_t*> (env->GetDirectBufferAddress(buffer.Get()));
|
||||
if (!data) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT (gfxPlatform::GetPlatform ()->SupportsAzureContentForType (BackendType::CAIRO),
|
||||
MOZ_ASSERT (gfxPlatform::GetPlatform()->SupportsAzureContentForType(BackendType::CAIRO),
|
||||
"Need BackendType::CAIRO support");
|
||||
RefPtr < DrawTarget > dt = Factory::CreateDrawTargetForData (
|
||||
BackendType::CAIRO, data, IntSize (zoomedViewRect.width, zoomedViewRect.height), stride,
|
||||
format);
|
||||
if (!dt) {
|
||||
ALOG_BRIDGE ("Error creating DrawTarget");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr < gfxContext > context = new gfxContext (dt);
|
||||
context->SetMatrix (context->CurrentMatrix ().Scale(zoomFactor, zoomFactor));
|
||||
RefPtr < DrawTarget > dt = Factory::CreateDrawTargetForData(
|
||||
BackendType::CAIRO, data, IntSize(zoomedViewRect.width, zoomedViewRect.height), stride,
|
||||
format);
|
||||
if (!dt) {
|
||||
ALOG_BRIDGE("Error creating DrawTarget");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsRefPtr <gfxContext> context = new gfxContext(dt);
|
||||
context->SetMatrix(context->CurrentMatrix().Scale(zoomFactor, zoomFactor));
|
||||
|
||||
rv = presShell->RenderDocument (r, renderDocFlags, bgColor, context);
|
||||
rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
|
||||
|
||||
if (is24bit) {
|
||||
gfxUtils::ConvertBGRAtoRGBA (data, stride * zoomedViewRect.height);
|
||||
}
|
||||
if (is24bit) {
|
||||
gfxUtils::ConvertBGRAtoRGBA(data, stride * zoomedViewRect.height);
|
||||
}
|
||||
|
||||
LayerView::updateZoomedView(buffer);
|
||||
LayerView::updateZoomedView(buffer);
|
||||
|
||||
NS_ENSURE_SUCCESS (rv, rv);
|
||||
return NS_OK;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, Object::Param buffer, bool &shouldStore)
|
||||
|
|
Загрузка…
Ссылка в новой задаче