This commit is contained in:
Tim Taubert 2012-01-26 15:17:01 +01:00
Родитель f1c4e5aabe ffa17360a5
Коммит e93f5dfbff
134 изменённых файлов: 2021 добавлений и 877 удалений

Просмотреть файл

@ -49,16 +49,15 @@ USE_STATIC_LIBS = 1
endif
CPPSRCS = nsBrowserProfileMigratorUtils.cpp \
$(NULL)
ifeq ($(OS_ARCH)_$(GNU_CXX),WINNT_)
CPPSRCS += nsIEProfileMigrator.cpp \
nsBrowserProfileMigratorUtils.cpp \
$(NULL)
endif
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += nsSafariProfileMigrator.cpp \
nsBrowserProfileMigratorUtils.cpp \
$(NULL)
endif

Просмотреть файл

@ -98,7 +98,14 @@ def build_tar_package(tar, name, base, directory):
##############################################
source_dir = os.path.realpath('src')
# The directories end up in the debug info, so the easy way of getting
# a reproducible build is to run it in a know absolute directory.
# We use a directory in /builds/slave because the mozilla infrastructure
# cleans it up automatically.
base_dir = "/builds/slave/moz-toolschain"
source_dir = base_dir + "/src"
build_dir = base_dir + "/build"
def build_source_dir(prefix, version):
return source_dir + '/' + prefix + version
@ -133,8 +140,6 @@ mpfr_source_tar = download_uri(mpfr_source_uri)
gmp_source_tar = download_uri(gmp_source_uri)
gcc_source_tar = download_uri(gcc_source_uri)
build_dir = os.path.realpath('build')
binutils_source_dir = build_source_dir('binutils-', binutils_version)
glibc_source_dir = build_source_dir('glibc-', glibc_version)
tar_source_dir = build_source_dir('tar-', tar_version)
@ -144,7 +149,7 @@ gmp_source_dir = build_source_dir('gmp-', gmp_version)
gcc_source_dir = build_source_dir('gcc-', gcc_version)
if not os.path.exists(source_dir):
os.mkdir(source_dir)
os.makedirs(source_dir)
extract(binutils_source_tar, source_dir)
patch('binutils-deterministic.patch', 1, binutils_source_dir)
extract(glibc_source_tar, source_dir)
@ -160,7 +165,7 @@ if not os.path.exists(source_dir):
if os.path.exists(build_dir):
shutil.rmtree(build_dir)
os.mkdir(build_dir)
os.makedirs(build_dir)
tar_inst_dir = build_dir + '/tar_inst'
build_tar(build_dir, tar_inst_dir)

Просмотреть файл

@ -268,6 +268,11 @@ freetype/ftoutln.h
freetype/ttnameid.h
freetype/tttables.h
freetype/t1tables.h
freetype/ftlcdfil.h
freetype/ftsizes.h
freetype/ftadvanc.h
freetype/ftbitmap.h
freetype/ftxf86.h
fribidi/fribidi.h
FSp_fopen.h
fstream

Просмотреть файл

@ -8056,7 +8056,7 @@ dnl ========================================================
dnl Graphics checks.
dnl ========================================================
if test "${OS_ARCH}" = "Darwin" -o "${MOZ_WIDGET_TOOLKIT}" = "android"; then
if test "${OS_ARCH}" = "Darwin" -o "${MOZ_WIDGET_TOOLKIT}" = "android" -o "${MOZ_WIDGET_TOOLKIT}" = "gtk2"; then
MOZ_ENABLE_SKIA=1
else
MOZ_ENABLE_SKIA=

Просмотреть файл

@ -2124,13 +2124,6 @@ public:
DOUBLE_HI32_EXPMASK | DOUBLE_HI32_MANTMASK}}
#endif
#if defined(XP_WIN)
#define DOUBLE_COMPARE(LVAL, OP, RVAL) \
(!DOUBLE_IS_NaN(LVAL) && !DOUBLE_IS_NaN(RVAL) && (LVAL) OP (RVAL))
#else
#define DOUBLE_COMPARE(LVAL, OP, RVAL) ((LVAL) OP (RVAL))
#endif
/*
* In the following helper macros we exploit the fact that the result of a
* series of additions will not be finite if any one of the operands in the

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsThreadUtils.h"
#include "nsNetUtil.h"
#include "nsAsyncDOMEvent.h"
#include "nsGenericHTMLElement.h"
#include "nsIPresShell.h"
#include "nsEventStates.h"
@ -774,9 +775,9 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
nsLoadFlags loadFlags = aLoadFlags;
PRInt32 corsmode = GetCORSMode();
if (corsmode == nsImageLoadingContent::CORS_ANONYMOUS) {
if (corsmode == nsGenericHTMLElement::CORS_ANONYMOUS) {
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
} else if (corsmode == nsImageLoadingContent::CORS_USE_CREDENTIALS) {
} else if (corsmode == nsGenericHTMLElement::CORS_USE_CREDENTIALS) {
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
}
@ -1186,8 +1187,8 @@ nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) cons
aDest->mSuppressed = mSuppressed;
}
nsImageLoadingContent::CORSMode
nsGenericHTMLElement::CORSMode
nsImageLoadingContent::GetCORSMode()
{
return CORS_NONE;
return nsGenericHTMLElement::CORS_NONE;
}

Просмотреть файл

@ -53,6 +53,7 @@
#include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
#include "nsString.h"
#include "nsEventStates.h"
#include "nsGenericHTMLElement.h"
class nsIURI;
class nsIDocument;
@ -70,25 +71,6 @@ public:
NS_DECL_IMGIDECODEROBSERVER
NS_DECL_NSIIMAGELOADINGCONTENT
enum CORSMode {
/**
* The default of not using CORS to validate cross-origin loads.
*/
CORS_NONE,
/**
* Validate cross-site loads using CORS, but do not send any credentials
* (cookies, HTTP auth logins, etc) along with the request.
*/
CORS_ANONYMOUS,
/**
* Validate cross-site loads using CORS, and send credentials such as cookies
* and HTTP auth logins along with the request.
*/
CORS_USE_CREDENTIALS
};
protected:
/**
* LoadImage is called by subclasses when the appropriate
@ -201,7 +183,7 @@ protected:
* Returns the CORS mode that will be used for all future image loads. The
* default implementation returns CORS_NONE unconditionally.
*/
virtual CORSMode GetCORSMode();
virtual nsGenericHTMLElement::CORSMode GetCORSMode();
private:
/**

Просмотреть файл

@ -3950,7 +3950,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
return NS_ERROR_FAILURE;
}
// We disallow loading cross-domain images that have not been validated
// We disallow loading cross-domain images and videos that have not been validated
// with CORS as WebGL textures. The reason for doing that is that timing
// attacks on WebGL shaders are able to retrieve approximations of the
// pixel values in WebGL textures; see bug 655987.

Просмотреть файл

@ -995,7 +995,7 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
!Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
return NS_ERROR_NOT_AVAILABLE;
}
#elif !defined(XP_MACOSX) && !defined(ANDROID)
#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(XP_LINUX)
return NS_ERROR_NOT_AVAILABLE;
#endif

Просмотреть файл

@ -51,6 +51,8 @@ _TEST_FILES = \
image.png \
test_canvas2d_crossorigin.html \
test_webgl_crossorigin_textures.html \
video.sjs \
test_video_crossorigin.html \
$(NULL)
libs:: $(_TEST_FILES)

Просмотреть файл

@ -0,0 +1,196 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=682299
-->
<head>
<title>Test for Bug 682299</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/content/media/test/manifest.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682299">Mozilla Bug 682299</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 682299 **/
const MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
const SECURITY_ERR = 0x805303e8;
function createCanvas(width, height) {
var c = document.createElement("canvas");
c.width = width;
c.height = height;
return c;
}
function testCanvasDrawImage(v) {
var c = createCanvas(v.width, v.height);
var ctx = c.getContext("2d");
ctx.drawImage(v, 0, 0);
try {
var data = ctx.getImageData(0, 0, 1, 1);
ok(true, "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
} catch(error) {
ok(!v.crossorigin && error.result === SECURITY_ERR, "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
v.tainted = true;
}
}
function testCanvasCreatePattern(v) {
var c = createCanvas(v.width, v.height);
var ctx = c.getContext("2d");
ctx.fillStyle = ctx.createPattern(v, "");
ctx.fillRect(0, 0, c.width, c.height);
try {
var data = ctx.getImageData(0, 0, 1, 1);
ok(true, "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
} catch(error) {
ok(!v.crossorigin && error.result === SECURITY_ERR, "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
v.tainted = true;
}
}
function testWebGL(v) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, v);
ok(true, "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' worked");
} catch (error) {
ok(!v.crossorigin && error.result === SECURITY_ERR, "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' failed");
v.tainted = true;
}
}
function testTaintedCanvas(v) {
var c = createCanvas(v.width, v.height);
var ctx = c.getContext("2d");
ctx.drawImage(v, 0, 0);
try {
var data = ctx.getImageData(0, 0, 1, 1);
ok(false, "changing the CORS mode should not allow reading data from remote videos");
} catch (error) {
ok(error.result === SECURITY_ERR, "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
}
}
function vidDataSuccess(e) {
ok(!e.target.error, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
testCanvasDrawImage(e.target);
testCanvasCreatePattern(e.target);
if (gl) {
testWebGL(e.target);
}
// If we change the CORS mode after loading the file without CORS it should still throw a security error
if (e.target.tainted) {
e.target.crossorigin = "anonymous";
testTaintedCanvas(e.target);
}
doneTest(e);
}
function vidLoadFailure(e) {
ok(false, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
doneTest(e);
}
function vidErrorSuccess(e) {
ok(e.target.error.code === MEDIA_ERR_SRC_NOT_SUPPORTED,
"Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
doneTest(e);
}
function startTest(test, token) {
var v = document.createElement('video');
if (test.cors === "just-crossOrigin-without-value") {
var div = document.createElement('div');
div.innerHTML="<video crossorigin>";
v = div.children[0];
} else if (test.cors !== "missing-value-default") {
v.crossorigin = test.cors;
}
v.token = token;
manager.started(token);
v.autoplay = true;
v.preload = "auto";
v.style.display = "none";
if (test.nameIntent === test.corsIntent || test.corsIntent === "none" ||
(test.nameIntent === "use-credentials" && test.corsIntent === "anonymous")) {
v.addEventListener("loadeddata", vidDataSuccess, false);
v.addEventListener("error", vidLoadFailure, false);
} else {
v.addEventListener("loadeddata", vidLoadFailure, false);
v.addEventListener("error", vidErrorSuccess, false);
}
v.src = test.name;
document.body.appendChild(v);
}
function doneTest(e) {
var v = e.target;
v.parentNode.removeChild(v);
manager.finished(v.token);
}
var videoFile = getPlayableVideo(gSmallTests);
if (!videoFile) {
SimpleTest.finish();
}
videoFile = "?name=tests/content/media/test/" + videoFile.name + "&type=" + videoFile.type;
var gl;
try {
gl = createCanvas(16, 16).getContext("experimental-webgl");
} catch (ex) {
// Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests
}
var manager = new MediaTestManager;
var corsTests = [];
const host = "http://example.com/tests/content/canvas/test/crossorigin/video.sjs";
const serverAttrValues = [
[ "&cors=none", "none" ],
[ "&cors=anonymous", "anonymous" ],
[ "&cors=use-credentials", "use-credentials" ]
];
const clientAttrValues = [
[ "missing-value-default", "none" ],
[ "", "anonymous" ],
[ "just-crossOrigin-without-value", "anonymous" ],
[ "anonymous", "anonymous" ],
[ "use-credentials", "use-credentials" ],
[ "foobar", "anonymous" ]
];
// Build the video file test array
for (var i = 0; i < serverAttrValues.length; i++) {
for (var n = 0; n < clientAttrValues.length; n++) {
corsTests.push({
name: host + videoFile + serverAttrValues[i][0],
nameIntent: serverAttrValues[i][1],
cors: clientAttrValues[n][0],
corsIntent: clientAttrValues[n][1]
});
}
}
manager.runTests(corsTests, startTest);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,43 @@
function parseQuery(request, key) {
var params = request.queryString.split('&');
for (var j = 0; j < params.length; ++j) {
var p = params[j];
if (p == key)
return true;
if (p.indexOf(key + "=") == 0)
return p.substring(key.length + 1);
if (p.indexOf("=") < 0 && key == "")
return p;
}
return false;
}
function handleRequest(request, response) {
var name = parseQuery(request, "name");
var type = parseQuery(request, "type");
var cors = parseQuery(request, "cors");
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
createInstance(Components.interfaces.nsIFileInputStream);
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
var split = name.split("/");
for(var i = 0; i < split.length; ++i) {
file.append(split[i]);
}
fis.init(file, -1, -1, false);
bis.setInputStream(fis);
var bytes = bis.readBytes(bis.available());
response.setHeader("Content-Length", ""+bytes.length, false);
response.setHeader("Content-Type", type, false);
if (cors == "anonymous") {
response.setHeader("Access-Control-Allow-Origin", "*", false);
} else if (cors == "use-credentials") {
response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
response.setHeader("Access-Control-Allow-Credentials", "true", false);
}
response.write(bytes, bytes.length);
bis.close();
}

Просмотреть файл

@ -73,6 +73,10 @@ public:
CANPLAY_YES
};
CORSMode GetCORSMode() {
return mCORSMode;
}
nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLMediaElement();
@ -233,8 +237,7 @@ public:
// autoplay pref enabled, etc), it should start playing back.
void NotifyAutoplayDataReady();
// Gets the pref media.enforce_same_site_origin, which determines
// if we should check Access Controls, or allow cross domain loads.
// Check if the media element had crossorigin set when loading started
bool ShouldCheckAllowOrigin();
// Is the media element potentially playing as defined by the HTML 5 specification.
@ -761,6 +764,9 @@ protected:
// True if a same-origin check has been done for the media element and resource.
bool mMediaSecurityVerified;
// The CORS mode when loading the media element
CORSMode mCORSMode;
};
#endif

Просмотреть файл

@ -2884,6 +2884,14 @@ nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
}
const nsAttrValue::EnumTable nsGenericHTMLElement::kCORSAttributeTable[] = {
// Order matters here
// See ParseAttribute in nsHTMLImageElement or nsHTMLMediaElement
{ "anonymous", nsGenericHTMLElement::CORS_ANONYMOUS },
{ "use-credentials", nsGenericHTMLElement::CORS_USE_CREDENTIALS },
{ 0 }
};
/* virtual */
bool
nsGenericHTMLFormElement::IsDisabled() const

Просмотреть файл

@ -542,6 +542,32 @@ public:
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
}
/**
* Shared cross-origin resource sharing attributes so they don't get
* duplicated on every CORS-enabled element
*/
enum CORSMode {
/**
* The default of not using CORS to validate cross-origin loads.
*/
CORS_NONE,
/**
* Validate cross-site loads using CORS, but do not send any credentials
* (cookies, HTTP auth logins, etc) along with the request.
*/
CORS_ANONYMOUS,
/**
* Validate cross-site loads using CORS, and send credentials such as cookies
* and HTTP auth logins along with the request.
*/
CORS_USE_CREDENTIALS
};
const static nsAttrValue::EnumTable kCORSAttributeTable[];
protected:
/**
* Add/remove this element to the documents name cache

Просмотреть файл

@ -126,7 +126,7 @@ public:
NS_DECL_NSIDOMHTMLIMAGEELEMENT
// override from nsImageLoadingContent
nsImageLoadingContent::CORSMode GetCORSMode();
CORSMode GetCORSMode();
// nsIJSNativeInitializer
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
@ -245,13 +245,6 @@ NS_IMPL_URI_ATTR(nsHTMLImageElement, Src, src)
NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap)
NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace)
static const nsAttrValue::EnumTable kCrossOriginTable[] = {
// Order matters here; see ParseAttribute
{ "anonymous", nsImageLoadingContent::CORS_ANONYMOUS },
{ "use-credentials", nsImageLoadingContent::CORS_USE_CREDENTIALS },
{ 0 }
};
// crossorigin is not "limited to only known values" per spec, so it's
// just a string attr purposes of the DOM crossOrigin property.
NS_IMPL_STRING_ATTR(nsHTMLImageElement, CrossOrigin, crossorigin)
@ -370,10 +363,10 @@ nsHTMLImageElement::ParseAttribute(PRInt32 aNamespaceID,
return ParseAlignValue(aValue, aResult);
}
if (aAttribute == nsGkAtoms::crossorigin) {
return aResult.ParseEnumValue(aValue, kCrossOriginTable, false,
return aResult.ParseEnumValue(aValue, nsGenericHTMLElement::kCORSAttributeTable, false,
// default value is anonymous if aValue is
// not a value we understand
&kCrossOriginTable[0]);
&nsGenericHTMLElement::kCORSAttributeTable[0]);
}
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return true;
@ -669,16 +662,16 @@ nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const
return nsGenericHTMLElement::CopyInnerTo(aDest);
}
nsImageLoadingContent::CORSMode
nsGenericHTMLElement::CORSMode
nsHTMLImageElement::GetCORSMode()
{
nsImageLoadingContent::CORSMode ret = nsImageLoadingContent::CORS_NONE;
nsGenericHTMLElement::CORSMode ret = nsGenericHTMLElement::CORS_NONE;
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
if (value) {
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
"Why is this not an enum value?");
ret = nsImageLoadingContent::CORSMode(value->GetEnumValue());
ret = nsGenericHTMLElement::CORSMode(value->GetEnumValue());
}
return ret;

Просмотреть файл

@ -940,6 +940,16 @@ nsresult nsHTMLMediaElement::LoadResource()
mChannel = nsnull;
}
// Set the media element's CORS mode only when loading a resource
// By default, it's CORS_NONE
mCORSMode = CORS_NONE;
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
if (value) {
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
"Why is this not an enum value?");
mCORSMode = CORSMode(value->GetEnumValue());
}
nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
if (other) {
// Clone it.
@ -1002,7 +1012,7 @@ nsresult nsHTMLMediaElement::LoadResource()
new nsCORSListenerProxy(loadListener,
NodePrincipal(),
channel,
false,
GetCORSMode() == CORS_USE_CREDENTIALS,
&rv);
} else {
rv = nsContentUtils::GetSecurityManager()->
@ -1392,11 +1402,10 @@ nsHTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
for (PRUint32 i = 0; i < entry->mElements.Length(); ++i) {
nsHTMLMediaElement* elem = entry->mElements[i];
bool equal;
// Look for elements that have the same principal.
// XXX when we implement crossorigin for video, we'll also need to check
// for the same crossorigin mode here. Ditto for anything else that could
// cause us to send different headers.
if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal) {
// Look for elements that have the same principal and CORS mode.
// Ditto for anything else that could cause us to send different headers.
if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal &&
elem->mCORSMode == mCORSMode) {
NS_ASSERTION(elem->mDecoder && elem->mDecoder->GetStream(), "Decoder gone");
return elem;
}
@ -1438,7 +1447,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mHasSelfReference(false),
mShuttingDown(false),
mLoadIsSuspended(false),
mMediaSecurityVerified(false)
mMediaSecurityVerified(false),
mCORSMode(CORS_NONE)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
@ -1559,6 +1569,8 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Crossorigin, crossorigin)
bool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
@ -1577,6 +1589,12 @@ bool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return true;
}
if (aAttribute == nsGkAtoms::crossorigin) {
return aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
// default value is anonymous if aValue is
// not a value we understand
&kCORSAttributeTable[0]);
}
if (aAttribute == nsGkAtoms::preload) {
return aResult.ParseEnumValue(aValue, kPreloadTable, false);
}
@ -2101,8 +2119,8 @@ nsresult nsHTMLMediaElement::FinishDecoderSetup(nsMediaDecoder* aDecoder)
}
if (NS_FAILED(rv)) {
RemoveMediaElementFromURITable();
mDecoder->Shutdown();
RemoveMediaElementFromURITable();
mDecoder->Shutdown();
mDecoder = nsnull;
}
@ -2330,7 +2348,7 @@ void nsHTMLMediaElement::DownloadStalled()
bool nsHTMLMediaElement::ShouldCheckAllowOrigin()
{
return Preferences::GetBool("media.enforce_same_site_origin", true);
return mCORSMode != CORS_NONE;
}
void nsHTMLMediaElement::UpdateReadyStateForData(NextFrameStatus aNextFrame)

Просмотреть файл

@ -76,7 +76,6 @@ var gTests = [
var gTestNum = 0;
var gVideo = null;
var gTestedRemoved = false;
var gOldPref;
function eventHandler(event) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
@ -93,6 +92,7 @@ function createVideo() {
var v = document.createElement('video');
v.addEventListener('loadeddata', eventHandler, false);
v.addEventListener('error', eventHandler, false);
v.crossorigin = 'anonymous';
return v;
}
@ -101,16 +101,7 @@ function load() {
opener.is(window.location.href,
"http://example.org/tests/content/media/test/file_access_controls.html",
"We must be on a example.org:80");
// Ensure access control check pref is on.
// media.enforce_same_site_origin
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
opener.ok(prefService!=null, "Get pref service");
var branch = prefService.getBranch("media.");
opener.ok(branch!=null, "Get media pref branch");
gOldPref = branch.getBoolPref("enforce_same_site_origin");
branch.setBoolPref("enforce_same_site_origin", true);
nextTest();
}
@ -159,11 +150,6 @@ function nextTest() {
function done() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
// Undo change to access control check pref.
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
var branch = prefService.getBranch("media.");
branch.setBoolPref("enforce_same_site_origin", gOldPref);
mediaTestCleanup();
opener.done();
}

Просмотреть файл

@ -119,7 +119,7 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
rtype == txAExprResult::NUMBER) {
double lval = aLeft->numberValue();
double rval = aRight->numberValue();
result = DOUBLE_COMPARE(lval, ==, rval);
result = (lval == rval);
}
// Otherwise compare as strings. Try to use the stringobject in
@ -154,19 +154,19 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
switch (mOp) {
case LESS_THAN:
{
return DOUBLE_COMPARE(leftDbl, <, rightDbl);
return (leftDbl < rightDbl);
}
case LESS_OR_EQUAL:
{
return DOUBLE_COMPARE(leftDbl, <=, rightDbl);
return (leftDbl <= rightDbl);
}
case GREATER_THAN:
{
return DOUBLE_COMPARE(leftDbl, >, rightDbl);
return (leftDbl > rightDbl);
}
case GREATER_OR_EQUAL:
{
return DOUBLE_COMPARE(leftDbl, >=, rightDbl);
return (leftDbl >= rightDbl);
}
default:
{

Просмотреть файл

@ -52,7 +52,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(c74b835f-bb68-4ab3-a02c-08152cbb09fa)]
[scriptable, uuid(390c059a-0a26-4a44-96b6-3f8817bf92e9)]
interface nsIDOMHTMLAudioElement : nsIDOMHTMLMediaElement
{
// Setup the audio stream for writing

Просмотреть файл

@ -57,7 +57,7 @@
#endif
%}
[scriptable, uuid(1f312b70-c1e1-40ca-94d4-5f70cac773da)]
[scriptable, uuid(6733a409-fab3-45e1-af23-9af8c361bdfd)]
interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
{
// error state
@ -66,6 +66,7 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
// network state
attribute DOMString src;
readonly attribute DOMString currentSrc;
attribute DOMString crossorigin;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
const unsigned short NETWORK_LOADING = 2;

Просмотреть файл

@ -48,7 +48,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(8e6d81a9-a6e1-44af-95be-cbe86de36ede)]
[scriptable, uuid(2274055b-8b3a-4a5a-8d72-5d5aea07021a)]
interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
{
attribute long width;

Просмотреть файл

@ -214,6 +214,7 @@ ContainerRender(Container* aContainer,
framebufferRect -= childOffset;
aManager->CreateFBOWithTexture(framebufferRect,
mode,
aPreviousFrameBuffer,
&frameBuffer,
&containerSurface);
childOffset.x = visibleRect.x;

Просмотреть файл

@ -1132,8 +1132,33 @@ LayerManagerOGL::SetLayerProgramProjectionMatrix(const gfx3DMatrix& aMatrix)
} FOR_EACH_LAYER_PROGRAM_END
}
static GLenum
GetFrameBufferInternalFormat(GLContext* gl,
GLuint aCurrentFrameBuffer,
nsIWidget* aWidget)
{
if (aCurrentFrameBuffer == 0) { // default framebuffer
return aWidget->GetGLFrameBufferFormat();
}
return LOCAL_GL_RGBA;
}
static bool
AreFormatsCompatibleForCopyTexImage2D(GLenum aF1, GLenum aF2)
{
// GL requires that the implementation has to handle copies between
// different formats, so all are "compatible". GLES does not
// require that.
#ifdef USE_GLES2
return (aF1 == aF2);
#else
return true;
#endif
}
void
LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
GLuint aCurrentFrameBuffer,
GLuint *aFBO, GLuint *aTexture)
{
GLuint tex, fbo;
@ -1142,12 +1167,40 @@ LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
mGLContext->fGenTextures(1, &tex);
mGLContext->fBindTexture(mFBOTextureTarget, tex);
if (aInit == InitModeCopy) {
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
0,
LOCAL_GL_RGBA,
aRect.x, aRect.y,
aRect.width, aRect.height,
0);
// We're going to create an RGBA temporary fbo. But to
// CopyTexImage() from the current framebuffer, the framebuffer's
// format has to be compatible with the new texture's. So we
// check the format of the framebuffer here and take a slow path
// if it's incompatible.
GLenum format =
GetFrameBufferInternalFormat(gl(), aCurrentFrameBuffer, mWidget);
if (AreFormatsCompatibleForCopyTexImage2D(format, LOCAL_GL_RGBA)) {
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
0,
LOCAL_GL_RGBA,
aRect.x, aRect.y,
aRect.width, aRect.height,
0);
} else {
// Curses, incompatible formats. Take a slow path.
//
// XXX Technically CopyTexSubImage2D also has the requirement of
// matching formats, but it doesn't seem to affect us in the
// real world.
mGLContext->fTexImage2D(mFBOTextureTarget,
0,
LOCAL_GL_RGBA,
aRect.width, aRect.height,
0,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
NULL);
mGLContext->fCopyTexSubImage2D(mFBOTextureTarget,
0, // level
0, 0, // offset
aRect.x, aRect.y,
aRect.width, aRect.height);
}
} else {
mGLContext->fTexImage2D(mFBOTextureTarget,
0,

Просмотреть файл

@ -308,6 +308,7 @@ public:
* texture types.
*/
void CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
GLuint aCurrentFrameBuffer,
GLuint *aFBO, GLuint *aTexture);
GLuint QuadVBO() { return mQuadVBO; }

Просмотреть файл

@ -68,6 +68,7 @@ VPATH += \
$(srcdir)/src/ports \
$(srcdir)/src/opts \
$(srcdir)/src/effects \
$(srcdir)/src/utils \
$(NULL)
EXPORTS_skia = \
@ -317,6 +318,19 @@ DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
endif
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
CPPSRCS += \
SkFontHost_FreeType.cpp \
SkFontHost_linux.cpp \
SkFontHost_gamma.cpp \
SkTime_Unix.cpp \
SkMMapStream.cpp \
SkOSFile.cpp \
$(NULL)
OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
endif
ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
EXPORTS_skia += \
include/config/sk_stdint.h \

Просмотреть файл

@ -56,6 +56,8 @@
#include "gfxFT2Fonts.h"
#endif
#include "mozilla/gfx/2D.h"
#include "cairo.h"
#include <gtk/gtk.h>
@ -83,6 +85,9 @@
#include FT_FREETYPE_H
#endif
using namespace mozilla;
using namespace mozilla::gfx;
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
#ifndef MOZ_PANGO
@ -761,3 +766,23 @@ gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
return NULL;
}
RefPtr<ScaledFont>
gfxPlatformGtk::GetScaledFontForFont(gfxFont *aFont)
{
NativeFont nativeFont;
nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
nativeFont.mFont = aFont;
RefPtr<ScaledFont> scaledFont =
Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
return scaledFont;
}
bool
gfxPlatformGtk::SupportsAzure(BackendType& aBackend)
{
aBackend = BACKEND_SKIA;
return true;
}

Просмотреть файл

@ -66,6 +66,11 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
mozilla::RefPtr<mozilla::gfx::ScaledFont>
GetScaledFontForFont(gfxFont *aFont);
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend);
nsresult GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
nsTArray<nsString>& aListOfFonts);

Просмотреть файл

@ -484,10 +484,8 @@ struct ParamTraits<mozilla::GraphicsFilterType>
WriteParam(msg, int32(param));
return;
default:
NS_RUNTIMEABORT("not reached");
return;
}
NS_RUNTIMEABORT("not reached");
}
static bool Read(const Message* msg, void** iter, paramType* result)

Просмотреть файл

@ -33,7 +33,6 @@
#include "assembler/wtf/Platform.h"
#include "assembler/assembler/MacroAssemblerCodeRef.h"
#include "assembler/assembler/CodeLocation.h"
#include "jsstdint.h"
#if ENABLE_ASSEMBLER

Просмотреть файл

@ -37,7 +37,6 @@
#include <string.h>
#include "assembler/jit/ExecutableAllocator.h"
#include "assembler/wtf/Assertions.h"
#include "jsstdint.h"
namespace JSC {

Просмотреть файл

@ -35,7 +35,6 @@
#if ENABLE_ASSEMBLER && (WTF_CPU_X86 || WTF_CPU_X86_64)
#include "AssemblerBuffer.h"
#include "jsstdint.h"
#include "assembler/wtf/Assertions.h"
#include "js/Vector.h"

Просмотреть файл

@ -268,6 +268,11 @@ freetype/ftoutln.h
freetype/ttnameid.h
freetype/tttables.h
freetype/t1tables.h
freetype/ftlcdfil.h
freetype/ftsizes.h
freetype/ftadvanc.h
freetype/ftbitmap.h
freetype/ftxf86.h
fribidi/fribidi.h
FSp_fopen.h
fstream

Просмотреть файл

@ -48,7 +48,6 @@
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jsapi.h"

Просмотреть файл

@ -57,7 +57,6 @@
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"
#include "jsarray.h"

Просмотреть файл

@ -53,7 +53,6 @@
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jsapi.h"

Просмотреть файл

@ -0,0 +1,15 @@
// |jit-test| error: InternalError
version(0);
eval("\
function TimeFromYear( y ) {}\
addTestCase( -2208988800000 );\
function addTestCase( t ) {\
var start = TimeFromYear((addTestCase(addTestCase << t, 0)));\
new TestCase( \
SECTION,\
'(new Date('+d+')).getUTCDay()',\
WeekDay((d)),\
(new Date(let ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
);\
}\
");

Просмотреть файл

@ -0,0 +1,15 @@
var n = 16;
var a = new Int32Array(n);
for (var i = 0; i < n; ++i) {
a[i] = i;
}
var b = new Int32Array(n);
for (var i = 0; i < n; ++i) {
b[i] = i * 2;
}
a.set(b, 0.99);
for (var i = 0; i < n; ++i) {
assertEq(a[i], b[i]);
}

Просмотреть файл

@ -47,7 +47,6 @@
#include <string.h>
#include <sys/stat.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsclist.h"
#include "jsdhash.h"

Просмотреть файл

@ -103,7 +103,6 @@
#include "mozilla/RangedPtr.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"

Просмотреть файл

@ -47,7 +47,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"
#include "jsprf.h"

Просмотреть файл

@ -41,7 +41,6 @@
* JS boolean implementation.
*/
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"
#include "jsatom.h"

Просмотреть файл

@ -41,7 +41,6 @@
#include "jsapi.h"
#include "jscntxt.h"
#include "jsstdint.h"
#include "js/HashTable.h"
#include "js/Vector.h"

Просмотреть файл

@ -54,8 +54,6 @@
# include <string>
#endif // ANDROID
#include "jsstdint.h"
#include "jstypes.h"
#include "jsutil.h"
#include "jsclist.h"

Просмотреть файл

@ -60,7 +60,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsprf.h"
#include "prmjtime.h"
#include "jsutil.h"

Просмотреть файл

@ -46,7 +46,6 @@
#include <stdarg.h>
#include "jsprvtd.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsclist.h"
#include "jsapi.h"

Просмотреть файл

@ -46,7 +46,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jsstdint.h"
#include "jsdhash.h"
#include "jsutil.h"

Просмотреть файл

@ -41,7 +41,6 @@
* Portable double to alphanumeric string and back converters.
*/
#include "jstypes.h"
#include "jsstdint.h"
#include "jsdtoa.h"
#include "jsprf.h"
#include "jsapi.h"

Просмотреть файл

@ -47,7 +47,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jsapi.h"

Просмотреть файл

@ -46,7 +46,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"
#include "jsarray.h"

Просмотреть файл

@ -55,7 +55,6 @@
#include <string.h> /* for memset used when DEBUG */
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"
#include "jsclist.h"

Просмотреть файл

@ -33,7 +33,6 @@
#include <stdlib.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsgcchunk.h"
#ifdef XP_WIN

Просмотреть файл

@ -43,7 +43,6 @@
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"

Просмотреть файл

@ -45,7 +45,6 @@
#include <string.h>
#include <math.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jsapi.h"
@ -824,7 +823,7 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *resu
if (lval.isDouble()) {
double l = lval.toDouble(), r = rval.toDouble();
*result = JSDOUBLE_COMPARE(l, ==, r, false);
*result = (l == r);
return true;
}
@ -875,7 +874,7 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *resu
double l, r;
if (!ToNumber(cx, lvalue, &l) || !ToNumber(cx, rvalue, &r))
return false;
*result = JSDOUBLE_COMPARE(l, ==, r, false);
*result = (l == r);
return true;
}
@ -887,7 +886,7 @@ js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equ
if (lval.isString())
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
if (lval.isDouble()) {
*equal = JSDOUBLE_COMPARE(lval.toDouble(), ==, rval.toDouble(), JS_FALSE);
*equal = (lval.toDouble() == rval.toDouble());
return true;
}
if (lval.isObject()) {
@ -905,13 +904,13 @@ js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equ
if (lval.isDouble() && rval.isInt32()) {
double ld = lval.toDouble();
double rd = rval.toInt32();
*equal = JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
*equal = (ld == rd);
return true;
}
if (lval.isInt32() && rval.isDouble()) {
double ld = lval.toInt32();
double rd = rval.toDouble();
*equal = JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
*equal = (ld == rd);
return true;
}
@ -2325,7 +2324,7 @@ END_CASE(JSOP_CASE)
double l, r; \
if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r)) \
goto error; \
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
cond = (l OP r); \
} \
} \
TRY_BRANCH_AFTER_COND(cond, 2); \

Просмотреть файл

@ -44,7 +44,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"
#include "jsarray.h"

Просмотреть файл

@ -42,7 +42,6 @@
*/
#include <stdlib.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "prmjtime.h"
#include "jsapi.h"
#include "jsatom.h"

Просмотреть файл

@ -55,7 +55,6 @@
#include "mozilla/RangedPtr.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsapi.h"
#include "jsatom.h"

Просмотреть файл

@ -42,7 +42,6 @@
#include <math.h>
#include "jsstdint.h"
#include "jsobj.h"
/*
@ -129,15 +128,6 @@ JS_HASH_DOUBLE(jsdouble d)
return u.s.lo ^ u.s.hi;
}
#if defined(XP_WIN)
#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) \
((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL)) \
? (IFNAN) \
: (LVAL) OP (RVAL))
#else
#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
#endif
extern jsdouble js_NaN;
extern jsdouble js_PositiveInfinity;
extern jsdouble js_NegativeInfinity;

Просмотреть файл

@ -47,7 +47,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"
#include "jsdhash.h"
@ -72,7 +71,6 @@
#include "jsproxy.h"
#include "jsscope.h"
#include "jsscript.h"
#include "jsstdint.h"
#include "jsstr.h"
#include "jsdbgapi.h"
#include "json.h"

Просмотреть файл

@ -55,7 +55,6 @@
#include "jsprf.h"
#include "jsstr.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsxml.h"

Просмотреть файл

@ -52,7 +52,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jsapi.h"
@ -856,8 +855,7 @@ Sprinter::put(const char *s, size_t len)
s = stringAt(s - oldBase); /* this is where it lives now */
memmove(bp, s, len);
} else {
JS_ASSERT(s < base || s >= base + size);
memcpy(bp, s, len);
js_memcpy(bp, s, len);
}
bp[len] = 0;
@ -2060,7 +2058,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc, JS
* the nb parameter.
*/
ptrdiff_t todo = ss->sprinter.getOffset();
ss->sprinter.setOffset(todo + PAREN_SLOP);
ss->sprinter.reserve(PAREN_SLOP);
pc = Decompile(ss, pc, -((intN)ss->top));
if (!pc)
return NULL;

Просмотреть файл

@ -46,7 +46,6 @@
#include <string.h>
#include <stdlib.h>
#include "jsprf.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jspubtd.h"
#include "jsstr.h"

Просмотреть файл

@ -45,7 +45,6 @@
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsclist.h"
#include "jsdhash.h"
#include "jsutil.h"

Просмотреть файл

@ -42,9 +42,9 @@
/*
* JS script operations.
*/
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jscrashreport.h"
#include "jsprf.h"

Просмотреть файл

@ -54,7 +54,6 @@
#include <stdlib.h>
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"
#include "jsprf.h"

Просмотреть файл

