Merge mozilla-inbound into mozilla-central.

This commit is contained in:
Mounir Lamouri 2011-07-11 16:18:03 +02:00
commit 0fc5d0deac
66 changed files with 1419 additions and 447 deletions

View File

@ -1351,6 +1351,18 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
rv = ParseURL(PromiseFlatString(aURL));
NS_ENSURE_SUCCESS(rv, rv);
// Don't allow https:// to open ws://
nsCOMPtr<nsIURI> originURI;
PRBool originHTTPS;
if (!mSecure &&
!Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
PR_FALSE) &&
NS_SUCCEEDED(NS_NewURI(getter_AddRefs(originURI), mUTF16Origin)) &&
NS_SUCCEEDED(originURI->SchemeIs("https", &originHTTPS)) &&
originHTTPS) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// sets the protocol
if (!aProtocol.IsEmpty()) {
rv = SetProtocol(PromiseFlatString(aProtocol));

View File

@ -2103,17 +2103,6 @@ nsGenericHTMLElement::SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue)
return SetAttr(kNameSpaceID_None, aAttr, aValue, PR_TRUE);
}
nsresult
nsGenericHTMLElement::GetStringAttrWithDefault(nsIAtom* aAttr,
const char* aDefault,
nsAString& aResult)
{
if (!GetAttr(kNameSpaceID_None, aAttr, aResult)) {
CopyASCIItoUTF16(aDefault, aResult);
}
return NS_OK;
}
nsresult
nsGenericHTMLElement::SetBoolAttr(nsIAtom* aAttr, PRBool aValue)
{

View File

@ -609,19 +609,6 @@ protected:
*/
NS_HIDDEN_(nsresult) SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue);
/**
* Helper method for NS_IMPL_STRING_ATTR_DEFAULT_VALUE macro.
* Gets the value of an attribute, returns specified default value if the
* attribute isn't set. Only works for attributes in null namespace.
*
* @param aAttr name of attribute.
* @param aDefault default-value to return if attribute isn't set.
* @param aResult result value [out]
*/
NS_HIDDEN_(nsresult) GetStringAttrWithDefault(nsIAtom* aAttr,
const char* aDefault,
nsAString& aResult);
/**
* Helper method for NS_IMPL_BOOL_ATTR macro.
* Gets value of boolean attribute. Only works for attributes in null
@ -1084,23 +1071,6 @@ protected:
return SetAttrHelper(nsGkAtoms::_atom, aValue); \
}
/**
* A macro to implement the getter and setter for a given string
* valued content property with a default value.
* The method uses the generic GetAttr and SetAttr methods.
*/
#define NS_IMPL_STRING_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
NS_IMETHODIMP \
_class::Get##_method(nsAString& aValue) \
{ \
return GetStringAttrWithDefault(nsGkAtoms::_atom, _default, aValue);\
} \
NS_IMETHODIMP \
_class::Set##_method(const nsAString& aValue) \
{ \
return SetAttrHelper(nsGkAtoms::_atom, aValue); \
}
/**
* A macro to implement the getter and setter for a given boolean
* valued content property. The method uses the generic GetAttr and

View File

@ -222,7 +222,7 @@ nsHTMLTableCellElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Abbr, abbr)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Axis, axis)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, BgColor, bgcolor)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, Ch, _char, ".")
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Ch, _char)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, ChOff, charoff)
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, ColSpan, colspan, 1)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Headers, headers)
@ -230,7 +230,7 @@ NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Height, height)
NS_IMPL_BOOL_ATTR(nsHTMLTableCellElement, NoWrap, nowrap)
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, RowSpan, rowspan, 1)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Scope, scope)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableCellElement, VAlign, valign, "middle")
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, VAlign, valign)
NS_IMPL_STRING_ATTR(nsHTMLTableCellElement, Width, width)

View File

@ -111,11 +111,11 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableColElement)
NS_IMPL_ELEMENT_CLONE(nsHTMLTableColElement)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Align, align, "left")
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Ch, _char, ".")
NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Align, align)
NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Ch, _char)
NS_IMPL_STRING_ATTR(nsHTMLTableColElement, ChOff, charoff)
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, Span, span, 1)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableColElement, VAlign, valign, "middle")
NS_IMPL_STRING_ATTR(nsHTMLTableColElement, VAlign, valign)
NS_IMPL_STRING_ATTR(nsHTMLTableColElement, Width, width)

View File

@ -965,17 +965,10 @@ nsHTMLTableElement::ParseAttribute(PRInt32 aNamespaceID,
aAttribute == nsGkAtoms::cellpadding) {
return aResult.ParseSpecialIntValue(aValue);
}
if (aAttribute == nsGkAtoms::cols) {
if (aAttribute == nsGkAtoms::cols ||
aAttribute == nsGkAtoms::border) {
return aResult.ParseIntWithBounds(aValue, 0);
}
if (aAttribute == nsGkAtoms::border) {
if (!aResult.ParseIntWithBounds(aValue, 0)) {
// XXX this should really be NavQuirks only to allow non numeric value
aResult.SetTo(1);
}
return PR_TRUE;
}
if (aAttribute == nsGkAtoms::height) {
return aResult.ParseSpecialIntValue(aValue);
}
@ -983,14 +976,12 @@ nsHTMLTableElement::ParseAttribute(PRInt32 aNamespaceID,
if (aResult.ParseSpecialIntValue(aValue)) {
// treat 0 width as auto
nsAttrValue::ValueType type = aResult.Type();
if ((type == nsAttrValue::eInteger &&
aResult.GetIntegerValue() == 0) ||
(type == nsAttrValue::ePercent &&
aResult.GetPercentValue() == 0.0f)) {
return PR_FALSE;
}
return !((type == nsAttrValue::eInteger &&
aResult.GetIntegerValue() == 0) ||
(type == nsAttrValue::ePercent &&
aResult.GetPercentValue() == 0.0f));
}
return PR_TRUE;
return PR_FALSE;
}
if (aAttribute == nsGkAtoms::align) {

View File

@ -359,11 +359,11 @@ nsHTMLTableRowElement::DeleteCell(PRInt32 aValue)
return RemoveChild(cell, getter_AddRefs(retChild));
}
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, Align, align, "left")
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Align, align)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, BgColor, bgcolor)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, Ch, _char, ".")
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, Ch, _char)
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, ChOff, charoff)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableRowElement, VAlign, valign, "middle")
NS_IMPL_STRING_ATTR(nsHTMLTableRowElement, VAlign, valign)
PRBool

View File

@ -120,9 +120,9 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTableSectionElement)
NS_IMPL_ELEMENT_CLONE(nsHTMLTableSectionElement)
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, Align, align, "left")
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, VAlign, valign, "middle")
NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLTableSectionElement, Ch, _char, ".")
NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, Align, align)
NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, VAlign, valign)
NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, Ch, _char)
NS_IMPL_STRING_ATTR(nsHTMLTableSectionElement, ChOff, charoff)

View File

@ -273,6 +273,7 @@ _TEST_FILES = \
test_bug659596.html \
test_bug659743.xml \
test_bug660663.html \
test_bug586786.html \
test_restore_from_parser_fragment.html \
$(NULL)

View File

@ -0,0 +1,58 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=586786
-->
<head>
<title>Test for Bug 586786</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="reflect.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=586786">Mozilla Bug 586786</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 586786 **/
var elements = ["col", "colgroup", "tbody", "tfoot", "thead", "tr", "td", "th"];
for(var i = 0; i < elements.length; i++)
{
reflectString({
element: document.createElement(elements[i]),
attribute: "align",
otherValues: [ "left", "right", "center", "justify", "char" ]
});
reflectString({
element: document.createElement(elements[i]),
attribute: "vAlign",
otherValues: [ "top", "middle", "bottom", "baseline" ]
});
reflectString({
element: document.createElement(elements[i]),
attribute: {idl: "ch", content: "char"}
});
}
// table.border, table.width
reflectString({
element: document.createElement("table"),
attribute: "border"
});
reflectString({
element: document.createElement("table"),
attribute: "width"
});
</script>
</pre>
</body>
</html>

View File

@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>

View File

@ -61,6 +61,7 @@ import android.util.*;
import android.net.*;
import android.database.*;
import android.provider.*;
import android.telephony.*;
abstract public class GeckoApp
extends Activity
@ -77,6 +78,7 @@ abstract public class GeckoApp
public Handler mMainHandler;
private IntentFilter mConnectivityFilter;
private BroadcastReceiver mConnectivityReceiver;
private PhoneStateListener mPhoneStateListener;
enum LaunchState {PreLaunch, Launching, WaitButton,
Launched, GeckoRunning, GeckoExiting};
@ -232,6 +234,8 @@ abstract public class GeckoApp
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mConnectivityReceiver = new GeckoConnectivityReceiver();
mPhoneStateListener = new GeckoPhoneStateListener();
if (!checkAndSetLaunchState(LaunchState.PreLaunch,
LaunchState.Launching))
return;
@ -326,6 +330,10 @@ abstract public class GeckoApp
super.onPause();
unregisterReceiver(mConnectivityReceiver);
TelephonyManager tm = (TelephonyManager)
GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
@Override
@ -344,6 +352,13 @@ abstract public class GeckoApp
onNewIntent(getIntent());
registerReceiver(mConnectivityReceiver, mConnectivityFilter);
TelephonyManager tm = (TelephonyManager)
GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
// Notify if network state changed since we paused
GeckoAppShell.onNetworkStateChange(true);
}
@Override

View File

@ -58,6 +58,7 @@ import android.graphics.*;
import android.widget.*;
import android.hardware.*;
import android.location.*;
import android.telephony.*;
import android.webkit.MimeTypeMap;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
@ -94,6 +95,10 @@ public class GeckoAppShell
static private File sCacheFile = null;
static private int sFreeSpace = -1;
static private String sNetworkState = "unknown";
static private String sNetworkType = "unknown";
static private int sNetworkTypeCode = 0;
/* The Android-side API: API methods that Android calls */
// Initialization methods
@ -108,7 +113,7 @@ public class GeckoAppShell
public static native void callObserver(String observerKey, String topic, String data);
public static native void removeObserver(String observerKey);
public static native void loadLibs(String apkName, boolean shouldExtract);
public static native void onChangeNetworkLinkStatus(String status);
public static native void onChangeNetworkLinkStatus(String status, String type);
public static native void reportJavaCrash(String stack);
// A looper thread, accessed by GeckoAppShell.getHandler
@ -654,6 +659,9 @@ public class GeckoAppShell
// mLaunchState can only be Launched at this point
GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoRunning);
sendPendingEventsToGecko();
// Refresh the network connectivity state
onNetworkStateChange(false);
}
static void onXreExit() {
@ -1010,20 +1018,92 @@ public class GeckoAppShell
}
public static boolean isNetworkLinkUp() {
ConnectivityManager cm = (ConnectivityManager)
GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null || !info.isConnected())
if (sNetworkState == "up")
return true;
return false;
}
public static boolean isNetworkLinkKnown() {
if (sNetworkState == "unknown")
return false;
return true;
}
public static boolean isNetworkLinkKnown() {
public static int getNetworkLinkType() {
return sNetworkTypeCode;
}
public static void onNetworkStateChange(boolean notifyChanged) {
String state;
String type;
int typeCode;
ConnectivityManager cm = (ConnectivityManager)
GeckoApp.mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.getActiveNetworkInfo() == null)
return false;
return true;
NetworkInfo info = cm.getActiveNetworkInfo();
// Note, these strings and codes correspond to those specified in
// nsINetworkLinkService. Make sure to keep them in sync!
type = "unknown";
typeCode = 0;
if (info == null) {
state = "unknown";
} else if (!info.isConnected()) {
state = "down";
} else {
state = "up";
int androidType = info.getType();
if (androidType == ConnectivityManager.TYPE_WIFI) {
type = "wifi";
typeCode = 3;
} else if (androidType == ConnectivityManager.TYPE_WIMAX) {
type = "wimax";
typeCode = 4;
} else if (androidType == ConnectivityManager.TYPE_MOBILE) {
TelephonyManager tm = (TelephonyManager)
GeckoApp.mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
typeCode = tm.getNetworkType();
// Note that the value of some of these constants are used due
// to not all of these existing in API level 8.
//
// In particular, EVDO_B appears at level 9, and EHRPD and LTE
// appear at level 11.
if (androidType == TelephonyManager.NETWORK_TYPE_GPRS ||
androidType == TelephonyManager.NETWORK_TYPE_EDGE ||
androidType == TelephonyManager.NETWORK_TYPE_CDMA ||
androidType == TelephonyManager.NETWORK_TYPE_IDEN ||
androidType == TelephonyManager.NETWORK_TYPE_1xRTT) {
type = "2g";
typeCode = 5;
} else if (androidType == TelephonyManager.NETWORK_TYPE_UMTS ||
androidType == TelephonyManager.NETWORK_TYPE_HSDPA ||
androidType == TelephonyManager.NETWORK_TYPE_HSUPA ||
androidType == TelephonyManager.NETWORK_TYPE_HSPA ||
androidType == TelephonyManager.NETWORK_TYPE_EVDO_0 ||
androidType == TelephonyManager.NETWORK_TYPE_EVDO_A ||
androidType == 12 || // TelephonyManager.NETWORK_TYPE_EVDO_B
androidType == 14) { // TelephonyManager.NETWORK_TYPE_EHRPD
type = "3g";
typeCode = 6;
} else if (androidType == 13) { // TelephonyManager.NETWORK_TYPE_LTE
type = "4g";
typeCode = 7;
}
}
}
// If the network state has changed, notify Gecko
if (notifyChanged && (state != sNetworkState || typeCode != sNetworkTypeCode)) {
Log.i("GeckoAppShell", "Network state changed: (" + state + ", " + type + ") ");
sNetworkState = state;
sNetworkType = type;
sNetworkTypeCode = typeCode;
if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning))
onChangeNetworkLinkStatus(sNetworkState, sNetworkType);
}
}
public static void setSelectedLocale(String localeCode) {

View File

@ -38,25 +38,12 @@
package org.mozilla.gecko;
import android.content.*;
import android.net.*;
public class GeckoConnectivityReceiver
extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
String status;
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null)
status = "unknown";
else if (!info.isConnected())
status = "down";
else
status = "up";
if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning))
GeckoAppShell.onChangeNetworkLinkStatus(status);
GeckoAppShell.onNetworkStateChange(true);
}
}

View File

@ -0,0 +1,50 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Lord <chrislord.net@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko;
import android.telephony.*;
public class GeckoPhoneStateListener
extends PhoneStateListener
{
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
GeckoAppShell.onNetworkStateChange(true);
}
}

View File

@ -52,6 +52,7 @@ JAVAFILES = \
GeckoEvent.java \
GeckoSurfaceView.java \
GeckoInputConnection.java \
GeckoPhoneStateListener.java \
AlertNotification.java \
$(NULL)

View File

@ -47,7 +47,7 @@ FORCE_STATIC_LIB = 1
LIBXUL_LIBRARY = 1
LOCAL_INCLUDES += -I$(srcdir)/../src
CPPSRCS = mozJSComponentLoader.cpp mozJSSubScriptLoader.cpp
CPPSRCS = mozJSComponentLoader.cpp mozJSSubScriptLoader.cpp mozJSLoaderUtils.cpp
EXTRA_JS_MODULES = XPCOMUtils.jsm ISO8601DateUtils.jsm

View File

