Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-01-09 13:05:34 +01:00
commit aa8c30548f
89 changed files with 1303 additions and 545 deletions

View File

@ -27,6 +27,7 @@
#include "nsIPersistentProperties2.h"
#include "nsIScrollableFrame.h"
#include "nsIServiceManager.h"
#include "nsITextControlElement.h"
#include "nsTextFragment.h"
#include "mozilla/Selection.h"
#include "mozilla/MathAlgorithms.h"
@ -102,8 +103,19 @@ HyperTextAccessible::NativeState()
{
uint64_t states = AccessibleWrap::NativeState();
nsCOMPtr<nsIEditor> editor = GetEditor();
if (editor) {
nsCOMPtr<nsITextControlElement> textControl = do_QueryInterface(mContent);
bool editable = !!textControl;
Accessible* hyperText = this;
while (!editable && hyperText) {
if (hyperText->IsHyperText())
editable = hyperText->GetNode()->IsEditable();
if (hyperText->IsDoc())
break;
hyperText = hyperText->Parent();
}
if (editable) {
states |= states::EDITABLE;
} else if (mContent->Tag() == nsGkAtoms::article) {

View File

@ -733,17 +733,29 @@
states: STATE_PROTECTED,
extraStates: EXT_STATE_EDITABLE,
actions: "activate",
children: [ ]
children: [
{
role: ROLE_TEXT_LEAF
}
]
};
testElm("input_password", obj);
ok(getAccessible("input_password").firstChild.name != "44",
"text leaf for password shouldn't have its real value as its name!");
obj = {
role: ROLE_PASSWORD_TEXT,
states: STATE_PROTECTED | STATE_READONLY,
actions: "activate",
children: [ ]
children: [
{
role: ROLE_TEXT_LEAF
}
]
};
testElm("input_password_readonly", obj);
ok(getAccessible("input_password_readonly").firstChild.name != "44",
"text leaf for password shouldn't have its real value as its name!");
//////////////////////////////////////////////////////////////////////////
// HTML:input@type="radio"

View File

@ -0,0 +1,51 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// from MouseEvents.h
const leftButtonFlag = 1;
const rightButtonFlag = 2;
gTests.push({
desc: "Test native mouse events",
run: function () {
let tab = yield addTab("about:mozilla");
// Mousemove.
let waitForMove = waitForEvent(document, "mousemove");
synthesizeNativeMouseMove(tab.browser, 1, 1);
synthesizeNativeMouseMove(tab.browser, 100, 100);
let mousemove = yield waitForMove;
is(mousemove.cancelable, false, "mousemove is not cancelable");
is(mousemove.buttons, 0, "no buttons are down");
// Left button down.
let waitForDown1 = waitForEvent(document, "mousedown");
synthesizeNativeMouseLDown(tab.browser, 100, 100);
let mousedown1 = yield waitForDown1;
is(mousedown1.cancelable, true, "mousedown is cancelable");
is(mousedown1.buttons, leftButtonFlag, "left button is down");
// Right button down.
let waitForDown2 = waitForEvent(document, "mousedown");
synthesizeNativeMouseRDown(tab.browser, 100, 100);
let mousedown2 = yield waitForDown2;
is(mousedown2.buttons, leftButtonFlag | rightButtonFlag, "both buttons are down");
// Left button up.
let waitForUp1 = waitForEvent(document, "mouseup");
synthesizeNativeMouseLUp(tab.browser, 100, 100);
let mouseup1 = yield waitForUp1;
is(mouseup1.buttons, rightButtonFlag, "right button is down");
// Right button up.
let waitForUp2 = waitForEvent(document, "mouseup");
synthesizeNativeMouseRUp(tab.browser, 100, 100);
let mouseup2 = yield waitForUp2;
is(mouseup2.buttons, 0, "no buttons are down");
Browser.closeTab(tab, { forceClose: true });
}
});
let test = runTests;

View File

@ -50,7 +50,7 @@ gTests.push({
notifyPrecise();
yield precisePromise;
todo(!isElementVisible(tabStrip._scrollButtonUp), "Bug 952297 - left scrollbutton is hidden in precise mode");
ok(!isElementVisible(tabStrip._scrollButtonUp), "Bug 952297 - left scrollbutton is hidden in precise mode");
ok(!isElementVisible(tabStrip._scrollButtonDown), "right scrollbutton is hidden in precise mode");
},
tearDown: tearDown
@ -98,17 +98,20 @@ gTests.push({
yield addTab("about:mozilla");
}
let tabs = Elements.tabList.strip.querySelectorAll("documenttab");
// select the first tab
Elements.tabs.selectedTab = tabs[0];
ok(isElementVisible(Elements.tabList.strip._scrollButtonDown), "right scrollbutton should be visible when tabList has overflow");
todo(!isElementVisible(Elements.tabList.strip._scrollButtonUp), "Bug 952297 - left scrollbutton should not visible when 1st tab is selected and tablist has overflow");
ok(isElementVisible(Elements.tabList.strip._scrollButtonUp), "left scrollbutton should be visible in precise mode");
ok(isElementVisible(Elements.tabList.strip._scrollButtonDown), "right scrollbutton should be visible in precise mode");
// select the first tab
Browser.selectedTab = Browser.tabs[0];
yield waitForMs(1000); // XXX maximum duration of arrowscrollbox _scrollAnim
ok(Elements.tabList.strip._scrollButtonUp.disabled, "left scrollbutton should be disabled when 1st tab is selected and tablist has overflow");
ok(!Elements.tabList.strip._scrollButtonDown.disabled, "right scrollbutton should be enabled when 1st tab is selected and tablist has overflow");
// select the last tab
Elements.tabs.selectedTab = tabs[tabs.length-1];
ok(isElementVisible(Elements.tabList.strip._scrollButtonUp), "left scrollbutton should be visible when tablist has overflow and last tab is selected");
todo(!isElementVisible(Elements.tabList.strip._scrollButtonDown), "Bug 952297 - right scrollbutton should not visible when last tab is selected and tablist has overflow");
Browser.selectedTab = Browser.tabs[Browser.tabs.length - 1];
yield waitForMs(1000); // XXX maximum duration of arrowscrollbox _scrollAnim
ok(!Elements.tabList.strip._scrollButtonUp.disabled, "left scrollbutton should be enabled when 1st tab is selected and tablist has overflow");
ok(Elements.tabList.strip._scrollButtonDown.disabled, "right scrollbutton should be disabled when last tab is selected and tablist has overflow");
}
});

View File

@ -32,6 +32,7 @@ support-files =
res/blankpage2.html
res/blankpage3.html
[browser_apzc_basic.js]
[browser_bookmarks.js]
[browser_canonizeURL.js]
[browser_circular_progress_indicator.js]
@ -45,6 +46,8 @@ support-files =
[browser_history.js]
[browser_inputsource.js]
[browser_link_click.js]
[browser_menu_hoverstate.js]
[browser_mouse_events.js]
[browser_onscreen_keyboard.js]
[browser_prefs_ui.js]
[browser_prompt.js]
@ -58,8 +61,6 @@ support-files =
[browser_urlbar.js]
[browser_urlbar_highlightURLs.js]
[browser_urlbar_trimURLs.js]
[browser_apzc_basic.js]
[browser_menu_hoverstate.js]
# These tests have known failures in debug builds
[browser_selection_basic.js]

View File

@ -46,18 +46,14 @@
overflow: auto;
}
#tabs[input="precise"] > .tabs-scrollbox > .scrollbutton-up {
visibility: visible !important;
}
#tabs[input="imprecise"] > .tabs-scrollbox > .scrollbutton-up {
.tabs-scrollbox > .scrollbutton-up[collapsed],
.tabs-scrollbox > .scrollbutton-down[collapsed],
#tabs[input="imprecise"] > .tabs-scrollbox > .scrollbutton-up,
#tabs[input="imprecise"] > .tabs-scrollbox > .scrollbutton-down {
visibility: hidden !important;
pointer-events: none;
}
#tabs[input="imprecise"] > .tabs-scrollbox > .scrollbutton-down {
visibility: collapse !important;
}
#tabs > .tabs-scrollbox > .scrollbutton-up {
list-style-image: url("images/tab-arrows.png") !important;
-moz-image-region: rect(15px 58px 63px 14px) !important;

View File

@ -93,7 +93,7 @@ class MachCommands(MachCommandBase):
valgrind,
'--error-exitcode=1',
'--smc-check=all-non-file',
'--vex-iropt-register-updates=allregs-at-each-insn',
'--vex-iropt-register-updates=allregs-at-mem-access',
'--gen-suppressions=all',
'--num-callers=20',
'--leak-check=full',

View File

@ -738,7 +738,13 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
if (!mUrlString.IsEmpty() && mIsAnchor) {
nsAutoString dragData(mUrlString);
dragData.AppendLiteral("\n");
dragData += mTitleString;
// Remove leading and trailing newlines in the title and replace them with
// space in remaining positions - they confuse PlacesUtils::unwrapNodes
// that expects url\ntitle formatted data for x-moz-url.
nsAutoString title(mTitleString);
title.Trim("\r\n");
title.ReplaceChar("\r\n", ' ');
dragData += title;
AddString(aDataTransfer, NS_LITERAL_STRING(kURLMime), dragData, principal);
AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal);

View File

@ -34,6 +34,7 @@
#include "nsINameSpaceManager.h"
#include "nsIBaseWindow.h"
#include "nsISelection.h"
#include "nsITextControlElement.h"
#include "nsFrameSelection.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
@ -2795,6 +2796,16 @@ nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
continue;
}
// Don't scroll vertically by mouse-wheel on a single-line text control.
if (checkIfScrollableY) {
nsIContent* c = scrollFrame->GetContent();
nsCOMPtr<nsITextControlElement> ctrl =
do_QueryInterface(c->IsInAnonymousSubtree() ? c->GetBindingParent() : c);
if (ctrl && ctrl->IsSingleLineTextControl()) {
continue;
}
}
if (!checkIfScrollableX && !checkIfScrollableY) {
return frameToScroll;
}

View File

@ -87,6 +87,7 @@ skip-if = true # Disabled due to timeouts.
[test_bug944847.html]
skip-if = toolkit == "gonk"
[test_bug944011.html]
[test_bug946632.html]
[test_clickevent_on_input.html]
[test_continuous_wheel_events.html]
[test_dblclick_explicit_original_target.html]

View File