@ -42,7 +42,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jshash.h"
#include "jsprf.h"
@ -1544,7 +1543,7 @@ class TypedArrayTemplate
int32_t length = -1;
if (argc > 1) {
if (!NonstandardToInt32(cx, argv[1], &byteOffset))
if (!ToInt32(cx, argv[1], &byteOffset))
return NULL;
if (byteOffset < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -1553,7 +1552,7 @@ class TypedArrayTemplate
}
if (argc > 2) {
if (!NonstandardToInt32(cx, argv[2], &length))
if (!ToInt32(cx, argv[2], &length))
return NULL;
if (length < 0) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -1625,7 +1624,7 @@ class TypedArrayTemplate
int32_t off = 0;
if (args.length() > 1) {
if (!NonstandardToInt32(cx, args[1], &off))
if (!ToInt32(cx, args[1], &off))
return false;
if (off < 0 || uint32_t(off) > getLength(tarray)) {

Просмотреть файл

@ -45,7 +45,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#ifdef WIN32

Просмотреть файл

@ -45,7 +45,6 @@
#include <string.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsdhash.h"
#include "jsprf.h"

Просмотреть файл

@ -48,7 +48,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsprf.h"
#include "jsutil.h"
#include "jsapi.h"
@ -5315,7 +5314,7 @@ js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp)
if (ok) {
d2 = JSVAL_IS_INT(v) ? JSVAL_TO_INT(v)
: JSVAL_TO_DOUBLE(v);
*bp = JSDOUBLE_COMPARE(d, ==, d2, JS_FALSE);
*bp = (d == d2);
}
}
} else {

Просмотреть файл

@ -525,7 +525,7 @@ template void JS_FASTCALL stubs::DefFun<false>(VMFrame &f, JSFunction *fun);
double l, r; \
if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r)) \
THROWV(JS_FALSE); \
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
cond = (l OP r); \
} \
regs.sp[-2].setBoolean(cond); \
return cond; \
@ -568,7 +568,7 @@ stubs::Not(VMFrame &f)
f.regs.sp[-1].setBoolean(b);
}
template <bool EQ, bool IFNAN>
template <bool EQ>
static inline bool
StubEqualityOp(VMFrame &f)
{
@ -606,9 +606,9 @@ StubEqualityOp(VMFrame &f)
double l = lval.toDouble();
double r = rval.toDouble();
if (EQ)
cond = JSDOUBLE_COMPARE(l, ==, r, IFNAN);
cond = (l == r);
else
cond = JSDOUBLE_COMPARE(l, !=, r, IFNAN);
cond = (l != r);
} else if (lval.isObject()) {
JSObject *l = &lval.toObject(), *r = &rval.toObject();
if (JSEqualityOp eq = l->getClass()->ext.equality) {
@ -652,9 +652,9 @@ StubEqualityOp(VMFrame &f)
return false;
if (EQ)
cond = JSDOUBLE_COMPARE(l, ==, r, false);
cond = (l == r);
else
cond = JSDOUBLE_COMPARE(l, !=, r, true);
cond = (l != r);
}
}
}
@ -666,7 +666,7 @@ StubEqualityOp(VMFrame &f)
JSBool JS_FASTCALL
stubs::Equal(VMFrame &f)
{
if (!StubEqualityOp<true, false>(f))
if (!StubEqualityOp<true>(f))
THROWV(JS_FALSE);
return f.regs.sp[-2].toBoolean();
}
@ -674,7 +674,7 @@ stubs::Equal(VMFrame &f)
JSBool JS_FASTCALL
stubs::NotEqual(VMFrame &f)
{
if (!StubEqualityOp<false, true>(f))
if (!StubEqualityOp<false>(f))
THROWV(JS_FALSE);
return f.regs.sp[-2].toBoolean();
}

Просмотреть файл

@ -46,7 +46,6 @@
#include <string.h>
#include <time.h>
#include "jsstdint.h"
#include "jstypes.h"
#include "jsutil.h"

Просмотреть файл

@ -52,7 +52,6 @@
#include "mozilla/Util.h"
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#include "jsprf.h"
#include "jswrapper.h"

Просмотреть файл

@ -49,7 +49,6 @@
#include "jsapi.h"
#include "jscntxt.h"
#include "jsdbgapi.h"
#include "jsstdint.h"
#include "jslock.h"
#include "jsworkers.h"

Просмотреть файл

@ -30,8 +30,9 @@
#ifndef PageBlock_h
#define PageBlock_h
#include "mozilla/StdInt.h"
#include <stdlib.h>
#include "jsstdint.h"
#include "assembler/wtf/Platform.h"
namespace WTF {

Просмотреть файл

@ -90,6 +90,7 @@
#ifdef MOZ_MEDIA
#include "nsHTMLVideoElement.h"
#endif
#include "nsGenericHTMLElement.h"
#include "imgIRequest.h"
#include "imgIContainer.h"
#include "nsIImageLoadingContent.h"
@ -4151,6 +4152,7 @@ nsLayoutUtils::SurfaceFromElement(dom::Element* aElement,
surf = imgSurf;
}
result.mCORSUsed = video->GetCORSMode() != nsGenericHTMLElement::CORS_NONE;
result.mSurface = surf;
result.mSize = size;
result.mPrincipal = principal.forget();

Просмотреть файл

@ -6582,10 +6582,10 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
// column-fill: enum
SetDiscrete(*aRuleData->ValueForColumnFill(),
column->mColumnFill, canStoreInRuleTree,
SETDSC_ENUMERATED, parent->mColumnFill,
NS_STYLE_COLUMN_FILL_BALANCE,
0, 0, 0, 0);
column->mColumnFill, canStoreInRuleTree,
SETDSC_ENUMERATED, parent->mColumnFill,
NS_STYLE_COLUMN_FILL_BALANCE,
0, 0, 0, 0);
COMPUTE_END_RESET(Column, column)
}

Просмотреть файл

@ -106,6 +106,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../../../xul/base/src \
-I$(srcdir)/../../../../content/svg/content/src \
-I$(srcdir)/../../../../content/base/src \
-I$(srcdir)/../../../../content/html/content/src \
$(NULL)
libs::

Просмотреть файл

@ -61,6 +61,10 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="org.mozilla.gecko.UPDATE"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- Default browser intents -->
<intent-filter>
@ -112,6 +116,7 @@
android:excludeFromRecents="true">
<intent-filter>
<action android:name="org.mozilla.gecko.restart"/>
<action android:name="org.mozilla.gecko.restart_update"/>
</intent-filter>
</activity>

Просмотреть файл

@ -105,6 +105,7 @@ abstract public class GeckoApp
public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG";
public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK";
public static final String ACTION_LOAD = "org.mozilla.gecko.LOAD";
public static final String ACTION_UPDATE = "org.mozilla.gecko.UPDATE";
public static final String SAVED_STATE_URI = "uri";
public static final String SAVED_STATE_TITLE = "title";
public static final String SAVED_STATE_VIEWPORT = "viewport";
@ -593,11 +594,10 @@ abstract public class GeckoApp
}
}
void getAndProcessThumbnailForTab(Tab tab) {
Bitmap bitmap = null;
if (Tabs.getInstance().isSelectedTab(tab))
bitmap = mSoftwareLayerClient.getBitmap();
void getAndProcessThumbnailForTab(final Tab tab) {
final Bitmap bitmap = Tabs.getInstance().isSelectedTab(tab) ?
mSoftwareLayerClient.getBitmap() : null;
if (bitmap != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos);
@ -1052,6 +1052,8 @@ abstract public class GeckoApp
}
});
}
} else if (event.equals("Update:Restart")) {
doRestart("org.mozilla.gecko.restart_update");
}
} catch (Exception e) {
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
@ -1458,6 +1460,11 @@ abstract public class GeckoApp
}
}
if (ACTION_UPDATE.equals(intent.getAction()) || args != null && args.contains("-alert update-app")) {
Log.i(LOGTAG,"onCreate: Update request");
checkAndLaunchUpdate();
}
String uri = intent.getDataString();
String title = uri;
if (uri != null && uri.length() > 0) {
@ -1606,6 +1613,7 @@ abstract public class GeckoApp
GeckoAppShell.registerGeckoEventListener("Downloads:Done", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("CharEncoding:Data", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("CharEncoding:State", GeckoApp.mAppContext);
GeckoAppShell.registerGeckoEventListener("Update:Restart", GeckoApp.mAppContext);
mConnectivityFilter = new IntentFilter();
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
@ -1641,10 +1649,6 @@ abstract public class GeckoApp
return;
}
// it would be good only to do this if MOZ_UPDATER was defined
long startTime = SystemClock.uptimeMillis();
checkAndLaunchUpdate();
Log.w(LOGTAG, "checking for an update took " + (SystemClock.uptimeMillis() - startTime) + "ms");
checkMigrateProfile();
}
}, 50);
@ -2012,8 +2016,12 @@ abstract public class GeckoApp
}
public void doRestart() {
doRestart("org.mozilla.gecko.restart");
}
public void doRestart(String action) {
Log.i(LOGTAG, "doRestart(\"" + action + "\")");
try {
String action = "org.mozilla.gecko.restart";
Intent intent = new Intent(action);
intent.setClassName(getPackageName(),
getPackageName() + ".Restarter");
@ -2108,12 +2116,19 @@ abstract public class GeckoApp
private void checkMigrateProfile() {
File profileDir = getProfileDir();
if (profileDir != null) {
long currentTime = SystemClock.uptimeMillis();
Log.i(LOGTAG, "checking profile migration in: " + profileDir.getAbsolutePath());
final GeckoApp app = GeckoApp.mAppContext;
final SetupScreen setupScreen = new SetupScreen(app);
// don't show unless we take a while
setupScreen.showDelayed(mMainHandler);
GeckoAppShell.ensureSQLiteLibsLoaded(app.getApplication().getPackageResourcePath());
ProfileMigrator profileMigrator =
new ProfileMigrator(app.getContentResolver(), profileDir);
profileMigrator.launchBackground();
profileMigrator.launch();
setupScreen.dismiss();
long timeDiff = SystemClock.uptimeMillis() - currentTime;
Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
}
}
@ -2363,7 +2378,7 @@ abstract public class GeckoApp
while (tabsIter.hasNext()) {
Tab tab = tabsIter.next();
if (url.equals(tab.getURL())) {
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Select", String.valueOf(tab.getId())));
Tabs.getInstance().selectTab(tab.getId());
return;
}
}

Просмотреть файл

@ -435,6 +435,7 @@ public class GeckoInputConnection
public void reset() {
mComposing = false;
mCompositionStart = -1;
mBatchMode = false;
mUpdateRequest = null;
}
@ -442,11 +443,17 @@ public class GeckoInputConnection
// TextWatcher
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if (mComposing && mCompositionStart != start) {
// Changed range is different from the composition, need to reset the composition
endComposition();
}
if (!mComposing) {
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_COMPOSITION_BEGIN");
GeckoAppShell.sendEventToGecko(
new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0));
mComposing = true;
mCompositionStart = start;
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + start + ", len=" + before);
GeckoAppShell.sendEventToGecko(
@ -474,6 +481,7 @@ public class GeckoInputConnection
GeckoAppShell.sendEventToGecko(
new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
mComposing = false;
mCompositionStart = -1;
}
private void sendTextToGecko(CharSequence text, int caretPos) {
@ -888,7 +896,8 @@ public class GeckoInputConnection
}
// Is a composition active?
boolean mComposing;
private boolean mComposing;
private int mCompositionStart = -1;
// IME stuff
public static final int IME_STATE_DISABLED = 0;

Просмотреть файл

@ -68,6 +68,7 @@ FENNEC_JAVA_FILES = \
AwesomeBarTabs.java \
BrowserToolbar.java \
ConfirmPreference.java \
SyncPreference.java \
db/AndroidBrowserDB.java \
db/BrowserDB.java \
db/LocalBrowserDB.java \
@ -95,6 +96,7 @@ FENNEC_JAVA_FILES = \
sqlite/ByteBufferInputStream.java \
sqlite/SQLiteBridge.java \
sqlite/SQLiteBridgeException.java \
SetupScreen.java \
SurfaceLockInfo.java \
Tab.java \
Tabs.java \
@ -231,6 +233,7 @@ RES_LAYOUT = \
res/layout/notification_progress.xml \
res/layout/notification_progress_text.xml \
res/layout/site_setting_title.xml \
res/layout/setup_screen.xml \
res/layout/tabs_row.xml \
res/layout/tabs_tray.xml \
res/layout/list_item_header.xml \
@ -277,6 +280,7 @@ RES_DRAWABLE_NODPI = \
$(NULL)
RES_DRAWABLE_MDPI_V8 = \
res/drawable-mdpi-v8/favicon.png \
res/drawable-mdpi-v8/abouthome_icon.png \
res/drawable-mdpi-v8/abouthome_logo.png \
res/drawable-mdpi-v8/abouthome_separator.9.png \
@ -319,6 +323,7 @@ RES_DRAWABLE_MDPI_V8 = \
$(NULL)
RES_DRAWABLE_HDPI_V8 = \
res/drawable-hdpi-v8/favicon.png \
res/drawable-hdpi-v8/home_bg.png \
res/drawable-hdpi-v8/home_star.png \
res/drawable-hdpi-v8/abouthome_icon.png \
@ -383,6 +388,7 @@ RES_DRAWABLE_HDPI_V11 = \
$(NULL)
RES_DRAWABLE_XHDPI_V11 = \
res/drawable-xhdpi-v11/favicon.png \
res/drawable-xhdpi-v11/abouthome_icon.png \
res/drawable-xhdpi-v11/abouthome_logo.png \
res/drawable-xhdpi-v11/abouthome_separator.9.png \
@ -496,7 +502,6 @@ MOZ_ANDROID_DRAWABLES += \
mobile/android/base/resources/drawable/awesomebar_tab_unselected.xml \
mobile/android/base/resources/drawable/background.png \
mobile/android/base/resources/drawable/desktop_notification.png \
mobile/android/base/resources/drawable/favicon.png \
mobile/android/base/resources/drawable/gecko_actionbar_bg.xml \
mobile/android/base/resources/drawable/progress_spinner.xml \
mobile/android/base/resources/drawable/progress_spinner_1.png \

Просмотреть файл

@ -69,12 +69,6 @@ public class ProfileMigrator {
private File mProfileDir;
private ContentResolver mCr;
/*
Amount of Android history entries we will remember
to prevent moving their last access date backwards.
*/
private static final int MAX_HISTORY_TO_CHECK = 1000;
/*
These queries are derived from the low-level Places schema
https://developer.mozilla.org/en/The_Places_database
@ -88,41 +82,48 @@ public class ProfileMigrator {
private final String bookmarkUrl = "a_url";
private final String bookmarkTitle = "a_title";
/*
The sort criterion here corresponds to the one used for the
Awesomebar results. It's an simplification of Frecency.
We must divide date by 1000 due to the micro (Places)
vs milli (Android) distiction.
*/
private final String historyQuery =
"SELECT places.url AS a_url, places.title AS a_title, "
+ "history.visit_date AS a_date FROM "
+ "(moz_historyvisits AS history JOIN moz_places AS places ON "
+ "places.id = history.place_id) WHERE places.hidden <> 1 "
+ "ORDER BY history.visit_date DESC";
private final String historyUrl = "a_url";
private final String historyTitle = "a_title";
private final String historyDate = "a_date";
private final String faviconQuery =
"SELECT places.url AS a_url, favicon.data AS a_data, "
+ "favicon.mime_type AS a_mime FROM (moz_places AS places JOIN "
+ "moz_favicons AS favicon ON places.favicon_id = favicon.id)";
private final String faviconUrl = "a_url";
private final String faviconData = "a_data";
private final String faviconMime = "a_mime";
"SELECT places.url AS a_url, places.title AS a_title,"
+ "MAX(history.visit_date) AS a_date, COUNT(*) AS a_visits, "
// see BrowserDB.filterAllSites for this formula
+ "MAX(1, (((MAX(history.visit_date)/1000) - ?) / 86400000 + 120)) AS a_recent, "
+ "favicon.data AS a_favicon_data, favicon.mime_type AS a_favicon_mime "
+ "FROM (moz_historyvisits AS history JOIN moz_places AS places "
+ "ON places.id = history.place_id "
// Add favicon data if a favicon is present for this URL.
+ "LEFT OUTER JOIN moz_favicons AS favicon "
+ "ON places.favicon_id = favicon.id) "
+ "WHERE places.hidden <> 1 "
+ "GROUP BY a_url ORDER BY a_visits * a_recent DESC LIMIT ?";
private final String historyUrl = "a_url";
private final String historyTitle = "a_title";
private final String historyDate = "a_date";
private final String historyVisits = "a_visits";
private final String faviconData = "a_favicon_data";
private final String faviconMime = "a_favicon_mime";
public ProfileMigrator(ContentResolver cr, File profileDir) {
mProfileDir = profileDir;
mCr = cr;
}
public void launchBackground() {
// Work around http://code.google.com/p/android/issues/detail?id=11291
// WebIconDatabase needs to be initialized within a looper thread.
GeckoAppShell.getHandler().post(new PlacesTask());
public void launch() {
new PlacesTask().run();
}
private class PlacesTask implements Runnable {
// Get a list of the last times an URL was accessed
protected Map<String, Long> gatherAndroidHistory() {
protected Map<String, Long> gatherBrowserDBHistory() {
Map<String, Long> history = new HashMap<String, Long>();
Cursor cursor = BrowserDB.getRecentHistory(mCr, MAX_HISTORY_TO_CHECK);
Cursor cursor =
BrowserDB.getRecentHistory(mCr, BrowserDB.getMaxHistoryCount());
final int urlCol =
cursor.getColumnIndexOrThrow(BrowserDB.URLColumns.URL);
final int dateCol =
@ -144,48 +145,71 @@ public class ProfileMigrator {
return history;
}
protected void addHistory(Map<String, Long> androidHistory,
String url, String title, long date) {
protected void addHistory(Map<String, Long> browserDBHistory,
String url, String title, long date, int visits) {
boolean allowUpdate = false;
if (!androidHistory.containsKey(url)) {
// Android doesn't know the URL, allow it to be
// inserted with places date
if (!browserDBHistory.containsKey(url)) {
// BrowserDB doesn't know the URL, allow it to be
// inserted with places date.
allowUpdate = true;
} else {
long androidDate = androidHistory.get(url);
long androidDate = browserDBHistory.get(url);
if (androidDate < date) {
// Places URL hit is newer than Android,
// allow it to be updated with places date
// Places URL hit is newer than BrowserDB,
// allow it to be updated with places date.
allowUpdate = true;
}
}
if (allowUpdate) {
BrowserDB.updateVisitedHistory(mCr, url);
BrowserDB.updateHistoryDate(mCr, url, date);
if (title != null) {
BrowserDB.updateHistoryTitle(mCr, url, title);
}
// The above records one visit. Subtract that one visit here.
BrowserDB.updateHistoryEntry(mCr, url, title, date, visits - 1);
}
}
protected void migrateHistory(SQLiteBridge db) {
Map<String, Long> androidHistory = gatherAndroidHistory();
Map<String, Long> browserDBHistory = gatherBrowserDBHistory();
final ArrayList<String> placesHistory = new ArrayList<String>();
try {
ArrayList<Object[]> queryResult = db.query(historyQuery);
final String[] queryParams = new String[] {
/* current time */
Long.toString(System.currentTimeMillis()),
/*
History entries to return. No point
in retrieving more than we can store.
*/
Integer.toString(BrowserDB.getMaxHistoryCount())
};
ArrayList<Object[]> queryResult =
db.query(historyQuery, queryParams);
final int urlCol = db.getColumnIndex(historyUrl);
final int titleCol = db.getColumnIndex(historyTitle);
final int dateCol = db.getColumnIndex(historyDate);
final int visitsCol = db.getColumnIndex(historyVisits);
final int faviconMimeCol = db.getColumnIndex(faviconMime);
final int faviconDataCol = db.getColumnIndex(faviconData);
for (Object[] resultRow: queryResult) {
String url = (String)resultRow[urlCol];
String title = (String)resultRow[titleCol];
long date = Long.parseLong((String)(resultRow[dateCol])) / (long)1000;
addHistory(androidHistory, url, title, date);
int visits = Integer.parseInt((String)(resultRow[visitsCol]));
addHistory(browserDBHistory, url, title, date, visits);
placesHistory.add(url);
String mime = (String)resultRow[faviconMimeCol];
if (mime != null) {
// Some GIFs can cause us to lock up completely
// without exceptions or anything. Not cool.
if (mime.compareTo("image/gif") != 0) {
ByteBuffer dataBuff =
(ByteBuffer)resultRow[faviconDataCol];
addFavicon(url, mime, dataBuff);
}
}
}
} catch (SQLiteBridgeException e) {
Log.i(LOGTAG, "Failed to get bookmarks: " + e.getMessage());
@ -241,25 +265,6 @@ public class ProfileMigrator {
}
}
protected void migrateFavicons(SQLiteBridge db) {
try {
ArrayList<Object[]> queryResult = db.query(faviconQuery);
final int urlCol = db.getColumnIndex(faviconUrl);
final int mimeCol = db.getColumnIndex(faviconMime);
final int dataCol = db.getColumnIndex(faviconData);
for (Object[] resultRow: queryResult) {
String url = (String)resultRow[urlCol];
String mime = (String)resultRow[mimeCol];
ByteBuffer dataBuff = (ByteBuffer)resultRow[dataCol];
addFavicon(url, mime, dataBuff);
}
} catch (SQLiteBridgeException e) {
Log.i(LOGTAG, "Failed to get favicons: " + e.getMessage());
return;
}
}
protected void migratePlaces(File aFile) {
String dbPath = aFile.getPath() + "/places.sqlite";
String dbPathWal = aFile.getPath() + "/places.sqlite-wal";
@ -279,7 +284,6 @@ public class ProfileMigrator {
db = new SQLiteBridge(dbPath);
migrateBookmarks(db);
migrateHistory(db);
migrateFavicons(db);
db.close();
// Clean up

Просмотреть файл

@ -75,7 +75,9 @@ public class Restarter extends Activity {
Log.i(LOGTAG, e.toString());
}
try {
String action = "android.intent.action.MAIN";
String action = "org.mozilla.gecko.restart_update".equals(getIntent().getAction()) ?
App.ACTION_UPDATE : Intent.ACTION_MAIN;
Intent intent = new Intent(action);
intent.setClassName("@ANDROID_PACKAGE_NAME@",
"@ANDROID_PACKAGE_NAME@.App");

Просмотреть файл

@ -0,0 +1,148 @@
/* -*- Mode: Java; 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) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Gian-Carlo Pascutto <gpascutto@mozilla.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.app.Dialog;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;
import java.util.Timer;
import java.util.TimerTask;
import org.mozilla.gecko.R;
public class SetupScreen extends Dialog
{
private static final String LOGTAG = "SetupScreen";
// Default delay before showing dialog, in milliseconds
private static final int DEFAULT_DELAY = 100;
private AnimationDrawable mProgressSpinner;
private Context mContext;
private Timer mTimer;
private TimerTask mShowTask;
public class ShowTask extends TimerTask {
private Handler mHandler;
public ShowTask(Handler aHandler) {
mHandler = aHandler;
}
@Override
public void run() {
mHandler.post(new Runnable() {
public void run() {
SetupScreen.this.show();
}
});
}
@Override
public boolean cancel() {
boolean stillInQueue = super.cancel();
if (!stillInQueue) {
mHandler.post(new Runnable() {
public void run() {
// SetupScreen.dismiss calls us,
// we need to call the real Dialog.dismiss.
SetupScreen.super.dismiss();
}
});
}
return stillInQueue;
}
}
public SetupScreen(Context aContext) {
super(aContext, android.R.style.Theme_NoTitleBar_Fullscreen);
mContext = aContext;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_screen);
setCancelable(false);
setTitle(R.string.splash_firstrun);
ImageView spinnerImage = (ImageView)findViewById(R.id.spinner_image);
mProgressSpinner = (AnimationDrawable)spinnerImage.getBackground();
spinnerImage.setImageDrawable(mProgressSpinner);
}
@Override
public void onWindowFocusChanged (boolean hasFocus) {
mProgressSpinner.start();
}
public void showDelayed(Handler aHandler) {
showDelayed(aHandler, DEFAULT_DELAY);
}
// Delay showing the dialog until at least aDelay ms have
// passed. We need to know the handler to (eventually) post the UI
// actions on.
public void showDelayed(Handler aHandler, int aDelay) {
mTimer = new Timer("SetupScreen");
mShowTask = new ShowTask(aHandler);
mTimer.schedule(mShowTask, aDelay);
}
@Override
public void dismiss() {
// Cancel the timers/tasks if we were using showDelayed,
// and post to the correct handler.
if (mShowTask != null) {
mShowTask.cancel();
mShowTask = null;
} else {
// If not using showDelayed, just dismiss here.
super.dismiss();
}
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
}

Просмотреть файл

@ -0,0 +1,73 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; 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) 2009-2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brian Nicholson <bnicholson@mozilla.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.accounts.Account;
import android.accounts.AccountManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
class SyncPreference extends Preference {
private static final String FENNEC_ACCOUNT_TYPE = "org.mozilla.firefox_sync";
private static final String SYNC_SETTINGS = "android.settings.SYNC_SETTINGS";
private Context mContext;
public SyncPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@Override
protected void onClick() {
// show sync setup if no accounts exist; otherwise, show account settings
Account[] accounts = AccountManager.get(mContext).getAccountsByType(FENNEC_ACCOUNT_TYPE);
Intent intent;
if (accounts.length > 0)
intent = new Intent(SYNC_SETTINGS);
else
intent = new Intent(mContext, SetupSyncActivity.class);
mContext.startActivity(intent);
}
}

Просмотреть файл

@ -55,11 +55,13 @@ import java.util.List;
public final class Tab {
private static final String LOGTAG = "GeckoTab";
private static final int kThumbnailWidth = 120;
private static final int kThumbnailHeight = 80;
private static final int kThumbnailWidth = 136;
private static final int kThumbnailHeight = 77;
private static int sMinDim = 0;
private static float sMinDim = 0;
private static float sDensity = 1;
private static int sMinScreenshotWidth = 0;
private static int sMinScreenshotHeight = 0;
private int mId;
private String mUrl;
private String mTitle;
@ -145,24 +147,73 @@ public final class Tab {
return mThumbnail;
}
void initMetrics() {
DisplayMetrics metrics = new DisplayMetrics();
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
sMinDim = Math.min(metrics.widthPixels / kThumbnailWidth, metrics.heightPixels / kThumbnailHeight);
sDensity = metrics.density;
}
float getMinDim() {
if (sMinDim == 0)
initMetrics();
return sMinDim;
}
float getDensity() {
if (sDensity == 0.0f)
initMetrics();
return sDensity;
}
int getMinScreenshotWidth() {
if (sMinScreenshotWidth != 0)
return sMinScreenshotWidth;
return sMinScreenshotWidth = (int)(getMinDim() * kThumbnailWidth);
}
int getMinScreenshotHeight() {
if (sMinScreenshotHeight != 0)
return sMinScreenshotHeight;
return sMinScreenshotHeight = (int)(getMinDim() * kThumbnailHeight);
}
int getThumbnailWidth() {
return (int)(kThumbnailWidth * getDensity());
}
int getThumbnailHeight() {
return (int)(kThumbnailHeight * getDensity());
}
public void updateThumbnail(final Bitmap b) {
final Tab tab = this;
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
if (sMinDim == 0) {
DisplayMetrics metrics = new DisplayMetrics();
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
sMinDim = Math.min(metrics.widthPixels / 3, metrics.heightPixels / 2);
sDensity = metrics.density;
}
if (b != null) {
try {
Bitmap cropped = Bitmap.createBitmap(b, 0, 0, sMinDim * 3, sMinDim * 2);
Bitmap bitmap = Bitmap.createScaledBitmap(cropped, (int) (kThumbnailWidth * sDensity), (int) (kThumbnailHeight * sDensity), false);
saveThumbnailToDB(new BitmapDrawable(bitmap));
b.recycle();
Bitmap cropped = null;
/* Crop to screen width if the bitmap is larger than the screen width or height. If smaller and the
* the aspect ratio is correct, just use the bitmap as is. Otherwise, fit the smaller
* smaller dimension, then crop the larger dimention.
*/
if (getMinScreenshotWidth() < b.getWidth() && getMinScreenshotHeight() < b.getHeight())
cropped = Bitmap.createBitmap(b, 0, 0, getMinScreenshotWidth(), getMinScreenshotHeight());
else if (b.getWidth() * getMinScreenshotHeight() == b.getHeight() * getMinScreenshotWidth())
cropped = b;
else if (b.getWidth() * getMinScreenshotHeight() < b.getHeight() * getMinScreenshotWidth())
cropped = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
b.getWidth() * getMinScreenshotHeight() / getMinScreenshotWidth());
else
cropped = Bitmap.createBitmap(b, 0, 0,
b.getHeight() * getMinScreenshotWidth() / getMinScreenshotHeight(),
b.getHeight());
bitmap = Bitmap.createBitmap(cropped, 0, 0, (int) (138 * sDensity), (int) (78 * sDensity));
Bitmap bitmap = Bitmap.createScaledBitmap(cropped, getThumbnailWidth(), getThumbnailHeight(), false);
saveThumbnailToDB(new BitmapDrawable(bitmap));
if (!cropped.equals(b))
b.recycle();
mThumbnail = new BitmapDrawable(bitmap);
cropped.recycle();
} catch (OutOfMemoryError oom) {

Просмотреть файл

@ -288,8 +288,12 @@ public class Tabs implements GeckoEventListener {
}
public void refreshThumbnails() {
Iterator<Tab> iterator = tabs.values().iterator();
while (iterator.hasNext())
GeckoApp.mAppContext.getAndProcessThumbnailForTab(iterator.next());
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
Iterator<Tab> iterator = tabs.values().iterator();
while (iterator.hasNext())
GeckoApp.mAppContext.getAndProcessThumbnailForTab(iterator.next());
}
});
}
}

Просмотреть файл

@ -91,8 +91,8 @@ public class TabsTray extends Activity implements GeckoApp.OnTabsChangedListener
}
});
Tabs.getInstance().refreshThumbnails();
GeckoApp.registerOnTabsChangedListener(this);
Tabs.getInstance().refreshThumbnails();
onTabsChanged(null);
}
@ -140,6 +140,7 @@ public class TabsTray extends Activity implements GeckoApp.OnTabsChangedListener
void finishActivity() {
finish();
overridePendingTransition(0, R.anim.shrink_fade_out);
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Screenshot:Cancel",""));
}
// Adapter to bind tabs into a list

Просмотреть файл

@ -118,9 +118,31 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
new String[] { uri });
}
public void updateHistoryDate(ContentResolver cr, String uri, long date) {
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
long date, int visits) {
int oldVisits = 0;
Cursor cursor = null;
try {
cursor = cr.query(Browser.BOOKMARKS_URI,
new String[] { Browser.BookmarkColumns.VISITS },
Browser.BookmarkColumns.URL + " = ?",
new String[] { uri },
null);
if (cursor.moveToFirst()) {
oldVisits = cursor.getInt(0);
}
} finally {
if (cursor != null)
cursor.close();
}
ContentValues values = new ContentValues();
values.put(Browser.BookmarkColumns.DATE, date);
values.put(Browser.BookmarkColumns.VISITS, oldVisits + visits);
if (title != null) {
values.put(Browser.BookmarkColumns.TITLE, title);
}
cr.update(Browser.BOOKMARKS_URI,
values,
@ -145,7 +167,8 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
BookmarkColumns.URL,
BookmarkColumns.TITLE,
BookmarkColumns.FAVICON,
BookmarkColumns.DATE },
BookmarkColumns.DATE,
BookmarkColumns.VISITS },
// Bookmarks that have not been visited have a date value
// of 0, so don't pick them up in the history view.
Browser.BookmarkColumns.DATE + " > 0",
@ -155,6 +178,11 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
return new AndroidDBCursor(c);
}
public int getMaxHistoryCount() {
// Valid for Android versions up to 4.0.
return 250;
}
public void clearHistory(ContentResolver cr) {
Browser.clearHistory(cr);
}
@ -357,6 +385,8 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
columnName = URL_COLUMN_THUMBNAIL;
} else if (columnName.equals(BrowserDB.URLColumns.DATE_LAST_VISITED)) {
columnName = Browser.BookmarkColumns.DATE;
} else if (columnName.equals(BrowserDB.URLColumns.VISITS)) {
columnName = Browser.BookmarkColumns.VISITS;
}
return columnName;

Просмотреть файл

@ -50,6 +50,7 @@ public class BrowserDB {
public static String FAVICON = "favicon";
public static String THUMBNAIL = "thumbnail";
public static String DATE_LAST_VISITED = "date-last-visited";
public static String VISITS = "visits";
}
private static BrowserDBIface sDb;
@ -63,12 +64,15 @@ public class BrowserDB {
public void updateHistoryTitle(ContentResolver cr, String uri, String title);
public void updateHistoryDate(ContentResolver cr, String uri, long date);
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
long date, int visits);
public Cursor getAllVisitedHistory(ContentResolver cr);
public Cursor getRecentHistory(ContentResolver cr, int limit);
public int getMaxHistoryCount();
public void clearHistory(ContentResolver cr);
public Cursor getAllBookmarks(ContentResolver cr);
@ -107,8 +111,9 @@ public class BrowserDB {
sDb.updateHistoryTitle(cr, uri, title);
}
public static void updateHistoryDate(ContentResolver cr, String uri, long date) {
sDb.updateHistoryDate(cr, uri, date);
public static void updateHistoryEntry(ContentResolver cr, String uri, String title,
long date, int visits) {
sDb.updateHistoryEntry(cr, uri, title, date, visits);
}
public static Cursor getAllVisitedHistory(ContentResolver cr) {
@ -119,6 +124,10 @@ public class BrowserDB {
return sDb.getRecentHistory(cr, limit);
}
public static int getMaxHistoryCount() {
return sDb.getMaxHistoryCount();
}
public static void clearHistory(ContentResolver cr) {
sDb.clearHistory(cr);
}

Просмотреть файл

@ -200,9 +200,31 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
new String[] { uri });
}
public void updateHistoryDate(ContentResolver cr, String uri, long date) {
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
long date, int visits) {
int oldVisits = 0;
Cursor cursor = null;
try {
cursor = cr.query(appendProfile(History.CONTENT_URI),
new String[] { History.VISITS },
History.URL + " = ?",
new String[] { uri },
null);
if (cursor.moveToFirst()) {
oldVisits = cursor.getInt(0);
}
} finally {
if (cursor != null)
cursor.close();
}
ContentValues values = new ContentValues();
values.put(History.DATE_LAST_VISITED, date);
values.put(History.VISITS, oldVisits + visits);
if (title != null) {
values.put(History.TITLE, title);
}
cr.update(appendProfile(History.CONTENT_URI),
values,
@ -226,7 +248,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
History.URL,
History.TITLE,
History.FAVICON,
History.DATE_LAST_VISITED },
History.DATE_LAST_VISITED,
History.VISITS },
History.DATE_LAST_VISITED + " > 0",
null,
History.DATE_LAST_VISITED + " DESC");
@ -234,6 +257,10 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
return new LocalDBCursor(c);
}
public int getMaxHistoryCount() {
return MAX_HISTORY_COUNT;
}
public void clearHistory(ContentResolver cr) {
cr.delete(appendProfile(History.CONTENT_URI), null, null);
}
@ -401,6 +428,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
columnName = ImageColumns.THUMBNAIL;
} else if (columnName.equals(BrowserDB.URLColumns.DATE_LAST_VISITED)) {
columnName = History.DATE_LAST_VISITED;
} else if (columnName.equals(BrowserDB.URLColumns.VISITS)) {
columnName = History.VISITS;
}
return columnName;

