Merge the last PGO-green inbound changeset to m-c.
@ -74,12 +74,6 @@ void nsAccessNode::LastRelease()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode public
|
||||
|
||||
bool
|
||||
nsAccessNode::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsAccessNode::Shutdown()
|
||||
|
@ -63,11 +63,6 @@ public:
|
||||
*/
|
||||
mozilla::a11y::RootAccessible* RootAccessible() const;
|
||||
|
||||
/**
|
||||
* Initialize the access node object, add it to the cache.
|
||||
*/
|
||||
virtual bool Init();
|
||||
|
||||
/**
|
||||
* Shutdown the access node object.
|
||||
*/
|
||||
|
@ -194,6 +194,12 @@ Accessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
mRoleMapEntry = aRoleMapEntry;
|
||||
}
|
||||
|
||||
bool
|
||||
Accessible::Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Accessible::GetDocument(nsIAccessibleDocument** aDocument)
|
||||
{
|
||||
|
@ -126,6 +126,11 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* Initialize the accessible.
|
||||
*/
|
||||
virtual bool Init();
|
||||
|
||||
/**
|
||||
* Get the description of this accessible.
|
||||
*/
|
||||
|
@ -393,7 +393,6 @@ nsAccessNodeWrap::MakeAccessNode(nsINode *aNode)
|
||||
if (!newNode)
|
||||
return NULL;
|
||||
|
||||
newNode->Init();
|
||||
iNode = static_cast<ISimpleDOMNode*>(newNode);
|
||||
iNode->AddRef();
|
||||
}
|
||||
|
@ -384,9 +384,6 @@ pref("dom.mozAlarms.enabled", true);
|
||||
// WebSettings
|
||||
pref("dom.mozSettings.enabled", true);
|
||||
|
||||
// Ignore X-Frame-Options headers.
|
||||
pref("b2g.ignoreXFrameOptions", true);
|
||||
|
||||
// controls if we want camera support
|
||||
pref("device.camera.enabled", true);
|
||||
pref("media.realtime_decoder.enabled", true);
|
||||
|
@ -240,40 +240,13 @@ int main(int argc, char* argv[])
|
||||
struct rusage initialRUsage;
|
||||
gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
|
||||
#elif defined(XP_WIN)
|
||||
// Don't change the order of these enumeration constants, the order matters
|
||||
// for reporting telemetry data. If new values are added adjust the
|
||||
// STARTUP_USING_PRELOAD_TRIAL histogram.
|
||||
enum PreloadType{ PREFETCH_PRELOAD,
|
||||
PREFETCH_NO_PRELOAD,
|
||||
NO_PREFETCH_PRELOAD,
|
||||
NO_PREFETCH_NO_PRELOAD };
|
||||
PreloadType preloadType;
|
||||
|
||||
IO_COUNTERS ioCounters;
|
||||
gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
|
||||
|
||||
srand(time(NULL));
|
||||
bool shouldUsePreload = rand() % 2 == 0;
|
||||
|
||||
if (IsPrefetchDisabledViaService()) {
|
||||
if (shouldUsePreload) {
|
||||
preloadType = NO_PREFETCH_PRELOAD;
|
||||
} else {
|
||||
preloadType = NO_PREFETCH_NO_PRELOAD;
|
||||
}
|
||||
} else {
|
||||
if (shouldUsePreload) {
|
||||
preloadType = PREFETCH_PRELOAD;
|
||||
} else {
|
||||
preloadType = PREFETCH_NO_PRELOAD;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldUsePreload)
|
||||
#endif
|
||||
{
|
||||
XPCOMGlueEnablePreload();
|
||||
}
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
XPCOMGlueEnablePreload();
|
||||
#endif
|
||||
|
||||
rv = XPCOMGlueStartup(exePath);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -295,11 +268,6 @@ int main(int argc, char* argv[])
|
||||
XRE_SetupDllBlocklist();
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
XRE_TelemetryAccumulate(mozilla::Telemetry::STARTUP_USING_PRELOAD_TRIAL,
|
||||
preloadType);
|
||||
#endif
|
||||
|
||||
if (gotCounters) {
|
||||
#if defined(XP_WIN)
|
||||
XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
|
||||
|
@ -95,6 +95,9 @@
|
||||
#elif MOZ_MSVC_REDIST == 1700
|
||||
@BINPATH@/msvcp110.dll
|
||||
@BINPATH@/msvcr110.dll
|
||||
#ifdef MOZ_METRO
|
||||
@BINPATH@/vccorlib110.dll
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1388,6 +1388,9 @@ xpicleanup@BIN_SUFFIX@
|
||||
#if MOZ_MSVC_REDIST != 1700
|
||||
msvcp110.dll
|
||||
msvcr110.dll
|
||||
#ifdef MOZ_METRO
|
||||
vccorlib110.dll
|
||||
#endif
|
||||
#endif
|
||||
plugins/npnul32.dll
|
||||
#endif
|
||||
|
@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
#downloadsHistory {
|
||||
background: inherit;
|
||||
background: transparent;
|
||||
color: -moz-nativehyperlinktext;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
#downloadsHistory {
|
||||
background: inherit;
|
||||
background: transparent;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
color: hsl(210,100%,75%);
|
||||
|
@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
#downloadsHistory {
|
||||
background: inherit;
|
||||
background: transparent;
|
||||
color: -moz-nativehyperlinktext;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -68,6 +68,10 @@ REDIST_FILES = \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_METRO
|
||||
REDIST_FILES += vccorlib110.dll
|
||||
endif
|
||||
|
||||
ifdef REDIST_FILES
|
||||
libs-preqs = \
|
||||
$(call mkdir_deps,$(FINAL_TARGET)) \
|
||||
|
@ -303,8 +303,6 @@ protected:
|
||||
// True if this is parser is a fragment parser or an HTML DOMParser.
|
||||
// XML DOMParser leaves this to false for now!
|
||||
PRUint8 mRunsToCompletion : 1;
|
||||
// True to call prevent script execution in the fragment mode.
|
||||
PRUint8 mPreventScriptExecution : 1;
|
||||
|
||||
//
|
||||
// -- Can interrupt parsing members --
|
||||
|
@ -9542,7 +9542,8 @@ nsDocument::UpdateVisibilityState()
|
||||
if (oldState != mVisibilityState) {
|
||||
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
|
||||
NS_LITERAL_STRING("mozvisibilitychange"),
|
||||
false, false);
|
||||
/* bubbles = */ true,
|
||||
/* cancelable = */ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1377,6 +1377,12 @@ nsFrameLoader::ShouldUseRemoteProcess()
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're inside a content process, don't use a remote process for this
|
||||
// frame; it won't work properly until bug 761935 is fixed.
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
|
||||
// fall back to the default.
|
||||
if (OwnerIsBrowserFrame() &&
|
||||
|
@ -1243,26 +1243,6 @@ NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(error, mOnErrorListener)
|
||||
NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(message, mOnMessageListener)
|
||||
NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(close, mOnCloseListener)
|
||||
|
||||
static bool
|
||||
ContainsUnpairedSurrogates(const nsAString& aData)
|
||||
{
|
||||
// Check for unpaired surrogates.
|
||||
PRUint32 i, length = aData.Length();
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (NS_IS_LOW_SURROGATE(aData[i])) {
|
||||
return true;
|
||||
}
|
||||
if (NS_IS_HIGH_SURROGATE(aData[i])) {
|
||||
++i;
|
||||
if (i == length || !NS_IS_LOW_SURROGATE(aData[i])) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebSocket::Send(nsIVariant *aData, JSContext *aCx)
|
||||
{
|
||||
@ -1373,66 +1353,13 @@ nsWebSocket::GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsString text;
|
||||
text.Adopt(data, len);
|
||||
|
||||
if (ContainsUnpairedSurrogates(text)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
rv = ConvertTextToUTF8(text, aStringOut);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
CopyUTF16toUTF8(text, aStringOut);
|
||||
|
||||
aIsBinary = false;
|
||||
aOutgoingLength = aStringOut.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebSocket::ConvertTextToUTF8(const nsString& aMessage, nsCString& buf)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> converter;
|
||||
rv = ccm->GetUnicodeEncoder("UTF-8", getter_AddRefs(converter));
|
||||
SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);
|
||||
|
||||
rv = converter->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
|
||||
nsnull, UTF_8_REPLACEMENT_CHAR);
|
||||
SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);
|
||||
|
||||
PRInt32 inLen = aMessage.Length();
|
||||
PRInt32 maxLen;
|
||||
rv = converter->GetMaxLength(aMessage.BeginReading(), inLen, &maxLen);
|
||||
SUCCESS_OR_FAIL_WEBSOCKET(rv, rv);
|
||||
|
||||
buf.SetLength(maxLen);
|
||||
TRUE_OR_FAIL_WEBSOCKET(buf.Length() == static_cast<PRUint32>(maxLen),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
char* start = buf.BeginWriting();
|
||||
|
||||
PRInt32 outLen = maxLen;
|
||||
rv = converter->Convert(aMessage.BeginReading(), &inLen, start, &outLen);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRInt32 outLen2 = maxLen - outLen;
|
||||
rv = converter->Finish(start + outLen, &outLen2);
|
||||
outLen += outLen2;
|
||||
}
|
||||
if (NS_FAILED(rv) || rv == NS_ERROR_UENC_NOMAPPING) {
|
||||
// Yes, NS_ERROR_UENC_NOMAPPING is a success code
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
buf.SetLength(outLen);
|
||||
TRUE_OR_FAIL_WEBSOCKET(buf.Length() == static_cast<PRUint32>(outLen),
|
||||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
|
||||
{
|
||||
@ -1449,9 +1376,6 @@ nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
|
||||
|
||||
nsCAutoString closeReason;
|
||||
if (argc >= 2) {
|
||||
if (ContainsUnpairedSurrogates(reason)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
CopyUTF16toUTF8(reason, closeReason);
|
||||
|
||||
// The API requires the UTF-8 string to be 123 or less bytes
|
||||
@ -1581,8 +1505,11 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
// the constructor should throw a SYNTAX_ERROR only if it fails to parse the
|
||||
// url parameter, so we don't care about the EstablishConnection result.
|
||||
EstablishConnection();
|
||||
// url parameter, so don't throw if EstablishConnection fails, and call
|
||||
// onerror/onclose asynchronously
|
||||
if (NS_FAILED(EstablishConnection())) {
|
||||
FailConnection(nsIWebSocketChannel::CLOSE_ABNORMAL);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -97,8 +97,6 @@ protected:
|
||||
const PRUnichar **aFormatStrings,
|
||||
PRUint32 aFormatStringsLen);
|
||||
|
||||
nsresult ConvertTextToUTF8(const nsString& aMessage, nsCString& buf);
|
||||
|
||||
// Get msg info out of JS variable being sent (string, arraybuffer, blob)
|
||||
nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
|
||||
nsCOMPtr<nsIInputStream> &aStreamOut,
|
||||
|
@ -71,7 +71,13 @@ def web_socket_transfer_data(request):
|
||||
resp = "server data"
|
||||
msgutil.send_message(request, resp.decode('utf-8'))
|
||||
elif request.ws_protocol == "test-12":
|
||||
msgutil.close_connection(request)
|
||||
msg = msgutil.receive_message(request)
|
||||
if msg == u'a\ufffdb':
|
||||
# converted unpaired surrogate in UTF-16 to UTF-8 OK
|
||||
msgutil.send_message(request, "SUCCESS")
|
||||
else:
|
||||
msgutil.send_message(request, "FAIL got '" + msg
|
||||
+ "' instead of string with replacement char'")
|
||||
elif request.ws_protocol == "test-13":
|
||||
# first one binary message containing the byte 0x61 ('a')
|
||||
request.connection.write('\xff\x01\x61')
|
||||
|
@ -30,7 +30,7 @@
|
||||
* 9. client closes the connection before the ws connection is established;
|
||||
* 10. client sends a message before the ws connection is established;
|
||||
* 11. a simple hello echo;
|
||||
* 12. client sends a message with bad bytes;
|
||||
* 12. client sends a message containing unpaired surrogates
|
||||
* 13. server sends an invalid message;
|
||||
* 14. server sends the close frame, it doesn't close the tcp connection and
|
||||
* it keeps sending normal ws messages;
|
||||
@ -485,29 +485,37 @@ function test11()
|
||||
|
||||
function test12()
|
||||
{
|
||||
ok(true,"test 12");
|
||||
|
||||
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-12");
|
||||
ws.onopen = function()
|
||||
{
|
||||
try {
|
||||
// send an unpaired surrogate
|
||||
ws.send(String.fromCharCode(0xD800));
|
||||
ok(false, "couldn't send an unpaired surrogate!");
|
||||
ws._gotMessage = false;
|
||||
ws.send("a\ud800b");
|
||||
ok(true, "ok to send an unpaired surrogate");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "couldn't send an unpaired surrogate!");
|
||||
ok(false, "shouldn't fail any more when sending an unpaired surrogate!");
|
||||
}
|
||||
ws.close();
|
||||
}
|
||||
|
||||
// there isnt really a server implementation of test-12, so just
|
||||
// ignore an error
|
||||
ws.onerror = function()
|
||||
{
|
||||
}
|
||||
ws.onmessage = function(msg)
|
||||
{
|
||||
ok(msg.data == "SUCCESS", "Unpaired surrogate in UTF-16 not converted in test-12");
|
||||
ws._gotMessage = true;
|
||||
// Must support unpaired surrogates in close reason, too
|
||||
ws.close(1000, "a\ud800b");
|
||||
}
|
||||
|
||||
ws.onclose = function(e)
|
||||
{
|
||||
ok(ws.readyState == 3, "onclose bad readyState in test-12!");
|
||||
ok(ws._gotMessage, "didn't receive message!");
|
||||
shouldCloseCleanly(e);
|
||||
ok(e.code == 1000, "test 12 got wrong close code: " + e.code);
|
||||
ok(e.reason == "a\ufffdb", "test 11 didn't get replacement char in close reason: " + e.reason);
|
||||
doTest(13);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function test13()
|
||||
|
@ -308,6 +308,10 @@ public:
|
||||
mList = nsnull;
|
||||
}
|
||||
|
||||
bool IsEmpty() const {
|
||||
return !mList || mList->IsEmpty();
|
||||
}
|
||||
|
||||
PRUint32 Length() const {
|
||||
return mList ? mList->Length() : 0;
|
||||
}
|
||||
|
@ -182,6 +182,8 @@ protected:
|
||||
PRUint8 mPrettyPrintHasFactoredElements : 1;
|
||||
PRUint8 mPrettyPrinting : 1; // True if we called PrettyPrint() and it
|
||||
// decided we should in fact prettyprint.
|
||||
// True to call prevent script execution in the fragment mode.
|
||||
PRUint8 mPreventScriptExecution : 1;
|
||||
|
||||
nsTArray<StackNode> mContentStack;
|
||||
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static bool sIgnoreXFrameOptions = false;
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsDSURIContentListener: Object Management
|
||||
//*****************************************************************************
|
||||
@ -30,18 +28,6 @@ nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell),
|
||||
mParentContentListener(nsnull)
|
||||
{
|
||||
static bool initializedPrefCache = false;
|
||||
|
||||
// Set up a pref cache for sIgnoreXFrameOptions, if we haven't already.
|
||||
if (NS_UNLIKELY(!initializedPrefCache)) {
|
||||
// Lock the pref so that the user's changes to it, if any, are ignored.
|
||||
nsIPrefBranch *root = Preferences::GetRootBranch();
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Content)
|
||||
root->LockPref("b2g.ignoreXFrameOptions");
|
||||
|
||||
Preferences::AddBoolVarCache(&sIgnoreXFrameOptions, "b2g.ignoreXFrameOptions");
|
||||
initializedPrefCache = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsDSURIContentListener::~nsDSURIContentListener()
|
||||
@ -292,8 +278,10 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
if (!thisWindow)
|
||||
return true;
|
||||
|
||||
// GetScriptableTop, not GetTop, because we want this to respect
|
||||
// <iframe mozbrowser> boundaries.
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
thisWindow->GetTop(getter_AddRefs(topWindow));
|
||||
thisWindow->GetScriptableTop(getter_AddRefs(topWindow));
|
||||
|
||||
// if the document is in the top window, it's not in a frame.
|
||||
if (thisWindow == topWindow)
|
||||
@ -316,10 +304,19 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Traverse up the parent chain to the top docshell that doesn't have
|
||||
// a system principal
|
||||
// Traverse up the parent chain and stop when we see a docshell whose
|
||||
// parent has a system principal, or a docshell corresponding to
|
||||
// <iframe mozbrowser>.
|
||||
while (NS_SUCCEEDED(curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) &&
|
||||
parentDocShellItem) {
|
||||
|
||||
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
|
||||
bool browserFrame = false;
|
||||
curDocShell->GetIsBrowserFrame(&browserFrame);
|
||||
if (browserFrame) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool system = false;
|
||||
topDoc = do_GetInterface(parentDocShellItem);
|
||||
if (topDoc) {
|
||||
@ -369,11 +366,6 @@ bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
|
||||
// in the request (comma-separated in a header, multiple headers, etc).
|
||||
bool nsDSURIContentListener::CheckFrameOptions(nsIRequest *request)
|
||||
{
|
||||
// If X-Frame-Options checking is disabled, return true unconditionally.
|
||||
if (sIgnoreXFrameOptions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
||||
if (!httpChannel) {
|
||||
return true;
|
||||
|
@ -41,6 +41,15 @@ MOCHITEST_FILES = \
|
||||
test_browserElement_inproc_SetVisible.html \
|
||||
browserElement_KeyEvents.js \
|
||||
test_browserElement_inproc_KeyEvents.html \
|
||||
browserElement_XFrameOptions.js \
|
||||
test_browserElement_inproc_XFrameOptions.html \
|
||||
file_browserElement_XFrameOptions.sjs \
|
||||
browserElement_XFrameOptionsDeny.js \
|
||||
test_browserElement_inproc_XFrameOptionsDeny.html \
|
||||
file_browserElement_XFrameOptionsDeny.html \
|
||||
browserElement_XFrameOptionsSameOrigin.js \
|
||||
test_browserElement_inproc_XFrameOptionsSameOrigin.html \
|
||||
file_browserElement_XFrameOptionsSameOrigin.html \
|
||||
browserElement_Alert.js \
|
||||
test_browserElement_inproc_Alert.html \
|
||||
browserElement_AlertInFrame.js \
|
||||
@ -53,6 +62,9 @@ MOCHITEST_FILES = \
|
||||
test_browserElement_inproc_PromptConfirm.html \
|
||||
browserElement_Close.js \
|
||||
test_browserElement_inproc_Close.html \
|
||||
browserElement_CloseFromOpener.js \
|
||||
test_browserElement_inproc_CloseFromOpener.html \
|
||||
file_browserElement_CloseFromOpener.html \
|
||||
browserElement_OpenWindow.js \
|
||||
test_browserElement_inproc_OpenWindow.html \
|
||||
file_browserElement_Open1.html \
|
||||
@ -85,11 +97,15 @@ MOCHITEST_FILES += \
|
||||
test_browserElement_oop_GetScreenshot.html \
|
||||
test_browserElement_oop_SetVisible.html \
|
||||
test_browserElement_oop_KeyEvents.html \
|
||||
test_browserElement_oop_XFrameOptions.html \
|
||||
test_browserElement_oop_XFrameOptionsDeny.html \
|
||||
test_browserElement_oop_XFrameOptionsSameOrigin.html \
|
||||
test_browserElement_oop_Alert.html \
|
||||
test_browserElement_oop_AlertInFrame.html \
|
||||
test_browserElement_oop_PromptCheck.html \
|
||||
test_browserElement_oop_PromptConfirm.html \
|
||||
test_browserElement_oop_Close.html \
|
||||
test_browserElement_oop_CloseFromOpener.html \
|
||||
test_browserElement_oop_OpenWindow.html \
|
||||
test_browserElement_oop_OpenWindowInFrame.html \
|
||||
test_browserElement_oop_OpenWindowRejected.html \
|
||||
|
@ -0,0 +1,34 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 764718 - Test that window.close() works from the opener window.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addToWhitelist();
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
iframe.addEventListener('mozbrowseropenwindow', function(e) {
|
||||
ok(true, "got openwindow event.");
|
||||
document.body.appendChild(e.detail.frameElement);
|
||||
|
||||
e.detail.frameElement.addEventListener("mozbrowserclose", function(e) {
|
||||
ok(true, "got mozbrowserclose event.");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// file_browserElement_CloseFromOpener opens a new window and then calls
|
||||
// close() on it.
|
||||
iframe.src = "file_browserElement_CloseFromOpener.html";
|
||||
}
|
||||
|
||||
runTest();
|
@ -115,7 +115,13 @@ function runTest() {
|
||||
}
|
||||
}
|
||||
|
||||
var gotError = false;
|
||||
function errorTriggered(msg) {
|
||||
if (gotError) {
|
||||
return;
|
||||
}
|
||||
|
||||
gotError = true;
|
||||
ok(true, 'An error in the callback triggers window.onerror');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 770239 - Test that we can load pages with X-Frame-Options: Deny inside
|
||||
// <iframe mozbrowser>.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addToWhitelist();
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
// The page we load will fire an alert when it successfully loads.
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
ok(true, "Got alert");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = 'file_browserElement_XFrameOptions.sjs?DENY';
|
||||
}
|
||||
|
||||
runTest();
|
@ -0,0 +1,55 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 770239 - Test that X-Frame-Options will correctly block a page inside a
|
||||
// subframe of <iframe mozbrowser>.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var initialScreenshot;
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addToWhitelist();
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
// Our child will create two iframes, so make sure this iframe is big enough
|
||||
// to show both of them without scrolling, so taking a screenshot gets both
|
||||
// frames.
|
||||
iframe.height = '1000px';
|
||||
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
switch (e.detail.message) {
|
||||
case 'step 1':
|
||||
// Make the page wait for us to unblock it (which we do after we finish
|
||||
// taking the screenshot).
|
||||
e.preventDefault();
|
||||
|
||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
||||
initialScreenshot = sshot.target.result;
|
||||
e.detail.unblock();
|
||||
};
|
||||
break;
|
||||
case 'step 2':
|
||||
// The page has now attempted to load the X-Frame-Options page; take
|
||||
// another screenshot.
|
||||
iframe.getScreenshot().onsuccess = function(sshot) {
|
||||
is(sshot.target.result, initialScreenshot, "Screenshots should be identical");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Load this page from a different origin than ourselves. This page will, in
|
||||
// turn, load a child from mochi.test:8888, our origin, with X-Frame-Options:
|
||||
// SAMEORIGIN. That load should be denied.
|
||||
iframe.src = 'http://example.com/tests/dom/browser-element/mochitest/file_browserElement_XFrameOptionsDeny.html';
|
||||
}
|
||||
|
||||
runTest();
|
@ -0,0 +1,29 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 770239 - Load an X-Frame-Options: SAMEORIGIN page inside an <iframe>
|
||||
// inside <iframe mozbrowser>. The two iframes will have the same origin, but
|
||||
// this page will be of a different origin. The load should succeed.
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addToWhitelist();
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
|
||||
// The innermost page we load will fire an alert when it successfully loads.
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
ok(true, "Got alert");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = 'http://example.com/tests/dom/browser-element/mochitest/file_browserElement_XFrameOptionsSameOrigin.html';
|
||||
}
|
||||
|
||||
runTest();
|
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var win = window.open('file_empty.html');
|
||||
win.close();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,9 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("X-Frame-Options", request.queryString, false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// Tests rely on this page not being entirely blank, because they take
|
||||
// screenshots to determine whether this page was loaded.
|
||||
response.write("<html><body>XFrameOptions test<script>alert('finish')</script></body></html>");
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<!-- Try to load in a frame a page which sends "X-Frame-Options: DENY", and a
|
||||
cross-origin page which sends "X-Frame-Options: SAMEORIGIN". -->
|
||||
|
||||
<script>
|
||||
|
||||
// Make sure these iframes aren't too tall; they both need to fit inside the
|
||||
// iframe this page is contained in, without scrolling, in order for the test's
|
||||
// screenshots to work properly.
|
||||
|
||||
var iframe1 = document.createElement('iframe');
|
||||
iframe1.height = '300px';
|
||||
var iframe2 = document.createElement('iframe');
|
||||
iframe2.height = '300px';
|
||||
document.body.appendChild(iframe1);
|
||||
document.body.appendChild(iframe2);
|
||||
|
||||
// This causes our embedder to take a screenshot (and blocks until the
|
||||
// screenshot is completed).
|
||||
alert('step 1');
|
||||
|
||||
// Wait for both iframes to load.
|
||||
|
||||
var iframe1Loaded = false;
|
||||
iframe1.addEventListener('load', function iframe1Load() {
|
||||
iframe1.removeEventListener('load', iframe1Load);
|
||||
iframe1Loaded = true;
|
||||
waitForBothLoads();
|
||||
});
|
||||
|
||||
var iframe2Loaded = false;
|
||||
iframe2.addEventListener('load', function iframe2Load() {
|
||||
iframe2.removeEventListener('load', iframe2Load);
|
||||
iframe2Loaded = true;
|
||||
waitForBothLoads();
|
||||
});
|
||||
|
||||
function waitForBothLoads() {
|
||||
if (iframe1Loaded && iframe2Loaded) {
|
||||
setTimeout(function() {
|
||||
// This causes our embedder to take another screenshot.
|
||||
alert('step 2');
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
iframe1.src = 'file_browserElement_XFrameOptions.sjs?DENY';
|
||||
|
||||
// Load iframe2 with the origin of our parent. Since we have a different
|
||||
// origin and are inside <iframe mozbrowser>, this should not load.
|
||||
iframe2.src = 'http://mochi.test:8888/tests/dom/browser-element/mochitest/file_browserElement_XFrameOptions.sjs?SAMEORIGIN';
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<iframe src='file_browserElement_XFrameOptions.sjs?SAMEORIGIN'></iframe>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=757182
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 757182</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=757182">Mozilla Bug 757182</a>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="browserElement_CloseFromOpener.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptions.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsDeny.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsSameOrigin.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=757182
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 757182</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=757182">Mozilla Bug 757182</a>
|
||||
|
||||
<script type="application/javascript;version=1.7" src="browserElement_CloseFromOpener.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptions.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsDeny.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 770239</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_XFrameOptionsSameOrigin.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -124,7 +124,7 @@ FileHandle::Open(const nsAString& aMode,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FileHandle::GetFile(nsIDOMFileRequest** _retval)
|
||||
FileHandle::GetFile(nsIDOMDOMRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
@ -137,19 +137,21 @@ FileHandle::GetFile(nsIDOMFileRequest** _retval)
|
||||
LockedFile::Create(this, LockedFile::READ_ONLY, LockedFile::PARALLEL);
|
||||
NS_ENSURE_TRUE(lockedFile, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<FileRequest> fileRequest =
|
||||
FileRequest::Create(GetOwner(), lockedFile);
|
||||
nsRefPtr<FileRequest> request =
|
||||
FileRequest::Create(GetOwner(), lockedFile, false);
|
||||
|
||||
nsRefPtr<MetadataParameters> params = new MetadataParameters();
|
||||
params->Init(true, false);
|
||||
|
||||
nsRefPtr<GetFileHelper> helper =
|
||||
new GetFileHelper(lockedFile, fileRequest, params, this);
|
||||
new GetFileHelper(lockedFile, request, params, this);
|
||||
|
||||
nsresult rv = helper->Enqueue();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
|
||||
|
||||
fileRequest.forget(_retval);
|
||||
nsCOMPtr<nsIDOMDOMRequest> result = static_cast<DOMRequest*>(request);
|
||||
result.forget(_retval);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
USING_FILE_NAMESPACE
|
||||
|
||||
FileRequest::FileRequest(nsIDOMWindow* aWindow)
|
||||
: DOMRequest(aWindow)
|
||||
: DOMRequest(aWindow), mIsFileRequest(true)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
@ -31,12 +31,14 @@ FileRequest::~FileRequest()
|
||||
// static
|
||||
already_AddRefed<FileRequest>
|
||||
FileRequest::Create(nsIDOMWindow* aOwner,
|
||||
LockedFile* aLockedFile)
|
||||
LockedFile* aLockedFile,
|
||||
bool aIsFileRequest)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsRefPtr<FileRequest> request = new FileRequest(aOwner);
|
||||
request->mLockedFile = aLockedFile;
|
||||
request->mIsFileRequest = aIsFileRequest;
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
@ -125,8 +127,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileRequest, DOMRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFileRequest)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileRequest)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFileRequest, mIsFileRequest)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(FileRequest, mIsFileRequest)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(DOMRequest, !mIsFileRequest)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(FileRequest, DOMRequest)
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileRequest, DOMRequest)
|
||||
|
||||
static already_AddRefed<FileRequest>
|
||||
Create(nsIDOMWindow* aOwner, LockedFile* aLockedFile);
|
||||
Create(nsIDOMWindow* aOwner, LockedFile* aLockedFile, bool aIsFileRequest);
|
||||
|
||||
// nsIDOMEventTarget
|
||||
virtual nsresult
|
||||
@ -55,6 +55,7 @@ private:
|
||||
RootResultVal();
|
||||
|
||||
nsRefPtr<LockedFile> mLockedFile;
|
||||
bool mIsFileRequest;
|
||||
|
||||
NS_DECL_EVENT_HANDLER(progress)
|
||||
};
|
||||
|
@ -439,7 +439,7 @@ already_AddRefed<FileRequest>
|
||||
LockedFile::GenerateFileRequest()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
return FileRequest::Create(GetOwner(), this);
|
||||
return FileRequest::Create(GetOwner(), this, true);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -18,11 +18,11 @@ class FileInfo;
|
||||
|
||||
[ptr] native FileInfo(mozilla::dom::indexedDB::FileInfo);
|
||||
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMEventListener;
|
||||
interface nsIDOMFileRequest;
|
||||
interface nsIDOMLockedFile;
|
||||
|
||||
[scriptable, builtinclass, uuid(0dc9c73c-4e44-4430-8898-85f61a70b1d2)]
|
||||
[scriptable, builtinclass, uuid(882ad3d0-6fb1-4841-8e17-0ba17b11edc8)]
|
||||
interface nsIDOMFileHandle : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
@ -34,7 +34,7 @@ interface nsIDOMFileHandle : nsISupports
|
||||
nsIDOMLockedFile
|
||||
open([optional /* "readonly" */] in DOMString mode);
|
||||
|
||||
nsIDOMFileRequest
|
||||
nsIDOMDOMRequest
|
||||
getFile();
|
||||
|
||||
[notxpcom]
|
||||
|
@ -55,6 +55,10 @@
|
||||
is(e.name, "LockedFileInactiveError", "Good error.");
|
||||
is(e.code, 0, "Good error code.");
|
||||
}
|
||||
|
||||
if (resultBuffer2) {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
|
||||
let reader2 = new FileReader();
|
||||
@ -63,10 +67,23 @@
|
||||
reader2.onload = function(event)
|
||||
{
|
||||
resultBuffer2 = event.target.result;
|
||||
|
||||
let reader = new FileReader();
|
||||
try {
|
||||
reader.readAsArrayBuffer(file);
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof DOMException, "Got exception.");
|
||||
is(e.name, "LockedFileInactiveError", "Good error.");
|
||||
is(e.code, 0, "Good error code.");
|
||||
}
|
||||
|
||||
if (resultBuffer1) {
|
||||
testGenerator.next();
|
||||
}
|
||||
}
|
||||
|
||||
lockedFile = event.target.lockedFile;
|
||||
lockedFile.oncomplete = grabEventAndContinueHandler;
|
||||
yield;
|
||||
|
||||
ok(compareBuffers(resultBuffer1, testBuffer), "Correct data");
|
||||
|
@ -59,9 +59,6 @@
|
||||
|
||||
let file = event.target.result;
|
||||
|
||||
lockedFile = event.target.lockedFile;
|
||||
is(lockedFile.active, true, "Correct active state");
|
||||
|
||||
let trans = db.transaction([objectStoreName], READ_WRITE);
|
||||
let objectStore = trans.objectStore(objectStoreName);
|
||||
|
||||
@ -69,7 +66,17 @@
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
||||
is(lockedFile.active, false, "Correct open state");
|
||||
// At this moment, the file should not be readable anymore.
|
||||
let reader = new FileReader();
|
||||
try {
|
||||
reader.readAsArrayBuffer(file);
|
||||
ok(false, "Should have thrown!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(e instanceof DOMException, "Got exception.");
|
||||
is(e.name, "LockedFileInactiveError", "Good error.");
|
||||
is(e.code, 0, "Good error code.");
|
||||
}
|
||||
|
||||
request = objectStore.get(42);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -244,3 +244,8 @@ void MaemoLocationProvider::Update(nsIDOMGeoPosition* aPosition)
|
||||
mCallback->Update(aPosition);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MaemoLocationProvider::SetHighAccuracy(bool)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ ifdef MOZ_PLATFORM_MAEMO
|
||||
CPPSRCS += nsHapticFeedback.cpp
|
||||
LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) \
|
||||
$(NULL)
|
||||
endif
|
||||
ifdef MOZ_ENABLE_QTMOBILITY
|
||||
MOCSRCS += moc_QTMLocationProvider.cpp
|
||||
CPPSRCS += $(MOCSRCS) \
|
||||
@ -41,6 +42,5 @@ LOCAL_INCLUDES += $(MOZ_QT_CFLAGS) \
|
||||
-I$(topsrcdir)/dom/src/geolocation \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -419,6 +419,10 @@ Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
|
||||
} else {
|
||||
mActiveCall = modifiedCall;
|
||||
}
|
||||
} else {
|
||||
if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
|
||||
mActiveCall = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Change state.
|
||||
|
@ -232,12 +232,6 @@ TelephonyCall::HangUp()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mCallState == nsIRadioInterfaceLayer::CALL_STATE_HOLDING ||
|
||||
mCallState == nsIRadioInterfaceLayer::CALL_STATE_HELD) {
|
||||
NS_WARNING("HangUp on non-active call ignored!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = mCallState == nsIRadioInterfaceLayer::CALL_STATE_INCOMING ?
|
||||
mTelephony->RIL()->RejectCall(mCallIndex) :
|
||||
mTelephony->RIL()->HangUp(mCallIndex);
|
||||
|
@ -8,6 +8,8 @@ qemu = true
|
||||
[test_outgoing_answer_hangup.js]
|
||||
[test_incoming_answer_hangup_oncallschanged.js]
|
||||
[test_outgoing_answer_hangup_oncallschanged.js]
|
||||
[test_outgoing_hangup_alerting.js]
|
||||
[test_outgoing_hangup_held.js]
|
||||
# Bug 761533
|
||||
#[test_outgoing_badNumber.js]
|
||||
#expectedfailure = true
|
||||
|
@ -0,0 +1,89 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 10000;
|
||||
|
||||
const WHITELIST_PREF = "dom.telephony.app.phone.url";
|
||||
SpecialPowers.setCharPref(WHITELIST_PREF, window.location.href);
|
||||
|
||||
let telephony = window.navigator.mozTelephony;
|
||||
let number = "5555552368";
|
||||
let outgoing;
|
||||
let calls;
|
||||
|
||||
function verifyInitialState() {
|
||||
log("Verifying initial state.");
|
||||
ok(telephony);
|
||||
is(telephony.active, null);
|
||||
ok(telephony.calls);
|
||||
is(telephony.calls.length, 0);
|
||||
calls = telephony.calls;
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Initial call list: " + result);
|
||||
is(result[0], "OK");
|
||||
dial();
|
||||
});
|
||||
}
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call.");
|
||||
|
||||
outgoing = telephony.dial(number);
|
||||
ok(outgoing);
|
||||
is(outgoing.number, number);
|
||||
is(outgoing.state, "dialing");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
//ok(telephony.calls === calls); // bug 717414
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoing);
|
||||
|
||||
outgoing.onalerting = function onalerting(event) {
|
||||
log("Received 'alerting' call event.");
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : ringing");
|
||||
is(result[1], "OK");
|
||||
hangUp();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function hangUp() {
|
||||
log("Hang up the outgoing call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
|
||||
outgoing.ondisconnecting = function ondisconnecting(event) {
|
||||
log("Received 'disconnecting' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
outgoing.ondisconnected = function ondisconnected(event) {
|
||||
log("Received 'disconnected' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "OK");
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
|
||||
outgoing.hangUp();
|
||||
};
|
||||
|
||||
function cleanUp() {
|
||||
SpecialPowers.clearUserPref(WHITELIST_PREF);
|
||||
finish();
|
||||
}
|
||||
|
||||
verifyInitialState();
|
136
dom/telephony/test/marionette/test_outgoing_hangup_held.js
Normal file
@ -0,0 +1,136 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 10000;
|
||||
|
||||
const WHITELIST_PREF = "dom.telephony.app.phone.url";
|
||||
SpecialPowers.setCharPref(WHITELIST_PREF, window.location.href);
|
||||
|
||||
let telephony = window.navigator.mozTelephony;
|
||||
let number = "5555552368";
|
||||
let outgoing;
|
||||
let calls;
|
||||
|
||||
function verifyInitialState() {
|
||||
log("Verifying initial state.");
|
||||
ok(telephony);
|
||||
is(telephony.active, null);
|
||||
ok(telephony.calls);
|
||||
is(telephony.calls.length, 0);
|
||||
calls = telephony.calls;
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Initial call list: " + result);
|
||||
is(result[0], "OK");
|
||||
dial();
|
||||
});
|
||||
}
|
||||
|
||||
function dial() {
|
||||
log("Make an outgoing call.");
|
||||
|
||||
outgoing = telephony.dial(number);
|
||||
ok(outgoing);
|
||||
is(outgoing.number, number);
|
||||
is(outgoing.state, "dialing");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
//ok(telephony.calls === calls); // bug 717414
|
||||
is(telephony.calls.length, 1);
|
||||
is(telephony.calls[0], outgoing);
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : unknown");
|
||||
is(result[1], "OK");
|
||||
answer();
|
||||
});
|
||||
}
|
||||
|
||||
function answer() {
|
||||
log("Answering the outgoing call.");
|
||||
|
||||
// We get no "connecting" event when the remote party answers the call.
|
||||
|
||||
outgoing.onconnected = function onconnected(event) {
|
||||
log("Received 'connected' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "connected");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : active");
|
||||
is(result[1], "OK");
|
||||
hold();
|
||||
});
|
||||
};
|
||||
runEmulatorCmd("gsm accept " + number);
|
||||
};
|
||||
|
||||
function hold() {
|
||||
log("Holding the outgoing call.");
|
||||
|
||||
outgoing.onholding = function onholding(event) {
|
||||
log("Received 'holding' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "holding");
|
||||
|
||||
is(outgoing, telephony.active);
|
||||
};
|
||||
|
||||
outgoing.onheld = function onheld(event) {
|
||||
log("Received 'held' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "held");
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 1);
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "outbound to " + number + " : held");
|
||||
is(result[1], "OK");
|
||||
hangUp();
|
||||
});
|
||||
};
|
||||
outgoing.hold();
|
||||
}
|
||||
|
||||
function hangUp() {
|
||||
log("Hanging up the outgoing call.");
|
||||
|
||||
let gotDisconnecting = false;
|
||||
outgoing.ondisconnecting = function ondisconnecting(event) {
|
||||
log("Received disconnecting call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "disconnecting");
|
||||
gotDisconnecting = true;
|
||||
};
|
||||
|
||||
outgoing.ondisconnected = function ondisconnected(event) {
|
||||
log("Received 'disconnected' call event.");
|
||||
is(outgoing, event.call);
|
||||
is(outgoing.state, "disconnected");
|
||||
ok(gotDisconnecting);
|
||||
|
||||
is(telephony.active, null);
|
||||
is(telephony.calls.length, 0);
|
||||
|
||||
runEmulatorCmd("gsm list", function(result) {
|
||||
log("Call list is now: " + result);
|
||||
is(result[0], "OK");
|
||||
cleanUp();
|
||||
});
|
||||
};
|
||||
|
||||
outgoing.hangUp();
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
SpecialPowers.clearUserPref(WHITELIST_PREF);
|
||||
finish();
|
||||
}
|
||||
|
||||
verifyInitialState();
|
21
editor/libeditor/base/crashtests/771749.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var root = document.documentElement;
|
||||
root.contentEditable = "true";
|
||||
document.removeChild(root);
|
||||
document.appendChild(root);
|
||||
document.execCommand("insertunorderedlist", false, null);
|
||||
document.execCommand("inserthtml", false, "<span></span>");
|
||||
document.execCommand("outdent", false, null);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -15,3 +15,4 @@ load 766360.html
|
||||
load 766413.html
|
||||
load 766845.xhtml
|
||||
load 768765.html
|
||||
needs-focus load 771749.html
|
||||
|
@ -617,19 +617,7 @@ NS_IMETHODIMP
|
||||
nsEditor::DoTransaction(nsITransaction* aTxn)
|
||||
{
|
||||
if (mPlaceHolderBatch && !mPlaceHolderTxn) {
|
||||
// it's pretty darn amazing how many different types of pointers this
|
||||
// transaction goes through here. I bet this is a record.
|
||||
|
||||
// We start off with an EditTxn since that's what the factory returns.
|
||||
nsRefPtr<EditTxn> editTxn = new PlaceholderTxn();
|
||||
|
||||
// Then we QI to an nsIAbsorbingTransaction to get at placeholder
|
||||
// functionality
|
||||
nsCOMPtr<nsIAbsorbingTransaction> plcTxn;
|
||||
editTxn->QueryInterface(NS_GET_IID(nsIAbsorbingTransaction),
|
||||
getter_AddRefs(plcTxn));
|
||||
// have to use line above instead of "plcTxn = do_QueryInterface(editTxn);"
|
||||
// due to our broken interface model for transactions.
|
||||
nsCOMPtr<nsIAbsorbingTransaction> plcTxn = new PlaceholderTxn();
|
||||
|
||||
// save off weak reference to placeholder txn
|
||||
mPlaceHolderTxn = do_GetWeakReference(plcTxn);
|
||||
@ -637,8 +625,7 @@ nsEditor::DoTransaction(nsITransaction* aTxn)
|
||||
// placeholder txn took ownership of this pointer
|
||||
mSelState = nsnull;
|
||||
|
||||
// finally we QI to an nsITransaction since that's what DoTransaction()
|
||||
// expects
|
||||
// QI to an nsITransaction since that's what DoTransaction() expects
|
||||
nsCOMPtr<nsITransaction> theTxn = do_QueryInterface(plcTxn);
|
||||
// we will recurse, but will not hit this case in the nested call
|
||||
DoTransaction(theTxn);
|
||||
@ -3124,6 +3111,7 @@ already_AddRefed<nsIDOMNode>
|
||||
nsEditor::GetNodeLocation(nsIDOMNode* aChild, PRInt32* outOffset)
|
||||
{
|
||||
MOZ_ASSERT(aChild && outOffset);
|
||||
NS_ENSURE_TRUE(aChild && outOffset, nsnull);
|
||||
*outOffset = -1;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
|
@ -13,8 +13,8 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
namespace layers {
|
||||
|
||||
class BasicCanvasLayer : public CanvasLayer,
|
||||
public BasicImplData
|
||||
{
|
||||
|
@ -919,11 +919,9 @@ ShadowBufferOGL::Upload(gfxASurface* aUpdate, const nsIntRegion& aUpdated,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation,
|
||||
bool aDelayUpload, nsIntRegion& aPendingUploadRegion)
|
||||
{
|
||||
// aUpdated is in screen coordinates. Move it so that the layer's
|
||||
// top-left is 0,0
|
||||
// aUpdated is in screen coordinates. Convert it to buffer coordinates.
|
||||
nsIntRegion destRegion(aUpdated);
|
||||
nsIntPoint visTopLeft = mLayer->GetVisibleRegion().GetBounds().TopLeft();
|
||||
destRegion.MoveBy(-visTopLeft);
|
||||
destRegion.MoveBy(-aRect.TopLeft());
|
||||
|
||||
// Correct for rotation
|
||||
destRegion.MoveBy(aRotation);
|
||||
|
@ -160,14 +160,6 @@ gfxAndroidPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
aLength);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
gfxAndroidPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
const nsAString& aFontName)
|
||||
{
|
||||
return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aProxyEntry,
|
||||
aFontName);
|
||||
}
|
||||
|
||||
RefPtr<ScaledFont>
|
||||
gfxAndroidPlatform::GetScaledFontForFont(gfxFont *aFont)
|
||||
{
|
||||
|
@ -48,8 +48,6 @@ public:
|
||||
virtual gfxPlatformFontList* CreatePlatformFontList();
|
||||
virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
const PRUint8 *aFontData, PRUint32 aLength);
|
||||
virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
const nsAString& aFontName);
|
||||
|
||||
virtual nsresult GetFontList(nsIAtom *aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
|
@ -186,7 +186,6 @@ FT2FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
|
||||
fe->mItalic = aProxyEntry.mItalic;
|
||||
fe->mWeight = aProxyEntry.mWeight;
|
||||
fe->mStretch = aProxyEntry.mStretch;
|
||||
fe->mIsUserFont = true;
|
||||
}
|
||||
return fe;
|
||||
}
|
||||
@ -1060,7 +1059,7 @@ struct FullFontNameSearch {
|
||||
{ }
|
||||
|
||||
nsString mFullName;
|
||||
FT2FontEntry *mFontEntry;
|
||||
gfxFontEntry *mFontEntry;
|
||||
};
|
||||
|
||||
// callback called for each family name, based on the assumption that the
|
||||
@ -1079,17 +1078,12 @@ FindFullName(nsStringHashKey::KeyType aKey,
|
||||
data->mFullName.Left(fullNameFamily, family.Length());
|
||||
|
||||
// if so, iterate over faces in this family to see if there is a match
|
||||
if (family.Equals(fullNameFamily, nsCaseInsensitiveStringComparator())) {
|
||||
if (family.Equals(fullNameFamily)) {
|
||||
nsTArray<nsRefPtr<gfxFontEntry> >& fontList = aFontFamily->GetFontList();
|
||||
int index, len = fontList.Length();
|
||||
for (index = 0; index < len; index++) {
|
||||
gfxFontEntry* fe = fontList[index];
|
||||
if (!fe) {
|
||||
continue;
|
||||
}
|
||||
if (fe->Name().Equals(data->mFullName,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
data->mFontEntry = static_cast<FT2FontEntry*>(fe);
|
||||
if (fontList[index]->Name().Equals(data->mFullName)) {
|
||||
data->mFontEntry = fontList[index];
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
}
|
||||
@ -1107,30 +1101,7 @@ gfxFT2FontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||
|
||||
mFontFamilies.Enumerate(FindFullName, &data);
|
||||
|
||||
if (!data.mFontEntry) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Clone the font entry so that we can then set its style descriptors
|
||||
// from the proxy rather than the actual font.
|
||||
|
||||
// Ensure existence of mFTFace in the original entry
|
||||
data.mFontEntry->CairoFontFace();
|
||||
if (!data.mFontEntry->mFTFace) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
FT2FontEntry* fe =
|
||||
FT2FontEntry::CreateFontEntry(data.mFontEntry->mFTFace, nsnull, 0,
|
||||
data.mFontEntry->Name(), nsnull);
|
||||
if (fe) {
|
||||
fe->mItalic = aProxyEntry->mItalic;
|
||||
fe->mWeight = aProxyEntry->mWeight;
|
||||
fe->mStretch = aProxyEntry->mStretch;
|
||||
fe->mIsUserFont = fe->mIsLocalUserFont = true;
|
||||
}
|
||||
|
||||
return fe;
|
||||
return data.mFontEntry;
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
@ -101,7 +101,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
||||
if (!parser.init())
|
||||
return NULL;
|
||||
|
||||
SharedContext sc(cx, scopeChain, /* fun = */ NULL, /* funbox = */ NULL);
|
||||
SharedContext sc(cx, scopeChain, /* fun = */ NULL, /* funbox = */ NULL, StrictModeFromContext(cx));
|
||||
|
||||
TreeContext tc(&parser, &sc, staticLevel, /* bodyid = */ 0);
|
||||
if (!tc.init())
|
||||
@ -133,7 +133,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
||||
|
||||
/* If this is a direct call to eval, inherit the caller's strictness. */
|
||||
if (callerFrame && callerFrame->isScriptFrame() && callerFrame->script()->strictModeCode)
|
||||
sc.setInStrictMode();
|
||||
sc.strictModeState = StrictMode::STRICT;
|
||||
|
||||
if (compileAndGo) {
|
||||
if (source) {
|
||||
@ -169,9 +169,18 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
||||
onlyXML = true;
|
||||
#endif
|
||||
|
||||
bool inDirectivePrologue = true;
|
||||
TokenStream &tokenStream = parser.tokenStream;
|
||||
tokenStream.setOctalCharacterEscape(false);
|
||||
{
|
||||
ParseNode *stringsAtStart = ListNode::create(PNK_STATEMENTLIST, &parser);
|
||||
if (!stringsAtStart)
|
||||
return NULL;
|
||||
stringsAtStart->makeEmpty();
|
||||
bool ok = parser.processDirectives(stringsAtStart) && EmitTree(cx, &bce, stringsAtStart);
|
||||
parser.freeTree(stringsAtStart);
|
||||
if (!ok)
|
||||
return NULL;
|
||||
}
|
||||
JS_ASSERT(sc.strictModeState != StrictMode::UNKNOWN);
|
||||
for (;;) {
|
||||
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
|
||||
if (tt <= TOK_EOF) {
|
||||
@ -185,9 +194,6 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
|
||||
if (!pn)
|
||||
return NULL;
|
||||
|
||||
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
|
||||
return NULL;
|
||||
|
||||
if (!FoldConstants(cx, pn, &parser))
|
||||
return NULL;
|
||||
|
||||
@ -263,7 +269,8 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun,
|
||||
return false;
|
||||
|
||||
JS_ASSERT(fun);
|
||||
SharedContext funsc(cx, /* scopeChain = */ NULL, fun, /* funbox = */ NULL);
|
||||
SharedContext funsc(cx, /* scopeChain = */ NULL, fun, /* funbox = */ NULL,
|
||||
StrictModeFromContext(cx));
|
||||
funsc.bindings.transfer(bindings);
|
||||
fun->setArgCount(funsc.bindings.numArgs());
|
||||
|
||||
|
@ -4816,11 +4816,12 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
{
|
||||
FunctionBox *funbox = pn->pn_funbox;
|
||||
SharedContext sc(cx, /* scopeChain = */ NULL, fun, funbox);
|
||||
SharedContext sc(cx, /* scopeChain = */ NULL, fun, funbox, funbox->strictModeState);
|
||||
sc.cxFlags = funbox->cxFlags;
|
||||
if (bce->sc->funMightAliasLocals())
|
||||
sc.setFunMightAliasLocals(); // inherit funMightAliasLocals from parent
|
||||
sc.bindings.transfer(&funbox->bindings);
|
||||
JS_ASSERT_IF(bce->sc->inStrictMode(), sc.inStrictMode());
|
||||
|
||||
// Inherit most things (principals, version, etc) from the parent.
|
||||
GlobalObject *globalObject = fun->getParent() ? &fun->getParent()->global() : NULL;
|
||||
|
@ -478,7 +478,7 @@ CloneParseTree(ParseNode *opn, Parser *parser)
|
||||
|
||||
case PN_FUNC:
|
||||
NULLCHECK(pn->pn_funbox =
|
||||
parser->newFunctionBox(opn->pn_funbox->object, pn, tc));
|
||||
parser->newFunctionBox(opn->pn_funbox->object, pn, tc, opn->pn_funbox->strictModeState));
|
||||
NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
|
||||
pn->pn_cookie = opn->pn_cookie;
|
||||
pn->pn_dflags = opn->pn_dflags;
|
||||
|
@ -809,48 +809,6 @@ struct ParseNode {
|
||||
isKind(PNK_NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* True if this statement node could be a member of a Directive Prologue: an
|
||||
* expression statement consisting of a single string literal.
|
||||
*
|
||||
* This considers only the node and its children, not its context. After
|
||||
* parsing, check the node's pn_prologue flag to see if it is indeed part of
|
||||
* a directive prologue.
|
||||
*
|
||||
* Note that a Directive Prologue can contain statements that cannot
|
||||
* themselves be directives (string literals that include escape sequences
|
||||
* or escaped newlines, say). This member function returns true for such
|
||||
* nodes; we use it to determine the extent of the prologue.
|
||||
* isEscapeFreeStringLiteral, below, checks whether the node itself could be
|
||||
* a directive.
|
||||
*/
|
||||
bool isStringExprStatement() const {
|
||||
if (getKind() == PNK_SEMI) {
|
||||
JS_ASSERT(pn_arity == PN_UNARY);
|
||||
ParseNode *kid = pn_kid;
|
||||
return kid && kid->getKind() == PNK_STRING && !kid->pn_parens;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if this node, known to be an unparenthesized string literal,
|
||||
* could be the string of a directive in a Directive Prologue. Directive
|
||||
* strings never contain escape sequences or line continuations.
|
||||
*/
|
||||
bool isEscapeFreeStringLiteral() const {
|
||||
JS_ASSERT(isKind(PNK_STRING) && !pn_parens);
|
||||
|
||||
/*
|
||||
* If the string's length in the source code is its length as a value,
|
||||
* accounting for the quotes, then it must not contain any escape
|
||||
* sequences or line continuations.
|
||||
*/
|
||||
JSString *str = pn_atom;
|
||||
return (pn_pos.begin.lineno == pn_pos.end.lineno &&
|
||||
pn_pos.begin.index + str->length() + 2 == pn_pos.end.index);
|
||||
}
|
||||
|
||||
/* Return true if this node appears in a Directive Prologue. */
|
||||
bool isDirectivePrologueMember() const { return pn_prologue; }
|
||||
|
||||
@ -1513,6 +1471,7 @@ struct FunctionBox : public ObjectBox
|
||||
Bindings bindings; /* bindings for this function */
|
||||
uint16_t level;
|
||||
uint16_t ndefaults;
|
||||
StrictMode::StrictModeState strictModeState;
|
||||
bool inLoop:1; /* in a loop in parent function */
|
||||
bool inWith:1; /* some enclosing scope is a with-statement
|
||||
or E4X filter-expression */
|
||||
@ -1520,7 +1479,8 @@ struct FunctionBox : public ObjectBox
|
||||
|
||||
ContextFlags cxFlags;
|
||||
|
||||
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, TreeContext *tc);
|
||||
FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, TreeContext *tc,
|
||||
StrictMode::StrictModeState sms);
|
||||
|
||||
bool funIsHeavyweight() const { return cxFlags.funIsHeavyweight; }
|
||||
bool funIsGenerator() const { return cxFlags.funIsGenerator; }
|
||||
@ -1535,6 +1495,8 @@ struct FunctionBox : public ObjectBox
|
||||
* filter-expression, or a function that uses direct eval.
|
||||
*/
|
||||
bool inAnyDynamicScope() const;
|
||||
|
||||
void recursivelySetStrictMode(StrictMode::StrictModeState strictness);
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -76,10 +76,22 @@ using namespace js::frontend;
|
||||
JS_END_MACRO
|
||||
#define MUST_MATCH_TOKEN(tt, errno) MUST_MATCH_TOKEN_WITH_FLAGS(tt, errno, 0)
|
||||
|
||||
bool
|
||||
StrictMode::StrictModeState
|
||||
StrictModeGetter::get() const
|
||||
{
|
||||
return parser->tc->sc->inStrictMode();
|
||||
return parser->tc->sc->strictModeState;
|
||||
}
|
||||
|
||||
CompileError *
|
||||
StrictModeGetter::queuedStrictModeError() const
|
||||
{
|
||||
return parser->tc->queuedStrictModeError;
|
||||
}
|
||||
|
||||
void
|
||||
StrictModeGetter::setQueuedStrictModeError(CompileError *e)
|
||||
{
|
||||
parser->tc->setQueuedStrictModeError(e);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -165,7 +177,8 @@ Parser::newObjectBox(JSObject *obj)
|
||||
return objbox;
|
||||
}
|
||||
|
||||
FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, TreeContext *tc)
|
||||
FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn, TreeContext *tc,
|
||||
StrictMode::StrictModeState sms)
|
||||
: ObjectBox(traceListHead, obj),
|
||||
node(fn),
|
||||
siblings(tc->functionList),
|
||||
@ -174,6 +187,7 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
|
||||
bindings(),
|
||||
level(tc->staticLevel),
|
||||
ndefaults(0),
|
||||
strictModeState(sms),
|
||||
inLoop(false),
|
||||
inWith(!!tc->innermostWith),
|
||||
inGenexpLambda(false),
|
||||
@ -197,7 +211,8 @@ FunctionBox::FunctionBox(ObjectBox* traceListHead, JSObject *obj, ParseNode *fn,
|
||||
}
|
||||
|
||||
FunctionBox *
|
||||
Parser::newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc)
|
||||
Parser::newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc,
|
||||
StrictMode::StrictModeState sms)
|
||||
{
|
||||
JS_ASSERT(obj && !IsPoisonedPtr(obj));
|
||||
JS_ASSERT(obj->isFunction());
|
||||
@ -209,7 +224,7 @@ Parser::newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc)
|
||||
* scanning, parsing and code generation for the whole script or top-level
|
||||
* function.
|
||||
*/
|
||||
FunctionBox *funbox = context->tempLifoAlloc().new_<FunctionBox>(traceListHead, obj, fn, tc);
|
||||
FunctionBox *funbox = context->tempLifoAlloc().new_<FunctionBox>(traceListHead, obj, fn, tc, sms);
|
||||
if (!funbox) {
|
||||
js_ReportOutOfMemory(context);
|
||||
return NULL;
|
||||
@ -261,7 +276,8 @@ Parser::parse(JSObject *chain)
|
||||
* an object lock before it finishes generating bytecode into a script
|
||||
* protected from the GC by a root or a stack frame reference.
|
||||
*/
|
||||
SharedContext globalsc(context, chain, /* fun = */ NULL, /* funbox = */ NULL);
|
||||
SharedContext globalsc(context, chain, /* fun = */ NULL, /* funbox = */ NULL,
|
||||
StrictModeFromContext(context));
|
||||
TreeContext globaltc(this, &globalsc, /* staticLevel = */ 0, /* bodyid = */ 0);
|
||||
if (!globaltc.init())
|
||||
return NULL;
|
||||
@ -520,13 +536,13 @@ CheckStrictParameters(JSContext *cx, Parser *parser)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc->inStrictMode() && FindKeyword(name->charsZ(), name->length())) {
|
||||
if (sc->needStrictChecks() && FindKeyword(name->charsZ(), name->length())) {
|
||||
/*
|
||||
* JSOPTION_STRICT is supposed to warn about future keywords, too,
|
||||
* but we took care of that in the scanner.
|
||||
*/
|
||||
JS_ALWAYS_TRUE(!ReportBadParameter(cx, parser, name, JSMSG_RESERVED_ID));
|
||||
return false;
|
||||
if (!ReportBadParameter(cx, parser, name, JSMSG_RESERVED_ID))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -579,6 +595,11 @@ Parser::functionBody(FunctionBodyType type)
|
||||
} else {
|
||||
JS_ASSERT(type == ExpressionBody);
|
||||
JS_ASSERT(JS_HAS_EXPR_CLOSURES);
|
||||
|
||||
// There are no directives to parse, so indicate we're done finding
|
||||
// strict mode directives.
|
||||
if (!setStrictMode(false))
|
||||
return NULL;
|
||||
pn = UnaryNode::create(PNK_RETURN, this);
|
||||
if (pn) {
|
||||
pn->pn_kid = assignExpr();
|
||||
@ -705,7 +726,7 @@ Parser::functionBody(FunctionBodyType type)
|
||||
* to any mutation we create it eagerly whenever parameters are (or
|
||||
* might, in the case of calls to eval) be assigned.
|
||||
*/
|
||||
if (tc->sc->inStrictMode()) {
|
||||
if (tc->sc->needStrictChecks()) {
|
||||
for (AtomDefnListMap::Range r = tc->decls.all(); !r.empty(); r.popFront()) {
|
||||
DefinitionList &dlist = r.front().value();
|
||||
for (DefinitionList::Range dr = dlist.all(); !dr.empty(); dr.popFront()) {
|
||||
@ -1538,20 +1559,21 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
|
||||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
/* Create box for fun->object early to protect against last-ditch GC. */
|
||||
FunctionBox *funbox = newFunctionBox(fun, pn, outertc);
|
||||
// Inherit strictness if neeeded.
|
||||
StrictMode::StrictModeState sms = (outertc->sc->strictModeState == StrictMode::STRICT) ?
|
||||
StrictMode::STRICT : StrictMode::UNKNOWN;
|
||||
|
||||
// Create box for fun->object early to protect against last-ditch GC.
|
||||
FunctionBox *funbox = newFunctionBox(fun, pn, outertc, sms);
|
||||
if (!funbox)
|
||||
return NULL;
|
||||
|
||||
/* Initialize early for possible flags mutation via destructuringExpr. */
|
||||
SharedContext funsc(context, /* scopeChain = */ NULL, fun, funbox);
|
||||
SharedContext funsc(context, /* scopeChain = */ NULL, fun, funbox, sms);
|
||||
TreeContext funtc(this, &funsc, outertc->staticLevel + 1, outertc->blockidGen);
|
||||
if (!funtc.init())
|
||||
return NULL;
|
||||
|
||||
if (outertc->sc->inStrictMode())
|
||||
funsc.setInStrictMode(); // inherit strict mode from parent
|
||||
|
||||
/* Now parse formal argument list and compute fun->nargs. */
|
||||
ParseNode *prelude = NULL;
|
||||
bool hasRest;
|
||||
@ -1693,7 +1715,7 @@ Parser::functionDef(HandlePropertyName funName, FunctionType type, FunctionSynta
|
||||
* compound statement such as the "then" part of an "if" statement,
|
||||
* binds a closure only if control reaches that sub-statement.
|
||||
*/
|
||||
JS_ASSERT(!outertc->sc->inStrictMode());
|
||||
JS_ASSERT(outertc->sc->strictModeState != StrictMode::STRICT);
|
||||
op = JSOP_DEFFUN;
|
||||
outertc->sc->setFunMightAliasLocals();
|
||||
outertc->sc->setFunHasExtensibleScope();
|
||||
@ -1746,10 +1768,9 @@ Parser::functionStmt()
|
||||
}
|
||||
|
||||
/* We forbid function statements in strict mode code. */
|
||||
if (!tc->atBodyLevel() && tc->sc->inStrictMode()) {
|
||||
reportStrictModeError(NULL, JSMSG_STRICT_FUNCTION_STATEMENT);
|
||||
if (!tc->atBodyLevel() && tc->sc->needStrictChecks() &&
|
||||
!reportStrictModeError(NULL, JSMSG_STRICT_FUNCTION_STATEMENT))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return functionDef(name, Normal, Statement);
|
||||
}
|
||||
@ -1765,6 +1786,83 @@ Parser::functionExpr()
|
||||
return functionDef(name, Normal, Expression);
|
||||
}
|
||||
|
||||
void
|
||||
FunctionBox::recursivelySetStrictMode(StrictMode::StrictModeState strictness)
|
||||
{
|
||||
if (strictModeState == StrictMode::UNKNOWN) {
|
||||
strictModeState = strictness;
|
||||
for (FunctionBox *kid = kids; kid; kid = kid->siblings)
|
||||
kid->recursivelySetStrictMode(strictness);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate that the current scope can't switch to strict mode with a body-level
|
||||
* "use strict" directive anymore. Return false on error.
|
||||
*/
|
||||
bool
|
||||
Parser::setStrictMode(bool strictMode)
|
||||
{
|
||||
if (tc->sc->strictModeState != StrictMode::UNKNOWN) {
|
||||
// Strict mode was inherited.
|
||||
JS_ASSERT(tc->sc->strictModeState == StrictMode::STRICT);
|
||||
if (tc->sc->inFunction() && tc->sc->funbox()) {
|
||||
JS_ASSERT(tc->sc->funbox()->strictModeState == tc->sc->strictModeState);
|
||||
JS_ASSERT(tc->parent->sc->strictModeState == StrictMode::STRICT);
|
||||
} else {
|
||||
JS_ASSERT(StrictModeFromContext(context) == StrictMode::STRICT || tc->staticLevel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (strictMode) {
|
||||
if (tc->queuedStrictModeError) {
|
||||
// There was a strict mode error in this scope before we knew it was
|
||||
// strict. Throw it.
|
||||
JS_ASSERT(!(tc->queuedStrictModeError->report.flags & JSREPORT_WARNING));
|
||||
tc->queuedStrictModeError->throwError();
|
||||
return false;
|
||||
}
|
||||
tc->sc->strictModeState = StrictMode::STRICT;
|
||||
} else if (!tc->parent || tc->parent->sc->strictModeState == StrictMode::NOTSTRICT) {
|
||||
// This scope will not be strict.
|
||||
tc->sc->strictModeState = StrictMode::NOTSTRICT;
|
||||
if (tc->queuedStrictModeError && context->hasStrictOption() &&
|
||||
tc->queuedStrictModeError->report.errorNumber != JSMSG_STRICT_CODE_WITH) {
|
||||
// Convert queued strict mode error to a warning.
|
||||
tc->queuedStrictModeError->report.flags |= JSREPORT_WARNING;
|
||||
tc->queuedStrictModeError->throwError();
|
||||
}
|
||||
}
|
||||
JS_ASSERT_IF(!tc->sc->inFunction(), !tc->functionList);
|
||||
if (tc->sc->strictModeState != StrictMode::UNKNOWN && tc->sc->inFunction()) {
|
||||
// We changed the strict mode state. Retroactively recursively set
|
||||
// strict mode status on all the function children we've seen so far
|
||||
// children (That is, functions in default expressions).
|
||||
if (tc->sc->funbox())
|
||||
tc->sc->funbox()->strictModeState = tc->sc->strictModeState;
|
||||
for (FunctionBox *kid = tc->functionList; kid; kid = kid->siblings)
|
||||
kid->recursivelySetStrictMode(tc->sc->strictModeState);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if this token, known to be an unparenthesized string literal,
|
||||
* could be the string of a directive in a Directive Prologue. Directive
|
||||
* strings never contain escape sequences or line continuations.
|
||||
*/
|
||||
static bool
|
||||
IsEscapeFreeStringLiteral(const Token &tok)
|
||||
{
|
||||
/*
|
||||
* If the string's length in the source code is its length as a value,
|
||||
* accounting for the quotes, then it must not contain any escape
|
||||
* sequences or line continuations.
|
||||
*/
|
||||
return (tok.pos.begin.lineno == tok.pos.end.lineno &&
|
||||
tok.pos.begin.index + tok.atom()->length() + 2 == tok.pos.end.index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recognize Directive Prologue members and directives. Assuming |pn| is a
|
||||
* candidate for membership in a directive prologue, recognize directives and
|
||||
@ -1785,52 +1883,45 @@ Parser::functionExpr()
|
||||
* to the "use strict" statement, which is indeed a directive.
|
||||
*/
|
||||
bool
|
||||
Parser::recognizeDirectivePrologue(ParseNode *pn, bool *isDirectivePrologueMember)
|
||||
Parser::processDirectives(ParseNode *stmts)
|
||||
{
|
||||
*isDirectivePrologueMember = pn->isStringExprStatement();
|
||||
if (!*isDirectivePrologueMember)
|
||||
return true;
|
||||
|
||||
ParseNode *kid = pn->pn_kid;
|
||||
if (kid->isEscapeFreeStringLiteral()) {
|
||||
/*
|
||||
* Mark this statement as being a possibly legitimate part of a
|
||||
* directive prologue, so the byte code emitter won't warn about it
|
||||
* being useless code. (We mustn't just omit the statement entirely yet,
|
||||
* as it could be producing the value of an eval or JSScript execution.)
|
||||
*
|
||||
* Note that even if the string isn't one we recognize as a directive,
|
||||
* the emitter still shouldn't flag it as useless, as it could become a
|
||||
* directive in the future. We don't want to interfere with people
|
||||
* taking advantage of directive-prologue-enabled features that appear
|
||||
* in other browsers first.
|
||||
*/
|
||||
pn->pn_prologue = true;
|
||||
|
||||
JSAtom *directive = kid->pn_atom;
|
||||
if (directive == context->runtime->atomState.useStrictAtom) {
|
||||
/*
|
||||
* Unfortunately, Directive Prologue members in general may contain
|
||||
* escapes, even while "use strict" directives may not. Therefore
|
||||
* we must check whether an octal character escape has been seen in
|
||||
* any previous directives whenever we encounter a "use strict"
|
||||
* directive, so that the octal escape is properly treated as a
|
||||
* syntax error. An example of this case:
|
||||
*
|
||||
* function error()
|
||||
* {
|
||||
* "\145"; // octal escape
|
||||
* "use strict"; // retroactively makes "\145" a syntax error
|
||||
* }
|
||||
*/
|
||||
if (tokenStream.hasOctalCharacterEscape()) {
|
||||
reportError(NULL, JSMSG_DEPRECATED_OCTAL);
|
||||
bool gotStrictMode = false;
|
||||
for (TokenKind tt = tokenStream.getToken(TSF_OPERAND); tt == TOK_STRING; tt = tokenStream.getToken(TSF_OPERAND)) {
|
||||
ParseNode *stringNode = atomNode(PNK_STRING, JSOP_STRING);
|
||||
if (!stringNode)
|
||||
return false;
|
||||
const Token directive = tokenStream.currentToken();
|
||||
bool isDirective = IsEscapeFreeStringLiteral(directive);
|
||||
JSAtom *atom = directive.atom();
|
||||
TokenKind next = tokenStream.peekTokenSameLine(TSF_OPERAND);
|
||||
if (next != TOK_EOF && next != TOK_EOL && next != TOK_SEMI && next != TOK_RC) {
|
||||
freeTree(stringNode);
|
||||
if (next == TOK_ERROR)
|
||||
return false;
|
||||
}
|
||||
|
||||
tc->sc->setInStrictMode();
|
||||
break;
|
||||
}
|
||||
tokenStream.matchToken(TOK_SEMI);
|
||||
if (isDirective) {
|
||||
// It's a directive. Is it one we know?
|
||||
if (atom == context->runtime->atomState.useStrictAtom && !gotStrictMode) {
|
||||
if (!setStrictMode(true))
|
||||
return false;
|
||||
gotStrictMode = true;
|
||||
}
|
||||
}
|
||||
ParseNode *stmt = UnaryNode::create(PNK_SEMI, this);
|
||||
if (!stmt) {
|
||||
freeTree(stringNode);
|
||||
return false;
|
||||
}
|
||||
stmt->pn_pos = stringNode->pn_pos;
|
||||
stmt->pn_kid = stringNode;
|
||||
stmt->pn_prologue = isDirective;
|
||||
stmts->append(stmt);
|
||||
}
|
||||
tokenStream.ungetToken();
|
||||
if (!gotStrictMode && !setStrictMode(false))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1854,8 +1945,8 @@ Parser::statements(bool *hasFunctionStmt)
|
||||
ParseNode *saveBlock = tc->blockNode;
|
||||
tc->blockNode = pn;
|
||||
|
||||
bool inDirectivePrologue = tc->atBodyLevel();
|
||||
tokenStream.setOctalCharacterEscape(false);
|
||||
if (tc->atBodyLevel() && !processDirectives(pn))
|
||||
return NULL;
|
||||
for (;;) {
|
||||
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
|
||||
if (tt <= TOK_EOF || tt == TOK_RC) {
|
||||
@ -1873,9 +1964,6 @@ Parser::statements(bool *hasFunctionStmt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (inDirectivePrologue && !recognizeDirectivePrologue(next, &inDirectivePrologue))
|
||||
return NULL;
|
||||
|
||||
if (next->isKind(PNK_FUNCTION)) {
|
||||
/*
|
||||
* PNX_FUNCDEFS notifies the emitter that the block contains body-
|
||||
@ -3545,18 +3633,16 @@ Parser::withStatement()
|
||||
{
|
||||
JS_ASSERT(tokenStream.isCurrentTokenType(TOK_WITH));
|
||||
|
||||
/*
|
||||
* In most cases, we want the constructs forbidden in strict mode
|
||||
* code to be a subset of those that JSOPTION_STRICT warns about, and
|
||||
* we should use reportStrictModeError. However, 'with' is the sole
|
||||
* instance of a construct that is forbidden in strict mode code, but
|
||||
* doesn't even merit a warning under JSOPTION_STRICT. See
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=514576#c1.
|
||||
*/
|
||||
if (tc->sc->inStrictMode()) {
|
||||
reportError(NULL, JSMSG_STRICT_CODE_WITH);
|
||||
// In most cases, we want the constructs forbidden in strict mode code to be
|
||||
// a subset of those that JSOPTION_STRICT warns about, and we should use
|
||||
// reportStrictModeError. However, 'with' is the sole instance of a
|
||||
// construct that is forbidden in strict mode code, but doesn't even merit a
|
||||
// warning under JSOPTION_STRICT. See
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=514576#c1. The actual
|
||||
// supression of the with code warning is in
|
||||
// TokenStream::reportCompileErrorNumberVA.
|
||||
if (!reportStrictModeError(NULL, JSMSG_STRICT_CODE_WITH))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ParseNode *pn = BinaryNode::create(PNK_WITH, this);
|
||||
if (!pn)
|
||||
@ -5391,11 +5477,11 @@ Parser::generatorExpr(ParseNode *kid)
|
||||
return NULL;
|
||||
|
||||
/* Create box for fun->object early to protect against last-ditch GC. */
|
||||
FunctionBox *funbox = newFunctionBox(fun, genfn, outertc);
|
||||
FunctionBox *funbox = newFunctionBox(fun, genfn, outertc, outertc->sc->strictModeState);
|
||||
if (!funbox)
|
||||
return NULL;
|
||||
|
||||
SharedContext gensc(context, /* scopeChain = */ NULL, fun, funbox);
|
||||
SharedContext gensc(context, /* scopeChain = */ NULL, fun, funbox, outertc->sc->strictModeState);
|
||||
TreeContext gentc(this, &gensc, outertc->staticLevel + 1, outertc->blockidGen);
|
||||
if (!gentc.init())
|
||||
return NULL;
|
||||
@ -5723,7 +5809,7 @@ Parser::memberExpr(bool allowCallSyntax)
|
||||
* In non-strict mode code, direct calls to eval can add
|
||||
* variables to the call object.
|
||||
*/
|
||||
if (!tc->sc->inStrictMode())
|
||||
if (tc->sc->strictModeState != StrictMode::STRICT)
|
||||
tc->sc->setFunHasExtensibleScope();
|
||||
}
|
||||
} else if (lhs->isOp(JSOP_GETPROP)) {
|
||||
@ -6367,11 +6453,10 @@ Parser::parseXMLText(JSObject *chain, bool allowList)
|
||||
* lightweight function activation, or if its scope chain doesn't match
|
||||
* the one passed to us.
|
||||
*/
|
||||
SharedContext xmlsc(context, chain, /* fun = */ NULL, /* funbox = */ NULL);
|
||||
SharedContext xmlsc(context, chain, /* fun = */ NULL, /* funbox = */ NULL, StrictMode::NOTSTRICT);
|
||||
TreeContext xmltc(this, &xmlsc, /* staticLevel = */ 0, /* bodyid = */ 0);
|
||||
if (!xmltc.init())
|
||||
return NULL;
|
||||
JS_ASSERT(!xmlsc.inStrictMode());
|
||||
|
||||
/* Set XML-only mode to turn off special treatment of {expr} in XML. */
|
||||
tokenStream.setXMLOnlyMode();
|
||||
@ -6875,9 +6960,9 @@ Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
|
||||
return NULL;
|
||||
|
||||
Reporter reporter =
|
||||
(oldAssignType == VALUE && assignType == VALUE && !tc->sc->inStrictMode())
|
||||
(oldAssignType == VALUE && assignType == VALUE && !tc->sc->needStrictChecks())
|
||||
? &Parser::reportWarning
|
||||
: &Parser::reportError;
|
||||
: (tc->sc->needStrictChecks() ? &Parser::reportStrictModeError : &Parser::reportError);
|
||||
if (!(this->*reporter)(NULL, JSMSG_DUPLICATE_PROPERTY, name.ptr()))
|
||||
return NULL;
|
||||
}
|
||||
|
@ -87,7 +87,8 @@ struct Parser : private AutoGCRooter
|
||||
*/
|
||||
ObjectBox *newObjectBox(JSObject *obj);
|
||||
|
||||
FunctionBox *newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc);
|
||||
FunctionBox *newFunctionBox(JSObject *obj, ParseNode *fn, TreeContext *tc,
|
||||
StrictMode::StrictModeState sms);
|
||||
|
||||
/*
|
||||
* Create a new function object given tree context (tc) and a name (which
|
||||
@ -136,7 +137,7 @@ struct Parser : private AutoGCRooter
|
||||
|
||||
/* Public entry points for parsing. */
|
||||
ParseNode *statement();
|
||||
bool recognizeDirectivePrologue(ParseNode *pn, bool *isDirectivePrologueMember);
|
||||
bool processDirectives(ParseNode *stringsAtStart);
|
||||
|
||||
/*
|
||||
* Parse a function body. Pass StatementListBody if the body is a list of
|
||||
@ -230,7 +231,7 @@ struct Parser : private AutoGCRooter
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
// True if E4X syntax is allowed in the current syntactic context.
|
||||
bool allowsXML() const { return !tc->sc->inStrictMode() && tokenStream.allowsXML(); }
|
||||
bool allowsXML() const { return tokenStream.allowsXML(); }
|
||||
|
||||
ParseNode *endBracketedExpr();
|
||||
|
||||
@ -249,6 +250,7 @@ struct Parser : private AutoGCRooter
|
||||
ParseNode *propertyQualifiedIdentifier();
|
||||
#endif /* JS_HAS_XML_SUPPORT */
|
||||
|
||||
bool setStrictMode(bool strictMode);
|
||||
bool setAssignmentLhsOps(ParseNode *pn, JSOp op);
|
||||
bool matchInOrOf(bool *isForOfp);
|
||||
};
|
||||
|
@ -396,76 +396,118 @@ bool
|
||||
TokenStream::reportStrictModeErrorNumberVA(ParseNode *pn, unsigned errorNumber, va_list args)
|
||||
{
|
||||
/* In strict mode code, this is an error, not merely a warning. */
|
||||
unsigned flags;
|
||||
if (isStrictMode())
|
||||
flags = JSREPORT_ERROR;
|
||||
unsigned flags = JSREPORT_STRICT;
|
||||
if (strictModeState() != StrictMode::NOTSTRICT)
|
||||
flags |= JSREPORT_ERROR;
|
||||
else if (cx->hasStrictOption())
|
||||
flags = JSREPORT_WARNING;
|
||||
flags |= JSREPORT_WARNING;
|
||||
else
|
||||
return true;
|
||||
|
||||
|
||||
return reportCompileErrorNumberVA(pn, flags, errorNumber, args);
|
||||
}
|
||||
|
||||
void
|
||||
CompileError::throwError()
|
||||
{
|
||||
/*
|
||||
* If there's a runtime exception type associated with this error
|
||||
* number, set that as the pending exception. For errors occuring at
|
||||
* compile time, this is very likely to be a JSEXN_SYNTAXERR.
|
||||
*
|
||||
* If an exception is thrown but not caught, the JSREPORT_EXCEPTION
|
||||
* flag will be set in report.flags. Proper behavior for an error
|
||||
* reporter is to ignore a report with this flag for all but top-level
|
||||
* compilation errors. The exception will remain pending, and so long
|
||||
* as the non-top-level "load", "eval", or "compile" native function
|
||||
* returns false, the top-level reporter will eventually receive the
|
||||
* uncaught exception report.
|
||||
*/
|
||||
if (!js_ErrorToException(cx, message, &report, NULL, NULL)) {
|
||||
/*
|
||||
* If debugErrorHook is present then we give it a chance to veto
|
||||
* sending the error on to the regular error reporter.
|
||||
*/
|
||||
bool reportError = true;
|
||||
if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook) {
|
||||
reportError = hook(cx, message, &report, cx->runtime->debugHooks.debugErrorHookData);
|
||||
}
|
||||
|
||||
/* Report the error */
|
||||
if (reportError && cx->errorReporter)
|
||||
cx->errorReporter(cx, message, &report);
|
||||
}
|
||||
}
|
||||
|
||||
CompileError::~CompileError()
|
||||
{
|
||||
cx->free_((void*)report.uclinebuf);
|
||||
cx->free_((void*)report.linebuf);
|
||||
cx->free_((void*)report.ucmessage);
|
||||
cx->free_(message);
|
||||
message = NULL;
|
||||
|
||||
if (report.messageArgs) {
|
||||
if (hasCharArgs) {
|
||||
unsigned i = 0;
|
||||
while (report.messageArgs[i])
|
||||
cx->free_((void*)report.messageArgs[i++]);
|
||||
}
|
||||
cx->free_(report.messageArgs);
|
||||
}
|
||||
|
||||
PodZero(&report);
|
||||
}
|
||||
|
||||
bool
|
||||
TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned errorNumber,
|
||||
va_list args)
|
||||
{
|
||||
class ReportManager
|
||||
{
|
||||
JSContext *cx;
|
||||
JSErrorReport *report;
|
||||
bool hasCharArgs;
|
||||
bool strict = JSREPORT_IS_STRICT(flags);
|
||||
bool warning = JSREPORT_IS_WARNING(flags);
|
||||
|
||||
public:
|
||||
char *message;
|
||||
|
||||
ReportManager(JSContext *cx, JSErrorReport *report, bool hasCharArgs)
|
||||
: cx(cx), report(report), hasCharArgs(hasCharArgs), message(NULL)
|
||||
{}
|
||||
|
||||
~ReportManager() {
|
||||
cx->free_((void*)report->uclinebuf);
|
||||
cx->free_((void*)report->linebuf);
|
||||
cx->free_(message);
|
||||
cx->free_((void*)report->ucmessage);
|
||||
|
||||
if (report->messageArgs) {
|
||||
if (hasCharArgs) {
|
||||
unsigned i = 0;
|
||||
while (report->messageArgs[i])
|
||||
cx->free_((void *)report->messageArgs[i++]);
|
||||
}
|
||||
cx->free_((void *)report->messageArgs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (JSREPORT_IS_STRICT(flags) && !cx->hasStrictOption())
|
||||
// Avoid reporting JSMSG_STRICT_CODE_WITH as a warning. See the comment in
|
||||
// Parser::withStatement.
|
||||
if (strict && warning && (!cx->hasStrictOption() || errorNumber == JSMSG_STRICT_CODE_WITH))
|
||||
return true;
|
||||
|
||||
bool warning = JSREPORT_IS_WARNING(flags);
|
||||
if (warning && cx->hasWErrorOption()) {
|
||||
flags &= ~JSREPORT_WARNING;
|
||||
warning = false;
|
||||
}
|
||||
|
||||
CompileError normalError(cx);
|
||||
CompileError *err = &normalError;
|
||||
if (strict && !warning && strictModeState() == StrictMode::UNKNOWN) {
|
||||
if (strictModeGetter->queuedStrictModeError()) {
|
||||
// Avoid reporting JSMSG_STRICT_CODE_WITH as a warning. See the
|
||||
// comment in Parser::withStatement.
|
||||
if (cx->hasStrictOption() && errorNumber != JSMSG_STRICT_CODE_WITH) {
|
||||
flags |= JSREPORT_WARNING;
|
||||
warning = true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
err = cx->new_<CompileError, JSContext *>(cx);
|
||||
if (!err)
|
||||
return false;
|
||||
strictModeGetter->setQueuedStrictModeError(err);
|
||||
}
|
||||
}
|
||||
|
||||
const TokenPos *const tp = pn ? &pn->pn_pos : ¤tToken().pos;
|
||||
|
||||
JSErrorReport report;
|
||||
PodZero(&report);
|
||||
report.flags = flags;
|
||||
report.errorNumber = errorNumber;
|
||||
report.filename = filename;
|
||||
report.originPrincipals = originPrincipals;
|
||||
report.lineno = tp->begin.lineno;
|
||||
err->report.flags = flags;
|
||||
err->report.errorNumber = errorNumber;
|
||||
err->report.filename = filename;
|
||||
err->report.originPrincipals = originPrincipals;
|
||||
err->report.lineno = tp->begin.lineno;
|
||||
|
||||
bool hasCharArgs = !(flags & JSREPORT_UC);
|
||||
err->hasCharArgs = !(flags & JSREPORT_UC);
|
||||
|
||||
ReportManager mgr(cx, &report, hasCharArgs);
|
||||
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &mgr.message, &report,
|
||||
hasCharArgs, args)) {
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &err->message, &err->report,
|
||||
err->hasCharArgs, args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -479,7 +521,7 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned
|
||||
* means that any error involving a multi-line token (eg. an unterminated
|
||||
* multi-line string literal) won't have a context printed.
|
||||
*/
|
||||
if (report.lineno == lineno) {
|
||||
if (err->report.lineno == lineno) {
|
||||
const jschar *tokptr = linebase + tp->begin.index;
|
||||
|
||||
// We show only a portion (a "window") of the line around the erroneous
|
||||
@ -508,47 +550,23 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned
|
||||
|
||||
// Unicode and char versions of the window into the offending source
|
||||
// line, without final \n.
|
||||
report.uclinebuf = windowBuf.extractWellSized();
|
||||
if (!report.uclinebuf)
|
||||
err->report.uclinebuf = windowBuf.extractWellSized();
|
||||
if (!err->report.uclinebuf)
|
||||
return false;
|
||||
report.linebuf = DeflateString(cx, report.uclinebuf, windowLength);
|
||||
if (!report.linebuf)
|
||||
err->report.linebuf = DeflateString(cx, err->report.uclinebuf, windowLength);
|
||||
if (!err->report.linebuf)
|
||||
return false;
|
||||
|
||||
// The lineno check above means we should only see single-line tokens here.
|
||||
JS_ASSERT(tp->begin.lineno == tp->end.lineno);
|
||||
report.tokenptr = report.linebuf + windowIndex;
|
||||
report.uctokenptr = report.uclinebuf + windowIndex;
|
||||
err->report.tokenptr = err->report.linebuf + windowIndex;
|
||||
err->report.uctokenptr = err->report.uclinebuf + windowIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's a runtime exception type associated with this error
|
||||
* number, set that as the pending exception. For errors occuring at
|
||||
* compile time, this is very likely to be a JSEXN_SYNTAXERR.
|
||||
*
|
||||
* If an exception is thrown but not caught, the JSREPORT_EXCEPTION
|
||||
* flag will be set in report.flags. Proper behavior for an error
|
||||
* reporter is to ignore a report with this flag for all but top-level
|
||||
* compilation errors. The exception will remain pending, and so long
|
||||
* as the non-top-level "load", "eval", or "compile" native function
|
||||
* returns false, the top-level reporter will eventually receive the
|
||||
* uncaught exception report.
|
||||
*/
|
||||
if (!js_ErrorToException(cx, mgr.message, &report, NULL, NULL)) {
|
||||
/*
|
||||
* If debugErrorHook is present then we give it a chance to veto
|
||||
* sending the error on to the regular error reporter.
|
||||
*/
|
||||
bool reportError = true;
|
||||
if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook) {
|
||||
reportError = hook(cx, mgr.message, &report,
|
||||
cx->runtime->debugHooks.debugErrorHookData);
|
||||
}
|
||||
|
||||
/* Report the error */
|
||||
if (reportError && cx->errorReporter)
|
||||
cx->errorReporter(cx, mgr.message, &report);
|
||||
}
|
||||
if (err == &normalError)
|
||||
err->throwError();
|
||||
else
|
||||
return true;
|
||||
|
||||
return warning;
|
||||
}
|
||||
@ -1324,9 +1342,7 @@ TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp, JSO
|
||||
}
|
||||
|
||||
/* Strict reserved word. */
|
||||
if (isStrictMode())
|
||||
return reportStrictModeError(JSMSG_RESERVED_ID, kw->chars);
|
||||
return reportStrictWarning(JSMSG_RESERVED_ID, kw->chars);
|
||||
return reportStrictModeError(JSMSG_RESERVED_ID, kw->chars);
|
||||
}
|
||||
|
||||
enum FirstCharKind {
|
||||
@ -1611,7 +1627,6 @@ TokenStream::getTokenInternal()
|
||||
if (val != 0 || JS7_ISDEC(c)) {
|
||||
if (!reportStrictModeError(JSMSG_DEPRECATED_OCTAL))
|
||||
goto error;
|
||||
setOctalCharacterEscape();
|
||||
}
|
||||
if ('0' <= c && c < '8') {
|
||||
val = 8 * val + JS7_UNDEC(c);
|
||||
|
@ -413,20 +413,53 @@ enum TokenStreamFlags
|
||||
|
||||
struct Parser;
|
||||
|
||||
struct CompileError {
|
||||
JSContext *cx;
|
||||
JSErrorReport report;
|
||||
char *message;
|
||||
bool hasCharArgs;
|
||||
CompileError(JSContext *cx)
|
||||
: cx(cx), message(NULL), hasCharArgs(false)
|
||||
{
|
||||
PodZero(&report);
|
||||
}
|
||||
~CompileError();
|
||||
void throwError();
|
||||
};
|
||||
|
||||
namespace StrictMode {
|
||||
/* For an explanation of how these are used, see the comment in the FunctionBox definition. */
|
||||
enum StrictModeState {
|
||||
NOTSTRICT,
|
||||
UNKNOWN,
|
||||
STRICT
|
||||
};
|
||||
}
|
||||
|
||||
inline StrictMode::StrictModeState
|
||||
StrictModeFromContext(JSContext *cx)
|
||||
{
|
||||
return cx->hasRunOption(JSOPTION_STRICT_MODE) ? StrictMode::STRICT : StrictMode::UNKNOWN;
|
||||
}
|
||||
|
||||
// Ideally, tokenizing would be entirely independent of context. But the
|
||||
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
||||
// TokenStream needs to see it.
|
||||
//
|
||||
// This class constitutes a tiny back-channel from TokenStream to the strict
|
||||
// mode flag that avoids exposing the rest of SharedContext to TokenStream.
|
||||
// get() is implemented in Parser.cpp.
|
||||
// This class is a tiny back-channel from TokenStream to the strict mode flag
|
||||
// that avoids exposing the rest of SharedContext to TokenStream. get()
|
||||
// returns the current strict mode state. The other two methods get and set
|
||||
// the queuedStrictModeError member of TreeContext. StrictModeGetter's
|
||||
// non-inline methods are implemented in Parser.cpp.
|
||||
//
|
||||
class StrictModeGetter {
|
||||
Parser *parser;
|
||||
public:
|
||||
StrictModeGetter(Parser *p) : parser(p) { }
|
||||
|
||||
bool get() const;
|
||||
StrictMode::StrictModeState get() const;
|
||||
CompileError *queuedStrictModeError() const;
|
||||
void setQueuedStrictModeError(CompileError *e);
|
||||
};
|
||||
|
||||
class TokenStream
|
||||
@ -437,7 +470,7 @@ class TokenStream
|
||||
PARA_SEPARATOR = 0x2029
|
||||
};
|
||||
|
||||
static const size_t ntokens = 4; /* 1 current + 2 lookahead, rounded
|
||||
static const size_t ntokens = 4; /* 1 current + 3 lookahead, rounded
|
||||
to power of 2 to avoid divmod by 3 */
|
||||
static const unsigned ntokensMask = ntokens - 1;
|
||||
|
||||
@ -467,7 +500,7 @@ class TokenStream
|
||||
/* Note that the version and hasMoarXML can get out of sync via setMoarXML. */
|
||||
JSVersion versionNumber() const { return VersionNumber(version); }
|
||||
JSVersion versionWithFlags() const { return version; }
|
||||
bool allowsXML() const { return allowXML && !isStrictMode(); }
|
||||
bool allowsXML() const { return allowXML && strictModeState() != StrictMode::STRICT; }
|
||||
bool hasMoarXML() const { return moarXML || VersionShouldParseXML(versionNumber()); }
|
||||
void setMoarXML(bool enabled) { moarXML = enabled; }
|
||||
|
||||
@ -491,14 +524,15 @@ class TokenStream
|
||||
void setXMLTagMode(bool enabled = true) { setFlag(enabled, TSF_XMLTAGMODE); }
|
||||
void setXMLOnlyMode(bool enabled = true) { setFlag(enabled, TSF_XMLONLYMODE); }
|
||||
void setUnexpectedEOF(bool enabled = true) { setFlag(enabled, TSF_UNEXPECTED_EOF); }
|
||||
void setOctalCharacterEscape(bool enabled = true) { setFlag(enabled, TSF_OCTAL_CHAR); }
|
||||
|
||||
bool isStrictMode() const { return strictModeGetter ? strictModeGetter->get() : false; }
|
||||
StrictMode::StrictModeState strictModeState() const
|
||||
{
|
||||
return strictModeGetter ? strictModeGetter->get() : StrictMode::NOTSTRICT;
|
||||
}
|
||||
bool isXMLTagMode() const { return !!(flags & TSF_XMLTAGMODE); }
|
||||
bool isXMLOnlyMode() const { return !!(flags & TSF_XMLONLYMODE); }
|
||||
bool isUnexpectedEOF() const { return !!(flags & TSF_UNEXPECTED_EOF); }
|
||||
bool isEOF() const { return !!(flags & TSF_EOF); }
|
||||
bool hasOctalCharacterEscape() const { return flags & TSF_OCTAL_CHAR; }
|
||||
|
||||
// TokenStream-specific error reporters.
|
||||
bool reportError(unsigned errorNumber, ...);
|
||||
@ -576,7 +610,7 @@ class TokenStream
|
||||
|
||||
TokenKind peekToken() {
|
||||
if (lookahead != 0) {
|
||||
JS_ASSERT(lookahead == 1);
|
||||
JS_ASSERT(lookahead <= 2);
|
||||
return tokens[(cursor + lookahead) & ntokensMask].type;
|
||||
}
|
||||
TokenKind tt = getTokenInternal();
|
||||
@ -594,7 +628,7 @@ class TokenStream
|
||||
return TOK_EOL;
|
||||
|
||||
if (lookahead != 0) {
|
||||
JS_ASSERT(lookahead == 1);
|
||||
JS_ASSERT(lookahead <= 2);
|
||||
return tokens[(cursor + lookahead) & ntokensMask].type;
|
||||
}
|
||||
|
||||
|
@ -17,18 +17,27 @@ namespace js {
|
||||
|
||||
inline
|
||||
SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fun,
|
||||
FunctionBox *funbox)
|
||||
FunctionBox *funbox, StrictMode::StrictModeState sms)
|
||||
: context(cx),
|
||||
fun_(cx, fun),
|
||||
funbox_(funbox),
|
||||
scopeChain_(cx, scopeChain),
|
||||
bindings(),
|
||||
bindingsRoot(cx, &bindings),
|
||||
cxFlags(cx)
|
||||
cxFlags(cx),
|
||||
strictModeState(sms)
|
||||
{
|
||||
JS_ASSERT((fun && !scopeChain_) || (!fun && !funbox));
|
||||
}
|
||||
|
||||
inline bool
|
||||
SharedContext::inStrictMode()
|
||||
{
|
||||
JS_ASSERT(strictModeState != StrictMode::UNKNOWN);
|
||||
JS_ASSERT_IF(inFunction() && funbox(), funbox()->strictModeState == strictModeState);
|
||||
return strictModeState == StrictMode::STRICT;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
TreeContext::blockid()
|
||||
{
|
||||
@ -42,8 +51,9 @@ TreeContext::atBodyLevel()
|
||||
}
|
||||
|
||||
inline bool
|
||||
SharedContext::needStrictChecks() {
|
||||
return context->hasStrictOption() || inStrictMode();
|
||||
SharedContext::needStrictChecks()
|
||||
{
|
||||
return context->hasStrictOption() || strictModeState != StrictMode::NOTSTRICT;
|
||||
}
|
||||
|
||||
inline
|
||||
@ -61,6 +71,7 @@ TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, u
|
||||
decls(prs->context),
|
||||
yieldNode(NULL),
|
||||
functionList(NULL),
|
||||
queuedStrictModeError(NULL),
|
||||
parserTC(&prs->tc),
|
||||
lexdeps(prs->context),
|
||||
parent(prs->tc),
|
||||
@ -83,9 +94,13 @@ TreeContext::init()
|
||||
return decls.init() && lexdeps.ensureMap(sc->context);
|
||||
}
|
||||
|
||||
// For functions the tree context is constructed and destructed a second
|
||||
// time during code generation. To avoid a redundant stats update in such
|
||||
// cases, we store UINT16_MAX in maxScopeDepth.
|
||||
inline void
|
||||
TreeContext::setQueuedStrictModeError(CompileError *e)
|
||||
{
|
||||
JS_ASSERT(!queuedStrictModeError);
|
||||
queuedStrictModeError = e;
|
||||
}
|
||||
|
||||
inline
|
||||
TreeContext::~TreeContext()
|
||||
{
|
||||
@ -94,6 +109,15 @@ TreeContext::~TreeContext()
|
||||
JS_ASSERT(*parserTC == this);
|
||||
*parserTC = this->parent;
|
||||
sc->context->delete_(funcStmts);
|
||||
if (queuedStrictModeError) {
|
||||
// If the parent context is looking for strict mode violations, pass
|
||||
// ours up. Otherwise, free it.
|
||||
if (parent && parent->sc->strictModeState == StrictMode::UNKNOWN &&
|
||||
!parent->queuedStrictModeError)
|
||||
parent->queuedStrictModeError = queuedStrictModeError;
|
||||
else
|
||||
sc->context->delete_(queuedStrictModeError);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ContextT>
|
||||
|
@ -29,13 +29,6 @@ class ContextFlags {
|
||||
friend struct SharedContext;
|
||||
friend struct FunctionBox;
|
||||
|
||||
// This function/global/eval code body contained a Use Strict Directive.
|
||||
// Treat certain strict warnings as errors, and forbid the use of 'with'.
|
||||
// See also StrictModeGetter, JSScript::strictModeCode,
|
||||
// JSREPORT_STRICT_ERROR, and JSOPTION_STRICT_MODE.
|
||||
//
|
||||
bool inStrictMode:1;
|
||||
|
||||
// The (static) bindings of this script need to support dynamic name
|
||||
// read/write access. Here, 'dynamic' means dynamic dictionary lookup on
|
||||
// the scope chain for a dynamic set of keys. The primary examples are:
|
||||
@ -114,8 +107,7 @@ class ContextFlags {
|
||||
|
||||
public:
|
||||
ContextFlags(JSContext *cx)
|
||||
: inStrictMode(cx->hasRunOption(JSOPTION_STRICT_MODE)),
|
||||
bindingsAccessedDynamically(false),
|
||||
: bindingsAccessedDynamically(false),
|
||||
funIsHeavyweight(false),
|
||||
funIsGenerator(false),
|
||||
funMightAliasLocals(false),
|
||||
@ -144,9 +136,31 @@ struct SharedContext {
|
||||
|
||||
ContextFlags cxFlags;
|
||||
|
||||
|
||||
// strictModeState tracks the strictness of this context. Normally, it
|
||||
// should be STRICT or NOTSTRICT. However, it can be UNKNOWN when parsing
|
||||
// code for which the strictness has not yet been determined. This happens
|
||||
// when parsing the defaults of a functions and non-"use strict" directive
|
||||
// prologue strings.
|
||||
//
|
||||
// Unless its parent is strict, a context starts out in the UNKNOWN
|
||||
// state. Parser::setStrictMode() should be called when a context has been
|
||||
// determined to be strict or it cannot possibly become strict through the
|
||||
// directive prologue. (It might become strict later if it is in the default
|
||||
// expressions of a strict function.)
|
||||
//
|
||||
// If the state is STRICT, all context children are STRICT, too. Neither of
|
||||
// the other two states have this behavior. A funbox with the UNKNOWN state
|
||||
// can have STRICT children but not NOTSTRICT children. NOTSTRICT funboxes
|
||||
// can have any kind of children.
|
||||
//
|
||||
// When parsing is done, no context may be in the UNKNOWN strictness state.
|
||||
StrictMode::StrictModeState strictModeState;
|
||||
|
||||
// If it's function code, fun must be non-NULL and scopeChain must be NULL.
|
||||
// If it's global code, fun and funbox must be NULL.
|
||||
inline SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fun, FunctionBox *funbox);
|
||||
inline SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fun, FunctionBox *funbox,
|
||||
StrictMode::StrictModeState sms);
|
||||
|
||||
// In theory, |fun*| flags are only relevant if |inFunction()| is true.
|
||||
// However, we get and set in some cases where |inFunction()| is false,
|
||||
@ -154,7 +168,6 @@ struct SharedContext {
|
||||
// functions below.
|
||||
#define INFUNC JS_ASSERT(inFunction())
|
||||
|
||||
bool inStrictMode() const { return cxFlags.inStrictMode; }
|
||||
bool bindingsAccessedDynamically() const { return cxFlags.bindingsAccessedDynamically; }
|
||||
bool funIsHeavyweight() const { INFUNC; return cxFlags.funIsHeavyweight; }
|
||||
bool funIsGenerator() const { INFUNC; return cxFlags.funIsGenerator; }
|
||||
@ -163,7 +176,6 @@ struct SharedContext {
|
||||
bool funArgumentsHasLocalBinding() const { INFUNC; return cxFlags.funArgumentsHasLocalBinding; }
|
||||
bool funDefinitelyNeedsArgsObj() const { INFUNC; return cxFlags.funDefinitelyNeedsArgsObj; }
|
||||
|
||||
void setInStrictMode() { cxFlags.inStrictMode = true; }
|
||||
void setBindingsAccessedDynamically() { cxFlags.bindingsAccessedDynamically = true; }
|
||||
void setFunIsHeavyweight() { cxFlags.funIsHeavyweight = true; }
|
||||
void setFunIsGenerator() { INFUNC; cxFlags.funIsGenerator = true; }
|
||||
@ -181,9 +193,9 @@ struct SharedContext {
|
||||
FunctionBox *funbox() const { JS_ASSERT(inFunction()); return funbox_; }
|
||||
JSObject *scopeChain() const { JS_ASSERT(!inFunction()); return scopeChain_; }
|
||||
|
||||
// Return true if we need to check for conditions that elicit
|
||||
// JSOPTION_STRICT warnings or strict mode errors.
|
||||
inline bool needStrictChecks();
|
||||
inline bool inStrictMode();
|
||||
};
|
||||
|
||||
typedef HashSet<JSAtom *> FuncStmtSet;
|
||||
@ -218,6 +230,11 @@ struct TreeContext { /* tree context for semantic checks */
|
||||
generator expression */
|
||||
FunctionBox *functionList;
|
||||
|
||||
// A strict mode error found in this scope or one of its children. It is
|
||||
// used only when strictModeState is UNKNOWN. If the scope turns out to be
|
||||
// strict and this is non-null, it is thrown.
|
||||
CompileError *queuedStrictModeError;
|
||||
|
||||
private:
|
||||
TreeContext **parserTC; /* this points to the Parser's active tc
|
||||
and holds either |this| or one of
|
||||
@ -261,6 +278,8 @@ struct TreeContext { /* tree context for semantic checks */
|
||||
|
||||
inline bool init();
|
||||
|
||||
inline void setQueuedStrictModeError(CompileError *e);
|
||||
|
||||
unsigned blockid();
|
||||
|
||||
// True if we are at the topmost level of a entire script or function body.
|
||||
|
34
js/src/jit-test/tests/arguments/defaults-strict-mode.js
Normal file
@ -0,0 +1,34 @@
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
function f1(f=(function () { return typeof this !== "object"; })) { "use strict"; return f; }
|
||||
assertEq(f1()(), true);
|
||||
function f2(f=(function () { "use strict"; return (function () { return typeof this !== "object"; }) })) { assertEq(typeof this, "object"); return f; }
|
||||
assertEq(f2()()(), true);
|
||||
function f3(f=(function () { return (function () { return typeof this !== "object"; }) })) { "use strict"; return f; }
|
||||
assertEq(f3()()(), true);
|
||||
// These should be okay.
|
||||
function f4(f=(function () { with (Object) {} }), g=(function () { "use strict"; })) {}
|
||||
function f5(g=(function () { "use strict"; }), f=(function () { with (Object) {} })) {}
|
||||
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=delete x) { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
Math.sin(4);
|
||||
eval("function f(a='\\251') { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a='\\251', b=delete x) { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=delete x, b='\\251') { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function () { '\\251'; })) { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function () { with (Object) {} })) { 'use strict'; }");
|
||||
}, SyntaxError);
|
||||
assertThrowsInstanceOf(function () {
|
||||
eval("function f(a=(function (b, b) {})) { 'use strict'; }");
|
||||
}, SyntaxError);
|
20
js/src/jit-test/tests/debug/Frame-onStep-iterators.js
Normal file
@ -0,0 +1,20 @@
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debugger;
|
||||
var gw = dbg.addDebuggee(g);
|
||||
var log;
|
||||
var a = [];
|
||||
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
log += 'd';
|
||||
frame.onStep = function () {
|
||||
// This handler must not wipe out the debuggee's value in JSContext::iterValue.
|
||||
log += 's';
|
||||
// This will use JSContext::iterValue in the debugger.
|
||||
for (let i of a)
|
||||
log += 'i';
|
||||
};
|
||||
};
|
||||
|
||||
log = '';
|
||||
g.eval("debugger; for (let i of [1,2,3]) print(i);");
|
||||
assertEq(!!log.match(/^ds*$/), true);
|
@ -313,6 +313,9 @@ js::InvokeKernel(JSContext *cx, CallArgs args, MaybeConstruct construct)
|
||||
JS_ASSERT(args.length() <= StackSpace::ARGS_LENGTH_MAX);
|
||||
JS_ASSERT(!cx->compartment->activeAnalysis);
|
||||
|
||||
/* We should never enter a new script while cx->iterValue is live. */
|
||||
JS_ASSERT(cx->iterValue.isMagic(JS_NO_ITER_VALUE));
|
||||
|
||||
/* MaybeConstruct is a subset of InitialFrameFlags */
|
||||
InitialFrameFlags initial = (InitialFrameFlags) construct;
|
||||
|
||||
|
@ -560,7 +560,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
|
||||
// that make 12 insufficent. In case 16 is also insufficent, I've bumped
|
||||
// it to 20.
|
||||
ensureSpace(20);
|
||||
int initFlushCount = flushCount();
|
||||
DebugOnly<int> initFlushCount = flushCount();
|
||||
#endif
|
||||
// [Bug 614953]: This can only be made conditional once the ARM back-end
|
||||
// is able to distinguish and patch both call sequences. Other
|
||||
|
@ -1223,6 +1223,21 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Preserve the debuggee's iterValue while handlers run. */
|
||||
class PreserveIterValue {
|
||||
JSContext *cx;
|
||||
RootedValue savedIterValue;
|
||||
|
||||
public:
|
||||
PreserveIterValue(JSContext *cx) : cx(cx), savedIterValue(cx, cx->iterValue) {
|
||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||
}
|
||||
~PreserveIterValue() {
|
||||
cx->iterValue = savedIterValue;
|
||||
}
|
||||
};
|
||||
PreserveIterValue piv(cx);
|
||||
|
||||
/* Call all the onStep handlers we found. */
|
||||
for (JSObject **p = frames.begin(); p != frames.end(); p++) {
|
||||
JSObject *frame = *p;
|
||||
|
6
layout/base/crashtests/763223-1.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="position: relative; padding-right: 59729800px;" onload="document.documentElement.offsetHeight; document.getElementById('x').style.right = '100px';">
|
||||
<div id="x" style="position: absolute; width: -moz-fit-content; height: 3px;"></div>
|
||||
</body>
|
||||
</html>
|
@ -356,4 +356,5 @@ skip-if(Android&&!browserIsRemote) asserts(0-2) pref(dom.disable_open_during_loa
|
||||
asserts(0-2) load 736389-1.xhtml # sometimes the above assertions are delayed and is reported on this test instead
|
||||
asserts-if(winWidget,0-2) load 736924-1.html # bug 738803
|
||||
load 749816-1.html
|
||||
load 763223-1.html
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) load 763702.xhtml
|
||||
|
@ -12385,9 +12385,9 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
|
||||
parentFrame->RemoveStateBits(~nsFrameState(0));
|
||||
parentFrame->AddStateBits(savedState);
|
||||
|
||||
NS_ASSERTION(parentSize.width != NS_INTRINSICSIZE &&
|
||||
parentSize.height != NS_INTRINSICSIZE,
|
||||
"parentSize should be valid");
|
||||
NS_WARN_IF_FALSE(parentSize.width != NS_INTRINSICSIZE &&
|
||||
parentSize.height != NS_INTRINSICSIZE,
|
||||
"parentSize should be valid");
|
||||
parentReflowState.SetComputedWidth(NS_MAX(parentSize.width, 0));
|
||||
parentReflowState.SetComputedHeight(NS_MAX(parentSize.height, 0));
|
||||
parentReflowState.mComputedMargin.SizeTo(0, 0, 0, 0);
|
||||
|
@ -82,7 +82,7 @@ nsPlaceholderFrame::AddInlineMinWidth(nsRenderingContext *aRenderingContext,
|
||||
// false.
|
||||
|
||||
// ...but push floats onto the list
|
||||
if (mOutOfFlowFrame->GetStyleDisplay()->mFloats != NS_STYLE_FLOAT_NONE)
|
||||
if (mOutOfFlowFrame->GetStyleDisplay()->IsFloating())
|
||||
aData->floats.AppendElement(mOutOfFlowFrame);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ nsPlaceholderFrame::AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
|
||||
// false.
|
||||
|
||||
// ...but push floats onto the list
|
||||
if (mOutOfFlowFrame->GetStyleDisplay()->mFloats != NS_STYLE_FLOAT_NONE)
|
||||
if (mOutOfFlowFrame->GetStyleDisplay()->IsFloating())
|
||||
aData->floats.AppendElement(mOutOfFlowFrame);
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,9 @@ HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
|
||||
# random-if(!cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-aat-ref.html
|
||||
# random-if(cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-ot-ref.html
|
||||
|
||||
== local-1.html local-1-ref.html
|
||||
== local-styled-1.html local-styled-1-ref.html
|
||||
# bug 769194 - src:local() completely broken on android
|
||||
fails-if(Android) == local-1.html local-1-ref.html
|
||||
fails-if(Android) == local-styled-1.html local-styled-1-ref.html
|
||||
|
||||
HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
|
||||
HTTP(..) == synthetic-variations.html synthetic-variations-ref.html
|
||||
|
@ -591,8 +591,7 @@ nsSVGUtils::GetPostFilterVisualOverflowRect(nsIFrame *aFrame,
|
||||
return aPreFilterRect;
|
||||
}
|
||||
|
||||
return filter->GetPostFilterBounds(aFrame, nsnull, &aPreFilterRect) -
|
||||
aFrame->GetPosition();
|
||||
return filter->GetPostFilterBounds(aFrame, nsnull, &aPreFilterRect);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1970,7 +1970,8 @@ pages_commit(void *addr, size_t size)
|
||||
{
|
||||
|
||||
# ifdef MOZ_MEMORY_WINDOWS
|
||||
VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE))
|
||||
abort();
|
||||
# else
|
||||
if (mmap(addr, size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE |
|
||||
MAP_ANON, -1, 0) == MAP_FAILED)
|
||||
|
@ -39,7 +39,6 @@ import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
@ -177,10 +176,12 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
public void onClick(View view) {
|
||||
int[] lockLocation = new int[2];
|
||||
view.getLocationOnScreen(lockLocation);
|
||||
LayoutParams lockLayoutParams = (LayoutParams) view.getLayoutParams();
|
||||
|
||||
RelativeLayout.LayoutParams iconsLayoutParams =
|
||||
(RelativeLayout.LayoutParams) ((View) view.getParent()).getLayoutParams();
|
||||
|
||||
// Calculate the left margin for the arrow based on the position of the lock icon.
|
||||
int leftMargin = lockLocation[0] - lockLayoutParams.rightMargin;
|
||||
int leftMargin = lockLocation[0] - iconsLayoutParams.rightMargin;
|
||||
SiteIdentityPopup.getInstance().show(mSiteSecurity, leftMargin);
|
||||
}
|
||||
});
|
||||
@ -237,6 +238,9 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
mMenu.setVisibility(View.VISIBLE);
|
||||
mMenu.setOnClickListener(new Button.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
if (!GeckoApp.mAppContext.isTablet() && GeckoApp.mAppContext.areTabsShown())
|
||||
return;
|
||||
|
||||
GeckoApp.mAppContext.openOptionsMenu();
|
||||
}
|
||||
});
|
||||
@ -328,7 +332,8 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
|
||||
private void toggleTabs() {
|
||||
if (GeckoApp.mAppContext.areTabsShown()) {
|
||||
GeckoApp.mAppContext.hideTabs();
|
||||
if (GeckoApp.mAppContext.isTablet())
|
||||
GeckoApp.mAppContext.hideTabs();
|
||||
} else {
|
||||
// hide the virtual keyboard
|
||||
InputMethodManager imm =
|
||||
@ -375,11 +380,25 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
|
||||
public void updateTabs(boolean areTabsShown) {
|
||||
if (areTabsShown) {
|
||||
mTabs.setImageLevel(TABS_EXPANDED);
|
||||
mTabs.getBackground().setLevel(TABS_EXPANDED);
|
||||
|
||||
if (!GeckoApp.mAppContext.isTablet()) {
|
||||
mTabs.setImageLevel(0);
|
||||
mTabsCount.setVisibility(View.GONE);
|
||||
mMenu.setImageLevel(TABS_EXPANDED);
|
||||
mMenu.getBackground().setLevel(TABS_EXPANDED);
|
||||
} else {
|
||||
mTabs.setImageLevel(TABS_EXPANDED);
|
||||
}
|
||||
} else {
|
||||
mTabs.setImageLevel(TABS_CONTRACTED);
|
||||
mTabs.getBackground().setLevel(TABS_CONTRACTED);
|
||||
|
||||
if (!GeckoApp.mAppContext.isTablet()) {
|
||||
mTabsCount.setVisibility(View.VISIBLE);
|
||||
mMenu.setImageLevel(TABS_CONTRACTED);
|
||||
mMenu.getBackground().setLevel(TABS_CONTRACTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +549,7 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
return false;
|
||||
|
||||
if (mMenuPopup != null && !mMenuPopup.isShowing())
|
||||
mMenuPopup.show(mMenu);
|
||||
mMenuPopup.showAsDropDown(mMenu);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -547,7 +566,6 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
|
||||
// MenuPopup holds the MenuPanel in Honeycomb/ICS devices with no hardware key
|
||||
public class MenuPopup extends PopupWindow {
|
||||
private ImageView mArrow;
|
||||
private RelativeLayout mPanel;
|
||||
|
||||
public MenuPopup(Context context) {
|
||||
@ -563,7 +581,6 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.menu_popup, null);
|
||||
setContentView(layout);
|
||||
|
||||
mArrow = (ImageView) layout.findViewById(R.id.menu_arrow);
|
||||
mPanel = (RelativeLayout) layout.findViewById(R.id.menu_panel);
|
||||
}
|
||||
|
||||
@ -571,32 +588,5 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
mPanel.removeAllViews();
|
||||
mPanel.addView(view);
|
||||
}
|
||||
|
||||
public void show(View anchor) {
|
||||
showAsDropDown(anchor);
|
||||
|
||||
int location[] = new int[2];
|
||||
anchor.getLocationOnScreen(location);
|
||||
|
||||
int menuButtonWidth = anchor.getWidth();
|
||||
int arrowWidth = mArrow.getWidth();
|
||||
|
||||
int rightMostEdge = location[0] + menuButtonWidth;
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
int leftMargin = (int)(240 * metrics.density) - (metrics.widthPixels - location[0] - menuButtonWidth/2);
|
||||
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mArrow.getLayoutParams();
|
||||
RelativeLayout.LayoutParams newParams = new RelativeLayout.LayoutParams(params);
|
||||
newParams.setMargins(leftMargin,
|
||||
params.topMargin,
|
||||
0,
|
||||
params.bottomMargin);
|
||||
|
||||
// From the left of popup, the arrow should move half of (menuButtonWidth - arrowWidth)
|
||||
mArrow.setLayoutParams(newParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ package org.mozilla.gecko;
|
||||
import java.util.HashMap;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
@ -15,6 +16,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
@ -29,11 +31,15 @@ public class DoorHangerPopup extends PopupWindow {
|
||||
private LinearLayout mContent;
|
||||
|
||||
private boolean mInflated;
|
||||
private ImageView mArrow;
|
||||
private int mArrowWidth;
|
||||
|
||||
public DoorHangerPopup(Context aContext) {
|
||||
super(aContext);
|
||||
mContext = aContext;
|
||||
|
||||
mInflated = false;
|
||||
mArrowWidth = aContext.getResources().getDimensionPixelSize(R.dimen.doorhanger_arrow_width);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
@ -44,6 +50,7 @@ public class DoorHangerPopup extends PopupWindow {
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.doorhangerpopup, null);
|
||||
mArrow = (ImageView) layout.findViewById(R.id.doorhanger_arrow);
|
||||
mContent = (LinearLayout) layout.findViewById(R.id.doorhanger_container);
|
||||
|
||||
setContentView(layout);
|
||||
@ -137,10 +144,18 @@ public class DoorHangerPopup extends PopupWindow {
|
||||
public void showPopup(View v) {
|
||||
fixBackgroundForFirst();
|
||||
|
||||
if (isShowing())
|
||||
if (isShowing()) {
|
||||
update();
|
||||
else
|
||||
showAsDropDown(v);
|
||||
return;
|
||||
}
|
||||
|
||||
// On tablets, we need to position the popup so that the center of the arrow points to the
|
||||
// center of the anchor view. On phones the popup stretches across the entire screen, so the
|
||||
// arrow position is determined by its left margin.
|
||||
int offset = GeckoApp.mAppContext.isTablet() ? v.getWidth()/2 - mArrowWidth/2 -
|
||||
((RelativeLayout.LayoutParams) mArrow.getLayoutParams()).leftMargin : 0;
|
||||
|
||||
showAsDropDown(v, offset, 0);
|
||||
}
|
||||
|
||||
private void fixBackgroundForFirst() {
|
||||
|
@ -1702,15 +1702,11 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
public boolean isTablet() {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
int screenLayout = getResources().getConfiguration().screenLayout;
|
||||
|
||||
// Checking for sw600dp for 7" tablet.
|
||||
if (((metrics.widthPixels / metrics.density) >= 600) &&
|
||||
((metrics.heightPixels / metrics.density) >= 600))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return (((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) ||
|
||||
((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE));
|
||||
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
|
@ -168,8 +168,7 @@ FENNEC_PP_XML_FILES = \
|
||||
res/menu/gecko_menu.xml \
|
||||
res/menu-v11/gecko_menu.xml \
|
||||
res/menu-v11/titlebar_contextmenu.xml \
|
||||
res/menu-xlarge/gecko_menu.xml \
|
||||
res/menu-sw600dp/gecko_menu.xml \
|
||||
res/menu-large/gecko_menu.xml \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@ -293,32 +292,27 @@ RES_LAYOUT = \
|
||||
res/layout/validation_message.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_LAYOUT_V14 = \
|
||||
res/layout-v14/browser_toolbar.xml \
|
||||
res/layout-v14/tabs_panel_toolbar.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_LAYOUT_LAND_V14 = \
|
||||
res/layout-land-v14/browser_toolbar.xml \
|
||||
res/layout-land-v14/tabs_panel_toolbar.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_LAYOUT_XLARGE = \
|
||||
res/layout-xlarge/awesomebar_search.xml \
|
||||
res/layout-xlarge/awesomebar_tab_indicator.xml \
|
||||
res/layout-xlarge/browser_toolbar.xml \
|
||||
res/layout-xlarge/doorhangerpopup.xml \
|
||||
res/layout-xlarge/gecko_app.xml \
|
||||
res/layout-xlarge/remote_tabs_child.xml \
|
||||
res/layout-xlarge/remote_tabs_group.xml \
|
||||
res/layout-xlarge/tabs_panel_toolbar.xml \
|
||||
res/layout-xlarge/tabs_row.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_LAYOUT_SW600DP = \
|
||||
res/layout-sw600dp/awesomebar_search.xml \
|
||||
res/layout-sw600dp/awesomebar_tab_indicator.xml \
|
||||
res/layout-sw600dp/browser_toolbar.xml \
|
||||
res/layout-sw600dp/doorhangerpopup.xml \
|
||||
res/layout-sw600dp/gecko_app.xml \
|
||||
res/layout-sw600dp/remote_tabs_child.xml \
|
||||
res/layout-sw600dp/remote_tabs_group.xml \
|
||||
res/layout-sw600dp/tabs_panel_toolbar.xml \
|
||||
res/layout-sw600dp/tabs_row.xml \
|
||||
RES_LAYOUT_LARGE = \
|
||||
res/layout-large/awesomebar_search.xml \
|
||||
res/layout-large/awesomebar_tab_indicator.xml \
|
||||
res/layout-large/browser_toolbar.xml \
|
||||
res/layout-large/doorhangerpopup.xml \
|
||||
res/layout-large/gecko_app.xml \
|
||||
res/layout-large/remote_tabs_child.xml \
|
||||
res/layout-large/remote_tabs_group.xml \
|
||||
res/layout-large/site_identity_popup.xml \
|
||||
res/layout-large/tabs_panel_toolbar.xml \
|
||||
res/layout-large/tabs_row.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES = \
|
||||
@ -337,24 +331,15 @@ RES_VALUES_V11 = \
|
||||
res/values-v11/themes.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES_XLARGE = \
|
||||
res/values-xlarge/dimens.xml \
|
||||
res/values-xlarge/styles.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES_SW600DP = \
|
||||
res/values-sw600dp/dimens.xml \
|
||||
res/values-sw600dp/styles.xml \
|
||||
RES_VALUES_LARGE = \
|
||||
res/values-large/dimens.xml \
|
||||
res/values-large/styles.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES_LAND_V14 = \
|
||||
res/values-land-v14/dimens.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_VALUES_SW600DP_V14 = \
|
||||
res/values-sw600dp-v14/dimens.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_XML = \
|
||||
$(SYNC_RES_XML) \
|
||||
$(NULL)
|
||||
@ -408,15 +393,13 @@ RES_DRAWABLE_BASE = \
|
||||
res/drawable/tab_close.png \
|
||||
res/drawable/tab_thumbnail_default.png \
|
||||
res/drawable/tab_thumbnail_shadow.png \
|
||||
res/drawable/tabs_carat_contracted.png \
|
||||
res/drawable/tabs_carat_expanded.png \
|
||||
res/drawable/tabs_expanded_normal.png \
|
||||
res/drawable/tabs_expanded_pressed.png \
|
||||
res/drawable/tabs_carat.png \
|
||||
res/drawable/tabs_normal.png \
|
||||
res/drawable/tabs_pressed.png \
|
||||
res/drawable/address_bar_back_button.xml \
|
||||
res/drawable/address_bar_back_button_bg.xml \
|
||||
res/drawable/address_bar_back_button_pressed_bg.xml \
|
||||
res/drawable/address_bar_bg_curve.png \
|
||||
res/drawable/address_bar_forward_button.xml \
|
||||
res/drawable/address_bar_texture_port.png \
|
||||
res/drawable/address_bar_url.xml \
|
||||
@ -490,12 +473,10 @@ RES_DRAWABLE_HDPI = \
|
||||
res/drawable-hdpi/tab_close.png \
|
||||
res/drawable-hdpi/tab_thumbnail_default.png \
|
||||
res/drawable-hdpi/tab_thumbnail_shadow.png \
|
||||
res/drawable-hdpi/tabs_carat_contracted.png \
|
||||
res/drawable-hdpi/tabs_carat_expanded.png \
|
||||
res/drawable-hdpi/tabs_expanded_normal.png \
|
||||
res/drawable-hdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-hdpi/tabs_carat.png \
|
||||
res/drawable-hdpi/tabs_normal.png \
|
||||
res/drawable-hdpi/tabs_pressed.png \
|
||||
res/drawable-hdpi/address_bar_bg_curve.png \
|
||||
res/drawable-hdpi/address_bar_texture_port.png \
|
||||
res/drawable-hdpi/address_bar_url_default.9.png \
|
||||
res/drawable-hdpi/address_bar_url_pressed.9.png \
|
||||
@ -579,6 +560,7 @@ RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/abouthome_sync_bg.9.png \
|
||||
res/drawable-xhdpi-v11/abouthome_sync_pressed_bg.9.png \
|
||||
res/drawable-xhdpi-v11/abouthome_thumbnail.png \
|
||||
res/drawable-xhdpi-v11/address_bar_bg_curve.png \
|
||||
res/drawable-xhdpi-v11/address_bar_bg_shadow.png \
|
||||
res/drawable-xhdpi-v11/alert_addon.png \
|
||||
res/drawable-xhdpi-v11/alert_app.png \
|
||||
@ -606,12 +588,11 @@ RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/remote_tabs_on.png \
|
||||
res/drawable-xhdpi-v11/tab_new.png \
|
||||
res/drawable-xhdpi-v11/tab_close.png \
|
||||
res/drawable-xhdpi-v11/tab_new_normal.png \
|
||||
res/drawable-xhdpi-v11/tab_new_pressed.png \
|
||||
res/drawable-xhdpi-v11/tab_thumbnail_default.png \
|
||||
res/drawable-xhdpi-v11/tab_thumbnail_shadow.png \
|
||||
res/drawable-xhdpi-v11/tabs_carat_contracted.png \
|
||||
res/drawable-xhdpi-v11/tabs_carat_expanded.png \
|
||||
res/drawable-xhdpi-v11/tabs_expanded_normal.png \
|
||||
res/drawable-xhdpi-v11/tabs_expanded_pressed.png \
|
||||
res/drawable-xhdpi-v11/tabs_carat.png \
|
||||
res/drawable-xhdpi-v11/tabs_normal.png \
|
||||
res/drawable-xhdpi-v11/tabs_pressed.png \
|
||||
res/drawable-xhdpi-v11/address_bar_texture_port.png \
|
||||
@ -629,7 +610,8 @@ RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/reading_list.png \
|
||||
res/drawable-xhdpi-v11/larry_blue.png \
|
||||
res/drawable-xhdpi-v11/larry_green.png \
|
||||
res/drawable-xhdpi-v11/menu.png \
|
||||
res/drawable-xhdpi-v11/menu_normal.png \
|
||||
res/drawable-xhdpi-v11/menu_pressed.png \
|
||||
res/drawable-xhdpi-v11/menu_panel_bg.9.png \
|
||||
res/drawable-xhdpi-v11/menu_popup_bg.9.png \
|
||||
res/drawable-xhdpi-v11/menu_popup_arrow.png \
|
||||
@ -643,6 +625,16 @@ RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/validation_bg.9.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_XHDPI_V14 = \
|
||||
res/drawable-xhdpi-v14/menu.png \
|
||||
res/drawable-xhdpi-v14/menu_normal.png \
|
||||
res/drawable-xhdpi-v14/menu_pressed.png \
|
||||
res/drawable-xhdpi-v14/tab_new_normal.png \
|
||||
res/drawable-xhdpi-v14/tab_new_pressed.png \
|
||||
res/drawable-xhdpi-v14/tabs_normal.png \
|
||||
res/drawable-xhdpi-v14/tabs_pressed.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_LAND_V14 = \
|
||||
res/drawable-land-v14/address_bar_bg.xml \
|
||||
$(NULL)
|
||||
@ -650,16 +642,14 @@ RES_DRAWABLE_LAND_V14 = \
|
||||
RES_DRAWABLE_LAND_MDPI_V14 = \
|
||||
res/drawable-land-mdpi-v14/ic_awesomebar_go.png \
|
||||
res/drawable-land-mdpi-v14/ic_awesomebar_search.png \
|
||||
res/drawable-land-mdpi-v14/address_bar_bg_curve.png \
|
||||
res/drawable-land-mdpi-v14/address_bar_texture_land.png \
|
||||
res/drawable-land-mdpi-v14/address_bar_url_default.9.png \
|
||||
res/drawable-land-mdpi-v14/address_bar_url_pressed.9.png \
|
||||
res/drawable-land-mdpi-v14/remote_tabs_off.png \
|
||||
res/drawable-land-mdpi-v14/remote_tabs_on.png \
|
||||
res/drawable-land-mdpi-v14/tab_new.png \
|
||||
res/drawable-land-mdpi-v14/tabs_carat_contracted.png \
|
||||
res/drawable-land-mdpi-v14/tabs_carat_expanded.png \
|
||||
res/drawable-land-mdpi-v14/tabs_expanded_normal.png \
|
||||
res/drawable-land-mdpi-v14/tabs_expanded_pressed.png \
|
||||
res/drawable-land-mdpi-v14/tabs_carat.png \
|
||||
res/drawable-land-mdpi-v14/tabs_normal.png \
|
||||
res/drawable-land-mdpi-v14/tabs_pressed.png \
|
||||
res/drawable-land-mdpi-v14/urlbar_stop.png \
|
||||
@ -671,16 +661,14 @@ RES_DRAWABLE_LAND_MDPI_V14 = \
|
||||
RES_DRAWABLE_LAND_HDPI_V14 = \
|
||||
res/drawable-land-hdpi-v14/ic_awesomebar_go.png \
|
||||
res/drawable-land-hdpi-v14/ic_awesomebar_search.png \
|
||||
res/drawable-land-hdpi-v14/address_bar_bg_curve.png \
|
||||
res/drawable-land-hdpi-v14/address_bar_texture_land.png \
|
||||
res/drawable-land-hdpi-v14/address_bar_url_default.9.png \
|
||||
res/drawable-land-hdpi-v14/address_bar_url_pressed.9.png \
|
||||
res/drawable-land-hdpi-v14/remote_tabs_off.png \
|
||||
res/drawable-land-hdpi-v14/remote_tabs_on.png \
|
||||
res/drawable-land-hdpi-v14/tab_new.png \
|
||||
res/drawable-land-hdpi-v14/tabs_carat_contracted.png \
|
||||
res/drawable-land-hdpi-v14/tabs_carat_expanded.png \
|
||||
res/drawable-land-hdpi-v14/tabs_expanded_normal.png \
|
||||
res/drawable-land-hdpi-v14/tabs_expanded_pressed.png \
|
||||
res/drawable-land-hdpi-v14/tabs_carat.png \
|
||||
res/drawable-land-hdpi-v14/tabs_normal.png \
|
||||
res/drawable-land-hdpi-v14/tabs_pressed.png \
|
||||
res/drawable-land-hdpi-v14/urlbar_stop.png \
|
||||
@ -692,210 +680,120 @@ RES_DRAWABLE_LAND_HDPI_V14 = \
|
||||
RES_DRAWABLE_LAND_XHDPI_V14 = \
|
||||
res/drawable-land-xhdpi-v14/ic_awesomebar_go.png \
|
||||
res/drawable-land-xhdpi-v14/ic_awesomebar_search.png \
|
||||
res/drawable-land-xhdpi-v14/address_bar_bg_curve.png \
|
||||
res/drawable-land-xhdpi-v14/address_bar_texture_land.png \
|
||||
res/drawable-land-xhdpi-v14/address_bar_url_default.9.png \
|
||||
res/drawable-land-xhdpi-v14/address_bar_url_pressed.9.png \
|
||||
res/drawable-land-xhdpi-v14/remote_tabs_off.png \
|
||||
res/drawable-land-xhdpi-v14/remote_tabs_on.png \
|
||||
res/drawable-land-xhdpi-v14/tab_new.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_carat_contracted.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_carat_expanded.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_expanded_normal.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_expanded_pressed.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_carat.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_normal.png \
|
||||
res/drawable-land-xhdpi-v14/tabs_pressed.png \
|
||||
res/drawable-land-xhdpi-v14/urlbar_stop.png \
|
||||
res/drawable-land-xhdpi-v14/menu.png \
|
||||
res/drawable-land-xhdpi-v14/menu_normal.png \
|
||||
res/drawable-land-xhdpi-v14/menu_pressed.png \
|
||||
res/drawable-land-xhdpi-v14/reader.png \
|
||||
res/drawable-land-xhdpi-v14/site_security_identified.png \
|
||||
res/drawable-land-xhdpi-v14/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_XLARGE_MDPI = \
|
||||
res/drawable-xlarge-mdpi/address_bar_bg.xml \
|
||||
res/drawable-xlarge-mdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-xlarge-mdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-xlarge-mdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-xlarge-mdpi/address_bar_url_default.9.png \
|
||||
res/drawable-xlarge-mdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-xlarge-mdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-xlarge-mdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-xlarge-mdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-xlarge-mdpi/menu.png \
|
||||
res/drawable-xlarge-mdpi/ic_awesomebar_go.png \
|
||||
res/drawable-xlarge-mdpi/ic_awesomebar_search.png \
|
||||
res/drawable-xlarge-mdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-xlarge-mdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-xlarge-mdpi/ic_menu_reload.png \
|
||||
res/drawable-xlarge-mdpi/ic_menu_forward.png \
|
||||
res/drawable-xlarge-mdpi/remote_tabs_off.png \
|
||||
res/drawable-xlarge-mdpi/remote_tabs_on.png \
|
||||
res/drawable-xlarge-mdpi/tab_new.png \
|
||||
res/drawable-xlarge-mdpi/tabs_carat_contracted.png \
|
||||
res/drawable-xlarge-mdpi/tabs_carat_expanded.png \
|
||||
res/drawable-xlarge-mdpi/tabs_expanded_normal.png \
|
||||
res/drawable-xlarge-mdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-xlarge-mdpi/tabs_normal.png \
|
||||
res/drawable-xlarge-mdpi/tabs_pressed.png \
|
||||
res/drawable-xlarge-mdpi/urlbar_stop.png \
|
||||
res/drawable-xlarge-mdpi/reader.png \
|
||||
res/drawable-xlarge-mdpi/site_security_identified.png \
|
||||
res/drawable-xlarge-mdpi/site_security_verified.png \
|
||||
RES_DRAWABLE_LARGE_MDPI = \
|
||||
res/drawable-large-mdpi/address_bar_bg.xml \
|
||||
res/drawable-large-mdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-large-mdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-large-mdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-large-mdpi/address_bar_url_default.9.png \
|
||||
res/drawable-large-mdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-large-mdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-large-mdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-large-mdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-large-mdpi/menu.png \
|
||||
res/drawable-large-mdpi/ic_awesomebar_go.png \
|
||||
res/drawable-large-mdpi/ic_awesomebar_search.png \
|
||||
res/drawable-large-mdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-large-mdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-large-mdpi/ic_menu_reload.png \
|
||||
res/drawable-large-mdpi/ic_menu_forward.png \
|
||||
res/drawable-large-mdpi/remote_tabs_off.png \
|
||||
res/drawable-large-mdpi/remote_tabs_on.png \
|
||||
res/drawable-large-mdpi/tab_new.png \
|
||||
res/drawable-large-mdpi/tabs_button.xml \
|
||||
res/drawable-large-mdpi/tabs_button_expanded.xml \
|
||||
res/drawable-large-mdpi/tabs_carat_contracted.png \
|
||||
res/drawable-large-mdpi/tabs_carat_expanded.png \
|
||||
res/drawable-large-mdpi/tabs_expanded_normal.png \
|
||||
res/drawable-large-mdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-large-mdpi/tabs_level.xml \
|
||||
res/drawable-large-mdpi/tabs_normal.png \
|
||||
res/drawable-large-mdpi/tabs_pressed.png \
|
||||
res/drawable-large-mdpi/urlbar_stop.png \
|
||||
res/drawable-large-mdpi/reader.png \
|
||||
res/drawable-large-mdpi/site_security_identified.png \
|
||||
res/drawable-large-mdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_XLARGE_HDPI = \
|
||||
res/drawable-xlarge-hdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-xlarge-hdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-xlarge-hdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-xlarge-hdpi/address_bar_url_default.9.png \
|
||||
res/drawable-xlarge-hdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-xlarge-hdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-xlarge-hdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-xlarge-hdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-xlarge-hdpi/menu.png \
|
||||
res/drawable-xlarge-hdpi/ic_awesomebar_go.png \
|
||||
res/drawable-xlarge-hdpi/ic_awesomebar_search.png \
|
||||
res/drawable-xlarge-hdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-xlarge-hdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-xlarge-hdpi/ic_menu_reload.png \
|
||||
res/drawable-xlarge-hdpi/ic_menu_forward.png \
|
||||
res/drawable-xlarge-hdpi/remote_tabs_off.png \
|
||||
res/drawable-xlarge-hdpi/remote_tabs_on.png \
|
||||
res/drawable-xlarge-hdpi/tab_new.png \
|
||||
res/drawable-xlarge-hdpi/tabs_carat_contracted.png \
|
||||
res/drawable-xlarge-hdpi/tabs_carat_expanded.png \
|
||||
res/drawable-xlarge-hdpi/tabs_expanded_normal.png \
|
||||
res/drawable-xlarge-hdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-xlarge-hdpi/tabs_normal.png \
|
||||
res/drawable-xlarge-hdpi/tabs_pressed.png \
|
||||
res/drawable-xlarge-hdpi/urlbar_stop.png \
|
||||
res/drawable-xlarge-hdpi/reader.png \
|
||||
res/drawable-xlarge-hdpi/site_security_identified.png \
|
||||
res/drawable-xlarge-hdpi/site_security_verified.png \
|
||||
RES_DRAWABLE_LARGE_HDPI = \
|
||||
res/drawable-large-hdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-large-hdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-large-hdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-large-hdpi/address_bar_url_default.9.png \
|
||||
res/drawable-large-hdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-large-hdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-large-hdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-large-hdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-large-hdpi/menu.png \
|
||||
res/drawable-large-hdpi/ic_awesomebar_go.png \
|
||||
res/drawable-large-hdpi/ic_awesomebar_search.png \
|
||||
res/drawable-large-hdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-large-hdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-large-hdpi/ic_menu_reload.png \
|
||||
res/drawable-large-hdpi/ic_menu_forward.png \
|
||||
res/drawable-large-hdpi/remote_tabs_off.png \
|
||||
res/drawable-large-hdpi/remote_tabs_on.png \
|
||||
res/drawable-large-hdpi/tab_new.png \
|
||||
res/drawable-large-hdpi/tabs_carat_contracted.png \
|
||||
res/drawable-large-hdpi/tabs_carat_expanded.png \
|
||||
res/drawable-large-hdpi/tabs_expanded_normal.png \
|
||||
res/drawable-large-hdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-large-hdpi/tabs_normal.png \
|
||||
res/drawable-large-hdpi/tabs_pressed.png \
|
||||
res/drawable-large-hdpi/urlbar_stop.png \
|
||||
res/drawable-large-hdpi/reader.png \
|
||||
res/drawable-large-hdpi/site_security_identified.png \
|
||||
res/drawable-large-hdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_XLARGE_XHDPI = \
|
||||
res/drawable-xlarge-xhdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-xlarge-xhdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-xlarge-xhdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-xlarge-xhdpi/address_bar_url_default.9.png \
|
||||
res/drawable-xlarge-xhdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-xlarge-xhdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-xlarge-xhdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-xlarge-xhdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-xlarge-xhdpi/menu.png \
|
||||
res/drawable-xlarge-xhdpi/ic_awesomebar_go.png \
|
||||
res/drawable-xlarge-xhdpi/ic_awesomebar_search.png \
|
||||
res/drawable-xlarge-xhdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-xlarge-xhdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-xlarge-xhdpi/ic_menu_reload.png \
|
||||
res/drawable-xlarge-xhdpi/ic_menu_forward.png \
|
||||
res/drawable-xlarge-xhdpi/remote_tabs_off.png \
|
||||
res/drawable-xlarge-xhdpi/tab_new.png \
|
||||
res/drawable-xlarge-xhdpi/remote_tabs_on.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_carat_contracted.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_carat_expanded.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_expanded_normal.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_normal.png \
|
||||
res/drawable-xlarge-xhdpi/tabs_pressed.png \
|
||||
res/drawable-xlarge-xhdpi/urlbar_stop.png \
|
||||
res/drawable-xlarge-xhdpi/reader.png \
|
||||
res/drawable-xlarge-xhdpi/site_security_identified.png \
|
||||
res/drawable-xlarge-xhdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_SW600DP_MDPI = \
|
||||
res/drawable-sw600dp-mdpi/address_bar_bg.xml \
|
||||
res/drawable-sw600dp-mdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-sw600dp-mdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-sw600dp-mdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-sw600dp-mdpi/address_bar_url_default.9.png \
|
||||
res/drawable-sw600dp-mdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-sw600dp-mdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-sw600dp-mdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-sw600dp-mdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-sw600dp-mdpi/menu.png \
|
||||
res/drawable-sw600dp-mdpi/ic_awesomebar_go.png \
|
||||
res/drawable-sw600dp-mdpi/ic_awesomebar_search.png \
|
||||
res/drawable-sw600dp-mdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-sw600dp-mdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-sw600dp-mdpi/ic_menu_reload.png \
|
||||
res/drawable-sw600dp-mdpi/ic_menu_forward.png \
|
||||
res/drawable-sw600dp-mdpi/remote_tabs_off.png \
|
||||
res/drawable-sw600dp-mdpi/remote_tabs_on.png \
|
||||
res/drawable-sw600dp-mdpi/tab_new.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_carat_contracted.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_carat_expanded.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_expanded_normal.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_normal.png \
|
||||
res/drawable-sw600dp-mdpi/tabs_pressed.png \
|
||||
res/drawable-sw600dp-mdpi/urlbar_stop.png \
|
||||
res/drawable-sw600dp-mdpi/reader.png \
|
||||
res/drawable-sw600dp-mdpi/site_security_identified.png \
|
||||
res/drawable-sw600dp-mdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_SW600DP_HDPI = \
|
||||
res/drawable-sw600dp-hdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-sw600dp-hdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-sw600dp-hdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-sw600dp-hdpi/address_bar_url_default.9.png \
|
||||
res/drawable-sw600dp-hdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-sw600dp-hdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-sw600dp-hdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-sw600dp-hdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-sw600dp-hdpi/menu.png \
|
||||
res/drawable-sw600dp-hdpi/ic_awesomebar_go.png \
|
||||
res/drawable-sw600dp-hdpi/ic_awesomebar_search.png \
|
||||
res/drawable-sw600dp-hdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-sw600dp-hdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-sw600dp-hdpi/ic_menu_reload.png \
|
||||
res/drawable-sw600dp-hdpi/ic_menu_forward.png \
|
||||
res/drawable-sw600dp-hdpi/remote_tabs_off.png \
|
||||
res/drawable-sw600dp-hdpi/remote_tabs_on.png \
|
||||
res/drawable-sw600dp-hdpi/tab_new.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_carat_contracted.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_carat_expanded.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_expanded_normal.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_normal.png \
|
||||
res/drawable-sw600dp-hdpi/tabs_pressed.png \
|
||||
res/drawable-sw600dp-hdpi/urlbar_stop.png \
|
||||
res/drawable-sw600dp-hdpi/reader.png \
|
||||
res/drawable-sw600dp-hdpi/site_security_identified.png \
|
||||
res/drawable-sw600dp-hdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_SW600DP_XHDPI = \
|
||||
res/drawable-sw600dp-xhdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-sw600dp-xhdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-sw600dp-xhdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-sw600dp-xhdpi/address_bar_url_default.9.png \
|
||||
res/drawable-sw600dp-xhdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-sw600dp-xhdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-sw600dp-xhdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-sw600dp-xhdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-sw600dp-xhdpi/menu.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_awesomebar_go.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_awesomebar_search.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_menu_reload.png \
|
||||
res/drawable-sw600dp-xhdpi/ic_menu_forward.png \
|
||||
res/drawable-sw600dp-xhdpi/remote_tabs_off.png \
|
||||
res/drawable-sw600dp-xhdpi/remote_tabs_on.png \
|
||||
res/drawable-sw600dp-xhdpi/tab_new.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_carat_contracted.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_carat_expanded.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_expanded_normal.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_normal.png \
|
||||
res/drawable-sw600dp-xhdpi/tabs_pressed.png \
|
||||
res/drawable-sw600dp-xhdpi/urlbar_stop.png \
|
||||
res/drawable-sw600dp-xhdpi/reader.png \
|
||||
res/drawable-sw600dp-xhdpi/site_security_identified.png \
|
||||
res/drawable-sw600dp-xhdpi/site_security_verified.png \
|
||||
RES_DRAWABLE_LARGE_XHDPI = \
|
||||
res/drawable-large-xhdpi/address_bar_texture_tablet.png \
|
||||
res/drawable-large-xhdpi/address_bar_back_button_bg.png \
|
||||
res/drawable-large-xhdpi/address_bar_back_button_pressed_bg.png \
|
||||
res/drawable-large-xhdpi/address_bar_url_default.9.png \
|
||||
res/drawable-large-xhdpi/address_bar_url_pressed.9.png \
|
||||
res/drawable-large-xhdpi/awesomebar_tab_center.9.png \
|
||||
res/drawable-large-xhdpi/awesomebar_tab_left.9.png \
|
||||
res/drawable-large-xhdpi/awesomebar_tab_right.9.png \
|
||||
res/drawable-large-xhdpi/menu.png \
|
||||
res/drawable-large-xhdpi/ic_awesomebar_go.png \
|
||||
res/drawable-large-xhdpi/ic_awesomebar_search.png \
|
||||
res/drawable-large-xhdpi/ic_menu_bookmark_add.png \
|
||||
res/drawable-large-xhdpi/ic_menu_bookmark_remove.png \
|
||||
res/drawable-large-xhdpi/ic_menu_reload.png \
|
||||
res/drawable-large-xhdpi/ic_menu_forward.png \
|
||||
res/drawable-large-xhdpi/remote_tabs_off.png \
|
||||
res/drawable-large-xhdpi/tab_new.png \
|
||||
res/drawable-large-xhdpi/remote_tabs_on.png \
|
||||
res/drawable-large-xhdpi/tabs_carat_contracted.png \
|
||||
res/drawable-large-xhdpi/tabs_carat_expanded.png \
|
||||
res/drawable-large-xhdpi/tabs_expanded_normal.png \
|
||||
res/drawable-large-xhdpi/tabs_expanded_pressed.png \
|
||||
res/drawable-large-xhdpi/tabs_normal.png \
|
||||
res/drawable-large-xhdpi/tabs_pressed.png \
|
||||
res/drawable-large-xhdpi/urlbar_stop.png \
|
||||
res/drawable-large-xhdpi/reader.png \
|
||||
res/drawable-large-xhdpi/site_security_identified.png \
|
||||
res/drawable-large-xhdpi/site_security_verified.png \
|
||||
$(NULL)
|
||||
|
||||
RES_COLOR = \
|
||||
@ -924,8 +822,8 @@ MOZ_ANDROID_DRAWABLES += \
|
||||
mobile/android/base/resources/drawable/abouthome_bg_repeat.xml \
|
||||
mobile/android/base/resources/drawable/abouthome_sync_box.xml \
|
||||
mobile/android/base/resources/drawable/abouthome_topsites_bg_repeat.xml \
|
||||
mobile/android/base/resources/drawable/address_bar_bg.xml \
|
||||
mobile/android/base/resources/drawable/action_bar_button.xml \
|
||||
mobile/android/base/resources/drawable/address_bar_bg.xml \
|
||||
mobile/android/base/resources/drawable/address_bar_bg_shadow.png \
|
||||
mobile/android/base/resources/drawable/address_bar_bg_shadow_repeat.xml \
|
||||
mobile/android/base/resources/drawable/autocomplete_list_bg.9.png \
|
||||
@ -934,6 +832,8 @@ MOZ_ANDROID_DRAWABLES += \
|
||||
mobile/android/base/resources/drawable/awesomebar_tab_unselected.xml \
|
||||
mobile/android/base/resources/drawable/desktop_notification.png \
|
||||
mobile/android/base/resources/drawable/highlight.xml \
|
||||
mobile/android/base/resources/drawable/menu_button.xml \
|
||||
mobile/android/base/resources/drawable/menu_level.xml \
|
||||
mobile/android/base/resources/drawable/progress_spinner.xml \
|
||||
mobile/android/base/resources/drawable/progress_spinner_1.png \
|
||||
mobile/android/base/resources/drawable/progress_spinner_2.png \
|
||||
@ -951,33 +851,33 @@ MOZ_ANDROID_DRAWABLES += \
|
||||
mobile/android/base/resources/drawable/start.png \
|
||||
mobile/android/base/resources/drawable/site_security_level.xml \
|
||||
mobile/android/base/resources/drawable/suggestion_selector.xml \
|
||||
mobile/android/base/resources/drawable/tab_new_button.xml \
|
||||
mobile/android/base/resources/drawable/tabs_button.xml \
|
||||
mobile/android/base/resources/drawable/tabs_button_contracted.xml \
|
||||
mobile/android/base/resources/drawable/tabs_button_expanded.xml \
|
||||
mobile/android/base/resources/drawable/tabs_level.xml \
|
||||
mobile/android/base/resources/drawable/tabs_tray_bg_repeat.xml \
|
||||
mobile/android/base/resources/drawable/tabs_tray_selected_bg_repeat.xml \
|
||||
mobile/android/base/resources/drawable/tabs_tray_active_selector.xml \
|
||||
mobile/android/base/resources/drawable/tabs_tray_default_selector.xml \
|
||||
mobile/android/base/resources/drawable/tabs_tray_list_divider.xml \
|
||||
mobile/android/base/resources/drawable/tabs_shadow.xml \
|
||||
mobile/android/base/resources/drawable/shadow.png \
|
||||
$(NULL)
|
||||
|
||||
MOZ_ANDROID_DRAWABLES += $(shell if test -e $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn; then cat $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/android-resources.mn | tr '\n' ' '; fi)
|
||||
|
||||
RESOURCES=$(RES_LAYOUT) $(RES_LAYOUT_LAND_V14) $(RES_LAYOUT_XLARGE) $(RES_LAYOUT_SW600DP) $(RES_VALUES) $(RES_VALUES_V11) $(RES_VALUES_XLARGE) $(RES_VALUES_SW600DP) $(RES_VALUES_LAND_V14) $(RES_VALUES_SW600DP_V14) $(RES_XML) $(RES_ANIM) $(RES_DRAWABLE_NODPI) $(RES_DRAWABLE_BASE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_HDPI) $(RES_DRAWABLE_MDPI_V11) $(RES_DRAWABLE_HDPI_V11) $(RES_DRAWABLE_XHDPI_V11) $(RES_DRAWABLE_LAND_V14) $(RES_DRAWABLE_LAND_MDPI_V14) $(RES_DRAWABLE_LAND_HDPI_V14) $(RES_DRAWABLE_LAND_XHDPI_V14) $(RES_DRAWABLE_XLARGE_MDPI) $(RES_DRAWABLE_XLARGE_HDPI) $(RES_DRAWABLE_XLARGE_XHDPI) $(RES_DRAWABLE_SW600DP_MDPI) $(RES_DRAWABLE_SW600DP_HDPI) $(RES_DRAWABLE_SW600DP_XHDPI) $(RES_COLOR) $(RES_MENU) $(RES_RAW)
|
||||
RESOURCES=$(RES_LAYOUT) $(RES_LAYOUT_V14) $(RES_LAYOUT_LAND_V14) $(RES_LAYOUT_LARGE) $(RES_VALUES) $(RES_VALUES_V11) $(RES_VALUES_LARGE) $(RES_VALUES_LAND_V14) $(RES_VALUES_LARGE_V14) $(RES_XML) $(RES_ANIM) $(RES_DRAWABLE_NODPI) $(RES_DRAWABLE_BASE) $(RES_DRAWABLE_LDPI) $(RES_DRAWABLE_HDPI) $(RES_DRAWABLE_MDPI_V11) $(RES_DRAWABLE_HDPI_V11) $(RES_DRAWABLE_XHDPI_V11) $(RES_DRAWABLE_XHDPI_V14) $(RES_DRAWABLE_LAND_V14) $(RES_DRAWABLE_LAND_MDPI_V14) $(RES_DRAWABLE_LAND_HDPI_V14) $(RES_DRAWABLE_LAND_XHDPI_V14) $(RES_DRAWABLE_LARGE_MDPI) $(RES_DRAWABLE_LARGE_HDPI) $(RES_DRAWABLE_LARGE_XHDPI) $(RES_COLOR) $(RES_MENU) $(RES_RAW)
|
||||
|
||||
RES_DIRS= \
|
||||
res/layout \
|
||||
res/layout-v14 \
|
||||
res/layout-land-v14 \
|
||||
res/layout-xlarge \
|
||||
res/layout-sw600dp \
|
||||
res/layout-large \
|
||||
res/values \
|
||||
res/values-v11 \
|
||||
res/values-xlarge \
|
||||
res/values-sw600dp \
|
||||
res/values-large \
|
||||
res/values-land-v14 \
|
||||
res/values-sw600dp-v14 \
|
||||
res/values-large-v14 \
|
||||
res/xml \
|
||||
res/anim \
|
||||
res/drawable-nodpi \
|
||||
@ -985,26 +885,21 @@ RES_DIRS= \
|
||||
res/drawable-mdpi \
|
||||
res/drawable-hdpi \
|
||||
res/drawable \
|
||||
res/drawable-mdpi-v9 \
|
||||
res/drawable-hdpi-v9 \
|
||||
res/drawable-mdpi-v11 \
|
||||
res/drawable-hdpi-v11 \
|
||||
res/drawable-xhdpi-v11 \
|
||||
res/drawable-xhdpi-v14 \
|
||||
res/drawable-land-v14 \
|
||||
res/drawable-land-mdpi-v14 \
|
||||
res/drawable-land-hdpi-v14 \
|
||||
res/drawable-land-xhdpi-v14 \
|
||||
res/drawable-xlarge-mdpi \
|
||||
res/drawable-xlarge-hdpi \
|
||||
res/drawable-xlarge-xhdpi \
|
||||
res/drawable-sw600dp-mdpi \
|
||||
res/drawable-sw600dp-hdpi \
|
||||
res/drawable-sw600dp-xhdpi \
|
||||
res/drawable-large-mdpi \
|
||||
res/drawable-large-hdpi \
|
||||
res/drawable-large-xhdpi \
|
||||
res/color \
|
||||
res/menu \
|
||||
res/menu-v11 \
|
||||
res/menu-xlarge \
|
||||
res/menu-sw600dp \
|
||||
res/menu-large \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -61,7 +61,8 @@ public class SiteIdentityPopup extends PopupWindow {
|
||||
private void init() {
|
||||
setBackgroundDrawable(new BitmapDrawable());
|
||||
setOutsideTouchable(true);
|
||||
setWindowLayoutMode(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
|
||||
setWindowLayoutMode(GeckoApp.mAppContext.isTablet() ? LayoutParams.WRAP_CONTENT : LayoutParams.FILL_PARENT,
|
||||
LayoutParams.WRAP_CONTENT);
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(GeckoApp.mAppContext);
|
||||
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.site_identity_popup, null);
|
||||
@ -147,13 +148,21 @@ public class SiteIdentityPopup extends PopupWindow {
|
||||
mSupplemental.setTextColor(mResources.getColor(R.color.identity_identified));
|
||||
}
|
||||
|
||||
// Position the mArrow according to lock position
|
||||
int offset = 0;
|
||||
if (GeckoApp.mAppContext.isTablet()) {
|
||||
int popupWidth = mResources.getDimensionPixelSize(R.dimen.site_identity_popup_width);
|
||||
int arrowWidth = mResources.getDimensionPixelSize(R.dimen.doorhanger_arrow_width);
|
||||
|
||||
// Double arrowWidth to leave extra space on the right side of the arrow
|
||||
leftMargin = popupWidth - arrowWidth*2;
|
||||
offset = 0 - popupWidth + arrowWidth*3/2 + v.getWidth()/2;
|
||||
}
|
||||
|
||||
LayoutParams layoutParams = (LayoutParams) mArrow.getLayoutParams();
|
||||
LayoutParams newLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
newLayoutParams.setMargins(leftMargin, layoutParams.topMargin, 0, 0);
|
||||
mArrow.setLayoutParams(newLayoutParams);
|
||||
|
||||
// This will place the popup at the correct vertical position
|
||||
showAsDropDown(v);
|
||||
showAsDropDown(v, offset, 0);
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |