mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team
This commit is contained in:
commit
de4073d036
@ -32,7 +32,7 @@ const AUDIO_FILTERS = ['audio/basic', 'audio/L24', 'audio/mp4',
|
||||
'audio/webm'];
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, 'cpmm',
|
||||
'@mozilla.org/childprocessmessagemanager;1',
|
||||
@ -191,10 +191,8 @@ FilePicker.prototype = {
|
||||
|
||||
// Let's try to remove the full path and take just the filename.
|
||||
if (name) {
|
||||
let file = new FileUtils.File(data.result.blob.name);
|
||||
if (file && file.leafName) {
|
||||
name = file.leafName;
|
||||
}
|
||||
let names = OS.Path.split(name);
|
||||
name = names.components[names.components.length - 1];
|
||||
}
|
||||
|
||||
// the fallback is a filename composed by 'blob' + extension.
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* 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/. */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// use ppmm to handle file-picker message.
|
||||
let ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1']
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
|
||||
let pickResult = null;
|
||||
|
||||
function processPickMessage(message) {
|
||||
let sender = message.target.QueryInterface(Ci.nsIMessageSender);
|
||||
// reply FilePicker's message
|
||||
sender.sendAsyncMessage('file-picked', pickResult);
|
||||
// notify caller
|
||||
sendAsyncMessage('file-picked-posted', { type: 'file-picked-posted' });
|
||||
}
|
||||
|
||||
function updatePickResult(result) {
|
||||
pickResult = result;
|
||||
sendAsyncMessage('pick-result-updated', { type: 'pick-result-updated' });
|
||||
}
|
||||
|
||||
ppmm.addMessageListener('file-picker', processPickMessage);
|
||||
// use update-pick-result to change the expected pick result.
|
||||
addMessageListener('update-pick-result', updatePickResult);
|
@ -3,5 +3,7 @@ run-if = toolkit == "gonk"
|
||||
support-files =
|
||||
permission_handler_chrome.js
|
||||
SandboxPromptTest.html
|
||||
filepicker_path_handler_chrome.js
|
||||
|
||||
[test_sandbox_permission.html]
|
||||
[test_filepicker_path.html]
|
||||
|
135
b2g/components/test/mochitest/test_filepicker_path.html
Normal file
135
b2g/components/test/mochitest/test_filepicker_path.html
Normal file
@ -0,0 +1,135 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=949944
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Permission Prompt Test</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body onload="processTestCase()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=949944"> [B2G][Helix][Browser][Wallpaper] use new File([blob], filename) to return a blob with filename when picking</a>
|
||||
<script type="application/javascript">
|
||||
|
||||
'use strict';
|
||||
|
||||
var testCases = [
|
||||
// case 1: returns blob with name
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new Blob(['1234567890'],
|
||||
{ type: 'text/plain' }),
|
||||
name: 'test1.txt'
|
||||
}
|
||||
},
|
||||
fileName: 'test1.txt' },
|
||||
// case 2: returns blob without name
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new Blob(['1234567890'],
|
||||
{ type: 'text/plain' })
|
||||
}
|
||||
},
|
||||
fileName: 'blob.txt' },
|
||||
// case 3: returns blob with full path name
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new Blob(['1234567890'],
|
||||
{ type: 'text/plain' }),
|
||||
name: '/full/path/test3.txt'
|
||||
}
|
||||
},
|
||||
fileName: 'test3.txt' },
|
||||
// case 4: returns blob relative path name
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new Blob(['1234567890'],
|
||||
{ type: 'text/plain' }),
|
||||
name: 'relative/path/test4.txt'
|
||||
}
|
||||
},
|
||||
fileName: 'test4.txt' },
|
||||
// case 5: returns file with name
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new File(['1234567890'],
|
||||
'useless-name.txt',
|
||||
{ type: 'text/plain' }),
|
||||
name: 'test5.txt'
|
||||
}
|
||||
},
|
||||
fileName: 'test5.txt'},
|
||||
// case 6: returns file without name. This case may fail because we
|
||||
// need to make sure the DOMFile can be sent through
|
||||
// sendAsyncMessage API.
|
||||
{ pickedResult: { success: true,
|
||||
result: {
|
||||
type: 'text/plain',
|
||||
blob: new File(['1234567890'],
|
||||
'test6.txt',
|
||||
{ type: 'text/plain' })
|
||||
}
|
||||
},
|
||||
todo: true,
|
||||
fileName: 'test6.txt'}
|
||||
];
|
||||
|
||||
var chromeJS = SimpleTest.getTestFileURL('filepicker_path_handler_chrome.js');
|
||||
var chromeScript = SpecialPowers.loadChromeScript(chromeJS);
|
||||
var activeTestCase;
|
||||
|
||||
chromeScript.addMessageListener('pick-result-updated', handleMessage);
|
||||
chromeScript.addMessageListener('file-picked-posted', handleMessage);
|
||||
|
||||
// handle messages returned from chromeScript
|
||||
function handleMessage(data) {
|
||||
var fileInput = document.getElementById('fileInput');
|
||||
switch (data.type) {
|
||||
case 'pick-result-updated':
|
||||
fileInput.click();
|
||||
break;
|
||||
case 'file-picked-posted':
|
||||
if (activeTestCase.todo) {
|
||||
todo_is(fileInput.value, activeTestCase.fileName,
|
||||
'DOMFile should be able to send through message.');
|
||||
} else {
|
||||
is(fileInput.value, activeTestCase.fileName);
|
||||
}
|
||||
processTestCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function processTestCase() {
|
||||
if (!testCases.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
activeTestCase = testCases.shift();
|
||||
var expectedResult = activeTestCase.pickedResult;
|
||||
if (navigator.userAgent.indexOf('Windows') > -1 &&
|
||||
expectedResult.result.name) {
|
||||
// If we run at a window box, we need to translate the path from '/' to '\\'
|
||||
var name = expectedResult.result.name;
|
||||
name = name.replace('/', '\\');
|
||||
// If the name is an absolute path, we need to prepend drive letter.
|
||||
if (name.startsWith('\\')) {
|
||||
name = 'C:' + name;
|
||||
}
|
||||
// update the expected name.
|
||||
expectedResult.result.name = name
|
||||
}
|
||||
chromeScript.sendAsyncMessage('update-pick-result', expectedResult);
|
||||
}
|
||||
|
||||
</script>
|
||||
<input type="file" id="fileInput">
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "6e971c6a9f947d301a0401fcbc87141b8eba23b6",
|
||||
"revision": "f1f4304e9f2fe7bcf79b1e6ead334706c119ac4a",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -790,7 +790,7 @@ pref("browser.safebrowsing.enabled", true);
|
||||
pref("browser.safebrowsing.malware.enabled", true);
|
||||
pref("browser.safebrowsing.debug", false);
|
||||
|
||||
pref("browser.safebrowsing.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&apikey=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
|
||||
pref("browser.safebrowsing.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
|
||||
pref("browser.safebrowsing.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
|
||||
@ -802,7 +802,7 @@ pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-erro
|
||||
|
||||
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
#ifndef MOZILLA_OFFICIAL
|
||||
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download&apikey=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.appRepURL", "https://sb-ssl.google.com/safebrowsing/clientreport/download&key=%GOOGLE_API_KEY%");
|
||||
#endif
|
||||
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
|
@ -541,6 +541,14 @@
|
||||
@BINPATH@/components/Push.js
|
||||
@BINPATH@/components/Push.manifest
|
||||
@BINPATH@/components/PushServiceLauncher.js
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
@BINPATH@/components/InterAppComm.manifest
|
||||
@BINPATH@/components/InterAppCommService.js
|
||||
@BINPATH@/components/InterAppConnection.js
|
||||
@BINPATH@/components/InterAppMessagePort.js
|
||||
#endif
|
||||
|
||||
@BINPATH@/components/TCPSocket.js
|
||||
@BINPATH@/components/TCPServerSocket.js
|
||||
@BINPATH@/components/TCPSocketParentIntermediary.js
|
||||
|
@ -11,7 +11,7 @@ interface nsIChannel;
|
||||
interface nsIDocShell;
|
||||
interface nsIDomainPolicy;
|
||||
|
||||
[scriptable, uuid(2911ae60-1b5f-47e6-941e-1bb7b53a167d)]
|
||||
[scriptable, uuid(712aa338-50a1-497b-be6f-dc3d97867c01)]
|
||||
interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
{
|
||||
///////////////// Security Checks //////////////////
|
||||
@ -160,12 +160,10 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
*/
|
||||
[deprecated] nsIPrincipal getCodebasePrincipal(in nsIURI uri);
|
||||
|
||||
///////////////////////
|
||||
/**
|
||||
* Return the principal of the specified object in the specified context.
|
||||
*/
|
||||
[noscript] nsIPrincipal getObjectPrincipal(in JSContextPtr cx,
|
||||
in JSObjectPtr obj);
|
||||
[implicit_jscontext] nsIPrincipal getObjectPrincipal(in jsval aObject);
|
||||
|
||||
/**
|
||||
* Returns true if the principal of the currently running script is the
|
||||
|
@ -1487,14 +1487,14 @@ nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
|
||||
nsScriptSecurityManager::GetObjectPrincipal(const JS::Value &aObjectVal,
|
||||
JSContext *aCx,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(aCx, aObj);
|
||||
*result = doGetObjectPrincipal(obj);
|
||||
if (!*result)
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ADDREF(*result);
|
||||
NS_ENSURE_TRUE(aObjectVal.isObject(), NS_ERROR_FAILURE);
|
||||
JS::RootedObject obj(aCx, &aObjectVal.toObject());
|
||||
nsCOMPtr<nsIPrincipal> principal = doGetObjectPrincipal(obj);
|
||||
principal.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
16
configure.in
16
configure.in
@ -4051,6 +4051,7 @@ MOZ_USE_NATIVE_POPUP_WINDOWS=
|
||||
MOZ_ANDROID_HISTORY=
|
||||
MOZ_WEBSMS_BACKEND=
|
||||
MOZ_ANDROID_BEAM=
|
||||
MOZ_ANDROID_SYNTHAPKS=
|
||||
ACCESSIBILITY=1
|
||||
MOZ_TIME_MANAGER=
|
||||
MOZ_PAY=
|
||||
@ -5011,6 +5012,18 @@ if test -n "$MOZ_ANDROID_BEAM"; then
|
||||
AC_DEFINE(MOZ_ANDROID_BEAM)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Synthesized Webapp APKs on Android
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(android-synthapks,
|
||||
[ --enable-android-synthapks Enable synthesized APKs],
|
||||
MOZ_ANDROID_SYNTHAPKS=1,
|
||||
MOZ_ANDROID_SYNTHAPKS=)
|
||||
|
||||
if test -n "$MOZ_ANDROID_SYNTHAPKS"; then
|
||||
AC_DEFINE(MOZ_ANDROID_SYNTHAPKS)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = JS Debugger XPCOM component (js/jsd)
|
||||
dnl ========================================================
|
||||
@ -7766,7 +7779,7 @@ dnl ========================================================
|
||||
|
||||
if test -z "$SKIP_PATH_CHECKS"; then
|
||||
if test -z "${GLIB_CFLAGS}" -o -z "${GLIB_LIBS}" ; then
|
||||
if test "$MOZ_ENABLE_GTK2" ; then
|
||||
if test "$MOZ_ENABLE_GTK" ; then
|
||||
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 1.3.7 gobject-2.0)
|
||||
fi
|
||||
fi
|
||||
@ -8328,6 +8341,7 @@ AC_SUBST(MOZ_METRO)
|
||||
AC_SUBST(MOZ_ANDROID_HISTORY)
|
||||
AC_SUBST(MOZ_WEBSMS_BACKEND)
|
||||
AC_SUBST(MOZ_ANDROID_BEAM)
|
||||
AC_SUBST(MOZ_ANDROID_SYNTHAPKS)
|
||||
AC_SUBST(MOZ_DISABLE_GECKOVIEW)
|
||||
AC_SUBST(ENABLE_STRIP)
|
||||
AC_SUBST(PKG_SKIP_STRIP)
|
||||
|
@ -12,8 +12,8 @@ class nsDOMAttributeMap;
|
||||
class nsIContent;
|
||||
|
||||
#define NS_IATTRIBUTE_IID \
|
||||
{ 0x8d9d7dbf, 0xc42d, 0x4715, \
|
||||
{ 0x95, 0xcf, 0x7a, 0x5e, 0xd5, 0xa4, 0x47, 0x70 } }
|
||||
{ 0x727dc139, 0xf516, 0x46ff, \
|
||||
{ 0x86, 0x11, 0x18, 0xea, 0xee, 0x4a, 0x3e, 0x6a } }
|
||||
|
||||
class nsIAttribute : public nsINode
|
||||
{
|
||||
@ -32,8 +32,6 @@ public:
|
||||
return mNodeInfo;
|
||||
}
|
||||
|
||||
virtual nsIContent* GetContent() const = 0;
|
||||
|
||||
/**
|
||||
* Called when our ownerElement is moved into a new document.
|
||||
* Updates the nodeinfo of this node.
|
||||
|
@ -77,7 +77,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Attr)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(Attr)
|
||||
Element* ownerElement = tmp->GetContentInternal();
|
||||
Element* ownerElement = tmp->GetElement();
|
||||
if (tmp->IsBlack()) {
|
||||
if (ownerElement) {
|
||||
// The attribute owns the element via attribute map so we can
|
||||
@ -128,16 +128,13 @@ Attr::SetMap(nsDOMAttributeMap *aMap)
|
||||
mAttrMap = aMap;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
Attr::GetContent() const
|
||||
{
|
||||
return GetContentInternal();
|
||||
}
|
||||
|
||||
Element*
|
||||
Attr::GetElement() const
|
||||
{
|
||||
nsIContent* content = GetContent();
|
||||
if (!mAttrMap) {
|
||||
return nullptr;
|
||||
}
|
||||
nsIContent* content = mAttrMap->GetContent();
|
||||
return content ? content->AsElement() : nullptr;
|
||||
}
|
||||
|
||||
@ -188,7 +185,7 @@ Attr::GetNameAtom(nsIContent* aContent)
|
||||
NS_IMETHODIMP
|
||||
Attr::GetValue(nsAString& aValue)
|
||||
{
|
||||
nsIContent* content = GetContentInternal();
|
||||
nsIContent* content = GetElement();
|
||||
if (content) {
|
||||
nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(content);
|
||||
content->GetAttr(mNodeInfo->NamespaceID(), nameAtom, aValue);
|
||||
@ -203,7 +200,7 @@ Attr::GetValue(nsAString& aValue)
|
||||
void
|
||||
Attr::SetValue(const nsAString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
nsIContent* content = GetContentInternal();
|
||||
nsIContent* content = GetElement();
|
||||
if (!content) {
|
||||
mValue = aValue;
|
||||
return;
|
||||
@ -276,7 +273,7 @@ Attr::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
already_AddRefed<nsIURI>
|
||||
Attr::GetBaseURI() const
|
||||
{
|
||||
nsINode *parent = GetContentInternal();
|
||||
nsINode *parent = GetElement();
|
||||
|
||||
return parent ? parent->GetBaseURI() : nullptr;
|
||||
}
|
||||
@ -301,7 +298,7 @@ Attr::SetTextContentInternal(const nsAString& aTextContent,
|
||||
NS_IMETHODIMP
|
||||
Attr::GetIsId(bool* aReturn)
|
||||
{
|
||||
nsIContent* content = GetContentInternal();
|
||||
nsIContent* content = GetElement();
|
||||
if (!content)
|
||||
{
|
||||
*aReturn = false;
|
||||
@ -387,11 +384,5 @@ Attr::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
|
||||
return AttrBinding::Wrap(aCx, aScope, this);
|
||||
}
|
||||
|
||||
Element*
|
||||
Attr::GetContentInternal() const
|
||||
{
|
||||
return mAttrMap ? mAttrMap->GetContent() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
|
||||
// nsIAttribute interface
|
||||
void SetMap(nsDOMAttributeMap *aMap) MOZ_OVERRIDE;
|
||||
nsIContent *GetContent() const MOZ_OVERRIDE;
|
||||
Element *GetElement() const;
|
||||
nsresult SetOwnerDocument(nsIDocument* aDocument) MOZ_OVERRIDE;
|
||||
|
||||
@ -96,14 +95,13 @@ public:
|
||||
protected:
|
||||
virtual Element* GetNameSpaceElement()
|
||||
{
|
||||
return GetContentInternal();
|
||||
return GetElement();
|
||||
}
|
||||
|
||||
static bool sInitialized;
|
||||
|
||||
private:
|
||||
already_AddRefed<nsIAtom> GetNameAtom(nsIContent* aContent);
|
||||
Element* GetContentInternal() const;
|
||||
|
||||
nsString mValue;
|
||||
};
|
||||
|
@ -56,7 +56,7 @@ function ContentSecurityPolicy() {
|
||||
this._weakDocRequest = { get : function() { return null; } };
|
||||
CSPdebug("CSP object initialized, no policies to enforce yet");
|
||||
|
||||
this._cache = { };
|
||||
this._cache = new Map();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -372,7 +372,7 @@ ContentSecurityPolicy.prototype = {
|
||||
newpolicy._specCompliant = !!aSpecCompliant;
|
||||
newpolicy._isInitialized = true;
|
||||
this._policies.push(newpolicy);
|
||||
this._cache = {}; // reset cache since effective policy changes
|
||||
this._cache.clear(); // reset cache since effective policy changes
|
||||
},
|
||||
|
||||
/**
|
||||
@ -385,7 +385,7 @@ ContentSecurityPolicy.prototype = {
|
||||
return;
|
||||
}
|
||||
this._policies.splice(index, 1);
|
||||
this._cache = {}; // reset cache since effective policy changes
|
||||
this._cache.clear(); // reset cache since effective policy changes
|
||||
},
|
||||
|
||||
/**
|
||||
@ -659,8 +659,8 @@ ContentSecurityPolicy.prototype = {
|
||||
aMimeTypeGuess,
|
||||
aOriginalUri) {
|
||||
let key = this._createCacheKey(aContentLocation, aContentType);
|
||||
if (key && this._cache[key]) {
|
||||
return this._cache[key];
|
||||
if (key && this._cache.has(key)) {
|
||||
return this._cache.get(key);
|
||||
}
|
||||
|
||||
#ifndef MOZ_B2G
|
||||
@ -764,7 +764,7 @@ ContentSecurityPolicy.prototype = {
|
||||
|
||||
// Do not cache the result if this is a nonce-source preload
|
||||
if (key && !possiblePreloadNonceConflict) {
|
||||
this._cache[key] = ret;
|
||||
this._cache.set(key, ret);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
@ -774,10 +774,10 @@ nsINode::CompareDocumentPosition(nsINode& aOtherNode) const
|
||||
const nsINode *node1 = &aOtherNode, *node2 = this;
|
||||
|
||||
// Check if either node is an attribute
|
||||
const nsIAttribute* attr1 = nullptr;
|
||||
const Attr* attr1 = nullptr;
|
||||
if (node1->IsNodeOfType(nsINode::eATTRIBUTE)) {
|
||||
attr1 = static_cast<const nsIAttribute*>(node1);
|
||||
const nsIContent* elem = attr1->GetContent();
|
||||
attr1 = static_cast<const Attr*>(node1);
|
||||
const nsIContent* elem = attr1->GetElement();
|
||||
// If there is an owner element add the attribute
|
||||
// to the chain and walk up to the element
|
||||
if (elem) {
|
||||
@ -786,8 +786,8 @@ nsINode::CompareDocumentPosition(nsINode& aOtherNode) const
|
||||
}
|
||||
}
|
||||
if (node2->IsNodeOfType(nsINode::eATTRIBUTE)) {
|
||||
const nsIAttribute* attr2 = static_cast<const nsIAttribute*>(node2);
|
||||
const nsIContent* elem = attr2->GetContent();
|
||||
const Attr* attr2 = static_cast<const Attr*>(node2);
|
||||
const nsIContent* elem = attr2->GetElement();
|
||||
if (elem == node1 && attr1) {
|
||||
// Both nodes are attributes on the same element.
|
||||
// Compare position between the attributes.
|
||||
|
@ -41,6 +41,7 @@ TextTrackCue::SetDefaultCueSettings()
|
||||
mSnapToLines = true;
|
||||
mLine = WEBVTT_AUTO;
|
||||
mAlign = AlignSetting::Middle;
|
||||
mLineAlign = AlignSetting::Start;
|
||||
mVertical = DirectionSetting::_empty;
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,9 @@ public:
|
||||
|
||||
void SetStartTime(double aStartTime)
|
||||
{
|
||||
if (mStartTime == aStartTime)
|
||||
if (mStartTime == aStartTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
mStartTime = aStartTime;
|
||||
CueChanged();
|
||||
@ -96,8 +97,9 @@ public:
|
||||
|
||||
void SetEndTime(double aEndTime)
|
||||
{
|
||||
if (mEndTime == aEndTime)
|
||||
if (mEndTime == aEndTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
mEndTime = aEndTime;
|
||||
CueChanged();
|
||||
@ -110,8 +112,9 @@ public:
|
||||
|
||||
void SetPauseOnExit(bool aPauseOnExit)
|
||||
{
|
||||
if (mPauseOnExit == aPauseOnExit)
|
||||
if (mPauseOnExit == aPauseOnExit) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPauseOnExit = aPauseOnExit;
|
||||
CueChanged();
|
||||
@ -139,8 +142,9 @@ public:
|
||||
|
||||
void SetVertical(const DirectionSetting& aVertical)
|
||||
{
|
||||
if (mVertical == aVertical)
|
||||
if (mVertical == aVertical) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReset = true;
|
||||
mVertical = aVertical;
|
||||
@ -154,8 +158,9 @@ public:
|
||||
|
||||
void SetSnapToLines(bool aSnapToLines)
|
||||
{
|
||||
if (mSnapToLines == aSnapToLines)
|
||||
if (mSnapToLines == aSnapToLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReset = true;
|
||||
mSnapToLines = aSnapToLines;
|
||||
@ -174,6 +179,26 @@ public:
|
||||
mLine = aLine;
|
||||
}
|
||||
|
||||
AlignSetting LineAlign() const
|
||||
{
|
||||
return mLineAlign;
|
||||
}
|
||||
|
||||
void SetLineAlign(AlignSetting& aLineAlign, ErrorResult& aRv)
|
||||
{
|
||||
if (mLineAlign == aLineAlign)
|
||||
return;
|
||||
|
||||
if (aLineAlign == AlignSetting::Left ||
|
||||
aLineAlign == AlignSetting::Right) {
|
||||
return aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
}
|
||||
|
||||
mReset = true;
|
||||
mLineAlign = aLineAlign;
|
||||
CueChanged();
|
||||
}
|
||||
|
||||
int32_t Position() const
|
||||
{
|
||||
return mPosition;
|
||||
@ -181,9 +206,9 @@ public:
|
||||
|
||||
void SetPosition(int32_t aPosition, ErrorResult& aRv)
|
||||
{
|
||||
// XXXhumph: validate? bug 868519.
|
||||
if (mPosition == aPosition)
|
||||
if (mPosition == aPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aPosition > 100 || aPosition < 0){
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
@ -223,8 +248,9 @@ public:
|
||||
|
||||
void SetAlign(AlignSetting& aAlign)
|
||||
{
|
||||
if (mAlign == aAlign)
|
||||
if (mAlign == aAlign) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReset = true;
|
||||
mAlign = aAlign;
|
||||
@ -238,8 +264,9 @@ public:
|
||||
|
||||
void SetText(const nsAString& aText)
|
||||
{
|
||||
if (mText == aText)
|
||||
if (mText == aText) {
|
||||
return;
|
||||
}
|
||||
|
||||
mReset = true;
|
||||
mText = aText;
|
||||
@ -324,6 +351,7 @@ private:
|
||||
DirectionSetting mVertical;
|
||||
int mLine;
|
||||
AlignSetting mAlign;
|
||||
AlignSetting mLineAlign;
|
||||
|
||||
// Holds the computed DOM elements that represent the parsed cue text.
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-display-state
|
||||
|
@ -76,6 +76,34 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
cue.pauseOnExit = true;
|
||||
is(cue.pauseOnExit, true, "Cue's pause on exit flag should be true.");
|
||||
|
||||
// Check that cue line align works properly
|
||||
is(cue.lineAlign, "start", "Cue's default line alignment should be start.");
|
||||
|
||||
var exceptionHappened = false;
|
||||
try {
|
||||
cue.lineAlign = "left";
|
||||
} catch(e) {
|
||||
exceptionHappened = true;
|
||||
is(e.name, "SyntaxError", "Should have thrown SyntaxError.");
|
||||
}
|
||||
ok(exceptionHappened, "Exception should have happened.");
|
||||
|
||||
exceptionHappened = false;
|
||||
try {
|
||||
cue.lineAlign = "right";
|
||||
} catch(e) {
|
||||
exceptionHappened = true;
|
||||
is(e.name, "SyntaxError", "Should have thrown SyntaxError.");
|
||||
}
|
||||
ok(exceptionHappened, "Exception should have happened.");
|
||||
|
||||
cue.lineAlign = "middle";
|
||||
is(cue.lineAlign, "middle", "Cue's line align should be middle.");
|
||||
cue.lineAlign = "START";
|
||||
is(cue.lineAlign, "middle", "Cue's line align should be middle.");
|
||||
cue.lineAlign = "end";
|
||||
is(cue.lineAlign, "end", "Cue's line align should be end.");
|
||||
|
||||
// Check that we can create and add new VTTCues
|
||||
var vttCue = new VTTCue(3.999, 4, "foo");
|
||||
trackElement.track.addCue(vttCue);
|
||||
@ -95,7 +123,7 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
trackElement.track.removeCue(cue);
|
||||
is(cueList.length, 6, "Cue list length should be 6.");
|
||||
|
||||
var exceptionHappened = false;
|
||||
exceptionHappened = false;
|
||||
try {
|
||||
// We should not be able to remove a cue that is not in the list.
|
||||
cue = new VTTCue(1, 2, "foo");
|
||||
|
@ -70,6 +70,9 @@ this.AppsUtils = {
|
||||
csp: aApp.csp,
|
||||
installOrigin: aApp.installOrigin,
|
||||
origin: aApp.origin,
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
packageName: aApp.packageName,
|
||||
#endif
|
||||
receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
|
||||
installTime: aApp.installTime,
|
||||
manifestURL: aApp.manifestURL,
|
||||
|
@ -40,6 +40,8 @@ for (let permName in PermissionsTable) {
|
||||
expandedPermNames = expandPermissions(permName);
|
||||
}
|
||||
AllPossiblePermissions = AllPossiblePermissions.concat(expandedPermNames);
|
||||
AllPossiblePermissions =
|
||||
AllPossiblePermissions.concat(["offline-app", "pin-app"]);
|
||||
}
|
||||
|
||||
this.PermissionsInstaller = {
|
||||
@ -75,6 +77,11 @@ this.PermissionsInstaller = {
|
||||
newPermNames = newPermNames.concat(expandedPermNames);
|
||||
}
|
||||
|
||||
// Add the appcache related permissions.
|
||||
if (newManifest.appcache_path) {
|
||||
newPermNames = newPermNames.concat(["offline-app", "pin-app"]);
|
||||
}
|
||||
|
||||
for (let idx in AllPossiblePermissions) {
|
||||
let permName = AllPossiblePermissions[idx];
|
||||
let index = newPermNames.indexOf(permName);
|
||||
@ -118,6 +125,13 @@ this.PermissionsInstaller = {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the appcache related permissions. We allow it for all kinds of
|
||||
// apps.
|
||||
if (newManifest.appcache_path) {
|
||||
this._setPermission("offline-app", "allow", aApp);
|
||||
this._setPermission("pin-app", "allow", aApp);
|
||||
}
|
||||
|
||||
for (let permName in newManifest.permissions) {
|
||||
if (!PermissionsTable[permName]) {
|
||||
Cu.reportError("PermissionsInstaller.jsm: '" + permName + "'" +
|
||||
|
@ -227,8 +227,6 @@ this.PermissionsTable = { geolocation: {
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: [
|
||||
"indexedDB-unlimited",
|
||||
"offline-app",
|
||||
"pin-app",
|
||||
"default-persistent-storage"
|
||||
]
|
||||
},
|
||||
|
@ -1119,9 +1119,14 @@ this.DOMApplicationRegistry = {
|
||||
msg.mm = mm;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install":
|
||||
case "Webapps:Install": {
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
Services.obs.notifyObservers(null, "webapps-download-apk", JSON.stringify(msg));
|
||||
#else
|
||||
this.doInstall(msg, mm);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case "Webapps:GetSelf":
|
||||
this.getSelf(msg, mm);
|
||||
break;
|
||||
@ -1143,9 +1148,14 @@ this.DOMApplicationRegistry = {
|
||||
case "Webapps:GetAll":
|
||||
this.doGetAll(msg, mm);
|
||||
break;
|
||||
case "Webapps:InstallPackage":
|
||||
case "Webapps:InstallPackage": {
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
Services.obs.notifyObservers(null, "webapps-download-apk", JSON.stringify(msg));
|
||||
#else
|
||||
this.doInstallPackage(msg, mm);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case "Webapps:RegisterForMessages":
|
||||
this.addMessageListener(msg.messages, msg.app, mm);
|
||||
break;
|
||||
@ -2012,6 +2022,65 @@ this.DOMApplicationRegistry = {
|
||||
return manifestStatus === "web";
|
||||
}
|
||||
|
||||
let checkManifest = (function() {
|
||||
if (!app.manifest) {
|
||||
sendError("MANIFEST_PARSE_ERROR");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disallow multiple hosted apps installations from the same origin for now.
|
||||
// We will remove this code after multiple apps per origin are supported (bug 778277).
|
||||
// This will also disallow reinstalls from the same origin for now.
|
||||
for (let id in this.webapps) {
|
||||
if (this.webapps[id].origin == app.origin &&
|
||||
!this.webapps[id].packageHash &&
|
||||
this._isLaunchable(this.webapps[id])) {
|
||||
sendError("MULTIPLE_APPS_PER_ORIGIN_FORBIDDEN");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkManifest(app.manifest, app)) {
|
||||
sendError("INVALID_MANIFEST");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkInstallAllowed(app.manifest, app.installOrigin)) {
|
||||
sendError("INSTALL_FROM_DENIED");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkAppStatus(app.manifest)) {
|
||||
sendError("INVALID_SECURITY_LEVEL");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).bind(this);
|
||||
|
||||
let installApp = (function() {
|
||||
app.manifestHash = this.computeManifestHash(app.manifest);
|
||||
// We allow bypassing the install confirmation process to facilitate
|
||||
// automation.
|
||||
let prefName = "dom.mozApps.auto_confirm_install";
|
||||
if (Services.prefs.prefHasUserValue(prefName) &&
|
||||
Services.prefs.getBoolPref(prefName)) {
|
||||
this.confirmInstall(aData);
|
||||
} else {
|
||||
Services.obs.notifyObservers(aMm, "webapps-ask-install",
|
||||
JSON.stringify(aData));
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
// We may already have the manifest (e.g. AutoInstall),
|
||||
// in which case we don't need to load it.
|
||||
if (app.manifest) {
|
||||
if (checkManifest()) {
|
||||
installApp();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open("GET", app.manifestURL, true);
|
||||
@ -2029,42 +2098,9 @@ this.DOMApplicationRegistry = {
|
||||
}
|
||||
|
||||
app.manifest = xhr.response;
|
||||
if (!app.manifest) {
|
||||
sendError("MANIFEST_PARSE_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
// Disallow multiple hosted apps installations from the same origin for now.
|
||||
// We will remove this code after multiple apps per origin are supported (bug 778277).
|
||||
// This will also disallow reinstalls from the same origin for now.
|
||||
for (let id in this.webapps) {
|
||||
if (this.webapps[id].origin == app.origin &&
|
||||
!this.webapps[id].packageHash &&
|
||||
this._isLaunchable(this.webapps[id])) {
|
||||
sendError("MULTIPLE_APPS_PER_ORIGIN_FORBIDDEN");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkManifest(app.manifest, app)) {
|
||||
sendError("INVALID_MANIFEST");
|
||||
} else if (!AppsUtils.checkInstallAllowed(app.manifest, app.installOrigin)) {
|
||||
sendError("INSTALL_FROM_DENIED");
|
||||
} else if (!checkAppStatus(app.manifest)) {
|
||||
sendError("INVALID_SECURITY_LEVEL");
|
||||
} else {
|
||||
if (checkManifest()) {
|
||||
app.etag = xhr.getResponseHeader("Etag");
|
||||
app.manifestHash = this.computeManifestHash(app.manifest);
|
||||
// We allow bypassing the install confirmation process to facilitate
|
||||
// automation.
|
||||
let prefName = "dom.mozApps.auto_confirm_install";
|
||||
if (Services.prefs.prefHasUserValue(prefName) &&
|
||||
Services.prefs.getBoolPref(prefName)) {
|
||||
this.confirmInstall(aData);
|
||||
} else {
|
||||
Services.obs.notifyObservers(aMm, "webapps-ask-install",
|
||||
JSON.stringify(aData));
|
||||
}
|
||||
installApp();
|
||||
}
|
||||
} else {
|
||||
sendError("MANIFEST_URL_ERROR");
|
||||
@ -2088,6 +2124,53 @@ this.DOMApplicationRegistry = {
|
||||
app.installOrigin + ": " + aError);
|
||||
}.bind(this);
|
||||
|
||||
let checkUpdateManifest = (function() {
|
||||
let manifest = app.updateManifest;
|
||||
|
||||
// Disallow reinstalls from the same manifest URL for now.
|
||||
let id = this._appIdForManifestURL(app.manifestURL);
|
||||
if (id !== null && this._isLaunchable(this.webapps[id])) {
|
||||
sendError("REINSTALL_FORBIDDEN");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(AppsUtils.checkManifest(manifest, app) && manifest.package_path)) {
|
||||
sendError("INVALID_MANIFEST");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AppsUtils.checkInstallAllowed(manifest, app.installOrigin)) {
|
||||
sendError("INSTALL_FROM_DENIED");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).bind(this);
|
||||
|
||||
let installApp = (function() {
|
||||
app.manifestHash = this.computeManifestHash(app.updateManifest);
|
||||
|
||||
// We allow bypassing the install confirmation process to facilitate
|
||||
// automation.
|
||||
let prefName = "dom.mozApps.auto_confirm_install";
|
||||
if (Services.prefs.prefHasUserValue(prefName) &&
|
||||
Services.prefs.getBoolPref(prefName)) {
|
||||
this.confirmInstall(aData);
|
||||
} else {
|
||||
Services.obs.notifyObservers(aMm, "webapps-ask-install",
|
||||
JSON.stringify(aData));
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
// We may already have the manifest (e.g. AutoInstall),
|
||||
// in which case we don't need to load it.
|
||||
if (app.updateManifest) {
|
||||
if (checkUpdateManifest()) {
|
||||
installApp();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open("GET", app.manifestURL, true);
|
||||
@ -2104,38 +2187,15 @@ this.DOMApplicationRegistry = {
|
||||
return;
|
||||
}
|
||||
|
||||
let manifest = app.updateManifest = xhr.response;
|
||||
if (!manifest) {
|
||||
app.updateManifest = xhr.response;
|
||||
if (!app.updateManifest) {
|
||||
sendError("MANIFEST_PARSE_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
// Disallow reinstalls from the same manifest URL for now.
|
||||
let id = this._appIdForManifestURL(app.manifestURL);
|
||||
if (id !== null && this._isLaunchable(this.webapps[id])) {
|
||||
sendError("REINSTALL_FORBIDDEN");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(AppsUtils.checkManifest(manifest, app) &&
|
||||
manifest.package_path)) {
|
||||
sendError("INVALID_MANIFEST");
|
||||
} else if (!AppsUtils.checkInstallAllowed(manifest, app.installOrigin)) {
|
||||
sendError("INSTALL_FROM_DENIED");
|
||||
} else {
|
||||
if (checkUpdateManifest()) {
|
||||
app.etag = xhr.getResponseHeader("Etag");
|
||||
app.manifestHash = this.computeManifestHash(manifest);
|
||||
debug("at install package got app etag=" + app.etag);
|
||||
// We allow bypassing the install confirmation process to facilitate
|
||||
// automation.
|
||||
let prefName = "dom.mozApps.auto_confirm_install";
|
||||
if (Services.prefs.prefHasUserValue(prefName) &&
|
||||
Services.prefs.getBoolPref(prefName)) {
|
||||
this.confirmInstall(aData);
|
||||
} else {
|
||||
Services.obs.notifyObservers(aMm, "webapps-ask-install",
|
||||
JSON.stringify(aData));
|
||||
}
|
||||
installApp();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -2346,7 +2406,17 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
// saved in the registry.
|
||||
this._saveApps((function() {
|
||||
this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
|
||||
this.broadcastMessage("Webapps:Install:Return:OK", aData);
|
||||
if (aData.isPackage && aData.autoInstall) {
|
||||
// Skip directly to onInstallSuccessAck, since there isn't
|
||||
// a WebappsRegistry to receive Webapps:Install:Return:OK and respond
|
||||
// Webapps:Install:Return:Ack when an app is being auto-installed.
|
||||
this.onInstallSuccessAck(app.manifestURL);
|
||||
} else {
|
||||
// Broadcast Webapps:Install:Return:OK so the WebappsRegistry can notify
|
||||
// the installing page about the successful install, after which it'll
|
||||
// respond Webapps:Install:Return:Ack, which calls onInstallSuccessAck.
|
||||
this.broadcastMessage("Webapps:Install:Return:OK", aData);
|
||||
}
|
||||
Services.obs.notifyObservers(null, "webapps-installed",
|
||||
JSON.stringify({ manifestURL: app.manifestURL }));
|
||||
}).bind(this));
|
||||
@ -2361,11 +2431,17 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
if (manifest.package_path) {
|
||||
// If it is a local app then it must been installed from a local file
|
||||
// instead of web.
|
||||
let origPath = jsonManifest.package_path;
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
// In that case, we would already have the manifest, not just the update
|
||||
// manifest.
|
||||
dontNeedNetwork = !!aData.app.manifest;
|
||||
#else
|
||||
if (aData.app.localInstallPath) {
|
||||
dontNeedNetwork = true;
|
||||
jsonManifest.package_path = "file://" + aData.app.localInstallPath;
|
||||
}
|
||||
#endif
|
||||
|
||||
// origin for install apps is meaningless here, since it's app:// and this
|
||||
// can't be used to resolve package paths.
|
||||
manifest = new ManifestHelper(jsonManifest, app.manifestURL);
|
||||
@ -2548,7 +2624,7 @@ onInstallSuccessAck: function onInstallSuccessAck(aManifestURL,
|
||||
let fullPackagePath = aManifest.fullPackagePath();
|
||||
|
||||
// Check if it's a local file install (we've downloaded/sideloaded the
|
||||
// package already or it did exist on the build).
|
||||
// package already, it existed on the build, or it came with an APK).
|
||||
// Note that this variable also controls whether files signed with expired
|
||||
// certificates are accepted or not. If isLocalFileInstall is true and the
|
||||
// device date is earlier than the build generation date, then the signature
|
||||
|
@ -1029,12 +1029,15 @@ private:
|
||||
bool
|
||||
Recv__delete__() MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(mOpened);
|
||||
|
||||
MOZ_ASSERT(!mFinished);
|
||||
mFinished = true;
|
||||
|
||||
MainProcessRunnable::Close();
|
||||
if (mOpened) {
|
||||
MainProcessRunnable::Close();
|
||||
} else {
|
||||
MainProcessRunnable::Fail();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2686,6 +2686,15 @@ class FailureFatalCastableObjectUnwrapper(CastableObjectUnwrapper):
|
||||
exceptionCode,
|
||||
isCallbackReturnValue)
|
||||
|
||||
class CGCallbackTempRoot(CGGeneric):
|
||||
def __init__(self, name):
|
||||
define = """{ // Scope for tempRoot
|
||||
JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());
|
||||
${declName} = new %s(tempRoot, mozilla::dom::GetIncumbentGlobal());
|
||||
}
|
||||
""" % name
|
||||
CGGeneric.__init__(self, define=define)
|
||||
|
||||
class JSToNativeConversionInfo():
|
||||
"""
|
||||
An object representing information about a JS-to-native conversion.
|
||||
@ -3402,11 +3411,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
declType = CGGeneric("nsRefPtr<%s>" % name);
|
||||
else:
|
||||
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||
conversion = (
|
||||
"{ // Scope for tempRoot\n"
|
||||
" JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());\n"
|
||||
" ${declName} = new %s(tempRoot, mozilla::dom::GetIncumbentGlobal());\n"
|
||||
"}" % name)
|
||||
conversion = CGIndenter(CGCallbackTempRoot(name)).define()
|
||||
|
||||
template = wrapObjectTemplate(conversion, type,
|
||||
"${declName} = nullptr",
|
||||
@ -3738,11 +3743,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
declType = CGGeneric("nsRefPtr<%s>" % name);
|
||||
else:
|
||||
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||
conversion = (
|
||||
"{ // Scope for tempRoot\n"
|
||||
" JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());\n"
|
||||
" ${declName} = new %s(tempRoot, mozilla::dom::GetIncumbentGlobal());\n"
|
||||
"}\n" % name)
|
||||
conversion = CGIndenter(CGCallbackTempRoot(name)).define()
|
||||
|
||||
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
|
||||
haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
|
||||
@ -4092,8 +4093,7 @@ class CGArgumentConverter(CGThing):
|
||||
"""
|
||||
def __init__(self, argument, index, descriptorProvider,
|
||||
argDescription,
|
||||
invalidEnumValueFatal=True, lenientFloatCode=None,
|
||||
allowTreatNonCallableAsNull=False):
|
||||
invalidEnumValueFatal=True, lenientFloatCode=None):
|
||||
CGThing.__init__(self)
|
||||
self.argument = argument
|
||||
self.argDescription = argDescription
|
||||
@ -4122,7 +4122,6 @@ class CGArgumentConverter(CGThing):
|
||||
self.argcAndIndex = None
|
||||
self.invalidEnumValueFatal = invalidEnumValueFatal
|
||||
self.lenientFloatCode = lenientFloatCode
|
||||
self.allowTreatNonCallableAsNull = allowTreatNonCallableAsNull
|
||||
|
||||
def define(self):
|
||||
typeConversion = getJSToNativeConversionInfo(
|
||||
@ -4137,7 +4136,7 @@ class CGArgumentConverter(CGThing):
|
||||
isClamp=self.argument.clamp,
|
||||
lenientFloatCode=self.lenientFloatCode,
|
||||
isMember="Variadic" if self.argument.variadic else False,
|
||||
allowTreatNonCallableAsNull=self.allowTreatNonCallableAsNull,
|
||||
allowTreatNonCallableAsNull=self.argument.allowTreatNonCallableAsNull(),
|
||||
sourceDescription=self.argDescription)
|
||||
|
||||
if not self.argument.variadic:
|
||||
@ -5106,7 +5105,6 @@ if (global.Failed()) {
|
||||
cgThings.extend([CGArgumentConverter(arguments[i], i, self.descriptor,
|
||||
argDescription % { "index": i + 1 },
|
||||
invalidEnumValueFatal=not setter,
|
||||
allowTreatNonCallableAsNull=setter,
|
||||
lenientFloatCode=lenientFloatCode) for
|
||||
i in range(argConversionStartsAt, self.argCount)])
|
||||
|
||||
@ -5687,11 +5685,12 @@ class FakeArgument():
|
||||
A class that quacks like an IDLArgument. This is used to make
|
||||
setters look like method calls or for special operations.
|
||||
"""
|
||||
def __init__(self, type, interfaceMember, name="arg"):
|
||||
def __init__(self, type, interfaceMember, name="arg", allowTreatNonCallableAsNull=False):
|
||||
self.type = type
|
||||
self.optional = False
|
||||
self.variadic = False
|
||||
self.defaultValue = None
|
||||
self._allowTreatNonCallableAsNull = allowTreatNonCallableAsNull
|
||||
self.treatNullAs = interfaceMember.treatNullAs
|
||||
if isinstance(interfaceMember, IDLAttribute):
|
||||
self.enforceRange = interfaceMember.enforceRange
|
||||
@ -5704,13 +5703,16 @@ class FakeArgument():
|
||||
self.name = name
|
||||
self.identifier = FakeIdentifier()
|
||||
|
||||
def allowTreatNonCallableAsNull(self):
|
||||
return self._allowTreatNonCallableAsNull
|
||||
|
||||
class CGSetterCall(CGPerSignatureCall):
|
||||
"""
|
||||
A class to generate a native object setter call for a particular IDL
|
||||
setter.
|
||||
"""
|
||||
def __init__(self, argType, nativeMethodName, descriptor, attr):
|
||||
CGPerSignatureCall.__init__(self, None, [FakeArgument(argType, attr)],
|
||||
CGPerSignatureCall.__init__(self, None, [FakeArgument(argType, attr, allowTreatNonCallableAsNull=True)],
|
||||
nativeMethodName, attr.isStatic(),
|
||||
descriptor, attr, setter=True)
|
||||
def wrap_return_value(self):
|
||||
@ -11933,3 +11935,4 @@ class CGEventRoot(CGThing):
|
||||
|
||||
def define(self):
|
||||
return self.root.define()
|
||||
|
||||
|
@ -2848,6 +2848,7 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||
self._isComplete = False
|
||||
self.enforceRange = False
|
||||
self.clamp = False
|
||||
self._allowTreatNonCallableAsNull = False
|
||||
|
||||
assert not variadic or optional
|
||||
|
||||
@ -2874,6 +2875,8 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||
raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
|
||||
[self.location]);
|
||||
self.enforceRange = True
|
||||
elif identifier == "TreatNonCallableAsNull":
|
||||
self._allowTreatNonCallableAsNull = True
|
||||
else:
|
||||
raise WebIDLError("Unhandled extended attribute on an argument",
|
||||
[attribute.location])
|
||||
@ -2908,6 +2911,9 @@ class IDLArgument(IDLObjectWithIdentifier):
|
||||
self.location)
|
||||
assert self.defaultValue
|
||||
|
||||
def allowTreatNonCallableAsNull(self):
|
||||
return self._allowTreatNonCallableAsNull
|
||||
|
||||
def _getDependentObjects(self):
|
||||
deps = set([self.type])
|
||||
if self.defaultValue:
|
||||
|
@ -2886,6 +2886,11 @@ BluetoothDBusService::GetServiceChannel(const nsAString& aDeviceAddress,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!IsReady()) {
|
||||
NS_NAMED_LITERAL_STRING(errorStr, "Bluetooth service is not ready yet!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
||||
nsString objectPath(GetObjectPathFromAddress(sAdapterPath, aDeviceAddress));
|
||||
|
||||
|
@ -129,7 +129,7 @@ nsDOMIdentity.prototype = {
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Watch", message);
|
||||
},
|
||||
|
||||
request: function nsDOMIdentity_request(aOptions) {
|
||||
request: function nsDOMIdentity_request(aOptions = {}) {
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
|
@ -107,6 +107,9 @@ this.SystemMessagePermissionsTable = {
|
||||
"nfc-manager-tech-lost": {
|
||||
"nfc-manager": []
|
||||
},
|
||||
"nfc-manager-send-file": {
|
||||
"nfc-manager": []
|
||||
},
|
||||
"nfc-powerlevel-change": {
|
||||
"settings": ["read", "write"]
|
||||
},
|
||||
|
@ -110,7 +110,7 @@ MozNFCPeer.prototype = {
|
||||
|
||||
initialize: function(aWindow, aSessionToken) {
|
||||
this._window = aWindow;
|
||||
this.session = aSessionToken;
|
||||
this.setSessionToken(aSessionToken);
|
||||
},
|
||||
|
||||
// ChromeOnly interface
|
||||
@ -127,6 +127,15 @@ MozNFCPeer.prototype = {
|
||||
return this._nfcContentHelper.writeNDEF(this._window, records, this.session);
|
||||
},
|
||||
|
||||
sendFile: function sendFile(blob) {
|
||||
let data = {
|
||||
"blob": blob.slice()
|
||||
};
|
||||
return this._nfcContentHelper.sendFile(this._window,
|
||||
ObjectWrapper.wrap(data, this._window),
|
||||
this.session);
|
||||
},
|
||||
|
||||
classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"),
|
||||
contractID: "@mozilla.org/nfc/NFCPeer;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
|
@ -8,7 +8,7 @@ var gData = [
|
||||
permission: "contacts",
|
||||
access: READWRITE,
|
||||
expected: ["contacts-read", "contacts-create",
|
||||
"contacts-write"]
|
||||
"contacts-write"]
|
||||
},
|
||||
// test additional expansion and access not having read+create+write
|
||||
{
|
||||
@ -16,12 +16,12 @@ var gData = [
|
||||
access: READWRITE,
|
||||
expected: ["settings-read", "settings-write",
|
||||
"indexedDB-chrome-settings-read",
|
||||
"indexedDB-chrome-settings-write"]
|
||||
"indexedDB-chrome-settings-write"]
|
||||
},
|
||||
// test substitute
|
||||
{
|
||||
permission: "storage",
|
||||
expected: ["indexedDB-unlimited", "offline-app", "pin-app",
|
||||
expected: ["indexedDB-unlimited",
|
||||
"default-persistent-storage"]
|
||||
},
|
||||
// test unknown access
|
||||
|
@ -25,6 +25,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WakeLock)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WakeLock)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
|
@ -1,5 +1,6 @@
|
||||
[DEFAULT]
|
||||
|
||||
[test_bug957899.html]
|
||||
[test_power_basics.html]
|
||||
[test_power_set_cpusleepallowed.html]
|
||||
[test_power_set_screen_brightness.html]
|
||||
|
15
dom/power/test/test_bug957899.html
Normal file
15
dom/power/test/test_bug957899.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test bug 957899 - Crash in WakeLock</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
var wl = navigator.requestWakeLock('a');
|
||||
ok(wl, "WakeLock created!");
|
||||
ok(!(wl instanceof XPathEvaluator), "Crashing?");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -51,7 +51,8 @@ const NFC_IPC_MSG_NAMES = [
|
||||
"NFC:GetDetailsNDEF",
|
||||
"NFC:MakeReadOnlyNDEF",
|
||||
"NFC:Connect",
|
||||
"NFC:Close"
|
||||
"NFC:Close",
|
||||
"NFC:SendFile"
|
||||
];
|
||||
|
||||
const NFC_IPC_PEER_MSG_NAMES = [
|
||||
@ -296,11 +297,11 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add extra permission check for two IPC Peer events:
|
||||
// Add extra permission check for below IPC Peer events:
|
||||
// 'NFC:CheckP2PRegistration' , 'NFC:NotifyUserAcceptedP2P'
|
||||
if ((msg.name == "NFC:CheckP2PRegistration") ||
|
||||
(msg.name == "NFC:NotifyUserAcceptedP2P")) {
|
||||
// ONLY privileged Content can send these two events
|
||||
// ONLY privileged Content can send these events
|
||||
if (!msg.target.assertPermission("nfc-manager")) {
|
||||
debug("NFC message " + message.name +
|
||||
" from a content process with no 'nfc-manager' privileges.");
|
||||
@ -532,6 +533,7 @@ Nfc.prototype = {
|
||||
break;
|
||||
case "NFC:WriteNDEF": // Fall through
|
||||
case "NFC:MakeReadOnlyNDEF":
|
||||
case "NFC:SendFile":
|
||||
if (!message.target.assertPermission("nfc-write")) {
|
||||
debug("NFC message " + message.name +
|
||||
" from a content process with no 'nfc-write' privileges.");
|
||||
@ -574,6 +576,17 @@ Nfc.prototype = {
|
||||
case "NFC:Close":
|
||||
this.sendToWorker("close", message.json);
|
||||
break;
|
||||
case "NFC:SendFile":
|
||||
// Chrome process is the arbitrator / mediator between
|
||||
// system app (content process) that issued nfc 'sendFile' operation
|
||||
// and system app that handles the system message :
|
||||
// 'nfc-manager-send-file'. System app subsequently handover's
|
||||
// the data to alternate carrier's (BT / WiFi) 'sendFile' interface.
|
||||
|
||||
// Notify system app to initiate BT send file operation
|
||||
gSystemMessenger.broadcastMessage("nfc-manager-send-file",
|
||||
message.json);
|
||||
break;
|
||||
default:
|
||||
debug("UnSupported : Message Name " + message.name);
|
||||
return null;
|
||||
|
@ -218,6 +218,23 @@ NfcContentHelper.prototype = {
|
||||
return request;
|
||||
},
|
||||
|
||||
sendFile: function sendFile(window, data, sessionToken) {
|
||||
if (window == null) {
|
||||
throw Components.Exception("Can't get window object",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
let request = Services.DOMRequest.createRequest(window);
|
||||
let requestId = btoa(this.getRequestId(request));
|
||||
this._requestMap[requestId] = window;
|
||||
|
||||
cpmm.sendAsyncMessage("NFC:SendFile", {
|
||||
requestId: requestId,
|
||||
sessionToken: sessionToken,
|
||||
blob: data.blob
|
||||
});
|
||||
return request;
|
||||
},
|
||||
|
||||
registerTargetForPeerEvent: function registerTargetForPeerEvent(window,
|
||||
appId, event, callback) {
|
||||
if (window == null) {
|
||||
@ -276,7 +293,6 @@ NfcContentHelper.prototype = {
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
if (topic == "xpcom-shutdown") {
|
||||
this.removeMessageListener();
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, function, uuid(271f48b0-c884-4f0b-a348-e29824c95168)]
|
||||
[scriptable, function, uuid(26673d1a-4af4-470a-ba96-f1f54b1f2052)]
|
||||
interface nsINfcPeerCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -40,6 +40,27 @@ interface nsINfcContentHelper : nsISupports
|
||||
nsIDOMDOMRequest connect(in nsIDOMWindow window, in unsigned long techType, in DOMString sessionToken);
|
||||
nsIDOMDOMRequest close(in nsIDOMWindow window, in DOMString sessionToken);
|
||||
|
||||
/**
|
||||
* Initiate Send file operation
|
||||
*
|
||||
* @param window
|
||||
* Current window
|
||||
*
|
||||
* @param blob
|
||||
* Raw data of the file to be sent. This object represents a file-like
|
||||
* (nsIDOMFile) object of immutable, raw data. The blob data needs
|
||||
* to be 'object wrapped' before calling this interface.
|
||||
*
|
||||
* @param sessionToken
|
||||
* Current token
|
||||
*
|
||||
* Returns DOMRequest, if initiation of send file operation is successful
|
||||
* then 'onsuccess' is called else 'onerror'
|
||||
*/
|
||||
nsIDOMDOMRequest sendFile(in nsIDOMWindow window,
|
||||
in jsval blob,
|
||||
in DOMString sessionToken);
|
||||
|
||||
/**
|
||||
* Register the given application id with Chrome process
|
||||
*
|
||||
|
@ -11,6 +11,7 @@
|
||||
[JSImplementation="@mozilla.org/nfc/NFCPeer;1"]
|
||||
interface MozNFCPeer {
|
||||
DOMRequest sendNDEF(sequence<MozNdefRecord> records);
|
||||
DOMRequest sendFile(Blob blob);
|
||||
};
|
||||
|
||||
// Mozilla Only
|
||||
|
@ -38,6 +38,8 @@ interface VTTCue : EventTarget {
|
||||
// XXXhumph: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20651
|
||||
// attribute (long or AutoKeyword) line;
|
||||
[SetterThrows]
|
||||
attribute AlignSetting lineAlign;
|
||||
[SetterThrows]
|
||||
attribute long position;
|
||||
[SetterThrows]
|
||||
attribute long size;
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "txExprResult.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "nsError.h"
|
||||
#include "mozilla/dom/Attr.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIAttribute.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
@ -362,7 +362,7 @@ nsXPathResult::Invalidate(const nsIContent* aChangeRoot)
|
||||
->GetBindingParent();
|
||||
} else if (contextNode->IsNodeOfType(nsINode::eATTRIBUTE)) {
|
||||
nsIContent* parent =
|
||||
static_cast<nsIAttribute*>(contextNode.get())->GetContent();
|
||||
static_cast<Attr*>(contextNode.get())->GetElement();
|
||||
if (parent) {
|
||||
ctxBindingParent = parent->GetBindingParent();
|
||||
}
|
||||
|
@ -21,10 +21,13 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsAttrName.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/Attr.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
|
||||
using mozilla::dom::Attr;
|
||||
|
||||
const uint32_t kUnknownIndex = uint32_t(-1);
|
||||
|
||||
txXPathTreeWalker::txXPathTreeWalker(const txXPathTreeWalker& aOther)
|
||||
@ -690,7 +693,7 @@ txXPathNativeNode::createXPathNode(nsIDOMNode* aNode, bool aKeepRootAlive)
|
||||
NS_ASSERTION(attr, "doesn't implement nsIAttribute");
|
||||
|
||||
nsINodeInfo *nodeInfo = attr->NodeInfo();
|
||||
nsIContent *parent = attr->GetContent();
|
||||
nsIContent *parent = static_cast<Attr*>(attr.get())->GetElement();
|
||||
if (!parent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
VPATH = $(srcdir) $(srcdir)/unittest
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gtk3 gonk qt))
|
||||
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
|
||||
endif
|
||||
|
@ -219,17 +219,6 @@ SplitBezier(const BezierControlPoints &aControlPoints,
|
||||
aSecondSegmentControlPoints->mCP1 = cp1aaa;
|
||||
aSecondSegmentControlPoints->mCP2 = cp2aa;
|
||||
aSecondSegmentControlPoints->mCP3 = cp3a;
|
||||
|
||||
// Ensure the result is a nice cubic bezier.
|
||||
if (aSecondSegmentControlPoints->mCP1 == aSecondSegmentControlPoints->mCP2 ||
|
||||
aSecondSegmentControlPoints->mCP2 == aSecondSegmentControlPoints->mCP3) {
|
||||
aSecondSegmentControlPoints->mCP2 = aSecondSegmentControlPoints->mCP1 +
|
||||
(aSecondSegmentControlPoints->mCP3 - aSecondSegmentControlPoints->mCP1) *
|
||||
Float(2. / 3.);
|
||||
aSecondSegmentControlPoints->mCP3 = aControlPoints.mCP4 +
|
||||
(aSecondSegmentControlPoints->mCP3 - aControlPoints.mCP4) *
|
||||
Float(2. / 3.);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -278,9 +267,16 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints,
|
||||
Point cp21 = aControlPoints.mCP2 - aControlPoints.mCP1;
|
||||
Point cp41 = aControlPoints.mCP4 - aControlPoints.mCP1;
|
||||
|
||||
Float s4 = (cp41.x * cp21.y - cp41.y * cp21.x) / hypotf(cp21.x, cp21.y);
|
||||
if (!cp21.x && !cp21.y) {
|
||||
// In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y.
|
||||
*aMin = aT - pow(aTolerance / (cp41.x - cp41.y), Float(1. / 3.));
|
||||
*aMax = aT + pow(aTolerance / (cp41.x - cp41.y), Float(1. / 3.));;
|
||||
return;
|
||||
}
|
||||
|
||||
Float tf = pow(abs(aTolerance / s4), Float(1. / 3.));
|
||||
Float s3 = (cp41.x * cp21.y - cp41.y * cp21.x) / hypotf(cp21.x, cp21.y);
|
||||
|
||||
Float tf = pow(abs(aTolerance / s3), Float(1. / 3.));
|
||||
|
||||
*aMin = aT - tf * (1 - aT);
|
||||
*aMax = aT + tf * (1 - aT);
|
||||
@ -367,6 +363,9 @@ FindInflectionPoints(const BezierControlPoints &aControlPoints,
|
||||
if (discriminant < 0) {
|
||||
// No inflection points.
|
||||
*aCount = 0;
|
||||
} else if (discriminant == 0) {
|
||||
*aCount = 1;
|
||||
*aT1 = -b / (2 * a);
|
||||
} else {
|
||||
/* Use the following formula for computing the roots:
|
||||
*
|
||||
@ -419,10 +418,10 @@ FlattenBezier(const BezierControlPoints &aControlPoints,
|
||||
|
||||
// For both inflection points, calulate the range where they can be linearly
|
||||
// approximated if they are positioned within [0,1]
|
||||
if (count > 0 && t1 >= 0 && t1 <= 1.0) {
|
||||
if (count > 0 && t1 >= 0 && t1 < 1.0) {
|
||||
FindInflectionApproximationRange(aControlPoints, &t1min, &t1max, t1, aTolerance);
|
||||
}
|
||||
if (count > 1 && t2 >= 0 && t2 <= 1.0) {
|
||||
if (count > 1 && t2 >= 0 && t2 < 1.0) {
|
||||
FindInflectionApproximationRange(aControlPoints, &t2min, &t2max, t2, aTolerance);
|
||||
}
|
||||
BezierControlPoints nextCPs = aControlPoints;
|
||||
@ -430,34 +429,33 @@ FlattenBezier(const BezierControlPoints &aControlPoints,
|
||||
|
||||
// Process ranges. [t1min, t1max] and [t2min, t2max] are approximated by line
|
||||
// segments.
|
||||
if (t1min < 1.0 && t1max > 0) {
|
||||
if (t1min > 0) {
|
||||
// Flatten the Bezier up until the first inflection point's approximation
|
||||
// point.
|
||||
SplitBezier(aControlPoints, &prevCPs,
|
||||
&remainingCP, t1min);
|
||||
FlattenBezierCurveSegment(prevCPs, aSink, aTolerance);
|
||||
}
|
||||
if (t1max < 1.0 && (count == 1 || t2min > t1max)) {
|
||||
// The second inflection point's approximation range begins after the end
|
||||
// of the first, approximate the first inflection point by a line and
|
||||
// subsequently flatten up until the end or the next inflection point.
|
||||
SplitBezier(aControlPoints, nullptr, &nextCPs, t1max);
|
||||
|
||||
aSink->LineTo(nextCPs.mCP1);
|
||||
|
||||
if (count > 1 && t2min > 1.0) {
|
||||
// No more inflection points to deal with, flatten the rest of the curve.
|
||||
FlattenBezierCurveSegment(nextCPs, aSink, aTolerance);
|
||||
}
|
||||
} else if (count > 1 && t2min > 1.0) {
|
||||
// We've already concluded t2min <= t1max, so if this is true the
|
||||
// approximation range for the first inflection point runs past the
|
||||
// end of the curve, draw a line to the end and we're done.
|
||||
aSink->LineTo(aControlPoints.mCP4);
|
||||
return;
|
||||
}
|
||||
if (t1min > 0) {
|
||||
// Flatten the Bezier up until the first inflection point's approximation
|
||||
// point.
|
||||
SplitBezier(aControlPoints, &prevCPs,
|
||||
&remainingCP, t1min);
|
||||
FlattenBezierCurveSegment(prevCPs, aSink, aTolerance);
|
||||
}
|
||||
if (t1max < 1.0 && (count == 1 || t2min > t1max)) {
|
||||
// The second inflection point's approximation range begins after the end
|
||||
// of the first, approximate the first inflection point by a line and
|
||||
// subsequently flatten up until the end or the next inflection point.
|
||||
SplitBezier(aControlPoints, nullptr, &nextCPs, t1max);
|
||||
|
||||
aSink->LineTo(nextCPs.mCP1);
|
||||
|
||||
if (count == 1 || (count > 1 && t2min >= 1.0)) {
|
||||
// No more inflection points to deal with, flatten the rest of the curve.
|
||||
FlattenBezierCurveSegment(nextCPs, aSink, aTolerance);
|
||||
}
|
||||
} else if (count > 1 && t2min > 1.0) {
|
||||
// We've already concluded t2min <= t1max, so if this is true the
|
||||
// approximation range for the first inflection point runs past the
|
||||
// end of the curve, draw a line to the end and we're done.
|
||||
aSink->LineTo(aControlPoints.mCP4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count > 1 && t2min < 1.0 && t2max > 0) {
|
||||
if (t2min > 0 && t2min < t1max) {
|
||||
// In this case the t2 approximation range starts inside the t1
|
||||
|
@ -2,22 +2,6 @@
|
||||
# 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/.
|
||||
|
||||
# The below is a rough translation of build_angle.gypi:
|
||||
# Target: 'preprocessor'
|
||||
# src/compiler/preprocessor:
|
||||
VPATH += $(srcdir)/src/compiler/preprocessor
|
||||
|
||||
# Target: 'translator_common'
|
||||
# Requires: 'preprocessor'
|
||||
VPATH += $(srcdir)/src/compiler
|
||||
VPATH += $(srcdir)/src/compiler/depgraph
|
||||
VPATH += $(srcdir)/src/compiler/timing
|
||||
VPATH += $(srcdir)/src/third_party/compiler
|
||||
VPATH += $(srcdir)/src/third_party/murmurhash
|
||||
|
||||
# Target: 'translator_glsl'
|
||||
# Requires: 'translator_common'
|
||||
# src/compiler:
|
||||
ifdef MOZ_ANGLE_RENDERER
|
||||
|
||||
libs::
|
||||
|
@ -13,10 +13,6 @@ endif
|
||||
# Below is a transcription of the EGL target from build_angle.gypi.
|
||||
# Target: 'libEGL'
|
||||
# Links with: 'libGLESv2'
|
||||
# src/common:
|
||||
VPATH += $(srcdir)/../common
|
||||
# src/libEGL:
|
||||
VPATH += $(srcdir)/../libEGL
|
||||
DEFFILE = $(srcdir)/libEGL.def
|
||||
RCFILE = $(srcdir)/libEGL.rc
|
||||
|
||||
|
@ -10,27 +10,6 @@ ifndef GNU_CC
|
||||
OS_CPPFLAGS += -EHsc
|
||||
endif
|
||||
|
||||
# The below is a rough translation of build_angle.gypi,
|
||||
# copied from src/Makefile.in.
|
||||
|
||||
# Target: 'preprocessor'
|
||||
# src/compiler/preprocessor:
|
||||
VPATH += $(srcdir)/../compiler/preprocessor
|
||||
|
||||
# Target: 'translator_common'
|
||||
# Requires: 'preprocessor'
|
||||
VPATH += $(srcdir)/renderer
|
||||
VPATH += $(srcdir)/..
|
||||
VPATH += $(srcdir)/../compiler
|
||||
VPATH += $(srcdir)/../compiler/depgraph
|
||||
VPATH += $(srcdir)/../compiler/timing
|
||||
VPATH += $(srcdir)/../third_party/compiler
|
||||
VPATH += $(srcdir)/../third_party/murmurhash
|
||||
|
||||
# Above should match the relevant targets from angle/Makefile.in.
|
||||
|
||||
VPATH += $(srcdir)/../common
|
||||
# src/common:
|
||||
DEFFILE = $(srcdir)/libGLESv2.def
|
||||
RCFILE = $(srcdir)/libGLESv2.rc
|
||||
|
||||
|
@ -100,20 +100,20 @@ Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
|
||||
#else
|
||||
int lWidth = 2;
|
||||
#endif
|
||||
float opacity = 0.7;
|
||||
float opacity = 0.7f;
|
||||
|
||||
gfx::Color color;
|
||||
if (aFlags & DIAGNOSTIC_CONTENT) {
|
||||
color = gfx::Color(0.0, 1.0, 0.0, 1.0); // green
|
||||
color = gfx::Color(0.0f, 1.0f, 0.0f, 1.0f); // green
|
||||
if (aFlags & DIAGNOSTIC_COMPONENT_ALPHA) {
|
||||
color = gfx::Color(0.0, 1.0, 1.0, 1.0); // greenish blue
|
||||
color = gfx::Color(0.0f, 1.0f, 1.0f, 1.0f); // greenish blue
|
||||
}
|
||||
} else if (aFlags & DIAGNOSTIC_IMAGE) {
|
||||
color = gfx::Color(1.0, 0.0, 0.0, 1.0); // red
|
||||
color = gfx::Color(1.0f, 0.0f, 0.0f, 1.0f); // red
|
||||
} else if (aFlags & DIAGNOSTIC_COLOR) {
|
||||
color = gfx::Color(0.0, 0.0, 1.0, 1.0); // blue
|
||||
color = gfx::Color(0.0f, 0.0f, 1.0f, 1.0f); // blue
|
||||
} else if (aFlags & DIAGNOSTIC_CONTAINER) {
|
||||
color = gfx::Color(0.8, 0.0, 0.8, 1.0); // purple
|
||||
color = gfx::Color(0.8f, 0.0f, 0.8f, 1.0f); // purple
|
||||
}
|
||||
|
||||
// make tile borders a bit more transparent to keep layer borders readable.
|
||||
@ -121,10 +121,10 @@ Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
|
||||
aFlags & DIAGNOSTIC_BIGIMAGE ||
|
||||
aFlags & DIAGNOSTIC_REGION_RECT) {
|
||||
lWidth = 1;
|
||||
opacity = 0.5;
|
||||
color.r *= 0.7;
|
||||
color.g *= 0.7;
|
||||
color.b *= 0.7;
|
||||
opacity = 0.5f;
|
||||
color.r *= 0.7f;
|
||||
color.g *= 0.7f;
|
||||
color.b *= 0.7f;
|
||||
}
|
||||
|
||||
EffectChain effects;
|
||||
|
@ -3,18 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
VPATH = \
|
||||
$(srcdir) \
|
||||
$(srcdir)/basic \
|
||||
$(srcdir)/client \
|
||||
$(srcdir)/composite \
|
||||
$(srcdir)/opengl \
|
||||
$(srcdir)/d3d9 \
|
||||
$(srcdir)/d3d10 \
|
||||
$(srcdir)/d3d11 \
|
||||
$(srcdir)/ipc \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CXXFLAGS += \
|
||||
|
@ -54,6 +54,11 @@ MacIOSurfaceTextureSourceBasic::GetSurface()
|
||||
return mSourceSurface;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureSourceBasic::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = static_cast<BasicCompositor*>(aCompositor);
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureHostBasic::Lock()
|
||||
|
@ -38,9 +38,7 @@ public:
|
||||
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
|
||||
|
||||
void SetCompositor(BasicCompositor* aCompositor) {
|
||||
mCompositor = aCompositor;
|
||||
}
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
BasicCompositor* mCompositor;
|
||||
|
@ -17,23 +17,16 @@ CreateTextureHostBasic(const SurfaceDescriptor& aDesc,
|
||||
ISurfaceAllocator* aDeallocator,
|
||||
TextureFlags aFlags)
|
||||
{
|
||||
RefPtr<TextureHost> result;
|
||||
switch (aDesc.type()) {
|
||||
#ifdef XP_MACOSX
|
||||
case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
|
||||
const SurfaceDescriptorMacIOSurface& desc =
|
||||
aDesc.get_SurfaceDescriptorMacIOSurface();
|
||||
result = new MacIOSurfaceTextureHostBasic(aFlags, desc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
|
||||
break;
|
||||
}
|
||||
if (aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorMacIOSurface) {
|
||||
const SurfaceDescriptorMacIOSurface& desc =
|
||||
aDesc.get_SurfaceDescriptorMacIOSurface();
|
||||
RefPtr<TextureHost> result = new MacIOSurfaceTextureHostBasic(aFlags, desc);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
@ -176,7 +176,7 @@ static void DrawVelGraph(const nsIntRect& aClipRect,
|
||||
|
||||
float opacity = 1.0;
|
||||
EffectChain effects;
|
||||
effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0.2,0,0,1));
|
||||
effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0.2f,0,0,1));
|
||||
compositor->DrawQuad(graphRect,
|
||||
clipRect,
|
||||
effects,
|
||||
|
@ -428,8 +428,10 @@ CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect,
|
||||
srcBox.back = 0;
|
||||
|
||||
const IntSize& srcSize = sourceD3D11->GetSize();
|
||||
if (srcBox.right <= srcSize.width &&
|
||||
srcBox.bottom <= srcSize.height) {
|
||||
MOZ_ASSERT(srcSize.width >= 0 && srcSize.height >= 0,
|
||||
"render targets should have nonnegative sizes");
|
||||
if (srcBox.right <= static_cast<uint32_t>(srcSize.width) &&
|
||||
srcBox.bottom <= static_cast<uint32_t>(srcSize.height)) {
|
||||
mContext->CopySubresourceRegion(texture, 0,
|
||||
0, 0, 0,
|
||||
sourceD3D11->GetD3D11Texture(), 0,
|
||||
|
@ -32,6 +32,7 @@ SurfaceFormatToDXGIFormat(gfx::SurfaceFormat aFormat)
|
||||
return DXGI_FORMAT_A8_UNORM;
|
||||
default:
|
||||
MOZ_ASSERT(false, "unsupported format");
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,8 +235,6 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
|
||||
}
|
||||
case CompositableOperation::TOpUpdateTexture: {
|
||||
const OpUpdateTexture& op = aEdit.get_OpUpdateTexture();
|
||||
CompositableHost* compositable = AsCompositable(op);
|
||||
MOZ_ASSERT(compositable);
|
||||
RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent());
|
||||
MOZ_ASSERT(texture);
|
||||
|
||||
|
@ -303,6 +303,8 @@ IPDL_SOURCES = [
|
||||
'ipc/PTexture.ipdl',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
MSVC_ENABLE_PGO = True
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
@ -845,8 +845,6 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
LOCAL_GL_ONE, LOCAL_GL_ONE);
|
||||
mGLContext->fEnable(LOCAL_GL_BLEND);
|
||||
|
||||
mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
|
||||
|
||||
if (aClipRectOut && !aClipRectIn) {
|
||||
aClipRectOut->SetRect(0, 0, width, height);
|
||||
}
|
||||
@ -1098,6 +1096,8 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
|
||||
}
|
||||
IntRect intClipRect;
|
||||
clipRect.ToIntRect(&intClipRect);
|
||||
|
||||
ScopedGLState scopedScissorTestState(mGLContext, LOCAL_GL_SCISSOR_TEST, true);
|
||||
ScopedScissorRect autoScissor(mGLContext,
|
||||
intClipRect.x,
|
||||
FlipY(intClipRect.y + intClipRect.height),
|
||||
|
@ -141,12 +141,12 @@ GrallocTextureSourceOGL::gl() const
|
||||
}
|
||||
|
||||
void
|
||||
GrallocTextureSourceOGL::SetCompositor(CompositorOGL* aCompositor)
|
||||
GrallocTextureSourceOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
if (mCompositor && !aCompositor) {
|
||||
DeallocateDeviceData();
|
||||
}
|
||||
mCompositor = aCompositor;
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
void SetCompositor(CompositorOGL* aCompositor);
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
void ForgetBuffer()
|
||||
{
|
||||
|
@ -81,6 +81,12 @@ MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit)
|
||||
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureSourceOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
MacIOSurfaceTextureSourceOGL::gl() const
|
||||
{
|
||||
|
@ -44,9 +44,7 @@ public:
|
||||
// MacIOSurfaceTextureSourceOGL doesn't own any gl texture
|
||||
virtual void DeallocateDeviceData() {}
|
||||
|
||||
void SetCompositor(CompositorOGL* aCompositor) {
|
||||
mCompositor = aCompositor;
|
||||
}
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
|
@ -355,9 +355,9 @@ SharedTextureSourceOGL::DetachSharedHandle()
|
||||
}
|
||||
|
||||
void
|
||||
SharedTextureSourceOGL::SetCompositor(CompositorOGL* aCompositor)
|
||||
SharedTextureSourceOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = aCompositor;
|
||||
mCompositor = static_cast<CompositorOGL*>(aCompositor);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -269,7 +269,7 @@ public:
|
||||
|
||||
void DetachSharedHandle();
|
||||
|
||||
void SetCompositor(CompositorOGL* aCompositor);
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
|
@ -3,25 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
VPATH += \
|
||||
$(srcdir)/src/core \
|
||||
$(srcdir)/src/gpu \
|
||||
$(srcdir)/src/gpu/effects \
|
||||
$(srcdir)/src/gpu/gl \
|
||||
$(srcdir)/src/image \
|
||||
$(srcdir)/src/images \
|
||||
$(srcdir)/src/lazy \
|
||||
$(srcdir)/src/pipe \
|
||||
$(srcdir)/src/ports \
|
||||
$(srcdir)/src/opts \
|
||||
$(srcdir)/src/effects \
|
||||
$(srcdir)/src/effects/gradients \
|
||||
$(srcdir)/src/utils \
|
||||
$(srcdir)/src/utils/android \
|
||||
$(srcdir)/src/utils/mac \
|
||||
$(srcdir)/src/sfnt \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gonk))
|
||||
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
|
||||
endif
|
||||
|
@ -137,18 +137,6 @@ public:
|
||||
|
||||
NS_IMPL_ISUPPORTS2(SRGBOverrideObserver, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
SRGBOverrideObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *someData)
|
||||
{
|
||||
NS_ASSERTION(NS_strcmp(someData,
|
||||
MOZ_UTF16("gfx.color_mangement.force_srgb")),
|
||||
"Restarting CMS on wrong pref!");
|
||||
ShutdownCMS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define GFX_DOWNLOADABLE_FONTS_ENABLED "gfx.downloadable_fonts.enabled"
|
||||
|
||||
#define GFX_PREF_HARFBUZZ_SCRIPTS "gfx.font_rendering.harfbuzz.scripts"
|
||||
@ -164,10 +152,29 @@ SRGBOverrideObserver::Observe(nsISupports *aSubject,
|
||||
|
||||
#define BIDI_NUMERAL_PREF "bidi.numeral"
|
||||
|
||||
#define GFX_PREF_CMS_RENDERING_INTENT "gfx.color_management.rendering_intent"
|
||||
#define GFX_PREF_CMS_DISPLAY_PROFILE "gfx.color_management.display_profile"
|
||||
#define GFX_PREF_CMS_ENABLED_OBSOLETE "gfx.color_management.enabled"
|
||||
#define GFX_PREF_CMS_FORCE_SRGB "gfx.color_management.force_srgb"
|
||||
#define GFX_PREF_CMS_ENABLEV4 "gfx.color_management.enablev4"
|
||||
#define GFX_PREF_CMS_MODE "gfx.color_management.mode"
|
||||
|
||||
NS_IMETHODIMP
|
||||
SRGBOverrideObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t* someData)
|
||||
{
|
||||
NS_ASSERTION(NS_strcmp(someData,
|
||||
MOZ_UTF16(GFX_PREF_CMS_FORCE_SRGB)) == 0,
|
||||
"Restarting CMS on wrong pref!");
|
||||
ShutdownCMS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const char* kObservedPrefs[] = {
|
||||
"gfx.downloadable_fonts.",
|
||||
"gfx.font_rendering.",
|
||||
"bidi.numeral",
|
||||
BIDI_NUMERAL_PREF,
|
||||
nullptr
|
||||
};
|
||||
|
||||
@ -454,7 +461,7 @@ gfxPlatform::Init()
|
||||
|
||||
/* Create and register our CMS Override observer. */
|
||||
gPlatform->mSRGBOverrideObserver = new SRGBOverrideObserver();
|
||||
Preferences::AddWeakObserver(gPlatform->mSRGBOverrideObserver, "gfx.color_management.force_srgb");
|
||||
Preferences::AddWeakObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
|
||||
|
||||
gPlatform->mFontPrefsObserver = new FontPrefsObserver();
|
||||
Preferences::AddStrongObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
|
||||
@ -524,7 +531,7 @@ gfxPlatform::Shutdown()
|
||||
if (gPlatform) {
|
||||
/* Unregister our CMS Override callback. */
|
||||
NS_ASSERTION(gPlatform->mSRGBOverrideObserver, "mSRGBOverrideObserver has alreay gone");
|
||||
Preferences::RemoveObserver(gPlatform->mSRGBOverrideObserver, "gfx.color_management.force_srgb");
|
||||
Preferences::RemoveObserver(gPlatform->mSRGBOverrideObserver, GFX_PREF_CMS_FORCE_SRGB);
|
||||
gPlatform->mSRGBOverrideObserver = nullptr;
|
||||
|
||||
NS_ASSERTION(gPlatform->mFontPrefsObserver, "mFontPrefsObserver has alreay gone");
|
||||
@ -1627,13 +1634,13 @@ gfxPlatform::GetCMSMode()
|
||||
nsresult rv;
|
||||
|
||||
int32_t mode;
|
||||
rv = Preferences::GetInt("gfx.color_management.mode", &mode);
|
||||
rv = Preferences::GetInt(GFX_PREF_CMS_MODE, &mode);
|
||||
if (NS_SUCCEEDED(rv) && (mode >= 0) && (mode < eCMSMode_AllCount)) {
|
||||
gCMSMode = static_cast<eCMSMode>(mode);
|
||||
}
|
||||
|
||||
bool enableV4;
|
||||
rv = Preferences::GetBool("gfx.color_management.enablev4", &enableV4);
|
||||
rv = Preferences::GetBool(GFX_PREF_CMS_ENABLEV4, &enableV4);
|
||||
if (NS_SUCCEEDED(rv) && enableV4) {
|
||||
qcms_enable_iccv4();
|
||||
}
|
||||
@ -1648,7 +1655,7 @@ gfxPlatform::GetRenderingIntent()
|
||||
|
||||
/* Try to query the pref system for a rendering intent. */
|
||||
int32_t pIntent;
|
||||
if (NS_SUCCEEDED(Preferences::GetInt("gfx.color_management.rendering_intent", &pIntent))) {
|
||||
if (NS_SUCCEEDED(Preferences::GetInt(GFX_PREF_CMS_RENDERING_INTENT, &pIntent))) {
|
||||
/* If the pref is within range, use it as an override. */
|
||||
if ((pIntent >= QCMS_INTENT_MIN) && (pIntent <= QCMS_INTENT_MAX)) {
|
||||
gCMSIntent = pIntent;
|
||||
@ -1713,12 +1720,12 @@ gfxPlatform::CreateCMSOutputProfile()
|
||||
default value of this preference, which means nsIPrefBranch::GetBoolPref
|
||||
will typically throw (and leave its out-param untouched).
|
||||
*/
|
||||
if (Preferences::GetBool("gfx.color_management.force_srgb", false)) {
|
||||
if (Preferences::GetBool(GFX_PREF_CMS_FORCE_SRGB, false)) {
|
||||
gCMSOutputProfile = GetCMSsRGBProfile();
|
||||
}
|
||||
|
||||
if (!gCMSOutputProfile) {
|
||||
nsAdoptingCString fname = Preferences::GetCString("gfx.color_management.display_profile");
|
||||
nsAdoptingCString fname = Preferences::GetCString(GFX_PREF_CMS_DISPLAY_PROFILE);
|
||||
if (!fname.IsEmpty()) {
|
||||
gCMSOutputProfile = qcms_profile_from_path(fname);
|
||||
}
|
||||
@ -1860,11 +1867,11 @@ static void MigratePrefs()
|
||||
{
|
||||
/* Migrate from the boolean color_management.enabled pref - we now use
|
||||
color_management.mode. */
|
||||
if (Preferences::HasUserValue("gfx.color_management.enabled")) {
|
||||
if (Preferences::GetBool("gfx.color_management.enabled", false)) {
|
||||
Preferences::SetInt("gfx.color_management.mode", static_cast<int32_t>(eCMSMode_All));
|
||||
if (Preferences::HasUserValue(GFX_PREF_CMS_ENABLED_OBSOLETE)) {
|
||||
if (Preferences::GetBool(GFX_PREF_CMS_ENABLED_OBSOLETE, false)) {
|
||||
Preferences::SetInt(GFX_PREF_CMS_MODE, static_cast<int32_t>(eCMSMode_All));
|
||||
}
|
||||
Preferences::ClearUser("gfx.color_management.enabled");
|
||||
Preferences::ClearUser(GFX_PREF_CMS_ENABLED_OBSOLETE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1009,7 +1009,7 @@ ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
|
||||
|
||||
int stackIndex = 0;
|
||||
for (NonBuiltinScriptFrameIter iter(cx); !iter.done(); ++iter) {
|
||||
if (iter.isFunctionFrame()) {
|
||||
if (iter.isFunctionFrame() && iter.compartment() == cx->compartment()) {
|
||||
if (!JS_DefinePropertyById(cx, stack, INT_TO_JSID(stackIndex), ObjectValue(*iter.callee()),
|
||||
JS_PropertyStub, JS_StrictPropertyStub, 0))
|
||||
{
|
||||
|
@ -220,7 +220,7 @@ function isRootedPointerTypeName(name)
|
||||
if (name.startsWith('MaybeRooted<'))
|
||||
return /\(js::AllowGC\)1u>::RootType/.test(name);
|
||||
|
||||
return name.startsWith('Rooted');
|
||||
return name.startsWith('Rooted') || name.startsWith('PersistentRooted');
|
||||
}
|
||||
|
||||
function isSuppressConstructor(name)
|
||||
|
9
js/src/jit-test/tests/basic/bug951632.js
Normal file
9
js/src/jit-test/tests/basic/bug951632.js
Normal file
@ -0,0 +1,9 @@
|
||||
setObjectMetadataCallback(true);
|
||||
var g = newGlobal()
|
||||
g.eval("function f(a) { return h(); }");
|
||||
g.h = function () {
|
||||
return [1, 2, 3];
|
||||
};
|
||||
var o = getObjectMetadata(g.f(5));
|
||||
assertEq(o.stack.length, 1);
|
||||
assertEq(o.stack[0], g.h);
|
@ -14,10 +14,12 @@ function f() {
|
||||
for (var len of [ 3, 30, 300, 3000, 30000 ]) {
|
||||
var arr = ctor(len);
|
||||
for (var i = 0; i < arr.length; i++)
|
||||
assertEq(arr[i], 0);
|
||||
assertEq(arr[i], 0, "index " + i + " of " + ctor.name + " len " + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f();
|
||||
f();
|
||||
gc()
|
||||
f();
|
||||
|
7
js/src/jit-test/tests/ion/bug956156.js
Normal file
7
js/src/jit-test/tests/ion/bug956156.js
Normal file
@ -0,0 +1,7 @@
|
||||
// |jit-test| error:TypeError
|
||||
function f() {
|
||||
((function g(x) {
|
||||
g(x.slice)
|
||||
})([]))
|
||||
}
|
||||
new f
|
@ -6411,11 +6411,11 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache *ool, DataPtr<NameIC> &ic)
|
||||
bool
|
||||
CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool allowGetters)
|
||||
bool allowGetters, bool monitoredResult)
|
||||
{
|
||||
switch (gen->info().executionMode()) {
|
||||
case SequentialExecution: {
|
||||
GetPropertyIC cache(liveRegs, objReg, name, output, allowGetters);
|
||||
GetPropertyIC cache(liveRegs, objReg, name, output, allowGetters, monitoredResult);
|
||||
return addCache(ins, allocateCache(cache));
|
||||
}
|
||||
case ParallelExecution: {
|
||||
@ -6474,9 +6474,10 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
PropertyName *name = ins->mir()->name();
|
||||
bool allowGetters = ins->mir()->allowGetters();
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
TypedOrValueRegister output = TypedOrValueRegister(GetValueOutput(ins));
|
||||
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, allowGetters);
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, allowGetters, monitoredResult);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -6486,9 +6487,10 @@ CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins)
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
PropertyName *name = ins->mir()->name();
|
||||
bool allowGetters = ins->mir()->allowGetters();
|
||||
bool monitoredResult = ins->mir()->monitoredResult();
|
||||
TypedOrValueRegister output(ins->mir()->type(), ToAnyRegister(ins->getDef(0)));
|
||||
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, allowGetters);
|
||||
return addGetPropertyCache(ins, liveRegs, objReg, name, output, allowGetters, monitoredResult);
|
||||
}
|
||||
|
||||
typedef bool (*GetPropertyICFn)(JSContext *, size_t, HandleObject, MutableHandleValue);
|
||||
|
@ -345,7 +345,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
private:
|
||||
bool addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool allowGetters);
|
||||
bool allowGetters, bool monitoredResult);
|
||||
bool addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult);
|
||||
|
@ -4683,7 +4683,8 @@ IonBuilder::createThisScripted(MDefinition *callee)
|
||||
// and thus invalidation.
|
||||
MInstruction *getProto;
|
||||
if (!invalidatedIdempotentCache()) {
|
||||
MGetPropertyCache *getPropCache = MGetPropertyCache::New(alloc(), callee, names().prototype);
|
||||
MGetPropertyCache *getPropCache = MGetPropertyCache::New(alloc(), callee, names().prototype,
|
||||
/* monitored = */ false);
|
||||
getPropCache->setIdempotent();
|
||||
getProto = getPropCache;
|
||||
} else {
|
||||
@ -8612,8 +8613,19 @@ IonBuilder::getPropTryCache(bool *emitted, PropertyName *name,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (accessGetter)
|
||||
barrier = true;
|
||||
|
||||
if (needsToMonitorMissingProperties(types))
|
||||
barrier = true;
|
||||
|
||||
// Caches can read values from prototypes, so update the barrier to
|
||||
// reflect such possible values.
|
||||
if (!barrier)
|
||||
barrier = PropertyReadOnPrototypeNeedsTypeBarrier(constraints(), obj, name, types);
|
||||
|
||||
current->pop();
|
||||
MGetPropertyCache *load = MGetPropertyCache::New(alloc(), obj, name);
|
||||
MGetPropertyCache *load = MGetPropertyCache::New(alloc(), obj, name, barrier);
|
||||
|
||||
// Try to mark the cache as idempotent.
|
||||
//
|
||||
@ -8643,17 +8655,6 @@ IonBuilder::getPropTryCache(bool *emitted, PropertyName *name,
|
||||
if (load->isEffectful() && !resumeAfter(load))
|
||||
return false;
|
||||
|
||||
if (accessGetter)
|
||||
barrier = true;
|
||||
|
||||
if (needsToMonitorMissingProperties(types))
|
||||
barrier = true;
|
||||
|
||||
// Caches can read values from prototypes, so update the barrier to
|
||||
// reflect such possible values.
|
||||
if (!barrier)
|
||||
barrier = PropertyReadOnPrototypeNeedsTypeBarrier(constraints(), obj, name, types);
|
||||
|
||||
MIRType rvalType = MIRTypeFromValueType(types->getKnownTypeTag());
|
||||
if (barrier || IsNullOrUndefined(rvalType))
|
||||
rvalType = MIRType_Value;
|
||||
|
@ -1749,7 +1749,8 @@ GetPropertyIC::update(JSContext *cx, size_t cacheIndex,
|
||||
#endif
|
||||
|
||||
// Monitor changes to cache entry.
|
||||
types::TypeScript::Monitor(cx, script, pc, vp);
|
||||
if (!cache.monitoredResult())
|
||||
types::TypeScript::Monitor(cx, script, pc, vp);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -3416,7 +3417,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
if (cache.isDisabled()) {
|
||||
if (!GetObjectElementOperation(cx, JSOp(*pc), obj, /* wasObject = */true, idval, res))
|
||||
return false;
|
||||
types::TypeScript::Monitor(cx, script, pc, res);
|
||||
if (!cache.monitoredResult())
|
||||
types::TypeScript::Monitor(cx, script, pc, res);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3472,7 +3474,8 @@ GetElementIC::update(JSContext *cx, size_t cacheIndex, HandleObject obj,
|
||||
cache.resetFailedUpdates();
|
||||
}
|
||||
|
||||
types::TypeScript::Monitor(cx, script, pc, res);
|
||||
if (!cache.monitoredResult())
|
||||
types::TypeScript::Monitor(cx, script, pc, res);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -531,6 +531,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
size_t numLocations_;
|
||||
|
||||
bool allowGetters_ : 1;
|
||||
bool monitoredResult_ : 1;
|
||||
bool hasTypedArrayLengthStub_ : 1;
|
||||
bool hasStrictArgumentsLengthStub_ : 1;
|
||||
bool hasNormalArgumentsLengthStub_ : 1;
|
||||
@ -540,7 +541,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
GetPropertyIC(RegisterSet liveRegs,
|
||||
Register object, PropertyName *name,
|
||||
TypedOrValueRegister output,
|
||||
bool allowGetters)
|
||||
bool allowGetters, bool monitoredResult)
|
||||
: liveRegs_(liveRegs),
|
||||
object_(object),
|
||||
name_(name),
|
||||
@ -548,6 +549,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
locationsIndex_(0),
|
||||
numLocations_(0),
|
||||
allowGetters_(allowGetters),
|
||||
monitoredResult_(monitoredResult),
|
||||
hasTypedArrayLengthStub_(false),
|
||||
hasStrictArgumentsLengthStub_(false),
|
||||
hasNormalArgumentsLengthStub_(false),
|
||||
@ -571,6 +573,9 @@ class GetPropertyIC : public RepatchIonCache
|
||||
bool allowGetters() const {
|
||||
return allowGetters_ && !idempotent();
|
||||
}
|
||||
bool monitoredResult() const {
|
||||
return monitoredResult_;
|
||||
}
|
||||
bool hasTypedArrayLengthStub() const {
|
||||
return hasTypedArrayLengthStub_;
|
||||
}
|
||||
|
@ -587,9 +587,15 @@ LinearScanAllocator::populateSafepoints()
|
||||
|
||||
// If the payload is an argument, we'll scan that explicitly as
|
||||
// part of the frame. It is therefore safe to not add any
|
||||
// safepoint entry.
|
||||
if (payloadAlloc->isArgument())
|
||||
// safepoint entry, as long as the vreg does not have a stack
|
||||
// slot as canonical spill slot.
|
||||
if (payloadAlloc->isArgument() &&
|
||||
(!payload->canonicalSpill() || payload->canonicalSpill() == payloadAlloc))
|
||||
{
|
||||
JS_ASSERT(typeAlloc->isArgument());
|
||||
JS_ASSERT(!type->canonicalSpill() || type->canonicalSpill() == typeAlloc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isSpilledAt(typeInterval, inputOf(ins)) &&
|
||||
isSpilledAt(payloadInterval, inputOf(ins)))
|
||||
|
@ -6572,16 +6572,18 @@ class MGetPropertyCache
|
||||
CompilerRootPropertyName name_;
|
||||
bool idempotent_;
|
||||
bool allowGetters_;
|
||||
bool monitoredResult_;
|
||||
|
||||
CacheLocationList location_;
|
||||
|
||||
InlinePropertyTable *inlinePropertyTable_;
|
||||
|
||||
MGetPropertyCache(MDefinition *obj, PropertyName *name)
|
||||
MGetPropertyCache(MDefinition *obj, PropertyName *name, bool monitoredResult)
|
||||
: MUnaryInstruction(obj),
|
||||
name_(name),
|
||||
idempotent_(false),
|
||||
allowGetters_(false),
|
||||
monitoredResult_(monitoredResult),
|
||||
location_(),
|
||||
inlinePropertyTable_(nullptr)
|
||||
{
|
||||
@ -6596,8 +6598,9 @@ class MGetPropertyCache
|
||||
public:
|
||||
INSTRUCTION_HEADER(GetPropertyCache)
|
||||
|
||||
static MGetPropertyCache *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name) {
|
||||
return new(alloc) MGetPropertyCache(obj, name);
|
||||
static MGetPropertyCache *New(TempAllocator &alloc, MDefinition *obj, PropertyName *name,
|
||||
bool monitoredResult) {
|
||||
return new(alloc) MGetPropertyCache(obj, name, monitoredResult);
|
||||
}
|
||||
|
||||
InlinePropertyTable *initInlinePropertyTable(TempAllocator &alloc, jsbytecode *pc) {
|
||||
@ -6630,6 +6633,9 @@ class MGetPropertyCache
|
||||
bool allowGetters() const {
|
||||
return allowGetters_;
|
||||
}
|
||||
bool monitoredResult() const {
|
||||
return monitoredResult_;
|
||||
}
|
||||
void setAllowGetters() {
|
||||
allowGetters_ = true;
|
||||
}
|
||||
|
@ -1041,8 +1041,6 @@ CheckDefinitePropertiesTypeSet(JSContext *cx, TemporaryTypeSet *frozen, StackTyp
|
||||
// contents of |frozen| though with new speculative types, and these need
|
||||
// to be reflected in |actual| for AddClearDefiniteFunctionUsesInScript
|
||||
// to work.
|
||||
JS_ASSERT(actual->isSubset(frozen));
|
||||
|
||||
if (!frozen->isSubset(actual)) {
|
||||
TypeSet::TypeList list;
|
||||
frozen->enumerateTypes(&list);
|
||||
@ -1055,16 +1053,40 @@ CheckDefinitePropertiesTypeSet(JSContext *cx, TemporaryTypeSet *frozen, StackTyp
|
||||
void
|
||||
types::FinishDefinitePropertiesAnalysis(JSContext *cx, CompilerConstraintList *constraints)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Assert no new types have been added to the StackTypeSets. Do this before
|
||||
// calling CheckDefinitePropertiesTypeSet, as it may add new types to the
|
||||
// StackTypeSets and break these invariants if a script is inlined more
|
||||
// than once. See also CheckDefinitePropertiesTypeSet.
|
||||
for (size_t i = 0; i < constraints->numFrozenScripts(); i++) {
|
||||
const CompilerConstraintList::FrozenScript &entry = constraints->frozenScript(i);
|
||||
JS_ASSERT(entry.script->types);
|
||||
JSScript *script = entry.script;
|
||||
JS_ASSERT(script->types);
|
||||
|
||||
CheckDefinitePropertiesTypeSet(cx, entry.thisTypes, types::TypeScript::ThisTypes(entry.script));
|
||||
unsigned nargs = entry.script->function() ? entry.script->function()->nargs() : 0;
|
||||
for (size_t i = 0; i < nargs; i++)
|
||||
CheckDefinitePropertiesTypeSet(cx, &entry.argTypes[i], types::TypeScript::ArgTypes(entry.script, i));
|
||||
for (size_t i = 0; i < entry.script->nTypeSets(); i++)
|
||||
CheckDefinitePropertiesTypeSet(cx, &entry.bytecodeTypes[i], &entry.script->types->typeArray()[i]);
|
||||
JS_ASSERT(TypeScript::ThisTypes(script)->isSubset(entry.thisTypes));
|
||||
|
||||
unsigned nargs = script->function() ? script->function()->nargs() : 0;
|
||||
for (size_t j = 0; j < nargs; j++)
|
||||
JS_ASSERT(TypeScript::ArgTypes(script, j)->isSubset(&entry.argTypes[j]));
|
||||
|
||||
for (size_t j = 0; j < script->nTypeSets(); j++)
|
||||
JS_ASSERT(script->types->typeArray()[j].isSubset(&entry.bytecodeTypes[j]));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < constraints->numFrozenScripts(); i++) {
|
||||
const CompilerConstraintList::FrozenScript &entry = constraints->frozenScript(i);
|
||||
JSScript *script = entry.script;
|
||||
JS_ASSERT(script->types);
|
||||
|
||||
CheckDefinitePropertiesTypeSet(cx, entry.thisTypes, TypeScript::ThisTypes(script));
|
||||
|
||||
unsigned nargs = script->function() ? script->function()->nargs() : 0;
|
||||
for (size_t j = 0; j < nargs; j++)
|
||||
CheckDefinitePropertiesTypeSet(cx, &entry.argTypes[j], TypeScript::ArgTypes(script, j));
|
||||
|
||||
for (size_t j = 0; j < script->nTypeSets(); j++)
|
||||
CheckDefinitePropertiesTypeSet(cx, &entry.bytecodeTypes[j], &script->types->typeArray()[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1216,10 +1216,19 @@ ScriptSource::setSourceCopy(ExclusiveContext *cx, const jschar *src, uint32_t le
|
||||
length_ = length;
|
||||
argumentsNotIncluded_ = argumentsNotIncluded;
|
||||
|
||||
// Don't use background compression if there is only one core since this
|
||||
// will contend with JS execution (which affects benchmarketting). Also,
|
||||
// since this thread is about to perform a blocking wait, require that there
|
||||
// are at least 2 worker threads:
|
||||
// There are several cases where source compression is not a good idea:
|
||||
// - If the script is enormous, then decompression can take seconds. With
|
||||
// lazy parsing, decompression is not uncommon, so this can significantly
|
||||
// increase latency.
|
||||
// - If there is only one core, then compression will contend with JS
|
||||
// execution (which hurts benchmarketing).
|
||||
// - If the source contains a giant string, then parsing will finish much
|
||||
// faster than compression which increases latency (this case is handled
|
||||
// in Parser::stringLiteral).
|
||||
//
|
||||
// Lastly, since the parsing thread will eventually perform a blocking wait
|
||||
// on the compresion task's worker thread, require that there are at least 2
|
||||
// worker threads:
|
||||
// - If we are on a worker thread, there must be another worker thread to
|
||||
// execute our compression task.
|
||||
// - If we are on the main thread, there must be at least two worker
|
||||
@ -1227,7 +1236,11 @@ ScriptSource::setSourceCopy(ExclusiveContext *cx, const jschar *src, uint32_t le
|
||||
// thread (see WorkerThreadState::canStartParseTask) which would cause a
|
||||
// deadlock if there wasn't a second worker thread that could make
|
||||
// progress on our compression task.
|
||||
if (task && cx->cpuCount() > 1 && cx->workerThreadCount() >= 2) {
|
||||
const size_t HUGE_SCRIPT = 5 * 1024 * 1024;
|
||||
if (length < HUGE_SCRIPT &&
|
||||
cx->cpuCount() > 1 &&
|
||||
cx->workerThreadCount() >= 2)
|
||||
{
|
||||
task->ss = this;
|
||||
task->chars = src;
|
||||
ready_ = false;
|
||||
|
@ -249,7 +249,7 @@ AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr =
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayBufferObject::allocateSlots(JSContext *maybecx, uint32_t bytes)
|
||||
ArrayBufferObject::allocateSlots(JSContext *maybecx, uint32_t bytes, bool clear)
|
||||
{
|
||||
/*
|
||||
* ArrayBufferObjects delegate added properties to another JSObject, so
|
||||
@ -267,6 +267,8 @@ ArrayBufferObject::allocateSlots(JSContext *maybecx, uint32_t bytes)
|
||||
elements = header->elements();
|
||||
} else {
|
||||
setFixedElements();
|
||||
if (clear)
|
||||
memset(dataPointer(), 0, bytes);
|
||||
}
|
||||
|
||||
initElementsHeader(getElementsHeader(), bytes);
|
||||
@ -631,12 +633,9 @@ ArrayBufferObject::create(JSContext *cx, uint32_t nbytes, bool clear /* = true *
|
||||
* The beginning stores an ObjectElements header structure holding the
|
||||
* length. The rest of it is a flat data store for the array buffer.
|
||||
*/
|
||||
if (!obj->as<ArrayBufferObject>().allocateSlots(cx, nbytes))
|
||||
if (!obj->as<ArrayBufferObject>().allocateSlots(cx, nbytes, clear))
|
||||
return nullptr;
|
||||
|
||||
if (clear)
|
||||
memset(obj->as<ArrayBufferObject>().dataPointer(), 0, nbytes);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ class ArrayBufferObject : public JSObject
|
||||
|
||||
void addView(ArrayBufferViewObject *view);
|
||||
|
||||
bool allocateSlots(JSContext *cx, uint32_t size);
|
||||
bool allocateSlots(JSContext *cx, uint32_t size, bool clear);
|
||||
|
||||
void changeContents(JSContext *cx, ObjectElements *newHeader);
|
||||
|
||||
|
@ -258,15 +258,8 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString& url,
|
||||
if (!targetObj)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (targetObj != result_obj) {
|
||||
nsCOMPtr<nsIScriptSecurityManager> secman =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
|
||||
if (!secman)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = secman->GetObjectPrincipal(cx, targetObj, getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (targetObj != result_obj)
|
||||
principal = GetObjectPrincipal(targetObj);
|
||||
|
||||
JSAutoCompartment ac(cx, targetObj);
|
||||
|
||||
|
@ -652,14 +652,9 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
|
||||
return NS_NOINTERFACE;
|
||||
|
||||
RootedObject selfObj(ccx, self->GetJSObject());
|
||||
nsCOMPtr<nsIPrincipal> objPrin;
|
||||
nsresult rv = secMan->GetObjectPrincipal(ccx, selfObj,
|
||||
getter_AddRefs(objPrin));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> objPrin = GetObjectPrincipal(selfObj);
|
||||
bool isSystem;
|
||||
rv = secMan->IsSystemPrincipal(objPrin, &isSystem);
|
||||
nsresult rv = secMan->IsSystemPrincipal(objPrin, &isSystem);
|
||||
if ((NS_FAILED(rv) || !isSystem) && !IS_WN_REFLECTOR(selfObj)) {
|
||||
// A content object.
|
||||
nsRefPtr<SameOriginCheckedComponent> checked =
|
||||
|
6
js/xpconnect/tests/unit/test_getObjectPrincipal.js
Normal file
6
js/xpconnect/tests/unit/test_getObjectPrincipal.js
Normal file
@ -0,0 +1,6 @@
|
||||
function run_test() {
|
||||
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].getService(
|
||||
Components.interfaces.nsIScriptSecurityManager);
|
||||
|
||||
do_check_true(secMan.isSystemPrincipal(secMan.getObjectPrincipal({})));
|
||||
}
|
@ -72,6 +72,7 @@ fail-if = os == "android"
|
||||
[test_url.js]
|
||||
[test_sandbox_atob.js]
|
||||
[test_isProxy.js]
|
||||
[test_getObjectPrincipal.js]
|
||||
[test_watchdog_enable.js]
|
||||
head = head_watchdog.js
|
||||
[test_watchdog_disable.js]
|
||||
|
27
layout/reftests/svg/g-transform-01.svg
Normal file
27
layout/reftests/svg/g-transform-01.svg
Normal file
@ -0,0 +1,27 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait">
|
||||
<script>
|
||||
document.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
setTimeout(doTest, 4000); // fallback for running outside reftest
|
||||
|
||||
function doTest() {
|
||||
document.getElementById("g").transform.baseVal.getItem(0).setTranslate(20, 20);
|
||||
document.getElementById("r2").transform.baseVal.getItem(0).setTranslate(70, 70);
|
||||
document.getElementById("r1").transform.baseVal.getItem(0).setTranslate(180, 180);
|
||||
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
</script>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<g transform="translate(20 20)">
|
||||
<rect transform="translate(70 70)" width="40" height="40" fill="red"/>
|
||||
<rect transform="translate(180 180)" width="40" height="40" fill="red"/>
|
||||
</g>
|
||||
<g transform="translate(0 1)" id="g">
|
||||
<rect transform="translate(49 49)" width="42" height="42" id="r2" fill="lime"/>
|
||||
<rect transform="translate(89 89)" width="42" height="42" id="r1" fill="lime"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
@ -173,6 +173,7 @@ skip-if(B2G) == foreignObject-style-change-01.svg pass.svg
|
||||
== foreignObject-dynamic-abspos-01.html foreignObject-dynamic-abspos-01-ref.html
|
||||
fuzzy-if(Android,18,600) == foreignObject-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html
|
||||
== foreignObject-dynamic-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html
|
||||
== g-transform-01.svg pass.svg
|
||||
== getElementById-a-element-01.svg pass.svg
|
||||
fuzzy-if(Android||B2G,9,980) == gradient-live-01a.svg gradient-live-01-ref.svg
|
||||
fuzzy-if(Android||B2G,9,980) == gradient-live-01b.svg gradient-live-01-ref.svg
|
||||
|
@ -3058,7 +3058,8 @@ class nsDisplaySVGText : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplaySVGText(nsDisplayListBuilder* aBuilder,
|
||||
SVGTextFrame* aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame),
|
||||
mDisableSubpixelAA(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplaySVGText);
|
||||
NS_ABORT_IF_FALSE(aFrame, "Must have a frame!");
|
||||
@ -3071,10 +3072,15 @@ public:
|
||||
|
||||
NS_DISPLAY_DECL_NAME("nsDisplaySVGText", TYPE_SVG_TEXT)
|
||||
|
||||
virtual void DisableComponentAlpha() MOZ_OVERRIDE {
|
||||
mDisableSubpixelAA = true;
|
||||
}
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx);
|
||||
private:
|
||||
bool mDisableSubpixelAA;
|
||||
};
|
||||
|
||||
void
|
||||
@ -3097,6 +3103,9 @@ void
|
||||
nsDisplaySVGText::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
gfxContextAutoDisableSubpixelAntialiasing
|
||||
disable(aCtx->ThebesContext(), mDisableSubpixelAA);
|
||||
|
||||
// ToReferenceFrame includes our mRect offset, but painting takes
|
||||
// account of that too. To avoid double counting, we subtract that
|
||||
// here.
|
||||
|
@ -426,7 +426,7 @@ stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
c = strchr(munged_ifname, '.');
|
||||
while (c != NULL) {
|
||||
*c = '+';
|
||||
c = strchr(munged_ifname, '+');
|
||||
c = strchr(munged_ifname, '.');
|
||||
}
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Converted ifname: %s", munged_ifname);
|
||||
|
@ -813,3 +813,9 @@ pref("browser.snippets.statsUrl", "https://snippets-stats.mozilla.org/mobile");
|
||||
|
||||
// This pref requires a restart to take effect.
|
||||
pref("browser.snippets.enabled", false);
|
||||
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
// The URL of the APK factory from which we obtain APKs for webapps.
|
||||
// XXX This currently points to jhugman's prototype server.
|
||||
pref("browser.webapps.apkFactoryUrl", "http://107.22.148.17:8080/application.apk");
|
||||
#endif
|
||||
|
@ -156,6 +156,25 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
<activity android:name="org.mozilla.gecko.webapp.WebAppDispatcher"
|
||||
android:noHistory="true" >
|
||||
<intent-filter>
|
||||
<!-- catch links from synthetic apks -->
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/webapp" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name="org.mozilla.gecko.webapp.UninstallListener" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED" />
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
#endif
|
||||
|
||||
<activity android:name=".WebApp"
|
||||
android:label="@string/webapp_generic_name"
|
||||
android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize"
|
||||
@ -178,7 +197,7 @@
|
||||
this number in sync with the total number of web apps handled in
|
||||
WebAppAllocator. -->
|
||||
|
||||
#define FRAGMENT WebAppManifestFragment.xml.frag
|
||||
#define FRAGMENT WebAppManifestFragment.xml.frag.in
|
||||
#include WebAppFragmentRepeater.inc
|
||||
|
||||
<!-- Masquerade as the Resolver so that we can be opened from the Marketplace. -->
|
||||
|
@ -139,6 +139,13 @@ public class AppConstants {
|
||||
false;
|
||||
#endif
|
||||
|
||||
public static final boolean MOZ_ANDROID_SYNTHAPKS =
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
// See this wiki page for more details about channel specific build defines:
|
||||
// https://wiki.mozilla.org/Platform/Channel-specific_build_defines
|
||||
public static final boolean RELEASE_BUILD =
|
||||
|
@ -28,6 +28,7 @@ import org.mozilla.gecko.util.GeckoEventResponder;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
import org.mozilla.gecko.webapp.UninstallListener;
|
||||
import org.mozilla.gecko.widget.ButtonToast;
|
||||
|
||||
import org.json.JSONArray;
|
||||
@ -55,6 +56,7 @@ import android.location.LocationListener;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Environment;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@ -631,6 +633,25 @@ public abstract class GeckoApp
|
||||
final String title = message.getString("title");
|
||||
final String type = message.getString("shortcutType");
|
||||
GeckoAppShell.removeShortcut(title, url, origin, type);
|
||||
} else if (AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:InstallApk")) {
|
||||
GeckoAppShell.installApk(this, message.getString("filePath"), message.getString("data"));
|
||||
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:PreInstall")) {
|
||||
String name = message.getString("name");
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String origin = message.getString("origin");
|
||||
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
|
||||
mCurrentResponse = GeckoAppShell.preInstallWebApp(name, manifestURL, origin).toString();
|
||||
} else if (event.equals("WebApps:PostInstall")) {
|
||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||
GeckoAppShell.postInstallWebApp(message.getString("packageName"), message.getString("origin"));
|
||||
} else {
|
||||
String name = message.getString("name");
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String iconURL = message.getString("iconURL");
|
||||
String originalOrigin = message.getString("originalOrigin");
|
||||
String origin = message.getString("origin");
|
||||
GeckoAppShell.postInstallWebApp(name, manifestURL, origin, iconURL, originalOrigin);
|
||||
}
|
||||
} else if (event.equals("WebApps:Open")) {
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String origin = message.getString("origin");
|
||||
@ -638,30 +659,8 @@ public abstract class GeckoApp
|
||||
if (intent == null)
|
||||
return;
|
||||
startActivity(intent);
|
||||
} else if (event.equals("WebApps:Install")) {
|
||||
String name = message.getString("name");
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String iconURL = message.getString("iconURL");
|
||||
String origin = message.getString("origin");
|
||||
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
|
||||
mCurrentResponse = GeckoAppShell.preInstallWebApp(name, manifestURL, origin).toString();
|
||||
GeckoAppShell.postInstallWebApp(name, manifestURL, origin, iconURL, origin);
|
||||
} else if (event.equals("WebApps:PreInstall")) {
|
||||
String name = message.getString("name");
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String origin = message.getString("origin");
|
||||
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
|
||||
mCurrentResponse = GeckoAppShell.preInstallWebApp(name, manifestURL, origin).toString();
|
||||
} else if (event.equals("WebApps:PostInstall")) {
|
||||
String name = message.getString("name");
|
||||
String manifestURL = message.getString("manifestURL");
|
||||
String iconURL = message.getString("iconURL");
|
||||
String originalOrigin = message.getString("originalOrigin");
|
||||
String origin = message.getString("origin");
|
||||
GeckoAppShell.postInstallWebApp(name, manifestURL, origin, iconURL, originalOrigin);
|
||||
} else if (event.equals("WebApps:Uninstall")) {
|
||||
String origin = message.getString("origin");
|
||||
GeckoAppShell.uninstallWebApp(origin);
|
||||
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:Uninstall")) {
|
||||
GeckoAppShell.uninstallWebApp(message.getString("origin"));
|
||||
} else if (event.equals("Share:Text")) {
|
||||
String text = message.getString("text");
|
||||
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, "");
|
||||
@ -1342,6 +1341,11 @@ public abstract class GeckoApp
|
||||
GeckoApp.this.onLocaleReady(uiLocale);
|
||||
}
|
||||
});
|
||||
|
||||
// Perform webapp uninstalls as appropiate.
|
||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||
UninstallListener.initUninstallPackageScan(getApplicationContext());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -1558,10 +1562,11 @@ public abstract class GeckoApp
|
||||
registerEventListener("Accessibility:Event");
|
||||
registerEventListener("Accessibility:Ready");
|
||||
registerEventListener("Shortcut:Remove");
|
||||
registerEventListener("WebApps:Open");
|
||||
// TODO Consider moving webapp install-related things into InstallHelper.
|
||||
registerEventListener("WebApps:InstallApk");
|
||||
registerEventListener("WebApps:PreInstall");
|
||||
registerEventListener("WebApps:PostInstall");
|
||||
registerEventListener("WebApps:Install");
|
||||
registerEventListener("WebApps:Open");
|
||||
registerEventListener("WebApps:Uninstall");
|
||||
registerEventListener("Share:Text");
|
||||
registerEventListener("Share:Image");
|
||||
@ -1898,6 +1903,9 @@ public abstract class GeckoApp
|
||||
Tabs.LOADURL_USER_ENTERED |
|
||||
Tabs.LOADURL_EXTERNAL);
|
||||
} else if (action != null && action.startsWith(ACTION_WEBAPP_PREFIX)) {
|
||||
// A lightweight mechanism for loading a web page as a webapp
|
||||
// without installing the app natively nor registering it in the DOM
|
||||
// application registry.
|
||||
String uri = getURIFromIntent(intent);
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createWebappLoadEvent(uri));
|
||||
} else if (ACTION_BOOKMARK.equals(action)) {
|
||||
@ -2085,10 +2093,10 @@ public abstract class GeckoApp
|
||||
unregisterEventListener("Accessibility:Event");
|
||||
unregisterEventListener("Accessibility:Ready");
|
||||
unregisterEventListener("Shortcut:Remove");
|
||||
unregisterEventListener("WebApps:Open");
|
||||
unregisterEventListener("WebApps:InstallApk");
|
||||
unregisterEventListener("WebApps:PreInstall");
|
||||
unregisterEventListener("WebApps:PostInstall");
|
||||
unregisterEventListener("WebApps:Install");
|
||||
unregisterEventListener("WebApps:Open");
|
||||
unregisterEventListener("WebApps:Uninstall");
|
||||
unregisterEventListener("Share:Text");
|
||||
unregisterEventListener("Share:Image");
|
||||
|
@ -16,11 +16,16 @@ import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
|
||||
import org.mozilla.gecko.prompts.PromptService;
|
||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import org.mozilla.gecko.util.ActivityResultHandler;
|
||||
import org.mozilla.gecko.util.EventDispatcher;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.ProxySelector;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.webapp.InstallListener;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
@ -28,6 +33,7 @@ import android.app.PendingIntent;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@ -62,6 +68,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@ -97,6 +104,7 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
@ -372,6 +380,7 @@ public class GeckoAppShell
|
||||
});
|
||||
|
||||
// and go
|
||||
Log.d(LOGTAG, "GeckoLoader.nativeRun " + combinedArgs);
|
||||
GeckoLoader.nativeRun(combinedArgs);
|
||||
|
||||
// Remove pumpMessageLoop() idle handler
|
||||
@ -700,33 +709,61 @@ public class GeckoAppShell
|
||||
gRestartScheduled = true;
|
||||
}
|
||||
|
||||
// The old implementation of preInstallWebApp. Not used by MOZ_ANDROID_SYNTHAPKS.
|
||||
public static File preInstallWebApp(String aTitle, String aURI, String aOrigin) {
|
||||
int index = WebAppAllocator.getInstance(getContext()).findAndAllocateIndex(aOrigin, aTitle, (String) null);
|
||||
GeckoProfile profile = GeckoProfile.get(getContext(), "webapp" + index);
|
||||
return profile.getDir();
|
||||
}
|
||||
|
||||
// The old implementation of postInstallWebApp. Not used by MOZ_ANDROID_SYNTHAPKS.
|
||||
public static void postInstallWebApp(String aTitle, String aURI, String aOrigin, String aIconURL, String aOriginalOrigin) {
|
||||
WebAppAllocator allocator = WebAppAllocator.getInstance(getContext());
|
||||
int index = allocator.getIndexForApp(aOriginalOrigin);
|
||||
assert index != -1 && aIconURL != null;
|
||||
allocator.updateAppAllocation(aOrigin, index, BitmapUtils.getBitmapFromDataURI(aIconURL));
|
||||
createShortcut(aTitle, aURI, aOrigin, aIconURL, "webapp");
|
||||
WebAppAllocator allocator = WebAppAllocator.getInstance(getContext());
|
||||
int index = allocator.getIndexForApp(aOriginalOrigin);
|
||||
assert index != -1 && aIconURL != null;
|
||||
allocator.updateAppAllocation(aOrigin, index, BitmapUtils.getBitmapFromDataURI(aIconURL));
|
||||
createShortcut(aTitle, aURI, aOrigin, aIconURL, "webapp");
|
||||
}
|
||||
|
||||
// The new implementation of postInstallWebApp. Used by MOZ_ANDROID_SYNTHAPKS.
|
||||
public static void postInstallWebApp(String aPackageName, String aOrigin) {
|
||||
org.mozilla.gecko.webapp.WebAppAllocator allocator = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext());
|
||||
int index = allocator.findOrAllocatePackage(aPackageName);
|
||||
allocator.putOrigin(index, aOrigin);
|
||||
}
|
||||
|
||||
public static Intent getWebAppIntent(String aURI, String aOrigin, String aTitle, Bitmap aIcon) {
|
||||
int index;
|
||||
if (aIcon != null && !TextUtils.isEmpty(aTitle))
|
||||
index = WebAppAllocator.getInstance(getContext()).findAndAllocateIndex(aOrigin, aTitle, aIcon);
|
||||
else
|
||||
index = WebAppAllocator.getInstance(getContext()).getIndexForApp(aOrigin);
|
||||
Intent intent;
|
||||
|
||||
if (index == -1)
|
||||
return null;
|
||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||
org.mozilla.gecko.webapp.WebAppAllocator slots = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext());
|
||||
int index = slots.getIndexForOrigin(aOrigin);
|
||||
|
||||
return getWebAppIntent(index, aURI);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
String packageName = slots.getAppForIndex(index);
|
||||
intent = getContext().getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
if (aURI != null) {
|
||||
intent.setData(Uri.parse(aURI));
|
||||
}
|
||||
} else {
|
||||
int index;
|
||||
if (aIcon != null && !TextUtils.isEmpty(aTitle))
|
||||
index = WebAppAllocator.getInstance(getContext()).findAndAllocateIndex(aOrigin, aTitle, aIcon);
|
||||
else
|
||||
index = WebAppAllocator.getInstance(getContext()).getIndexForApp(aOrigin);
|
||||
|
||||
if (index == -1)
|
||||
return null;
|
||||
|
||||
intent = getWebAppIntent(index, aURI);
|
||||
}
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
// The old implementation of getWebAppIntent. Not used by MOZ_ANDROID_SYNTHAPKS.
|
||||
public static Intent getWebAppIntent(int aIndex, String aURI) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(GeckoApp.ACTION_WEBAPP_PREFIX + aIndex);
|
||||
@ -803,7 +840,6 @@ public class GeckoAppShell
|
||||
// the intent to be launched by the shortcut
|
||||
Intent shortcutIntent;
|
||||
if (aType.equalsIgnoreCase(SHORTCUT_TYPE_WEBAPP)) {
|
||||
int index = WebAppAllocator.getInstance(getContext()).getIndexForApp(aUniqueURI);
|
||||
shortcutIntent = getWebAppIntent(aURI, aUniqueURI, "", null);
|
||||
if (shortcutIntent == null)
|
||||
return;
|
||||
@ -835,7 +871,12 @@ public class GeckoAppShell
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int index = WebAppAllocator.getInstance(getContext()).releaseIndexForApp(uniqueURI);
|
||||
int index;
|
||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||
index = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext()).releaseIndexForApp(uniqueURI);
|
||||
} else {
|
||||
index = WebAppAllocator.getInstance(getContext()).releaseIndexForApp(uniqueURI);
|
||||
}
|
||||
|
||||
// if -1, nothing to do; we didn't think it was installed anyway
|
||||
if (index == -1)
|
||||
@ -2681,4 +2722,55 @@ public class GeckoAppShell
|
||||
|
||||
return "DIRECT";
|
||||
}
|
||||
|
||||
public static void installApk(final Activity context, String filePath, String data) {
|
||||
// This is the data that mozApps.install sent to Webapps.jsm.
|
||||
JSONObject argsObj = null;
|
||||
|
||||
// We get the manifest url out of javascript here so we can use it as a checksum
|
||||
// in a minute, when a package has been installed.
|
||||
String manifestUrl = null;
|
||||
try {
|
||||
argsObj = new JSONObject(data);
|
||||
manifestUrl = argsObj.getJSONObject("app").getString("manifestURL");
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "can't get manifest URL from JSON data", e);
|
||||
// TODO: propagate the error back to the mozApps.install caller.
|
||||
return;
|
||||
}
|
||||
|
||||
// We will check the manifestUrl from the one in the APK.
|
||||
// Thus, we can have a one-to-one mapping of apk to receiver.
|
||||
final InstallListener receiver = new InstallListener(manifestUrl, argsObj);
|
||||
|
||||
// Listen for packages being installed.
|
||||
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addDataScheme("package");
|
||||
context.registerReceiver(receiver, filter);
|
||||
|
||||
// Now call the package installer.
|
||||
File file = new File(filePath);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
|
||||
|
||||
sActivityHelper.startIntentForActivity(context, intent, new ActivityResultHandler() {
|
||||
@Override
|
||||
public void onActivityResult(int resultCode, Intent data) {
|
||||
// The InstallListener will catch the case where the user pressed install.
|
||||
// Now deal with if the user pressed cancel.
|
||||
if (resultCode == Activity.RESULT_CANCELED) {
|
||||
try {
|
||||
context.unregisterReceiver(receiver);
|
||||
receiver.cleanup();
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
// IllegalArgumentException happens because resultCode is RESULT_CANCELED
|
||||
// when the user presses the Done button in the install confirmation dialog,
|
||||
// even though the install has been successful (and InstallListener already
|
||||
// unregistered the receiver).
|
||||
Log.e(LOGTAG, "error unregistering install receiver: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -547,11 +547,16 @@ public final class GeckoProfile {
|
||||
// If this is the first time its created, we also add a General section
|
||||
// look for the first profile number that isn't taken yet
|
||||
int profileNum = 0;
|
||||
while (parser.getSection("Profile" + profileNum) != null) {
|
||||
boolean isDefaultSet = false;
|
||||
INISection profileSection;
|
||||
while ((profileSection = parser.getSection("Profile" + profileNum)) != null) {
|
||||
profileNum++;
|
||||
if (profileSection.getProperty("Default") != null) {
|
||||
isDefaultSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
INISection profileSection = new INISection("Profile" + profileNum);
|
||||
profileSection = new INISection("Profile" + profileNum);
|
||||
profileSection.setProperty("Name", mName);
|
||||
profileSection.setProperty("IsRelative", 1);
|
||||
profileSection.setProperty("Path", saltedName);
|
||||
@ -560,8 +565,11 @@ public final class GeckoProfile {
|
||||
INISection generalSection = new INISection("General");
|
||||
generalSection.setProperty("StartWithLastProfile", 1);
|
||||
parser.addSection(generalSection);
|
||||
}
|
||||
|
||||
// only set as default if this is the first profile we're creating
|
||||
if (!isDefaultSet && !mName.startsWith("webapp")) {
|
||||
// only set as default if this is the first non-webapp
|
||||
// profile we're creating
|
||||
profileSection.setProperty("Default", 1);
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ DEFINES += \
|
||||
|
||||
GARBAGE += \
|
||||
AndroidManifest.xml \
|
||||
WebAppManifestFragment.xml.frag \
|
||||
classes.dex \
|
||||
gecko.ap_ \
|
||||
res/values/strings.xml \
|
||||
@ -131,6 +132,7 @@ PP_JAVAFILES := $(filter-out $(gecko_package_dir)/R.java,$(gecko-mozglue_PP_JAVA
|
||||
|
||||
manifest := \
|
||||
AndroidManifest.xml.in \
|
||||
WebAppManifestFragment.xml.frag.in \
|
||||
$(NULL)
|
||||
|
||||
PP_TARGETS += manifest
|
||||
@ -182,6 +184,7 @@ res/values/strings.xml: FORCE
|
||||
|
||||
all_resources = \
|
||||
$(CURDIR)/AndroidManifest.xml \
|
||||
$(CURDIR)/WebAppManifestFragment.xml.frag \
|
||||
$(android_res_files) \
|
||||
$(ANDROID_GENERATED_RESFILES) \
|
||||
$(NULL)
|
||||
|
@ -6,10 +6,13 @@
|
||||
#filter substitution
|
||||
package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
import org.mozilla.gecko.webapp.WebAppImpl;
|
||||
#else
|
||||
import org.mozilla.gecko.WebAppImpl;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class serves only as a namespace wrapper for WebAppImpl.
|
||||
*/
|
||||
public class WebApp extends WebAppImpl {}
|
||||
|
||||
|
@ -10,9 +10,12 @@ import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WebAppAllocator {
|
||||
private final String LOGTAG = "GeckoWebAppAllocator";
|
||||
// The number of WebApp# and WEBAPP# activites/apps/intents
|
||||
|
@ -2,11 +2,16 @@
|
||||
android:label="@string/webapp_generic_name"
|
||||
android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize"
|
||||
android:windowSoftInputMode="stateUnspecified|adjustResize"
|
||||
android:process=":@ANDROID_PACKAGE_NAME@.WebApp@APPNUM@"
|
||||
android:theme="@style/Gecko.App"
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
android:launchMode="singleTop"
|
||||
android:exported="true"
|
||||
/>
|
||||
#else
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity="org.mozilla.gecko.WEBAPP@APPNUM@"
|
||||
android:process=":@ANDROID_PACKAGE_NAME@.WebApp@APPNUM@"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/Gecko.App">
|
||||
android:excludeFromRecents="true">
|
||||
<intent-filter>
|
||||
<action android:name="org.mozilla.gecko.WEBAPP@APPNUM@" />
|
||||
</intent-filter>
|
||||
@ -14,4 +19,4 @@
|
||||
<action android:name="org.mozilla.gecko.ACTION_ALERT_CALLBACK" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
@ -294,6 +295,24 @@ public final class BitmapUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapFromDrawable(Drawable drawable) {
|
||||
if (drawable instanceof BitmapDrawable) {
|
||||
return ((BitmapDrawable) drawable).getBitmap();
|
||||
}
|
||||
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
width = width > 0 ? width : 1;
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
height = height > 0 ? height : 1;
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static int getResource(Uri resourceUrl, int defaultIcon) {
|
||||
int icon = defaultIcon;
|
||||
|
||||
|
@ -321,6 +321,13 @@ gbjar.sources += [
|
||||
'updater/UpdateService.java',
|
||||
'updater/UpdateServiceHelper.java',
|
||||
'VideoPlayer.java',
|
||||
'webapp/ApkResources.java',
|
||||
'webapp/InstallHelper.java',
|
||||
'webapp/InstallListener.java',
|
||||
'webapp/UninstallListener.java',
|
||||
'webapp/WebAppAllocator.java',
|
||||
'webapp/WebAppDispatcher.java',
|
||||
'webapp/WebAppImpl.java',
|
||||
'WebAppAllocator.java',
|
||||
'WebAppImpl.java',
|
||||
'widget/ActivityChooserModel.java',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user