@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=946632
-->
<head>
<title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
.scrollable {
overflow: scroll;
height: 200px;
width: 200px;
}
input {
font-size: 72px;
height: 20px;
width: 20px;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946632">Mozilla Bug 946632</a>
<p id="display"></p>
<div id="container" class="scrollable">
<input value="value">
x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</div>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests, window);
var input = document.querySelector("input");
var container = document.querySelector("#container");
function prepare(check)
{
container.scrollTop = 0;
container.scrollLeft = 0;
input.scrollTop = 0;
input.scrollLeft = 0;
container.style.display='none';
container.getBoundingClientRect();
container.style.display='';
container.getBoundingClientRect();
scrollHandler = function(event) {
window.removeEventListener("scroll", arguments.callee, true);
event.stopPropagation();
check(event)
setTimeout(nextTest,0);
};
window.addEventListener("scroll", scrollHandler, true);
}
var tests = [
{
check: function(event) {
is(event.target, container, "<input> vertical line scroll targets container");
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
is(input.scrollLeft, 0, "<input> horizontal line scroll input.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
}
},
{
check: function(event) {
is(event.target, input, "<input> horizontal line scroll targets <input>");
is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
ok(input.scrollLeft > 0, "<input> horizontal line scroll input.scrollLeft");
is(container.scrollTop, 0, "<input> horizontal line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> horizontal line scroll container.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
}
},
{
check: function(event) {
is(event.target, container, "<input> vertical page scroll targets container");
ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
is(input.scrollTop, 0, "<input> vertical page scroll input.scrollTop");
is(input.scrollLeft, 0, "<input> vertical page scroll input.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaY: 1.0, lineOrPageDeltaY: 1 });
}
},
{
check: function(event) {
is(event.target, input, "<input> horizontal page scroll targets <input>");
is(input.scrollTop, 0, "<input> horizontal page scroll input.scrollTop");
ok(input.scrollLeft > 0, "<input> horizontal page scroll input.scrollLeft");
is(container.scrollTop, 0, "<input> horizontal page scroll container.scrollTop");
is(container.scrollLeft, 0, "<input> horizontal page scroll container.scrollLeft");
},
test: function() {
synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
deltaX: 1.0, lineOrPageDeltaX: 1 });
}
},
];
var i = 0;
function nextTest()
{
if (i == tests.length) {
SimpleTest.finish();
return;
}
var test = tests[i];
++i;
prepare(test.check);
test.test();
}
function runTests()
{
nextTest();
}
</script>
</pre>
</body>
</html>

View File

@ -152,7 +152,13 @@ static const char* GetOmxLibraryName()
return nullptr;
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
if (version == 13 || version == 12 || version == 11) {
/*
if (version >= 19) {
*/
if (version >= 16) {
return "libomxpluginkk.so";
}
else if (version == 13 || version == 12 || version == 11) {
return "libomxpluginhc.so";
}
else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) {
@ -180,7 +186,7 @@ static const char* GetOmxLibraryName()
return nullptr;
}
// Default libomxplugin for non-gingerbread devices
// Ice Cream Sandwich and Jellybean
return "libomxplugin.so";
#elif defined(ANDROID) && defined(MOZ_WIDGET_GONK)

View File

@ -131,7 +131,7 @@ IndexedDBParent::CloneProtocol(Channel* aChannel,
bool
IndexedDBParent::CheckPermissionInternal(const nsAString& aDatabaseName,
const nsDependentCString& aPermission)
const nsACString& aPermission)
{
MOZ_ASSERT(!mASCIIOrigin.IsEmpty());
MOZ_ASSERT(mManagerContent || mManagerTab);

View File

@ -201,7 +201,7 @@ public:
protected:
bool
CheckPermissionInternal(const nsAString& aDatabaseName,
const nsDependentCString& aPermission);
const nsACString& aPermission);
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;

View File

@ -611,7 +611,7 @@ TabChild::HandlePossibleViewportChange()
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
metrics, ScreenPoint(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same
// as the resolution.

View File

@ -754,6 +754,16 @@ static SourceSet *
class GetUserMediaRunnable : public nsRunnable
{
public:
/**
* GetUserMediaRunnable is meant for dispatch off main thread, where it would
* be illegal to free JS callbacks. Therefore, it uses a rather risky strategy
* of holding "already_AddRefed" references to the JS callbacks that must be
* transfered and released in consequent dispatches arriving on main thread.
*
* A special Arm() method must be called before dispatch to enable this
* behavior, because GetUserMediaRunnables are held in other circumstances.
*/
GetUserMediaRunnable(
const MediaStreamConstraintsInternal& aConstraints,
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> aSuccess,
@ -761,8 +771,10 @@ public:
uint64_t aWindowID, GetUserMediaCallbackMediaStreamListener *aListener,
MediaEnginePrefs &aPrefs)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
, mSuccess(nullptr)
, mError(nullptr)
, mSuccessHolder(aSuccess)
, mErrorHolder(aError)
, mWindowID(aWindowID)
, mListener(aListener)
, mPrefs(aPrefs)
@ -783,8 +795,10 @@ public:
MediaEnginePrefs &aPrefs,
MediaEngine* aBackend)
: mConstraints(aConstraints)
, mSuccess(aSuccess)
, mError(aError)
, mSuccess(nullptr)
, mError(nullptr)
, mSuccessHolder(aSuccess)
, mErrorHolder(aError)
, mWindowID(aWindowID)
, mListener(aListener)
, mPrefs(aPrefs)
@ -800,10 +814,24 @@ public:
}
}
/**
* Once "armed", GetUserMediaRunnable will leak its JS callbacks if destroyed.
* Arm() must be called before the runnable can be dispatched or used, and the
* runnable must be dispatched or used once armed. Callbacks get released on
* the main thread at the runnable's completion.
*/
void
Arm() {
mSuccess = mSuccessHolder.forget();
mError = mErrorHolder.forget();
}
NS_IMETHOD
Run()
{
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
// Was a backend provided?
if (!mBackendChosen) {
@ -842,8 +870,11 @@ public:
nsresult
Denied(const nsAString& aErrorMsg)
{
// We add a disabled listener to the StreamListeners array until accepted
// If this was the only active MediaStream, remove the window from the list.
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
// We add a disabled listener to the StreamListeners array until accepted
// If this was the only active MediaStream, remove the window from the list.
if (NS_IsMainThread()) {
// This is safe since we're on main-thread, and the window can only
// be invalidated from the main-thread (see OnNavigation)
@ -886,6 +917,8 @@ public:
nsresult
SelectDevice()
{
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
if (mConstraints.mPicture || mConstraints.mVideo) {
ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
@ -924,6 +957,8 @@ public:
void
ProcessGetUserMedia(MediaEngineSource* aAudioSource, MediaEngineSource* aVideoSource)
{
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
nsresult rv;
if (aAudioSource) {
rv = aAudioSource->Allocate(mPrefs);
@ -962,6 +997,8 @@ public:
void
ProcessGetUserMediaSnapshot(MediaEngineSource* aSource, int aDuration)
{
MOZ_ASSERT(mSuccess.mRawPtr);
MOZ_ASSERT(mError.mRawPtr);
nsresult rv = aSource->Allocate(mPrefs);
if (NS_FAILED(rv)) {
NS_DispatchToMainThread(new ErrorCallbackRunnable(
@ -988,6 +1025,8 @@ private:
already_AddRefed<nsIDOMGetUserMediaSuccessCallback> mSuccess;
already_AddRefed<nsIDOMGetUserMediaErrorCallback> mError;
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mSuccessHolder;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mErrorHolder;
uint64_t mWindowID;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
nsRefPtr<MediaDevice> mAudioDevice;
@ -1296,7 +1335,6 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
// Store the WindowID in a hash table and mark as active. The entry is removed
// when this window is closed or navigated away from.
uint64_t windowID = aWindow->WindowID();
nsRefPtr<GetUserMediaRunnable> gUMRunnable;
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
StreamListeners* listeners = GetActiveWindows()->Get(windowID);
@ -1340,17 +1378,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
c.mVideo = false;
}
/**
* Pass runnables along to GetUserMediaRunnable so it can add the
* MediaStreamListener to the runnable list.
*/
// Pass callbacks and MediaStreamListener along to GetUserMediaRunnable.
nsRefPtr<GetUserMediaRunnable> runnable;
if (c.mFake) {
// Fake stream from default backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs, new MediaEngineDefault());
} else {
// Stream from default device from WebRTC backend.
gUMRunnable = new GetUserMediaRunnable(c, onSuccess.forget(),
runnable = new GetUserMediaRunnable(c, onSuccess.forget(),
onError.forget(), windowID, listener, mPrefs);
}
@ -1363,13 +1399,15 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
if (c.mPicture) {
// ShowFilePickerForMimeType() must run on the Main Thread! (on Android)
NS_DispatchToMainThread(gUMRunnable);
runnable->Arm();
NS_DispatchToMainThread(runnable);
return NS_OK;
}
#endif
// XXX No full support for picture in Desktop yet (needs proper UI)
if (aPrivileged || c.mFake) {
mMediaThread->Dispatch(gUMRunnable, NS_DISPATCH_NORMAL);
runnable->Arm();
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
} else {
// Ask for user permission, and dispatch runnable (or not) when a response
// is received via an observer notification. Each call is paired with its
@ -1388,9 +1426,18 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
id.ToProvidedString(buffer);
NS_ConvertUTF8toUTF16 callID(buffer);
// Store the current callback.
mActiveCallbacks.Put(callID, gUMRunnable);
// Store the current unarmed runnable w/callbacks.
mActiveCallbacks.Put(callID, runnable);
// Add a WindowID cross-reference so OnNavigation can tear things down
nsTArray<nsString>* array;
if (!mCallIds.Get(windowID, &array)) {
array = new nsTArray<nsString>();
array->AppendElement(callID);
mCallIds.Put(windowID, array);
} else {
array->AppendElement(callID);
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
nsRefPtr<GetUserMediaRequest> req = new GetUserMediaRequest(aWindow,
callID, c);
@ -1471,6 +1518,14 @@ MediaManager::OnNavigation(uint64_t aWindowID)
// Invalidate this window. The runnables check this value before making
// a call to content.
nsTArray<nsString>* callIds;
if (mCallIds.Get(aWindowID, &callIds)) {
for (int i = 0, len = callIds->Length(); i < len; ++i) {
mActiveCallbacks.Remove((*callIds)[i]);
}
mCallIds.Remove(aWindowID);
}
// This is safe since we're on main-thread, and the windowlist can only
// be added to from the main-thread
StreamListeners* listeners = GetWindowListeners(aWindowID);
@ -1606,6 +1661,7 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
MutexAutoLock lock(mMutex);
GetActiveWindows()->Clear();
mActiveCallbacks.Clear();
mCallIds.Clear();
LOG(("Releasing MediaManager singleton and thread"));
sSingleton = nullptr;
}
@ -1614,25 +1670,24 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
} else if (!strcmp(aTopic, "getUserMedia:response:allow")) {
nsString key(aData);
nsRefPtr<nsRunnable> runnable;
nsRefPtr<GetUserMediaRunnable> runnable;
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
return NS_OK;
}
mActiveCallbacks.Remove(key);
runnable->Arm();
if (aSubject) {
// A particular device or devices were chosen by the user.
// NOTE: does not allow setting a device to null; assumes nullptr
GetUserMediaRunnable* gUMRunnable =
static_cast<GetUserMediaRunnable*>(runnable.get());
nsCOMPtr<nsISupportsArray> array(do_QueryInterface(aSubject));
MOZ_ASSERT(array);
uint32_t len = 0;
array->Count(&len);
MOZ_ASSERT(len);
if (!len) {
gUMRunnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED")); // neither audio nor video were selected
// neither audio nor video were selected
runnable->Denied(NS_LITERAL_STRING("PERMISSION_DENIED"));
return NS_OK;
}
for (uint32_t i = 0; i < len; i++) {
@ -1644,9 +1699,9 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
nsString type;
device->GetType(type);
if (type.EqualsLiteral("video")) {
gUMRunnable->SetVideoDevice(static_cast<MediaDevice*>(device.get()));
runnable->SetVideoDevice(static_cast<MediaDevice*>(device.get()));
} else if (type.EqualsLiteral("audio")) {
gUMRunnable->SetAudioDevice(static_cast<MediaDevice*>(device.get()));
runnable->SetAudioDevice(static_cast<MediaDevice*>(device.get()));
} else {
NS_WARNING("Unknown device type in getUserMedia");
}
@ -1670,15 +1725,13 @@ MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
}
nsString key(aData);
nsRefPtr<nsRunnable> runnable;
nsRefPtr<GetUserMediaRunnable> runnable;
if (!mActiveCallbacks.Get(key, getter_AddRefs(runnable))) {
return NS_OK;
}
mActiveCallbacks.Remove(key);
GetUserMediaRunnable* gUMRunnable =
static_cast<GetUserMediaRunnable*>(runnable.get());
gUMRunnable->Denied(errorMessage);
runnable->Arm();
runnable->Denied(errorMessage);
return NS_OK;
} else if (!strcmp(aTopic, "getUserMedia:revoke")) {

View File

@ -241,6 +241,7 @@ typedef enum {
} MediaOperation;
class MediaManager;
class GetUserMediaRunnable;
/**
* Send an error back to content. The error is the form a string.
@ -524,7 +525,8 @@ private:
// ONLY access from MainThread so we don't need to lock
WindowTable mActiveWindows;
nsRefPtrHashtable<nsStringHashKey, nsRunnable> mActiveCallbacks;
nsRefPtrHashtable<nsStringHashKey, GetUserMediaRunnable> mActiveCallbacks;
nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
// Always exists
nsCOMPtr<nsIThread> mMediaThread;

View File

@ -80,6 +80,7 @@ class nsGeolocationRequest
void SendLocation(nsIDOMGeoPosition* location);
bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
void SetTimeoutTimer();
void StopTimeoutTimer();
void NotifyErrorAndShutdown(uint16_t);
nsIPrincipal* GetPrincipal();
@ -348,6 +349,7 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
NS_IMETHODIMP
nsGeolocationRequest::Notify(nsITimer* aTimer)
{
StopTimeoutTimer();
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
return NS_OK;
}
@ -363,10 +365,6 @@ nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
}
NotifyError(aErrorCode);
if (!mShutdown) {
SetTimeoutTimer();
}
}
NS_IMETHODIMP
@ -475,10 +473,7 @@ nsGeolocationRequest::Allow()
void
nsGeolocationRequest::SetTimeoutTimer()
{
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
StopTimeoutTimer();
int32_t timeout;
if (mOptions && (timeout = mOptions->mTimeout) != 0) {
@ -494,6 +489,15 @@ nsGeolocationRequest::SetTimeoutTimer()
}
}
void
nsGeolocationRequest::StopTimeoutTimer()
{
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
}
void
nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
{
@ -539,12 +543,9 @@ nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition)
callback->HandleEvent(aPosition);
}
if (!mShutdown) {
// For watch requests, the handler may have called clearWatch
MOZ_ASSERT(mIsWatchPositionRequest,
"non-shutdown getCurrentPosition request after callback!");
SetTimeoutTimer();
}
StopTimeoutTimer();
MOZ_ASSERT(mShutdown || mIsWatchPositionRequest,
"non-shutdown getCurrentPosition request after callback!");
}
nsIPrincipal*
@ -564,6 +565,16 @@ nsGeolocationRequest::Update(nsIDOMGeoPosition* aPosition)
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationRequest::LocationUpdatePending()
{
if (!mTimeoutTimer) {
SetTimeoutTimer();
}
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationRequest::NotifyError(uint16_t aErrorCode)
{
@ -809,6 +820,16 @@ nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationService::LocationUpdatePending()
{
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
mGeolocators[i]->LocationUpdatePending();
}
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationService::NotifyError(uint16_t aErrorCode)
{
@ -1130,6 +1151,17 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
return NS_OK;
}
NS_IMETHODIMP
Geolocation::LocationUpdatePending()
{
// this event is only really interesting for watch callbacks
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
mWatchingCallbacks[i]->LocationUpdatePending();
}
return NS_OK;
}
NS_IMETHODIMP
Geolocation::NotifyError(uint16_t aErrorCode)
{

View File

@ -143,6 +143,9 @@ WifiGeoPositionProvider.prototype = {
LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE"));
this.hasSeenWiFi = true;
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
.locationUpdatePending();
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
function isPublic(ap) {

View File

@ -24,16 +24,16 @@ class CoreLocationObjects;
class CoreLocationLocationProvider
: public nsIGeolocationProvider
, public nsIGeolocationUpdate
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
NS_DECL_NSIGEOLOCATIONPROVIDER
CoreLocationLocationProvider();
static bool IsCoreLocationAvailable();
void NotifyError(uint16_t aErrorCode);
void Update(nsIDOMGeoPosition* aSomewhere);
private:
virtual ~CoreLocationLocationProvider() {};

View File

@ -218,19 +218,16 @@ CoreLocationLocationProvider::SetHighAccuracy(bool aEnable)
return NS_OK;
}
NS_IMETHODIMP
void
CoreLocationLocationProvider::Update(nsIDOMGeoPosition* aSomewhere)
{
if (aSomewhere && mCallback) {
mCallback->Update(aSomewhere);
}
return NS_OK;
}
NS_IMETHODIMP
void
CoreLocationLocationProvider::NotifyError(uint16_t aErrorCode)
{
mCallback->NotifyError(aErrorCode);
return NS_OK;
}

View File

@ -502,6 +502,16 @@ _cairo_win32_surface_finish (void *abstract_surface)
return CAIRO_STATUS_SUCCESS;
}
static void
get_d3d9_dc_and_clear_clip (cairo_win32_surface_t *surface)
{
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
// The DC that we get back from the surface will not have
// a clip so clear surface->clip_region so that we don't think we have
// one when we don't.
_cairo_win32_surface_set_clip_region (surface, NULL);
}
static cairo_status_t
_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
int x,
@ -521,7 +531,7 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
&rectout, &rectin, 0);
surface->dc = 0; // Don't use the DC when this is locked!
if (hr) {
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
get_d3d9_dc_and_clear_clip (surface);
return CAIRO_INT_STATUS_UNSUPPORTED;
}
local = cairo_image_surface_create_for_data (rectout.pBits,
@ -530,12 +540,12 @@ _cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface,
rectout.Pitch);
if (local == NULL) {
IDirect3DSurface9_UnlockRect (surface->d3d9surface);
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
get_d3d9_dc_and_clear_clip (surface);
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (local->base.status) {
IDirect3DSurface9_UnlockRect (surface->d3d9surface);
IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
get_d3d9_dc_and_clear_clip (surface);
return local->base.status;
}
@ -709,7 +719,7 @@ _cairo_win32_surface_release_source_image (void *abstract_surf
if (local && local->d3d9surface) {
IDirect3DSurface9_UnlockRect (local->d3d9surface);
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
get_d3d9_dc_and_clear_clip (surface);
cairo_surface_destroy ((cairo_surface_t *)image);
} else {
cairo_surface_destroy ((cairo_surface_t *)local);
@ -784,7 +794,7 @@ _cairo_win32_surface_release_dest_image (void *abstract_surfa
if (local->d3d9surface) {
IDirect3DSurface9_UnlockRect (local->d3d9surface);
IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
get_d3d9_dc_and_clear_clip (surface);
cairo_surface_destroy ((cairo_surface_t *)image);
} else {

View File

@ -154,8 +154,6 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
if (aOperator == OP_SOURCE) {
aTarget->PopClip();
}
aTarget->Flush();
}
void
@ -391,6 +389,17 @@ ComputeBufferRect(const nsIntRect& aRequestedRect)
return rect;
}
void
RotatedContentBuffer::FlushBuffers()
{
if (mDTBuffer) {
mDTBuffer->Flush();
}
if (mDTBufferOnWhite) {
mDTBufferOnWhite->Flush();
}
}
RotatedContentBuffer::PaintState
RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
uint32_t aFlags)

View File

@ -75,6 +75,8 @@ public:
BUFFER_WHITE, // The buffer with white background, only valid with component alpha.
BUFFER_BOTH // The combined black/white buffers, only valid for writing operations, not reading.
};
// It is the callers repsonsibility to ensure aTarget is flushed after calling
// this method.
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
float aOpacity = 1.0,
gfx::CompositionOp aOperator = gfx::OP_OVER,
@ -396,6 +398,10 @@ protected:
*/
bool EnsureBuffer();
bool EnsureBufferOnWhite();
// Flush our buffers if they are mapped.
void FlushBuffers();
/**
* True if we have a buffer where we can get it (but not necessarily
* mapped currently).

View File

@ -598,6 +598,8 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
mFrontBufferRect,
mFrontBufferRotation);
UpdateDestinationFrom(frontBuffer, updateRegion);
// We need to flush our buffers before we unlock our front textures
FlushBuffers();
mFrontClient->Unlock();
if (mFrontClientOnWhite) {
mFrontClientOnWhite->Unlock();
@ -816,6 +818,9 @@ DeprecatedContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
mFrontBufferRotation);
UpdateDestinationFrom(frontBuffer, updateRegion);
// We need to flush our buffers before we unlock our front textures
FlushBuffers();
mFrontAndBackBufferDiffer = false;
}

View File

@ -168,10 +168,10 @@ static int32_t gPanRepaintInterval = 250;
static int32_t gFlingRepaintInterval = 75;
/**
* Minimum amount of speed along an axis before we begin painting far ahead by
* adjusting the displayport.
* Minimum amount of speed along an axis before we switch to "skate" multipliers
* rather than using the "stationary" multipliers.
*/
static float gMinSkateSpeed = 0.7f;
static float gMinSkateSpeed = 1.0f;
/**
* Duration of a zoom to animation.
@ -207,22 +207,26 @@ static int gTouchListenerTimeout = 300;
*/
static int gNumPaintDurationSamples = 3;
/** The multiplier we apply to a dimension's length if it is skating. That is,
* if it's going above sMinSkateSpeed. We prefer to increase the size of the
/**
* The multiplier we apply to the displayport size if it is skating (current
* velocity is above gMinSkateSpeed). We prefer to increase the size of the
* Y axis because it is more natural in the case that a user is reading a page
* that scrolls up/down. Note that one, both or neither of these may be used
* at any instant.
* In general we want g[XY]SkateSizeMultiplier to be smaller than the corresponding
* stationary size multiplier because when panning fast we would like to paint
* less and get faster, more predictable paint times. When panning slowly we
* can afford to paint more even though it's slower.
*/
static float gXSkateSizeMultiplier = 3.0f;
static float gYSkateSizeMultiplier = 3.5f;
static float gXSkateSizeMultiplier = 1.5f;
static float gYSkateSizeMultiplier = 2.5f;
/** The multiplier we apply to a dimension's length if it is stationary. We
* prefer to increase the size of the Y axis because it is more natural in the
* case that a user is reading a page that scrolls up/down. Note that one,
* both or neither of these may be used at any instant.
/**
* The multiplier we apply to the displayport size if it is not skating (see
* documentation for gXSkateSizeMultiplier).
*/
static float gXStationarySizeMultiplier = 1.5f;
static float gYStationarySizeMultiplier = 2.5f;
static float gXStationarySizeMultiplier = 3.0f;
static float gYStationarySizeMultiplier = 3.5f;
/**
* The time period in ms that throttles mozbrowserasyncscroll event.
@ -931,8 +935,8 @@ float AsyncPanZoomController::PanDistance() {
return NS_hypot(mX.PanDistance(), mY.PanDistance());
}
const gfx::Point AsyncPanZoomController::GetVelocityVector() {
return gfx::Point(mX.GetVelocity(), mY.GetVelocity());
const ScreenPoint AsyncPanZoomController::GetVelocityVector() {
return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
}
const gfx::Point AsyncPanZoomController::GetAccelerationVector() {
@ -1159,103 +1163,65 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale,
mFrameMetrics.mScrollOffset = (mFrameMetrics.mScrollOffset + aFocus) - (aFocus / aScale);
}
bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier,
double aEstimatedPaintDuration,
float aCompositionBounds,
float aVelocity,
float aAcceleration,
float* aDisplayPortOffset,
float* aDisplayPortLength)
/**
* Attempts to enlarge the displayport along a single axis based on the
* velocity. aOffset and aLength are in/out parameters; they are initially set
* to the currently visible area and will be transformed to the area we should
* be drawing to minimize checkerboarding.
*/
static void
EnlargeDisplayPortAlongAxis(float* aOutOffset, float* aOutLength,
double aEstimatedPaintDurationMillis, float aVelocity,
float aStationarySizeMultiplier, float aSkateSizeMultiplier)
{
if (fabsf(aVelocity) > gMinSkateSpeed) {
// Enlarge the area we paint.
*aDisplayPortLength = aCompositionBounds * aSkateSizeMultiplier;
// Position the area we paint such that all of the excess that extends past
// the screen is on the side towards the velocity.
*aDisplayPortOffset = aVelocity > 0 ? 0 : aCompositionBounds - *aDisplayPortLength;
// Scale up the length using the appropriate multiplier and center the
// displayport around the visible area.
float multiplier = (fabsf(aVelocity) < gMinSkateSpeed
? aStationarySizeMultiplier
: aSkateSizeMultiplier);
float newLength = (*aOutLength) * multiplier;
*aOutOffset -= (newLength - (*aOutLength)) / 2;
*aOutLength = newLength;
// Only compensate for acceleration when we actually have any. Otherwise
// we'll overcompensate when a user is just panning around without flinging.
if (aAcceleration > 1.01f) {
// Compensate for acceleration and how long we expect a paint to take. We
// try to predict where the viewport will be when painting has finished.
*aDisplayPortOffset +=
fabsf(aAcceleration) * aVelocity * aCompositionBounds * aEstimatedPaintDuration;
// If our velocity is in the negative direction of the axis, we have to
// compensate for the fact that our scroll offset is the top-left position
// of the viewport. In this case, let's make it relative to the
// bottom-right. That way, we'll always be growing the displayport upwards
// and to the left when skating negatively.
*aDisplayPortOffset -= aVelocity < 0 ? aCompositionBounds : 0;
}
return true;
}
return false;
// Project the displayport out based on the estimated time it will take to paint
*aOutOffset += (aVelocity * aEstimatedPaintDurationMillis);
}
/* static */
const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const gfx::Point& aVelocity,
const ScreenPoint& aVelocity,
const gfx::Point& aAcceleration,
double aEstimatedPaintDuration)
{
// If we don't get an estimated paint duration, we probably don't have any
// data. In this case, we're dealing with either a stationary frame or a first
// paint. In either of these cases, we can just assume it'll take 1 second to
// paint. Getting this correct is not important anyways since it's only really
// useful when accelerating, which can't be happening at this point.
double estimatedPaintDuration =
aEstimatedPaintDuration > EPSILON ? aEstimatedPaintDuration : 1.0;
// convert to milliseconds
double estimatedPaintDurationMillis = aEstimatedPaintDuration * 1000;
CSSIntRect compositionBounds = gfx::RoundedIn(aFrameMetrics.mCompositionBounds / aFrameMetrics.mZoom);
CSSRect compositionBounds = aFrameMetrics.CalculateCompositedRectInCssPixels();
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
CSSRect displayPort(scrollOffset, compositionBounds.Size());
CSSPoint velocity = aVelocity / aFrameMetrics.mZoom;
// Enlarge the displayport along both axes depending on how fast we're moving
// on that axis and how long it takes to paint. Apply some heuristics to try
// to minimize checkerboarding.
EnlargeDisplayPortAlongAxis(&(displayPort.x), &(displayPort.width),
estimatedPaintDurationMillis, velocity.x,
gXStationarySizeMultiplier, gXSkateSizeMultiplier);
EnlargeDisplayPortAlongAxis(&(displayPort.y), &(displayPort.height),
estimatedPaintDurationMillis, velocity.y,
gYStationarySizeMultiplier, gYSkateSizeMultiplier);
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
CSSRect displayPort = CSSRect(compositionBounds);
displayPort.MoveTo(0, 0);
displayPort.Scale(gXStationarySizeMultiplier, gYStationarySizeMultiplier);
APZC_LOG_FM(aFrameMetrics,
"Calculated displayport as (%f %f %f %f) from velocity (%f %f) acceleration (%f %f) paint time %f metrics",
displayPort.x, displayPort.y, displayPort.width, displayPort.height,
aVelocity.x, aVelocity.y, aAcceleration.x, aAcceleration.y,
(float)estimatedPaintDurationMillis);
// If there's motion along an axis of movement, and it's above a threshold,
// then we want to paint a larger area in the direction of that motion so that
// it's less likely to checkerboard.
bool enlargedX = EnlargeDisplayPortAlongAxis(
gXSkateSizeMultiplier, estimatedPaintDuration,
compositionBounds.width, aVelocity.x, aAcceleration.x,
&displayPort.x, &displayPort.width);
bool enlargedY = EnlargeDisplayPortAlongAxis(
gYSkateSizeMultiplier, estimatedPaintDuration,
compositionBounds.height, aVelocity.y, aAcceleration.y,
&displayPort.y, &displayPort.height);
if (!enlargedX && !enlargedY) {
// Position the x and y such that the screen falls in the middle of the displayport.
displayPort.x = -(displayPort.width - compositionBounds.width) / 2;
displayPort.y = -(displayPort.height - compositionBounds.height) / 2;
} else if (!enlargedX) {
displayPort.width = compositionBounds.width;
} else if (!enlargedY) {
displayPort.height = compositionBounds.height;
}
// If we go over the bounds when trying to predict where we will be when this
// paint finishes, move it back into the range of the CSS content rect.
// FIXME/bug 780395: Generalize this. This code is pretty hacky as it will
// probably not work at all for RTL content. This is not intended to be
// incredibly accurate; it'll just prevent the entire displayport from being
// outside the content rect (which causes bad things to happen).
if (scrollOffset.x + compositionBounds.width > scrollableRect.width) {
scrollOffset.x -= compositionBounds.width + scrollOffset.x - scrollableRect.width;
} else if (scrollOffset.x < scrollableRect.x) {
scrollOffset.x = scrollableRect.x;
}
if (scrollOffset.y + compositionBounds.height > scrollableRect.height) {
scrollOffset.y -= compositionBounds.height + scrollOffset.y - scrollableRect.height;
} else if (scrollOffset.y < scrollableRect.y) {
scrollOffset.y = scrollableRect.y;
}
return displayPort.ForceInside(scrollableRect - scrollOffset);
return displayPort;
}
void AsyncPanZoomController::ScheduleComposite() {
@ -1598,7 +1564,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
endZoomToMetrics.mScrollOffset = aRect.TopLeft();
endZoomToMetrics.mDisplayPort =
CalculatePendingDisplayPort(endZoomToMetrics,
gfx::Point(0,0),
ScreenPoint(0,0),
gfx::Point(0,0),
0);

View File

@ -229,7 +229,7 @@ public:
*/
static const CSSRect CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const gfx::Point& aVelocity,
const ScreenPoint& aVelocity,
const gfx::Point& aAcceleration,
double aEstimatedPaintDuration);
@ -408,7 +408,7 @@ protected:
/**
* Gets a vector of the velocities of each axis.
*/
const gfx::Point GetVelocityVector();
const ScreenPoint GetVelocityVector();
/**
* Gets a vector of the acceleration factors of each axis.
@ -439,22 +439,6 @@ protected:
*/
void TrackTouch(const MultiTouchInput& aEvent);
/**
* Attempts to enlarge the displayport along a single axis. Returns whether or
* not the displayport was enlarged. This will fail in circumstances where the
* velocity along that axis is not high enough to need any changes. The
* displayport metrics are expected to be passed into |aDisplayPortOffset| and
* |aDisplayPortLength|. If enlarged, these will be updated with the new
* metrics.
*/
static bool EnlargeDisplayPortAlongAxis(float aSkateSizeMultiplier,
double aEstimatedPaintDuration,
float aCompositionBounds,
float aVelocity,
float aAcceleration,
float* aDisplayPortOffset,
float* aDisplayPortLength);
/**
* Utility function to send updated FrameMetrics to Gecko so that it can paint
* the displayport area. Calls into GeckoContentController to do the actual

View File

@ -29,111 +29,98 @@ extern PRLogModuleInfo *GetImgLog();
class LogScope {
public:
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn) :
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {ENTER}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get()));
GIVE_ME_MS_NOW(), mFrom, mFunc));
}
/* const char * constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
const nsDependentCString &paramName, const char *paramValue) :
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, const char *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get(),
paramName.get(),
paramValue));
GIVE_ME_MS_NOW(), mFrom, mFunc,
paramName, paramValue));
}
/* void ptr constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
const nsDependentCString &paramName, const void *paramValue) :
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, const void *paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=%p) {ENTER}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get(),
paramName.get(),
paramValue));
GIVE_ME_MS_NOW(), mFrom, mFunc,
paramName, paramValue));
}
/* int32_t constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
const nsDependentCString &paramName, int32_t paramValue) :
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, int32_t paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get(),
paramName.get(),
paramValue));
GIVE_ME_MS_NOW(), mFrom, mFunc,
paramName, paramValue));
}
/* uint32_t constructor */
LogScope(PRLogModuleInfo *aLog, void *from, const nsACString &fn,
const nsDependentCString &paramName, uint32_t paramValue) :
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, uint32_t paramValue) :
mLog(aLog), mFrom(from), mFunc(fn)
{
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get(),
paramName.get(),
paramValue));
GIVE_ME_MS_NOW(), mFrom, mFunc,
paramName, paramValue));
}
~LogScope() {
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {EXIT}\n",
GIVE_ME_MS_NOW(),
mFrom, mFunc.get()));
GIVE_ME_MS_NOW(), mFrom, mFunc));
}
private:
PRLogModuleInfo *mLog;
void *mFrom;
nsAutoCString mFunc;
const char *mFunc;
};
class LogFunc {
public:
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn)
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn)
{
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s\n",
GIVE_ME_MS_NOW(), from,
fn.get()));
GIVE_ME_MS_NOW(), from, fn));
}
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
const nsDependentCString &paramName, const char *paramValue)
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, const char *paramValue)
{
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\")\n",
GIVE_ME_MS_NOW(), from,
fn.get(),
paramName.get(), paramValue));
GIVE_ME_MS_NOW(), from, fn,
paramName, paramValue));
}
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
const nsDependentCString &paramName, const void *paramValue)
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, const void *paramValue)
{
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%p\")\n",
GIVE_ME_MS_NOW(), from,
fn.get(),
paramName.get(), paramValue));
GIVE_ME_MS_NOW(), from, fn,
paramName, paramValue));
}
LogFunc(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
const nsDependentCString &paramName, uint32_t paramValue)
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *paramName, uint32_t paramValue)
{
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\")\n",
GIVE_ME_MS_NOW(), from,
fn.get(),
paramName.get(), paramValue));
fn,
paramName, paramValue));
}
};
@ -141,13 +128,11 @@ public:
class LogMessage {
public:
LogMessage(PRLogModuleInfo *aLog, void *from, const nsDependentCString &fn,
const nsDependentCString &msg)
LogMessage(PRLogModuleInfo *aLog, void *from, const char *fn,
const char *msg)
{
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s -- %s\n",
GIVE_ME_MS_NOW(), from,
fn.get(),
msg.get()));
GIVE_ME_MS_NOW(), from, fn, msg));
}
};
@ -156,45 +141,22 @@ public:
#define LOG_SCOPE_APPEND_LINE_NUMBER(id) LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
#define LOG_SCOPE(l, s) \
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s))
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s)
#define LOG_SCOPE_WITH_PARAM(l, s, pn, pv) \
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s, pn, pv)
#define LOG_FUNC(l, s) \
LogFunc(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s))
#define LOG_FUNC(l, s) LogFunc(l, this, s)
#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) \
LogFunc(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#define LOG_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, this, s, pn, pv)
#define LOG_STATIC_FUNC(l, s) \
LogFunc(l, \
nullptr, \
NS_LITERAL_CSTRING(s))
#define LOG_STATIC_FUNC(l, s) LogFunc(l, nullptr, s)
#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) \
LogFunc(l, \
nullptr, \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(pn), pv)
#define LOG_STATIC_FUNC_WITH_PARAM(l, s, pn, pv) LogFunc(l, nullptr, s, pn, pv)
#define LOG_MSG(l, s, m) \
LogMessage(l, \
static_cast<void *>(this), \
NS_LITERAL_CSTRING(s), \
NS_LITERAL_CSTRING(m))
#define LOG_MSG(l, s, m) LogMessage(l, this, s, m)
#else

View File

@ -314,6 +314,12 @@ struct ParamTraits<nsCString> : ParamTraits<nsACString>
typedef nsCString paramType;
};
template <>
struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString>
{
typedef nsLiteralCString paramType;
};
#ifdef MOZILLA_INTERNAL_API
template<>
@ -330,6 +336,12 @@ struct ParamTraits<nsString> : ParamTraits<nsAString>
typedef nsString paramType;
};
template <>
struct ParamTraits<nsLiteralString> : ParamTraits<nsAString>
{
typedef nsLiteralString paramType;
};
template <typename E>
struct ParamTraits<FallibleTArray<E> >
{

View File

@ -335,6 +335,14 @@ const Class SIMDObject::class_ = {
JSObject *
SIMDObject::initClass(JSContext *cx, Handle<GlobalObject *> global)
{
// SIMD relies on having the TypedObject module initialized.
// In particular, the self-hosted code for array() wants
// to be able to call GetTypedObjectModule(). It is NOT necessary
// to install the TypedObjectModule global, but at the moment
// those two things are not separable.
if (!global->getOrCreateTypedObjectModule(cx))
return nullptr;
// Create SIMD Object.
RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
if(!objProto)

View File

@ -947,6 +947,8 @@ SizedTypeRepresentation::initInstance(const JSRuntime *rt,
uint8_t *mem,
size_t length)
{
JS_ASSERT(length >= 1);
MemoryInitVisitor visitor(rt);
// Initialize the 0th instance

View File

@ -231,7 +231,8 @@ class SizedTypeRepresentation : public TypeRepresentation {
size_t size() const { return size_; }
size_t alignment() const { return alignment_; }
// Initializes memory that contains `count` instances of this type
// Initializes memory that contains `count` instances of this type.
// `count` must be at least 1.
void initInstance(const JSRuntime *rt, uint8_t *mem, size_t count);
// Traces memory that contains `count` instances of this type.

View File

@ -2339,7 +2339,8 @@ TypedObject::createZeroed(JSContext *cx,
if (!memory)
return nullptr;
elementTypeRepr->initInstance(cx->runtime(), memory, length);
if (length)
elementTypeRepr->initInstance(cx->runtime(), memory, length);
obj->attach(memory);
return obj;
}

View File

@ -0,0 +1,10 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var float32x4 = SIMD.float32x4;
float32x4.array(1);

View File

@ -0,0 +1,18 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
// bug 953111
var A = TypedObject.uint8.array();
var a = new A(0);
a.forEach(function(val, i) {});
// bug 951356 (dup, but a dup that is more likely to crash)
var AA = TypedObject.uint8.array(2147483647).array();
var aa = new AA(0);

View File

@ -6686,7 +6686,7 @@ IonBuilder::getElemTryScalarElemOfTypedObject(bool *emitted,
TypeRepresentationSet elemTypeReprs,
size_t elemSize)
{
JS_ASSERT(objTypeReprs.kind() == TypeRepresentation::SizedArray);
JS_ASSERT(objTypeReprs.allOfArrayKind());
// Must always be loading the same scalar type
if (!elemTypeReprs.singleton())

View File

@ -703,19 +703,21 @@ CodeGeneratorARM::modICommon(MMod *mir, Register lhs, Register rhs, Register out
// the flags necessary for LT to trigger, we don't test X, and take the
// bailout because the EQ flag is set.
// if (Y > 0), we don't set EQ, and we don't trigger LT, so we don't take the bailout.
masm.ma_cmp(rhs, Imm32(0));
masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
if (mir->isTruncated()) {
// NaN|0 == 0 and (0 % -X)|0 == 0
Label skip;
masm.ma_b(&skip, Assembler::NotEqual);
masm.ma_mov(Imm32(0), output);
masm.ma_b(&done);
masm.bind(&skip);
} else {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Equal, snapshot))
return false;
if (mir->canBeDivideByZero() || mir->canBeNegativeDividend()) {
masm.ma_cmp(rhs, Imm32(0));
masm.ma_cmp(lhs, Imm32(0), Assembler::LessThan);
if (mir->isTruncated()) {
// NaN|0 == 0 and (0 % -X)|0 == 0
Label skip;
masm.ma_b(&skip, Assembler::NotEqual);
masm.ma_mov(Imm32(0), output);
masm.ma_b(&done);
masm.bind(&skip);
} else {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Equal, snapshot))
return false;
}
}
return true;
@ -740,16 +742,18 @@ CodeGeneratorARM::visitModI(LModI *ins)
masm.ma_smod(lhs, rhs, output);
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
if (mir->isTruncated()) {
// -0.0|0 == 0
} else {
JS_ASSERT(mir->fallible());
// See if X < 0
masm.ma_cmp(output, Imm32(0));
masm.ma_b(&done, Assembler::NotEqual);
masm.ma_cmp(callTemp, Imm32(0));
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
if (mir->canBeNegativeDividend()) {
if (mir->isTruncated()) {
// -0.0|0 == 0
} else {
JS_ASSERT(mir->fallible());
// See if X < 0
masm.ma_cmp(output, Imm32(0));
masm.ma_b(&done, Assembler::NotEqual);
masm.ma_cmp(callTemp, Imm32(0));
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
}
}
masm.bind(&done);
@ -802,16 +806,18 @@ CodeGeneratorARM::visitSoftModI(LSoftModI *ins)
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, __aeabi_idivmod));
// If X%Y == 0 and X < 0, then we *actually* wanted to return -0.0
if (mir->isTruncated()) {
// -0.0|0 == 0
} else {
JS_ASSERT(mir->fallible());
// See if X < 0
masm.ma_cmp(r1, Imm32(0));
masm.ma_b(&done, Assembler::NotEqual);
masm.ma_cmp(callTemp, Imm32(0));
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
if (mir->canBeNegativeDividend()) {
if (mir->isTruncated()) {
// -0.0|0 == 0
} else {
JS_ASSERT(mir->fallible());
// See if X < 0
masm.ma_cmp(r1, Imm32(0));
masm.ma_b(&done, Assembler::NotEqual);
masm.ma_cmp(callTemp, Imm32(0));
if (!bailoutIf(Assembler::Signed, ins->snapshot()))
return false;
}
}
masm.bind(&done);
return true;
@ -830,12 +836,14 @@ CodeGeneratorARM::visitModPowTwoI(LModPowTwoI *ins)
masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed);
masm.ma_and(Imm32((1<<ins->shift())-1), out);
masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed);
if (!mir->isTruncated()) {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
} else {
// -0|0 == 0
if (mir->canBeNegativeDividend()) {
if (!mir->isTruncated()) {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
} else {
// -0|0 == 0
}
}
masm.bind(&fin);
return true;
@ -849,12 +857,14 @@ CodeGeneratorARM::visitModMaskI(LModMaskI *ins)
Register tmp = ToRegister(ins->getTemp(0));
MMod *mir = ins->mir();
masm.ma_mod_mask(src, dest, tmp, ins->shift());
if (!mir->isTruncated()) {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
} else {
// -0|0 == 0
if (mir->canBeNegativeDividend()) {
if (!mir->isTruncated()) {
JS_ASSERT(mir->fallible());
if (!bailoutIf(Assembler::Zero, ins->snapshot()))
return false;
} else {
// -0|0 == 0
}
}
return true;
}

View File

@ -3209,7 +3209,7 @@ TypeObject::clearNewScriptAddendum(ExclusiveContext *cx)
}
if (!finished) {
if (!obj->rollbackProperties(cx, numProperties))
if (!JSObject::rollbackProperties(cx, obj, numProperties))
cx->compartment()->types.setPendingNukeTypes(cx);
}
}

View File

@ -416,7 +416,8 @@ class JSObject : public js::ObjectImpl
elements[i].js::HeapSlot::~HeapSlot();
}
bool rollbackProperties(js::ExclusiveContext *cx, uint32_t slotSpan);
static bool rollbackProperties(js::ExclusiveContext *cx, js::HandleObject obj,
uint32_t slotSpan);
void nativeSetSlot(uint32_t slot, const js::Value &value) {
JS_ASSERT(isNative());

View File

@ -1156,26 +1156,26 @@ JSObject::clear(JSContext *cx, HandleObject obj)
obj->checkShapeConsistency();
}
bool
JSObject::rollbackProperties(ExclusiveContext *cx, uint32_t slotSpan)
/* static */ bool
JSObject::rollbackProperties(ExclusiveContext *cx, HandleObject obj, uint32_t slotSpan)
{
/*
* Remove properties from this object until it has a matching slot span.
* The object cannot have escaped in a way which would prevent safe
* removal of the last properties.
*/
JS_ASSERT(!inDictionaryMode() && slotSpan <= this->slotSpan());
JS_ASSERT(!obj->inDictionaryMode() && slotSpan <= obj->slotSpan());
while (true) {
if (lastProperty()->isEmptyShape()) {
if (obj->lastProperty()->isEmptyShape()) {
JS_ASSERT(slotSpan == 0);
break;
} else {
uint32_t slot = lastProperty()->slot();
uint32_t slot = obj->lastProperty()->slot();
if (slot < slotSpan)
break;
JS_ASSERT(getSlot(slot).isUndefined());
JS_ASSERT(obj->getSlot(slot).isUndefined());
}
if (!removeProperty(cx, lastProperty()->propid()))
if (!obj->removeProperty(cx, obj->lastProperty()->propid()))
return false;
}

View File

@ -47,6 +47,15 @@ XPCStringConvert::ClearZoneCache(JS::Zone *zone)
}
}
// static
void
XPCStringConvert::FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars)
{
}
const JSStringFinalizer XPCStringConvert::sLiteralFinalizer =
{ XPCStringConvert::FinalizeLiteral };
// static
void
XPCStringConvert::FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
@ -74,6 +83,16 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
return true;
}
if (readable.IsLiteral()) {
JSString *str = JS_NewExternalString(cx,
static_cast<const jschar*>(readable.BeginReading()),
length, &sLiteralFinalizer);
if (!str)
return false;
vp.setString(str);
return true;
}
nsStringBuffer *buf = nsStringBuffer::FromString(readable);
if (buf) {
bool shared;

View File

@ -238,7 +238,9 @@ public:
static void ClearZoneCache(JS::Zone *zone);
private:
static const JSStringFinalizer sDOMStringFinalizer;
static const JSStringFinalizer sLiteralFinalizer, sDOMStringFinalizer;
static void FinalizeLiteral(const JSStringFinalizer *fin, jschar *chars);
static void FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars);