@ -58,6 +58,7 @@
#include "nsIServiceManager.h"
#include "nsISupports.h"
#include "mozJSComponentLoader.h"
#include "mozJSLoaderUtils.h"
#include "nsIJSRuntimeService.h"
#include "nsIJSContextStack.h"
#include "nsIXPConnect.h"
@ -386,108 +387,6 @@ ReportOnCaller(JSCLContextHelper &helper,
return NS_OK;
}
static nsresult
ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
JSObject **scriptObj)
{
*scriptObj = nsnull;
PRUint32 size;
nsresult rv = stream->Read32(&size);
NS_ENSURE_SUCCESS(rv, rv);
char *data;
rv = stream->ReadBytes(size, &data);
NS_ENSURE_SUCCESS(rv, rv);
JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
xdr->userdata = stream;
JS_XDRMemSetData(xdr, data, size);
if (!JS_XDRScriptObject(xdr, scriptObj)) {
rv = NS_ERROR_FAILURE;
}
// Update data in case ::JS_XDRScript called back into C++ code to
// read an XPCOM object.
//
// In that case, the serialization process must have flushed a run
// of counted bytes containing JS data at the point where the XPCOM
// object starts, after which an encoding C++ callback from the JS
// XDR code must have written the XPCOM object directly into the
// nsIObjectOutputStream.
//
// The deserialization process will XDR-decode counted bytes up to
// but not including the XPCOM object, then call back into C++ to
// read the object, then read more counted bytes and hand them off
// to the JSXDRState, so more JS data can be decoded.
//
// This interleaving of JS XDR data and XPCOM object data may occur
// several times beneath the call to ::JS_XDRScript, above. At the
// end of the day, we need to free (via nsMemory) the data owned by
// the JSXDRState. So we steal it back, nulling xdr's buffer so it
// doesn't get passed to ::JS_free by ::JS_XDRDestroy.
uint32 length;
data = static_cast<char*>(JS_XDRMemGetData(xdr, &length));
if (data) {
JS_XDRMemSetData(xdr, nsnull, 0);
}
JS_XDRDestroy(xdr);
// If data is null now, it must have been freed while deserializing an
// XPCOM object (e.g., a principal) beneath ::JS_XDRScript.
if (data) {
nsMemory::Free(data);
}
return rv;
}
static nsresult
WriteScriptToStream(JSContext *cx, JSObject *scriptObj,
nsIObjectOutputStream *stream)
{
JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
xdr->userdata = stream;
nsresult rv = NS_OK;
if (JS_XDRScriptObject(xdr, &scriptObj)) {
// Get the encoded JSXDRState data and write it. The JSXDRState owns
// this buffer memory and will free it beneath ::JS_XDRDestroy.
//
// If an XPCOM object needs to be written in the midst of the JS XDR
// encoding process, the C++ code called back from the JS engine (e.g.,
// nsEncodeJSPrincipals in caps/src/nsJSPrincipals.cpp) will flush data
// from the JSXDRState to aStream, then write the object, then return
// to JS XDR code with xdr reset so new JS data is encoded at the front
// of the xdr's data buffer.
//
// However many XPCOM objects are interleaved with JS XDR data in the
// stream, when control returns here from ::JS_XDRScript, we'll have
// one last buffer of data to write to aStream.
uint32 size;
const char* data = reinterpret_cast<const char*>
(JS_XDRMemGetData(xdr, &size));
NS_ASSERTION(data, "no decoded JSXDRState data!");
rv = stream->Write32(size);
if (NS_SUCCEEDED(rv)) {
rv = stream->WriteBytes(data, size);
}
} else {
rv = NS_ERROR_FAILURE; // likely to be a principals serialization error
}
JS_XDRDestroy(xdr);
return rv;
}
mozJSComponentLoader::mozJSComponentLoader()
: mRuntime(nsnull),
mContext(nsnull),
@ -849,66 +748,6 @@ class JSPrincipalsHolder
JSPrincipals *mPrincipals;
};
/* static */
nsresult
mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
JSContext *cx, JSObject **scriptObj)
{
nsresult rv;
nsCAutoString spec(kJSCachePrefix);
rv = NS_PathifyURI(uri, spec);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoArrayPtr<char> buf;
PRUint32 len;
rv = cache->GetBuffer(spec.get(), getter_Transfers(buf),
&len);
if (NS_FAILED(rv)) {
return rv; // don't warn since NOT_AVAILABLE is an ok error
}
LOG(("Found %s in startupcache\n", spec.get()));
nsCOMPtr<nsIObjectInputStream> ois;
rv = NS_NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(ois));
NS_ENSURE_SUCCESS(rv, rv);
buf.forget();
return ReadScriptFromStream(cx, ois, scriptObj);
}
nsresult
mozJSComponentLoader::WriteScript(StartupCache* cache, JSObject *scriptObj,
nsIFile *component, nsIURI *uri, JSContext *cx)
{
nsresult rv;
nsCAutoString spec(kJSCachePrefix);
rv = NS_PathifyURI(uri, spec);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("Writing %s to startupcache\n", spec.get()));
nsCOMPtr<nsIObjectOutputStream> oos;
nsCOMPtr<nsIStorageStream> storageStream;
rv = NS_NewObjectOutputWrappedStorageStream(getter_AddRefs(oos),
getter_AddRefs(storageStream),
true);
NS_ENSURE_SUCCESS(rv, rv);
rv = WriteScriptToStream(cx, scriptObj, oos);
oos->Close();
NS_ENSURE_SUCCESS(rv, rv);
nsAutoArrayPtr<char> buf;
PRUint32 len;
rv = NS_NewBufferFromStorageStream(storageStream, getter_Transfers(buf),
&len);
NS_ENSURE_SUCCESS(rv, rv);
rv = cache->PutBuffer(spec.get(), buf, len);
return rv;
}
nsresult
mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
nsIURI *aURI,
@ -1015,8 +854,12 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
PRBool writeToCache = PR_FALSE;
StartupCache* cache = StartupCache::GetSingleton();
nsCAutoString cachePath(kJSCachePrefix);
rv = NS_PathifyURI(aURI, cachePath);
NS_ENSURE_SUCCESS(rv, rv);
if (cache) {
rv = ReadScript(cache, aURI, cx, &scriptObj);
rv = ReadCachedScript(cache, cachePath, cx, &scriptObj);
if (NS_SUCCEEDED(rv)) {
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
} else {
@ -1170,7 +1013,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
if (writeToCache) {
// We successfully compiled the script, so cache it.
rv = WriteScript(cache, scriptObj, aComponentFile, aURI, cx);
rv = WriteCachedScript(cache, cachePath, cx, scriptObj);
// Don't treat failure to write as fatal, since we might be working
// with a read-only cache.

View File

@ -106,11 +106,6 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
char **location,
jsval *exception);
nsresult ReadScript(StartupCache *cache, nsIURI *uri,
JSContext *cx, JSObject **scriptObj);
nsresult WriteScript(StartupCache *cache, JSObject *scriptObj,
nsIFile *component, nsIURI *uri, JSContext *cx);
nsCOMPtr<nsIComponentManager> mCompMgr;
nsCOMPtr<nsIJSRuntimeService> mRuntimeService;
nsCOMPtr<nsIThreadJSContextStack> mContextStack;

View File

@ -0,0 +1,196 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010-2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Wu <mwu@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if !defined(XPCONNECT_STANDALONE)
#include "nsAutoPtr.h"
#include "nsScriptLoader.h"
#include "jsapi.h"
#include "jsxdrapi.h"
#include "mozilla/scache/StartupCache.h"
#include "mozilla/scache/StartupCacheUtils.h"
using namespace mozilla::scache;
static nsresult
ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
JSObject **scriptObj)
{
*scriptObj = nsnull;
PRUint32 size;
nsresult rv = stream->Read32(&size);
NS_ENSURE_SUCCESS(rv, rv);
char *data;
rv = stream->ReadBytes(size, &data);
NS_ENSURE_SUCCESS(rv, rv);
JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
xdr->userdata = stream;
JS_XDRMemSetData(xdr, data, size);
if (!JS_XDRScriptObject(xdr, scriptObj)) {
rv = NS_ERROR_FAILURE;
}
// Update data in case ::JS_XDRScript called back into C++ code to
// read an XPCOM object.
//
// In that case, the serialization process must have flushed a run
// of counted bytes containing JS data at the point where the XPCOM
// object starts, after which an encoding C++ callback from the JS
// XDR code must have written the XPCOM object directly into the
// nsIObjectOutputStream.
//
// The deserialization process will XDR-decode counted bytes up to
// but not including the XPCOM object, then call back into C++ to
// read the object, then read more counted bytes and hand them off
// to the JSXDRState, so more JS data can be decoded.
//
// This interleaving of JS XDR data and XPCOM object data may occur
// several times beneath the call to ::JS_XDRScript, above. At the
// end of the day, we need to free (via nsMemory) the data owned by
// the JSXDRState. So we steal it back, nulling xdr's buffer so it
// doesn't get passed to ::JS_free by ::JS_XDRDestroy.
uint32 length;
data = static_cast<char*>(JS_XDRMemGetData(xdr, &length));
JS_XDRMemSetData(xdr, nsnull, 0);
JS_XDRDestroy(xdr);
// If data is null now, it must have been freed while deserializing an
// XPCOM object (e.g., a principal) beneath ::JS_XDRScript.
nsMemory::Free(data);
return rv;
}
static nsresult
WriteScriptToStream(JSContext *cx, JSObject *scriptObj,
nsIObjectOutputStream *stream)
{
JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
xdr->userdata = stream;
nsresult rv = NS_OK;
if (JS_XDRScriptObject(xdr, &scriptObj)) {
// Get the encoded JSXDRState data and write it. The JSXDRState owns
// this buffer memory and will free it beneath ::JS_XDRDestroy.
//
// If an XPCOM object needs to be written in the midst of the JS XDR
// encoding process, the C++ code called back from the JS engine (e.g.,
// nsEncodeJSPrincipals in caps/src/nsJSPrincipals.cpp) will flush data
// from the JSXDRState to aStream, then write the object, then return
// to JS XDR code with xdr reset so new JS data is encoded at the front
// of the xdr's data buffer.
//
// However many XPCOM objects are interleaved with JS XDR data in the
// stream, when control returns here from ::JS_XDRScript, we'll have
// one last buffer of data to write to aStream.
uint32 size;
const char* data = reinterpret_cast<const char*>
(JS_XDRMemGetData(xdr, &size));
NS_ASSERTION(data, "no decoded JSXDRState data!");
rv = stream->Write32(size);
if (NS_SUCCEEDED(rv)) {
rv = stream->WriteBytes(data, size);
}
} else {
rv = NS_ERROR_FAILURE; // likely to be a principals serialization error
}
JS_XDRDestroy(xdr);
return rv;
}
nsresult
ReadCachedScript(StartupCache* cache, nsACString &uri, JSContext *cx, JSObject **scriptObj)
{
nsresult rv;
nsAutoArrayPtr<char> buf;
PRUint32 len;
rv = cache->GetBuffer(PromiseFlatCString(uri).get(), getter_Transfers(buf),
&len);
if (NS_FAILED(rv)) {
return rv; // don't warn since NOT_AVAILABLE is an ok error
}
nsCOMPtr<nsIObjectInputStream> ois;
rv = NS_NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(ois));
NS_ENSURE_SUCCESS(rv, rv);
buf.forget();
return ReadScriptFromStream(cx, ois, scriptObj);
}
nsresult
WriteCachedScript(StartupCache* cache, nsACString &uri, JSContext *cx, JSObject *scriptObj)
{
nsresult rv;
nsCOMPtr<nsIObjectOutputStream> oos;
nsCOMPtr<nsIStorageStream> storageStream;
rv = NS_NewObjectOutputWrappedStorageStream(getter_AddRefs(oos),
getter_AddRefs(storageStream),
true);
NS_ENSURE_SUCCESS(rv, rv);
rv = WriteScriptToStream(cx, scriptObj, oos);
oos->Close();
NS_ENSURE_SUCCESS(rv, rv);
nsAutoArrayPtr<char> buf;
PRUint32 len;
rv = NS_NewBufferFromStorageStream(storageStream, getter_Transfers(buf),
&len);
NS_ENSURE_SUCCESS(rv, rv);
rv = cache->PutBuffer(PromiseFlatCString(uri).get(), buf, len);
return rv;
}
#endif /* XPCONNECT_STANDALONE */

