Merge mozilla-central and inbound
This commit is contained in:
3
CLOBBER
3
CLOBBER
@@ -17,4 +17,5 @@
|
|||||||
#
|
#
|
||||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||||
#
|
#
|
||||||
Bug 870180 - CPOWs
|
Bug 889503 - Move Settings API to WebIDL.
|
||||||
|
Requires a clobber due to Bug 890744.
|
||||||
|
|||||||
@@ -6868,7 +6868,7 @@ var gIdentityHandler = {
|
|||||||
continue;
|
continue;
|
||||||
let menuitem = document.createElement("menuitem");
|
let menuitem = document.createElement("menuitem");
|
||||||
menuitem.setAttribute("value", state);
|
menuitem.setAttribute("value", state);
|
||||||
menuitem.setAttribute("label", SitePermissions.getStateLabel(state));
|
menuitem.setAttribute("label", SitePermissions.getStateLabel(aPermission, state));
|
||||||
menupopup.appendChild(menuitem);
|
menupopup.appendChild(menuitem);
|
||||||
}
|
}
|
||||||
menulist.appendChild(menupopup);
|
menulist.appendChild(menupopup);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ function createRow(aPartId) {
|
|||||||
for (let state of SitePermissions.getAvailableStates(aPartId)) {
|
for (let state of SitePermissions.getAvailableStates(aPartId)) {
|
||||||
let radio = document.createElement("radio");
|
let radio = document.createElement("radio");
|
||||||
radio.setAttribute("id", aPartId + "#" + state);
|
radio.setAttribute("id", aPartId + "#" + state);
|
||||||
radio.setAttribute("label", SitePermissions.getStateLabel(state));
|
radio.setAttribute("label", SitePermissions.getStateLabel(aPartId, state));
|
||||||
radio.setAttribute("command", commandId);
|
radio.setAttribute("command", commandId);
|
||||||
radiogroup.appendChild(radio);
|
radiogroup.appendChild(radio);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ let Cu = Components.utils;
|
|||||||
|
|
||||||
const appStartup = Services.startup;
|
const appStartup = Services.startup;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/ResetProfile.jsm");
|
||||||
|
|
||||||
let defaultToReset = false;
|
let defaultToReset = false;
|
||||||
|
|
||||||
function restartApp() {
|
function restartApp() {
|
||||||
@@ -69,7 +71,7 @@ function onLoad() {
|
|||||||
if (appStartup.automaticSafeModeNecessary) {
|
if (appStartup.automaticSafeModeNecessary) {
|
||||||
document.getElementById("autoSafeMode").hidden = false;
|
document.getElementById("autoSafeMode").hidden = false;
|
||||||
document.getElementById("safeMode").hidden = true;
|
document.getElementById("safeMode").hidden = true;
|
||||||
if (resetSupported()) {
|
if (ResetProfile.resetSupported()) {
|
||||||
populateResetPane("resetProfileItems");
|
populateResetPane("resetProfileItems");
|
||||||
document.getElementById("resetProfile").hidden = false;
|
document.getElementById("resetProfile").hidden = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -77,7 +79,7 @@ function onLoad() {
|
|||||||
document.documentElement.getButton("extra1").hidden = true;
|
document.documentElement.getButton("extra1").hidden = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!resetSupported()) {
|
if (!ResetProfile.resetSupported()) {
|
||||||
// Hide the reset button and text if it's not supported.
|
// Hide the reset button and text if it's not supported.
|
||||||
document.documentElement.getButton("extra1").hidden = true;
|
document.documentElement.getButton("extra1").hidden = true;
|
||||||
document.getElementById("resetProfileInstead").hidden = true;
|
document.getElementById("resetProfileInstead").hidden = true;
|
||||||
|
|||||||
@@ -200,8 +200,24 @@ function checkSocialUI(win) {
|
|||||||
let active = Social.providers.length > 0 && !win.SocialUI._chromeless &&
|
let active = Social.providers.length > 0 && !win.SocialUI._chromeless &&
|
||||||
!PrivateBrowsingUtils.isWindowPrivate(win);
|
!PrivateBrowsingUtils.isWindowPrivate(win);
|
||||||
|
|
||||||
|
// some local helpers to avoid log-spew for the many checks made here.
|
||||||
|
let numGoodTests = 0, numTests = 0;
|
||||||
|
function _ok(what, msg) {
|
||||||
|
numTests++;
|
||||||
|
if (!ok)
|
||||||
|
ok(what, msg)
|
||||||
|
else
|
||||||
|
++numGoodTests;
|
||||||
|
}
|
||||||
|
function _is(a, b, msg) {
|
||||||
|
numTests++;
|
||||||
|
if (a != b)
|
||||||
|
is(a, b, msg)
|
||||||
|
else
|
||||||
|
++numGoodTests;
|
||||||
|
}
|
||||||
function isbool(a, b, msg) {
|
function isbool(a, b, msg) {
|
||||||
is(!!a, !!b, msg);
|
_is(!!a, !!b, msg);
|
||||||
}
|
}
|
||||||
isbool(win.SocialSidebar.canShow, enabled, "social sidebar active?");
|
isbool(win.SocialSidebar.canShow, enabled, "social sidebar active?");
|
||||||
if (enabled)
|
if (enabled)
|
||||||
@@ -216,15 +232,15 @@ function checkSocialUI(win) {
|
|||||||
isbool(!doc.getElementById("social-toolbar-item").hidden, active, "toolbar items visible?");
|
isbool(!doc.getElementById("social-toolbar-item").hidden, active, "toolbar items visible?");
|
||||||
if (active) {
|
if (active) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
ok(!win.SocialToolbar.button.style.listStyleImage, "toolbar button is default icon");
|
_ok(!win.SocialToolbar.button.style.listStyleImage, "toolbar button is default icon");
|
||||||
} else {
|
} else {
|
||||||
is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
|
_is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// the menus should always have the provider name
|
// the menus should always have the provider name
|
||||||
if (provider) {
|
if (provider) {
|
||||||
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
|
for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
|
||||||
is(document.getElementById(id).getAttribute("label"), Social.provider.name, "element has the provider name");
|
_is(document.getElementById(id).getAttribute("label"), Social.provider.name, "element has the provider name");
|
||||||
}
|
}
|
||||||
|
|
||||||
// and for good measure, check all the social commands.
|
// and for good measure, check all the social commands.
|
||||||
@@ -232,10 +248,12 @@ function checkSocialUI(win) {
|
|||||||
isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
|
isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
|
||||||
isbool(!doc.getElementById("Social:FocusChat").hidden, enabled && Social.haveLoggedInUser(), "Social:FocusChat visible?");
|
isbool(!doc.getElementById("Social:FocusChat").hidden, enabled && Social.haveLoggedInUser(), "Social:FocusChat visible?");
|
||||||
isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
|
isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
|
||||||
is(doc.getElementById("Social:TogglePageMark").getAttribute("disabled"), canMark ? "false" : "true", "Social:TogglePageMark enabled?");
|
_is(doc.getElementById("Social:TogglePageMark").getAttribute("disabled"), canMark ? "false" : "true", "Social:TogglePageMark enabled?");
|
||||||
|
|
||||||
// broadcasters.
|
// broadcasters.
|
||||||
isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
|
isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
|
||||||
|
// and report on overall success of failure of the various checks here.
|
||||||
|
is(numGoodTests, numTests, "The Social UI tests succeeded.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// blocklist testing
|
// blocklist testing
|
||||||
|
|||||||
@@ -1180,6 +1180,9 @@ var StartUI = {
|
|||||||
// of the keyboard transition.
|
// of the keyboard transition.
|
||||||
ContentAreaObserver.navBarWillBlur();
|
ContentAreaObserver.navBarWillBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aEvent.button == 0)
|
||||||
|
ContextUI.dismissTabs();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function handleEvent(aEvent) {
|
handleEvent: function handleEvent(aEvent) {
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ this.SitePermissions = {
|
|||||||
|
|
||||||
/* Removes the saved state of a particular permission for a given URI.
|
/* Removes the saved state of a particular permission for a given URI.
|
||||||
*/
|
*/
|
||||||
remove: function (aURI, aPermission) {
|
remove: function (aURI, aPermissionID) {
|
||||||
if (!this.isSupportedURI(aURI))
|
if (!this.isSupportedURI(aURI))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Services.perms.remove(aURI.host, aPermission);
|
Services.perms.remove(aURI.host, aPermissionID);
|
||||||
|
|
||||||
if (aPermissionID in gPermissionObject &&
|
if (aPermissionID in gPermissionObject &&
|
||||||
gPermissionObject[aPermissionID].onChange)
|
gPermissionObject[aPermissionID].onChange)
|
||||||
@@ -110,7 +110,14 @@ this.SitePermissions = {
|
|||||||
/* Returns the localized label for the given permission state, to be used in
|
/* Returns the localized label for the given permission state, to be used in
|
||||||
* a UI for managing permissions.
|
* a UI for managing permissions.
|
||||||
*/
|
*/
|
||||||
getStateLabel: function (aState) {
|
getStateLabel: function (aPermissionID, aState) {
|
||||||
|
if (aPermissionID in gPermissionObject &&
|
||||||
|
gPermissionObject[aPermissionID].getStateLabel) {
|
||||||
|
let label = gPermissionObject[aPermissionID].getStateLabel(aState);
|
||||||
|
if (label)
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
switch (aState) {
|
switch (aState) {
|
||||||
case this.UNKNOWN:
|
case this.UNKNOWN:
|
||||||
return gStringBundle.GetStringFromName("alwaysAsk");
|
return gStringBundle.GetStringFromName("alwaysAsk");
|
||||||
@@ -140,6 +147,11 @@ let gPermissionObject = {
|
|||||||
* Defaults to UNKNOWN, indicating that the user will be asked each time
|
* Defaults to UNKNOWN, indicating that the user will be asked each time
|
||||||
* a page asks for that permissions.
|
* a page asks for that permissions.
|
||||||
*
|
*
|
||||||
|
* - getStateLabel
|
||||||
|
* Called to get the localized label for the given permission state, to be
|
||||||
|
* used in a UI for managing permissions. May return null for states that
|
||||||
|
* should use their default label.
|
||||||
|
*
|
||||||
* - onChange
|
* - onChange
|
||||||
* Called when a permission state changes.
|
* Called when a permission state changes.
|
||||||
*
|
*
|
||||||
@@ -189,8 +201,18 @@ let gPermissionObject = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
"indexedDB": {
|
"indexedDB": {
|
||||||
getDefault: function () {
|
states: [ SitePermissions.ALLOW, SitePermissions.UNKNOWN, SitePermissions.BLOCK ],
|
||||||
return SitePermissions.ALLOW;
|
getStateLabel: function (aState) {
|
||||||
|
// indexedDB redefines nsIPermissionManager.UNKNOWN_ACTION (the default)
|
||||||
|
// as "allow" and nsIPermissionManager.ALLOW_ACTION as "ask the user."
|
||||||
|
switch (aState) {
|
||||||
|
case SitePermissions.UNKNOWN:
|
||||||
|
return gStringBundle.GetStringFromName("allow");
|
||||||
|
case SitePermissions.ALLOW:
|
||||||
|
return gStringBundle.GetStringFromName("alwaysAsk");
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onChange: function (aURI, aState) {
|
onChange: function (aURI, aState) {
|
||||||
if (aState == SitePermissions.ALLOW || aState == SitePermissions.BLOCK)
|
if (aState == SitePermissions.ALLOW || aState == SitePermissions.BLOCK)
|
||||||
|
|||||||
@@ -2750,8 +2750,11 @@ nsDocument::SetDocumentURI(nsIURI* aURI)
|
|||||||
nsIURI* newBase = GetDocBaseURI();
|
nsIURI* newBase = GetDocBaseURI();
|
||||||
|
|
||||||
bool equalBases = false;
|
bool equalBases = false;
|
||||||
|
// Changing just the ref of a URI does not change how relative URIs would
|
||||||
|
// resolve wrt to it, so we can treat the bases as equal as long as they're
|
||||||
|
// equal ignoring the ref.
|
||||||
if (oldBase && newBase) {
|
if (oldBase && newBase) {
|
||||||
oldBase->Equals(newBase, &equalBases);
|
oldBase->EqualsExceptRef(newBase, &equalBases);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
equalBases = !oldBase && !newBase;
|
equalBases = !oldBase && !newBase;
|
||||||
|
|||||||
@@ -3350,8 +3350,8 @@ nsObjectLoadingContent::TeardownProtoChain()
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||||
JS::Handle<jsid> aId, unsigned aFlags,
|
JS::Handle<jsid> aId,
|
||||||
JS::MutableHandle<JSObject*> aObjp)
|
JS::MutableHandle<JS::Value> aValue)
|
||||||
{
|
{
|
||||||
// We don't resolve anything; we just try to make sure we're instantiated
|
// We don't resolve anything; we just try to make sure we're instantiated
|
||||||
|
|
||||||
|
|||||||
@@ -148,8 +148,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||||||
void TeardownProtoChain();
|
void TeardownProtoChain();
|
||||||
|
|
||||||
// Helper for WebIDL newResolve
|
// Helper for WebIDL newResolve
|
||||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject, JS::Handle<jsid> aId,
|
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||||
unsigned aFlags, JS::MutableHandle<JSObject*> aObjp);
|
JS::Handle<jsid> aId,
|
||||||
|
JS::MutableHandle<JS::Value> aValue);
|
||||||
|
|
||||||
// WebIDL API
|
// WebIDL API
|
||||||
nsIDocument* GetContentDocument();
|
nsIDocument* GetContentDocument();
|
||||||
|
|||||||
@@ -3296,6 +3296,8 @@ CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
|
|||||||
// gfxContext-over-Azure may modify the DrawTarget's transform, so
|
// gfxContext-over-Azure may modify the DrawTarget's transform, so
|
||||||
// save and restore it
|
// save and restore it
|
||||||
Matrix matrix = mTarget->GetTransform();
|
Matrix matrix = mTarget->GetTransform();
|
||||||
|
double sw = matrix._11 * w;
|
||||||
|
double sh = matrix._22 * h;
|
||||||
nsRefPtr<gfxContext> thebes;
|
nsRefPtr<gfxContext> thebes;
|
||||||
nsRefPtr<gfxASurface> drawSurf;
|
nsRefPtr<gfxASurface> drawSurf;
|
||||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget)) {
|
if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget)) {
|
||||||
@@ -3304,7 +3306,7 @@ CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
|
|||||||
matrix._22, matrix._31, matrix._32));
|
matrix._22, matrix._31, matrix._32));
|
||||||
} else {
|
} else {
|
||||||
drawSurf =
|
drawSurf =
|
||||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(ceil(w), ceil(h)),
|
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(ceil(sw), ceil(sh)),
|
||||||
gfxASurface::CONTENT_COLOR_ALPHA);
|
gfxASurface::CONTENT_COLOR_ALPHA);
|
||||||
if (!drawSurf) {
|
if (!drawSurf) {
|
||||||
error.Throw(NS_ERROR_FAILURE);
|
error.Throw(NS_ERROR_FAILURE);
|
||||||
@@ -3314,6 +3316,7 @@ CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
|
|||||||
drawSurf->SetDeviceOffset(gfxPoint(-floor(x), -floor(y)));
|
drawSurf->SetDeviceOffset(gfxPoint(-floor(x), -floor(y)));
|
||||||
thebes = new gfxContext(drawSurf);
|
thebes = new gfxContext(drawSurf);
|
||||||
thebes->Translate(gfxPoint(floor(x), floor(y)));
|
thebes->Translate(gfxPoint(floor(x), floor(y)));
|
||||||
|
thebes->Scale(matrix._11, matrix._22);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
|
nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
|
||||||
@@ -3333,8 +3336,9 @@ CanvasRenderingContext2D::DrawWindow(nsIDOMWindow* window, double x,
|
|||||||
IntSize(size.width, size.height),
|
IntSize(size.width, size.height),
|
||||||
img->Stride(),
|
img->Stride(),
|
||||||
FORMAT_B8G8R8A8);
|
FORMAT_B8G8R8A8);
|
||||||
mgfx::Rect rect(0, 0, w, h);
|
mgfx::Rect destRect(0, 0, w, h);
|
||||||
mTarget->DrawSurface(data, rect, rect);
|
mgfx::Rect sourceRect(0, 0, sw, sh);
|
||||||
|
mTarget->DrawSurface(data, destRect, sourceRect);
|
||||||
mTarget->Flush();
|
mTarget->Flush();
|
||||||
} else {
|
} else {
|
||||||
mTarget->SetTransform(matrix);
|
mTarget->SetTransform(matrix);
|
||||||
|
|||||||
@@ -176,12 +176,13 @@ AudioContext::CreateBuffer(JSContext* aJSContext, ArrayBuffer& aBuffer,
|
|||||||
aBuffer.Data(), aBuffer.Length(),
|
aBuffer.Data(), aBuffer.Length(),
|
||||||
contentType);
|
contentType);
|
||||||
|
|
||||||
WebAudioDecodeJob job(contentType, this);
|
nsRefPtr<WebAudioDecodeJob> job =
|
||||||
|
new WebAudioDecodeJob(contentType, this, aBuffer);
|
||||||
|
|
||||||
if (mDecoder.SyncDecodeMedia(contentType.get(),
|
if (mDecoder.SyncDecodeMedia(contentType.get(),
|
||||||
aBuffer.Data(), aBuffer.Length(), job) &&
|
aBuffer.Data(), aBuffer.Length(), *job) &&
|
||||||
job.mOutput) {
|
job->mOutput) {
|
||||||
nsRefPtr<AudioBuffer> buffer = job.mOutput.forget();
|
nsRefPtr<AudioBuffer> buffer = job->mOutput.forget();
|
||||||
if (aMixToMono) {
|
if (aMixToMono) {
|
||||||
buffer->MixToMono(aJSContext);
|
buffer->MixToMono(aJSContext);
|
||||||
}
|
}
|
||||||
@@ -374,8 +375,8 @@ AudioContext::DecodeAudioData(const ArrayBuffer& aBuffer,
|
|||||||
if (aFailureCallback.WasPassed()) {
|
if (aFailureCallback.WasPassed()) {
|
||||||
failureCallback = &aFailureCallback.Value();
|
failureCallback = &aFailureCallback.Value();
|
||||||
}
|
}
|
||||||
nsAutoPtr<WebAudioDecodeJob> job(
|
nsRefPtr<WebAudioDecodeJob> job(
|
||||||
new WebAudioDecodeJob(contentType, this,
|
new WebAudioDecodeJob(contentType, this, aBuffer,
|
||||||
&aSuccessCallback, failureCallback));
|
&aSuccessCallback, failureCallback));
|
||||||
mDecoder.AsyncDecodeMedia(contentType.get(),
|
mDecoder.AsyncDecodeMedia(contentType.get(),
|
||||||
aBuffer.Data(), aBuffer.Length(), *job);
|
aBuffer.Data(), aBuffer.Length(), *job);
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ private:
|
|||||||
nsRefPtr<AudioDestinationNode> mDestination;
|
nsRefPtr<AudioDestinationNode> mDestination;
|
||||||
nsRefPtr<AudioListener> mListener;
|
nsRefPtr<AudioListener> mListener;
|
||||||
MediaBufferDecoder mDecoder;
|
MediaBufferDecoder mDecoder;
|
||||||
nsTArray<nsAutoPtr<WebAudioDecodeJob> > mDecodeJobs;
|
nsTArray<nsRefPtr<WebAudioDecodeJob> > mDecodeJobs;
|
||||||
// Two hashsets containing all the PannerNodes and AudioBufferSourceNodes,
|
// Two hashsets containing all the PannerNodes and AudioBufferSourceNodes,
|
||||||
// to compute the doppler shift, and also to stop AudioBufferSourceNodes.
|
// to compute the doppler shift, and also to stop AudioBufferSourceNodes.
|
||||||
// These are all weak pointers.
|
// These are all weak pointers.
|
||||||
|
|||||||
@@ -25,6 +25,29 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebAudioDecodeJob)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutput)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuccessCallback)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFailureCallback)
|
||||||
|
tmp->mArrayBuffer = nullptr;
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebAudioDecodeJob)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutput)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuccessCallback)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFailureCallback)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WebAudioDecodeJob)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mArrayBuffer)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebAudioDecodeJob, AddRef)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebAudioDecodeJob, Release)
|
||||||
|
|
||||||
using namespace dom;
|
using namespace dom;
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
@@ -793,6 +816,7 @@ MediaBufferDecoder::Shutdown() {
|
|||||||
|
|
||||||
WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
|
WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
|
||||||
AudioContext* aContext,
|
AudioContext* aContext,
|
||||||
|
const ArrayBuffer& aBuffer,
|
||||||
DecodeSuccessCallback* aSuccessCallback,
|
DecodeSuccessCallback* aSuccessCallback,
|
||||||
DecodeErrorCallback* aFailureCallback)
|
DecodeErrorCallback* aFailureCallback)
|
||||||
: mContentType(aContentType)
|
: mContentType(aContentType)
|
||||||
@@ -805,15 +829,21 @@ WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_COUNT_CTOR(WebAudioDecodeJob);
|
MOZ_COUNT_CTOR(WebAudioDecodeJob);
|
||||||
|
|
||||||
|
mArrayBuffer = aBuffer.Obj();
|
||||||
|
|
||||||
MOZ_ASSERT(aSuccessCallback ||
|
MOZ_ASSERT(aSuccessCallback ||
|
||||||
(!aSuccessCallback && !aFailureCallback),
|
(!aSuccessCallback && !aFailureCallback),
|
||||||
"If a success callback is not passed, no failure callback should be passed either");
|
"If a success callback is not passed, no failure callback should be passed either");
|
||||||
|
|
||||||
|
nsContentUtils::HoldJSObjects(this, NS_CYCLE_COLLECTION_PARTICIPANT(WebAudioDecodeJob));
|
||||||
}
|
}
|
||||||
|
|
||||||
WebAudioDecodeJob::~WebAudioDecodeJob()
|
WebAudioDecodeJob::~WebAudioDecodeJob()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_COUNT_DTOR(WebAudioDecodeJob);
|
MOZ_COUNT_DTOR(WebAudioDecodeJob);
|
||||||
|
mArrayBuffer = nullptr;
|
||||||
|
nsContentUtils::DropJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -26,16 +26,20 @@ class DecodeErrorCallback;
|
|||||||
class DecodeSuccessCallback;
|
class DecodeSuccessCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WebAudioDecodeJob
|
struct WebAudioDecodeJob MOZ_FINAL
|
||||||
{
|
{
|
||||||
// You may omit both the success and failure callback, or you must pass both.
|
// You may omit both the success and failure callback, or you must pass both.
|
||||||
// The callbacks are only necessary for asynchronous operation.
|
// The callbacks are only necessary for asynchronous operation.
|
||||||
WebAudioDecodeJob(const nsACString& aContentType,
|
WebAudioDecodeJob(const nsACString& aContentType,
|
||||||
dom::AudioContext* aContext,
|
dom::AudioContext* aContext,
|
||||||
|
const dom::ArrayBuffer& aBuffer,
|
||||||
dom::DecodeSuccessCallback* aSuccessCallback = nullptr,
|
dom::DecodeSuccessCallback* aSuccessCallback = nullptr,
|
||||||
dom::DecodeErrorCallback* aFailureCallback = nullptr);
|
dom::DecodeErrorCallback* aFailureCallback = nullptr);
|
||||||
~WebAudioDecodeJob();
|
~WebAudioDecodeJob();
|
||||||
|
|
||||||
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebAudioDecodeJob)
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebAudioDecodeJob)
|
||||||
|
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
NoError,
|
NoError,
|
||||||
UnknownContent,
|
UnknownContent,
|
||||||
@@ -52,6 +56,8 @@ struct WebAudioDecodeJob
|
|||||||
|
|
||||||
bool AllocateBuffer();
|
bool AllocateBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
JS::Heap<JSObject*> mArrayBuffer;
|
||||||
nsCString mContentType;
|
nsCString mContentType;
|
||||||
uint32_t mWriteIndex;
|
uint32_t mWriteIndex;
|
||||||
nsRefPtr<dom::AudioContext> mContext;
|
nsRefPtr<dom::AudioContext> mContext;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@ class nsIDOMMozConnection;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
class Geolocation;
|
class Geolocation;
|
||||||
|
class systemMessageCallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +70,8 @@ class nsIDOMTelephony;
|
|||||||
// Navigator: Script "navigator" object
|
// Navigator: Script "navigator" object
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
||||||
|
void NS_GetNavigatorAppName(nsAString& aAppName);
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
@@ -79,6 +82,15 @@ class BatteryManager;
|
|||||||
class DesktopNotificationCenter;
|
class DesktopNotificationCenter;
|
||||||
class SmsManager;
|
class SmsManager;
|
||||||
class MobileMessageManager;
|
class MobileMessageManager;
|
||||||
|
class MozIdleObserver;
|
||||||
|
#ifdef MOZ_GAMEPAD
|
||||||
|
class Gamepad;
|
||||||
|
#endif // MOZ_GAMEPAD
|
||||||
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
|
class MozDOMGetUserMediaSuccessCallback;
|
||||||
|
class MozDOMGetUserMediaErrorCallback;
|
||||||
|
class MozGetUserMediaDevicesSuccessCallback;
|
||||||
|
#endif // MOZ_MEDIA_NAVIGATOR
|
||||||
|
|
||||||
namespace icc {
|
namespace icc {
|
||||||
#ifdef MOZ_B2G_RIL
|
#ifdef MOZ_B2G_RIL
|
||||||
@@ -192,7 +204,7 @@ public:
|
|||||||
static void Init();
|
static void Init();
|
||||||
|
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
nsPIDOMWindow *GetWindow()
|
nsPIDOMWindow *GetWindow() const
|
||||||
{
|
{
|
||||||
return mWindow;
|
return mWindow;
|
||||||
}
|
}
|
||||||
@@ -218,8 +230,186 @@ public:
|
|||||||
|
|
||||||
NS_DECL_NSIDOMNAVIGATORCAMERA
|
NS_DECL_NSIDOMNAVIGATORCAMERA
|
||||||
|
|
||||||
|
// WebIDL API
|
||||||
|
void GetAppName(nsString& aAppName)
|
||||||
|
{
|
||||||
|
NS_GetNavigatorAppName(aAppName);
|
||||||
|
}
|
||||||
|
void GetAppVersion(nsString& aAppVersion, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetAppVersion(aAppVersion);
|
||||||
|
}
|
||||||
|
void GetPlatform(nsString& aPlatform, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetPlatform(aPlatform);
|
||||||
|
}
|
||||||
|
void GetUserAgent(nsString& aUserAgent, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetUserAgent(aUserAgent);
|
||||||
|
}
|
||||||
|
// The XPCOM GetProduct is OK
|
||||||
|
// The XPCOM GetLanguage is OK
|
||||||
|
bool OnLine();
|
||||||
|
void RegisterProtocolHandler(const nsAString& aScheme, const nsAString& aURL,
|
||||||
|
const nsAString& aTitle, ErrorResult& rv)
|
||||||
|
{
|
||||||
|
rv = RegisterProtocolHandler(aScheme, aURL, aTitle);
|
||||||
|
}
|
||||||
|
void RegisterContentHandler(const nsAString& aMIMEType, const nsAString& aURL,
|
||||||
|
const nsAString& aTitle, ErrorResult& rv)
|
||||||
|
{
|
||||||
|
rv = RegisterContentHandler(aMIMEType, aURL, aTitle);
|
||||||
|
}
|
||||||
|
nsMimeTypeArray* GetMimeTypes(ErrorResult& aRv);
|
||||||
|
nsPluginArray* GetPlugins(ErrorResult& aRv);
|
||||||
|
// The XPCOM GetDoNotTrack is ok
|
||||||
|
Geolocation* GetGeolocation(ErrorResult& aRv);
|
||||||
|
battery::BatteryManager* GetBattery(ErrorResult& aRv);
|
||||||
|
void Vibrate(uint32_t aDuration, ErrorResult& aRv);
|
||||||
|
void Vibrate(const nsTArray<uint32_t>& aDuration, ErrorResult& aRv);
|
||||||
|
void GetAppCodeName(nsString& aAppCodeName, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetAppCodeName(aAppCodeName);
|
||||||
|
}
|
||||||
|
void GetOscpu(nsString& aOscpu, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetOscpu(aOscpu);
|
||||||
|
}
|
||||||
|
// The XPCOM GetVendor is OK
|
||||||
|
// The XPCOM GetVendorSub is OK
|
||||||
|
// The XPCOM GetProductSub is OK
|
||||||
|
bool CookieEnabled();
|
||||||
|
void GetBuildID(nsString& aBuildID, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
aRv = GetBuildID(aBuildID);
|
||||||
|
}
|
||||||
|
nsIDOMMozPowerManager* GetMozPower(ErrorResult& aRv);
|
||||||
|
bool JavaEnabled(ErrorResult& aRv);
|
||||||
|
bool TaintEnabled()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void AddIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv);
|
||||||
|
void RemoveIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv);
|
||||||
|
already_AddRefed<nsIDOMMozWakeLock> RequestWakeLock(const nsAString &aTopic,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
nsDOMDeviceStorage* GetDeviceStorage(const nsAString& aType,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
void GetDeviceStorages(const nsAString& aType,
|
||||||
|
nsTArray<nsRefPtr<nsDOMDeviceStorage> >& aStores,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv);
|
||||||
|
bool MozIsLocallyAvailable(const nsAString& aURI, bool aWhenOffline,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
bool available = false;
|
||||||
|
aRv = MozIsLocallyAvailable(aURI, aWhenOffline, &available);
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
nsIDOMMozSmsManager* GetMozSms();
|
||||||
|
nsIDOMMozMobileMessageManager* GetMozMobileMessage();
|
||||||
|
nsIDOMMozConnection* GetMozConnection();
|
||||||
|
nsDOMCameraManager* GetMozCameras(ErrorResult& aRv);
|
||||||
|
void MozSetMessageHandler(const nsAString& aType,
|
||||||
|
systemMessageCallback* aCallback,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
bool MozHasPendingMessage(const nsAString& aType, ErrorResult& aRv);
|
||||||
|
#ifdef MOZ_B2G_RIL
|
||||||
|
nsIDOMTelephony* GetMozTelephony(ErrorResult& aRv);
|
||||||
|
nsIDOMMozMobileConnection* GetMozMobileConnection(ErrorResult& aRv);
|
||||||
|
nsIDOMMozCellBroadcast* GetMozCellBroadcast(ErrorResult& aRv);
|
||||||
|
nsIDOMMozVoicemail* GetMozVoicemail(ErrorResult& aRv);
|
||||||
|
nsIDOMMozIccManager* GetMozIccManager(ErrorResult& aRv);
|
||||||
|
#endif // MOZ_B2G_RIL
|
||||||
|
#ifdef MOZ_GAMEPAD
|
||||||
|
void GetGamepads(nsTArray<nsRefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
|
||||||
|
#endif // MOZ_GAMEPAD
|
||||||
|
#ifdef MOZ_B2G_BT
|
||||||
|
nsIDOMBluetoothManager* GetMozBluetooth(ErrorResult& aRv);
|
||||||
|
#endif // MOZ_B2G_BT
|
||||||
|
#ifdef MOZ_TIME_MANAGER
|
||||||
|
time::TimeManager* GetMozTime(ErrorResult& aRv);
|
||||||
|
#endif // MOZ_TIME_MANAGER
|
||||||
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
||||||
|
system::AudioChannelManager* GetMozAudioChannelManager(ErrorResult& aRv);
|
||||||
|
#endif // MOZ_AUDIO_CHANNEL_MANAGER
|
||||||
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
|
void MozGetUserMedia(nsIMediaStreamOptions* aParams,
|
||||||
|
MozDOMGetUserMediaSuccessCallback* aOnSuccess,
|
||||||
|
MozDOMGetUserMediaErrorCallback* aOnError,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
void MozGetUserMedia(nsIMediaStreamOptions* aParams,
|
||||||
|
nsIDOMGetUserMediaSuccessCallback* aOnSuccess,
|
||||||
|
nsIDOMGetUserMediaErrorCallback* aOnError,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
void MozGetUserMediaDevices(MozGetUserMediaDevicesSuccessCallback* aOnSuccess,
|
||||||
|
MozDOMGetUserMediaErrorCallback* aOnError,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
void MozGetUserMediaDevices(nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
|
||||||
|
nsIDOMGetUserMediaErrorCallback* aOnError,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
#endif // MOZ_MEDIA_NAVIGATOR
|
||||||
|
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||||
|
JS::Handle<jsid> aId, JS::MutableHandle<JS::Value> aValue);
|
||||||
|
|
||||||
|
// WebIDL helper methods
|
||||||
|
static bool HasBatterySupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||||
|
static bool HasPowerSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
static bool HasIdleSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
static bool HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */);
|
||||||
|
static bool HasDesktopNotificationSupport(JSContext* /* unused*/,
|
||||||
|
JSObject* /*unused */)
|
||||||
|
{
|
||||||
|
return HasDesktopNotificationSupport();
|
||||||
|
}
|
||||||
|
static bool HasSmsSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
static bool HasMobileMessageSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
static bool HasCameraSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
#ifdef MOZ_B2G_RIL
|
||||||
|
static bool HasTelephonySupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
static bool HasMobileConnectionSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
static bool HasCellBroadcastSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
static bool HasVoicemailSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
static bool HasIccManagerSupport(JSContext* /* unused */,
|
||||||
|
JSObject* aGlobal);
|
||||||
|
#endif // MOZ_B2G_RIL
|
||||||
|
#ifdef MOZ_B2G_BT
|
||||||
|
static bool HasBluetoothSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
#endif // MOZ_B2G_BT
|
||||||
|
#ifdef MOZ_TIME_MANAGER
|
||||||
|
static bool HasTimeSupport(JSContext* /* unused */, JSObject* aGlobal);
|
||||||
|
#endif // MOZ_TIME_MANAGER
|
||||||
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
|
static bool HasUserMediaSupport(JSContext* /* unused */,
|
||||||
|
JSObject* /* unused */);
|
||||||
|
#endif // MOZ_MEDIA_NAVIGATOR
|
||||||
|
|
||||||
|
nsPIDOMWindow* GetParentObject() const
|
||||||
|
{
|
||||||
|
return GetWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* cx,
|
||||||
|
JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CheckPermission(const char* type);
|
bool CheckPermission(const char* type);
|
||||||
|
static bool CheckPermission(nsPIDOMWindow* aWindow, const char* aType);
|
||||||
|
static bool HasMobileMessageSupport(nsPIDOMWindow* aWindow);
|
||||||
|
// GetWindowFromGlobal returns the inner window for this global, if
|
||||||
|
// any, else null.
|
||||||
|
static already_AddRefed<nsPIDOMWindow> GetWindowFromGlobal(JSObject* aGlobal);
|
||||||
|
|
||||||
|
// Methods to common up the XPCOM and WebIDL implementations of
|
||||||
|
// Add/RemoveIdleObserver.
|
||||||
|
void AddIdleObserver(nsIIdleObserver& aIdleObserver);
|
||||||
|
void RemoveIdleObserver(nsIIdleObserver& aIdleObserver);
|
||||||
|
|
||||||
nsRefPtr<nsMimeTypeArray> mMimeTypes;
|
nsRefPtr<nsMimeTypeArray> mMimeTypes;
|
||||||
nsRefPtr<nsPluginArray> mPlugins;
|
nsRefPtr<nsPluginArray> mPlugins;
|
||||||
@@ -258,6 +448,5 @@ private:
|
|||||||
nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
|
nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
|
||||||
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
|
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
|
||||||
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);
|
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);
|
||||||
nsresult NS_GetNavigatorAppName(nsAString& aAppName);
|
|
||||||
|
|
||||||
#endif // mozilla_dom_Navigator_h
|
#endif // mozilla_dom_Navigator_h
|
||||||
|
|||||||
@@ -129,7 +129,6 @@
|
|||||||
#include "nsIXSLTProcessorPrivate.h"
|
#include "nsIXSLTProcessorPrivate.h"
|
||||||
|
|
||||||
#include "nsXMLHttpRequest.h"
|
#include "nsXMLHttpRequest.h"
|
||||||
#include "nsIDOMSettingsManager.h"
|
|
||||||
#include "nsIDOMContactManager.h"
|
#include "nsIDOMContactManager.h"
|
||||||
#include "nsIDOMPermissionSettings.h"
|
#include "nsIDOMPermissionSettings.h"
|
||||||
#include "nsIDOMApplicationRegistry.h"
|
#include "nsIDOMApplicationRegistry.h"
|
||||||
@@ -4660,101 +4659,24 @@ nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||||
JS::Rooted<jsid> id(cx, aId);
|
JS::Rooted<jsid> id(cx, aId);
|
||||||
if (!JSID_IS_STRING(id)) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsScriptNameSpaceManager *nameSpaceManager =
|
|
||||||
nsJSRuntime::GetNameSpaceManager();
|
|
||||||
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
|
|
||||||
|
|
||||||
nsDependentJSString name(id);
|
|
||||||
|
|
||||||
const nsGlobalNameStruct* name_struct =
|
|
||||||
nameSpaceManager->LookupNavigatorName(name);
|
|
||||||
if (!name_struct) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name_struct->mType == nsGlobalNameStruct::eTypeNewDOMBinding) {
|
|
||||||
mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty;
|
|
||||||
MOZ_ASSERT(construct);
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
|
|
||||||
NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR);
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> domObject(cx);
|
|
||||||
{
|
|
||||||
JSAutoCompartment ac(cx, naviObj);
|
|
||||||
|
|
||||||
// Check whether our constructor is enabled after we unwrap Xrays, since
|
|
||||||
// we don't want to define an interface on the Xray if it's disabled in
|
|
||||||
// the target global, even if it's enabled in the Xray's global.
|
|
||||||
if (name_struct->mConstructorEnabled &&
|
|
||||||
!(*name_struct->mConstructorEnabled)(cx, naviObj)) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
domObject = construct(cx, naviObj);
|
|
||||||
if (!domObject) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JS_WrapObject(cx, domObject.address()) ||
|
|
||||||
!JS_DefinePropertyById(cx, obj, id,
|
|
||||||
JS::ObjectValue(*domObject),
|
|
||||||
nullptr, nullptr, JSPROP_ENUMERATE)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*_retval = true;
|
|
||||||
*objp = obj;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeNavigatorProperty,
|
|
||||||
"unexpected type");
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
|
|
||||||
|
|
||||||
if (gpi) {
|
|
||||||
nsCOMPtr<nsIDOMNavigator> navigator = do_QueryWrappedNative(wrapper);
|
nsCOMPtr<nsIDOMNavigator> navigator = do_QueryWrappedNative(wrapper);
|
||||||
nsIDOMWindow *window = static_cast<Navigator*>(navigator.get())->GetWindow();
|
JS::Rooted<JS::Value> value(cx, JS::UndefinedValue());
|
||||||
NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
|
if (!static_cast<Navigator*>(navigator.get())->DoNewResolve(cx, obj, id,
|
||||||
|
&value)) {
|
||||||
rv = gpi->Init(window, prop_val.address());
|
return NS_ERROR_FAILURE;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
|
if (!value.isUndefined()) {
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
if (!JS_DefinePropertyById(cx, obj, id, value, JS_PropertyStub,
|
||||||
rv = WrapNative(cx, obj, native, true, prop_val.address(),
|
JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
|
||||||
getter_AddRefs(holder));
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!JS_WrapValue(cx, prop_val.address())) {
|
*objp = obj;
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val,
|
|
||||||
JS_PropertyStub, JS_StrictPropertyStub,
|
|
||||||
JSPROP_ENUMERATE);
|
|
||||||
|
|
||||||
*_retval = true;
|
*_retval = true;
|
||||||
*objp = obj;
|
return NS_OK;
|
||||||
|
|
||||||
return ok ? NS_OK : NS_ERROR_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|||||||
@@ -1702,17 +1702,30 @@ addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
|
|||||||
addExternalIface('LockedFile')
|
addExternalIface('LockedFile')
|
||||||
addExternalIface('MediaList')
|
addExternalIface('MediaList')
|
||||||
addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
|
addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
|
||||||
|
addExternalIface('MozBluetoothManager', nativeType='nsIDOMBluetoothManager')
|
||||||
addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
|
addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
|
||||||
|
addExternalIface('MozCellBroadcast')
|
||||||
|
addExternalIface('MozConnection', headerFile='nsIDOMConnection.h')
|
||||||
addExternalIface('MozControllers', nativeType='nsIControllers')
|
addExternalIface('MozControllers', nativeType='nsIControllers')
|
||||||
addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
|
addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
|
||||||
|
addExternalIface('MozIccManager', headerFile='nsIDOMIccManager.h')
|
||||||
|
addExternalIface('MozMediaStreamOptions', nativeType='nsIMediaStreamOptions',
|
||||||
|
headerFile='nsIDOMNavigatorUserMedia.h')
|
||||||
|
addExternalIface('MozMobileConnection', headerFile='nsIDOMMobileConnection.h')
|
||||||
|
addExternalIface('MozMobileMessageManager', headerFile='nsIDOMMobileMessageManager.h')
|
||||||
addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
|
addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
|
||||||
|
addExternalIface('MozPowerManager', headerFile='nsIDOMPowerManager.h')
|
||||||
addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
|
addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
|
||||||
notflattened=True)
|
notflattened=True)
|
||||||
addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
|
addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
|
||||||
|
addExternalIface('MozSmsManager', headerFile='nsIDOMSmsManager.h')
|
||||||
|
addExternalIface('MozTelephony', nativeType='nsIDOMTelephony')
|
||||||
addExternalIface('MozTreeBoxObject', nativeType='nsITreeBoxObject',
|
addExternalIface('MozTreeBoxObject', nativeType='nsITreeBoxObject',
|
||||||
notflattened=True)
|
notflattened=True)
|
||||||
addExternalIface('MozTreeColumn', nativeType='nsITreeColumn',
|
addExternalIface('MozTreeColumn', nativeType='nsITreeColumn',
|
||||||
headerFile='nsITreeColumns.h')
|
headerFile='nsITreeColumns.h')
|
||||||
|
addExternalIface('MozVoicemail')
|
||||||
|
addExternalIface('MozWakeLock', headerFile='nsIDOMWakeLock.h')
|
||||||
addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
|
addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
|
||||||
addExternalIface('nsIControllers', nativeType='nsIControllers')
|
addExternalIface('nsIControllers', nativeType='nsIControllers')
|
||||||
addExternalIface('nsIInputStreamCallback', nativeType='nsIInputStreamCallback',
|
addExternalIface('nsIInputStreamCallback', nativeType='nsIInputStreamCallback',
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ class CGNativePropertyHooks(CGThing):
|
|||||||
if self.descriptor.concrete and self.descriptor.proxy:
|
if self.descriptor.concrete and self.descriptor.proxy:
|
||||||
resolveOwnProperty = "ResolveOwnProperty"
|
resolveOwnProperty = "ResolveOwnProperty"
|
||||||
enumerateOwnProperties = "EnumerateOwnProperties"
|
enumerateOwnProperties = "EnumerateOwnProperties"
|
||||||
|
elif self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||||
|
resolveOwnProperty = "ResolveOwnPropertyViaNewresolve"
|
||||||
|
enumerateOwnProperties = "nullptr"
|
||||||
else:
|
else:
|
||||||
resolveOwnProperty = "nullptr"
|
resolveOwnProperty = "nullptr"
|
||||||
enumerateOwnProperties = "nullptr"
|
enumerateOwnProperties = "nullptr"
|
||||||
@@ -3732,7 +3735,7 @@ def convertConstIDLValueToJSVal(value):
|
|||||||
return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
|
return "JSVAL_TRUE" if value.value else "JSVAL_FALSE"
|
||||||
if tag in [IDLType.Tags.float, IDLType.Tags.double]:
|
if tag in [IDLType.Tags.float, IDLType.Tags.double]:
|
||||||
return "DOUBLE_TO_JSVAL(%s)" % (value.value)
|
return "DOUBLE_TO_JSVAL(%s)" % (value.value)
|
||||||
raise TypeError("Const value of unhandled type: " + value.type)
|
raise TypeError("Const value of unhandled type: %s" % value.type)
|
||||||
|
|
||||||
class CGArgumentConverter(CGThing):
|
class CGArgumentConverter(CGThing):
|
||||||
"""
|
"""
|
||||||
@@ -5130,8 +5133,9 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
|
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
|
||||||
getThisObj="args.computeThis(cx).toObjectOrNull()",
|
getThisObj="args.computeThis(cx).toObjectOrNull()",
|
||||||
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);"):
|
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);",
|
||||||
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
|
returnType="JSBool"):
|
||||||
|
CGAbstractStaticMethod.__init__(self, descriptor, name, returnType, args)
|
||||||
|
|
||||||
if unwrapFailureCode is None:
|
if unwrapFailureCode is None:
|
||||||
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");' % descriptor.interface.identifier.name
|
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");' % descriptor.interface.identifier.name
|
||||||
@@ -5145,13 +5149,14 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
|||||||
# we're someone's consequential interface. But for this-unwrapping, we
|
# we're someone's consequential interface. But for this-unwrapping, we
|
||||||
# know that we're the real deal. So fake a descriptor here for
|
# know that we're the real deal. So fake a descriptor here for
|
||||||
# consumption by CastableObjectUnwrapper.
|
# consumption by CastableObjectUnwrapper.
|
||||||
getThis = CGGeneric("""%s
|
getThis = CGList([
|
||||||
JS::RootedObject obj(cx, %s);
|
CGGeneric(self.callArgs) if self.callArgs != "" else None,
|
||||||
if (!obj) {
|
CGGeneric("JS::RootedObject obj(cx, %s);\n"
|
||||||
return false;
|
"if (!obj) {\n"
|
||||||
}
|
" return false;\n"
|
||||||
|
"}" % self.getThisObj) if self.getThisObj else None,
|
||||||
%s* self;""" % (self.callArgs, self.getThisObj, self.descriptor.nativeType))
|
CGGeneric("%s* self;" % self.descriptor.nativeType)
|
||||||
|
], "\n")
|
||||||
unwrapThis = CGGeneric(
|
unwrapThis = CGGeneric(
|
||||||
str(CastableObjectUnwrapper(
|
str(CastableObjectUnwrapper(
|
||||||
self.descriptor,
|
self.descriptor,
|
||||||
@@ -5265,13 +5270,13 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
self._needNewResolve = descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
self._needNewResolve = descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||||
args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'obj_'),
|
args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject*>', 'obj'),
|
||||||
Argument('JS::Handle<jsid>', 'id'), Argument('unsigned', 'flags'),
|
Argument('JS::Handle<jsid>', 'id'), Argument('unsigned', 'flags'),
|
||||||
Argument('JS::MutableHandle<JSObject*>', 'objp')]
|
Argument('JS::MutableHandle<JSObject*>', 'objp')]
|
||||||
# Our "self" is actually the callee in this case, not the thisval.
|
# Our "self" is actually the callee in this case, not the thisval.
|
||||||
CGAbstractBindingMethod.__init__(
|
CGAbstractBindingMethod.__init__(
|
||||||
self, descriptor, NEWRESOLVE_HOOK_NAME,
|
self, descriptor, NEWRESOLVE_HOOK_NAME,
|
||||||
args, getThisObj="obj_", callArgs="")
|
args, getThisObj="", callArgs="")
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
if not self._needNewResolve:
|
if not self._needNewResolve:
|
||||||
@@ -5279,7 +5284,19 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
|||||||
return CGAbstractBindingMethod.define(self)
|
return CGAbstractBindingMethod.define(self)
|
||||||
|
|
||||||
def generate_code(self):
|
def generate_code(self):
|
||||||
return CGIndenter(CGGeneric("return self->DoNewResolve(cx, obj, id, flags, objp);"))
|
return CGIndenter(CGGeneric(
|
||||||
|
"JS::Rooted<JS::Value> value(cx);\n"
|
||||||
|
"if (!self->DoNewResolve(cx, obj, id, &value)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n"
|
||||||
|
"if (value.isUndefined()) {\n"
|
||||||
|
" return true;\n"
|
||||||
|
"}\n"
|
||||||
|
"if (!JS_DefinePropertyById(cx, obj, id, value, nullptr, nullptr, JSPROP_ENUMERATE)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n"
|
||||||
|
"objp.set(obj);\n"
|
||||||
|
"return true;"))
|
||||||
|
|
||||||
class CppKeywords():
|
class CppKeywords():
|
||||||
"""
|
"""
|
||||||
@@ -6629,7 +6646,7 @@ class CGClass(CGThing):
|
|||||||
result = result + memberString
|
result = result + memberString
|
||||||
return result
|
return result
|
||||||
|
|
||||||
class CGResolveOwnProperty(CGAbstractMethod):
|
class CGResolveOwnProperty(CGAbstractStaticMethod):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
args = [Argument('JSContext*', 'cx'),
|
args = [Argument('JSContext*', 'cx'),
|
||||||
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
||||||
@@ -6637,18 +6654,47 @@ class CGResolveOwnProperty(CGAbstractMethod):
|
|||||||
Argument('JS::Handle<jsid>', 'id'),
|
Argument('JS::Handle<jsid>', 'id'),
|
||||||
Argument('JSPropertyDescriptor*', 'desc'), Argument('unsigned', 'flags'),
|
Argument('JSPropertyDescriptor*', 'desc'), Argument('unsigned', 'flags'),
|
||||||
]
|
]
|
||||||
CGAbstractMethod.__init__(self, descriptor, "ResolveOwnProperty", "bool", args)
|
CGAbstractStaticMethod.__init__(self, descriptor, "ResolveOwnProperty",
|
||||||
|
"bool", args)
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return """ return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
|
return """ return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc, flags);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class CGEnumerateOwnProperties(CGAbstractMethod):
|
class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
|
||||||
|
"""
|
||||||
|
An implementation of Xray ResolveOwnProperty stuff for things that have a
|
||||||
|
newresolve hook.
|
||||||
|
"""
|
||||||
|
def __init__(self, descriptor):
|
||||||
|
args = [Argument('JSContext*', 'cx'),
|
||||||
|
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
||||||
|
Argument('JS::Handle<JSObject*>', 'obj'),
|
||||||
|
Argument('JS::Handle<jsid>', 'id'),
|
||||||
|
Argument('JSPropertyDescriptor*', 'desc'), Argument('unsigned', 'flags'),
|
||||||
|
]
|
||||||
|
CGAbstractBindingMethod.__init__(self, descriptor,
|
||||||
|
"ResolveOwnPropertyViaNewresolve",
|
||||||
|
args, getThisObj="",
|
||||||
|
callArgs="", returnType="bool")
|
||||||
|
def generate_code(self):
|
||||||
|
return CGIndenter(CGGeneric(
|
||||||
|
"JS::Rooted<JS::Value> value(cx);\n"
|
||||||
|
"if (!self->DoNewResolve(cx, obj, id, &value)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n"
|
||||||
|
"if (!value.isUndefined()) {\n"
|
||||||
|
" FillPropertyDescriptor(desc, wrapper, value, /* readonly = */ false);\n"
|
||||||
|
"}\n"
|
||||||
|
"return true;"))
|
||||||
|
|
||||||
|
class CGEnumerateOwnProperties(CGAbstractStaticMethod):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
args = [Argument('JSContext*', 'cx'),
|
args = [Argument('JSContext*', 'cx'),
|
||||||
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
Argument('JS::Handle<JSObject*>', 'wrapper'),
|
||||||
Argument('JS::Handle<JSObject*>', 'obj'),
|
Argument('JS::Handle<JSObject*>', 'obj'),
|
||||||
Argument('JS::AutoIdVector&', 'props')]
|
Argument('JS::AutoIdVector&', 'props')]
|
||||||
CGAbstractMethod.__init__(self, descriptor, "EnumerateOwnProperties", "bool", args)
|
CGAbstractStaticMethod.__init__(self, descriptor,
|
||||||
|
"EnumerateOwnProperties", "bool", args)
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return """ return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
|
return """ return js::GetProxyHandler(obj)->getOwnPropertyNames(cx, wrapper, props);
|
||||||
"""
|
"""
|
||||||
@@ -7606,6 +7652,16 @@ class CGDescriptor(CGThing):
|
|||||||
cgThings.append(CGGeneric(define=str(properties)))
|
cgThings.append(CGGeneric(define=str(properties)))
|
||||||
cgThings.append(CGNativeProperties(descriptor, properties))
|
cgThings.append(CGNativeProperties(descriptor, properties))
|
||||||
|
|
||||||
|
# Set up our Xray callbacks as needed. Note that we don't need to do
|
||||||
|
# it in workers.
|
||||||
|
if not descriptor.workers and descriptor.concrete and descriptor.proxy:
|
||||||
|
cgThings.append(CGResolveOwnProperty(descriptor))
|
||||||
|
cgThings.append(CGEnumerateOwnProperties(descriptor))
|
||||||
|
elif descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||||
|
cgThings.append(CGResolveOwnPropertyViaNewresolve(descriptor))
|
||||||
|
|
||||||
|
# Now that we have our ResolveOwnProperty/EnumerateOwnProperties stuff
|
||||||
|
# done, set up our NativePropertyHooks.
|
||||||
cgThings.append(CGNativePropertyHooks(descriptor, properties))
|
cgThings.append(CGNativePropertyHooks(descriptor, properties))
|
||||||
|
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
@@ -7629,12 +7685,6 @@ class CGDescriptor(CGThing):
|
|||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
||||||
|
|
||||||
# Set up our Xray callbacks as needed. Note that we don't need to do
|
|
||||||
# it in workers.
|
|
||||||
if not descriptor.workers and descriptor.concrete and descriptor.proxy:
|
|
||||||
cgThings.append(CGResolveOwnProperty(descriptor))
|
|
||||||
cgThings.append(CGEnumerateOwnProperties(descriptor))
|
|
||||||
|
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ include $(topsrcdir)/dom/dom-config.mk
|
|||||||
include $(topsrcdir)/dom/webidl/WebIDL.mk
|
include $(topsrcdir)/dom/webidl/WebIDL.mk
|
||||||
|
|
||||||
binding_include_path := mozilla/dom
|
binding_include_path := mozilla/dom
|
||||||
all_webidl_files = $(webidl_files) $(generated_webidl_files)
|
all_webidl_files = $(webidl_files) $(generated_webidl_files) $(preprocessed_webidl_files)
|
||||||
# Set exported_binding_headers before adding the test IDL to the mix
|
# Set exported_binding_headers before adding the test IDL to the mix
|
||||||
exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
|
exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
|
||||||
# Set linked_binding_cpp_files before adding the test IDL to the mix
|
# Set linked_binding_cpp_files before adding the test IDL to the mix
|
||||||
@@ -142,6 +142,23 @@ $(webidl_files): %: $(webidl_base)/%
|
|||||||
$(test_webidl_files): %: $(srcdir)/test/%
|
$(test_webidl_files): %: $(srcdir)/test/%
|
||||||
$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
|
$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
|
||||||
|
|
||||||
|
# We can't easily use PP_TARGETS here because it insists on outputting targets
|
||||||
|
# that look like "$(CURDIR)/foo" whereas we want our target to just be "foo".
|
||||||
|
# Make sure to include $(GLOBAL_DEPS) so we pick up changes to what symbols are
|
||||||
|
# defined. Also make sure to remove $@ before writing to it, because otherwise
|
||||||
|
# if a file goes from non-preprocessed to preprocessed we can end up writing to
|
||||||
|
# a symlink, which will clobber files in the srcdir, which is bad.
|
||||||
|
$(preprocessed_webidl_files): %: $(webidl_base)/% $(GLOBAL_DEPS)
|
||||||
|
$(RM) $@
|
||||||
|
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \
|
||||||
|
$(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(webidl_base)/$* -o $@
|
||||||
|
|
||||||
|
# Make is dumb and can get confused between "foo" and "$(CURDIR)/foo". Make
|
||||||
|
# sure that the latter depends on the former, since the latter gets used in .pp
|
||||||
|
# files.
|
||||||
|
all_webidl_files_absolute = $(addprefix $(CURDIR)/,$(all_webidl_files))
|
||||||
|
$(all_webidl_files_absolute): $(CURDIR)/%: %
|
||||||
|
|
||||||
$(binding_header_files): .BindingGen
|
$(binding_header_files): .BindingGen
|
||||||
|
|
||||||
$(binding_cpp_files): .BindingGen
|
$(binding_cpp_files): .BindingGen
|
||||||
|
|||||||
@@ -168,30 +168,23 @@ BluetoothManager::Create(nsPIDOMWindow* aWindow)
|
|||||||
return manager.forget();
|
return manager.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
// static
|
||||||
NS_NewBluetoothManager(nsPIDOMWindow* aWindow,
|
bool
|
||||||
nsIDOMBluetoothManager** aBluetoothManager)
|
BluetoothManager::CheckPermission(nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aWindow, "Null pointer!");
|
NS_ASSERTION(aWindow, "Null pointer!");
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(permMgr, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(permMgr, false);
|
||||||
|
|
||||||
uint32_t permission;
|
uint32_t permission;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
permMgr->TestPermissionFromWindow(aWindow, "bluetooth",
|
permMgr->TestPermissionFromWindow(aWindow, "bluetooth",
|
||||||
&permission);
|
&permission);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
nsRefPtr<BluetoothManager> bluetoothManager;
|
return permission == nsIPermissionManager::ALLOW_ACTION;
|
||||||
|
|
||||||
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
|
||||||
bluetoothManager = BluetoothManager::Create(aWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
bluetoothManager.forget(aBluetoothManager);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -29,8 +29,10 @@ public:
|
|||||||
|
|
||||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
|
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
|
||||||
|
|
||||||
|
// Never returns null
|
||||||
static already_AddRefed<BluetoothManager>
|
static already_AddRefed<BluetoothManager>
|
||||||
Create(nsPIDOMWindow* aWindow);
|
Create(nsPIDOMWindow* aWindow);
|
||||||
|
static bool CheckPermission(nsPIDOMWindow* aWindow);
|
||||||
void Notify(const BluetoothSignal& aData);
|
void Notify(const BluetoothSignal& aData);
|
||||||
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) MOZ_OVERRIDE;
|
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) MOZ_OVERRIDE;
|
||||||
private:
|
private:
|
||||||
@@ -40,7 +42,4 @@ private:
|
|||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
nsresult NS_NewBluetoothManager(nsPIDOMWindow* aWindow,
|
|
||||||
nsIDOMBluetoothManager** aBluetoothManager);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -71,21 +71,27 @@ nsDOMCameraManager::~nsDOMCameraManager()
|
|||||||
obs->RemoveObserver(this, "xpcom-shutdown");
|
obs->RemoveObserver(this, "xpcom-shutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
// static creator
|
bool
|
||||||
already_AddRefed<nsDOMCameraManager>
|
nsDOMCameraManager::CheckPermission(nsPIDOMWindow* aWindow)
|
||||||
nsDOMCameraManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
|
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(permMgr, nullptr);
|
NS_ENSURE_TRUE(permMgr, false);
|
||||||
|
|
||||||
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
||||||
permMgr->TestPermissionFromWindow(aWindow, "camera", &permission);
|
permMgr->TestPermissionFromWindow(aWindow, "camera", &permission);
|
||||||
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
||||||
NS_WARNING("No permission to access camera");
|
NS_WARNING("No permission to access camera");
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static creator
|
||||||
|
already_AddRefed<nsDOMCameraManager>
|
||||||
|
nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow)
|
||||||
|
{
|
||||||
// Initialize the shared active window tracker
|
// Initialize the shared active window tracker
|
||||||
if (!sActiveWindowsInitialized) {
|
if (!sActiveWindowsInitialized) {
|
||||||
sActiveWindows.Init();
|
sActiveWindows.Init();
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ public:
|
|||||||
nsIObserver)
|
nsIObserver)
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
static bool CheckPermission(nsPIDOMWindow* aWindow);
|
||||||
static already_AddRefed<nsDOMCameraManager>
|
static already_AddRefed<nsDOMCameraManager>
|
||||||
CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow);
|
CreateInstance(nsPIDOMWindow* aWindow);
|
||||||
static bool IsWindowStillActive(uint64_t aWindowId);
|
static bool IsWindowStillActive(uint64_t aWindowId);
|
||||||
|
|
||||||
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
|
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
|
||||||
|
|||||||
@@ -6,13 +6,28 @@ MARIONETTE_TIMEOUT = 30000;
|
|||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
SpecialPowers.addPermission("settings-write", true, document);
|
SpecialPowers.addPermission("settings-write", true, document);
|
||||||
|
|
||||||
let icc = navigator.mozIccManager;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(icc instanceof MozIccManager, "icc is instanceof " + icc.constructor);
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let icc;
|
||||||
|
ifr.onload = function() {
|
||||||
|
icc = ifr.contentWindow.navigator.mozIccManager;
|
||||||
|
|
||||||
|
ok(icc instanceof ifr.contentWindow.MozIccManager,
|
||||||
|
"icc is instanceof " + icc.constructor);
|
||||||
|
|
||||||
is(icc.cardState, "ready");
|
is(icc.cardState, "ready");
|
||||||
|
|
||||||
|
// Enable Airplane mode, expect got cardstatechange to null
|
||||||
|
testCardStateChange(true, null,
|
||||||
|
// Disable Airplane mode, expect got cardstatechange to 'ready'
|
||||||
|
testCardStateChange.bind(window, false, "ready", cleanUp)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
function setAirplaneModeEnabled(enabled) {
|
function setAirplaneModeEnabled(enabled) {
|
||||||
let settings = window.navigator.mozSettings;
|
let settings = ifr.contentWindow.navigator.mozSettings;
|
||||||
let setLock = settings.createLock();
|
let setLock = settings.createLock();
|
||||||
let obj = {
|
let obj = {
|
||||||
"ril.radio.disabled": enabled
|
"ril.radio.disabled": enabled
|
||||||
@@ -53,9 +68,3 @@ function cleanUp() {
|
|||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable Airplane mode, expect got cardstatechange to null
|
|
||||||
testCardStateChange(true, null,
|
|
||||||
// Disable Airplane mode, expect got cardstatechange to 'ready'
|
|
||||||
testCardStateChange.bind(this, false, "ready", cleanUp)
|
|
||||||
);
|
|
||||||
@@ -5,10 +5,43 @@ MARIONETTE_TIMEOUT = 30000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let icc = navigator.mozIccManager;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(icc instanceof MozIccManager,
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let icc;
|
||||||
|
let iccInfo;
|
||||||
|
ifr.onload = function() {
|
||||||
|
icc = ifr.contentWindow.navigator.mozIccManager;
|
||||||
|
ok(icc instanceof ifr.contentWindow.MozIccManager,
|
||||||
"icc is instanceof " + icc.constructor);
|
"icc is instanceof " + icc.constructor);
|
||||||
|
|
||||||
|
iccInfo = icc.iccInfo;
|
||||||
|
|
||||||
|
// The emulator's hard coded iccid value.
|
||||||
|
// See it here {B2G_HOME}/external/qemu/telephony/sim_card.c#L299.
|
||||||
|
is(iccInfo.iccid, 89014103211118510720);
|
||||||
|
|
||||||
|
// The emulator's hard coded mcc and mnc codes.
|
||||||
|
// See it here {B2G_HOME}/external/qemu/telephony/android_modem.c#L2465.
|
||||||
|
is(iccInfo.mcc, 310);
|
||||||
|
is(iccInfo.mnc, 260);
|
||||||
|
is(iccInfo.spn, "Android");
|
||||||
|
// Phone number is hardcoded in MSISDN
|
||||||
|
// See {B2G_HOME}/external/qemu/telephony/sim_card.c, in asimcard_io()
|
||||||
|
is(iccInfo.msisdn, "15555215554");
|
||||||
|
|
||||||
|
testDisplayConditionChange(testSPN, [
|
||||||
|
// [MCC, MNC, isDisplayNetworkNameRequired, isDisplaySpnRequired]
|
||||||
|
[123, 456, false, true], // Not in HPLMN.
|
||||||
|
[234, 136, true, true], // Not in HPLMN, but in PLMN specified in SPDI.
|
||||||
|
[123, 456, false, true], // Not in HPLMN. Triggering iccinfochange
|
||||||
|
[466, 92, true, true], // Not in HPLMN, but in another PLMN specified in SPDI.
|
||||||
|
[123, 456, false, true], // Not in HPLMN. Triggering iccinfochange
|
||||||
|
[310, 260, true, true], // inside HPLMN.
|
||||||
|
], finalize);
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let emulatorCmdPendingCount = 0;
|
let emulatorCmdPendingCount = 0;
|
||||||
function sendEmulatorCommand(cmd, callback) {
|
function sendEmulatorCommand(cmd, callback) {
|
||||||
emulatorCmdPendingCount++;
|
emulatorCmdPendingCount++;
|
||||||
@@ -39,21 +72,6 @@ function finalize() {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
let iccInfo = icc.iccInfo;
|
|
||||||
|
|
||||||
// The emulator's hard coded iccid value.
|
|
||||||
// See it here {B2G_HOME}/external/qemu/telephony/sim_card.c#L299.
|
|
||||||
is(iccInfo.iccid, 89014103211118510720);
|
|
||||||
|
|
||||||
// The emulator's hard coded mcc and mnc codes.
|
|
||||||
// See it here {B2G_HOME}/external/qemu/telephony/android_modem.c#L2465.
|
|
||||||
is(iccInfo.mcc, 310);
|
|
||||||
is(iccInfo.mnc, 260);
|
|
||||||
is(iccInfo.spn, "Android");
|
|
||||||
// Phone number is hardcoded in MSISDN
|
|
||||||
// See {B2G_HOME}/external/qemu/telephony/sim_card.c, in asimcard_io()
|
|
||||||
is(iccInfo.msisdn, "15555215554");
|
|
||||||
|
|
||||||
// Test display condition change.
|
// Test display condition change.
|
||||||
function testDisplayConditionChange(func, caseArray, oncomplete) {
|
function testDisplayConditionChange(func, caseArray, oncomplete) {
|
||||||
(function do_call(index) {
|
(function do_call(index) {
|
||||||
@@ -75,13 +93,3 @@ function testSPN(mcc, mnc, expectedIsDisplayNetworkNameRequired,
|
|||||||
});
|
});
|
||||||
setEmulatorMccMnc(mcc, mnc);
|
setEmulatorMccMnc(mcc, mnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
testDisplayConditionChange(testSPN, [
|
|
||||||
// [MCC, MNC, isDisplayNetworkNameRequired, isDisplaySpnRequired]
|
|
||||||
[123, 456, false, true], // Not in HPLMN.
|
|
||||||
[234, 136, true, true], // Not in HPLMN, but in PLMN specified in SPDI.
|
|
||||||
[123, 456, false, true], // Not in HPLMN. Triggering iccinfochange
|
|
||||||
[466, 92, true, true], // Not in HPLMN, but in another PLMN specified in SPDI.
|
|
||||||
[123, 456, false, true], // Not in HPLMN. Triggering iccinfochange
|
|
||||||
[310, 260, true, true], // inside HPLMN.
|
|
||||||
], finalize);
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
'nsIDOMMozSettingsEvent.idl',
|
'nsIDOMMozSettingsEvent.idl',
|
||||||
'nsIDOMSettingsManager.idl',
|
|
||||||
'nsISettingsService.idl',
|
'nsISettingsService.idl',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/* 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/. */
|
|
||||||
|
|
||||||
#include "domstubs.idl"
|
|
||||||
#include "nsIDOMEventTarget.idl"
|
|
||||||
|
|
||||||
interface nsIDOMDOMRequest;
|
|
||||||
interface nsIVariant;
|
|
||||||
|
|
||||||
[scriptable, uuid(ef95ddd0-6308-11e1-b86c-0800200c9a66)]
|
|
||||||
interface nsIDOMSettingsLock : nsISupports
|
|
||||||
{
|
|
||||||
// Whether this lock is invalid
|
|
||||||
readonly attribute boolean closed;
|
|
||||||
|
|
||||||
// Contains a JSON object with name/value pairs to be set.
|
|
||||||
nsIDOMDOMRequest set(in nsIVariant settings);
|
|
||||||
|
|
||||||
// result contains the value of the setting.
|
|
||||||
nsIDOMDOMRequest get(in jsval name);
|
|
||||||
|
|
||||||
nsIDOMDOMRequest clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
[scriptable, uuid(c40b1c70-00fb-11e2-a21f-0800200c9a66)]
|
|
||||||
interface nsIDOMSettingsManager : nsISupports
|
|
||||||
{
|
|
||||||
nsIDOMSettingsLock createLock();
|
|
||||||
|
|
||||||
void addObserver(in DOMString name, in jsval callback);
|
|
||||||
void removeObserver(in DOMString name, in jsval callback);
|
|
||||||
|
|
||||||
attribute nsIDOMEventListener onsettingchange;
|
|
||||||
};
|
|
||||||
@@ -78,7 +78,12 @@ const BrowserElementIsPreloaded = true;
|
|||||||
Cc["@mozilla.org/contentsecuritypolicy;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
|
Cc["@mozilla.org/contentsecuritypolicy;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
|
||||||
|
|
||||||
/* Applications Specific Helper */
|
/* Applications Specific Helper */
|
||||||
Cc["@mozilla.org/settingsManager;1"].getService(Ci["nsIDOMSettingsManager"]);
|
try {
|
||||||
|
// May throw if we don't have the settings permission
|
||||||
|
navigator.mozSettings;
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
|
if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
|
||||||
Cc["@mozilla.org/system-message-manager;1"].getService(Ci["nsIDOMNavigatorSystemMessages"]);
|
Cc["@mozilla.org/system-message-manager;1"].getService(Ci["nsIDOMNavigatorSystemMessages"]);
|
||||||
|
|||||||
@@ -1095,9 +1095,9 @@ MediaManager::GetUserMedia(bool aPrivileged, nsPIDOMWindow* aWindow,
|
|||||||
|
|
||||||
#ifdef MOZ_B2G_CAMERA
|
#ifdef MOZ_B2G_CAMERA
|
||||||
if (mCameraManager == nullptr) {
|
if (mCameraManager == nullptr) {
|
||||||
mCameraManager = nsDOMCameraManager::CheckPermissionAndCreateInstance(aWindow);
|
aPrivileged = nsDOMCameraManager::CheckPermission(aWindow);
|
||||||
if (!mCameraManager) {
|
if (aPrivileged) {
|
||||||
aPrivileged = false;
|
mCameraManager = nsDOMCameraManager::CreateInstance(aWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=802982
|
|||||||
function boom()
|
function boom()
|
||||||
{
|
{
|
||||||
for (var j = 0; j < 100; ++j) {
|
for (var j = 0; j < 100; ++j) {
|
||||||
navigator.mozGetUserMedia({}, {}, {});
|
navigator.mozGetUserMedia({}, function(){}, function(){});
|
||||||
}
|
}
|
||||||
finish(); // we're not waiting for success/error callbacks here
|
finish(); // we're not waiting for success/error callbacks here
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,26 +26,26 @@ var exceptionTests = [
|
|||||||
// Each test here verifies that a caller is required to have all
|
// Each test here verifies that a caller is required to have all
|
||||||
// three arguments in order to call mozGetUserMedia
|
// three arguments in order to call mozGetUserMedia
|
||||||
{ params: undefined,
|
{ params: undefined,
|
||||||
error: Cr.NS_ERROR_XPC_NOT_ENOUGH_ARGS,
|
error: "Not enough arguments to Navigator.mozGetUserMedia.",
|
||||||
message: "no arguments specified" },
|
message: "no arguments specified" },
|
||||||
{ params: [{video: true, fake: true}],
|
{ params: [{video: true, fake: true}],
|
||||||
error: Cr.NS_ERROR_XPC_NOT_ENOUGH_ARGS,
|
error: "Not enough arguments to Navigator.mozGetUserMedia.",
|
||||||
message: "one argument specified" },
|
message: "one argument specified" },
|
||||||
{ params: [{video: true, fake: true}, unexpectedCall],
|
{ params: [{video: true, fake: true}, unexpectedCall],
|
||||||
error: Cr.NS_ERROR_XPC_NOT_ENOUGH_ARGS,
|
error: "Not enough arguments to Navigator.mozGetUserMedia.",
|
||||||
message: "two arguments specified" },
|
message: "two arguments specified" },
|
||||||
|
|
||||||
// Each test here verifies that providing an incorret object
|
// Each test here verifies that providing an incorret object
|
||||||
// type to any mozGetUserMedia parameter should throw
|
// type to any mozGetUserMedia parameter should throw
|
||||||
// the correct exception specified
|
// the correct exception specified
|
||||||
{ params: [1, unexpectedCall, unexpectedCall],
|
{ params: [1, unexpectedCall, unexpectedCall],
|
||||||
error: Cr.NS_ERROR_XPC_BAD_CONVERT_JS,
|
error: "Argument 1 of Navigator.mozGetUserMedia is not an object.",
|
||||||
message: "wrong object type as first parameter" },
|
message: "wrong object type as first parameter" },
|
||||||
{ params: [{video: true, fake: true}, 1, unexpectedCall],
|
{ params: [{video: true, fake: true}, 1, unexpectedCall],
|
||||||
error: Cr.NS_ERROR_XPC_BAD_CONVERT_JS,
|
error: "Argument 2 of Navigator.mozGetUserMedia is not an object.",
|
||||||
message: "wrong object type as second parameter" },
|
message: "wrong object type as second parameter" },
|
||||||
{ params: [{video: true, fake: true}, unexpectedCall, 1],
|
{ params: [{video: true, fake: true}, unexpectedCall, 1],
|
||||||
error: Cr.NS_ERROR_XPC_BAD_CONVERT_JS,
|
error: "Argument 3 of Navigator.mozGetUserMedia is not an object.",
|
||||||
message: "wrong object type as third parameter" }
|
message: "wrong object type as third parameter" }
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ runTest(function () {
|
|||||||
try {
|
try {
|
||||||
navigator.mozGetUserMedia.apply(navigator, test.params);
|
navigator.mozGetUserMedia.apply(navigator, test.params);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
exception = (e.result === test.error);
|
exception = (e.message === test.error);
|
||||||
}
|
}
|
||||||
ok(exception, "Exception for " + test.message);
|
ok(exception, "Exception for " + test.message);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,41 +54,49 @@ NS_IMPL_EVENT_HANDLER(SmsManager, failed)
|
|||||||
NS_IMPL_EVENT_HANDLER(SmsManager, deliverysuccess)
|
NS_IMPL_EVENT_HANDLER(SmsManager, deliverysuccess)
|
||||||
NS_IMPL_EVENT_HANDLER(SmsManager, deliveryerror)
|
NS_IMPL_EVENT_HANDLER(SmsManager, deliveryerror)
|
||||||
|
|
||||||
/* static */already_AddRefed<SmsManager>
|
/* static */
|
||||||
SmsManager::CreateInstanceIfAllowed(nsPIDOMWindow* aWindow)
|
bool
|
||||||
|
SmsManager::CreationIsAllowed(nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aWindow, "Null pointer!");
|
NS_ASSERTION(aWindow, "Null pointer!");
|
||||||
|
|
||||||
#ifndef MOZ_WEBSMS_BACKEND
|
#ifndef MOZ_WEBSMS_BACKEND
|
||||||
return nullptr;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// First of all, the general pref has to be turned on.
|
// First of all, the general pref has to be turned on.
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
Preferences::GetBool("dom.sms.enabled", &enabled);
|
Preferences::GetBool("dom.sms.enabled", &enabled);
|
||||||
NS_ENSURE_TRUE(enabled, nullptr);
|
NS_ENSURE_TRUE(enabled, false);
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(permMgr, nullptr);
|
NS_ENSURE_TRUE(permMgr, false);
|
||||||
|
|
||||||
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
||||||
permMgr->TestPermissionFromWindow(aWindow, "sms", &permission);
|
permMgr->TestPermissionFromWindow(aWindow, "sms", &permission);
|
||||||
|
|
||||||
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the Sms Service:
|
// Check the Sms Service:
|
||||||
nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
|
nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(smsService, nullptr);
|
NS_ENSURE_TRUE(smsService, false);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
smsService->HasSupport(&result);
|
smsService->HasSupport(&result);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<SmsManager>
|
||||||
|
SmsManager::CreateInstance(nsPIDOMWindow* aWindow)
|
||||||
|
{
|
||||||
nsRefPtr<SmsManager> smsMgr = new SmsManager();
|
nsRefPtr<SmsManager> smsMgr = new SmsManager();
|
||||||
smsMgr->Init(aWindow);
|
smsMgr->Init(aWindow);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ public:
|
|||||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
|
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
|
||||||
|
|
||||||
static already_AddRefed<SmsManager>
|
static already_AddRefed<SmsManager>
|
||||||
CreateInstanceIfAllowed(nsPIDOMWindow *aWindow);
|
CreateInstance(nsPIDOMWindow *aWindow);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
CreationIsAllowed(nsPIDOMWindow *aWindow);
|
||||||
|
|
||||||
void Init(nsPIDOMWindow *aWindow);
|
void Init(nsPIDOMWindow *aWindow);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
/** Test for WebSMS **/
|
/** Test for WebSMS **/
|
||||||
|
|
||||||
function checkSmsDisabled() {
|
function checkSmsDisabled() {
|
||||||
ok('mozSms' in frames[0].navigator, "navigator.mozSms should exist");
|
ok(!('mozSms' in frames[0].navigator), "navigator.mozSms should not exist");
|
||||||
is(frames[0].navigator.mozSms, null, "navigator.mozSms should return null");
|
ok(frames[0].navigator.mozSms === undefined,
|
||||||
|
"navigator.mozSms should return undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSmsEnabled() {
|
function checkSmsEnabled() {
|
||||||
|
|||||||
@@ -5,10 +5,20 @@ MARIONETTE_TIMEOUT = 60000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let connection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(connection instanceof MozMobileConnection,
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let connection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
connection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
|
||||||
|
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
|
||||||
"connection is instanceof " + connection.constructor);
|
"connection is instanceof " + connection.constructor);
|
||||||
|
|
||||||
|
testGetCallBarringOption();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
function testGetCallBarringOption() {
|
function testGetCallBarringOption() {
|
||||||
let option = {'program': 0, 'password': '', 'serviceClass': 0};
|
let option = {'program': 0, 'password': '', 'serviceClass': 0};
|
||||||
let request = connection.getCallBarringOption(option);
|
let request = connection.getCallBarringOption(option);
|
||||||
@@ -27,5 +37,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
testGetCallBarringOption();
|
|
||||||
|
|||||||
@@ -5,10 +5,20 @@ MARIONETTE_TIMEOUT = 60000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let connection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(connection instanceof MozMobileConnection,
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let connection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
connection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
|
||||||
|
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
|
||||||
"connection is instanceof " + connection.constructor);
|
"connection is instanceof " + connection.constructor);
|
||||||
|
|
||||||
|
nextTest();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let caseId = 0;
|
let caseId = 0;
|
||||||
let options = [
|
let options = [
|
||||||
buildOption(5, true, '0000', 0), // invalid program.
|
buildOption(5, true, '0000', 0), // invalid program.
|
||||||
@@ -61,5 +71,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
nextTest();
|
|
||||||
|
|||||||
@@ -5,7 +5,18 @@ MARIONETTE_TIMEOUT = 20000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let mobileConnection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let mobileConnection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
|
||||||
|
// Start the test
|
||||||
|
verifyInitialState();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let emulatorStartLac = 0;
|
let emulatorStartLac = 0;
|
||||||
let emulatorStartCid = 0;
|
let emulatorStartCid = 0;
|
||||||
|
|
||||||
@@ -114,6 +125,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the test
|
|
||||||
verifyInitialState();
|
|
||||||
|
|||||||
@@ -5,7 +5,17 @@ MARIONETTE_TIMEOUT = 30000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let mobileConnection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let mobileConnection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
|
||||||
|
// Start the test
|
||||||
|
verifyInitialState();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
function verifyInitialState() {
|
function verifyInitialState() {
|
||||||
log("Verifying initial state.");
|
log("Verifying initial state.");
|
||||||
@@ -116,6 +126,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the test
|
|
||||||
verifyInitialState();
|
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ MARIONETTE_TIMEOUT = 20000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let mobileConnection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let mobileConnection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
mobileConnection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
|
||||||
|
tasks.run();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let tasks = {
|
let tasks = {
|
||||||
// List of test functions. Each of them should call |tasks.next()| when
|
// List of test functions. Each of them should call |tasks.next()| when
|
||||||
@@ -43,7 +52,7 @@ let tasks = {
|
|||||||
tasks.push(function verifyInitialState() {
|
tasks.push(function verifyInitialState() {
|
||||||
log("Verifying initial state.");
|
log("Verifying initial state.");
|
||||||
|
|
||||||
ok(mobileConnection instanceof MozMobileConnection,
|
ok(mobileConnection instanceof ifr.contentWindow.MozMobileConnection,
|
||||||
"mobileConnection is instanceof " + mobileConnection.constructor);
|
"mobileConnection is instanceof " + mobileConnection.constructor);
|
||||||
|
|
||||||
tasks.next();
|
tasks.next();
|
||||||
@@ -77,5 +86,3 @@ tasks.push(function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
});
|
});
|
||||||
|
|
||||||
tasks.run();
|
|
||||||
|
|||||||
@@ -8,16 +8,29 @@ SpecialPowers.addPermission("mobileconnection", true, document);
|
|||||||
const OPERATOR_HOME = 0;
|
const OPERATOR_HOME = 0;
|
||||||
const OPERATOR_ROAMING = 1;
|
const OPERATOR_ROAMING = 1;
|
||||||
|
|
||||||
let connection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(connection instanceof MozMobileConnection,
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let connection;
|
||||||
|
let voice;
|
||||||
|
let network;
|
||||||
|
ifr.onload = function() {
|
||||||
|
connection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
|
||||||
"connection is instanceof " + connection.constructor);
|
"connection is instanceof " + connection.constructor);
|
||||||
|
|
||||||
let voice = connection.voice;
|
voice = connection.voice;
|
||||||
ok(voice, "voice connection valid");
|
ok(voice, "voice connection valid");
|
||||||
|
|
||||||
let network = voice.network;
|
network = voice.network;
|
||||||
ok(network, "voice network info valid");
|
ok(network, "voice network info valid");
|
||||||
|
|
||||||
|
waitFor(testMobileOperatorNames, function () {
|
||||||
|
return voice.connected;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let emulatorCmdPendingCount = 0;
|
let emulatorCmdPendingCount = 0;
|
||||||
function sendEmulatorCommand(cmd, callback) {
|
function sendEmulatorCommand(cmd, callback) {
|
||||||
emulatorCmdPendingCount++;
|
emulatorCmdPendingCount++;
|
||||||
@@ -203,7 +216,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
waitFor(testMobileOperatorNames, function () {
|
|
||||||
return voice.connected;
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -5,9 +5,17 @@ MARIONETTE_TIMEOUT = 30000;
|
|||||||
|
|
||||||
SpecialPowers.addPermission("mobileconnection", true, document);
|
SpecialPowers.addPermission("mobileconnection", true, document);
|
||||||
|
|
||||||
let connection = navigator.mozMobileConnection;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
ok(connection instanceof MozMobileConnection,
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let connection;
|
||||||
|
ifr.onload = function() {
|
||||||
|
connection = ifr.contentWindow.navigator.mozMobileConnection;
|
||||||
|
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
|
||||||
"connection is instanceof " + connection.constructor);
|
"connection is instanceof " + connection.constructor);
|
||||||
|
testConnectionInfo();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
let emulatorCmdPendingCount = 0;
|
let emulatorCmdPendingCount = 0;
|
||||||
function setEmulatorVoiceState(state) {
|
function setEmulatorVoiceState(state) {
|
||||||
@@ -149,5 +157,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("mobileconnection", document);
|
SpecialPowers.removePermission("mobileconnection", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
testConnectionInfo();
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ var gData = [
|
|||||||
{
|
{
|
||||||
perm: ["settings"],
|
perm: ["settings"],
|
||||||
obj: 'mozSettings',
|
obj: 'mozSettings',
|
||||||
idl: 'nsIDOMSettingsManager',
|
webidl: 'SettingsManager',
|
||||||
settings: [["dom.mozSettings.enabled", true]],
|
settings: [["dom.mozSettings.enabled", true]],
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -179,22 +179,26 @@ PowerManager::SetCpuSleepAllowed(bool aAllowed)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<PowerManager>
|
bool
|
||||||
PowerManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
|
PowerManager::CheckPermission(nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(permMgr, nullptr);
|
NS_ENSURE_TRUE(permMgr, false);
|
||||||
|
|
||||||
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
uint32_t permission = nsIPermissionManager::DENY_ACTION;
|
||||||
permMgr->TestPermissionFromWindow(aWindow, "power", &permission);
|
permMgr->TestPermissionFromWindow(aWindow, "power", &permission);
|
||||||
|
|
||||||
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
return permission == nsIPermissionManager::ALLOW_ACTION;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<PowerManager>
|
||||||
|
PowerManager::CreateInstance(nsPIDOMWindow* aWindow)
|
||||||
|
{
|
||||||
nsRefPtr<PowerManager> powerManager = new PowerManager();
|
nsRefPtr<PowerManager> powerManager = new PowerManager();
|
||||||
powerManager->Init(aWindow);
|
if (NS_FAILED(powerManager->Init(aWindow))) {
|
||||||
|
powerManager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return powerManager.forget();
|
return powerManager.forget();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ public:
|
|||||||
nsresult Init(nsIDOMWindow *aWindow);
|
nsresult Init(nsIDOMWindow *aWindow);
|
||||||
nsresult Shutdown();
|
nsresult Shutdown();
|
||||||
|
|
||||||
static already_AddRefed<PowerManager>
|
static bool CheckPermission(nsPIDOMWindow*);
|
||||||
CheckPermissionAndCreateInstance(nsPIDOMWindow*);
|
|
||||||
|
static already_AddRefed<PowerManager> CreateInstance(nsPIDOMWindow*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -23,13 +23,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
|||||||
"@mozilla.org/childprocessmessagemanager;1",
|
"@mozilla.org/childprocessmessagemanager;1",
|
||||||
"nsIMessageSender");
|
"nsIMessageSender");
|
||||||
|
|
||||||
const nsIClassInfo = Ci.nsIClassInfo;
|
function SettingsLock(aSettingsManager) {
|
||||||
const SETTINGSLOCK_CONTRACTID = "@mozilla.org/settingsLock;1";
|
|
||||||
const SETTINGSLOCK_CID = Components.ID("{60c9357c-3ae0-4222-8f55-da01428470d5}");
|
|
||||||
const nsIDOMSettingsLock = Ci.nsIDOMSettingsLock;
|
|
||||||
|
|
||||||
function SettingsLock(aSettingsManager)
|
|
||||||
{
|
|
||||||
this._open = true;
|
this._open = true;
|
||||||
this._isBusy = false;
|
this._isBusy = false;
|
||||||
this._requests = new Queue();
|
this._requests = new Queue();
|
||||||
@@ -38,7 +32,6 @@ function SettingsLock(aSettingsManager)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsLock.prototype = {
|
SettingsLock.prototype = {
|
||||||
|
|
||||||
get closed() {
|
get closed() {
|
||||||
return !this._open;
|
return !this._open;
|
||||||
},
|
},
|
||||||
@@ -217,8 +210,7 @@ SettingsLock.prototype = {
|
|||||||
|
|
||||||
set: function set(aSettings) {
|
set: function set(aSettings) {
|
||||||
if (!this._open) {
|
if (!this._open) {
|
||||||
dump("Settings lock not open!\n");
|
throw "Settings lock not open";
|
||||||
throw Components.results.NS_ERROR_ABORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._settingsManager.hasWritePrivileges) {
|
if (this._settingsManager.hasWritePrivileges) {
|
||||||
@@ -230,14 +222,13 @@ SettingsLock.prototype = {
|
|||||||
return req;
|
return req;
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) debug("set not allowed");
|
if (DEBUG) debug("set not allowed");
|
||||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
throw "No permission to call set";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function clear() {
|
clear: function clear() {
|
||||||
if (!this._open) {
|
if (!this._open) {
|
||||||
dump("Settings lock not open!\n");
|
throw "Settings lock not open";
|
||||||
throw Components.results.NS_ERROR_ABORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._settingsManager.hasWritePrivileges) {
|
if (this._settingsManager.hasWritePrivileges) {
|
||||||
@@ -247,28 +238,18 @@ SettingsLock.prototype = {
|
|||||||
return req;
|
return req;
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) debug("clear not allowed");
|
if (DEBUG) debug("clear not allowed");
|
||||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
throw "No permission to call clear";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
classID : SETTINGSLOCK_CID,
|
classID: Components.ID("{60c9357c-3ae0-4222-8f55-da01428470d5}"),
|
||||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMSettingsLock]),
|
contractID: "@mozilla.org/settingsLock;1",
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||||
classInfo : XPCOMUtils.generateCI({classID: SETTINGSLOCK_CID,
|
|
||||||
contractID: SETTINGSLOCK_CONTRACTID,
|
|
||||||
classDescription: "SettingsLock",
|
|
||||||
interfaces: [nsIDOMSettingsLock],
|
|
||||||
flags: nsIClassInfo.DOM_OBJECT})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SETTINGSMANAGER_CONTRACTID = "@mozilla.org/settingsManager;1";
|
|
||||||
const SETTINGSMANAGER_CID = Components.ID("{c40b1c70-00fb-11e2-a21f-0800200c9a66}");
|
|
||||||
const nsIDOMSettingsManager = Ci.nsIDOMSettingsManager;
|
|
||||||
|
|
||||||
let myGlobal = this;
|
let myGlobal = this;
|
||||||
|
|
||||||
function SettingsManager()
|
function SettingsManager() {
|
||||||
{
|
|
||||||
this._locks = new Queue();
|
this._locks = new Queue();
|
||||||
if (!("indexedDB" in myGlobal)) {
|
if (!("indexedDB" in myGlobal)) {
|
||||||
let idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
|
let idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
|
||||||
@@ -279,7 +260,6 @@ function SettingsManager()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsManager.prototype = {
|
SettingsManager.prototype = {
|
||||||
_onsettingchange: null,
|
|
||||||
_callbacks: null,
|
_callbacks: null,
|
||||||
|
|
||||||
_wrap: function _wrap(obj) {
|
_wrap: function _wrap(obj) {
|
||||||
@@ -293,19 +273,12 @@ SettingsManager.prototype = {
|
|||||||
Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
|
Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
},
|
},
|
||||||
|
|
||||||
set onsettingchange(aCallback) {
|
set onsettingchange(aHandler) {
|
||||||
if (this.hasReadPrivileges) {
|
this.__DOM_IMPL__.setEventHandler("onsettingchange", aHandler);
|
||||||
if (!this._onsettingchange) {
|
|
||||||
cpmm.sendAsyncMessage("Settings:RegisterForMessages");
|
|
||||||
}
|
|
||||||
this._onsettingchange = aCallback;
|
|
||||||
} else {
|
|
||||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get onsettingchange() {
|
get onsettingchange() {
|
||||||
return this._onsettingchange;
|
return this.__DOM_IMPL__.getEventHandler("onsettingchange");
|
||||||
},
|
},
|
||||||
|
|
||||||
createLock: function() {
|
createLock: function() {
|
||||||
@@ -326,22 +299,19 @@ SettingsManager.prototype = {
|
|||||||
|
|
||||||
switch (aMessage.name) {
|
switch (aMessage.name) {
|
||||||
case "Settings:Change:Return:OK":
|
case "Settings:Change:Return:OK":
|
||||||
if (this._onsettingchange || this._callbacks) {
|
|
||||||
if (DEBUG) debug('data:' + msg.key + ':' + msg.value + '\n');
|
if (DEBUG) debug('data:' + msg.key + ':' + msg.value + '\n');
|
||||||
|
|
||||||
if (this._onsettingchange) {
|
let event = new this._window.MozSettingsEvent("settingchange", this._wrap({
|
||||||
let event = new this._window.MozSettingsEvent("settingchanged", this._wrap({
|
|
||||||
settingName: msg.key,
|
settingName: msg.key,
|
||||||
settingValue: msg.value
|
settingValue: msg.value
|
||||||
}));
|
}));
|
||||||
this._onsettingchange.handleEvent(event);
|
this.__DOM_IMPL__.dispatchEvent(event);
|
||||||
}
|
|
||||||
if (this._callbacks && this._callbacks[msg.key]) {
|
if (this._callbacks && this._callbacks[msg.key]) {
|
||||||
if (DEBUG) debug("observe callback called! " + msg.key + " " + this._callbacks[msg.key].length);
|
if (DEBUG) debug("observe callback called! " + msg.key + " " + this._callbacks[msg.key].length);
|
||||||
this._callbacks[msg.key].forEach(function(cb) {
|
this._callbacks[msg.key].forEach(function(cb) {
|
||||||
cb(this._wrap({settingName: msg.key, settingValue: msg.value}));
|
cb(this._wrap({settingName: msg.key, settingValue: msg.value}));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) debug("no observers stored!");
|
if (DEBUG) debug("no observers stored!");
|
||||||
}
|
}
|
||||||
@@ -390,9 +360,12 @@ SettingsManager.prototype = {
|
|||||||
this.hasReadPrivileges = readPerm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
this.hasReadPrivileges = readPerm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||||
this.hasWritePrivileges = writePerm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
this.hasWritePrivileges = writePerm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||||
|
|
||||||
|
if (this.hasReadPrivileges) {
|
||||||
|
cpmm.sendAsyncMessage("Settings:RegisterForMessages");
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.hasReadPrivileges && !this.hasWritePrivileges) {
|
if (!this.hasReadPrivileges && !this.hasWritePrivileges) {
|
||||||
Cu.reportError("NO SETTINGS PERMISSION FOR: " + aWindow.document.nodePrincipal.origin + "\n");
|
throw "NO SETTINGS PERMISSION FOR: " + aWindow.document.nodePrincipal.origin + "\n";
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -406,20 +379,15 @@ SettingsManager.prototype = {
|
|||||||
this._requests = null;
|
this._requests = null;
|
||||||
this._window = null;
|
this._window = null;
|
||||||
this._innerWindowID = null;
|
this._innerWindowID = null;
|
||||||
this._onsettingchange = null;
|
|
||||||
this._settingsDB.close();
|
this._settingsDB.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
classID : SETTINGSMANAGER_CID,
|
classID: Components.ID("{c40b1c70-00fb-11e2-a21f-0800200c9a66}"),
|
||||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMSettingsManager, Ci.nsIDOMGlobalPropertyInitializer]),
|
contractID: "@mozilla.org/settingsManager;1",
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||||
classInfo : XPCOMUtils.generateCI({classID: SETTINGSMANAGER_CID,
|
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||||
contractID: SETTINGSMANAGER_CONTRACTID,
|
};
|
||||||
classDescription: "SettingsManager",
|
|
||||||
interfaces: [nsIDOMSettingsManager],
|
|
||||||
flags: nsIClassInfo.DOM_OBJECT})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SettingsManager, SettingsLock])
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SettingsManager, SettingsLock])
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
component {c40b1c70-00fb-11e2-a21f-0800200c9a66} SettingsManager.js
|
component {c40b1c70-00fb-11e2-a21f-0800200c9a66} SettingsManager.js
|
||||||
contract @mozilla.org/settingsManager;1 {c40b1c70-00fb-11e2-a21f-0800200c9a66}
|
contract @mozilla.org/settingsManager;1 {c40b1c70-00fb-11e2-a21f-0800200c9a66}
|
||||||
category JavaScript-navigator-property mozSettings @mozilla.org/settingsManager;1
|
|
||||||
|
|
||||||
component {60c9357c-3ae0-4222-8f55-da01428470d5} SettingsManager.js
|
component {60c9357c-3ae0-4222-8f55-da01428470d5} SettingsManager.js
|
||||||
contract @mozilla.org/settingsLock;1 {60c9357c-3ae0-4222-8f55-da01428470d5}
|
contract @mozilla.org/settingsLock;1 {60c9357c-3ae0-4222-8f55-da01428470d5}
|
||||||
|
|||||||
@@ -64,11 +64,12 @@ let steps = [
|
|||||||
req.onerror = onFailure("Deleting database");
|
req.onerror = onFailure("Deleting database");
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
mozSettings.addObserver("test1", function(e) {
|
function obs(e) {
|
||||||
checkBlob(e.settingValue);
|
checkBlob(e.settingValue);
|
||||||
mozSettings.removeObserver("test1", this);
|
mozSettings.removeObserver("test1", obs);
|
||||||
next();
|
next();
|
||||||
});
|
}
|
||||||
|
mozSettings.addObserver("test1", obs);
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
|
|||||||
@@ -117,29 +117,47 @@ Telephony::~Telephony()
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<Telephony>
|
already_AddRefed<Telephony>
|
||||||
Telephony::Create(nsPIDOMWindow* aOwner, nsITelephonyProvider* aProvider)
|
Telephony::Create(nsPIDOMWindow* aOwner, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aOwner, "Null owner!");
|
NS_ASSERTION(aOwner, "Null owner!");
|
||||||
NS_ASSERTION(aProvider, "Null provider!");
|
|
||||||
|
nsCOMPtr<nsITelephonyProvider> ril =
|
||||||
|
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
|
||||||
|
if (!ril) {
|
||||||
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
|
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
|
||||||
NS_ENSURE_TRUE(sgo, nullptr);
|
if (!sgo) {
|
||||||
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
|
nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
|
||||||
NS_ENSURE_TRUE(scriptContext, nullptr);
|
if (!scriptContext) {
|
||||||
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<Telephony> telephony = new Telephony();
|
nsRefPtr<Telephony> telephony = new Telephony();
|
||||||
|
|
||||||
telephony->BindToOwner(aOwner);
|
telephony->BindToOwner(aOwner);
|
||||||
|
|
||||||
telephony->mProvider = aProvider;
|
telephony->mProvider = ril;
|
||||||
telephony->mListener = new Listener(telephony);
|
telephony->mListener = new Listener(telephony);
|
||||||
|
|
||||||
nsresult rv = aProvider->EnumerateCalls(telephony->mListener);
|
nsresult rv = ril->EnumerateCalls(telephony->mListener);
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
if (NS_FAILED(rv)) {
|
||||||
|
aRv.Throw(rv);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
rv = aProvider->RegisterTelephonyMsg(telephony->mListener);
|
rv = ril->RegisterTelephonyMsg(telephony->mListener);
|
||||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
if (NS_FAILED(rv)) {
|
||||||
|
aRv.Throw(rv);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return telephony.forget();
|
return telephony.forget();
|
||||||
}
|
}
|
||||||
@@ -574,36 +592,24 @@ Telephony::EnqueueEnumerationAck()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
/* static */
|
||||||
NS_NewTelephony(nsPIDOMWindow* aWindow, nsIDOMTelephony** aTelephony)
|
bool
|
||||||
|
Telephony::CheckPermission(nsPIDOMWindow* aWindow)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aWindow, "Null pointer!");
|
MOZ_ASSERT(aWindow && aWindow->IsInnerWindow());
|
||||||
|
|
||||||
nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
|
|
||||||
aWindow :
|
|
||||||
aWindow->GetCurrentInnerWindow();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(permMgr, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(permMgr, false);
|
||||||
|
|
||||||
uint32_t permission;
|
uint32_t permission;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
permMgr->TestPermissionFromWindow(aWindow, "telephony", &permission);
|
permMgr->TestPermissionFromWindow(aWindow, "telephony", &permission);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
if (permission != nsIPermissionManager::ALLOW_ACTION) {
|
||||||
*aTelephony = nullptr;
|
return false;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsITelephonyProvider> ril =
|
return true;
|
||||||
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(ril, NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
nsRefPtr<Telephony> telephony = Telephony::Create(innerWindow, ril);
|
|
||||||
NS_ENSURE_TRUE(telephony, NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
telephony.forget(aTelephony);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
#define mozilla_dom_telephony_telephony_h__
|
#define mozilla_dom_telephony_telephony_h__
|
||||||
|
|
||||||
#include "TelephonyCommon.h"
|
#include "TelephonyCommon.h"
|
||||||
|
// Need to include TelephonyCall.h because we have inline methods that
|
||||||
|
// assume they see the definition of TelephonyCall.
|
||||||
|
#include "TelephonyCall.h"
|
||||||
|
|
||||||
#include "nsIDOMTelephony.h"
|
#include "nsIDOMTelephony.h"
|
||||||
#include "nsIDOMTelephonyCall.h"
|
#include "nsIDOMTelephonyCall.h"
|
||||||
@@ -56,7 +59,9 @@ public:
|
|||||||
nsDOMEventTargetHelper)
|
nsDOMEventTargetHelper)
|
||||||
|
|
||||||
static already_AddRefed<Telephony>
|
static already_AddRefed<Telephony>
|
||||||
Create(nsPIDOMWindow* aOwner, nsITelephonyProvider* aProvider);
|
Create(nsPIDOMWindow* aOwner, ErrorResult& aRv);
|
||||||
|
|
||||||
|
static bool CheckPermission(nsPIDOMWindow* aOwner);
|
||||||
|
|
||||||
nsISupports*
|
nsISupports*
|
||||||
ToISupports()
|
ToISupports()
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
|
||||||
/* vim: set ts=2 et sw=2 tw=40: */
|
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_dom_telephony_telephonyfactory_h__
|
|
||||||
#define mozilla_dom_telephony_telephonyfactory_h__
|
|
||||||
|
|
||||||
#include "nsIDOMTelephony.h"
|
|
||||||
#include "nsPIDOMWindow.h"
|
|
||||||
|
|
||||||
// Implemented in Telephony.cpp.
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_NewTelephony(nsPIDOMWindow* aWindow, nsIDOMTelephony** aTelephony);
|
|
||||||
|
|
||||||
#endif // mozilla_dom_telephony_telephonyfactory_h__
|
|
||||||
@@ -8,10 +8,19 @@ const KEY = "ril.radio.disabled";
|
|||||||
SpecialPowers.addPermission("telephony", true, document);
|
SpecialPowers.addPermission("telephony", true, document);
|
||||||
SpecialPowers.addPermission("settings-write", true, document);
|
SpecialPowers.addPermission("settings-write", true, document);
|
||||||
|
|
||||||
let settings = window.navigator.mozSettings;
|
// Permission changes can't change existing Navigator.prototype
|
||||||
let telephony = window.navigator.mozTelephony;
|
// objects, so grab our objects from a new Navigator
|
||||||
|
let ifr = document.createElement("iframe");
|
||||||
|
let settings;
|
||||||
|
let telephony;
|
||||||
let number = "112";
|
let number = "112";
|
||||||
let outgoing;
|
let outgoing;
|
||||||
|
ifr.onload = function() {
|
||||||
|
settings = ifr.contentWindow.navigator.mozSettings;
|
||||||
|
telephony = ifr.contentWindow.navigator.mozTelephony;
|
||||||
|
getExistingCalls();
|
||||||
|
};
|
||||||
|
document.body.appendChild(ifr);
|
||||||
|
|
||||||
function getExistingCalls() {
|
function getExistingCalls() {
|
||||||
runEmulatorCmd("gsm list", function(result) {
|
runEmulatorCmd("gsm list", function(result) {
|
||||||
@@ -155,5 +164,3 @@ function cleanUp() {
|
|||||||
SpecialPowers.removePermission("settings-write", document);
|
SpecialPowers.removePermission("settings-write", document);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
getExistingCalls();
|
|
||||||
|
|||||||
@@ -17,23 +17,28 @@ var idleObserver = {
|
|||||||
onactive: null
|
onactive: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function doAddIdleObserver(obs) {
|
||||||
|
var i = document.createElement("iframe");
|
||||||
|
document.body.appendChild(i);
|
||||||
|
var added = false;
|
||||||
|
try {
|
||||||
|
i.contentWindow.navigator.addIdleObserver(obs);
|
||||||
|
added = true;
|
||||||
|
} catch (e) { }
|
||||||
|
i.remove();
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
function run_test() {
|
function run_test() {
|
||||||
// addIdleObserver checks whether time is > 0.
|
// addIdleObserver checks whether time is > 0.
|
||||||
this.idleObserver.time = 100;
|
this.idleObserver.time = 100;
|
||||||
|
|
||||||
var added = false;
|
var added = doAddIdleObserver(this.idleObserver, false);
|
||||||
try {
|
|
||||||
navigator.addIdleObserver(this.idleObserver);
|
|
||||||
added = true;
|
|
||||||
} catch (e) { }
|
|
||||||
ok(!added, "Should not be able to add idle observer without permission");
|
ok(!added, "Should not be able to add idle observer without permission");
|
||||||
|
|
||||||
SpecialPowers.addPermission("idle", true, document);
|
SpecialPowers.addPermission("idle", true, document);
|
||||||
added = false;
|
|
||||||
try {
|
added = doAddIdleObserver(this.idleObserver, true);
|
||||||
navigator.addIdleObserver(this.idleObserver);
|
|
||||||
added = true;
|
|
||||||
} catch (e) { }
|
|
||||||
ok(added, "Should be able to add idle observer with permission.");
|
ok(added, "Should be able to add idle observer with permission.");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ function expectSuccess(param) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testFailures() {
|
function testFailures() {
|
||||||
expectFailure(null);
|
expectSuccess(null);
|
||||||
expectFailure(undefined);
|
expectSuccess(undefined);
|
||||||
expectFailure(-1);
|
expectFailure(-1);
|
||||||
expectFailure('a');
|
expectSuccess('a');
|
||||||
expectFailure([100, -1]);
|
expectFailure([100, -1]);
|
||||||
expectFailure([100, 'a']);
|
expectSuccess([100, 'a']);
|
||||||
|
|
||||||
var maxVibrateMs = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_ms');
|
var maxVibrateMs = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_ms');
|
||||||
var maxVibrateListLen = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_list_len');
|
var maxVibrateListLen = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_list_len');
|
||||||
|
|||||||
353
dom/webidl/Navigator.webidl
Normal file
353
dom/webidl/Navigator.webidl
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
||||||
|
* http://www.w3.org/TR/tracking-dnt/
|
||||||
|
* http://www.w3.org/TR/geolocation-API/#geolocation_interface
|
||||||
|
* http://www.w3.org/TR/battery-status/#navigatorbattery-interface
|
||||||
|
* http://www.w3.org/TR/vibration/#vibration-interface
|
||||||
|
* http://www.w3.org/2012/sysapps/runtime/#extension-to-the-navigator-interface-1
|
||||||
|
* https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#navigator-interface-extension
|
||||||
|
*
|
||||||
|
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
|
||||||
|
* Opera Software ASA. You are granted a license to use, reproduce
|
||||||
|
* and create derivative works of this document.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface MozPowerManager;
|
||||||
|
interface MozWakeLock;
|
||||||
|
|
||||||
|
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
||||||
|
[HeaderFile="Navigator.h", NeedNewResolve]
|
||||||
|
interface Navigator {
|
||||||
|
// objects implementing this interface also implement the interfaces given below
|
||||||
|
};
|
||||||
|
Navigator implements NavigatorID;
|
||||||
|
Navigator implements NavigatorLanguage;
|
||||||
|
Navigator implements NavigatorOnLine;
|
||||||
|
Navigator implements NavigatorContentUtils;
|
||||||
|
Navigator implements NavigatorStorageUtils;
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorID {
|
||||||
|
readonly attribute DOMString appName;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString appVersion;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString platform;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString userAgent;
|
||||||
|
|
||||||
|
// Spec has this as a const, but that's wrong because it should not
|
||||||
|
// be on the interface object.
|
||||||
|
//const DOMString product = "Gecko"; // for historical reasons
|
||||||
|
readonly attribute DOMString product;
|
||||||
|
};
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorLanguage {
|
||||||
|
readonly attribute DOMString? language;
|
||||||
|
};
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorOnLine {
|
||||||
|
readonly attribute boolean onLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorContentUtils {
|
||||||
|
// content handler registration
|
||||||
|
[Throws]
|
||||||
|
void registerProtocolHandler(DOMString scheme, DOMString url, DOMString title);
|
||||||
|
[Throws]
|
||||||
|
void registerContentHandler(DOMString mimeType, DOMString url, DOMString title);
|
||||||
|
// NOT IMPLEMENTED
|
||||||
|
//DOMString isProtocolHandlerRegistered(DOMString scheme, DOMString url);
|
||||||
|
//DOMString isContentHandlerRegistered(DOMString mimeType, DOMString url);
|
||||||
|
//void unregisterProtocolHandler(DOMString scheme, DOMString url);
|
||||||
|
//void unregisterContentHandler(DOMString mimeType, DOMString url);
|
||||||
|
};
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorStorageUtils {
|
||||||
|
// NOT IMPLEMENTED
|
||||||
|
//void yieldForStorageUpdates();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Things that definitely need to be in the spec and and are not for some
|
||||||
|
// reason. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=22406
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws]
|
||||||
|
readonly attribute MimeTypeArray mimeTypes;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute PluginArray plugins;
|
||||||
|
};
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/tracking-dnt/ sort of
|
||||||
|
partial interface Navigator {
|
||||||
|
readonly attribute DOMString doNotTrack;
|
||||||
|
};
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/geolocation-API/#geolocation_interface
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorGeolocation {
|
||||||
|
// XXXbz This should perhaps be controleld by the "geo.enabled" pref, instead
|
||||||
|
// of checking it in the C++. Let's not for now to reduce risk.
|
||||||
|
// Also, we violate the spec as a result, since we can return null. See bug
|
||||||
|
// 884921.
|
||||||
|
[Throws]
|
||||||
|
readonly attribute Geolocation? geolocation;
|
||||||
|
};
|
||||||
|
Navigator implements NavigatorGeolocation;
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/battery-status/#navigatorbattery-interface
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface NavigatorBattery {
|
||||||
|
// XXXbz Per spec this should be non-nullable, but we return null in
|
||||||
|
// torn-down windows. See bug 884925.
|
||||||
|
[Throws, Func="Navigator::HasBatterySupport"]
|
||||||
|
readonly attribute BatteryManager? battery;
|
||||||
|
};
|
||||||
|
Navigator implements NavigatorBattery;
|
||||||
|
|
||||||
|
// http://www.w3.org/TR/vibration/#vibration-interface
|
||||||
|
partial interface Navigator {
|
||||||
|
// We don't support sequences in unions yet
|
||||||
|
//boolean vibrate ((unsigned long or sequence<unsigned long>) pattern);
|
||||||
|
// XXXbz also, per spec we should be returning a boolean, and we just don't.
|
||||||
|
// See bug 884935.
|
||||||
|
[Throws]
|
||||||
|
void vibrate(unsigned long duration);
|
||||||
|
[Throws]
|
||||||
|
void vibrate(sequence<unsigned long> pattern);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mozilla-specific extensions
|
||||||
|
|
||||||
|
callback interface MozIdleObserver {
|
||||||
|
// Time is in seconds and is read only when idle observers are added
|
||||||
|
// and removed.
|
||||||
|
readonly attribute unsigned long time;
|
||||||
|
void onidle();
|
||||||
|
void onactive();
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMNavigator
|
||||||
|
partial interface Navigator {
|
||||||
|
// WebKit/Blink/Trident/Presto support this (hardcoded "Mozilla").
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString appCodeName;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString oscpu;
|
||||||
|
// WebKit/Blink support this; Trident/Presto do not.
|
||||||
|
readonly attribute DOMString vendor;
|
||||||
|
// WebKit/Blink supports this (hardcoded ""); Trident/Presto do not.
|
||||||
|
readonly attribute DOMString vendorSub;
|
||||||
|
// WebKit/Blink supports this (hardcoded "20030107"); Trident/Presto don't
|
||||||
|
readonly attribute DOMString productSub;
|
||||||
|
// WebKit/Blink/Trident/Presto support this.
|
||||||
|
readonly attribute boolean cookieEnabled;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute DOMString buildID;
|
||||||
|
[Throws, Func="Navigator::HasPowerSupport"]
|
||||||
|
readonly attribute MozPowerManager mozPower;
|
||||||
|
|
||||||
|
// WebKit/Blink/Trident/Presto support this.
|
||||||
|
[Throws]
|
||||||
|
boolean javaEnabled();
|
||||||
|
// Everyone but WebKit/Blink supports this. See bug 679971.
|
||||||
|
boolean taintEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigator requests to add an idle observer to the existing window.
|
||||||
|
*/
|
||||||
|
[Throws, Func="Navigator::HasIdleSupport"]
|
||||||
|
void addIdleObserver(MozIdleObserver aIdleObserver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigator requests to remove an idle observer from the existing window.
|
||||||
|
*/
|
||||||
|
[Throws, Func="Navigator::HasIdleSupport"]
|
||||||
|
void removeIdleObserver(MozIdleObserver aIdleObserver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a wake lock for a resource.
|
||||||
|
*
|
||||||
|
* A page holds a wake lock to request that a resource not be turned
|
||||||
|
* off (or otherwise made unavailable).
|
||||||
|
*
|
||||||
|
* The topic is the name of a resource that might be made unavailable for
|
||||||
|
* various reasons. For example, on a mobile device the power manager might
|
||||||
|
* decide to turn off the screen after a period of idle time to save power.
|
||||||
|
*
|
||||||
|
* The resource manager checks the lock state of a topic before turning off
|
||||||
|
* the associated resource. For example, a page could hold a lock on the
|
||||||
|
* "screen" topic to prevent the screensaver from appearing or the screen
|
||||||
|
* from turning off.
|
||||||
|
*
|
||||||
|
* The resource manager defines what each topic means and sets policy. For
|
||||||
|
* example, the resource manager might decide to ignore 'screen' wake locks
|
||||||
|
* held by pages which are not visible.
|
||||||
|
*
|
||||||
|
* One topic can be locked multiple times; it is considered released only when
|
||||||
|
* all locks on the topic have been released.
|
||||||
|
*
|
||||||
|
* The returned nsIDOMMozWakeLock object is a token of the lock. You can
|
||||||
|
* unlock the lock via the object's |unlock| method. The lock is released
|
||||||
|
* automatically when its associated window is unloaded.
|
||||||
|
*
|
||||||
|
* @param aTopic resource name
|
||||||
|
*/
|
||||||
|
[Throws, Func="Navigator::HasWakeLockSupport"]
|
||||||
|
MozWakeLock requestWakeLock(DOMString aTopic);
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMNavigatorDeviceStorage
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Pref="device.storage.enabled"]
|
||||||
|
DeviceStorage? getDeviceStorage(DOMString type);
|
||||||
|
[Throws, Pref="device.storage.enabled"]
|
||||||
|
sequence<DeviceStorage> getDeviceStorages(DOMString type);
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMNavigatorDesktopNotification
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasDesktopNotificationSupport"]
|
||||||
|
readonly attribute DesktopNotificationCenter mozNotification;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMClientInformation
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws]
|
||||||
|
boolean mozIsLocallyAvailable(DOMString uri, boolean whenOffline);
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMMozNavigatorSms
|
||||||
|
interface MozSmsManager;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Func="Navigator::HasSmsSupport"]
|
||||||
|
readonly attribute MozSmsManager? mozSms;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMMozNavigatorMobileMessage
|
||||||
|
interface MozMobileMessageManager;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Func="Navigator::HasMobileMessageSupport"]
|
||||||
|
readonly attribute MozMobileMessageManager? mozMobileMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMMozNavigatorNetwork
|
||||||
|
interface MozConnection;
|
||||||
|
partial interface Navigator {
|
||||||
|
readonly attribute MozConnection? mozConnection;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMNavigatorCamera
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasCameraSupport"]
|
||||||
|
readonly attribute CameraManager mozCameras;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIDOMNavigatorSystemMessages and sort of maybe
|
||||||
|
// http://www.w3.org/2012/sysapps/runtime/#extension-to-the-navigator-interface-1
|
||||||
|
callback systemMessageCallback = void (optional object message);
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Pref="dom.sysmsg.enabled"]
|
||||||
|
void mozSetMessageHandler (DOMString type, systemMessageCallback? callback);
|
||||||
|
[Throws, Pref="dom.sysmsg.enabled"]
|
||||||
|
boolean mozHasPendingMessage (DOMString type);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MOZ_B2G_RIL
|
||||||
|
interface MozTelephony;
|
||||||
|
// nsIDOMNavigatorTelephony
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasTelephonySupport"]
|
||||||
|
readonly attribute MozTelephony? mozTelephony;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIMozNavigatorMobileConnection
|
||||||
|
interface MozMobileConnection;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasMobileConnectionSupport"]
|
||||||
|
readonly attribute MozMobileConnection mozMobileConnection;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIMozNavigatorCellBroadcast
|
||||||
|
interface MozCellBroadcast;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasCellBroadcastSupport"]
|
||||||
|
readonly attribute MozCellBroadcast mozCellBroadcast;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIMozNavigatorVoicemail
|
||||||
|
interface MozVoicemail;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasVoicemailSupport"]
|
||||||
|
readonly attribute MozVoicemail mozVoicemail;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsIMozNavigatorIccManager
|
||||||
|
interface MozIccManager;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasIccManagerSupport"]
|
||||||
|
readonly attribute MozIccManager? mozIccManager;
|
||||||
|
};
|
||||||
|
#endif // MOZ_B2G_RIL
|
||||||
|
|
||||||
|
#ifdef MOZ_GAMEPAD
|
||||||
|
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#navigator-interface-extension
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Pref="dom.gamepad.enabled"]
|
||||||
|
sequence<Gamepad?> getGamepads();
|
||||||
|
};
|
||||||
|
#endif // MOZ_GAMEPAD
|
||||||
|
|
||||||
|
#ifdef MOZ_B2G_BT
|
||||||
|
// nsIDOMNavigatorBluetooth
|
||||||
|
interface MozBluetoothManager;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasBluetoothSupport"]
|
||||||
|
readonly attribute MozBluetoothManager mozBluetooth;
|
||||||
|
};
|
||||||
|
#endif // MOZ_B2G_BT
|
||||||
|
|
||||||
|
#ifdef MOZ_TIME_MANAGER
|
||||||
|
// nsIDOMMozNavigatorTime
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasTimeSupport"]
|
||||||
|
readonly attribute MozTimeManager mozTime;
|
||||||
|
};
|
||||||
|
#endif // MOZ_TIME_MANAGER
|
||||||
|
|
||||||
|
#ifdef MOZ_AUDIO_CHANNEL_MANAGER
|
||||||
|
// nsIMozNavigatorAudioChannelManager
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws]
|
||||||
|
readonly attribute AudioChannelManager mozAudioChannelManager;
|
||||||
|
};
|
||||||
|
#endif // MOZ_AUDIO_CHANNEL_MANAGER
|
||||||
|
|
||||||
|
#ifdef MOZ_MEDIA_NAVIGATOR
|
||||||
|
// nsIDOMNavigatorUserMedia
|
||||||
|
callback MozDOMGetUserMediaSuccessCallback = void (nsISupports? value);
|
||||||
|
callback MozDOMGetUserMediaErrorCallback = void (DOMString error);
|
||||||
|
interface MozMediaStreamOptions;
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, Func="Navigator::HasUserMediaSupport"]
|
||||||
|
void mozGetUserMedia(MozMediaStreamOptions? params,
|
||||||
|
MozDOMGetUserMediaSuccessCallback? onsuccess,
|
||||||
|
MozDOMGetUserMediaErrorCallback? onerror);
|
||||||
|
};
|
||||||
|
|
||||||
|
// nsINavigatorUserMedia
|
||||||
|
callback MozGetUserMediaDevicesSuccessCallback = void (nsIVariant? devices);
|
||||||
|
partial interface Navigator {
|
||||||
|
[Throws, ChromeOnly]
|
||||||
|
void mozGetUserMediaDevices(MozGetUserMediaDevicesSuccessCallback? onsuccess,
|
||||||
|
MozDOMGetUserMediaErrorCallback? onerror);
|
||||||
|
};
|
||||||
|
#endif // MOZ_MEDIA_NAVIGATOR
|
||||||
39
dom/webidl/SettingsManager.webidl
Normal file
39
dom/webidl/SettingsManager.webidl
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[JSImplementation="@mozilla.org/settingsLock;1",
|
||||||
|
Pref="dom.mozSettings.enabled"]
|
||||||
|
interface SettingsLock {
|
||||||
|
// Whether this lock is invalid
|
||||||
|
readonly attribute boolean closed;
|
||||||
|
|
||||||
|
// Contains a JSON object with name/value pairs to be set.
|
||||||
|
DOMRequest set(object settings);
|
||||||
|
|
||||||
|
// Result contains the value of the setting.
|
||||||
|
DOMRequest get(DOMString name);
|
||||||
|
|
||||||
|
DOMRequest clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary SettingChange {
|
||||||
|
DOMString settingName;
|
||||||
|
DOMString settingValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
callback SettingChangeCallback = void (SettingChange setting);
|
||||||
|
|
||||||
|
[JSImplementation="@mozilla.org/settingsManager;1",
|
||||||
|
NavigatorProperty="mozSettings",
|
||||||
|
Pref="dom.mozSettings.enabled"]
|
||||||
|
interface SettingsManager : EventTarget {
|
||||||
|
SettingsLock createLock();
|
||||||
|
|
||||||
|
void addObserver(DOMString name, SettingChangeCallback callback);
|
||||||
|
void removeObserver(DOMString name, SettingChangeCallback callback);
|
||||||
|
|
||||||
|
attribute EventHandler onsettingchange;
|
||||||
|
};
|
||||||
@@ -8,6 +8,10 @@ generated_webidl_files = \
|
|||||||
CSS2Properties.webidl \
|
CSS2Properties.webidl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
preprocessed_webidl_files = \
|
||||||
|
Navigator.webidl \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
webidl_files = \
|
webidl_files = \
|
||||||
AnalyserNode.webidl \
|
AnalyserNode.webidl \
|
||||||
AnimationEvent.webidl \
|
AnimationEvent.webidl \
|
||||||
@@ -227,6 +231,7 @@ webidl_files = \
|
|||||||
Screen.webidl \
|
Screen.webidl \
|
||||||
ScriptProcessorNode.webidl \
|
ScriptProcessorNode.webidl \
|
||||||
ScrollAreaEvent.webidl \
|
ScrollAreaEvent.webidl \
|
||||||
|
SettingsManager.webidl \
|
||||||
SimpleGestureEvent.webidl \
|
SimpleGestureEvent.webidl \
|
||||||
SourceBuffer.webidl \
|
SourceBuffer.webidl \
|
||||||
SourceBufferList.webidl \
|
SourceBufferList.webidl \
|
||||||
|
|||||||
@@ -1158,8 +1158,8 @@ RuntimeService::RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!mNavigatorStringsLoaded) {
|
if (!mNavigatorStringsLoaded) {
|
||||||
if (NS_FAILED(NS_GetNavigatorAppName(mNavigatorStrings.mAppName)) ||
|
NS_GetNavigatorAppName(mNavigatorStrings.mAppName);
|
||||||
NS_FAILED(NS_GetNavigatorAppVersion(mNavigatorStrings.mAppVersion)) ||
|
if (NS_FAILED(NS_GetNavigatorAppVersion(mNavigatorStrings.mAppVersion)) ||
|
||||||
NS_FAILED(NS_GetNavigatorPlatform(mNavigatorStrings.mPlatform)) ||
|
NS_FAILED(NS_GetNavigatorPlatform(mNavigatorStrings.mPlatform)) ||
|
||||||
NS_FAILED(NS_GetNavigatorUserAgent(mNavigatorStrings.mUserAgent))) {
|
NS_FAILED(NS_GetNavigatorUserAgent(mNavigatorStrings.mUserAgent))) {
|
||||||
JS_ReportError(aCx, "Failed to load navigator strings!");
|
JS_ReportError(aCx, "Failed to load navigator strings!");
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ Tests of DOM Worker Navigator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
is(navigator[args.name], args.value, "Mismatched navigator string!");
|
is(navigator[args.name], args.value,
|
||||||
|
"Mismatched navigator string for " + args.name + "!");
|
||||||
};
|
};
|
||||||
|
|
||||||
worker.onerror = function(event) {
|
worker.onerror = function(event) {
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ VPATH += \
|
|||||||
|
|
||||||
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
|
||||||
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
|
OS_CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(CAIRO_FT_CFLAGS)
|
||||||
|
DEFINES += -DSK_FONTHOST_CAIRO_STANDALONE=0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||||
|
|||||||
@@ -222,8 +222,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
|||||||
'ashmem.cpp',
|
'ashmem.cpp',
|
||||||
'SkDebug_android.cpp',
|
'SkDebug_android.cpp',
|
||||||
'SkFontHost_cairo.cpp',
|
'SkFontHost_cairo.cpp',
|
||||||
|
'SkFontHost_linux.cpp',
|
||||||
'SkFontHost_FreeType_common.cpp',
|
'SkFontHost_FreeType_common.cpp',
|
||||||
|
'SkFontHost_FreeType.cpp',
|
||||||
'SkImageRef_ashmem.cpp',
|
'SkImageRef_ashmem.cpp',
|
||||||
|
'SkOSFile.cpp',
|
||||||
'SkTime_Unix.cpp',
|
'SkTime_Unix.cpp',
|
||||||
'SkThread_pthread.cpp',
|
'SkThread_pthread.cpp',
|
||||||
'SkThreadUtils_pthread.cpp',
|
'SkThreadUtils_pthread.cpp',
|
||||||
|
|||||||
@@ -20,6 +20,10 @@
|
|||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
#ifndef SK_FONTHOST_CAIRO_STANDALONE
|
||||||
|
#define SK_FONTHOST_CAIRO_STANDALONE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
static cairo_user_data_key_t kSkTypefaceKey;
|
static cairo_user_data_key_t kSkTypefaceKey;
|
||||||
|
|
||||||
class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
|
class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
|
||||||
@@ -138,6 +142,7 @@ SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypefac
|
|||||||
return typeface;
|
return typeface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SK_FONTHOST_CAIRO_STANDALONE
|
||||||
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
|
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
|
||||||
const char famillyName[],
|
const char famillyName[],
|
||||||
SkTypeface::Style style)
|
SkTypeface::Style style)
|
||||||
@@ -157,6 +162,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
|
|||||||
SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
|
SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -355,10 +361,12 @@ SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if SK_FONTHOST_CAIRO_STANDALONE
|
||||||
#include "SkFontMgr.h"
|
#include "SkFontMgr.h"
|
||||||
|
|
||||||
SkFontMgr* SkFontMgr::Factory() {
|
SkFontMgr* SkFontMgr::Factory() {
|
||||||
// todo
|
// todo
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,12 @@
|
|||||||
#include "SkTSearch.h"
|
#include "SkTSearch.h"
|
||||||
|
|
||||||
#ifndef SK_FONT_FILE_PREFIX
|
#ifndef SK_FONT_FILE_PREFIX
|
||||||
|
#ifdef SK_BUILD_FOR_ANDROID
|
||||||
|
#define SK_FONT_FILE_PREFIX "/fonts/"
|
||||||
|
#else
|
||||||
#define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/"
|
#define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/"
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifndef SK_FONT_FILE_DIR_SEPERATOR
|
#ifndef SK_FONT_FILE_DIR_SEPERATOR
|
||||||
#define SK_FONT_FILE_DIR_SEPERATOR "/"
|
#define SK_FONT_FILE_DIR_SEPERATOR "/"
|
||||||
#endif
|
#endif
|
||||||
@@ -419,7 +423,13 @@ static void load_system_fonts() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkString baseDirectory(SK_FONT_FILE_PREFIX);
|
SkString baseDirectory;
|
||||||
|
#ifdef SK_BUILD_FOR_ANDROID
|
||||||
|
baseDirectory.set(getenv("ANDROID_ROOT"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
baseDirectory.append(SK_FONT_FILE_PREFIX);
|
||||||
|
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
load_directory_fonts(baseDirectory, &count);
|
load_directory_fonts(baseDirectory, &count);
|
||||||
|
|
||||||
|
|||||||
@@ -205,8 +205,8 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
|||||||
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||||
parser.sct = sct;
|
parser.sct = sct;
|
||||||
|
|
||||||
GlobalSharedContext globalsc(cx, scopeChain,
|
Directives directives(options.strictOption);
|
||||||
options.strictOption, options.extraWarningsOption);
|
GlobalSharedContext globalsc(cx, scopeChain, directives, options.extraWarningsOption);
|
||||||
|
|
||||||
bool savedCallerFun =
|
bool savedCallerFun =
|
||||||
options.compileAndGo &&
|
options.compileAndGo &&
|
||||||
@@ -240,7 +240,8 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
|||||||
// reset when this occurs.
|
// reset when this occurs.
|
||||||
Maybe<ParseContext<FullParseHandler> > pc;
|
Maybe<ParseContext<FullParseHandler> > pc;
|
||||||
|
|
||||||
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, staticLevel, /* bodyid = */ 0);
|
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, (Directives *) NULL,
|
||||||
|
staticLevel, /* bodyid = */ 0);
|
||||||
if (!pc.ref().init())
|
if (!pc.ref().init())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -267,7 +268,8 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
|||||||
* wishes to decompile it while it's running.
|
* wishes to decompile it while it's running.
|
||||||
*/
|
*/
|
||||||
JSFunction *fun = evalCaller->functionOrCallerFunction();
|
JSFunction *fun = evalCaller->functionOrCallerFunction();
|
||||||
ObjectBox *funbox = parser.newFunctionBox(fun, pc.addr(), fun->strict());
|
Directives directives(/* strict = */ fun->strict());
|
||||||
|
ObjectBox *funbox = parser.newFunctionBox(fun, pc.addr(), directives);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return NULL;
|
return NULL;
|
||||||
bce.objectList.add(funbox);
|
bce.objectList.add(funbox);
|
||||||
@@ -305,7 +307,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
|||||||
|
|
||||||
pc.destroy();
|
pc.destroy();
|
||||||
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc,
|
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc,
|
||||||
staticLevel, /* bodyid = */ 0);
|
(Directives *) NULL, staticLevel, /* bodyid = */ 0);
|
||||||
if (!pc.ref().init())
|
if (!pc.ref().init())
|
||||||
return NULL;
|
return NULL;
|
||||||
JS_ASSERT(parser.pc == pc.addr());
|
JS_ASSERT(parser.pc == pc.addr());
|
||||||
@@ -462,16 +464,19 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
|||||||
|
|
||||||
fun->setArgCount(formals.length());
|
fun->setArgCount(formals.length());
|
||||||
|
|
||||||
// If the context is strict, immediately parse the body in strict
|
// Speculatively parse using the default directives implied by the context.
|
||||||
// mode. Otherwise, we parse it normally. If we see a "use strict"
|
// If a directive is encountered (e.g., "use strict") that changes how the
|
||||||
// directive, we backup and reparse it as strict.
|
// function should have been parsed, we backup and reparse with the new set
|
||||||
ParseNode *fn;
|
// of directives.
|
||||||
|
Directives directives(options.strictOption);
|
||||||
|
|
||||||
TokenStream::Position start(parser.keepAtoms);
|
TokenStream::Position start(parser.keepAtoms);
|
||||||
parser.tokenStream.tell(&start);
|
parser.tokenStream.tell(&start);
|
||||||
bool strict = options.strictOption;
|
|
||||||
bool becameStrict;
|
ParseNode *fn;
|
||||||
while (true) {
|
while (true) {
|
||||||
fn = parser.standaloneFunctionBody(fun, formals, strict, &becameStrict);
|
Directives newDirectives = directives;
|
||||||
|
fn = parser.standaloneFunctionBody(fun, formals, directives, &newDirectives);
|
||||||
if (fn)
|
if (fn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -481,10 +486,12 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
|||||||
// the parse.
|
// the parse.
|
||||||
parser.clearAbortedSyntaxParse();
|
parser.clearAbortedSyntaxParse();
|
||||||
} else {
|
} else {
|
||||||
// If the function became strict, reparse in strict mode.
|
if (parser.tokenStream.hadError() || directives == newDirectives)
|
||||||
if (strict || !becameStrict || parser.tokenStream.hadError())
|
|
||||||
return false;
|
return false;
|
||||||
strict = true;
|
|
||||||
|
// Assignment must be monotonic to prevent reparsing iloops
|
||||||
|
JS_ASSERT_IF(directives.strict(), newDirectives.strict());
|
||||||
|
directives = newDirectives;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.tokenStream.seek(start);
|
parser.tokenStream.seek(start);
|
||||||
|
|||||||
@@ -384,7 +384,8 @@ Parser<FullParseHandler>::cloneParseTree(ParseNode *opn)
|
|||||||
MOZ_ASSUME_UNREACHABLE("module nodes cannot be cloned");
|
MOZ_ASSUME_UNREACHABLE("module nodes cannot be cloned");
|
||||||
}
|
}
|
||||||
NULLCHECK(pn->pn_funbox =
|
NULLCHECK(pn->pn_funbox =
|
||||||
newFunctionBox(opn->pn_funbox->function(), pc, opn->pn_funbox->strict));
|
newFunctionBox(opn->pn_funbox->function(), pc,
|
||||||
|
Directives(/* strict = */ opn->pn_funbox->strict)));
|
||||||
NULLCHECK(pn->pn_body = cloneParseTree(opn->pn_body));
|
NULLCHECK(pn->pn_body = cloneParseTree(opn->pn_body));
|
||||||
pn->pn_cookie = opn->pn_cookie;
|
pn->pn_cookie = opn->pn_cookie;
|
||||||
pn->pn_dflags = opn->pn_dflags;
|
pn->pn_dflags = opn->pn_dflags;
|
||||||
|
|||||||
@@ -453,9 +453,10 @@ Parser<ParseHandler>::newObjectBox(JSObject *obj)
|
|||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||||
ParseContext<ParseHandler> *outerpc, bool strict, bool extraWarnings)
|
ParseContext<ParseHandler> *outerpc, Directives directives,
|
||||||
|
bool extraWarnings)
|
||||||
: ObjectBox(fun, traceListHead),
|
: ObjectBox(fun, traceListHead),
|
||||||
SharedContext(cx, strict, extraWarnings),
|
SharedContext(cx, directives, extraWarnings),
|
||||||
bindings(),
|
bindings(),
|
||||||
bufStart(0),
|
bufStart(0),
|
||||||
bufEnd(0),
|
bufEnd(0),
|
||||||
@@ -516,8 +517,8 @@ FunctionBox::FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunct
|
|||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
FunctionBox *
|
FunctionBox *
|
||||||
Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
|
Parser<ParseHandler>::newFunctionBox(JSFunction *fun, ParseContext<ParseHandler> *outerpc,
|
||||||
ParseContext<ParseHandler> *outerpc, bool strict)
|
Directives inheritedDirectives)
|
||||||
{
|
{
|
||||||
JS_ASSERT(fun && !IsPoisonedPtr(fun));
|
JS_ASSERT(fun && !IsPoisonedPtr(fun));
|
||||||
|
|
||||||
@@ -530,7 +531,7 @@ Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
|
|||||||
*/
|
*/
|
||||||
FunctionBox *funbox =
|
FunctionBox *funbox =
|
||||||
alloc.new_<FunctionBox>(context, traceListHead, fun, outerpc,
|
alloc.new_<FunctionBox>(context, traceListHead, fun, outerpc,
|
||||||
strict, options().extraWarningsOption);
|
inheritedDirectives, options().extraWarningsOption);
|
||||||
if (!funbox) {
|
if (!funbox) {
|
||||||
js_ReportOutOfMemory(context);
|
js_ReportOutOfMemory(context);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -544,7 +545,7 @@ Parser<ParseHandler>::newFunctionBox(JSFunction *fun,
|
|||||||
ModuleBox::ModuleBox(ExclusiveContext *cx, ObjectBox *traceListHead, Module *module,
|
ModuleBox::ModuleBox(ExclusiveContext *cx, ObjectBox *traceListHead, Module *module,
|
||||||
ParseContext<FullParseHandler> *pc, bool extraWarnings)
|
ParseContext<FullParseHandler> *pc, bool extraWarnings)
|
||||||
: ObjectBox(module, traceListHead),
|
: ObjectBox(module, traceListHead),
|
||||||
SharedContext(cx, true, extraWarnings)
|
SharedContext(cx, Directives(/* strict = */ true), extraWarnings)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,9 +603,11 @@ Parser<ParseHandler>::parse(JSObject *chain)
|
|||||||
* an object lock before it finishes generating bytecode into a script
|
* an object lock before it finishes generating bytecode into a script
|
||||||
* protected from the GC by a root or a stack frame reference.
|
* protected from the GC by a root or a stack frame reference.
|
||||||
*/
|
*/
|
||||||
GlobalSharedContext globalsc(context, chain,
|
Directives directives(options().strictOption);
|
||||||
options().strictOption, options().extraWarningsOption);
|
GlobalSharedContext globalsc(context, chain, directives, options().extraWarningsOption);
|
||||||
ParseContext<ParseHandler> globalpc(this, NULL, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
|
ParseContext<ParseHandler> globalpc(this, /* parent = */ NULL, &globalsc,
|
||||||
|
/* newDirectives = */ NULL, /* staticLevel = */ 0,
|
||||||
|
/* bodyid = */ 0);
|
||||||
if (!globalpc.init())
|
if (!globalpc.init())
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@@ -843,11 +846,9 @@ Parser<ParseHandler>::checkStrictBinding(PropertyName *name, Node pn)
|
|||||||
template <>
|
template <>
|
||||||
ParseNode *
|
ParseNode *
|
||||||
Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
|
Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
|
||||||
bool strict, bool *becameStrict)
|
Directives inheritedDirectives,
|
||||||
|
Directives *newDirectives)
|
||||||
{
|
{
|
||||||
if (becameStrict)
|
|
||||||
*becameStrict = false;
|
|
||||||
|
|
||||||
Node fn = handler.newFunctionDefinition();
|
Node fn = handler.newFunctionDefinition();
|
||||||
if (!fn)
|
if (!fn)
|
||||||
return null();
|
return null();
|
||||||
@@ -859,12 +860,13 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoN
|
|||||||
argsbody->makeEmpty();
|
argsbody->makeEmpty();
|
||||||
fn->pn_body = argsbody;
|
fn->pn_body = argsbody;
|
||||||
|
|
||||||
FunctionBox *funbox = newFunctionBox(fun, /* outerpc = */ NULL, strict);
|
FunctionBox *funbox = newFunctionBox(fun, /* outerpc = */ NULL, inheritedDirectives);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return null();
|
return null();
|
||||||
handler.setFunctionBox(fn, funbox);
|
handler.setFunctionBox(fn, funbox);
|
||||||
|
|
||||||
ParseContext<FullParseHandler> funpc(this, pc, funbox, /* staticLevel = */ 0, /* bodyid = */ 0);
|
ParseContext<FullParseHandler> funpc(this, pc, funbox, newDirectives,
|
||||||
|
/* staticLevel = */ 0, /* bodyid = */ 0);
|
||||||
if (!funpc.init())
|
if (!funpc.init())
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@@ -874,11 +876,8 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoN
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParseNode *pn = functionBody(Statement, StatementListBody);
|
ParseNode *pn = functionBody(Statement, StatementListBody);
|
||||||
if (!pn) {
|
if (!pn)
|
||||||
if (becameStrict && pc->funBecameStrict)
|
|
||||||
*becameStrict = true;
|
|
||||||
return null();
|
return null();
|
||||||
}
|
|
||||||
|
|
||||||
if (!tokenStream.matchToken(TOK_EOF)) {
|
if (!tokenStream.matchToken(TOK_EOF)) {
|
||||||
report(ParseError, false, null(), JSMSG_SYNTAX_ERROR);
|
report(ParseError, false, null(), JSMSG_SYNTAX_ERROR);
|
||||||
@@ -1798,7 +1797,7 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
|||||||
// so we can skip over them after accounting for their free variables.
|
// so we can skip over them after accounting for their free variables.
|
||||||
if (LazyScript *lazyOuter = handler.lazyOuterFunction()) {
|
if (LazyScript *lazyOuter = handler.lazyOuterFunction()) {
|
||||||
JSFunction *fun = handler.nextLazyInnerFunction();
|
JSFunction *fun = handler.nextLazyInnerFunction();
|
||||||
FunctionBox *funbox = newFunctionBox(fun, pc, /* strict = */ false);
|
FunctionBox *funbox = newFunctionBox(fun, pc, Directives(/* strict = */ false));
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
handler.setFunctionBox(pn, funbox);
|
handler.setFunctionBox(pn, funbox);
|
||||||
@@ -1933,27 +1932,29 @@ Parser<ParseHandler>::functionDef(HandlePropertyName funName, const TokenStream:
|
|||||||
if (!fun)
|
if (!fun)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
// If the outer scope is strict, immediately parse the function in strict
|
// Speculatively parse using the directives of the parent parsing context.
|
||||||
// mode. Otherwise, we parse it normally. If we see a "use strict"
|
// If a directive is encountered (e.g., "use strict") that changes how the
|
||||||
// directive, we backup and reparse it as strict.
|
// function should have been parsed, we backup and reparse with the new set
|
||||||
bool initiallyStrict = pc->sc->strict;
|
// of directives.
|
||||||
bool becameStrict;
|
Directives directives(pc);
|
||||||
if (!functionArgsAndBody(pn, fun, type, kind, initiallyStrict,
|
Directives newDirectives = directives;
|
||||||
&becameStrict))
|
|
||||||
{
|
while (true) {
|
||||||
if (initiallyStrict || !becameStrict || tokenStream.hadError())
|
if (functionArgsAndBody(pn, fun, type, kind, directives, &newDirectives))
|
||||||
|
break;
|
||||||
|
if (tokenStream.hadError() || directives == newDirectives)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
// Reparse the function in strict mode.
|
// Assignment must be monotonic to prevent reparsing iloops
|
||||||
|
JS_ASSERT_IF(directives.strict(), newDirectives.strict());
|
||||||
|
directives = newDirectives;
|
||||||
|
|
||||||
tokenStream.seek(start);
|
tokenStream.seek(start);
|
||||||
if (funName && tokenStream.getToken() == TOK_ERROR)
|
if (funName && tokenStream.getToken() == TOK_ERROR)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
// functionArgsAndBody may have already set pn->pn_body before failing.
|
// functionArgsAndBody may have already set pn->pn_body before failing.
|
||||||
handler.setFunctionBody(pn, null());
|
handler.setFunctionBody(pn, null());
|
||||||
|
|
||||||
if (!functionArgsAndBody(pn, fun, type, kind, true))
|
|
||||||
return null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pn;
|
return pn;
|
||||||
@@ -2054,14 +2055,13 @@ template <>
|
|||||||
bool
|
bool
|
||||||
Parser<FullParseHandler>::functionArgsAndBody(ParseNode *pn, HandleFunction fun,
|
Parser<FullParseHandler>::functionArgsAndBody(ParseNode *pn, HandleFunction fun,
|
||||||
FunctionType type, FunctionSyntaxKind kind,
|
FunctionType type, FunctionSyntaxKind kind,
|
||||||
bool strict, bool *becameStrict)
|
Directives inheritedDirectives,
|
||||||
|
Directives *newDirectives)
|
||||||
{
|
{
|
||||||
if (becameStrict)
|
|
||||||
*becameStrict = false;
|
|
||||||
ParseContext<FullParseHandler> *outerpc = pc;
|
ParseContext<FullParseHandler> *outerpc = pc;
|
||||||
|
|
||||||
// Create box for fun->object early to protect against last-ditch GC.
|
// Create box for fun->object early to protect against last-ditch GC.
|
||||||
FunctionBox *funbox = newFunctionBox(fun, pc, strict);
|
FunctionBox *funbox = newFunctionBox(fun, pc, inheritedDirectives);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -2077,13 +2077,13 @@ Parser<FullParseHandler>::functionArgsAndBody(ParseNode *pn, HandleFunction fun,
|
|||||||
tokenStream.tell(&position);
|
tokenStream.tell(&position);
|
||||||
parser->tokenStream.seek(position, tokenStream);
|
parser->tokenStream.seek(position, tokenStream);
|
||||||
|
|
||||||
ParseContext<SyntaxParseHandler> funpc(parser, outerpc, funbox,
|
ParseContext<SyntaxParseHandler> funpc(parser, outerpc, funbox, newDirectives,
|
||||||
outerpc->staticLevel + 1, outerpc->blockidGen);
|
outerpc->staticLevel + 1, outerpc->blockidGen);
|
||||||
if (!funpc.init())
|
if (!funpc.init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!parser->functionArgsAndBodyGeneric(SyntaxParseHandler::NodeGeneric,
|
if (!parser->functionArgsAndBodyGeneric(SyntaxParseHandler::NodeGeneric,
|
||||||
fun, type, kind, becameStrict))
|
fun, type, kind, newDirectives))
|
||||||
{
|
{
|
||||||
if (parser->hadAbortedSyntaxParse()) {
|
if (parser->hadAbortedSyntaxParse()) {
|
||||||
// Try again with a full parse.
|
// Try again with a full parse.
|
||||||
@@ -2111,12 +2111,12 @@ Parser<FullParseHandler>::functionArgsAndBody(ParseNode *pn, HandleFunction fun,
|
|||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
// Continue doing a full parse for this inner function.
|
// Continue doing a full parse for this inner function.
|
||||||
ParseContext<FullParseHandler> funpc(this, pc, funbox,
|
ParseContext<FullParseHandler> funpc(this, pc, funbox, newDirectives,
|
||||||
outerpc->staticLevel + 1, outerpc->blockidGen);
|
outerpc->staticLevel + 1, outerpc->blockidGen);
|
||||||
if (!funpc.init())
|
if (!funpc.init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!functionArgsAndBodyGeneric(pn, fun, type, kind, becameStrict))
|
if (!functionArgsAndBodyGeneric(pn, fun, type, kind, newDirectives))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!leaveFunction(pn, outerpc, kind))
|
if (!leaveFunction(pn, outerpc, kind))
|
||||||
@@ -2138,24 +2138,23 @@ template <>
|
|||||||
bool
|
bool
|
||||||
Parser<SyntaxParseHandler>::functionArgsAndBody(Node pn, HandleFunction fun,
|
Parser<SyntaxParseHandler>::functionArgsAndBody(Node pn, HandleFunction fun,
|
||||||
FunctionType type, FunctionSyntaxKind kind,
|
FunctionType type, FunctionSyntaxKind kind,
|
||||||
bool strict, bool *becameStrict)
|
Directives inheritedDirectives,
|
||||||
|
Directives *newDirectives)
|
||||||
{
|
{
|
||||||
if (becameStrict)
|
|
||||||
*becameStrict = false;
|
|
||||||
ParseContext<SyntaxParseHandler> *outerpc = pc;
|
ParseContext<SyntaxParseHandler> *outerpc = pc;
|
||||||
|
|
||||||
// Create box for fun->object early to protect against last-ditch GC.
|
// Create box for fun->object early to protect against last-ditch GC.
|
||||||
FunctionBox *funbox = newFunctionBox(fun, pc, strict);
|
FunctionBox *funbox = newFunctionBox(fun, pc, inheritedDirectives);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Initialize early for possible flags mutation via destructuringExpr.
|
// Initialize early for possible flags mutation via destructuringExpr.
|
||||||
ParseContext<SyntaxParseHandler> funpc(this, pc, funbox,
|
ParseContext<SyntaxParseHandler> funpc(this, pc, funbox, newDirectives,
|
||||||
outerpc->staticLevel + 1, outerpc->blockidGen);
|
outerpc->staticLevel + 1, outerpc->blockidGen);
|
||||||
if (!funpc.init())
|
if (!funpc.init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!functionArgsAndBodyGeneric(pn, fun, type, kind, becameStrict))
|
if (!functionArgsAndBodyGeneric(pn, fun, type, kind, newDirectives))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!leaveFunction(pn, outerpc, kind))
|
if (!leaveFunction(pn, outerpc, kind))
|
||||||
@@ -2177,17 +2176,23 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
|
|||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
FunctionBox *funbox = newFunctionBox(fun, /* outerpc = */ NULL, strict);
|
Directives directives(/* strict = */ strict);
|
||||||
|
FunctionBox *funbox = newFunctionBox(fun, /* outerpc = */ NULL, directives);
|
||||||
if (!funbox)
|
if (!funbox)
|
||||||
return null();
|
return null();
|
||||||
handler.setFunctionBox(pn, funbox);
|
handler.setFunctionBox(pn, funbox);
|
||||||
|
|
||||||
ParseContext<FullParseHandler> funpc(this, NULL, funbox, staticLevel, 0);
|
Directives newDirectives = directives;
|
||||||
|
ParseContext<FullParseHandler> funpc(this, /* parent = */ NULL, funbox,
|
||||||
|
&newDirectives, staticLevel, /* bodyid = */ 0);
|
||||||
if (!funpc.init())
|
if (!funpc.init())
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
if (!functionArgsAndBodyGeneric(pn, fun, Normal, Statement, NULL))
|
if (!functionArgsAndBodyGeneric(pn, fun, Normal, Statement, &newDirectives)) {
|
||||||
|
JS_ASSERT(directives == newDirectives);
|
||||||
return null();
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fun->isNamedLambda()) {
|
if (fun->isNamedLambda()) {
|
||||||
if (AtomDefnPtr p = pc->lexdeps->lookup(fun->name())) {
|
if (AtomDefnPtr p = pc->lexdeps->lookup(fun->name())) {
|
||||||
@@ -2208,7 +2213,8 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
|
|||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
bool
|
bool
|
||||||
Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
|
Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
|
||||||
FunctionSyntaxKind kind, bool *becameStrict)
|
FunctionSyntaxKind kind,
|
||||||
|
Directives *newDirectives)
|
||||||
{
|
{
|
||||||
// Given a properly initialized parse context, try to parse an actual
|
// Given a properly initialized parse context, try to parse an actual
|
||||||
// function without concern for conversion to strict mode, use of lazy
|
// function without concern for conversion to strict mode, use of lazy
|
||||||
@@ -2254,12 +2260,8 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun, Fu
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node body = functionBody(kind, bodyType);
|
Node body = functionBody(kind, bodyType);
|
||||||
if (!body) {
|
if (!body)
|
||||||
// Notify the caller if this function was discovered to be strict.
|
|
||||||
if (becameStrict && pc->funBecameStrict)
|
|
||||||
*becameStrict = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!yieldGuard.empty() && !yieldGuard.ref().checkValidBody(body, JSMSG_YIELD_IN_ARROW))
|
if (!yieldGuard.empty() && !yieldGuard.ref().checkValidBody(body, JSMSG_YIELD_IN_ARROW))
|
||||||
return false;
|
return false;
|
||||||
@@ -2312,7 +2314,8 @@ Parser<FullParseHandler>::moduleDecl()
|
|||||||
return NULL;
|
return NULL;
|
||||||
pn->pn_modulebox = modulebox;
|
pn->pn_modulebox = modulebox;
|
||||||
|
|
||||||
ParseContext<FullParseHandler> modulepc(this, pc, modulebox, pc->staticLevel + 1, pc->blockidGen);
|
ParseContext<FullParseHandler> modulepc(this, pc, modulebox, /* newDirectives = */ NULL,
|
||||||
|
pc->staticLevel + 1, pc->blockidGen);
|
||||||
if (!modulepc.init())
|
if (!modulepc.init())
|
||||||
return NULL;
|
return NULL;
|
||||||
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_MODULE);
|
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_MODULE);
|
||||||
@@ -2441,7 +2444,7 @@ Parser<ParseHandler>::maybeParseDirective(Node pn, bool *cont)
|
|||||||
if (!pc->sc->strict) {
|
if (!pc->sc->strict) {
|
||||||
if (pc->sc->isFunctionBox()) {
|
if (pc->sc->isFunctionBox()) {
|
||||||
// Request that this function be reparsed as strict.
|
// Request that this function be reparsed as strict.
|
||||||
pc->funBecameStrict = true;
|
pc->newDirectives->setStrict();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// We don't reparse global scopes, so we keep track of the
|
// We don't reparse global scopes, so we keep track of the
|
||||||
@@ -5984,11 +5987,12 @@ Parser<FullParseHandler>::generatorExpr(ParseNode *kid)
|
|||||||
return null();
|
return null();
|
||||||
|
|
||||||
/* Create box for fun->object early to protect against last-ditch GC. */
|
/* Create box for fun->object early to protect against last-ditch GC. */
|
||||||
FunctionBox *genFunbox = newFunctionBox(fun, outerpc, outerpc->sc->strict);
|
Directives directives(/* strict = */ outerpc->sc->strict);
|
||||||
|
FunctionBox *genFunbox = newFunctionBox(fun, outerpc, directives);
|
||||||
if (!genFunbox)
|
if (!genFunbox)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
ParseContext<FullParseHandler> genpc(this, outerpc, genFunbox,
|
ParseContext<FullParseHandler> genpc(this, outerpc, genFunbox, /* newDirectives = */ NULL,
|
||||||
outerpc->staticLevel + 1, outerpc->blockidGen);
|
outerpc->staticLevel + 1, outerpc->blockidGen);
|
||||||
if (!genpc.init())
|
if (!genpc.init())
|
||||||
return null();
|
return null();
|
||||||
|
|||||||
@@ -214,6 +214,13 @@ struct ParseContext : public GenericParseContext
|
|||||||
// All inner functions in this context. Only filled in when parsing syntax.
|
// All inner functions in this context. Only filled in when parsing syntax.
|
||||||
AutoFunctionVector innerFunctions;
|
AutoFunctionVector innerFunctions;
|
||||||
|
|
||||||
|
// In a function context, points to a Directive struct that can be updated
|
||||||
|
// to reflect new directives encountered in the Directive Prologue that
|
||||||
|
// require reparsing the function. In global/module/generator-tail contexts,
|
||||||
|
// we don't need to reparse when encountering a DirectivePrologue so this
|
||||||
|
// pointer may be NULL.
|
||||||
|
Directives *newDirectives;
|
||||||
|
|
||||||
// Set when parsing a declaration-like destructuring pattern. This flag
|
// Set when parsing a declaration-like destructuring pattern. This flag
|
||||||
// causes PrimaryExpr to create PN_NAME parse nodes for variable references
|
// causes PrimaryExpr to create PN_NAME parse nodes for variable references
|
||||||
// which are not hooked into any definition's use chain, added to any tree
|
// which are not hooked into any definition's use chain, added to any tree
|
||||||
@@ -225,12 +232,9 @@ struct ParseContext : public GenericParseContext
|
|||||||
// they need to be treated differently.
|
// they need to be treated differently.
|
||||||
bool inDeclDestructuring:1;
|
bool inDeclDestructuring:1;
|
||||||
|
|
||||||
// True if we are in a function, saw a "use strict" directive, and weren't
|
|
||||||
// strict before.
|
|
||||||
bool funBecameStrict:1;
|
|
||||||
|
|
||||||
ParseContext(Parser<ParseHandler> *prs, GenericParseContext *parent,
|
ParseContext(Parser<ParseHandler> *prs, GenericParseContext *parent,
|
||||||
SharedContext *sc, unsigned staticLevel, uint32_t bodyid)
|
SharedContext *sc, Directives *newDirectives,
|
||||||
|
unsigned staticLevel, uint32_t bodyid)
|
||||||
: GenericParseContext(parent, sc),
|
: GenericParseContext(parent, sc),
|
||||||
bodyid(0), // initialized in init()
|
bodyid(0), // initialized in init()
|
||||||
blockidGen(bodyid), // used to set |bodyid| and subsequently incremented in init()
|
blockidGen(bodyid), // used to set |bodyid| and subsequently incremented in init()
|
||||||
@@ -250,8 +254,8 @@ struct ParseContext : public GenericParseContext
|
|||||||
lexdeps(prs->context),
|
lexdeps(prs->context),
|
||||||
funcStmts(NULL),
|
funcStmts(NULL),
|
||||||
innerFunctions(prs->context),
|
innerFunctions(prs->context),
|
||||||
inDeclDestructuring(false),
|
newDirectives(newDirectives),
|
||||||
funBecameStrict(false)
|
inDeclDestructuring(false)
|
||||||
{
|
{
|
||||||
prs->pc = this;
|
prs->pc = this;
|
||||||
}
|
}
|
||||||
@@ -288,6 +292,12 @@ struct ParseContext : public GenericParseContext
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ParseHandler>
|
||||||
|
inline
|
||||||
|
Directives::Directives(ParseContext<ParseHandler> *parent)
|
||||||
|
: strict_(parent->sc->strict)
|
||||||
|
{}
|
||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
struct BindData;
|
struct BindData;
|
||||||
|
|
||||||
@@ -369,7 +379,8 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
|||||||
*/
|
*/
|
||||||
ObjectBox *newObjectBox(JSObject *obj);
|
ObjectBox *newObjectBox(JSObject *obj);
|
||||||
ModuleBox *newModuleBox(Module *module, ParseContext<ParseHandler> *pc);
|
ModuleBox *newModuleBox(Module *module, ParseContext<ParseHandler> *pc);
|
||||||
FunctionBox *newFunctionBox(JSFunction *fun, ParseContext<ParseHandler> *pc, bool strict);
|
FunctionBox *newFunctionBox(JSFunction *fun, ParseContext<ParseHandler> *pc,
|
||||||
|
Directives directives);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new function object given parse context (pc) and a name (which
|
* Create a new function object given parse context (pc) and a name (which
|
||||||
@@ -402,7 +413,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
|||||||
|
|
||||||
// Parse a function, given only its body. Used for the Function constructor.
|
// Parse a function, given only its body. Used for the Function constructor.
|
||||||
Node standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
|
Node standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
|
||||||
bool strict, bool *becameStrict);
|
Directives inheritedDirectives, Directives *newDirectives);
|
||||||
|
|
||||||
// Parse a function, given only its arguments and body. Used for lazily
|
// Parse a function, given only its arguments and body. Used for lazily
|
||||||
// parsed functions.
|
// parsed functions.
|
||||||
@@ -416,7 +427,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
|||||||
Node functionBody(FunctionSyntaxKind kind, FunctionBodyType type);
|
Node functionBody(FunctionSyntaxKind kind, FunctionBodyType type);
|
||||||
|
|
||||||
bool functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
|
bool functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
|
||||||
FunctionSyntaxKind kind, bool *becameStrict);
|
FunctionSyntaxKind kind, Directives *newDirectives);
|
||||||
|
|
||||||
virtual bool strictMode() { return pc->sc->strict; }
|
virtual bool strictMode() { return pc->sc->strict; }
|
||||||
|
|
||||||
@@ -487,7 +498,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
|||||||
FunctionType type, FunctionSyntaxKind kind);
|
FunctionType type, FunctionSyntaxKind kind);
|
||||||
bool functionArgsAndBody(Node pn, HandleFunction fun,
|
bool functionArgsAndBody(Node pn, HandleFunction fun,
|
||||||
FunctionType type, FunctionSyntaxKind kind,
|
FunctionType type, FunctionSyntaxKind kind,
|
||||||
bool strict, bool *becameStrict = NULL);
|
Directives inheritedDirectives, Directives *newDirectives);
|
||||||
|
|
||||||
Node unaryOpExpr(ParseNodeKind kind, JSOp op, uint32_t begin);
|
Node unaryOpExpr(ParseNodeKind kind, JSOp op, uint32_t begin);
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,30 @@ class FunctionContextFlags
|
|||||||
|
|
||||||
class GlobalSharedContext;
|
class GlobalSharedContext;
|
||||||
|
|
||||||
|
// List of directives that may be encountered in a Directive Prologue (ES5 15.1).
|
||||||
|
class Directives
|
||||||
|
{
|
||||||
|
bool strict_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Directives(bool strict) : strict_(strict) {}
|
||||||
|
template <typename ParseHandler> explicit Directives(ParseContext<ParseHandler> *parent);
|
||||||
|
|
||||||
|
void setStrict() { strict_ = true; }
|
||||||
|
bool strict() const { return strict_; }
|
||||||
|
|
||||||
|
Directives &operator=(Directives rhs) {
|
||||||
|
strict_ = rhs.strict_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool operator==(const Directives &rhs) const {
|
||||||
|
return strict_ == rhs.strict_;
|
||||||
|
}
|
||||||
|
bool operator!=(const Directives &rhs) const {
|
||||||
|
return strict_ != rhs.strict_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The struct SharedContext is part of the current parser context (see
|
* The struct SharedContext is part of the current parser context (see
|
||||||
* ParseContext). It stores information that is reused between the parser and
|
* ParseContext). It stores information that is reused between the parser and
|
||||||
@@ -156,10 +180,10 @@ class SharedContext
|
|||||||
|
|
||||||
// If it's function code, funbox must be non-NULL and scopeChain must be NULL.
|
// If it's function code, funbox must be non-NULL and scopeChain must be NULL.
|
||||||
// If it's global code, funbox must be NULL.
|
// If it's global code, funbox must be NULL.
|
||||||
SharedContext(ExclusiveContext *cx, bool strict, bool extraWarnings)
|
SharedContext(ExclusiveContext *cx, Directives directives, bool extraWarnings)
|
||||||
: context(cx),
|
: context(cx),
|
||||||
anyCxFlags(),
|
anyCxFlags(),
|
||||||
strict(strict),
|
strict(directives.strict()),
|
||||||
extraWarnings(extraWarnings)
|
extraWarnings(extraWarnings)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -192,8 +216,8 @@ class GlobalSharedContext : public SharedContext
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
GlobalSharedContext(ExclusiveContext *cx, JSObject *scopeChain,
|
GlobalSharedContext(ExclusiveContext *cx, JSObject *scopeChain,
|
||||||
bool strict, bool extraWarnings)
|
Directives directives, bool extraWarnings)
|
||||||
: SharedContext(cx, strict, extraWarnings),
|
: SharedContext(cx, directives, extraWarnings),
|
||||||
scopeChain_(cx, scopeChain)
|
scopeChain_(cx, scopeChain)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -249,8 +273,8 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
FunctionBox(ExclusiveContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||||
ParseContext<ParseHandler> *pc,
|
ParseContext<ParseHandler> *pc, Directives directives,
|
||||||
bool strict, bool extraWarnings);
|
bool extraWarnings);
|
||||||
|
|
||||||
ObjectBox *toObjectBox() { return this; }
|
ObjectBox *toObjectBox() { return this; }
|
||||||
JSFunction *function() const { return &object->as<JSFunction>(); }
|
JSFunction *function() const { return &object->as<JSFunction>(); }
|
||||||
|
|||||||
@@ -966,7 +966,14 @@ TypeScript::MonitorAssign(JSContext *cx, HandleObject obj, jsid id)
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
if (js_IdIsIndex(id, &i))
|
if (js_IdIsIndex(id, &i))
|
||||||
return;
|
return;
|
||||||
MarkTypeObjectUnknownProperties(cx, obj->type());
|
|
||||||
|
// But if we don't have too many properties yet, don't do anything. The
|
||||||
|
// idea here is that normal object initialization should not trigger
|
||||||
|
// deoptimization in most cases, while actual usage as a hashmap should.
|
||||||
|
TypeObject* type = obj->type();
|
||||||
|
if (type->getPropertyCount() < 8)
|
||||||
|
return;
|
||||||
|
MarkTypeObjectUnknownProperties(cx, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,13 +221,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=668855
|
|||||||
|
|
||||||
let dummy_test_map = new WeakMap;
|
let dummy_test_map = new WeakMap;
|
||||||
|
|
||||||
let navi_fail = false;
|
let rule_fail = false;
|
||||||
|
let got_rule = false;
|
||||||
try {
|
try {
|
||||||
dummy_test_map.set(window.navigator, 1);
|
var rule = document.styleSheets[0].cssRules[0];
|
||||||
|
got_rule = true;
|
||||||
|
dummy_test_map.set(rule, 1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
navi_fail = true;
|
rule_fail = true;
|
||||||
}
|
}
|
||||||
ok(navi_fail, "Using window.navigator as a weak map key should produce an exception because it can't be wrapper preserved.");
|
ok(got_rule, "Got the CSS rule");
|
||||||
|
ok(rule_fail, "Using a CSS rule as a weak map key should produce an exception because it can't be wrapper preserved.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<link rel="stylesheet" href="data:text/css,div {}">
|
||||||
<title>Test Cross-Compartment DOM WeakMaps</title>
|
<title>Test Cross-Compartment DOM WeakMaps</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ function setup() {
|
|||||||
|
|
||||||
my_map.set(item, "success_string");
|
my_map.set(item, "success_string");
|
||||||
|
|
||||||
var navi_fail = false;
|
var rule_fail = false;
|
||||||
try {
|
try {
|
||||||
my_map.set(window.frames[0].navigator, 1);
|
my_map.set(window.frames[0].document.styleSheets[0].cssRules[0], 1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
navi_fail = true;
|
rule_fail = true;
|
||||||
}
|
}
|
||||||
ok(navi_fail, "Using window.navigator as a weak map key across compartments should produce an exception because it can't be wrapper preserved.");
|
ok(rule_fail, "Using rule as a weak map key across compartments should produce an exception because it can't be wrapper preserved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function runTest() {
|
function runTest() {
|
||||||
|
|||||||
@@ -333,8 +333,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
|||||||
aBottomMarginResult.Zero();
|
aBottomMarginResult.Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
nscoord x = mX;
|
nsPoint position(mX, mY);
|
||||||
nscoord y = mY;
|
|
||||||
nscoord backupContainingBlockAdvance = 0;
|
nscoord backupContainingBlockAdvance = 0;
|
||||||
|
|
||||||
// Check whether the block's bottom margin collapses with its top
|
// Check whether the block's bottom margin collapses with its top
|
||||||
@@ -358,7 +357,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
|||||||
printf(": ");
|
printf(": ");
|
||||||
nsFrame::ListTag(stdout, mFrame);
|
nsFrame::ListTag(stdout, mFrame);
|
||||||
printf(" -- collapsing top & bottom margin together; y=%d spaceY=%d\n",
|
printf(" -- collapsing top & bottom margin together; y=%d spaceY=%d\n",
|
||||||
y, mSpace.y);
|
position.y, mSpace.y);
|
||||||
#endif
|
#endif
|
||||||
// Section 8.3.1 of CSS 2.1 says that blocks with adjoining
|
// Section 8.3.1 of CSS 2.1 says that blocks with adjoining
|
||||||
// top/bottom margins whose top margin collapses with their
|
// top/bottom margins whose top margin collapses with their
|
||||||
@@ -385,7 +384,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
|||||||
// even if there's some sort of integer overflow that makes y +
|
// even if there's some sort of integer overflow that makes y +
|
||||||
// mMetrics.height appear to go beyond the available height.
|
// mMetrics.height appear to go beyond the available height.
|
||||||
if (!empty && !aForceFit && mSpace.height != NS_UNCONSTRAINEDSIZE) {
|
if (!empty && !aForceFit && mSpace.height != NS_UNCONSTRAINEDSIZE) {
|
||||||
nscoord yMost = y - backupContainingBlockAdvance + mMetrics.height;
|
nscoord yMost = position.y - backupContainingBlockAdvance + mMetrics.height;
|
||||||
if (yMost > mSpace.YMost()) {
|
if (yMost > mSpace.YMost()) {
|
||||||
// didn't fit, we must acquit.
|
// didn't fit, we must acquit.
|
||||||
mFrame->DidReflow(mPresContext, &aReflowState, nsDidReflowStatus::FINISHED);
|
mFrame->DidReflow(mPresContext, &aReflowState, nsDidReflowStatus::FINISHED);
|
||||||
@@ -393,20 +392,16 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aInFlowBounds = nsRect(x, y - backupContainingBlockAdvance,
|
aInFlowBounds = nsRect(position.x, position.y - backupContainingBlockAdvance,
|
||||||
mMetrics.width, mMetrics.height);
|
mMetrics.width, mMetrics.height);
|
||||||
|
|
||||||
// Apply CSS relative positioning
|
aReflowState.ApplyRelativePositioning(&position);
|
||||||
const nsStyleDisplay* styleDisp = mFrame->StyleDisplay();
|
|
||||||
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
|
|
||||||
x += aReflowState.mComputedOffsets.left;
|
|
||||||
y += aReflowState.mComputedOffsets.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now place the frame and complete the reflow process
|
// Now place the frame and complete the reflow process
|
||||||
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, &aReflowState, mMetrics, x, y, 0);
|
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, &aReflowState,
|
||||||
|
mMetrics, position.x, position.y, 0);
|
||||||
|
|
||||||
aOverflowAreas = mMetrics.mOverflowAreas + nsPoint(x, y);
|
aOverflowAreas = mMetrics.mOverflowAreas + position;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -476,12 +476,8 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
nsPoint kidPt(kidReflowState.mComputedMargin.left,
|
nsPoint kidPt(kidReflowState.mComputedMargin.left,
|
||||||
kidReflowState.mComputedMargin.top);
|
kidReflowState.mComputedMargin.top);
|
||||||
// Apply CSS relative positioning
|
|
||||||
const nsStyleDisplay* styleDisp = kidFrame->StyleDisplay();
|
kidReflowState.ApplyRelativePositioning(&kidPt);
|
||||||
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
|
|
||||||
kidPt += nsPoint(kidReflowState.mComputedOffsets.left,
|
|
||||||
kidReflowState.mComputedOffsets.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reflow the frame
|
// Reflow the frame
|
||||||
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
||||||
|
|||||||
@@ -2400,12 +2400,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||||||
"We gave flex item unconstrained available height, so it "
|
"We gave flex item unconstrained available height, so it "
|
||||||
"should be complete");
|
"should be complete");
|
||||||
|
|
||||||
// Apply CSS relative positioning
|
childReflowState.ApplyRelativePositioning(&physicalPosn);
|
||||||
const nsStyleDisplay* styleDisp = curItem.Frame()->StyleDisplay();
|
|
||||||
if (NS_STYLE_POSITION_RELATIVE == styleDisp->mPosition) {
|
|
||||||
physicalPosn.x += childReflowState.mComputedOffsets.left;
|
|
||||||
physicalPosn.y += childReflowState.mComputedOffsets.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = FinishReflowChild(curItem.Frame(), aPresContext,
|
rv = FinishReflowChild(curItem.Frame(), aPresContext,
|
||||||
&childReflowState, childDesiredSize,
|
&childReflowState, childDesiredSize,
|
||||||
|
|||||||
@@ -2934,10 +2934,6 @@ void nsGfxScrollFrameInner::CurPosAttributeChanged(nsIContent* aContent)
|
|||||||
(mVScrollbarBox && mVScrollbarBox->GetContent() == aContent),
|
(mVScrollbarBox && mVScrollbarBox->GetContent() == aContent),
|
||||||
"unexpected child");
|
"unexpected child");
|
||||||
|
|
||||||
if (mScrollbarActivity) {
|
|
||||||
mScrollbarActivity->ActivityOccurred();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attribute changes on the scrollbars happen in one of three ways:
|
// Attribute changes on the scrollbars happen in one of three ways:
|
||||||
// 1) The scrollbar changed the attribute in response to some user event
|
// 1) The scrollbar changed the attribute in response to some user event
|
||||||
// 2) We changed the attribute in response to a ScrollPositionDidChange
|
// 2) We changed the attribute in response to a ScrollPositionDidChange
|
||||||
@@ -2970,6 +2966,10 @@ void nsGfxScrollFrameInner::CurPosAttributeChanged(nsIContent* aContent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mScrollbarActivity) {
|
||||||
|
mScrollbarActivity->ActivityOccurred();
|
||||||
|
}
|
||||||
|
|
||||||
bool isSmooth = aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::smooth);
|
bool isSmooth = aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::smooth);
|
||||||
if (isSmooth) {
|
if (isSmooth) {
|
||||||
// Make sure an attribute-setting callback occurs even if the view
|
// Make sure an attribute-setting callback occurs even if the view
|
||||||
|
|||||||
@@ -838,6 +838,16 @@ nsHTMLReflowState::ComputeRelativeOffsets(uint8_t aCBDirection,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsHTMLReflowState::ApplyRelativePositioning(const nsStyleDisplay* aDisplay,
|
||||||
|
const nsMargin &aComputedOffsets,
|
||||||
|
nsPoint* aPosition)
|
||||||
|
{
|
||||||
|
if (NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition) {
|
||||||
|
*aPosition += nsPoint(aComputedOffsets.left, aComputedOffsets.top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsIFrame*
|
nsIFrame*
|
||||||
nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
|
nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
|
||||||
nscoord& aCBLeftEdge,
|
nscoord& aCBLeftEdge,
|
||||||
|
|||||||
@@ -533,6 +533,15 @@ public:
|
|||||||
nscoord aContainingBlockHeight,
|
nscoord aContainingBlockHeight,
|
||||||
nsMargin& aComputedOffsets);
|
nsMargin& aComputedOffsets);
|
||||||
|
|
||||||
|
// If a relatively positioned element, adjust the position appropriately.
|
||||||
|
static void ApplyRelativePositioning(const nsStyleDisplay* aDisplay,
|
||||||
|
const nsMargin& aComputedOffsets,
|
||||||
|
nsPoint* aPosition);
|
||||||
|
|
||||||
|
void ApplyRelativePositioning(nsPoint* aPosition) const {
|
||||||
|
ApplyRelativePositioning(mStyleDisplay, mComputedOffsets, aPosition);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Reflow trace methods. Defined in nsFrame.cpp so they have access
|
// Reflow trace methods. Defined in nsFrame.cpp so they have access
|
||||||
// to the display-reflow infrastructure.
|
// to the display-reflow infrastructure.
|
||||||
|
|||||||
@@ -2628,8 +2628,9 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo
|
|||||||
if (pfd->GetFlag(PFD_RELATIVEPOS)) {
|
if (pfd->GetFlag(PFD_RELATIVEPOS)) {
|
||||||
// right and bottom are handled by
|
// right and bottom are handled by
|
||||||
// nsHTMLReflowState::ComputeRelativeOffsets
|
// nsHTMLReflowState::ComputeRelativeOffsets
|
||||||
nsPoint change(pfd->mOffsets.left, pfd->mOffsets.top);
|
nsHTMLReflowState::ApplyRelativePositioning(pfd->mFrame->StyleDisplay(),
|
||||||
origin += change;
|
pfd->mOffsets,
|
||||||
|
&origin);
|
||||||
frame->SetPosition(origin);
|
frame->SetPosition(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ LOCAL_INCLUDES += \
|
|||||||
-I$(srcdir)/../../content/xul/document/src \
|
-I$(srcdir)/../../content/xul/document/src \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
nsStyleStructList.h : $(srcdir)/generate-stylestructlist.py
|
||||||
|
$(PYTHON) $< > $@
|
||||||
|
|
||||||
_FILES = \
|
_FILES = \
|
||||||
contenteditable.css \
|
contenteditable.css \
|
||||||
designmode.css \
|
designmode.css \
|
||||||
@@ -42,7 +45,10 @@ _FILES = \
|
|||||||
TopLevelVideoDocument.css \
|
TopLevelVideoDocument.css \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
GARBAGE += $(addprefix $(DIST)/bin/res/,$(_FILES))
|
GARBAGE += \
|
||||||
|
$(addprefix $(DIST)/bin/res/,$(_FILES)) \
|
||||||
|
nsStyleStructList.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_FILES)
|
libs:: $(_FILES)
|
||||||
$(INSTALL) $^ $(DIST)/bin/res
|
$(INSTALL) $^ $(DIST)/bin/res
|
||||||
|
|||||||
169
layout/style/generate-stylestructlist.py
Normal file
169
layout/style/generate-stylestructlist.py
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
# This script generates nsStyleStructList.h, which contains macro invocations
|
||||||
|
# that can be used for three things:
|
||||||
|
#
|
||||||
|
# 1. To generate code for each inherited style struct.
|
||||||
|
# 2. To generate code for each reset style struct.
|
||||||
|
# 3. To generate a tree of nested if statements that can be used to run
|
||||||
|
# some code on each style struct.
|
||||||
|
#
|
||||||
|
# As an example, if we assume that we have only four style structs, the
|
||||||
|
# generated tree of nested if statements looks like this:
|
||||||
|
#
|
||||||
|
# if (STYLE_STRUCT_TEST < 4) {
|
||||||
|
# if (STYLE_STRUCT_TEST < 2) {
|
||||||
|
# if (STYLE_STRUCT_TEST == 0) {
|
||||||
|
# ... code for style struct with id 0 ...
|
||||||
|
# } else {
|
||||||
|
# ... code for style struct with id 1 ...
|
||||||
|
# }
|
||||||
|
# } else {
|
||||||
|
# if (STYLE_STRUCT_TEST == 2) {
|
||||||
|
# ... code for style struct with id 2 ...
|
||||||
|
# } else {
|
||||||
|
# ... code for style struct with id 3 ...
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# The TOPLEVELBRANCHES variable controls how widely we branch on the outermost
|
||||||
|
# if statement. In the example above, it splits the search space in 2, but with
|
||||||
|
# a larger number of style structs to test -- particularly when the number is
|
||||||
|
# closer to one power of two than the next higher one -- the average number of
|
||||||
|
# comparisons can be reduced by splitting the top level check into more than 2.
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
# List of style structs and their corresponding Check callback functions,
|
||||||
|
# if any.
|
||||||
|
STYLE_STRUCTS = [("INHERITED",) + x for x in [
|
||||||
|
# Inherited style structs.
|
||||||
|
("Font", "CheckFontCallback"),
|
||||||
|
("Color", "CheckColorCallback"),
|
||||||
|
("List", "nullptr"),
|
||||||
|
("Text", "CheckTextCallback"),
|
||||||
|
("Visibility", "nullptr"),
|
||||||
|
("Quotes", "nullptr"),
|
||||||
|
("UserInterface", "nullptr"),
|
||||||
|
("TableBorder", "nullptr"),
|
||||||
|
("SVG", "nullptr"),
|
||||||
|
]] + [("RESET",) + x for x in [
|
||||||
|
# Reset style structs.
|
||||||
|
("Background", "nullptr"),
|
||||||
|
("Position", "nullptr"),
|
||||||
|
("TextReset", "nullptr"),
|
||||||
|
("Display", "nullptr"),
|
||||||
|
("Content", "nullptr"),
|
||||||
|
("UIReset", "nullptr"),
|
||||||
|
("Table", "nullptr"),
|
||||||
|
("Margin", "nullptr"),
|
||||||
|
("Padding", "nullptr"),
|
||||||
|
("Border", "nullptr"),
|
||||||
|
("Outline", "nullptr"),
|
||||||
|
("XUL", "nullptr"),
|
||||||
|
("SVGReset", "nullptr"),
|
||||||
|
("Column", "nullptr"),
|
||||||
|
]]
|
||||||
|
|
||||||
|
# How widely to branch on the outermost if statement.
|
||||||
|
TOPLEVELBRANCHES = 4
|
||||||
|
|
||||||
|
|
||||||
|
# ---- Generate nsStyleStructList.h ----
|
||||||
|
|
||||||
|
count = len(STYLE_STRUCTS)
|
||||||
|
|
||||||
|
def nextPowerOf2(x):
|
||||||
|
return int(pow(2, math.ceil(math.log(x, 2))))
|
||||||
|
|
||||||
|
def printEntry(i):
|
||||||
|
print "STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i]
|
||||||
|
|
||||||
|
def printTestTree(min, max, depth, branches):
|
||||||
|
indent = " " * depth
|
||||||
|
if min == count - 1 and max >= count:
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%sNS_ASSERTION(STYLE_STRUCT_TEST == %d, \"out of range\");)" % (indent, min)
|
||||||
|
printEntry(min)
|
||||||
|
elif max - min == 2:
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST == %d) {)" % (indent, min)
|
||||||
|
printEntry(min)
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
|
||||||
|
printEntry(min + 1)
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%s})" % indent
|
||||||
|
elif min < count:
|
||||||
|
mid = min + (max - min) / branches
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST < %d) {)" % (indent, mid)
|
||||||
|
printTestTree(min, mid, depth + 1, 2)
|
||||||
|
for branch in range(1, branches):
|
||||||
|
lo = min + branch * (max - min) / branches
|
||||||
|
hi = min + (branch + 1) * (max - min) / branches
|
||||||
|
if lo >= count:
|
||||||
|
break
|
||||||
|
if branch == branches - 1 or hi >= count:
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
|
||||||
|
else:
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%s} else if (STYLE_STRUCT_TEST < %d) {)" % (indent, hi)
|
||||||
|
printTestTree(lo, hi, depth + 1, 2)
|
||||||
|
print " STYLE_STRUCT_TEST_CODE(%s})" % indent
|
||||||
|
|
||||||
|
HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
|
||||||
|
|
||||||
|
// IWYU pragma: private, include "nsStyleStructFwd.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* list of structs that contain the data provided by nsStyleContext, the
|
||||||
|
* internal API for computed style data for an element
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is intended to be used by different parts of the code, with
|
||||||
|
* the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and
|
||||||
|
* STYLE_STRUCT_RESET pair of macros) defined in different ways.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STYLE_STRUCT_INHERITED
|
||||||
|
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \\
|
||||||
|
STYLE_STRUCT(name, checkdata_cb)
|
||||||
|
#define UNDEF_STYLE_STRUCT_INHERITED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STYLE_STRUCT_RESET
|
||||||
|
#define STYLE_STRUCT_RESET(name, checkdata_cb) \\
|
||||||
|
STYLE_STRUCT(name, checkdata_cb)
|
||||||
|
#define UNDEF_STYLE_STRUCT_RESET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STYLE_STRUCT_TEST
|
||||||
|
#define STYLE_STRUCT_TEST_CODE(c) c
|
||||||
|
#else
|
||||||
|
#define STYLE_STRUCT_TEST_CODE(c)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The inherited structs are listed before the Reset structs.
|
||||||
|
// nsStyleStructID assumes this is the case, and callers other than
|
||||||
|
// nsStyleStructFwd.h that want the structs in id-order just define
|
||||||
|
// STYLE_STRUCT rather than including the file twice.
|
||||||
|
|
||||||
|
"""
|
||||||
|
FOOTER = """
|
||||||
|
#ifdef UNDEF_STYLE_STRUCT_INHERITED
|
||||||
|
#undef STYLE_STRUCT_INHERITED
|
||||||
|
#undef UNDEF_STYLE_STRUCT_INHERITED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNDEF_STYLE_STRUCT_RESET
|
||||||
|
#undef STYLE_STRUCT_RESET
|
||||||
|
#undef UNDEF_STYLE_STRUCT_RESET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef STYLE_STRUCT_TEST_CODE
|
||||||
|
"""
|
||||||
|
|
||||||
|
print HEADER
|
||||||
|
printTestTree(0, nextPowerOf2(count), 0, TOPLEVELBRANCHES)
|
||||||
|
print FOOTER
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
// vim:cindent:ts=8:et:sw=4:
|
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
// IWYU pragma: private, include "nsStyleStructFwd.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* list of structs that contain the data provided by nsStyleContext, the
|
|
||||||
* internal API for computed style data for an element
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is intended to be used by different parts of the code, with
|
|
||||||
* the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and
|
|
||||||
* STYLE_STRUCT_RESET pair of macros) defined in different ways.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef STYLE_STRUCT_INHERITED
|
|
||||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \
|
|
||||||
STYLE_STRUCT(name, checkdata_cb)
|
|
||||||
#define UNDEF_STYLE_STRUCT_INHERITED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef STYLE_STRUCT_RESET
|
|
||||||
#define STYLE_STRUCT_RESET(name, checkdata_cb) \
|
|
||||||
STYLE_STRUCT(name, checkdata_cb)
|
|
||||||
#define UNDEF_STYLE_STRUCT_RESET
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef STYLE_STRUCT_TEST
|
|
||||||
#define STYLE_STRUCT_TEST_CODE(c) c
|
|
||||||
#else
|
|
||||||
#define STYLE_STRUCT_TEST_CODE(c)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The inherited structs must be listed before the Reset structs.
|
|
||||||
// nsStyleStructID assumes this is the case, and callers other than
|
|
||||||
// nsStyleStructFwd.h that want the structs in id-order just define
|
|
||||||
// STYLE_STRUCT rather than including the file twice.
|
|
||||||
|
|
||||||
STYLE_STRUCT_TEST_CODE(if (STYLE_STRUCT_TEST < 8) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 4) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 2) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 0) {)
|
|
||||||
STYLE_STRUCT_INHERITED(Font, CheckFontCallback)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_INHERITED(Color, CheckColorCallback)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 2) {)
|
|
||||||
STYLE_STRUCT_INHERITED(List, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_INHERITED(Text, CheckTextCallback)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 6) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 4) {)
|
|
||||||
STYLE_STRUCT_INHERITED(Visibility, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_INHERITED(Quotes, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 6) {)
|
|
||||||
STYLE_STRUCT_INHERITED(UserInterface, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_INHERITED(TableBorder, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE(} else if (STYLE_STRUCT_TEST < 16) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 12) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 10) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 8) {)
|
|
||||||
STYLE_STRUCT_INHERITED(SVG, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(Background, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 10) {)
|
|
||||||
STYLE_STRUCT_RESET(Position, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(TextReset, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 14) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 12) {)
|
|
||||||
STYLE_STRUCT_RESET(Display, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(Content, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 14) {)
|
|
||||||
STYLE_STRUCT_RESET(UIReset, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(Table, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE(} else if (STYLE_STRUCT_TEST < 20) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST < 18) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 16) {)
|
|
||||||
STYLE_STRUCT_RESET(Margin, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(Padding, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 18) {)
|
|
||||||
STYLE_STRUCT_RESET(Border, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(Outline, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE(} else if (STYLE_STRUCT_TEST < 22) {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 20) {)
|
|
||||||
STYLE_STRUCT_RESET(XUL, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( } else {)
|
|
||||||
STYLE_STRUCT_RESET(SVGReset, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE( })
|
|
||||||
STYLE_STRUCT_TEST_CODE(} else {)
|
|
||||||
STYLE_STRUCT_TEST_CODE( NS_ASSERTION(STYLE_STRUCT_TEST == 22, "out of range");)
|
|
||||||
STYLE_STRUCT_RESET(Column, nullptr)
|
|
||||||
STYLE_STRUCT_TEST_CODE(})
|
|
||||||
|
|
||||||
#ifdef UNDEF_STYLE_STRUCT_INHERITED
|
|
||||||
#undef STYLE_STRUCT_INHERITED
|
|
||||||
#undef UNDEF_STYLE_STRUCT_INHERITED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNDEF_STYLE_STRUCT_RESET
|
|
||||||
#undef STYLE_STRUCT_RESET
|
|
||||||
#undef UNDEF_STYLE_STRUCT_RESET
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef STYLE_STRUCT_TEST_CODE
|
|
||||||
@@ -113,7 +113,6 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Vector<MenuItemInfo> mAddonMenuItemsCache;
|
private Vector<MenuItemInfo> mAddonMenuItemsCache;
|
||||||
private ButtonToast mToast;
|
|
||||||
private PropertyAnimator mMainLayoutAnimator;
|
private PropertyAnimator mMainLayoutAnimator;
|
||||||
|
|
||||||
private static final Interpolator sTabsInterpolator = new Interpolator() {
|
private static final Interpolator sTabsInterpolator = new Interpolator() {
|
||||||
@@ -395,15 +394,6 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
|
|
||||||
mBrowserToolbar = (BrowserToolbar) findViewById(R.id.browser_toolbar);
|
mBrowserToolbar = (BrowserToolbar) findViewById(R.id.browser_toolbar);
|
||||||
|
|
||||||
mToast = new ButtonToast(findViewById(R.id.toast), new ButtonToast.ToastListener() {
|
|
||||||
@Override
|
|
||||||
public void onButtonClicked(CharSequence token) {
|
|
||||||
if (ADD_SHORTCUT_TOAST.equals(token)) {
|
|
||||||
showBookmarkDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
((GeckoApp.MainLayout) mMainLayout).setTouchEventInterceptor(new HideTabsTouchListener());
|
((GeckoApp.MainLayout) mMainLayout).setTouchEventInterceptor(new HideTabsTouchListener());
|
||||||
((GeckoApp.MainLayout) mMainLayout).setMotionEventInterceptor(new MotionEventInterceptor() {
|
((GeckoApp.MainLayout) mMainLayout).setMotionEventInterceptor(new MotionEventInterceptor() {
|
||||||
@Override
|
@Override
|
||||||
@@ -815,7 +805,7 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
|
|
||||||
// If the page has shrunk so that the toolbar no longer scrolls, make
|
// If the page has shrunk so that the toolbar no longer scrolls, make
|
||||||
// sure the toolbar is visible.
|
// sure the toolbar is visible.
|
||||||
if (aMetrics.getPageHeight() < aMetrics.getHeight()) {
|
if (aMetrics.getPageHeight() <= aMetrics.getHeight()) {
|
||||||
if (mDynamicToolbarCanScroll) {
|
if (mDynamicToolbarCanScroll) {
|
||||||
mDynamicToolbarCanScroll = false;
|
mDynamicToolbarCanScroll = false;
|
||||||
if (!mBrowserToolbar.isVisible()) {
|
if (!mBrowserToolbar.isVisible()) {
|
||||||
@@ -1449,34 +1439,20 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (info.icon != null) {
|
if (info.icon != null) {
|
||||||
if (info.icon.startsWith("data")) {
|
BitmapUtils.getDrawable(this, info.icon, new BitmapUtils.BitmapLoader() {
|
||||||
BitmapDrawable drawable = new BitmapDrawable(BitmapUtils.getBitmapFromDataURI(info.icon));
|
|
||||||
item.setIcon(drawable);
|
|
||||||
}
|
|
||||||
else if (info.icon.startsWith("jar:") || info.icon.startsWith("file://")) {
|
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void onBitmapFound(Drawable d) {
|
||||||
try {
|
if (d == null) {
|
||||||
URL url = new URL(info.icon);
|
item.setIcon(R.drawable.ic_menu_addons_filler);
|
||||||
InputStream is = (InputStream) url.getContent();
|
return;
|
||||||
try {
|
|
||||||
Drawable drawable = Drawable.createFromStream(is, "src");
|
|
||||||
item.setIcon(drawable);
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(LOGTAG, "Unable to set icon", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.setIcon(d);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
item.setIcon(R.drawable.ic_menu_addons_filler);
|
item.setIcon(R.drawable.ic_menu_addons_filler);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
item.setIcon(R.drawable.ic_menu_addons_filler);
|
|
||||||
}
|
|
||||||
|
|
||||||
item.setCheckable(info.checkable);
|
item.setCheckable(info.checkable);
|
||||||
item.setChecked(info.checked);
|
item.setChecked(info.checked);
|
||||||
@@ -1701,8 +1677,16 @@ abstract public class BrowserApp extends GeckoApp
|
|||||||
mToast.show(false,
|
mToast.show(false,
|
||||||
getResources().getString(R.string.bookmark_added),
|
getResources().getString(R.string.bookmark_added),
|
||||||
getResources().getString(R.string.bookmark_options),
|
getResources().getString(R.string.bookmark_options),
|
||||||
0,
|
null,
|
||||||
ADD_SHORTCUT_TOAST);
|
new ButtonToast.ToastListener() {
|
||||||
|
@Override
|
||||||
|
public void onButtonClicked() {
|
||||||
|
showBookmarkDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onToastHidden(ButtonToast.ReasonHidden reason) { }
|
||||||
|
});
|
||||||
item.setIcon(R.drawable.ic_menu_bookmark_remove);
|
item.setIcon(R.drawable.ic_menu_bookmark_remove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
|||||||
import org.mozilla.gecko.gfx.LayerView;
|
import org.mozilla.gecko.gfx.LayerView;
|
||||||
import org.mozilla.gecko.menu.GeckoMenu;
|
import org.mozilla.gecko.menu.GeckoMenu;
|
||||||
import org.mozilla.gecko.menu.MenuPopup;
|
import org.mozilla.gecko.menu.MenuPopup;
|
||||||
|
import org.mozilla.gecko.PageActionLayout;
|
||||||
|
import org.mozilla.gecko.PrefsHelper;
|
||||||
import org.mozilla.gecko.util.Clipboard;
|
import org.mozilla.gecko.util.Clipboard;
|
||||||
import org.mozilla.gecko.util.StringUtils;
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.mozilla.gecko.util.HardwareUtils;
|
import org.mozilla.gecko.util.HardwareUtils;
|
||||||
|
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
import org.mozilla.gecko.util.UiAsyncTask;
|
import org.mozilla.gecko.util.UiAsyncTask;
|
||||||
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
import org.mozilla.gecko.PrefsHelper;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@@ -63,14 +63,14 @@ import android.widget.RelativeLayout;
|
|||||||
import android.widget.RelativeLayout.LayoutParams;
|
import android.widget.RelativeLayout.LayoutParams;
|
||||||
import android.widget.ViewSwitcher;
|
import android.widget.ViewSwitcher;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BrowserToolbar extends GeckoRelativeLayout
|
public class BrowserToolbar extends GeckoRelativeLayout
|
||||||
implements Tabs.OnTabsChangedListener,
|
implements Tabs.OnTabsChangedListener,
|
||||||
GeckoMenu.ActionItemBarPresenter,
|
GeckoMenu.ActionItemBarPresenter,
|
||||||
Animation.AnimationListener {
|
Animation.AnimationListener,
|
||||||
|
GeckoEventListener {
|
||||||
private static final String LOGTAG = "GeckoToolbar";
|
private static final String LOGTAG = "GeckoToolbar";
|
||||||
public static final String PREF_TITLEBAR_MODE = "browser.chrome.titlebarMode";
|
public static final String PREF_TITLEBAR_MODE = "browser.chrome.titlebarMode";
|
||||||
private LayoutParams mAwesomeBarParams;
|
private LayoutParams mAwesomeBarParams;
|
||||||
@@ -88,7 +88,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
public ImageButton mFavicon;
|
public ImageButton mFavicon;
|
||||||
public ImageButton mStop;
|
public ImageButton mStop;
|
||||||
public ImageButton mSiteSecurity;
|
public ImageButton mSiteSecurity;
|
||||||
public ImageButton mReader;
|
public PageActionLayout mPageActionLayout;
|
||||||
private AnimationDrawable mProgressSpinner;
|
private AnimationDrawable mProgressSpinner;
|
||||||
private TabCounter mTabsCounter;
|
private TabCounter mTabsCounter;
|
||||||
private ImageView mShadow;
|
private ImageView mShadow;
|
||||||
@@ -183,6 +183,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
mDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext));
|
mDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext));
|
||||||
mPrivateDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext_private));
|
mPrivateDomainColor = new ForegroundColorSpan(res.getColor(R.color.url_bar_domaintext_private));
|
||||||
|
|
||||||
|
registerEventListener("Reader:Click");
|
||||||
|
registerEventListener("Reader:LongClick");
|
||||||
|
|
||||||
mShowSiteSecurity = false;
|
mShowSiteSecurity = false;
|
||||||
mShowReader = false;
|
mShowReader = false;
|
||||||
|
|
||||||
@@ -221,8 +224,8 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
mProgressSpinner = (AnimationDrawable) res.getDrawable(R.drawable.progress_spinner);
|
mProgressSpinner = (AnimationDrawable) res.getDrawable(R.drawable.progress_spinner);
|
||||||
|
|
||||||
mStop = (ImageButton) findViewById(R.id.stop);
|
mStop = (ImageButton) findViewById(R.id.stop);
|
||||||
mReader = (ImageButton) findViewById(R.id.reader);
|
|
||||||
mShadow = (ImageView) findViewById(R.id.shadow);
|
mShadow = (ImageView) findViewById(R.id.shadow);
|
||||||
|
mPageActionLayout = (PageActionLayout) findViewById(R.id.page_action_layout);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 16) {
|
if (Build.VERSION.SDK_INT >= 16) {
|
||||||
mShadow.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
mShadow.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
|
||||||
@@ -237,9 +240,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
// order appropriately.
|
// order appropriately.
|
||||||
if (HardwareUtils.isTablet()) {
|
if (HardwareUtils.isTablet()) {
|
||||||
mFocusOrder = Arrays.asList(mTabs, mBack, mForward, this,
|
mFocusOrder = Arrays.asList(mTabs, mBack, mForward, this,
|
||||||
mSiteSecurity, mReader, mStop, mActionItemBar, mMenu);
|
mSiteSecurity, mPageActionLayout, mStop, mActionItemBar, mMenu);
|
||||||
} else {
|
} else {
|
||||||
mFocusOrder = Arrays.asList(this, mSiteSecurity, mReader, mStop,
|
mFocusOrder = Arrays.asList(this, mSiteSecurity, mPageActionLayout, mStop,
|
||||||
mTabs, mMenu);
|
mTabs, mMenu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,28 +356,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mReader.setOnClickListener(new Button.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
|
||||||
if (tab != null) {
|
|
||||||
tab.toggleReaderMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mReader.setOnLongClickListener(new Button.OnLongClickListener() {
|
|
||||||
public boolean onLongClick(View v) {
|
|
||||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
|
||||||
if (tab != null) {
|
|
||||||
tab.addToReadingList();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mShadow.setOnClickListener(new Button.OnClickListener() {
|
mShadow.setOnClickListener(new Button.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -474,7 +455,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
if (showProgress && tab.getState() == Tab.STATE_LOADING)
|
if (showProgress && tab.getState() == Tab.STATE_LOADING)
|
||||||
setProgressVisibility(true);
|
setProgressVisibility(true);
|
||||||
setSecurityMode(tab.getSecurityMode());
|
setSecurityMode(tab.getSecurityMode());
|
||||||
setReaderMode(tab.getReaderEnabled());
|
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STOP:
|
case STOP:
|
||||||
@@ -519,7 +500,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
break;
|
break;
|
||||||
case READER_ENABLED:
|
case READER_ENABLED:
|
||||||
if (Tabs.getInstance().isSelectedTab(tab)) {
|
if (Tabs.getInstance().isSelectedTab(tab)) {
|
||||||
setReaderMode(tab.getReaderEnabled());
|
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -537,7 +518,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
mFavicon.setNextFocusDownId(nextId);
|
mFavicon.setNextFocusDownId(nextId);
|
||||||
mStop.setNextFocusDownId(nextId);
|
mStop.setNextFocusDownId(nextId);
|
||||||
mSiteSecurity.setNextFocusDownId(nextId);
|
mSiteSecurity.setNextFocusDownId(nextId);
|
||||||
mReader.setNextFocusDownId(nextId);
|
mPageActionLayout.setNextFocusDownId(nextId);
|
||||||
mMenu.setNextFocusDownId(nextId);
|
mMenu.setNextFocusDownId(nextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +594,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
ViewHelper.setTranslationX(mMenuIcon, curveTranslation);
|
ViewHelper.setTranslationX(mMenuIcon, curveTranslation);
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewHelper.setAlpha(mReader, 0);
|
ViewHelper.setAlpha(mPageActionLayout, 0);
|
||||||
ViewHelper.setAlpha(mStop, 0);
|
ViewHelper.setAlpha(mStop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +642,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
|
|
||||||
// Fade toolbar buttons (reader, stop) after the entry
|
// Fade toolbar buttons (reader, stop) after the entry
|
||||||
// is schrunk back to its original size.
|
// is schrunk back to its original size.
|
||||||
buttonsAnimator.attach(mReader,
|
buttonsAnimator.attach(mPageActionLayout,
|
||||||
PropertyAnimator.Property.ALPHA,
|
PropertyAnimator.Property.ALPHA,
|
||||||
1);
|
1);
|
||||||
buttonsAnimator.attach(mStop,
|
buttonsAnimator.attach(mStop,
|
||||||
@@ -708,7 +689,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
setSelected(true);
|
setSelected(true);
|
||||||
|
|
||||||
// Hide stop/reader buttons immediately
|
// Hide stop/reader buttons immediately
|
||||||
ViewHelper.setAlpha(mReader, 0);
|
ViewHelper.setAlpha(mPageActionLayout, 0);
|
||||||
ViewHelper.setAlpha(mStop, 0);
|
ViewHelper.setAlpha(mStop, 0);
|
||||||
|
|
||||||
// Slide the right side elements of the toolbar
|
// Slide the right side elements of the toolbar
|
||||||
@@ -827,22 +808,16 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
// Handle the viewing mode page actions
|
// Handle the viewing mode page actions
|
||||||
setSiteSecurityVisibility(mShowSiteSecurity && !isLoading);
|
setSiteSecurityVisibility(mShowSiteSecurity && !isLoading);
|
||||||
|
|
||||||
// Handle the readerMode image and visibility: We show the reader mode button if 1) you can
|
|
||||||
// enter reader mode for current page or 2) if you're already in reader mode,
|
|
||||||
// in which case we show the reader mode "close" (reader_active) icon.
|
|
||||||
boolean inReaderMode = false;
|
boolean inReaderMode = false;
|
||||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||||
if (tab != null)
|
if (tab != null)
|
||||||
inReaderMode = ReaderModeUtils.isAboutReader(tab.getURL());
|
inReaderMode = ReaderModeUtils.isAboutReader(tab.getURL());
|
||||||
mReader.setImageResource(inReaderMode ? R.drawable.reader_active : R.drawable.reader);
|
|
||||||
|
|
||||||
mReader.setVisibility(!isLoading && (mShowReader || inReaderMode) ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
|
mPageActionLayout.setVisibility(!isLoading ? View.VISIBLE : View.GONE);
|
||||||
// We want title to fill the whole space available for it when there are icons
|
// We want title to fill the whole space available for it when there are icons
|
||||||
// being shown on the right side of the toolbar as the icons already have some
|
// being shown on the right side of the toolbar as the icons already have some
|
||||||
// padding in them. This is just to avoid wasting space when icons are shown.
|
// padding in them. This is just to avoid wasting space when icons are shown.
|
||||||
mTitle.setPadding(0, 0, (!isLoading && !(mShowReader || inReaderMode) ? mTitlePadding : 0), 0);
|
mTitle.setPadding(0, 0, (!isLoading && !(mShowReader || inReaderMode) ? mTitlePadding : 0), 0);
|
||||||
|
|
||||||
updateFocusOrder();
|
updateFocusOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,11 +972,6 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setReaderMode(boolean showReader) {
|
|
||||||
mShowReader = showReader;
|
|
||||||
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void prepareTabsAnimation(PropertyAnimator animator, boolean tabsAreShown) {
|
public void prepareTabsAnimation(PropertyAnimator animator, boolean tabsAreShown) {
|
||||||
if (!tabsAreShown) {
|
if (!tabsAreShown) {
|
||||||
PropertyAnimator buttonsAnimator =
|
PropertyAnimator buttonsAnimator =
|
||||||
@@ -1162,7 +1132,7 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
setFavicon(tab.getFavicon());
|
setFavicon(tab.getFavicon());
|
||||||
setProgressVisibility(tab.getState() == Tab.STATE_LOADING);
|
setProgressVisibility(tab.getState() == Tab.STATE_LOADING);
|
||||||
setSecurityMode(tab.getSecurityMode());
|
setSecurityMode(tab.getSecurityMode());
|
||||||
setReaderMode(tab.getReaderEnabled());
|
setPageActionVisibility(mStop.getVisibility() == View.VISIBLE);
|
||||||
setShadowVisibility(true);
|
setShadowVisibility(true);
|
||||||
updateBackButton(tab.canDoBack());
|
updateBackButton(tab.canDoBack());
|
||||||
updateForwardButton(tab.canDoForward());
|
updateForwardButton(tab.canDoForward());
|
||||||
@@ -1189,6 +1159,9 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
mPrefObserverId = null;
|
mPrefObserverId = null;
|
||||||
}
|
}
|
||||||
Tabs.unregisterOnTabsChangedListener(this);
|
Tabs.unregisterOnTabsChangedListener(this);
|
||||||
|
|
||||||
|
unregisterEventListener("Reader:Click");
|
||||||
|
unregisterEventListener("Reader:LongClick");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean openOptionsMenu() {
|
public boolean openOptionsMenu() {
|
||||||
@@ -1225,4 +1198,27 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void registerEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().registerEventListener(event, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void unregisterEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().unregisterEventListener(event, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(String event, JSONObject message) {
|
||||||
|
if (event.equals("Reader:Click")) {
|
||||||
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||||
|
if (tab != null) {
|
||||||
|
tab.toggleReaderMode();
|
||||||
|
}
|
||||||
|
} else if (event.equals("Reader:LongClick")) {
|
||||||
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||||
|
if (tab != null) {
|
||||||
|
tab.addToReadingList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.mozilla.gecko.util.GeckoEventResponder;
|
|||||||
import org.mozilla.gecko.util.HardwareUtils;
|
import org.mozilla.gecko.util.HardwareUtils;
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
import org.mozilla.gecko.util.UiAsyncTask;
|
import org.mozilla.gecko.util.UiAsyncTask;
|
||||||
|
import org.mozilla.gecko.widget.ButtonToast;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -44,6 +45,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
@@ -187,6 +189,7 @@ abstract public class GeckoApp
|
|||||||
protected DoorHangerPopup mDoorHangerPopup;
|
protected DoorHangerPopup mDoorHangerPopup;
|
||||||
protected FormAssistPopup mFormAssistPopup;
|
protected FormAssistPopup mFormAssistPopup;
|
||||||
protected TabsPanel mTabsPanel;
|
protected TabsPanel mTabsPanel;
|
||||||
|
protected ButtonToast mToast;
|
||||||
|
|
||||||
// Handles notification messages from javascript
|
// Handles notification messages from javascript
|
||||||
protected NotificationHelper mNotificationHelper;
|
protected NotificationHelper mNotificationHelper;
|
||||||
@@ -545,8 +548,16 @@ abstract public class GeckoApp
|
|||||||
try {
|
try {
|
||||||
if (event.equals("Toast:Show")) {
|
if (event.equals("Toast:Show")) {
|
||||||
final String msg = message.getString("message");
|
final String msg = message.getString("message");
|
||||||
|
final JSONObject button = message.optJSONObject("button");
|
||||||
|
if (button != null) {
|
||||||
|
final String label = button.optString("label");
|
||||||
|
final String icon = button.optString("icon");
|
||||||
|
final String id = button.optString("id");
|
||||||
|
showButtonToast(msg, label, icon, id);
|
||||||
|
} else {
|
||||||
final String duration = message.getString("duration");
|
final String duration = message.getString("duration");
|
||||||
handleShowToast(msg, duration);
|
showNormalToast(msg, duration);
|
||||||
|
}
|
||||||
} else if (event.equals("log")) {
|
} else if (event.equals("log")) {
|
||||||
// generic log listener
|
// generic log listener
|
||||||
final String msg = message.getString("msg");
|
final String msg = message.getString("msg");
|
||||||
@@ -810,20 +821,42 @@ abstract public class GeckoApp
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleShowToast(final String message, final String duration) {
|
public void showNormalToast(final String message, final String duration) {
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Toast toast;
|
Toast toast;
|
||||||
if (duration.equals("long"))
|
if (duration.equals("long")) {
|
||||||
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_LONG);
|
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_LONG);
|
||||||
else
|
} else {
|
||||||
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_SHORT);
|
toast = Toast.makeText(GeckoApp.this, message, Toast.LENGTH_SHORT);
|
||||||
|
}
|
||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showButtonToast(final String message, final String buttonText,
|
||||||
|
final String buttonIcon, final String buttonId) {
|
||||||
|
BitmapUtils.getDrawable(GeckoApp.this, buttonIcon, new BitmapUtils.BitmapLoader() {
|
||||||
|
public void onBitmapFound(Drawable d) {
|
||||||
|
mToast.show(false, message, buttonText, d, new ButtonToast.ToastListener() {
|
||||||
|
@Override
|
||||||
|
public void onButtonClicked() {
|
||||||
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Toast:Click", buttonId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onToastHidden(ButtonToast.ReasonHidden reason) {
|
||||||
|
if (reason == ButtonToast.ReasonHidden.TIMEOUT) {
|
||||||
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Toast:Hidden", buttonId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void addFullScreenPluginView(View view) {
|
private void addFullScreenPluginView(View view) {
|
||||||
if (mFullScreenPluginView != null) {
|
if (mFullScreenPluginView != null) {
|
||||||
Log.w(LOGTAG, "Already have a fullscreen plugin view");
|
Log.w(LOGTAG, "Already have a fullscreen plugin view");
|
||||||
@@ -1278,6 +1311,7 @@ abstract public class GeckoApp
|
|||||||
// Set up tabs panel.
|
// Set up tabs panel.
|
||||||
mTabsPanel = (TabsPanel) findViewById(R.id.tabs_panel);
|
mTabsPanel = (TabsPanel) findViewById(R.id.tabs_panel);
|
||||||
mNotificationHelper = new NotificationHelper(this);
|
mNotificationHelper = new NotificationHelper(this);
|
||||||
|
mToast = new ButtonToast(findViewById(R.id.toast));
|
||||||
|
|
||||||
// Check if the last run was exited due to a normal kill while
|
// Check if the last run was exited due to a normal kill while
|
||||||
// we were in the background, or a more harsh kill while we were
|
// we were in the background, or a more harsh kill while we were
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ FENNEC_JAVA_FILES = \
|
|||||||
NotificationService.java \
|
NotificationService.java \
|
||||||
NSSBridge.java \
|
NSSBridge.java \
|
||||||
OrderedBroadcastHelper.java \
|
OrderedBroadcastHelper.java \
|
||||||
|
PageActionLayout.java \
|
||||||
PrefsHelper.java \
|
PrefsHelper.java \
|
||||||
PrivateDataPreference.java \
|
PrivateDataPreference.java \
|
||||||
PrivateTab.java \
|
PrivateTab.java \
|
||||||
@@ -641,6 +642,7 @@ RES_DRAWABLE_MDPI = \
|
|||||||
res/drawable-mdpi/ic_menu_new_tab.png \
|
res/drawable-mdpi/ic_menu_new_tab.png \
|
||||||
res/drawable-mdpi/ic_menu_reload.png \
|
res/drawable-mdpi/ic_menu_reload.png \
|
||||||
res/drawable-mdpi/ic_status_logo.png \
|
res/drawable-mdpi/ic_status_logo.png \
|
||||||
|
res/drawable-mdpi/icon_pageaction.png \
|
||||||
res/drawable-mdpi/progress_spinner_1.png \
|
res/drawable-mdpi/progress_spinner_1.png \
|
||||||
res/drawable-mdpi/progress_spinner_2.png \
|
res/drawable-mdpi/progress_spinner_2.png \
|
||||||
res/drawable-mdpi/progress_spinner_3.png \
|
res/drawable-mdpi/progress_spinner_3.png \
|
||||||
@@ -763,6 +765,7 @@ RES_DRAWABLE_HDPI = \
|
|||||||
res/drawable-hdpi/ic_menu_new_tab.png \
|
res/drawable-hdpi/ic_menu_new_tab.png \
|
||||||
res/drawable-hdpi/ic_menu_reload.png \
|
res/drawable-hdpi/ic_menu_reload.png \
|
||||||
res/drawable-hdpi/ic_status_logo.png \
|
res/drawable-hdpi/ic_status_logo.png \
|
||||||
|
res/drawable-hdpi/icon_pageaction.png \
|
||||||
res/drawable-hdpi/tab_indicator_divider.9.png \
|
res/drawable-hdpi/tab_indicator_divider.9.png \
|
||||||
res/drawable-hdpi/tab_indicator_selected.9.png \
|
res/drawable-hdpi/tab_indicator_selected.9.png \
|
||||||
res/drawable-hdpi/tab_indicator_selected_focused.9.png \
|
res/drawable-hdpi/tab_indicator_selected_focused.9.png \
|
||||||
@@ -861,6 +864,7 @@ RES_DRAWABLE_XHDPI = \
|
|||||||
res/drawable-xhdpi/ic_menu_new_tab.png \
|
res/drawable-xhdpi/ic_menu_new_tab.png \
|
||||||
res/drawable-xhdpi/ic_menu_reload.png \
|
res/drawable-xhdpi/ic_menu_reload.png \
|
||||||
res/drawable-xhdpi/ic_status_logo.png \
|
res/drawable-xhdpi/ic_status_logo.png \
|
||||||
|
res/drawable-xhdpi/icon_pageaction.png \
|
||||||
res/drawable-xhdpi/spinner_default.9.png \
|
res/drawable-xhdpi/spinner_default.9.png \
|
||||||
res/drawable-xhdpi/spinner_focused.9.png \
|
res/drawable-xhdpi/spinner_focused.9.png \
|
||||||
res/drawable-xhdpi/spinner_pressed.9.png \
|
res/drawable-xhdpi/spinner_pressed.9.png \
|
||||||
|
|||||||
315
mobile/android/base/PageActionLayout.java
Normal file
315
mobile/android/base/PageActionLayout.java
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||||
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
import org.mozilla.gecko.widget.GeckoPopupMenu;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.ContextMenu;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
public class PageActionLayout extends LinearLayout implements GeckoEventListener,
|
||||||
|
View.OnClickListener,
|
||||||
|
View.OnLongClickListener {
|
||||||
|
private final String LOGTAG = "GeckoPageActionLayout";
|
||||||
|
private final String MENU_BUTTON_KEY = "MENU_BUTTON_KEY";
|
||||||
|
private final int DEFAULT_PAGE_ACTIONS_SHOWN = 2;
|
||||||
|
|
||||||
|
private LinkedHashMap<String, PageAction> mPageActionList;
|
||||||
|
private GeckoPopupMenu mPageActionsMenu;
|
||||||
|
private Context mContext;
|
||||||
|
private LinearLayout mLayout;
|
||||||
|
|
||||||
|
// By default it's two, can be changed by calling setNumberShown(int)
|
||||||
|
private int mMaxVisiblePageActions;
|
||||||
|
|
||||||
|
public PageActionLayout(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
mContext = context;
|
||||||
|
mLayout = this;
|
||||||
|
|
||||||
|
mPageActionList = new LinkedHashMap<String, PageAction>();
|
||||||
|
setNumberShown(DEFAULT_PAGE_ACTIONS_SHOWN);
|
||||||
|
|
||||||
|
registerEventListener("PageActions:Add");
|
||||||
|
registerEventListener("PageActions:Remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumberShown(int count) {
|
||||||
|
mMaxVisiblePageActions = count;
|
||||||
|
|
||||||
|
for(int index = 0; index < count; index++) {
|
||||||
|
if ((this.getChildCount() - 1) < index) {
|
||||||
|
mLayout.addView(createImageButton());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDestroy() {
|
||||||
|
unregisterEventListener("PageActions:Add");
|
||||||
|
unregisterEventListener("PageActions:Remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().registerEventListener(event, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void unregisterEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().unregisterEventListener(event, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(String event, JSONObject message) {
|
||||||
|
try {
|
||||||
|
if (event.equals("PageActions:Add")) {
|
||||||
|
final String id = message.getString("id");
|
||||||
|
final String title = message.getString("title");
|
||||||
|
final String imageURL = message.optString("icon");
|
||||||
|
|
||||||
|
addPageAction(id, title, imageURL, new OnPageActionClickListeners() {
|
||||||
|
@Override
|
||||||
|
public void onClick(String id) {
|
||||||
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:Clicked", id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(String id) {
|
||||||
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:LongClicked", id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (event.equals("PageActions:Remove")) {
|
||||||
|
final String id = message.getString("id");
|
||||||
|
|
||||||
|
removePageAction(id);
|
||||||
|
}
|
||||||
|
} catch(JSONException ex) {
|
||||||
|
Log.e(LOGTAG, "Error deocding", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPageAction(final String id, final String title, final String imageData, final OnPageActionClickListeners mOnPageActionClickListeners) {
|
||||||
|
final PageAction pageAction = new PageAction(id, title, null, mOnPageActionClickListeners);
|
||||||
|
mPageActionList.put(id, pageAction);
|
||||||
|
|
||||||
|
BitmapUtils.getDrawable(mContext, imageData, new BitmapUtils.BitmapLoader() {
|
||||||
|
@Override
|
||||||
|
public void onBitmapFound(final Drawable d) {
|
||||||
|
if (mPageActionList.containsKey(id)) {
|
||||||
|
pageAction.setDrawable(d);
|
||||||
|
refreshPageActionIcons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePageAction(String id) {
|
||||||
|
mPageActionList.remove(id);
|
||||||
|
refreshPageActionIcons();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageButton createImageButton() {
|
||||||
|
ImageButton imageButton = new ImageButton(mContext, null, R.style.AddressBar_ImageButton_Icon);
|
||||||
|
imageButton.setLayoutParams(new LayoutParams(mContext.getResources().getDimensionPixelSize(R.dimen.page_action_button_width), LayoutParams.MATCH_PARENT));
|
||||||
|
imageButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||||
|
imageButton.setOnClickListener(this);
|
||||||
|
imageButton.setOnLongClickListener(this);
|
||||||
|
return imageButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String buttonClickedId = (String)v.getTag();
|
||||||
|
if (buttonClickedId != null) {
|
||||||
|
if (buttonClickedId.equals(MENU_BUTTON_KEY)) {
|
||||||
|
showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1);
|
||||||
|
} else {
|
||||||
|
mPageActionList.get(buttonClickedId).onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
String buttonClickedId = (String)v.getTag();
|
||||||
|
if (buttonClickedId.equals(MENU_BUTTON_KEY)) {
|
||||||
|
showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return mPageActionList.get(buttonClickedId).onLongClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshPageActionIcons() {
|
||||||
|
final Resources resources = mContext.getResources();
|
||||||
|
for(int index = 0; index < this.getChildCount(); index++) {
|
||||||
|
final ImageButton v = (ImageButton)this.getChildAt(index);
|
||||||
|
final PageAction pageAction = getPageActionForViewAt(index);
|
||||||
|
|
||||||
|
if (index == (this.getChildCount() - 1)) {
|
||||||
|
String id = (pageAction != null) ? pageAction.getID() : null;
|
||||||
|
v.setTag((mPageActionList.size() > mMaxVisiblePageActions) ? MENU_BUTTON_KEY : id);
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run () {
|
||||||
|
// If there are more pageactions then buttons, set the menu icon. Otherwise set the page action's icon if there is a page action.
|
||||||
|
Drawable d = (pageAction != null) ? pageAction.getDrawable() : null;
|
||||||
|
v.setImageDrawable((mPageActionList.size() > mMaxVisiblePageActions) ? resources.getDrawable(R.drawable.icon_pageaction) : d);
|
||||||
|
v.setVisibility((pageAction != null) ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
v.setTag((pageAction != null) ? pageAction.getID() : null);
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run () {
|
||||||
|
v.setImageDrawable((pageAction != null) ? pageAction.getDrawable() : null);
|
||||||
|
v.setVisibility((pageAction != null) ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PageAction getPageActionForViewAt(int index) {
|
||||||
|
/**
|
||||||
|
* We show the user the most recent pageaction added since this keeps the user aware of any new page actions being added
|
||||||
|
* Also, the order of the pageAction is important i.e. if a page action is added, instead of shifting the pagactions to the
|
||||||
|
* left to make space for the new one, it would be more visually appealing to have the pageaction appear in the blank space.
|
||||||
|
*
|
||||||
|
* buttonIndex is needed for this reason because every new View added to PageActionLayout gets added to the right of its neighbouring View.
|
||||||
|
* Hence the button on the very leftmost has the index 0. We want our pageactions to start from the rightmost
|
||||||
|
* and hence we maintain the insertion order of the child Views which is essentially the reverse of their index
|
||||||
|
*/
|
||||||
|
|
||||||
|
int buttonIndex = (this.getChildCount() - 1) - index;
|
||||||
|
int totalVisibleButtons = ((mPageActionList.size() < this.getChildCount()) ? mPageActionList.size() : this.getChildCount());
|
||||||
|
|
||||||
|
if (mPageActionList.size() > buttonIndex) {
|
||||||
|
// Return the pageactions starting from the end of the list for the number of visible pageactions.
|
||||||
|
return getPageActionAt((mPageActionList.size() - totalVisibleButtons) + buttonIndex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PageAction getPageActionAt(int index) {
|
||||||
|
int count = 0;
|
||||||
|
for(PageAction pageAction : mPageActionList.values()) {
|
||||||
|
if (count == index) {
|
||||||
|
return pageAction;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMenu(View mPageActionButton, int toShow) {
|
||||||
|
if (mPageActionsMenu == null) {
|
||||||
|
mPageActionsMenu = new GeckoPopupMenu(mPageActionButton.getContext(), mPageActionButton);
|
||||||
|
mPageActionsMenu.inflate(0);
|
||||||
|
mPageActionsMenu.setOnMenuItemClickListener(new GeckoPopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
for(PageAction pageAction : mPageActionList.values()) {
|
||||||
|
if (pageAction.key() == item.getItemId()) {
|
||||||
|
pageAction.onClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Menu menu = mPageActionsMenu.getMenu();
|
||||||
|
menu.clear();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for(PageAction pageAction : mPageActionList.values()) {
|
||||||
|
if (count < toShow) {
|
||||||
|
MenuItem item = menu.add(Menu.NONE, pageAction.key(), Menu.NONE, pageAction.getTitle());
|
||||||
|
item.setIcon(pageAction.getDrawable());
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
mPageActionsMenu.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface OnPageActionClickListeners {
|
||||||
|
public void onClick(String id);
|
||||||
|
public boolean onLongClick(String id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PageAction {
|
||||||
|
private OnPageActionClickListeners mOnPageActionClickListeners;
|
||||||
|
private Drawable mDrawable;
|
||||||
|
private String mTitle;
|
||||||
|
private String mId;
|
||||||
|
private int key;
|
||||||
|
|
||||||
|
public PageAction(String id, String title, Drawable image, OnPageActionClickListeners mOnPageActionClickListeners) {
|
||||||
|
this.mId = id;
|
||||||
|
this.mTitle = title;
|
||||||
|
this.mDrawable = image;
|
||||||
|
this.mOnPageActionClickListeners = mOnPageActionClickListeners;
|
||||||
|
|
||||||
|
this.key = UUID.fromString(mId.subSequence(1, mId.length() - 2).toString()).hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable getDrawable() {
|
||||||
|
return mDrawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawable(Drawable d) {
|
||||||
|
this.mDrawable = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return mId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int key() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClick() {
|
||||||
|
if (mOnPageActionClickListeners != null) {
|
||||||
|
mOnPageActionClickListeners.onClick(mId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onLongClick() {
|
||||||
|
if (mOnPageActionClickListeners != null) {
|
||||||
|
return mOnPageActionClickListeners.onLongClick(mId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,14 +5,22 @@
|
|||||||
|
|
||||||
package org.mozilla.gecko.gfx;
|
package org.mozilla.gecko.gfx;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
import org.mozilla.gecko.util.GeckoJarReader;
|
||||||
|
import org.mozilla.gecko.util.UiAsyncTask;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import org.mozilla.gecko.R;
|
import org.mozilla.gecko.R;
|
||||||
|
|
||||||
@@ -27,6 +35,70 @@ public final class BitmapUtils {
|
|||||||
|
|
||||||
private BitmapUtils() {}
|
private BitmapUtils() {}
|
||||||
|
|
||||||
|
public interface BitmapLoader {
|
||||||
|
public void onBitmapFound(Drawable d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a string url, returns a drawable for the bitmap. Should work with data, file, jar,
|
||||||
|
* or chrome (converted to jar:jar) urls. Results are sent to the passed in BitmapLoader object.
|
||||||
|
* Can return null if a Drawable couldn't be created.
|
||||||
|
* Results are always posted on the UI thread.
|
||||||
|
* TODO: Support for http(s) and drawable urls.
|
||||||
|
*/
|
||||||
|
public static void getDrawable(final Context context, final String data, final BitmapLoader loader) {
|
||||||
|
if (TextUtils.isEmpty(data)) {
|
||||||
|
postResultToUiThread(null, loader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.startsWith("data")) {
|
||||||
|
BitmapDrawable d = new BitmapDrawable(getBitmapFromDataURI(data));
|
||||||
|
postResultToUiThread(d, loader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.startsWith("jar:") && !data.startsWith("file://")) {
|
||||||
|
postResultToUiThread(null, loader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(new UiAsyncTask<Void, Void, Drawable>(ThreadUtils.getBackgroundHandler()) {
|
||||||
|
@Override
|
||||||
|
public Drawable doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
if (data.startsWith("jar:jar")) {
|
||||||
|
return GeckoJarReader.getBitmapDrawable(context.getResources(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
URL url = new URL(data);
|
||||||
|
InputStream is = (InputStream) url.getContent();
|
||||||
|
try {
|
||||||
|
return Drawable.createFromStream(is, "src");
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(LOGTAG, "Unable to set icon", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPostExecute(Drawable drawable) {
|
||||||
|
postResultToUiThread(drawable, loader);
|
||||||
|
}
|
||||||
|
}).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void postResultToUiThread(final Drawable d, final BitmapLoader loader) {
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
loader.onBitmapFound(d);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static Bitmap decodeByteArray(byte[] bytes) {
|
public static Bitmap decodeByteArray(byte[] bytes) {
|
||||||
return decodeByteArray(bytes, null);
|
return decodeByteArray(bytes, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -854,6 +854,21 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||||||
viewportMetricsChanged(true);
|
viewportMetricsChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Implementation of PanZoomTarget
|
||||||
|
* Notification that a subdocument has been scrolled by a certain amount.
|
||||||
|
* This is used here to make sure that the margins are still accessible
|
||||||
|
* during subdocument scrolling.
|
||||||
|
*
|
||||||
|
* You must hold the monitor while calling this.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onSubdocumentScrollBy(float dx, float dy) {
|
||||||
|
ImmutableViewportMetrics newMarginsMetrics =
|
||||||
|
mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy);
|
||||||
|
mViewportMetrics = mViewportMetrics.setMarginsFrom(newMarginsMetrics);
|
||||||
|
viewportMetricsChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
/** Implementation of PanZoomTarget */
|
/** Implementation of PanZoomTarget */
|
||||||
@Override
|
@Override
|
||||||
public void panZoomStopped() {
|
public void panZoomStopped() {
|
||||||
|
|||||||
@@ -806,7 +806,11 @@ class JavaPanZoomController
|
|||||||
if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
|
if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! mSubscroller.scrollBy(displacement)) {
|
if (mSubscroller.scrollBy(displacement)) {
|
||||||
|
synchronized (mTarget.getLock()) {
|
||||||
|
mTarget.onSubdocumentScrollBy(displacement.x, displacement.y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
synchronized (mTarget.getLock()) {
|
synchronized (mTarget.getLock()) {
|
||||||
scrollBy(displacement.x, displacement.y);
|
scrollBy(displacement.x, displacement.y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ public interface PanZoomTarget {
|
|||||||
public void setAnimationTarget(ImmutableViewportMetrics viewport);
|
public void setAnimationTarget(ImmutableViewportMetrics viewport);
|
||||||
public void setViewportMetrics(ImmutableViewportMetrics viewport);
|
public void setViewportMetrics(ImmutableViewportMetrics viewport);
|
||||||
public void scrollBy(float dx, float dy);
|
public void scrollBy(float dx, float dy);
|
||||||
|
public void onSubdocumentScrollBy(float dx, float dy);
|
||||||
public void panZoomStopped();
|
public void panZoomStopped();
|
||||||
/** This triggers an (asynchronous) viewport update/redraw. */
|
/** This triggers an (asynchronous) viewport update/redraw. */
|
||||||
public void forceRedraw(DisplayPortMetrics displayPort);
|
public void forceRedraw(DisplayPortMetrics displayPort);
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class MenuPopup extends PopupWindow {
|
|||||||
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mPopupWidth - anchor.getWidth() + arrowOffset;
|
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mPopupWidth - anchor.getWidth() + arrowOffset;
|
||||||
} else {
|
} else {
|
||||||
// right align
|
// right align
|
||||||
((LayoutParams) mArrowTop.getLayoutParams()).rightMargin = mArrowMargin;
|
((LayoutParams) mArrowTop.getLayoutParams()).rightMargin = screenWidth - anchorLocation[0] - anchor.getWidth()/2 - arrowWidth/2;
|
||||||
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mArrowMargin;
|
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mArrowMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
mobile/android/base/resources/drawable-hdpi/icon_pageaction.png
Normal file
BIN
mobile/android/base/resources/drawable-hdpi/icon_pageaction.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 B |
BIN
mobile/android/base/resources/drawable-mdpi/icon_pageaction.png
Normal file
BIN
mobile/android/base/resources/drawable-mdpi/icon_pageaction.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 174 B |
BIN
mobile/android/base/resources/drawable-xhdpi/icon_pageaction.png
Normal file
BIN
mobile/android/base/resources/drawable-xhdpi/icon_pageaction.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 289 B |
@@ -103,11 +103,12 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
gecko:autoUpdateTheme="false"/>
|
gecko:autoUpdateTheme="false"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/reader"
|
<org.mozilla.gecko.PageActionLayout android:id="@+id/page_action_layout"
|
||||||
style="@style/AddressBar.ImageButton.Icon"
|
android:layout_width="wrap_content"
|
||||||
android:src="@drawable/reader"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/reader"
|
android:layout_marginRight="@dimen/browser_toolbar_button_padding"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"
|
||||||
|
android:orientation="horizontal"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/stop"
|
<ImageButton android:id="@+id/stop"
|
||||||
style="@style/AddressBar.ImageButton.Icon"
|
style="@style/AddressBar.ImageButton.Icon"
|
||||||
|
|||||||
@@ -129,11 +129,12 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
gecko:autoUpdateTheme="false"/>
|
gecko:autoUpdateTheme="false"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/reader"
|
<org.mozilla.gecko.PageActionLayout android:id="@+id/page_action_layout"
|
||||||
style="@style/AddressBar.ImageButton.Icon"
|
android:layout_width="wrap_content"
|
||||||
android:src="@drawable/reader"
|
android:layout_height="match_parent"
|
||||||
android:contentDescription="@string/reader"
|
android:layout_marginRight="12dp"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"
|
||||||
|
android:orientation="horizontal"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/stop"
|
<ImageButton android:id="@+id/stop"
|
||||||
style="@style/AddressBar.ImageButton.Icon"
|
style="@style/AddressBar.ImageButton.Icon"
|
||||||
|
|||||||
@@ -76,4 +76,8 @@
|
|||||||
<dimen name="validation_message_margin_top">6dp</dimen>
|
<dimen name="validation_message_margin_top">6dp</dimen>
|
||||||
<dimen name="forward_default_offset">-13dip</dimen>
|
<dimen name="forward_default_offset">-13dip</dimen>
|
||||||
<dimen name="addressbar_offset_left">32dp</dimen>
|
<dimen name="addressbar_offset_left">32dp</dimen>
|
||||||
|
|
||||||
|
<!-- PageActionButtons dimensions -->
|
||||||
|
<dimen name="page_action_button_width">32dp</dimen>
|
||||||
|
<dimen name="toast_button_padding">8dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -506,7 +506,7 @@
|
|||||||
<item name="android:textAppearance">?android:textAppearanceSmall</item>
|
<item name="android:textAppearance">?android:textAppearanceSmall</item>
|
||||||
<item name="android:paddingTop">0dp</item>
|
<item name="android:paddingTop">0dp</item>
|
||||||
<item name="android:paddingBottom">0dp</item>
|
<item name="android:paddingBottom">0dp</item>
|
||||||
<item name="android:paddingLeft">8dp</item>
|
<item name="android:paddingLeft">@dimen/toast_button_padding</item>
|
||||||
<item name="android:paddingRight">0dp</item>
|
<item name="android:paddingRight">0dp</item>
|
||||||
<item name="android:layout_marginTop">0dp</item>
|
<item name="android:layout_marginTop">0dp</item>
|
||||||
<item name="android:layout_marginBottom">0dp</item>
|
<item name="android:layout_marginBottom">0dp</item>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user