View File

@ -376,7 +376,9 @@ nsFirstLetterFrame::DrainOverflowFrames(nsPresContext* aPresContext)
if (kidContent) {
NS_ASSERTION(kidContent->IsNodeOfType(nsINode::eTEXT),
"should contain only text nodes");
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(mStyleContext);
nsStyleContext* parentSC = prevInFlow ? mStyleContext->GetParent() :
mStyleContext;
sc = aPresContext->StyleSet()->ResolveStyleForNonElement(parentSC);
kid->SetStyleContext(sc);
}
}

View File

@ -1359,8 +1359,9 @@ nsFlexContainerFrame::SanityCheckAnonymousFlexItems() const
"but it isn't");
if (child->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::anonymousFlexItem) {
MOZ_ASSERT(!prevChildWasAnonFlexItem,
"two anon flex items in a row (shouldn't happen)");
MOZ_ASSERT(!prevChildWasAnonFlexItem || mChildrenHaveBeenReordered,
"two anon flex items in a row (shouldn't happen, unless our "
"children have been reordered with the 'order' property)");
nsIFrame* firstWrappedChild = child->GetFirstPrincipalChild();
MOZ_ASSERT(firstWrappedChild,

View File

@ -0,0 +1,22 @@
<style type="text/css">
#descdiv{
overflow: hidden;
height: 60px;
border: 1px solid red;
}
#descdiv p{
height:30px;
margin:0;
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
This causes the text to be drawn even when it's outside of the clip*/
text-shadow: #fff 1px -1px 2px;
}
</style>
<div id="descdiv">
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
</div>

View File

@ -0,0 +1,22 @@
<style type="text/css">
#descdiv{
overflow: hidden;
height: 60px;
border: 1px solid red;
}
#descdiv p{
height:30px;
margin:0;
/* The shadow of the text will be inside the overflow-hidden but the text it self will not.
This causes the text to be drawn even when it's outside of the clip*/
text-shadow: #fff 1px -1px 2px;
}
</style>
<div id="descdiv">
<p class="um_desc">&nbsp;</p>
<p class="um_desc">&nbsp;</p>
<p class="um_desc">sed diam nonummy nibh</p>
</div>

View File

@ -1791,5 +1791,6 @@ fuzzy-if(OSX==10.6,2,30) == 933264-1.html 933264-1-ref.html
== 941940-1.html 941940-1-ref.html
== 942017.html 942017-ref.html
== 942672-1.html 942672-1-ref.html
== 953334-win32-clipping.html 953334-win32-clipping-ref.html
== 956513-1.svg 956513-1-ref.svg
== 944291-1.html 944291-1-ref.html

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<meta charset="utf-8">
</head>
<body>
a ab bx x
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>CSS Test: Testing that we gracefully handle cases where two anonymous flex items become adjacent due to "order" reordering</title>
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#flex-items">
<link rel="match" href="flexbox-anonymous-items-1-ref.html">
<meta charset="utf-8">
<style>
.flexContainer {
display: flex;
}
</style>
</head>
<body>
<div class="flexContainer">
a a
<div style="order: 1">x x</div>
b b
</div>
</body>
</html>

View File

@ -1,3 +1,6 @@
# Tests for handling anonymous flex items
== flexbox-anonymous-items-1.html flexbox-anonymous-items-1-ref.html
# Tests for alignment of flex lines (align-content property)
== flexbox-align-content-horiz-1a.xhtml flexbox-align-content-horiz-1-ref.xhtml
== flexbox-align-content-horiz-1b.xhtml flexbox-align-content-horiz-1-ref.xhtml

View File

@ -23,6 +23,9 @@
#include "android/log.h"
#define MAX_DECODER_NAME_LEN 256
#define AVC_MIME_TYPE "video/avc"
#if !defined(MOZ_ANDROID_FROYO)
#define DEFAULT_STAGEFRIGHT_FLAGS OMXCodec::kClientNeedsFramebuffer
#else
@ -239,7 +242,13 @@ static uint32_t GetVideoCreationFlags(PluginHost* aPluginHost)
#endif
}
static bool
enum ColorFormatSupport {
ColorFormatNotSupported = 0,
ColorFormatSupportOK,
ColorFormatSupportPreferred,
};
static ColorFormatSupport
IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
{
switch (aColorFormat) {
@ -250,15 +259,19 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
LOG("Colour format %#x supported natively.", aColorFormat);
return true;
// Prefer natively supported colour formats over formats that need another
// slow software conversion.
return ColorFormatSupportPreferred;
default:
break;
}
// These formats are okay if we can't find a better one; Android provides a
// software conversion to a sane colour format.
#if !defined(MOZ_ANDROID_HC)
if (ColorConverter(aColorFormat, OMX_COLOR_Format16bitRGB565).isValid()) {
LOG("Colour format %#x supported by Android ColorConverter.", aColorFormat);
return true;
return ColorFormatSupportOK;
}
#endif
@ -268,12 +281,64 @@ IsColorFormatSupported(OMX_COLOR_FORMATTYPE aColorFormat)
if (yuvConverter.isLoaded() &&
yuvConverter.getDecoderOutputFormat() == aColorFormat) {
LOG("Colour format %#x supported by Android I420ColorConverter.", aColorFormat);
return true;
return ColorFormatSupportOK;
}
#endif
return ColorFormatNotSupported;
}
#if defined(MOZ_ANDROID_KK)
/**
* Look for a decoder that supports a colour format that we support.
*/
static bool
FindPreferredDecoderAndColorFormat(const sp<IOMX>& aOmx,
char *aDecoderName,
size_t aDecoderLen,
OMX_COLOR_FORMATTYPE *aColorFormat)
{
Vector<CodecCapabilities> codecs;
// Get all AVC decoder/colour format pairs that this device supports.
QueryCodecs(aOmx, AVC_MIME_TYPE, true /* queryDecoders */, &codecs);
// We assume that faster (hardware accelerated) decoders come first in the
// list, so we choose the first decoder with a colour format we can use.
for (uint32_t i = 0; i < codecs.size(); i++) {
const CodecCapabilities &caps = codecs[i];
const Vector<OMX_U32> &colors = caps.mColorFormats;
bool found = false;
for (uint32_t j = 0; j < colors.size(); j++) {
OMX_COLOR_FORMATTYPE color = (OMX_COLOR_FORMATTYPE)colors[j];
LOG("Decoder %s can output colour format %#x.\n",
caps.mComponentName.string(), color);
ColorFormatSupport supported = IsColorFormatSupported(color);
if (supported) {
strncpy(aDecoderName, caps.mComponentName.string(), aDecoderLen);
*aColorFormat = (OMX_COLOR_FORMATTYPE)color;
found = true;
}
if (supported == ColorFormatSupportPreferred) {
// The colour format is natively supported -- that's as good as we're
// going to get.
break;
}
}
if (found) {
return true;
}
}
return false;
}
#endif
static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
const sp<IOMX>& aOmx,
@ -281,10 +346,29 @@ static sp<MediaSource> CreateVideoSource(PluginHost* aPluginHost,
{
uint32_t flags = GetVideoCreationFlags(aPluginHost);
char decoderName[MAX_DECODER_NAME_LEN] = "";
sp<MetaData> videoFormat = aVideoTrack->getFormat();
#if defined(MOZ_ANDROID_KK)
OMX_COLOR_FORMATTYPE colorFormat = (OMX_COLOR_FORMATTYPE)0;
if (FindPreferredDecoderAndColorFormat(aOmx,
decoderName, sizeof(decoderName),
&colorFormat)) {
// We found a colour format that we can handle. Tell OMXCodec to use it in
// case it isn't the default.
videoFormat->setInt32(kKeyColorFormat, colorFormat);
LOG("Found compatible decoder %s with colour format %#x.\n",
decoderName, colorFormat);
}
#endif
if (flags == DEFAULT_STAGEFRIGHT_FLAGS) {
// Let Stagefright choose hardware or software decoder.
sp<MediaSource> videoSource = OMXCodec::Create(aOmx, aVideoTrack->getFormat(),
false, aVideoTrack, nullptr, flags);
sp<MediaSource> videoSource = OMXCodec::Create(aOmx, videoFormat,
false, aVideoTrack,
decoderName[0] ? decoderName : nullptr,
flags);
if (videoSource == nullptr)
return nullptr;

View File

@ -21,7 +21,8 @@
#include <stdint.h>
#include <sys/types.h>
#include <utils/Log.h>
#include <cutils/log.h>
#include <utils/VectorImpl.h>
#include <utils/TypeHelpers.h>
@ -43,11 +44,11 @@ class Vector : private VectorImpl
{
public:
typedef TYPE value_type;
/*!
/*!
* Constructors and destructors
*/
Vector();
Vector(const Vector<TYPE>& rhs);
explicit Vector(const SortedVector<TYPE>& rhs);
@ -55,7 +56,7 @@ public:
/*! copy operator */
const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
@ -66,29 +67,35 @@ public:
inline void clear() { VectorImpl::clear(); }
/*!
/*!
* vector stats
*/
//! returns number of items in the vector
inline size_t size() const { return VectorImpl::size(); }
//! returns wether or not the vector is empty
//! returns whether or not the vector is empty
inline bool isEmpty() const { return VectorImpl::isEmpty(); }
//! returns how many items can be stored without reallocating the backing store
inline size_t capacity() const { return VectorImpl::capacity(); }
//! setst the capacity. capacity can never be reduced less than size()
//! sets the capacity. capacity can never be reduced less than size()
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
/*!
/*!
* set the size of the vector. items are appended with the default
* constructor, or removed from the end as needed.
*/
inline ssize_t resize(size_t size) { return VectorImpl::resize(size); }
/*!
* C-style array access
*/
//! read-only C-style access
//! read-only C-style access
inline const TYPE* array() const;
//! read-write C-style access
TYPE* editArray();
/*!
/*!
* accessors
*/
@ -98,22 +105,20 @@ public:
inline const TYPE& itemAt(size_t index) const;
//! stack-usage of the vector. returns the top of the stack (last element)
const TYPE& top() const;
//! same as operator [], but allows to access the vector backward (from the end) with a negative index
const TYPE& mirrorItemAt(ssize_t index) const;
/*!
* modifing the array
* modifying the array
*/
//! copy-on write support, grants write access to an item
TYPE& editItemAt(size_t index);
//! grants right acces to the top of the stack (last element)
//! grants right access to the top of the stack (last element)
TYPE& editTop();
/*!
/*!
* append/insert another vector
*/
//! insert another vector at a given index
ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index);
@ -127,10 +132,10 @@ public:
//! append an array at the end of this vector
ssize_t appendArray(const TYPE* array, size_t length);
/*!
/*!
* add/insert/replace items
*/
//! insert one or several items initialized with their default constructor
inline ssize_t insertAt(size_t index, size_t numItems = 1);
//! insert one or several items initialized from a prototype item
@ -144,7 +149,7 @@ public:
//! same as push() but returns the index the item was added at (or an error)
inline ssize_t add();
//! same as push() but returns the index the item was added at (or an error)
ssize_t add(const TYPE& item);
ssize_t add(const TYPE& item);
//! replace an item with a new one initialized with its default constructor
inline ssize_t replaceAt(size_t index);
//! replace an item with a new one
@ -162,10 +167,10 @@ public:
/*!
* sort (stable) the array
*/
typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
inline status_t sort(compar_t cmp);
inline status_t sort(compar_r_t cmp, void* state);
@ -186,10 +191,11 @@ public:
inline const_iterator end() const { return array() + size(); }
inline void reserve(size_t n) { setCapacity(n); }
inline bool empty() const{ return isEmpty(); }
inline void push_back(const TYPE& item) { insertAt(item, size()); }
inline void push_front(const TYPE& item) { insertAt(item, 0); }
inline void push_back(const TYPE& item) { insertAt(item, size(), 1); }
inline void push_front(const TYPE& item) { insertAt(item, 0, 1); }
inline iterator erase(iterator pos) {
return begin() + removeItemsAt(pos-array());
ssize_t index = removeItemsAt(pos-array());
return begin() + index;
}
protected:
@ -201,6 +207,9 @@ protected:
virtual void do_move_backward(void* dest, const void* from, size_t num) const;
};
// Vector<T> can be trivially moved using memcpy() because moving does not
// require any change to the underlying SharedBuffer contents or reference count.
template<typename T> struct trait_trivial_move<Vector<T> > { enum { value = true }; };
// ---------------------------------------------------------------------------
// No user serviceable parts from here...
@ -234,7 +243,7 @@ Vector<TYPE>::~Vector() {
template<class TYPE> inline
Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
VectorImpl::operator = (rhs);
return *this;
return *this;
}
template<class TYPE> inline
@ -252,7 +261,7 @@ Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
template<class TYPE> inline
const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
VectorImpl::operator = (rhs);
return *this;
return *this;
}
template<class TYPE> inline
@ -268,8 +277,9 @@ TYPE* Vector<TYPE>::editArray() {
template<class TYPE> inline
const TYPE& Vector<TYPE>::operator[](size_t index) const {
LOG_FATAL_IF( index>=size(),
"itemAt: index %d is past size %d", (int)index, (int)size() );
LOG_FATAL_IF(index>=size(),
"%s: index=%u out of range (%u)", __PRETTY_FUNCTION__,
int(index), int(size()));
return *(array() + index);
}
@ -278,14 +288,6 @@ const TYPE& Vector<TYPE>::itemAt(size_t index) const {
return operator[](index);
}
template<class TYPE> inline
const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
"mirrorItemAt: index %d is past size %d",
(int)index, (int)size() );
return *(array() + ((index<0) ? (size()-index) : index));
}
template<class TYPE> inline
const TYPE& Vector<TYPE>::top() const {
return *(array() + size() - 1);
@ -419,3 +421,4 @@ void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) co
// ---------------------------------------------------------------------------
#endif // ANDROID_VECTOR_H

View File

@ -53,24 +53,25 @@ public:
/*! must be called from subclasses destructor */
void finish_vector();
VectorImpl& operator = (const VectorImpl& rhs);
VectorImpl& operator = (const VectorImpl& rhs);
/*! C-style array access */
inline const void* arrayImpl() const { return mStorage; }
void* editArrayImpl();
/*! vector stats */
inline size_t size() const { return mCount; }
inline bool isEmpty() const { return mCount == 0; }
size_t capacity() const;
ssize_t setCapacity(size_t size);
ssize_t resize(size_t size);
/*! append/insert another vector or array */
ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
ssize_t appendVector(const VectorImpl& vector);
ssize_t insertArrayAt(const void* array, size_t index, size_t length);
ssize_t appendArray(const void* array, size_t length);
/*! add/insert/replace items */
ssize_t insertAt(size_t where, size_t numItems = 1);
ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
@ -105,16 +106,6 @@ protected:
virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
// take care of FBC...
virtual void reservedVectorImpl1();
virtual void reservedVectorImpl2();
virtual void reservedVectorImpl3();
virtual void reservedVectorImpl4();
virtual void reservedVectorImpl5();
virtual void reservedVectorImpl6();
virtual void reservedVectorImpl7();
virtual void reservedVectorImpl8();
private:
void* _grow(size_t where, size_t amount);
void _shrink(size_t where, size_t amount);
@ -143,8 +134,8 @@ public:
SortedVectorImpl(size_t itemSize, uint32_t flags);
SortedVectorImpl(const VectorImpl& rhs);
virtual ~SortedVectorImpl();
SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
//! finds the index of an item
ssize_t indexOf(const void* item) const;
@ -158,23 +149,13 @@ public:
//! merges a vector into this one
ssize_t merge(const VectorImpl& vector);
ssize_t merge(const SortedVectorImpl& vector);
//! removes an item
ssize_t remove(const void* item);
protected:
virtual int do_compare(const void* lhs, const void* rhs) const = 0;
// take care of FBC...
virtual void reservedSortedVectorImpl1();
virtual void reservedSortedVectorImpl2();
virtual void reservedSortedVectorImpl3();
virtual void reservedSortedVectorImpl4();
virtual void reservedSortedVectorImpl5();
virtual void reservedSortedVectorImpl6();
virtual void reservedSortedVectorImpl7();
virtual void reservedSortedVectorImpl8();
private:
ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
@ -200,3 +181,4 @@ private:
// ---------------------------------------------------------------------------
#endif // ANDROID_VECTOR_IMPL_H

View File

@ -0,0 +1,31 @@
# Copyright 2012 Mozilla Foundation and Mozilla contributors
#
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Don't use STL wrappers; this isn't Gecko code
STL_FLAGS =
# must link statically with the CRT; this isn't Gecko code
USE_STATIC_LIBS = 1
include $(topsrcdir)/config/rules.mk
EXTRA_DSO_LDOPTS += \
-L$(DEPTH)/media/omx-plugin/lib/ics/libutils \
-lutils \
-L$(DEPTH)/media/omx-plugin/lib/ics/libstagefright \
-lstagefright \
-L$(DEPTH)/media/omx-plugin/lib/ics/libvideoeditorplayer \
-lvideoeditorplayer \
$(NULL)

View File

@ -0,0 +1,8 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#define MOZ_STAGEFRIGHT_OFF_T off64_t
#define MOZ_ANDROID_KK
#include "../OmxPlugin.cpp"

View File

@ -0,0 +1,20 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
SOURCES += [
'OmxPluginKitKat.cpp',
]
LIBRARY_NAME = 'omxpluginkk'
FORCE_SHARED_LIB = True
LOCAL_INCLUDES += [
'../../../content/media/plugins',
'../include/ics',
'../include/ics/media/stagefright/openmax',
]

View File

@ -61,6 +61,12 @@ MetaData::findInt32(uint32_t key, int32_t *value)
return false;
}
MOZ_EXPORT bool
MetaData::setInt32(uint32_t, int32_t)
{
return false;
}
MOZ_EXPORT bool
MetaData::findInt64(uint32_t key, int64_t *value)
{
@ -176,4 +182,12 @@ ColorConverter::convert(const void *srcBits,
{
return 0;
}
MOZ_EXPORT status_t QueryCodecs(const sp<IOMX> &omx,
const char *mimeType, bool queryDecoders,
Vector<CodecCapabilities> *results)
{
return 0;
}
}

View File

@ -7,6 +7,7 @@
#include "utils/RefBase.h"
#include "utils/String16.h"
#include "utils/String8.h"
#include "utils/Vector.h"
namespace android {
MOZ_EXPORT RefBase::RefBase() : mRefs(0)
@ -54,7 +55,30 @@ MOZ_EXPORT String8::String8()
{
}
MOZ_EXPORT String8::String8(const String8 &)
{
}
MOZ_EXPORT String8::~String8()
{
}
MOZ_EXPORT VectorImpl::VectorImpl(size_t, uint32_t)
: mFlags(0), mItemSize(0)
{
}
MOZ_EXPORT VectorImpl::VectorImpl(const VectorImpl &)
: mFlags(0), mItemSize(0)
{
}
MOZ_EXPORT VectorImpl::~VectorImpl()
{
}
MOZ_EXPORT void VectorImpl::finish_vector()
{
}
}

View File

@ -47,6 +47,7 @@
@BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginkk@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginfroyo@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@

View File

@ -1381,6 +1381,9 @@ nsHttpConnection::OnSocketReadable()
PRIntervalTime now = PR_IntervalNow();
PRIntervalTime delta = now - mLastReadTime;
// Reset mResponseTimeoutEnabled to stop response timeout checks.
mResponseTimeoutEnabled = false;
if (mKeepAliveMask && (delta >= mMaxHangTime)) {
LOG(("max hang time exceeded!\n"));
// give the handler a chance to create a new persistent connection to

View File

@ -23,7 +23,8 @@ XCODE_APP_STORE = 'macappstore://itunes.apple.com/app/id497799835?mt=12'
XCODE_LEGACY = 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_3.2.6_and_ios_sdk_4.3__final/xcode_3.2.6_and_ios_sdk_4.3.dmg'
HOMEBREW_AUTOCONF213 = 'https://raw.github.com/Homebrew/homebrew-versions/master/autoconf213.rb'
MACPORTS_URL = {'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg',
MACPORTS_URL = {'9': 'https://distfiles.macports.org/MacPorts/MacPorts-2.2.1-10.9-Mavericks.pkg',
'8': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg',
'7': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.7-Lion.pkg',
'6': 'https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.6-SnowLeopard.pkg',}

View File

@ -209,3 +209,8 @@ class WaitUntilTest(MarionetteTestCase):
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)
self.assertEqual(self.clock.ticks, 2)
def test_timeout_elapsed_duration(self):
with self.assertRaisesRegexp(errors.TimeoutException,
"Timed out after 2 seconds"):
self.w.until(lambda x: x.true(wait=4), is_true=at_third_attempt)

View File

@ -40,7 +40,7 @@ class Wait(object):
# every 5 seconds.
wait = Wait(marionette, timeout=30, interval=5,
ignored_exceptions=errors.NoSuchWindowException)
window = wait.until(lambda marionette: marionette.switch_to_window(42))
window = wait.until(lambda m: m.switch_to_window(42))
:param marionette: The input value to be provided to
conditions, usually a Marionette instance.
@ -78,7 +78,6 @@ class Wait(object):
exceptions.append(ignored_exceptions)
self.exceptions = tuple(set(exceptions))
def until(self, condition, is_true=None):
"""Repeatedly runs condition until its return value evaluates to true,
or its timeout expires or the predicate evaluates to true.
@ -109,6 +108,7 @@ class Wait(object):
rv = None
last_exc = None
until = is_true or until_pred
start = self.clock.now
while not until(self.clock, self.end):
try:
@ -130,7 +130,8 @@ class Wait(object):
if last_exc is not None:
raise last_exc
raise errors.TimeoutException
raise errors.TimeoutException(
"Timed out after %s seconds" % (self.clock.now - start))
def until_pred(clock, end):
return clock.now >= end

View File

@ -187,6 +187,8 @@
"dom/tests/mochitest/geolocation/test_mozsettings.html": "mozSettings is undefined",
"dom/tests/mochitest/geolocation/test_mozsettingsWatch.html": "mozSettings is undefined",
"dom/tests/mochitest/geolocation/test_shutdown.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_timeoutWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_timerRestartWatch.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_windowClose.html": "TIMED_OUT",
"dom/tests/mochitest/geolocation/test_worseAccuracyDoesNotBlockCallback.html": "TIMED_OUT",
"dom/tests/mochitest/localstorage/test_bug624047.html": "TIMED_OUT",

View File

@ -1093,7 +1093,7 @@ nsDownloadManager::GetDownloadFromDB(const nsACString& aGUID, nsDownload **retVa
MOZ_ASSERT(!FindDownload(aGUID),
"If it is a current download, you should not call this method!");
nsDependentCString query = NS_LITERAL_CSTRING(
NS_NAMED_LITERAL_CSTRING(query,
"SELECT id, state, startTime, source, target, tempPath, name, referrer, "
"entityID, currBytes, maxBytes, mimeType, preferredAction, "
"preferredApplication, autoResume, guid "

View File

@ -408,7 +408,8 @@ INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is only enabled o
endif
ifdef MOZ_OMX_PLUGIN
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginfroyo.so
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so \
libomxpluginhc.so libomxpluginfroyo.so libomxpluginkk.so
endif
SO_LIBRARIES := $(filter %.so,$(DIST_FILES))

View File

@ -87,6 +87,7 @@ if CONFIG['MOZ_OMX_PLUGIN']:
'media/omx-plugin/froyo',
'media/omx-plugin/lib/hc/libstagefright',
'media/omx-plugin/hc',
'media/omx-plugin/kk',
])
if CONFIG['ENABLE_TESTS']:

View File

@ -109,7 +109,6 @@ protected:
// to 3%-4%). See bmo bug 395397.
static const uint32_t kHadMoreEventsCountMax = 3;
int32_t mRecursionDepth;
int32_t mNativeEventCallbackDepth;
// Can be set from different threads, so must be modified atomically
int32_t mNativeEventScheduledDepth;

View File

@ -210,7 +210,6 @@ nsAppShell::nsAppShell()
, mTerminated(false)
, mSkippedNativeCallback(false)
, mHadMoreEventsCount(0)
, mRecursionDepth(0)
, mNativeEventCallbackDepth(0)
, mNativeEventScheduledDepth(0)
{
@ -712,11 +711,14 @@ nsAppShell::ProcessNextNativeEvent(bool aMayWait)
bool
nsAppShell::InGeckoMainEventLoop()
{
if ((gXULModalLevel > 0) || (mRecursionDepth > 0))
if (gXULModalLevel > 0)
return false;
if (mNativeEventCallbackDepth <= 0)
return false;
return true;
bool isProcessingEvents = false;
NS_GetCurrentThread()->GetIsProcessingEvents(&isProcessingEvents);
return !isProcessingEvents;
}
// Run
@ -818,8 +820,6 @@ nsAppShell::OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait,
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
mRecursionDepth = aRecursionDepth;
NS_ASSERTION(mAutoreleasePools,
"No stack on which to store autorelease pool");
@ -845,8 +845,6 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
mRecursionDepth = aRecursionDepth;
CFIndex count = ::CFArrayGetCount(mAutoreleasePools);
NS_ASSERTION(mAutoreleasePools && count,

View File

@ -200,6 +200,11 @@ ModifierKeyState::InitMouseEvent(WidgetInputEvent& aMouseEvent) const
aMouseEvent.eventStructType == NS_SIMPLE_GESTURE_EVENT,
"called with non-mouse event");
if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
// Buttons for immersive mode are handled in MetroInput.
return;
}
WidgetMouseEventBase& mouseEvent = *aMouseEvent.AsMouseEventBase();
mouseEvent.buttons = 0;
if (::GetKeyState(VK_LBUTTON) < 0) {

View File

@ -160,6 +160,37 @@ namespace {
}
}
int16_t
ButtonsForPointerPoint(UI::Input::IPointerPoint* aPoint) {
WRL::ComPtr<UI::Input::IPointerPointProperties> props;
aPoint->get_Properties(props.GetAddressOf());
int16_t buttons = 0;
boolean buttonPressed;
props->get_IsLeftButtonPressed(&buttonPressed);
if (buttonPressed) {
buttons |= WidgetMouseEvent::eLeftButtonFlag;
}
props->get_IsMiddleButtonPressed(&buttonPressed);
if (buttonPressed) {
buttons |= WidgetMouseEvent::eMiddleButtonFlag;
}
props->get_IsRightButtonPressed(&buttonPressed);
if (buttonPressed) {
buttons |= WidgetMouseEvent::eRightButtonFlag;
}
props->get_IsXButton1Pressed(&buttonPressed);
if (buttonPressed) {
buttons |= WidgetMouseEvent::e4thButtonFlag;
}
props->get_IsXButton2Pressed(&buttonPressed);
if (buttonPressed) {
buttons |= WidgetMouseEvent::e5thButtonFlag;
}
return buttons;
}
/**
* This function is for use with mTouches.Enumerate. It will
* append each element it encounters to the {@link nsTArray}
@ -408,40 +439,43 @@ MetroInput::OnPointerNonTouch(UI::Input::IPointerPoint* aPoint) {
aPoint->get_Properties(props.GetAddressOf());
props->get_PointerUpdateKind(&pointerUpdateKind);
WidgetMouseEvent* event =
new WidgetMouseEvent(true, NS_MOUSE_MOVE, mWidget.Get(),
WidgetMouseEvent::eReal,
WidgetMouseEvent::eNormal);
uint32_t message = NS_MOUSE_MOVE;
int16_t button = 0;
switch (pointerUpdateKind) {
case UI::Input::PointerUpdateKind::PointerUpdateKind_LeftButtonPressed:
// We don't bother setting mouseEvent.button because it is already
// set to WidgetMouseEvent::buttonType::eLeftButton whose value is 0.
event->message = NS_MOUSE_BUTTON_DOWN;
button = WidgetMouseEvent::buttonType::eLeftButton;
message = NS_MOUSE_BUTTON_DOWN;
break;
case UI::Input::PointerUpdateKind::PointerUpdateKind_MiddleButtonPressed:
event->button = WidgetMouseEvent::buttonType::eMiddleButton;
event->message = NS_MOUSE_BUTTON_DOWN;
button = WidgetMouseEvent::buttonType::eMiddleButton;
message = NS_MOUSE_BUTTON_DOWN;
break;
case UI::Input::PointerUpdateKind::PointerUpdateKind_RightButtonPressed:
event->button = WidgetMouseEvent::buttonType::eRightButton;
event->message = NS_MOUSE_BUTTON_DOWN;
button = WidgetMouseEvent::buttonType::eRightButton;
message = NS_MOUSE_BUTTON_DOWN;
break;
case UI::Input::PointerUpdateKind::PointerUpdateKind_LeftButtonReleased:
// We don't bother setting mouseEvent.button because it is already
// set to WidgetMouseEvent::buttonType::eLeftButton whose value is 0.
event->message = NS_MOUSE_BUTTON_UP;
button = WidgetMouseEvent::buttonType::eLeftButton;
message = NS_MOUSE_BUTTON_UP;
break;
case UI::Input::PointerUpdateKind::PointerUpdateKind_MiddleButtonReleased:
event->button = WidgetMouseEvent::buttonType::eMiddleButton;
event->message = NS_MOUSE_BUTTON_UP;
button = WidgetMouseEvent::buttonType::eMiddleButton;
message = NS_MOUSE_BUTTON_UP;
break;
case UI::Input::PointerUpdateKind::PointerUpdateKind_RightButtonReleased:
event->button = WidgetMouseEvent::buttonType::eRightButton;
event->message = NS_MOUSE_BUTTON_UP;
button = WidgetMouseEvent::buttonType::eRightButton;
message = NS_MOUSE_BUTTON_UP;
break;
}
UpdateInputLevel(LEVEL_PRECISE);
WidgetMouseEvent* event =
new WidgetMouseEvent(true, message, mWidget.Get(),
WidgetMouseEvent::eReal,
WidgetMouseEvent::eNormal);
event->button = button;
InitGeckoMouseEventFromPointerPoint(event, aPoint);
DispatchAsyncEventIgnoreStatus(event);
}
@ -746,6 +780,7 @@ MetroInput::InitGeckoMouseEventFromPointerPoint(
aEvent->clickCount = 2;
}
aEvent->pressure = pressure;
aEvent->buttons = ButtonsForPointerPoint(aPointerPoint);
MozInputSourceFromDeviceType(deviceType, aEvent->inputSource);
}

View File

@ -66,11 +66,21 @@ stack_callback(void *pc, void *sp, void *closure)
}
#ifdef DEBUG
#include "nsCocoaFeatures.h"
#define MAC_OS_X_VERSION_10_7_HEX 0x00001070
static int32_t OSXVersion()
{
static int32_t gOSXVersion = 0x0;
if (gOSXVersion == 0x0) {
OSErr err = ::Gestalt(gestaltSystemVersion, (SInt32*)&gOSXVersion);
MOZ_ASSERT(err == noErr);
}
return gOSXVersion;
}
static bool OnLionOrLater()
{
return nsCocoaFeatures::OnLionOrLater();
return (OSXVersion() >= MAC_OS_X_VERSION_10_7_HEX);
}
#endif

View File

@ -1892,8 +1892,7 @@ nsLocalFile::Launch()
if (NS_SUCCEEDED(rv))
rv = mimeService->GetTypeFromFile(this, type);
nsDependentCString fileUri = NS_LITERAL_CSTRING("file://");
fileUri.Append(mPath);
nsAutoCString fileUri = NS_LITERAL_CSTRING("file://") + mPath;
return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
#elif defined(MOZ_WIDGET_COCOA)
CFURLRef url;

View File

@ -23,6 +23,7 @@ EXPORTS += [
'nsSubstringTuple.h',
'nsTDependentString.h',
'nsTDependentSubstring.h',
'nsTLiteralString.h',
'nsTPromiseFlatString.h',
'nsTString.h',
'nsTSubstring.h',

View File

@ -16,14 +16,6 @@
#include "nsStringIterator.h"
#endif
// If some platform(s) can't handle our template that matches literal strings,
// then we'll disable it on those platforms.
#ifndef NS_DISABLE_LITERAL_TEMPLATE
# if (defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x560)) || (defined(__HP_aCC) && (__HP_aCC <= 012100))
# define NS_DISABLE_LITERAL_TEMPLATE
# endif
#endif /* !NS_DISABLE_LITERAL_TEMPLATE */
#include <string.h>
#include <stdarg.h>

View File

@ -10,46 +10,32 @@
#include "nscore.h"
#endif
#ifndef nsDependentString_h___
#include "nsDependentString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
// declare nsLiteralString
#include "string-template-def-unichar.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
// declare nsLiteralCString
#include "string-template-def-char.h"
#include "nsTLiteralString.h"
#include "string-template-undef.h"
#include "mozilla/Char16.h"
namespace mozilla {
namespace internal {
#define NS_MULTILINE_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(s))
#define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(s)
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsLiteralString n(s)
// This is the same as sizeof(c) - 1, except it won't compile if c isn't a
// string literal. This ensures that NS_LITERAL_CSTRING doesn't compile if you
// pass it a char* (or something else for that matter).
template<int n>
inline uint32_t LiteralStringLength(const char (&c)[n])
{
return n - 1;
}
#define NS_LITERAL_STRING(s) static_cast<const nsLiteralString&>(nsLiteralString(MOZ_UTF16(s)))
#define NS_LITERAL_STRING_INIT(n,s) n(MOZ_UTF16(s))
#define NS_NAMED_LITERAL_STRING(n,s) const nsLiteralString n(MOZ_UTF16(s))
template<int n>
inline uint32_t LiteralWStringLength(const char16_t (&c)[n])
{
return n - 1;
}
} // namespace internal
} // namespace mozilla
#define NS_MULTILINE_LITERAL_STRING(s) nsDependentString(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
#define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
#define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsDependentString n(reinterpret_cast<const nsAString::char_type*>(s), mozilla::internal::LiteralWStringLength(s))
typedef nsDependentString nsLiteralString;
#define NS_LITERAL_STRING(s) static_cast<const nsAFlatString&>(NS_MULTILINE_LITERAL_STRING(MOZ_UTF16(s)))
#define NS_LITERAL_STRING_INIT(n,s) NS_MULTILINE_LITERAL_STRING_INIT(n, MOZ_UTF16(s))
#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n, MOZ_UTF16(s))
#define NS_LITERAL_CSTRING(s) static_cast<const nsDependentCString&>(nsDependentCString(s, mozilla::internal::LiteralStringLength(s)))
#define NS_LITERAL_CSTRING_INIT(n,s) n(s, mozilla::internal::LiteralStringLength(s))
#define NS_NAMED_LITERAL_CSTRING(n,s) const nsDependentCString n(s, mozilla::internal::LiteralStringLength(s))
typedef nsDependentCString nsLiteralCString;
#define NS_LITERAL_CSTRING(s) static_cast<const nsLiteralCString&>(nsLiteralCString(s))
#define NS_LITERAL_CSTRING_INIT(n,s) n(s)
#define NS_NAMED_LITERAL_CSTRING(n,s) const nsLiteralCString n(s)
#endif /* !defined(nsLiteralString_h___) */

View File

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* nsTLiteralString_CharT
*
* Stores a null-terminated, immutable sequence of characters.
*
* Subclass of nsTString that restricts string value to a literal
* character sequence. This class does not own its data. The data is
* assumed to be permanent. In practice this is true because this code
* is only usable by and for libxul.
*/
class nsTLiteralString_CharT : public nsTString_CharT
{
public:
typedef nsTLiteralString_CharT self_type;
public:
/**
* constructor
*/
template<size_type N>
nsTLiteralString_CharT( const char_type (&str)[N] )
: string_type(const_cast<char_type*>(str), N - 1, F_TERMINATED | F_LITERAL)
{
}
private:
// NOT TO BE IMPLEMENTED
template<size_type N>
nsTLiteralString_CharT( char_type (&str)[N] ) MOZ_DELETE;
};

View File

@ -214,11 +214,21 @@ class nsTSubstring_CharT
return mLength;
}
uint32_t Flags() const
{
return mFlags;
}
bool IsEmpty() const
{
return mLength == 0;
}
bool IsLiteral() const
{
return (mFlags & F_LITERAL) != 0;
}
bool IsVoid() const
{
return (mFlags & F_VOIDED) != 0;
@ -297,24 +307,11 @@ class nsTSubstring_CharT
// non-constant char array variable. Use EqualsASCII for them.
// The template trick to acquire the array length at compile time without
// using a macro is due to Corey Kosak, with much thanks.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline bool EqualsLiteral( const char* str ) const
{
return EqualsASCII(str);
}
#else
template<int N>
inline bool EqualsLiteral( const char (&str)[N] ) const
{
return EqualsASCII(str, N-1);
}
template<int N>
inline bool EqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return EqualsASCII(s, N-1);
}
#endif
// The LowerCaseEquals methods compare the ASCII-lowercase version of
// this string (lowercasing only ASCII uppercase characters) to some
@ -330,24 +327,11 @@ class nsTSubstring_CharT
// explicit size. Do not attempt to use it with a regular char*
// pointer, or with a non-constant char array variable. Use
// LowerCaseEqualsASCII for them.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
inline bool LowerCaseEqualsLiteral( const char* str ) const
{
return LowerCaseEqualsASCII(str);
}
#else
template<int N>
inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const
{
return LowerCaseEqualsASCII(str, N-1);
}
template<int N>
inline bool LowerCaseEqualsLiteral( char (&str)[N] ) const
{
const char* s = str;
return LowerCaseEqualsASCII(s, N-1);
}
#endif
/**
* assignment
@ -406,16 +390,13 @@ class nsTSubstring_CharT
// non-constant char array variable. Use AssignASCII for those.
// There are not fallible version of these methods because they only really
// apply to small allocations that we wouldn't want to check anyway.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AssignLiteral( const char* str )
{ AssignASCII(str); }
#else
template<int N>
void AssignLiteral( const char_type (&str)[N] )
{ AssignLiteral(str, N - 1); }
#ifdef CharT_is_PRUnichar
template<int N>
void AssignLiteral( const char (&str)[N] )
{ AssignASCII(str, N-1); }
template<int N>
void AssignLiteral( char (&str)[N] )
{ AssignASCII(str, N-1); }
#endif
self_type& operator=( char_type c ) { Assign(c); return *this; }
@ -440,6 +421,12 @@ class nsTSubstring_CharT
void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
// ReplaceLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use Replace or ReplaceASCII for those.
template<int N>
void ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type (&str)[N] ) { ReplaceLiteral(cutStart, cutLength, str, N - 1); }
void Append( char_type c ) { Replace(mLength, 0, c); }
void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
@ -496,17 +483,13 @@ class nsTSubstring_CharT
// AppendLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use AppendASCII for those.
#ifdef NS_DISABLE_LITERAL_TEMPLATE
void AppendLiteral( const char* str )
{ AppendASCII(str); }
#else
// array variable. Use Append or AppendASCII for those.
template<int N>
void AppendLiteral( const char_type (&str)[N] ) { ReplaceLiteral(mLength, 0, str, N - 1); }
#ifdef CharT_is_PRUnichar
template<int N>
void AppendLiteral( const char (&str)[N] )
{ AppendASCII(str, N-1); }
template<int N>
void AppendLiteral( char (&str)[N] )
{ AppendASCII(str, N-1); }
#endif
self_type& operator+=( char_type c ) { Append(c); return *this; }
@ -526,6 +509,12 @@ class nsTSubstring_CharT
void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
// InsertLiteral must ONLY be applied to an actual literal string.
// Do not attempt to use it with a regular char* pointer, or with a char
// array variable. Use Insert for those.
template<int N>
void InsertLiteral( const char_type (&str)[N], index_type pos ) { ReplaceLiteral(pos, 0, str, N - 1); }
void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
@ -845,6 +834,9 @@ class nsTSubstring_CharT
mFlags = dataFlags | (mFlags & 0xFFFF0000);
}
void NS_FASTCALL AssignLiteral( const char_type* data, size_type length );
void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
static int AppendFunc( void* arg, const char* s, uint32_t len);
public:
@ -865,6 +857,7 @@ class nsTSubstring_CharT
F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
F_LITERAL = 1 << 5, // mData points to a string literal; F_TERMINATED will also be set
// class flags are in the upper 16-bits
F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString

View File

@ -17,6 +17,7 @@
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
#define nsTDependentString_CharT nsDependentCString
#define nsTDependentSubstring_CharT nsDependentCSubstring
#define nsTLiteralString_CharT nsLiteralCString
#define nsTXPIDLString_CharT nsXPIDLCString
#define nsTGetterCopies_CharT nsCGetterCopies
#define nsTAdoptingString_CharT nsAdoptingCString

View File

@ -17,6 +17,7 @@
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
#define nsTDependentString_CharT nsDependentString
#define nsTDependentSubstring_CharT nsDependentSubstring
#define nsTLiteralString_CharT nsLiteralString
#define nsTXPIDLString_CharT nsXPIDLString
#define nsTGetterCopies_CharT nsGetterCopies
#define nsTAdoptingString_CharT nsAdoptingString

View File

@ -18,6 +18,7 @@
#undef nsTDefaultStringComparator_CharT
#undef nsTDependentString_CharT
#undef nsTDependentSubstring_CharT
#undef nsTLiteralString_CharT
#undef nsTXPIDLString_CharT
#undef nsTGetterCopies_CharT
#undef nsTAdoptingString_CharT

View File

@ -7,6 +7,8 @@
void
nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
{
NS_ABORT_IF_FALSE(str.Flags() & F_TERMINATED, "Unterminated flat string");
// If we currently own a buffer, release it.
Finalize();
@ -18,5 +20,5 @@ nsTDependentString_CharT::Rebind( const string_type& str, uint32_t startPos )
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
mLength = strLength - startPos;
SetDataFlags(F_TERMINATED);
SetDataFlags(str.Flags() & (F_TERMINATED | F_LITERAL));
}

View File

@ -11,7 +11,8 @@ nsTPromiseFlatString_CharT::Init(const substring_type& str)
{
mData = const_cast<char_type*>(static_cast<const char_type*>(str.Data()));
mLength = str.Length();
mFlags = F_TERMINATED; // does not promote F_VOIDED
mFlags = str.mFlags & (F_TERMINATED | F_LITERAL);
// does not promote F_VOIDED
}
else
{

View File

@ -351,6 +351,15 @@ nsTSubstring_CharT::AssignASCII( const char* data, size_type length, const falli
return true;
}
void
nsTSubstring_CharT::AssignLiteral( const char_type* data, size_type length )
{
::ReleaseData(mData, mFlags);
mData = const_cast<char_type*>(data);
mLength = length;
SetDataFlags(F_TERMINATED | F_LITERAL);
}
void
nsTSubstring_CharT::Assign( const self_type& str )
{
@ -391,6 +400,13 @@ nsTSubstring_CharT::Assign( const self_type& str, const fallible_t& )
nsStringBuffer::FromData(mData)->AddRef();
return true;
}
else if (str.mFlags & F_LITERAL)
{
NS_ABORT_IF_FALSE(str.mFlags & F_TERMINATED, "Unterminated literal");
AssignLiteral(str.mData, str.mLength);
return true;
}
// else, treat this like an ordinary assignment.
return Assign(str.Data(), str.Length(), fallible_t());
@ -536,6 +552,17 @@ nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const sub
tuple.WriteTo(mData + cutStart, length);
}
void
nsTSubstring_CharT::ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
{
cutStart = XPCOM_MIN(cutStart, Length());
if (!cutStart && cutLength == Length())
AssignLiteral(data, length);
else if (ReplacePrep(cutStart, cutLength, length) && length > 0)
char_traits::copy(mData + cutStart, data, length);
}
void
nsTSubstring_CharT::SetCapacity( size_type capacity )
{

View File

@ -17,7 +17,7 @@ interface nsIGeolocationPrompt;
* Interface provides a way for a geolocation provider to
* notify the system that a new location is available.
*/
[scriptable, uuid(f00ff730-acff-4e8c-9991-0d4c84ba0e10)]
[scriptable, uuid(643dc5e9-b911-4b2c-8d44-603162696baf)]
interface nsIGeolocationUpdate : nsISupports {
/**
@ -27,6 +27,13 @@ interface nsIGeolocationUpdate : nsISupports {
*/
void update(in nsIDOMGeoPosition position);
/**
* Notify the geolocation service that the location has
* potentially changed, and thus a new position is in the
* process of being acquired.
*/
void locationUpdatePending();
/**
* Notify the geolocation service of an error.
* This must be called on the main thread.

View File

@ -462,6 +462,17 @@ LazyIdleThread::ProcessNextEvent(bool aMayWait,
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LazyIdleThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (mThread) {
return mThread->GetIsProcessingEvents(aIsProcessing);
}
*aIsProcessing = false;
return NS_OK;
}
NS_IMETHODIMP
LazyIdleThread::Notify(nsITimer* aTimer)
{

View File

@ -17,7 +17,7 @@
*
* See nsIThreadManager for the API used to create and locate threads.
*/
[scriptable, uuid(9c889946-a73a-4af3-ae9a-ea64f7d4e3ca)]
[scriptable, uuid(4df07d3a-e759-4256-ba4e-7e2265354ec3)]
interface nsIThread : nsIEventTarget
{
/**
@ -82,4 +82,10 @@ interface nsIThread : nsIEventTarget
* not the current thread.
*/
boolean processNextEvent(in boolean mayWait);
/**
* true if we're processing runnables or thread observers and if this is the
* current thread.
*/
readonly attribute boolean isProcessingEvents;
};

View File

@ -304,6 +304,7 @@ nsThread::nsThread(MainThreadFlag aMainThread, uint32_t aStackSize)
, mThread(nullptr)
, mRunningEvent(0)
, mStackSize(aStackSize)
, mProcessingEvent(0)
, mShutdownContext(nullptr)
, mShutdownRequired(false)
, mEventsAreDoomed(false)
@ -596,6 +597,8 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
}
}
++mProcessingEvent;
bool notifyMainThreadObserver =
(MAIN_THREAD == mIsMainThread) && sMainThreadObserver;
if (notifyMainThreadObserver)
@ -650,9 +653,22 @@ nsThread::ProcessNextEvent(bool mayWait, bool *result)
if (notifyMainThreadObserver && sMainThreadObserver)
sMainThreadObserver->AfterProcessNextEvent(this, mRunningEvent, *result);
--mProcessingEvent;
return rv;
}
NS_IMETHODIMP
nsThread::GetIsProcessingEvents(bool* aIsProcessing)
{
if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
return NS_ERROR_NOT_SAME_THREAD;
}
*aIsProcessing = mProcessingEvent != 0;
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsISupportsPriority

View File

@ -150,6 +150,8 @@ protected:
uint32_t mRunningEvent; // counter
uint32_t mStackSize;
uint32_t mProcessingEvent;
struct nsThreadShutdownContext *mShutdownContext;
bool mShutdownRequired;