View File

@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Wu <mwu@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozJSLoaderUtils_h
#define mozJSLoaderUtils_h
#include "nsString.h"
#include "jsapi.h"
class nsIURI;
namespace mozilla {
namespace scache {
class StartupCache;
}
}
nsresult
ReadCachedScript(mozilla::scache::StartupCache* cache, nsACString &uri,
JSContext *cx, JSObject **scriptObj);
nsresult
WriteCachedScript(mozilla::scache::StartupCache* cache, nsACString &uri,
JSContext *cx, JSObject *scriptObj);
#endif /* mozJSLoaderUtils_h */

View File

@ -41,6 +41,7 @@
* ***** END LICENSE BLOCK ***** */
#include "mozJSSubScriptLoader.h"
#include "mozJSLoaderUtils.h"
#include "nsIServiceManager.h"
#include "nsIXPConnect.h"
@ -58,10 +59,15 @@
#include "nsScriptLoader.h"
#include "jsapi.h"
#include "jscntxt.h"
#include "jsdbgapi.h"
#include "jsfriendapi.h"
#include "mozilla/FunctionTimer.h"
#include "mozilla/scache/StartupCache.h"
#include "mozilla/scache/StartupCacheUtils.h"
using namespace mozilla::scache;
/* load() error msgs, XXX localize? */
#define LOAD_ERROR_NOSERVICE "Error creating IO Service."
@ -91,6 +97,89 @@ mozJSSubScriptLoader::~mozJSSubScriptLoader()
NS_IMPL_THREADSAFE_ISUPPORTS1(mozJSSubScriptLoader, mozIJSSubScriptLoader)
static nsresult
ReportError(JSContext *cx, const char *msg)
{
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg)));
return NS_OK;
}
nsresult
mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
jschar *charset, const char *uriStr,
nsIIOService *serv, JSObject **scriptObjp)
{
nsCOMPtr<nsIChannel> chan;
nsCOMPtr<nsIInputStream> instream;
JSPrincipals *jsPrincipals;
JSErrorReporter er;
nsresult rv;
// Instead of calling NS_OpenURI, we create the channel ourselves and call
// SetContentType, to avoid expensive MIME type lookups (bug 632490).
rv = NS_NewChannel(getter_AddRefs(chan), uri, serv,
nsnull, nsnull, nsIRequest::LOAD_NORMAL);
if (NS_SUCCEEDED(rv)) {
chan->SetContentType(NS_LITERAL_CSTRING("application/javascript"));
rv = chan->Open(getter_AddRefs(instream));
}
if (NS_FAILED(rv)) {
return ReportError(cx, LOAD_ERROR_NOSTREAM);
}
PRInt32 len = -1;
rv = chan->GetContentLength(&len);
if (NS_FAILED(rv) || len == -1) {
return ReportError(cx, LOAD_ERROR_NOCONTENT);
}
nsCString buf;
rv = NS_ReadInputStreamToString(instream, buf, len);
if (NS_FAILED(rv))
return rv;
/* we can't hold onto jsPrincipals as a module var because the
* JSPRINCIPALS_DROP macro takes a JSContext, which we won't have in the
* destructor */
rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
if (NS_FAILED(rv) || !jsPrincipals) {
return ReportError(cx, LOAD_ERROR_NOPRINCIPALS);
}
/* set our own error reporter so we can report any bad things as catchable
* exceptions, including the source/line number */
er = JS_SetErrorReporter(cx, mozJSLoaderErrorReporter);
if (charset) {
nsString script;
rv = nsScriptLoader::ConvertToUTF16(
nsnull, reinterpret_cast<const PRUint8*>(buf.get()), len,
nsDependentString(reinterpret_cast<PRUnichar*>(charset)), nsnull, script);
if (NS_FAILED(rv)) {
JSPRINCIPALS_DROP(cx, jsPrincipals);
return ReportError(cx, LOAD_ERROR_BADCHARSET);
}
*scriptObjp =
JS_CompileUCScriptForPrincipals(cx, target_obj, jsPrincipals,
reinterpret_cast<const jschar*>(script.get()),
script.Length(), uriStr, 1);
} else {
*scriptObjp = JS_CompileScriptForPrincipals(cx, target_obj, jsPrincipals, buf.get(),
len, uriStr, 1);
}
JSPRINCIPALS_DROP(cx, jsPrincipals);
/* repent for our evil deeds */
JS_SetErrorReporter(cx, er);
return NS_OK;
}
NS_IMETHODIMP /* args and return value are delt with using XPConnect and JSAPI */
mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
/* [, JSObject *target_obj] */)
@ -227,17 +316,6 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
/* load up the url. From here on, failures are reflected as ``custom''
* js exceptions */
PRInt32 len = -1;
PRUint32 readcount = 0; // Total amount of data read
PRUint32 lastReadCount = 0; // Amount of data read in last Read() call
nsAutoArrayPtr<char> buf;
JSString *errmsg;
JSErrorReporter er;
JSPrincipals *jsPrincipals;
nsCOMPtr<nsIChannel> chan;
nsCOMPtr<nsIInputStream> instream;
nsCOMPtr<nsIURI> uri;
nsCAutoString uriStr;
nsCAutoString scheme;
@ -261,32 +339,27 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
return NS_ERROR_FAILURE;
}
StartupCache* cache = StartupCache::GetSingleton();
nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
if (!serv)
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSERVICE);
goto return_exception;
if (!serv) {
return ReportError(cx, LOAD_ERROR_NOSERVICE);
}
// Make sure to explicitly create the URI, since we'll need the
// canonicalized spec.
rv = NS_NewURI(getter_AddRefs(uri), urlbytes.ptr(), nsnull, serv);
if (NS_FAILED(rv)) {
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOURI);
goto return_exception;
return ReportError(cx, LOAD_ERROR_NOURI);
}
rv = uri->GetSpec(uriStr);
if (NS_FAILED(rv)) {
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSPEC);
goto return_exception;
return ReportError(cx, LOAD_ERROR_NOSPEC);
}
rv = uri->GetScheme(scheme);
if (NS_FAILED(rv))
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSCHEME);
goto return_exception;
if (NS_FAILED(rv)) {
return ReportError(cx, LOAD_ERROR_NOSCHEME);
}
if (!scheme.EqualsLiteral("chrome"))
@ -294,10 +367,8 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
// This might be a URI to a local file, though!
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri);
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(innerURI);
if (!fileURL)
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_URI_NOT_LOCAL);
goto return_exception;
if (!fileURL) {
return ReportError(cx, LOAD_ERROR_URI_NOT_LOCAL);
}
// For file URIs prepend the filename with the filename of the
@ -309,104 +380,38 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
uriStr = tmp;
}
// Instead of calling NS_OpenURI, we create the channel ourselves and call
// SetContentType, to avoid expensive MIME type lookups (bug 632490).
rv = NS_NewChannel(getter_AddRefs(chan), uri, serv,
nsnull, nsnull, nsIRequest::LOAD_NORMAL);
if (NS_SUCCEEDED(rv))
{
chan->SetContentType(NS_LITERAL_CSTRING("application/javascript"));
rv = chan->Open(getter_AddRefs(instream));
bool writeScript = false;
JSObject *scriptObj = nsnull;
JSVersion version = cx->findVersion();
nsCAutoString cachePath;
cachePath.AppendPrintf("jssubloader/%d", version);
NS_PathifyURI(uri, cachePath);
if (cache)
rv = ReadCachedScript(cache, cachePath, cx, &scriptObj);
if (!scriptObj) {
rv = ReadScript(uri, cx, target_obj, charset, (char *)uriStr.get(), serv, &scriptObj);
writeScript = true;
}
if (NS_FAILED(rv))
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSTREAM);
goto return_exception;
}
rv = chan->GetContentLength (&len);
if (NS_FAILED(rv) || len == -1)
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOCONTENT);
goto return_exception;
}
if (NS_FAILED(rv) || !scriptObj)
return rv;
buf = new char[len + 1];
if (!buf)
return NS_ERROR_OUT_OF_MEMORY;
buf[len] = '\0';
do {
rv = instream->Read (buf + readcount, len - readcount, &lastReadCount);
if (NS_FAILED(rv))
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_BADREAD);
goto return_exception;
}
readcount += lastReadCount;
} while (lastReadCount && readcount != PRUint32(len));
if (static_cast<PRUint32>(len) != readcount)
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_READUNDERFLOW);
goto return_exception;
}
ok = false;
if (scriptObj)
ok = JS_ExecuteScriptVersion(cx, target_obj, scriptObj, rval, version);
/* we can't hold onto jsPrincipals as a module var because the
* JSPRINCIPALS_DROP macro takes a JSContext, which we won't have in the
* destructor */
rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals);
if (NS_FAILED(rv) || !jsPrincipals)
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOPRINCIPALS);
goto return_exception;
}
/* set our own error reporter so we can report any bad things as catchable
* exceptions, including the source/line number */
er = JS_SetErrorReporter (cx, mozJSLoaderErrorReporter);
if (charset)
{
nsString script;
rv = nsScriptLoader::ConvertToUTF16(
nsnull, reinterpret_cast<PRUint8*>(buf.get()), len,
nsDependentString(reinterpret_cast<PRUnichar*>(charset)), nsnull, script);
if (NS_FAILED(rv))
{
JSPRINCIPALS_DROP(cx, jsPrincipals);
errmsg = JS_NewStringCopyZ(cx, LOAD_ERROR_BADCHARSET);
goto return_exception;
}
ok = JS_EvaluateUCScriptForPrincipals(cx, target_obj, jsPrincipals,
reinterpret_cast<const jschar*>(script.get()),
script.Length(), uriStr.get(), 1, rval);
}
else
{
ok = JS_EvaluateScriptForPrincipals(cx, target_obj, jsPrincipals,
buf, len, uriStr.get(), 1, rval);
}
JSPRINCIPALS_DROP(cx, jsPrincipals);
if (ok)
{
if (ok) {
JSAutoEnterCompartment rac;
if (!rac.enter(cx, result_obj) || !JS_WrapValue(cx, rval))
return NS_ERROR_UNEXPECTED;
}
/* repent for our evil deeds */
JS_SetErrorReporter (cx, er);
if (cache && ok && writeScript) {
WriteCachedScript(cache, cachePath, cx, scriptObj);
}
cc->SetReturnValueWasSet (ok);
return NS_OK;
return_exception:
JS_SetPendingException (cx, STRING_TO_JSVAL(errmsg));
return NS_OK;
}

View File

@ -38,6 +38,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "jsapi.h"
#include "nsCOMPtr.h"
#include "mozIJSSubScriptLoader.h"
#include "nsIScriptSecurityManager.h"
@ -50,6 +51,8 @@
{0x8e, 0x08, 0x82, 0xfa, 0x0a, 0x33, 0x9b, 0x00} \
}
class nsIIOService;
class mozJSSubScriptLoader : public mozIJSSubScriptLoader
{
public:
@ -61,6 +64,9 @@ public:
NS_DECL_MOZIJSSUBSCRIPTLOADER
private:
nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
jschar *charset, const char *uriStr,
nsIIOService *serv, JSObject **scriptObjp);
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
};

View File

@ -83,6 +83,15 @@ _CHROME_FILES = \
test_bug536567.html \
$(NULL)
ifeq (WINNT,$(OS_ARCH))
$(warning test_bug665540.html disabled due to bug 670053)
else
_CHROME_FILES += \
test_bug665540.html \
bug665540_window.xul \
$(NULL)
endif
libs:: $(_TEST_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Test Select Dropdown Positioning in Fullscreen Window"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
sizemode="fullscreen">
<title><label>Test Select Dropdown Positioning in Fullscreen Window</label></title>
<script>
opener.SimpleTest.waitForFocus(opener.childFocused, window);
</script>
<body xmlns="http://www.w3.org/1999/xhtml">
<select id="select" style="-moz-appearance:none">
<option id="optiona">a</option>
<option>b</option>
</select>
</body>
</window>

View File

@ -0,0 +1,104 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=665540
-->
<head>
<title>Test for Bug 665540 Select dropdown position in fullscreen window</title>
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body onload="openFullscreenWindow()">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=665540">Mozilla Bug 665540</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 665540 **/
SimpleTest.waitForExplicitFinish();
var win;
var optiona;
var eventType = "mouseover";
var timeoutID;
var eventOffsetX = 2;
var eventOffsetY = 2;
function openFullscreenWindow() {
win = open("bug665540_window.xul", "_blank", "resizable=yes,chrome");
// Close our window if the test times out so that it doesn't interfere
// with later tests.
timeoutID = setTimeout(function () {
ok(false, "Test timed out.");
// Provide some time for a screenshot
setTimeout(finish, 1000);
}, 20000);
}
function childFocused() {
ok(win.fullScreen, "window should be fullscreen");
// bug 670026
((navigator.platform.indexOf("Mac") < 0) ? is : todo_is)
(win.windowState, win.STATE_FULLSCREEN,
"window state should be fullscreen");
// The select doesn't open if the mouse click is fired too soon
// (on X11 at least).
setTimeout(openSelect, 1000);
}
function openSelect() {
var select = win.document.getElementById("select");
synthesizeMouseAtCenter(select, {}, win);
// A yield was required on X11 tinderbox machines.
// (Wasn't required on other platforms nor on an X11 system with kwin.)
setTimeout(checkPosition, 1000);
}
function checkPosition() {
optiona = win.document.getElementById("optiona");
optiona.addEventListener(eventType, eventReceived, false);
// If the select dropdown is opened in the position where
// getBoundingClientRect() predicts, then optiona will receive the event.
// The event is received asynchronously (I don't know why), so the handler
// is removed later.
synthesizeMouse(optiona, eventOffsetX, eventOffsetY,
{ type: eventType }, win);
}
function eventReceived(event) {
clearTimeout(timeoutID);
optiona.removeEventListener(eventType, eventReceived, false);
var rect = optiona.getBoundingClientRect();
// Note that fullscreen only fully covers one monitor, so win.screenX can
// be non-zero.
is(event.screenX, win.screenX + rect.left + eventOffsetX,
"event.screenX should match sent event");
is(event.screenY, win.screenY + rect.top + eventOffsetY,
"event.screenY should match sent event");
finish();
}
function finish() {
// bug 670026
((navigator.platform.indexOf("Mac") < 0) ? is : todo_is)
(win.windowState, win.STATE_FULLSCREEN,
"window state should still be fullscreen");
win.close();
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -378,6 +378,11 @@ public:
return sDraggingFrameSelection;
}
/**
* Call AbortDragForSelection() when we abort handling the drag as selecting.
*/
void AbortDragForSelection();
/**
if we are in table cell selection mode. aka ctrl click in table cell
*/
@ -616,7 +621,11 @@ public:
nsIPresShell *GetShell()const { return mShell; }
void DisconnectFromPresShell() { StopAutoScrollTimer(); mShell = nsnull; }
void DisconnectFromPresShell()
{
AbortDragForSelection();
mShell = nsnull;
}
private:
nsresult TakeFocus(nsIContent *aNewFocus,
PRUint32 aContentOffset,

View File

@ -1927,15 +1927,33 @@ nsFrameSelection::SetMouseDownState(PRBool aState)
mMouseDownState = aState;
if (mMouseDownState) {
if (sDraggingFrameSelection) {
sDraggingFrameSelection->AbortDragForSelection();
}
sDraggingFrameSelection = this;
} else {
sDraggingFrameSelection = nsnull;
if (sDraggingFrameSelection == this) {
sDraggingFrameSelection = nsnull;
}
mDragSelectingCells = PR_FALSE;
PostReason(nsISelectionListener::MOUSEUP_REASON);
NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL); //notify that reason is mouse up please.
}
}
void
nsFrameSelection::AbortDragForSelection()
{
if (sDraggingFrameSelection == this) {
sDraggingFrameSelection = nsnull;
mMouseDownState = PR_FALSE;
mDragSelectingCells = PR_FALSE;
PostReason(nsISelectionListener::NO_REASON);
NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL);
}
StopAutoScrollTimer();
}
nsISelection*
nsFrameSelection::GetSelection(SelectionType aType) const
{

View File

@ -24,6 +24,7 @@
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Pierre Phaneuf <pp@ludusdesign.com>
* Frederic Wang <fred.wang@free.fr>
* Florian Scholz <elchi3@elchi3.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -351,12 +352,10 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext,
// adjust the origin of children.
// we need to center around the axis
if (firstChild) { // do nothing for an empty <mfenced></mfenced>
nscoord delta = NS_MAX(containerSize.ascent - axisHeight,
containerSize.descent + axisHeight);
containerSize.ascent = delta + axisHeight;
containerSize.descent = delta - axisHeight;
}
nscoord delta = NS_MAX(containerSize.ascent - axisHeight,
containerSize.descent + axisHeight);
containerSize.ascent = delta + axisHeight;
containerSize.descent = delta - axisHeight;
/////////////////
// opening fence ...

View File

@ -2,12 +2,11 @@
<html>
<head>
<style>
body {
width: 500px;
}
div {
width: 500px;
height: 100px;
opacity: 0.5;
opacity: 0.999;
background: lime;
border: 1px solid black;
}
</style>

View File

@ -9,20 +9,22 @@ body {
}
canvas {
-moz-box-flex: 1;
height: 100px;
opacity: 0.5;
opacity: 0.999;
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="c" width="100" height="100"></canvas>
<script>
var ctx = document.getElementById("c").getContext('2d');
ctx.fillStyle = "lime";
ctx.fillRect(0, 0, 100, 100);
function doTest() {
document.body.style.width = "500px";
document.body.style.width = "502px";
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body>
<canvas></canvas>
</body>
</html>

View File

@ -1545,7 +1545,7 @@ random-if(!winWidget) == 574907-2.html 574907-2-ref.html
random-if(!winWidget) fails-if(winWidget&&!d2d) random-if(winWidget&&d2d) != 574907-3.html 574907-3-notref.html
== 577838-1.html 577838-1-ref.html
== 577838-2.html 577838-2-ref.html
fails-if(Android) random-if(layersGPUAccelerated) == 579323-1.html 579323-1-ref.html
== 579323-1.html 579323-1-ref.html
== 579349-1.html 579349-1-ref.html
== 579655-1.html 579655-1-ref.html
fails-if(Android) == 579808-1.html 579808-1-ref.html

View File

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Stretchy fences -->
<math>
<mrow>
<mo form="prefix" fence="true" stretchy="true">(</mo>
<mtable>
<mtr>
<mtd><mi>a</mi></mtd>
<mtd><mi>b</mi></mtd>
</mtr>
<mtr>
<mtd><mi>c</mi></mtd>
<mtd><mi>d</mi></mtd>
</mtr>
</mtable>
<mo form="postfix" fence="true" stretchy="true">)</mo>
</mrow>
</math>
</body>
</html>

View File

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Stretchy fences -->
<math>
<mfenced>
<mtable>
<mtr>
<mtd><mi>a</mi></mtd>
<mtd><mi>b</mi></mtd>
</mtr>
<mtr>
<mtd><mi>c</mi></mtd>
<mtd><mi>d</mi></mtd>
</mtr>
</mtable>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Too many separators: Excess is ignored -->
<math>
<mfenced separators=";;;;">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
<!-- Too few separators: Last separator is repeated -->
<math>
<mfenced separators=";;,,">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,28 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Too many separators: Excess is ignored -->
<math>
<mfenced separators=";;;;,,,,">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
<!-- Too few separators: Last separator is repeated -->
<math>
<mfenced separators=";;,">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Default values for open, close, separators -->
<math>
<mfenced open="(" close=")" separators=",">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Default values for open, close, separators -->
<math>
<mfenced>
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
<mi>d</mi>
<mi>e</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Empty separators -->
<math>
<mfenced>
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- Empty separators -->
<math>
<mfenced separators="">
<mi>a</mi>
<mi>b</mi>
<mi>c</mi>
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- No arguments -->
<math>
<mfenced>
<mspace />
</mfenced>
</math>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<body>
<!-- No arguments -->
<math>
<mfenced>
</mfenced>
</math>
</body>
</html>

View File

@ -12,6 +12,11 @@
== mfenced-5b.xhtml mfenced-5-ref.xhtml
== mfenced-5c.xhtml mfenced-5-ref.xhtml
== mfenced-5d.xhtml mfenced-5-ref.xhtml
== mfenced-6.html mfenced-6-ref.html
== mfenced-7.html mfenced-7-ref.html
!= mfenced-8.html mfenced-8-ref.html
== mfenced-9.html mfenced-9-ref.html
fails-if(winWidget) == mfenced-10.html mfenced-10-ref.html
== mi-mathvariant-1.xhtml mi-mathvariant-1-ref.xhtml
== mi-mathvariant-2.xhtml mi-mathvariant-2-ref.xhtml
!= non-spacing-accent-1.xhtml non-spacing-accent-1-ref.xhtml

View File

@ -479,6 +479,10 @@ let DOMEvents = {
rel: target.rel,
type: target.type
};
// rel=icon can also have a sizes attribute
if (target.hasAttribute("sizes"))
json.sizes = target.getAttribute("sizes");
sendAsyncMessage("DOMLinkAdded", json);
break;

View File

@ -1039,17 +1039,31 @@ var BrowserUI = {
break;
case "DOMLinkAdded":
// checks for an icon to use for a web app
// priority is : icon < apple-touch-icon
// apple-touch-icon size is 57px and default size is 16px
let rel = json.rel.toLowerCase().split(" ");
if ((rel.indexOf("icon") != -1) && !browser.appIcon) {
// We should also use the sizes attribute if available
if (rel.indexOf("icon") != -1) {
// We use the sizes attribute if available
// see http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon
browser.appIcon = json.href;
let size = 16;
if (json.sizes) {
let sizes = json.sizes.toLowerCase().split(" ");
sizes.forEach(function(item) {
if (item != "any") {
let [w, h] = item.split("x");
size = Math.max(Math.min(w, h), size);
}
});
}
if (size > browser.appIcon.size) {
browser.appIcon.href = json.href;
browser.appIcon.size = size;
}
}
else if (rel.indexOf("apple-touch-icon") != -1) {
else if ((rel.indexOf("apple-touch-icon") != -1) && (browser.appIcon.size < 57)) {
// XXX should we support apple-touch-icon-precomposed ?
// see http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/configuringwebapplications/configuringwebapplications.html
browser.appIcon = json.href;
browser.appIcon.href = json.href;
browser.appIcon.size = 57;
}
// Handle favicon changes

View File

@ -1493,7 +1493,7 @@ Browser.WebProgress.prototype = {
tab.hostChanged = true;
tab.browser.lastLocation = location;
tab.browser.userTypedValue = "";
tab.browser.appIcon = null;
tab.browser.appIcon = { href: null, size:-1 };
#ifdef MOZ_CRASH_REPORTER
if (CrashReporter.enabled)

View File

@ -1682,7 +1682,7 @@ var WebappsUI = {
if (!aManifest) {
// Try every way to get an icon
let browser = Browser.selectedBrowser;
let icon = browser.appIcon;
let icon = browser.appIcon.href;
if (!icon)
icon = browser.mIconURL;
if (!icon)
@ -1753,7 +1753,13 @@ var WebappsUI = {
},
updateWebappsInstall: function updateWebappsInstall(aNode) {
return !document.getElementById("main-window").hasAttribute("webapp");
if (document.getElementById("main-window").hasAttribute("webapp"))
return false;
let browser = Browser.selectedBrowser;
let webapp = Cc["@mozilla.org/webapps/support;1"].getService(Ci.nsIWebappsSupport);
return !(webapp && webapp.isApplicationInstalled(browser.currentURI.spec));
},
install: function(aURI, aTitle, aIcon) {

View File

@ -817,6 +817,10 @@ pref("network.websocket.extensions.stream-deflate", true);
// one time.
pref("network.websocket.max-connections", 200);
// by default scripts loaded from a https:// origin can only open secure
// (i.e. wss://) websockets.
pref("network.websocket.allowInsecureFromHTTPS", false);
// </ws>
// Server-Sent Events

View File

@ -42,9 +42,19 @@
/**
* Network link status monitoring service.
*/
[scriptable, uuid(61618a52-ea91-4277-a4ab-ebe10d7b9a64)]
[scriptable, uuid(f7d3be87-7403-4a1e-b89f-2797776e9b08)]
interface nsINetworkLinkService : nsISupports
{
/* Link type constants */
const unsigned long LINK_TYPE_UNKNOWN = 0;
const unsigned long LINK_TYPE_ETHERNET = 1;
const unsigned long LINK_TYPE_USB = 2;
const unsigned long LINK_TYPE_WIFI = 3;
const unsigned long LINK_TYPE_WIMAX = 4;
const unsigned long LINK_TYPE_2G = 5;
const unsigned long LINK_TYPE_3G = 6;
const unsigned long LINK_TYPE_4G = 7;
/**
* This is set to true when the system is believed to have a usable
* network connection.
@ -62,6 +72,11 @@ interface nsINetworkLinkService : nsISupports
* This is set to true when we believe that isLinkUp is accurate.
*/
readonly attribute boolean linkStatusKnown;
/**
* The type of network connection.
*/
readonly attribute unsigned long linkType;
};
%{C++
@ -85,4 +100,36 @@ interface nsINetworkLinkService : nsISupports
* linkStatusKnown is now false.
*/
#define NS_NETWORK_LINK_DATA_UNKNOWN "unknown"
/**
* We send notifications through nsIObserverService with topic
* NS_NETWORK_LINK_TYPE_TOPIC whenever the network connection type
* changes. We pass one of the valid connection type constants
* below as the aData parameter of the notification.
*/
#define NS_NETWORK_LINK_TYPE_TOPIC "network:link-type-changed"
/** We were unable to determine the network connection type */
#define NS_NETWORK_LINK_TYPE_UNKNOWN "unknown"
/** A standard wired ethernet connection */
#define NS_NETWORK_LINK_TYPE_ETHERNET "ethernet"
/** A connection via a USB port */
#define NS_NETWORK_LINK_TYPE_USB "usb"
/** A connection via a WiFi access point (IEEE802.11) */
#define NS_NETWORK_LINK_TYPE_WIFI "wifi"
/** A connection via WiMax (IEEE802.16) */
#define NS_NETWORK_LINK_TYPE_WIMAX "wimax"
/** A '2G' mobile connection (e.g. GSM, GPRS, EDGE) */
#define NS_NETWORK_LINK_TYPE_2G "2g"
/** A '3G' mobile connection (e.g. UMTS, CDMA) */
#define NS_NETWORK_LINK_TYPE_3G "3g"
/** A '4G' mobile connection (e.g. LTE, UMB) */
#define NS_NETWORK_LINK_TYPE_4G "4g"
%}

View File

@ -70,3 +70,13 @@ nsAndroidNetworkLinkService::GetLinkStatusKnown(PRBool *aIsKnown)
*aIsKnown = mozilla::AndroidBridge::Bridge()->IsNetworkLinkKnown();
return NS_OK;
}
NS_IMETHODIMP
nsAndroidNetworkLinkService::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_UNEXPECTED);
*aLinkType = mozilla::AndroidBridge::Bridge()->GetNetworkLinkType();
return NS_OK;
}

View File

@ -41,6 +41,7 @@
#include "nsIObserverService.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsCRT.h"
#import <Cocoa/Cocoa.h>
#import <netinet/in.h>
@ -75,6 +76,16 @@ nsNetworkLinkService::GetLinkStatusKnown(PRBool *aIsUp)
return NS_OK;
}
NS_IMETHODIMP
nsNetworkLinkService::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
// XXX This function has not yet been implemented for this platform
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
return NS_OK;
}
NS_IMETHODIMP
nsNetworkLinkService::Observe(nsISupports *subject,
const char *topic,

View File

@ -43,6 +43,7 @@
#include "nsString.h"
#include "nsMaemoNetworkManager.h"
#include "mozilla/Services.h"
#include "nsCRT.h"
NS_IMPL_ISUPPORTS2(nsMaemoNetworkLinkService,
nsINetworkLinkService,
@ -70,6 +71,16 @@ nsMaemoNetworkLinkService::GetLinkStatusKnown(PRBool *aIsKnown)
return NS_OK;
}
NS_IMETHODIMP
nsMaemoNetworkLinkService::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
// XXX This function has not yet been implemented for this platform
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
return NS_OK;
}
NS_IMETHODIMP
nsMaemoNetworkLinkService::Observe(nsISupports *aSubject,
const char *aTopic,

View File

@ -42,6 +42,7 @@
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "mozilla/Services.h"
#include "nsCRT.h"
NS_IMPL_ISUPPORTS2(nsQtNetworkLinkService,
nsINetworkLinkService,
@ -69,6 +70,16 @@ nsQtNetworkLinkService::GetLinkStatusKnown(PRBool* aIsKnown)
return NS_OK;
}
NS_IMETHODIMP
nsQtNetworkLinkService::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
// XXX This function has not yet been implemented for this platform
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
return NS_OK;
}
NS_IMETHODIMP
nsQtNetworkLinkService::Observe(nsISupports* aSubject,
const char* aTopic,

View File

@ -54,6 +54,7 @@
#include "nsString.h"
#include "nsAutoPtr.h"
#include "mozilla/Services.h"
#include "nsCRT.h"
#include <iptypes.h>
#include <iphlpapi.h>
@ -166,6 +167,16 @@ nsNotifyAddrListener::GetLinkStatusKnown(PRBool *aIsUp)
return NS_OK;
}
NS_IMETHODIMP
nsNotifyAddrListener::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
// XXX This function has not yet been implemented for this platform
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
return NS_OK;
}
NS_IMETHODIMP
nsNotifyAddrListener::Run()
{

View File

@ -238,7 +238,7 @@ SHELL_WRAPPER0(onResume)
SHELL_WRAPPER0(onLowMemory)
SHELL_WRAPPER3(callObserver, jstring, jstring, jstring)
SHELL_WRAPPER1(removeObserver, jstring)
SHELL_WRAPPER1(onChangeNetworkLinkStatus, jstring)
SHELL_WRAPPER2(onChangeNetworkLinkStatus, jstring, jstring)
SHELL_WRAPPER1(reportJavaCrash, jstring)
static void * xul_handle = NULL;
@ -249,11 +249,6 @@ extern "C" int extractLibs = 1;
extern "C" int extractLibs = 0;
#endif
#ifdef DEBUG
#define DEBUG_EXTRACT_LIBS 1
#endif
#ifdef DEBUG_EXTRACT_LIBS
static uint32_t simple_write(int fd, const void *buf, uint32_t count)
{
uint32_t out_offset = 0;
@ -333,7 +328,6 @@ extractFile(const char * path, const struct cdir_entry *entry, void * data)
close(fd);
munmap(buf, 4096);
}
#endif
static void
extractLib(const struct cdir_entry *entry, void * data, void * dest)
@ -454,7 +448,6 @@ static void * mozload(const char * path, void *zip,
void * data = ((void *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
void * handle;
#ifdef DEBUG_EXTRACT_LIBS
if (extractLibs) {
char fullpath[PATH_MAX];
snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path + 4);
@ -473,7 +466,7 @@ static void * mozload(const char * path, void *zip,
#endif
return handle;
}
#endif
size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
bool skipLibCache = false;
int fd = zip_fd;

View File

@ -54,10 +54,8 @@ static void set_dlerror(int err)
void *__wrap_dlopen(const char *filename, int flag)
{
#ifdef DEBUG
if (extractLibs)
return dlopen(filename, flag);
#endif
soinfo *ret;

View File

@ -70,6 +70,8 @@ _TEST_FILES = findbar_window.xul \
test_bug451540.xul \
test_bug471776.xul \
test_bug570192.xul \
test_bug624329.xul \
bug624329_window.xul \
test_bug649840.xul \
test_popup_preventdefault_chrome.xul \
window_popup_preventdefault_chrome.xul \

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window title="Test for bug 624329 context menu position"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
context="menu">
<title><label>Test for bug 624329 context menu position</label></title>
<script>
opener.SimpleTest.waitForFocus(opener.childFocused, window);
</script>
<menupopup id="menu">
<!-- The bug demonstrated only when the accesskey was presented separately
from the label.
e.g. because the accesskey is not a letter in the label.
The bug demonstrates only on the first show of the context menu
unless menu items are removed/added each time the menu is
constructed. -->
<menuitem label="Long label to ensure the popup would hit the right of the screen" accesskey="1"/>
</menupopup>
</window>

View File

@ -0,0 +1,125 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=624329
-->
<window title="Mozilla Bug 624329 context menu position"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml"
onload="openTestWindow()">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=624329"
target="_blank">Mozilla Bug 624329</a>
</body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/** Test for Bug 624329 **/
SimpleTest.waitForExplicitFinish();
var win;
var timeoutID;
var menu;
function openTestWindow() {
win = open("bug624329_window.xul", "_blank", "width=300,resizable=yes,chrome");
// Close our window if the test times out so that it doesn't interfere
// with later tests.
timeoutID = setTimeout(function () {
ok(false, "Test timed out.");
// Provide some time for a screenshot
setTimeout(finish, 1000);
}, 20000);
}
function listenOnce(event, callback) {
win.addEventListener(event, function listener() {
win.removeEventListener(event, listener, false);
callback();
}, false);
}
function childFocused() {
// maximizing the window is a simple way to ensure that the menu is near
// the right edge of the screen.
listenOnce("resize", childResized);
win.maximize();
}
function childResized() {
is(win.windowState, win.STATE_MAXIMIZED,
"window should be maximized");
isnot(win.innerWidth, 300,
"window inner width should have changed");
openContextMenu();
}
function openContextMenu() {
var mouseX = win.innerWidth - 10;
var mouseY = 10;
menu = win.document.getElementById("menu");
var screenX = menu.boxObject.screenX;
var screenY = menu.boxObject.screenY;
var utils =
win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendMouseEvent("contextmenu", mouseX, mouseY, 2, 0, 0);
var interval = setInterval(checkMoved, 200);
function checkMoved() {
if (menu.boxObject.screenX != screenX ||
menu.boxObject.screenY != screenY) {
clearInterval(interval);
// Wait further to check that the window does not move again.
setTimeout(checkPosition, 1000);
}
}
function checkPosition() {
var menubox = menu.boxObject;
var winbox = win.document.documentElement.boxObject
var x = menubox.screenX - winbox.screenX;
var y = menubox.screenY - winbox.screenY;
ok(y >= mouseY,
"menu top " + y + " should be below click point " + mouseY);
ok(y <= mouseY + 20,
"menu top " + y + " should not be too far below click point " + mouseY);
ok(x < mouseX,
"menu left " + x + " should be left of click point " + mouseX);
var right = x + menubox.width;
ok(right > mouseX,
"menu right " + right + " should be right of click point " + mouseX);
clearTimeout(timeoutID);
finish();
}
}
function finish() {
if (menu && navigator.platform.indexOf("Win") >= 0) {
todo(false, "Should not have to hide popup before closing its window");
// This avoids mochitest "Unable to restore focus" errors (bug 670053).
menu.hidePopup();
}
win.close();
SimpleTest.finish();
}
]]>
</script>
</window>

View File

@ -45,6 +45,7 @@
#include "nsServiceManagerUtils.h"
#include "nsIObserverService.h"
#include "nsStringAPI.h"
#include "nsCRT.h"
// Define NetworkManager API constants. This avoids a dependency on
// NetworkManager-devel.
@ -87,6 +88,16 @@ nsNetworkManagerListener::GetLinkStatusKnown(PRBool* aKnown) {
return NS_OK;
}
nsresult
nsNetworkManagerListener::GetLinkType(PRUint32 *aLinkType)
{
NS_ENSURE_ARG_POINTER(aLinkType);
// XXX This function has not yet been implemented for this platform
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
return NS_OK;
}
nsresult
nsNetworkManagerListener::Init() {
mDBUS = nsDBusService::Get();

View File

@ -0,0 +1 @@
<html xmlns="http://www.w3.org/1999/xhtml"><div><td style="-moz-appearance: progressbar;"></td></div></html>

View File

@ -1,2 +1,3 @@
skip-if(!cocoaWidget) != 507947.html about:blank
== progressbar-fallback-default-style.html progressbar-fallback-default-style-ref.html
load 664925.xhtml

View File

@ -48,6 +48,7 @@
#include "nsOSHelperAppService.h"
#include "nsWindow.h"
#include "mozilla/Preferences.h"
#include "nsINetworkLinkService.h"
#ifdef DEBUG
#define ALOG_BRIDGE(args...) ALOG(args)
@ -141,6 +142,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
jSetKeepScreenOn = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setKeepScreenOn", "(Z)V");
jIsNetworkLinkUp = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isNetworkLinkUp", "()Z");
jIsNetworkLinkKnown = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isNetworkLinkKnown", "()Z");
jGetNetworkLinkType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getNetworkLinkType", "()I");
jSetSelectedLocale = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setSelectedLocale", "(Ljava/lang/String;)V");
jScanMedia = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scanMedia", "(Ljava/lang/String;Ljava/lang/String;)V");
jGetSystemColors = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getSystemColors", "()[I");
@ -669,6 +671,13 @@ AndroidBridge::IsNetworkLinkKnown()
return !!mJNIEnv->CallStaticBooleanMethod(mGeckoAppShellClass, jIsNetworkLinkKnown);
}
int
AndroidBridge::GetNetworkLinkType()
{
ALOG_BRIDGE("AndroidBridge::GetNetworkLinkType");
return (int) mJNIEnv->CallStaticIntMethod(mGeckoAppShellClass, jGetNetworkLinkType);
}
void
AndroidBridge::SetSelectedLocale(const nsAString& aLocale)
{

View File

@ -204,6 +204,8 @@ public:
bool IsNetworkLinkKnown();
int GetNetworkLinkType();
void SetSelectedLocale(const nsAString&);
void GetSystemColors(AndroidSystemColors *aColors);
@ -312,6 +314,7 @@ protected:
jmethodID jSetKeepScreenOn;
jmethodID jIsNetworkLinkUp;
jmethodID jIsNetworkLinkKnown;
jmethodID jGetNetworkLinkType;
jmethodID jSetSelectedLocale;
jmethodID jScanMedia;
jmethodID jGetSystemColors;

View File

@ -69,7 +69,7 @@ extern "C" {
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *, jclass);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_callObserver(JNIEnv *, jclass, jstring observerKey, jstring topic, jstring data);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstring jObserverKey);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *, jclass, jstring status);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *, jclass, jstring status, jstring type);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *, jclass, jstring stack);
}
@ -143,7 +143,7 @@ Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstrin
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *jenv, jclass, jstring jStatus)
Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *jenv, jclass, jstring jStatus, jstring jType)
{
if (!nsAppShell::gAppShell)
return;
@ -153,6 +153,12 @@ Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *jenv, jcl
nsAppShell::gAppShell->NotifyObservers(nsnull,
NS_NETWORK_LINK_TOPIC,
sStatus.get());
nsJNIString sType(jType, jenv);
nsAppShell::gAppShell->NotifyObservers(nsnull,
NS_NETWORK_LINK_TYPE_TOPIC,
sType.get());
}
NS_EXPORT void JNICALL

View File

@ -1111,6 +1111,10 @@ nsWindow::Show(PRBool aState)
NS_IMETHODIMP
nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
// For top-level windows, aWidth and aHeight should possibly be
// interpreted as frame bounds, but NativeResize treats these as window
// bounds (Bug 581866).
mBounds.SizeTo(GetSafeWindowSize(nsIntSize(aWidth, aHeight)));
if (!mCreated)
@ -1547,11 +1551,13 @@ nsWindow::GetScreenBounds(nsIntRect &aRect)
else {
aRect.MoveTo(WidgetToScreenOffset());
}
// mBounds.Size() is the window bounds, not the window-manager frame
// bounds (bug 581863). gdk_window_get_frame_extents would give the
// frame bounds, but mBounds.Size() is returned here for consistency
// with Resize.
aRect.SizeTo(mBounds.Size());
LOG(("GetScreenBounds %d %d | %d %d | %d %d\n",
aRect.x, aRect.y,
mBounds.width, mBounds.height,
aRect.width, aRect.height));
LOG(("GetScreenBounds %d,%d | %dx%d\n",
aRect.x, aRect.y, aRect.width, aRect.height));
return NS_OK;
}
@ -2353,31 +2359,64 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
gboolean
nsWindow::OnConfigureEvent(GtkWidget *aWidget, GdkEventConfigure *aEvent)
{
// These events are only received on toplevel windows.
//
// GDK ensures that the coordinates are the client window top-left wrt the
// root window.
//
// GDK calculates the cordinates for real ConfigureNotify events on
// managed windows (that would normally be relative to the parent
// window).
//
// Synthetic ConfigureNotify events are from the window manager and
// already relative to the root window. GDK creates all X windows with
// border_width = 0, so synthetic events also indicate the top-left of
// the client window.
//
// Override-redirect windows are children of the root window so parent
// coordinates are root coordinates.
LOG(("configure event [%p] %d %d %d %d\n", (void *)this,
aEvent->x, aEvent->y, aEvent->width, aEvent->height));
// can we shortcut?
if (mBounds.x == aEvent->x &&
mBounds.y == aEvent->y)
return FALSE;
if (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog) {
check_for_rollup(aEvent->window, 0, 0, PR_FALSE, PR_TRUE);
}
// Toplevel windows need to have their bounds set so that we can
// keep track of our location. It's not often that the x,y is set
// by the layout engine. Width and height are set elsewhere.
nsIntPoint pnt(aEvent->x, aEvent->y);
if (mIsTopLevel) {
// Need to translate this into the right coordinates
mBounds.MoveTo(WidgetToScreenOffset());
pnt = mBounds.TopLeft();
// This event indicates that the window position may have changed.
// mBounds.Size() is updated in OnSizeAllocate().
// (The gtk_window_get_window_type() function is only available from
// version 2.20.)
NS_ASSERTION(GTK_IS_WINDOW(aWidget),
"Configure event on widget that is not a GtkWindow");
gint type;
g_object_get(aWidget, "type", &type, NULL);
if (type == GTK_WINDOW_POPUP) {
// Override-redirect window
//
// These windows should not be moved by the window manager, and so any
// change in position is a result of our direction. mBounds has
// already been set in Move() or Resize(), and that is more
// up-to-date than the position in the ConfigureNotify event if the
// event is from an earlier window move.
//
// Skipping the NS_MOVE dispatch saves context menus from an infinite
// loop when nsXULPopupManager::PopupMoved moves the window to the new
// position and nsMenuPopupFrame::SetPopupPosition adds
// offsetForContextMenu on each iteration.
return FALSE;
}
// This is wrong, but noautohide titlebar panels currently depend on it
// (bug 601545#c13). mBounds.TopLeft() should refer to the
// window-manager frame top-left, but WidgetToScreenOffset() gives the
// client window origin.
mBounds.MoveTo(WidgetToScreenOffset());
nsGUIEvent event(PR_TRUE, NS_MOVE, this);
event.refPoint = pnt;
event.refPoint = mBounds.TopLeft();
// XXX mozilla will invalidate the entire window after this move
// complete. wtf?
@ -3868,16 +3907,6 @@ nsWindow::Create(nsIWidget *aParent,
// save our bounds
mBounds = aRect;
if (mWindowType != eWindowType_child &&
mWindowType != eWindowType_plugin) {
// We only move a toplevel window if someone has actually placed the
// window somewhere. If no placement has taken place, we just let the
// window manager Do The Right Thing.
//
// Indicate that if we're shown, we at least need to have our size set.
// If we get explicitly moved, the position will also be set.
mNeedsResize = PR_TRUE;
}
// figure out our parent window
GtkWidget *parentMozContainer = nsnull;
@ -3913,6 +3942,14 @@ nsWindow::Create(nsIWidget *aParent,
case eWindowType_invisible: {
mIsTopLevel = PR_TRUE;
// We only move a general managed toplevel window if someone has
// actually placed the window somewhere. If no placement has taken
// place, we just let the window manager Do The Right Thing.
//
// Indicate that if we're shown, we at least need to have our size set.
// If we get explicitly moved, the position will also be set.
mNeedsResize = PR_TRUE;
nsXPIDLString brandName;
GetBrandName(brandName);
NS_ConvertUTF16toUTF8 cBrand(brandName);
@ -3949,6 +3986,11 @@ nsWindow::Create(nsIWidget *aParent,
}
}
else if (mWindowType == eWindowType_popup) {
// With popup windows, we want to control their position, so don't
// wait for the window manager to place them (which wouldn't
// happen with override-redirect windows anyway).
mNeedsMove = PR_TRUE;
// Popups that are not noautohide are only temporary. The are used
// for menus and the like and disappear when another window is used.
if (!aInitData->mNoAutoHide) {
@ -4402,7 +4444,9 @@ nsWindow::NativeResize(PRInt32 aX, PRInt32 aY,
ResizeTransparencyBitmap(aWidth, aHeight);
if (mIsTopLevel) {
// aX and aY give the position of the window manager frame top-left.
gtk_window_move(GTK_WINDOW(mShell), aX, aY);
// This sets the client window size.
gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);
}
else if (mContainer) {