Просмотреть файл

@ -162,7 +162,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateAndDraw", this);
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
GeckoAppShell.registerGeckoEventListener("Document:Shown", this);
GeckoAppShell.registerGeckoEventListener("Tab:Selected", this);
GeckoAppShell.registerGeckoEventListener("Tab:Selected:Done", this);
sendResizeEventIfNecessary();
}
@ -519,7 +519,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
} else if ("Viewport:UpdateLater".equals(event)) {
mUpdateViewportOnEndDraw = true;
} else if (("Document:Shown".equals(event) ||
"Tab:Selected".equals(event)) &&
"Tab:Selected:Done".equals(event)) &&
(mTileLayer instanceof MultiTileLayer)) {
beginTransaction(mTileLayer);
try {

Просмотреть файл

@ -189,10 +189,24 @@ public class LayerController {
public void setViewportSize(FloatSize size) {
// Resize the viewport, and modify its zoom factor so that the page retains proportionally
// zoomed relative to the screen.
float oldHeight = mViewportMetrics.getSize().height;
float oldWidth = mViewportMetrics.getSize().width;
float oldZoomFactor = mViewportMetrics.getZoomFactor();
mViewportMetrics.setSize(size);
// if the viewport got larger (presumably because the vkb went away), and the page
// is smaller than the new viewport size, increase the page size so that the panzoomcontroller
// doesn't zoom in to make it fit (bug 718270). this page size change is in anticipation of
// gecko increasing the page size to match the new viewport size, which will happen the next
// time we get a draw update.
if (size.width >= oldWidth && size.height >= oldHeight) {
FloatSize pageSize = mViewportMetrics.getPageSize();
if (pageSize.width < size.width || pageSize.height < size.height) {
mViewportMetrics.setPageSize(new FloatSize(Math.max(pageSize.width, size.width),
Math.max(pageSize.height, size.height)));
}
}
PointF newFocus = new PointF(size.width / 2.0f, size.height / 2.0f);
float newZoomFactor = size.width * oldZoomFactor / oldWidth;
mViewportMetrics.scaleTo(newZoomFactor, newFocus);

Просмотреть файл

@ -69,6 +69,7 @@
<!ENTITY pref_font_size_large "Large">
<!ENTITY pref_font_size_xlarge "Extra Large">
<!ENTITY pref_use_master_password "Use master password">
<!ENTITY pref_sync "Sync">
<!ENTITY quit "Quit">

Двоичные данные
mobile/android/base/resources/drawable-hdpi-v8/favicon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
mobile/android/base/resources/drawable-mdpi-v8/favicon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
mobile/android/base/resources/drawable-xhdpi-v11/favicon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 268 B

Просмотреть файл

@ -8,15 +8,15 @@
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_width="138dip"
android:layout_height="80dip"
android:background="@drawable/abouthome_topsite_shadow"
android:padding="1dip"
android:paddingTop="2dip">
android:paddingBottom="2dip">
<ImageView android:id="@+id/thumbnail"
android:layout_width="fill_parent"
android:layout_height="80dip"
android:layout_width="136dip"
android:layout_height="77dip"
android:scaleType="centerCrop"/>
</LinearLayout>

Просмотреть файл

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Screen"
android:background="@drawable/tabs_tray_bg_repeat"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:layout_gravity="center" >
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center" >
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:src="@drawable/logo" />
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" >
<ImageView android:id="@+id/spinner_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="@drawable/progress_spinner" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textSize="15dp"
android:textColor="#FFFFFF"
android:typeface="sans"
android:text="@string/splash_firstrun" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше