Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-11-09 12:27:27 +01:00
Родитель 4a68937a49 f8d51d3d31
Коммит f867f4c5e7
68 изменённых файлов: 1609 добавлений и 728 удалений

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

@ -983,9 +983,8 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible();
if (rootAccWrap && rootAccWrap->mActivated) {
// Fire state change event for focus
nsRefPtr<AccEvent> stateChangeEvent =
new AccStateChangeEvent(accessible, states::FOCUSED, true);
return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
atk_object_notify_state_change(atkObj, ATK_STATE_FOCUSED, true);
return NS_OK;
}
} break;

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

@ -750,7 +750,6 @@ pref("webgl.can-lose-context-in-foreground", false);
pref("memory_info_dumper.watch_fifo.enabled", true);
pref("memory_info_dumper.watch_fifo.directory", "/data/local");
pref("general.useragent.enable_overrides", true);
// See ua-update.json.in for the packaged UA override list
pref("general.useragent.updates.enabled", true);
pref("general.useragent.updates.url", "https://dynamicua.cdn.mozilla.net/0/%APP_ID%");

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

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1383344509000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1383954148000">
<emItems>
<emItem blockID="i454" id="sqlmoz@facebook.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
@ -37,6 +37,10 @@
<versionRange minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1">
</versionRange>
</emItem>
<emItem blockID="i433" id="{c95a4e8e-816d-4655-8c79-d736da1adb6d}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i65" id="activity@facebook.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -45,6 +49,10 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -90,8 +98,8 @@
<versionRange minVersion="3.4.1" maxVersion="3.4.1.194" severity="1">
</versionRange>
</emItem>
<emItem blockID="i433" id="{c95a4e8e-816d-4655-8c79-d736da1adb6d}">
<versionRange minVersion="0" maxVersion="*" severity="1">
<emItem blockID="i474" id="{906000a4-88d9-4d52-b209-7a772970d91f}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
@ -121,6 +129,10 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i478" id="{7e8a1050-cf67-4575-92df-dcc60e7d952d}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i84" id="pink@rosaplugin.info">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -133,6 +145,10 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i467" id="plugin@analytic-s.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i360" id="ytd@mybrowserbar.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
@ -159,6 +175,10 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i475" id="{B21F5E31-B8E8-41CD-B74C-168A71A10E49}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i11" id="yslow@yahoo-inc.com">
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@ -170,6 +190,10 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i472" id="linksicle@linksicle.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -194,16 +218,8 @@
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion="3.3.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="5.0a1" maxVersion="*" />
</targetApplication>
<emItem blockID="i466" id="afext@anchorfree.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i98" id="youtubeeing@youtuberie.com">
@ -255,6 +271,10 @@
<versionRange minVersion=" " maxVersion="6.*">
</versionRange>
</emItem>
<emItem blockID="i358" id="lfind@nijadsoft.net">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i228" id="crossriderapp5060@crossrider.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
@ -313,6 +333,10 @@
<versionRange minVersion="0" maxVersion="1.0" severity="1">
</versionRange>
</emItem>
<emItem blockID="i468" id="05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
@ -369,6 +393,10 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i477" id="mbrnovone@facebook.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
@ -379,7 +407,11 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
<emItem blockID="i471" id="firefox@luckyleap.net">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i320" id="torntv@torntv.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
@ -469,8 +501,8 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i196" id="info@wxdownloadmanager.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
<emItem blockID="i91" id="crossriderapp4926@crossrider.com">
<versionRange minVersion="0" maxVersion="0.81.43" severity="1">
</versionRange>
</emItem>
<emItem blockID="i435" id="pluggets@gmail.com">
@ -485,6 +517,18 @@
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion="3.3.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="5.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
<versionRange minVersion=" " maxVersion="8.5">
</versionRange>
@ -547,8 +591,8 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i320" id="torntv@torntv.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
<emItem blockID="i476" id="mbroctone@facebook.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
@ -559,8 +603,8 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i358" id="lfind@nijadsoft.net">
<versionRange minVersion="0" maxVersion="*" severity="1">
<emItem blockID="i470" id="extension@FastFreeConverter.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
@ -620,8 +664,12 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i91" id="crossriderapp4926@crossrider.com">
<versionRange minVersion="0" maxVersion="0.81.43" severity="1">
<emItem blockID="i196" id="info@wxdownloadmanager.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i469" id="OKitSpace@OKitSpace.es">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i167" id="{b64982b1-d112-42b5-b1e4-d3867c4533f8}">
@ -664,6 +712,10 @@
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
</emItem>
<emItem blockID="i473" id="{81b13b5d-fba1-49fd-9a6b-189483ac548a}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i437" id="{4933189D-C7F7-4C6E-834B-A29F087BFD23}">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
@ -754,15 +806,15 @@
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i21" id="support@update-firefox.com">
<emItem blockID="i374" id="update@firefox.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i322" id="jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
</emItem>
<emItem blockID="i374" id="update@firefox.com">
<versionRange minVersion="0" maxVersion="*" severity="3">
</versionRange>
<emItem blockID="i21" id="support@update-firefox.com">
</emItem>
</emItems>

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

@ -373,16 +373,6 @@ HTMLBreadcrumbs.prototype = {
}
},
/**
* Re-init the cache and remove all the buttons.
*/
invalidateHierarchy: function BC_invalidateHierarchy()
{
this.inspector.hideNodeMenu();
this.nodeHierarchy = [];
this.empty();
},
/**
* Set which button represent the selected node.
*
@ -615,7 +605,9 @@ HTMLBreadcrumbs.prototype = {
*/
update: function BC_update(reason)
{
if (reason !== "markupmutation") {
this.inspector.hideNodeMenu();
}
let cmdDispatcher = this.chromeDoc.commandDispatcher;
this.hadFocus = (cmdDispatcher.focusedElement &&

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

@ -987,7 +987,8 @@ MarkupView.prototype = {
* Initialize the preview panel.
*/
_initPreview: function() {
if (!Services.prefs.getBoolPref("devtools.inspector.markupPreview")) {
this._previewEnabled = Services.prefs.getBoolPref("devtools.inspector.markupPreview");
if (!this._previewEnabled) {
return;
}
@ -1017,6 +1018,9 @@ MarkupView.prototype = {
* Move the preview viewbox.
*/
_updatePreview: function() {
if (!this._previewEnabled) {
return;
}
let win = this._frame.contentWindow;
if (win.scrollMaxY == 0) {
@ -1052,6 +1056,9 @@ MarkupView.prototype = {
* Hide the preview while resizing, to avoid slowness.
*/
_resizePreview: function() {
if (!this._previewEnabled) {
return;
}
let win = this._frame.contentWindow;
this._previewBar.classList.add("hide");
win.clearTimeout(this._resizePreviewTimeout);

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

@ -590,13 +590,13 @@ var Browser = {
if (tab)
tab.active = true;
BrowserUI.update();
if (isFirstTab) {
// Don't waste time at startup updating the whole UI; just display the URL.
BrowserUI._titleChanged(browser);
} else {
// Update all of our UI to reflect the new tab's location
BrowserUI.updateURI();
BrowserUI.update();
let event = document.createEvent("Events");
event.initEvent("TabSelect", true, false);

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

@ -210,7 +210,7 @@
<!-- Navigation bar -->
<appbar id="navbar" mousethrough="never" visible="true">
<hbox id="progress-container" layer="true">
<hbox id="progress-container" layer="true" observes="bcast_windowState">
<hbox id="progress-control" />
</hbox>

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

@ -460,6 +460,9 @@ documenttab[selected] .documenttab-selection {
box-shadow: 0 1px 0 hsla(210,5%,50%,.1) inset;
-moz-user-focus: ignore;
}
#progress-container[startpage] {
visibility: collapse;
}
#progress-control {
display: block;

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

@ -25,7 +25,7 @@ class nsNPAPIPluginInstance;
* interface to mirror this interface when changing it.
*/
[scriptable, uuid(070bfc7f-f8b8-4e84-aa31-a0bfaffa8e8e)]
[scriptable, uuid(16c14177-52eb-49d3-9842-a1a0b92be11a)]
interface nsIObjectLoadingContent : nsISupports
{
/**
@ -133,6 +133,14 @@ interface nsIObjectLoadingContent : nsISupports
*/
void playPlugin();
/**
* Forces a re-evaluation and reload of the tag, optionally invalidating its
* click-to-play state. This can be used when the MIME type that provides a
* type has changed, for instance, to force the tag to re-evalulate the
* handler to use.
*/
void reload(in boolean aClearActivation);
/**
* This attribute will return true if the current content type has been
* activated, either explicitly or by passing checks that would have it be

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

@ -2399,6 +2399,14 @@ nsObjectLoadingContent::UnloadObject(bool aResetState)
mScriptRequested = false;
if (!mInstanceOwner) {
// The protochain is normally thrown out after a plugin stops, but if we
// re-enter while stopping a plugin and try to load something new, we need
// to throw away the old protochain in the nested unload.
TeardownProtoChain();
mIsStopping = false;
}
// This call should be last as it may re-enter
StopPluginInstance();
}
@ -2786,9 +2794,17 @@ nsObjectLoadingContent::DoStopPlugin(nsPluginInstanceOwner* aInstanceOwner,
NS_ASSERTION(pluginHost, "No plugin host?");
pluginHost->StopPluginInstance(inst);
}
TeardownProtoChain();
aInstanceOwner->Destroy();
// If we re-enter in plugin teardown UnloadObject will tear down the
// protochain -- the current protochain could be from a new, unrelated, load.
if (!mIsStopping) {
LOG(("OBJLC [%p]: Re-entered in plugin teardown", this));
return;
}
TeardownProtoChain();
mIsStopping = false;
}
@ -2894,6 +2910,17 @@ nsObjectLoadingContent::PlayPlugin()
return NS_OK;
}
NS_IMETHODIMP
nsObjectLoadingContent::Reload(bool aClearActivation)
{
if (aClearActivation) {
mActivated = false;
mPlayPreviewCanceled = false;
}
return LoadObject(true, true);
}
NS_IMETHODIMP
nsObjectLoadingContent::GetActivated(bool *aActivated)
{

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

@ -179,6 +179,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
{
aRv = PlayPlugin();
}
void Reload(bool aClearActivation, mozilla::ErrorResult& aRv)
{
aRv = Reload(aClearActivation);
}
bool Activated() const
{
return mActivated;

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

@ -1,401 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Media tests should be backend independent, i.e., not conditioned on
# MOZ_OGG, MOZ_WAVE etc. (The only exception is the can_play_type tests,
# which necessarily depend on the backend(s) configured.) As far as possible,
# each test should work with any resource type. This makes it
# easy to add new backends and reduces the amount of test duplication.
# For each supported backend, resources that can be played by that backend
# should be added to the lists in manifest.js. Media tests that aren't
# testing for a bug in handling a specific resource type should pick one of
# the lists in manifest.js and run the test for each resource in the list
# that is supported in the current build (the canPlayType API is useful
# for this).
# To test whether a valid resource can simply be played through correctly,
# and optionally that its metadata is read correctly, just
# add it to gPlayTests in manifest.js. To test whether an invalid
# resource correctly throws an error (and does not cause a crash or hang),
# just add it to gErrorTests in manifest.js.
# To test for a specific bug in handling a specific resource type,
# make the test first check canPlayType for the type, and if it's not
# supported, just do ok(true, "Type not supported") and stop the test.
# Disabled for too many intermittent failures (bug 897108)
# test_playback_rate_playpause.html \
MOCHITEST_FILES = \
allowed.sjs \
can_play_type_ogg.js \
can_play_type_wave.js \
can_play_type_webm.js \
can_play_type_dash.js \
can_play_type_mpeg.js \
cancellable_request.sjs \
dynamic_redirect.sjs \
dynamic_resource.sjs \
file_access_controls.html \
fragment_play.js \
fragment_noplay.js \
manifest.js \
reactivate_helper.html \
redirect.sjs \
referer.sjs \
seek1.js \
seek2.js \
seek3.js \
seek4.js \
seek5.js \
seek6.js \
seek7.js \
seek8.js \
seek9.js \
seek10.js \
seek11.js \
seek12.js \
seek13.js \
seekLies.sjs \
test_access_control.html \
test_audio1.html \
test_audio2.html \
test_autoplay.html \
test_bug448534.html \
test_bug463162.xhtml \
test_bug495145.html \
test_bug495300.html \
test_bug654550.html \
test_bug686942.html \
test_bug883173.html \
test_bug895305.html \
test_bug895091.html \
test_bug919265.html \
test_can_play_type.html \
test_can_play_type_mpeg.html \
test_closing_connections.html \
test_constants.html \
test_controls.html \
test_currentTime.html \
test_decode_error.html \
test_defaultMuted.html \
test_delay_load.html \
test_error_on_404.html \
test_info_leak.html \
test_invalid_reject.html \
test_load.html \
test_load_candidates.html \
test_load_same_resource.html \
test_load_source.html \
test_loop.html \
test_metadata.html \
test_no_load_event.html \
test_networkState.html \
test_new_audio.html \
test_paused.html \
test_paused_after_ended.html \
test_play_events.html \
test_play_events_2.html \
test_playback_errors.html \
test_seekable1.html \
test_preload_actions.html \
test_preload_attribute.html \
test_progress.html \
test_reactivate.html \
test_readyState.html \
test_replay_metadata.html \
test_seek2.html \
test_seek_out_of_range.html \
test_source.html \
test_source_write.html \
test_source_null.html \
test_standalone.html \
test_volume.html \
test_video_to_canvas.html \
test_audiowrite.html \
test_mediarecorder_avoid_recursion.html \
test_mediarecorder_creation.html \
test_mediarecorder_record_audiocontext.html \
test_mediarecorder_record_immediate_stop.html \
test_mediarecorder_record_no_timeslice.html \
test_mediarecorder_record_nosrc.html \
test_mediarecorder_record_session.html \
test_mediarecorder_record_stopms.html \
test_mediarecorder_record_timeslice.html \
test_mediarecorder_reload_crash.html \
test_mediarecorder_state_transition.html \
test_mozHasAudio.html \
test_source_media.html \
test_autoplay_contentEditable.html \
test_decoder_disable.html \
test_playback.html \
test_seekLies.html \
test_media_sniffer.html \
contentType.sjs \
test_streams_srcObject.html \
test_reset_src.html \
test_streams_autoplay.html \
test_streams_element_capture.html \
test_streams_element_capture_reset.html \
test_streams_element_capture_createObjectURL.html \
test_streams_gc.html \
test_streams_tracks.html \
$(filter disabled-for-intermittent-failures--bug-608634, test_error_in_video_document.html) \
test_texttrack.html \
test_texttrackcue.html \
test_trackevent.html \
test_texttrackregion.html \
test_timeupdate_small_files.html \
test_unseekable.html \
test_VideoPlaybackQuality.html \
test_VideoPlaybackQuality_disabled.html \
test_webvtt_disabled.html \
$(NULL)
# Don't run in suite
ifndef MOZ_SUITE
MOCHITEST_FILES += test_play_twice.html
else
$(filter disabled-pending-investigation--bug-598252, test_play_twice.html)
endif
# These tests are disabled until we figure out random failures.
# When these tests are fixed, we should also make them backend-independent.
# test_resume.html \
# Bug 492821:
# test_videoDocumentTitle.html
# Bug 493692:
# test_preload_suspend.html
# Bug 567954 and Bug 574586:
# test_mixed_principals.html
# Disabled since we don't play Wave files standalone, for now
# test_audioDocumentTitle.html
# Bug 751539:
# test_played.html
# Disabled since it causes random memory corruption, bug 921622, so
# the best-case scenario is that it results in random crashes while it
# runs, like bug 918417, bug 920827, bug 923996, bug 928225, bug 929521
# bug 930982, bug 932193. Worst-case but quite likely, it causes random
# crashes and failures in other tests which run after it. Don't even think
# about reenabling it on any platform unless you *know* that you have fixed
# that. Then don't think about reenabling it on Windows until you know that
# you have fixed the timeouts of bug 832768, bug 814533, bug 840742
# test_playback_rate.html \
# The below tests are disabled on Windows due to frequent timeouts.
# Bug 832768 and Bug 864682:
# test_buffered.html
# test_bug465498.html
# Bug 707777:
# test_bug493187.html
# Bug 897843:
# test_media_selection.html
# Bug 832678, bug 795271, and bug 857424
# test_seek.html
ifneq ($(OS_ARCH), WINNT)
MOCHITEST_FILES += \
test_buffered.html \
test_bug465498.html \
test_bug493187.html \
test_media_selection.html \
test_seek.html \
$(NULL)
endif
# sample files
MOCHITEST_FILES += \
320x240.ogv \
448636.ogv \
audio-overhang.ogg \
audio-gaps.ogg \
badtags.ogg \
beta-phrasebook.ogg \
big-buck-bunny-unseekable.mp4 \
bogus.ogv \
bug495129.ogv \
bug495794.ogg \
bug461281.ogg \
bug482461.ogv \
bug482461-theora.ogv \
bug498380.ogv \
bug498855-1.ogv \
bug498855-2.ogv \
bug498855-3.ogv \
bug499519.ogv \
bug500311.ogv \
bug500311.ogv^headers^ \
bug501279.ogg \
bug504613.ogv \
bug504644.ogv \
bug504843.ogv \
bug506094.ogv \
bug516323.ogv \
bug516323.indexed.ogv \
bug520493.ogg \
bug520500.ogg \
bug520908.ogv \
bug520908.ogv^headers^ \
bug523816.ogv \
bug533822.ogg \
bug557094.ogv \
bug556821.ogv \
bug580982.webm \
bug603918.webm \
bug604067.webm \
chain.ogv \
chain.ogg \
chain.opus \
variable-samplerate.ogg \
variable-samplerate.opus \
variable-channel.ogg \
variable-channel.opus \
chained-video.ogv \
chained-audio-video.ogg \
variable-preskip.opus \
dirac.ogg \
multiple-bos.ogg \
no-cues.webm \
owl.mp3 \
owl-funnier-id3.mp3 \
owl-funny-id3.mp3 \
split.webm \
seek.ogv \
seek.webm \
seek.yuv \
short-video.ogv \
small-shot.ogg \
small-shot.m4a \
small-shot.mp3 \
sound.ogg \
spacestorm-1000Hz-100ms.ogg \
test-1-mono.opus \
test-2-stereo.opus \
test-3-LCR.opus \
test-4-quad.opus \
test-5-5.0.opus \
test-6-5.1.opus \
test-7-6.1.opus \
test-8-7.1.opus \
vbr.mp3 \
video-overhang.ogg \
file_a4_tone.ogg \
detodos.opus \
notags.mp3 \
id3tags.mp3 \
basic.vtt \
region.vtt \
long.vtt \
bug883173.vtt \
$(NULL)
# Wave sample files
MOCHITEST_FILES += \
big.wav \
bogus.wav \
r11025_msadpcm_c1.wav \
r11025_s16_c1.wav \
r11025_s16_c1_trailing.wav \
r11025_u8_c1.wav \
r11025_u8_c1_trunc.wav \
r16000_u8_c1_list.wav \
wavedata_u8.wav \
wavedata_s16.wav \
wave_metadata_bad_len.wav \
wave_metadata_bad_no_null.wav \
wave_metadata_bad_utf8.wav \
wave_metadata_unknown_tag.wav \
wave_metadata_utf8.wav \
wave_metadata.wav \
audio.wav \
$(NULL)
# Media plugin sample files
MOCHITEST_FILES += \
gizmo.mp4 \
$(NULL)
# Other files
MOCHITEST_FILES += \
bogus.duh \
invalid-m0c0.opus \
invalid-m0c3.opus \
invalid-m1c0.opus \
invalid-m1c9.opus \
invalid-m2c0.opus \
invalid-m2c1.opus \
invalid-cmap-short.opus \
invalid-cmap-s0c0.opus \
invalid-cmap-s0c2.opus \
invalid-cmap-s1c2.opus \
$(NULL)
# These tests contain backend-specific tests. Try to write backend
# independent tests rather than adding to this list.
ifdef MOZ_OGG
MOCHITEST_FILES += \
test_can_play_type_ogg.html \
noContentLength.sjs \
test_seekable3.html \
test_a4_tone.html \
file_audio_event_adopt_iframe.html \
test_audio_event_adopt.html \
test_referer.html \
test_bug686137.html \
test_contentDuration1.html \
test_contentDuration2.html \
test_contentDuration3.html \
test_contentDuration4.html \
test_contentDuration5.html \
test_contentDuration6.html \
test_contentDuration7.html \
contentDuration1.sjs \
contentDuration2.sjs \
contentDuration3.sjs \
contentDuration4.sjs \
contentDuration5.sjs \
contentDuration6.sjs \
contentDuration7.sjs \
test_framebuffer.html \
test_seekable2.html \
test_chaining.html \
$(NULL)
# Temporarily disabled for bug 754860
# test_bug726904.html
else
MOCHITEST_FILES += \
test_can_play_type_no_ogg.html \
$(NULL)
endif
ifdef MOZ_WEBM
MOCHITEST_FILES += \
test_can_play_type_webm.html \
$(NULL)
else
MOCHITEST_FILES += \
test_can_play_type_no_webm.html \
$(NULL)
endif
ifdef MOZ_WAVE
MOCHITEST_FILES += \
test_can_play_type_wave.html \
$(NULL)
# Bug 759221
MOCHITEST_FILES += \
test_fragment_play.html \
test_fragment_noplay.html \
test_wave_data_u8.html \
test_wave_data_s16.html \
$(NULL)
else
MOCHITEST_FILES += \
test_can_play_type_no_wave.html \
$(NULL)
endif

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

@ -0,0 +1,326 @@
# Media tests should be backend independent, i.e., not conditioned on ogg,
# wave etc. (The only exception is the can_play_type tests, which
# necessarily depend on the backend(s) configured.) As far as possible, each
# test should work with any resource type. This makes it easy to add new
# backends and reduces the amount of test duplication.
# For each supported backend, resources that can be played by that backend
# should be added to the lists in manifest.js. Media tests that aren't
# testing for a bug in handling a specific resource type should pick one of
# the lists in manifest.js and run the test for each resource in the list
# that is supported in the current build (the canPlayType API is useful for
# this).
# To test whether a valid resource can simply be played through correctly,
# and optionally that its metadata is read correctly, just add it to
# gPlayTests in manifest.js. To test whether an invalid resource correctly
# throws an error (and does not cause a crash or hang), just add it to
# gErrorTests in manifest.js.
# To test for a specific bug in handling a specific resource type, make the
# test first check canPlayType for the type, and if it's not supported, just
# do ok(true, "Type not supported") and stop the test.
[DEFAULT]
support-files =
320x240.ogv
448636.ogv
allowed.sjs
audio-gaps.ogg
audio-overhang.ogg
audio.wav
badtags.ogg
basic.vtt
beta-phrasebook.ogg
big-buck-bunny-unseekable.mp4
big.wav
bogus.duh
bogus.ogv
bogus.wav
bug461281.ogg
bug482461-theora.ogv
bug482461.ogv
bug495129.ogv
bug495794.ogg
bug498380.ogv
bug498855-1.ogv
bug498855-2.ogv
bug498855-3.ogv
bug499519.ogv
bug500311.ogv
bug500311.ogv^headers^
bug501279.ogg
bug504613.ogv
bug504644.ogv
bug504843.ogv
bug506094.ogv
bug516323.indexed.ogv
bug516323.ogv
bug520493.ogg
bug520500.ogg
bug520908.ogv
bug520908.ogv^headers^
bug523816.ogv
bug533822.ogg
bug556821.ogv
bug557094.ogv
bug580982.webm
bug603918.webm
bug604067.webm
bug883173.vtt
can_play_type_dash.js
can_play_type_mpeg.js
can_play_type_ogg.js
can_play_type_wave.js
can_play_type_webm.js
cancellable_request.sjs
chain.ogg
chain.ogv
chain.opus
chained-audio-video.ogg
chained-video.ogv
contentDuration1.sjs
contentDuration2.sjs
contentDuration3.sjs
contentDuration4.sjs
contentDuration5.sjs
contentDuration6.sjs
contentDuration7.sjs
contentType.sjs
detodos.opus
dirac.ogg
dynamic_redirect.sjs
dynamic_resource.sjs
file_a4_tone.ogg
file_access_controls.html
file_audio_event_adopt_iframe.html
fragment_noplay.js
fragment_play.js
gizmo.mp4
id3tags.mp3
invalid-cmap-s0c0.opus
invalid-cmap-s0c2.opus
invalid-cmap-s1c2.opus
invalid-cmap-short.opus
invalid-m0c0.opus
invalid-m0c3.opus
invalid-m1c0.opus
invalid-m1c9.opus
invalid-m2c0.opus
invalid-m2c1.opus
long.vtt
manifest.js
multiple-bos.ogg
no-cues.webm
noContentLength.sjs
notags.mp3
owl-funnier-id3.mp3
owl-funny-id3.mp3
owl.mp3
r11025_msadpcm_c1.wav
r11025_s16_c1.wav
r11025_s16_c1_trailing.wav
r11025_u8_c1.wav
r11025_u8_c1_trunc.wav
r16000_u8_c1_list.wav
reactivate_helper.html
redirect.sjs
referer.sjs
region.vtt
seek.ogv
seek.webm
seek.yuv
seek1.js
seek10.js
seek11.js
seek12.js
seek13.js
seek2.js
seek3.js
seek4.js
seek5.js
seek6.js
seek7.js
seek8.js
seek9.js
seekLies.sjs
short-video.ogv
small-shot.m4a
small-shot.mp3
small-shot.ogg
sound.ogg
spacestorm-1000Hz-100ms.ogg
split.webm
test-1-mono.opus
test-2-stereo.opus
test-3-LCR.opus
test-4-quad.opus
test-5-5.0.opus
test-6-5.1.opus
test-7-6.1.opus
test-8-7.1.opus
variable-channel.ogg
variable-channel.opus
variable-preskip.opus
variable-samplerate.ogg
variable-samplerate.opus
vbr.mp3
video-overhang.ogg
wave_metadata.wav
wave_metadata_bad_len.wav
wave_metadata_bad_no_null.wav
wave_metadata_bad_utf8.wav
wave_metadata_unknown_tag.wav
wave_metadata_utf8.wav
wavedata_s16.wav
wavedata_u8.wav
[test_access_control.html]
[test_audio1.html]
[test_audio2.html]
[test_autoplay.html]
[test_bug448534.html]
[test_bug463162.xhtml]
[test_bug495145.html]
[test_bug495300.html]
[test_bug654550.html]
[test_bug686942.html]
[test_bug883173.html]
[test_bug895305.html]
[test_bug895091.html]
[test_bug919265.html]
[test_can_play_type.html]
[test_can_play_type_mpeg.html]
[test_closing_connections.html]
[test_constants.html]
[test_controls.html]
[test_currentTime.html]
[test_decode_error.html]
[test_defaultMuted.html]
[test_delay_load.html]
[test_error_on_404.html]
[test_info_leak.html]
[test_invalid_reject.html]
[test_load.html]
[test_load_candidates.html]
[test_load_same_resource.html]
[test_load_source.html]
[test_loop.html]
[test_metadata.html]
[test_no_load_event.html]
[test_networkState.html]
[test_new_audio.html]
[test_paused.html]
[test_paused_after_ended.html]
[test_play_events.html]
[test_play_events_2.html]
[test_playback_errors.html]
[test_seekable1.html]
[test_preload_actions.html]
[test_preload_attribute.html]
[test_progress.html]
[test_reactivate.html]
[test_readyState.html]
[test_replay_metadata.html]
[test_seek2.html]
[test_seek_out_of_range.html]
[test_source.html]
[test_source_write.html]
[test_source_null.html]
[test_standalone.html]
[test_volume.html]
[test_video_to_canvas.html]
[test_audiowrite.html]
[test_mediarecorder_creation.html]
[test_mediarecorder_avoid_recursion.html]
[test_mediarecorder_record_timeslice.html]
[test_mediarecorder_record_audiocontext.html]
[test_mediarecorder_record_stopms.html]
[test_mediarecorder_record_nosrc.html]
[test_mozHasAudio.html]
[test_source_media.html]
[test_autoplay_contentEditable.html]
[test_decoder_disable.html]
[test_mediarecorder_record_no_timeslice.html]
[test_mediarecorder_reload_crash.html]
[test_mediarecorder_record_immediate_stop.html]
[test_mediarecorder_record_session.html]
[test_playback.html]
[test_seekLies.html]
[test_media_sniffer.html]
[test_streams_srcObject.html]
[test_reset_src.html]
[test_streams_autoplay.html]
[test_streams_element_capture.html]
[test_streams_element_capture_reset.html]
[test_streams_element_capture_createObjectURL.html]
[test_streams_gc.html]
[test_streams_tracks.html]
[test_texttrack.html]
[test_texttrackcue.html]
[test_trackevent.html]
[test_texttrackregion.html]
[test_timeupdate_small_files.html]
[test_unseekable.html]
[test_VideoPlaybackQuality.html]
[test_VideoPlaybackQuality_disabled.html]
[test_webvtt_disabled.html]
# [test_audioDocumentTitle.html] # disabled - See bug 475110
# [test_error_in_video_document.html] # disabled - See bug 608634
# [test_mixed_principals.html] # disabled - See bug 567954 and 574586
# [test_playback_rate_playpause.html] # disabled - See bug 897108
# [test_played.html] # disabled - See bug 751539
# [test_preload_suspend.html] # disabled - See bug 493692
# [test_resume.html] # disabled - No bug :-(
# [test_videoDocumentTitle.html] # disabled - See bug 492821
# [test_playback_rate.html] # disabled - See bug 921622
# Disabled since it causes random memory corruption, bug 921622, so
# the best-case scenario is that it results in random crashes while it
# runs, like bug 918417, bug 920827, bug 923996, bug 928225, bug 929521
# bug 930982, bug 932193. Worst-case but quite likely, it causes random
# crashes and failures in other tests which run after it. Don't even think
# about reenabling it on any platform unless you *know* that you have fixed
# that. Then don't think about reenabling it on Windows until you know that
# you have fixed the timeouts of bug 832768, bug 814533, bug 840742
[test_play_twice.html] skip-if = appname == "seamonkey" # See bug 598252
[test_buffered.html] skip-if = os == "win" # See bug 832768 and 864682
[test_bug465498.html] skip-if = os == "win" # See bug 832768 and 864682
[test_bug493187.html] skip-if = os == "win" # See bug 707777
[test_media_selection.html] skip-if = os == "win" # See bug 897843
[test_seek.html] skip-if = os == "win" # See bug 832678, 795271, and 857424
# The tests below contain backend-specific tests. Write backend independent
# tests rather than adding to this list.
[test_can_play_type_ogg.html] run-if = ogg
[test_can_play_type_no_ogg.html] skip-if = ogg
[test_a4_tone.html] run-if = ogg
[test_audio_event_adopt.html] run-if = ogg
[test_bug686137.html] run-if = ogg
[test_chaining.html] run-if = ogg
[test_contentDuration1.html] run-if = ogg
[test_contentDuration2.html] run-if = ogg
[test_contentDuration3.html] run-if = ogg
[test_contentDuration4.html] run-if = ogg
[test_contentDuration5.html] run-if = ogg
[test_contentDuration6.html] run-if = ogg
[test_contentDuration7.html] run-if = ogg
[test_framebuffer.html] run-if = ogg
[test_referer.html] run-if = ogg
[test_seekable2.html] run-if = ogg
[test_seekable3.html] run-if = ogg
# [test_bug726904.html] run-if = ogg # disabled - See bug 754860
[test_can_play_type_webm.html] run-if = webm
[test_can_play_type_no_webm.html] skip-if = webm
[test_can_play_type_wave.html] run-if = wave
[test_can_play_type_no_wave.html] skip-if = wave
[test_fragment_noplay.html] run-if = wave
[test_fragment_play.html] run-if = wave
[test_wave_data_s16.html] run-if = wave
[test_wave_data_u8.html] run-if = wave

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

@ -4,3 +4,4 @@
# 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/.
MOCHITEST_MANIFESTS += ['mochitest.ini']

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

@ -1045,13 +1045,13 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
"re-cache of attrs/params not implemented! use the DOM "
"node directy instead");
// Convert to a 16-bit count. Subtract 2 in case we add an extra
// "src" or "wmode" entry below.
// Convert to a 16-bit count. Subtract 3 in case we add an extra
// "src", "wmode", or "codebase" entry below.
uint32_t cattrs = mContent->GetAttrCount();
if (cattrs < 0x0000FFFD) {
if (cattrs < 0x0000FFFC) {
mNumCachedAttrs = static_cast<uint16_t>(cattrs);
} else {
mNumCachedAttrs = 0xFFFD;
mNumCachedAttrs = 0xFFFC;
}
// Check if we are java for special codebase handling
@ -1144,12 +1144,25 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
mNumCachedAttrs++;
}
// "plugins.force.wmode" preference is forcing wmode type for plugins
// possible values - "opaque", "transparent", "windowed"
nsAdoptingCString wmodeType = Preferences::GetCString("plugins.force.wmode");
if (!wmodeType.IsEmpty()) {
// "plugins.force.wmode" forces us to send a specific "wmode" parameter,
// used by flash to select a rendering mode. Common values include
// "opaque", "transparent", "windowed", "direct"
nsCString wmodeType;
nsAdoptingCString wmodePref = Preferences::GetCString("plugins.force.wmode");
if (!wmodePref.IsEmpty()) {
mNumCachedAttrs++;
wmodeType = wmodePref;
}
#if defined(XP_WIN) || defined(XP_LINUX)
// Bug 923745 - Until we support windowed mode plugins in content processes,
// force flash to use a windowless rendering mode. This hack should go away
// when bug 923746 lands. (OS X plugins always use some native widgets, so
// unfortunately this does not help there)
else if (XRE_GetProcessType() == GeckoProcessType_Content) {
mNumCachedAttrs++;
wmodeType.AssignLiteral("transparent");
}
#endif
// (Bug 738396) java has quirks in its codebase parsing, pass the
// absolute codebase URI as content sees it.

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

@ -162,6 +162,15 @@ interface MozObjectLoadingContent {
[ChromeOnly, Throws]
void playPlugin();
/**
* Forces a re-evaluation and reload of the tag, optionally invalidating its
* click-to-play state. This can be used when the MIME type that provides a
* type has changed, for instance, to force the tag to re-evalulate the
* handler to use.
*/
[ChromeOnly, Throws]
void reload(boolean aClearActivation);
/**
* This attribute will return true if the current content type has been
* activated, either explicitly or by passing checks that would have it be

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

@ -4577,11 +4577,16 @@ aggregation_batch_stress_test()
int32_t iterations =
#ifdef DEBUG
10
#else
#if defined(MOZ_ASAN) || defined(MOZ_WIDGET_ANDROID)
// See Bug 929985: 500 is too many for ASAN and Android, 100 is safe.
100
#else
//
// 500 iterations sends 2,630,250 transactions through the system!!
//
500
#endif
#endif
;
return stress_test(&factory, iterations);

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

@ -1,4 +1,11 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:set ts=2 sts=2 sw=2 et cin:
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MacIOSurface.h"
#include <OpenGL/gl.h>
#include <QuartzCore/QuartzCore.h>
#include <dlfcn.h>
#include "mozilla/RefPtr.h"

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

@ -142,7 +142,8 @@ public:
// instead.
//
// This value is valid for nested scrollable layers as well, and is still
// relative to the layer tree origin.
// relative to the layer tree origin. This value is provided by Gecko at
// layout/paint time.
ScreenIntRect mCompositionBounds;
// ---------------------------------------------------------------------------
@ -226,23 +227,20 @@ public:
// The following metrics are dimensionless.
//
// The resolution that the current frame has been painted at.
//
// Every time this frame is composited and the compositor samples its
// transform, this metric is used to create a transform which is
// post-multiplied into the parent's transform. Since this only happens when
// we walk the layer tree, the resulting transform isn't stored here. Thus the
// resolution of parent layers is opaque to this metric.
// The incremental resolution that the current frame has been painted at
// relative to the parent frame's resolution. This information is provided
// by Gecko at layout/paint time.
ParentLayerToLayerScale mResolution;
// The cumulative resolution that the current frame has been painted at.
// This is the product of our mResolution and the mResolutions of our parent frames.
// This information is provided by Gecko at layout/paint time.
LayoutDeviceToLayerScale mCumulativeResolution;
// The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
// diverge.
// diverge. This information is initialized in Gecko but updated in the APZC.
CSSToScreenScale mZoom;
// The conversion factor between CSS pixels and device pixels for this frame.

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

@ -638,27 +638,32 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
// comments explain what values are stored in the variables at these two levels. All the comments
// use standard matrix notation where the leftmost matrix in a multiplication is applied first.
// ancestorUntransform takes points from aApzc's parent APZC's screen coordinates
// ancestorUntransform takes points from aApzc's parent APZC's layer coordinates
// to aApzc's screen coordinates.
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
// and RC.Inverse() * QC.Inverse() at recursion level for P.
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
// Hit testing for this layer is performed in aApzc's screen coordinates.
gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
APZC_LOG("Untransformed %f %f to screen coordinates %f %f for hit-testing APZC %p\n",
// hitTestTransform takes points from aApzc's parent APZC's layer coordinates to
// the hit test space (which is aApzc's transient coordinates).
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() at L,
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PN.Inverse() at P.
gfx3DMatrix hitTestTransform = ancestorUntransform
* aApzc->GetCSSTransform().Inverse()
* aApzc->GetNontransientAsyncTransform().Inverse();
gfxPoint hitTestPointForThisLayer = hitTestTransform.ProjectPoint(aHitTestPoint);
APZC_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
// myUntransform takes points from aApzc's screen coordinates
// childUntransform takes points from aApzc's parent APZC's layer coordinates
// to aApzc's layer coordinates (which are aApzc's children's screen coordinates).
// It is LA.Inverse() * LC.Inverse() at L
// and PA.Inverse() * PC.Inverse() at P.
gfx3DMatrix myUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse()
* aApzc->GetCSSTransform().Inverse();
// Hit testing for child layers is performed in aApzc's layer coordinates.
gfxPoint hitTestPointForChildLayers = myUntransform.ProjectPoint(hitTestPointForThisLayer);
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P.
gfx3DMatrix childUntransform = ancestorUntransform
* aApzc->GetCSSTransform().Inverse()
* gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
gfxPoint hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
APZC_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
@ -687,22 +692,34 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
When layer L is displayed to the screen by the compositor, the set of transforms that
are applied to L are (in order from top to bottom):
L's transient async transform (hereafter referred to as transform matrix LT)
L's nontransient async transform (hereafter referred to as transform matrix LN)
L's CSS transform (hereafter referred to as transform matrix LC)
L's async transform (hereafter referred to as transform matrix LA)
M's transient async transform (hereafter referred to as transform matrix MT)
M's nontransient async transform (hereafter referred to as transform matrix MN)
M's CSS transform (hereafter referred to as transform matrix MC)
M's async transform (hereafter referred to as transform matrix MA)
...
R's transient async transform (hereafter referred to as transform matrix RT)
R's nontransient async transform (hereafter referred to as transform matrix RN)
R's CSS transform (hereafter referred to as transform matrix RC)
R's async transform (hereafter referred to as transform matrix RA)
Therefore, if we want user input to modify L's async transform, we have to first convert
user input from screen space to the coordinate space of L's async transform. Doing this
involves applying the following transforms (in order from top to bottom):
RA.Inverse()
Also, for any layer, the async transform is the combination of its transient and non-transient
parts. That is, for any layer L:
LA === LT * LN
LA.Inverse() === LN.Inverse() * LT.Inverse()
If we want user input to modify L's transient async transform, we have to first convert
user input from screen space to the coordinate space of L's transient async transform. Doing
this involves applying the following transforms (in order from top to bottom):
RC.Inverse()
RN.Inverse()
RT.Inverse()
...
MA.Inverse()
MC.Inverse()
MN.Inverse()
MT.Inverse()
LC.Inverse()
LN.Inverse()
This combined transformation is returned in the aTransformToApzcOut out-parameter.
Next, if we want user inputs sent to gecko for event-dispatching, we will need to strip
@ -710,34 +727,39 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
transforms are stored only in the compositor and gecko does not account for them when
doing display-list-based hit-testing for event dispatching. Therefore, given a user input
in screen space, the following transforms need to be applied (in order from top to bottom):
RA.Inverse()
RC.Inverse()
RN.Inverse()
RT.Inverse()
...
MA.Inverse()
MC.Inverse()
LA.Inverse()
MN.Inverse()
MT.Inverse()
LC.Inverse()
LN.Inverse()
LT.Inverse()
LC
MC
...
RC
This sequence can be simplified and refactored to the following:
aTransformToApzcOut
LA.Inverse()
LT.Inverse()
LC
MC
...
RC
Since aTransformToApzcOut is already one of the out-parameters, we set aTransformToGeckoOut
to the remaining transforms (LA.Inverse() * MC * ... * RC), so that the caller code can
to the remaining transforms (LT.Inverse() * LC * ... * RC), so that the caller code can
combine it with aTransformToApzcOut to get the final transform required in this case.
Note that for many of these layers, there will be no AsyncPanZoomController attached, and
so the async transform will be the identity transform. So, in the example above, if layers
L and P have APZC instances attached, MA, NA, OA, QA, and RA will be identity transforms.
Additionally, for space-saving purposes, each APZC instance stores its layers individual
L and P have APZC instances attached, MT, MN, NT, NN, OT, ON, QT, QN, RT and RN will be
identity transforms.
Additionally, for space-saving purposes, each APZC instance stores its layer's individual
CSS transform and the accumulation of CSS transforms to its parent APZC. So the APZC for
layer L would store LC and (MC * NC * OC), and the layer P would store PC and (QC * RC).
The APZCs also obviously have LA and PA, so all of the above transformation combinations
The APZCs also obviously have LT, LN, PT, and PN, so all of the above transformation combinations
required can be generated.
*/
void
@ -754,23 +776,27 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix&
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
// asyncUntransform is LA.Inverse()
gfx3DMatrix asyncUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
// nontransientAsyncTransform is LN
gfx3DMatrix nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform();
// transientAsyncUntransform is LT.Inverse()
gfx3DMatrix transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform;
// aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse()
aTransformToApzcOut = ancestorUntransform;
// aTransformToGeckoOut is initialized to LA.Inverse() * MC * NC * OC
aTransformToGeckoOut = asyncUntransform * aApzc->GetAncestorTransform();
// aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = ancestorUntransform * aApzc->GetCSSTransform().Inverse() * nontransientAsyncTransform.Inverse();
// aTransformToGeckoOut is initialized to LT.Inverse() * LC * MC * NC * OC
aTransformToGeckoOut = transientAsyncUntransform * aApzc->GetCSSTransform() * aApzc->GetAncestorTransform();
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform().Inverse();
// asyncUntransform is updated to PA.Inverse() when parent == P
asyncUntransform = gfx3DMatrix(parent->GetCurrentAsyncTransform()).Inverse();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse()
gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * asyncUntransform * parent->GetCSSTransform().Inverse();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse()
gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * parent->GetCSSTransform().Inverse() * asyncUntransform;
// aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
// aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut;
// aTransformToGeckoOut is LA.Inverse() * MC * NC * OC * PC * QC * RC
// aTransformToGeckoOut is LT.Inverse() * LC * MC * NC * OC * PC * QC * RC
aTransformToGeckoOut = aTransformToGeckoOut * parent->GetCSSTransform() * parent->GetAncestorTransform();
// The above values for aTransformToApzcOut and aTransformToGeckoOut when parent == P match

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

@ -450,8 +450,6 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
// this touchstart is just a tap that doesn't end up triggering a redraw.
{
ReentrantMonitorAutoEnter lock(mMonitor);
// Bring the resolution back in sync with the zoom.
SetZoomAndResolution(mFrameMetrics.mZoom);
RequestContentRepaint();
ScheduleComposite();
}
@ -917,9 +915,6 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
shouldContinueFlingY = mY.FlingApplyFrictionOrCancel(aDelta);
// If we shouldn't continue the fling, let's just stop and repaint.
if (!shouldContinueFlingX && !shouldContinueFlingY) {
// Bring the resolution back in sync with the zoom, in case we scaled down
// the zoom while accelerating.
SetZoomAndResolution(mFrameMetrics.mZoom);
SendAsyncScrollEvent();
RequestContentRepaint();
mState = NOTHING;
@ -960,7 +955,7 @@ void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
void AsyncPanZoomController::ScaleWithFocus(float aScale,
const CSSPoint& aFocus) {
SetZoomAndResolution(CSSToScreenScale(mFrameMetrics.mZoom.scale * aScale));
mFrameMetrics.mZoom.scale *= aScale;
// We want to adjust the scroll offset such that the CSS point represented by aFocus remains
// at the same position on the screen before and after the change in zoom. The below code
// accomplishes this; see https://bugzilla.mozilla.org/show_bug.cgi?id=923431#c6 for an
@ -1113,7 +1108,7 @@ void AsyncPanZoomController::RequestContentRepaint() {
mFrameMetrics.mScrollOffset.x) < EPSILON &&
fabsf(mLastPaintRequestMetrics.mScrollOffset.y -
mFrameMetrics.mScrollOffset.y) < EPSILON &&
mFrameMetrics.mCumulativeResolution == mLastPaintRequestMetrics.mCumulativeResolution) {
mFrameMetrics.mZoom == mLastPaintRequestMetrics.mZoom) {
return;
}
@ -1202,8 +1197,6 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
requestAnimationFrame = true;
if (aSampleTime - mAnimationStartTime >= ZOOM_TO_DURATION) {
// Bring the resolution in sync with the zoom.
SetZoomAndResolution(mFrameMetrics.mZoom);
mState = NOTHING;
SendAsyncScrollEvent();
RequestContentRepaint();
@ -1269,6 +1262,13 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
/ mFrameMetrics.GetParentResolution());
}
gfx3DMatrix AsyncPanZoomController::GetNontransientAsyncTransform() {
ReentrantMonitorAutoEnter lock(mMonitor);
return gfx3DMatrix::ScalingMatrix(mLastContentPaintMetrics.mResolution.scale,
mLastContentPaintMetrics.mResolution.scale,
1.0f);
}
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
ReentrantMonitorAutoEnter lock(mMonitor);
@ -1302,8 +1302,17 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics = aLayerMetrics;
mState = NOTHING;
} else if (!mFrameMetrics.mScrollableRect.IsEqualEdges(aLayerMetrics.mScrollableRect)) {
} else {
// If we're not taking the aLayerMetrics wholesale we still need to pull
// in some things into our local mFrameMetrics because these things are
// determined by Gecko and our copy in mFrameMetrics may be stale.
mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect;
mFrameMetrics.mCompositionBounds = aLayerMetrics.mCompositionBounds;
float parentResolutionChange = aLayerMetrics.GetParentResolution().scale
/ mFrameMetrics.GetParentResolution().scale;
mFrameMetrics.mZoom.scale *= parentResolutionChange;
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
}
if (needContentRepaint) {
@ -1329,7 +1338,7 @@ void AsyncPanZoomController::UpdateCompositionBounds(const ScreenIntRect& aCompo
if (aCompositionBounds.width && aCompositionBounds.height &&
oldCompositionBounds.width && oldCompositionBounds.height) {
float adjustmentFactor = float(aCompositionBounds.width) / float(oldCompositionBounds.width);
SetZoomAndResolution(CSSToScreenScale(mFrameMetrics.mZoom.scale * adjustmentFactor));
mFrameMetrics.mZoom.scale *= adjustmentFactor;
// Repaint on a rotation so that our new resolution gets properly updated.
RequestContentRepaint();
@ -1479,18 +1488,6 @@ void AsyncPanZoomController::TimeoutTouchListeners() {
ContentReceivedTouch(false);
}
void AsyncPanZoomController::SetZoomAndResolution(const CSSToScreenScale& aZoom) {
mMonitor.AssertCurrentThreadIn();
LayoutDeviceToParentLayerScale parentResolution = mFrameMetrics.GetParentResolution();
mFrameMetrics.mZoom = aZoom;
// We use ScreenToLayerScale(1) below in order to ask gecko to render
// what's currently visible on the screen. This is effectively turning
// the async zoom amount into the gecko zoom amount.
mFrameMetrics.mCumulativeResolution = aZoom / mFrameMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
// The parent resolution will not have changed.
mFrameMetrics.mResolution = mFrameMetrics.mCumulativeResolution / parentResolution;
}
void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,
const CSSToScreenScale& aMinZoom,
const CSSToScreenScale& aMaxZoom) {

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

@ -200,6 +200,13 @@ public:
*/
ViewTransform GetCurrentAsyncTransform();
/**
* Returns the part of the async transform that will remain once Gecko does a
* repaint at the desired metrics. That is, in the steady state:
* gfx3DMatrix(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
*/
gfx3DMatrix GetNontransientAsyncTransform();
/**
* Recalculates the displayport. Ideally, this should paint an area bigger
* than the composite-to dimensions so that when you scroll down, you don't
@ -450,14 +457,6 @@ protected:
*/
void TimeoutTouchListeners();
/**
* Utility function that sets the zoom and resolution simultaneously. This is
* useful when we want to repaint at the current zoom level.
*
* *** The monitor must be held while calling this.
*/
void SetZoomAndResolution(const mozilla::CSSToScreenScale& aZoom);
/**
* Timeout function for mozbrowserasyncscroll event. Because we throttle
* mozbrowserasyncscroll events in some conditions, this function ensures

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

@ -0,0 +1,27 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.ArrayType(TypedObject.uint16, 3);
var VecPointType = new TypedObject.ArrayType(PointType, 3);
function foo() {
for (var i = 0; i < 10000; i += 9) {
var vec = new VecPointType([
[i, i+1, i+2],
[i+3, i+4, i+5],
[i+6, i+7, i+8]]);
var sum = vec[0][0] + vec[0][1] + vec[0][2];
assertEq(sum, 3*i + 3);
sum = vec[1][0] + vec[1][1] + vec[1][2];
assertEq(sum, 3*i + 12);
sum = vec[2][0] + vec[2][1] + vec[2][2];
assertEq(sum, 3*i + 21);
}
}
foo();

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

@ -0,0 +1,45 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.StructType({x: TypedObject.uint16,
y: TypedObject.uint16,
z: TypedObject.uint16});
var VecPointType = new TypedObject.ArrayType(PointType, 3);
var PairVecType = new TypedObject.StructType({fst: VecPointType,
snd: VecPointType});
function foo() {
for (var i = 0; i < 5000; i += 9) {
var p = new PairVecType({fst: [{x: i, y: i+1, z:i+2},
{x: i+3, y: i+4, z:i+5},
{x: i+6, y: i+7, z:i+8}],
snd: [{x: i+9, y:i+10, z:i+11},
{x: i+12, y:i+13, z:i+14},
{x: i+15, y:i+16, z:i+17}]
});
var sum;
sum = p.fst[0].x + p.fst[0].y + p.fst[0].z;
assertEq(sum, 3*i + 3);
sum = p.fst[1].x + p.fst[1].y + p.fst[1].z;
assertEq(sum, 3*i + 12);
sum = p.fst[2].x + p.fst[2].y + p.fst[2].z;
assertEq(sum, 3*i + 21);
sum = p.snd[0].x + p.snd[0].y + p.snd[0].z;
assertEq(sum, 3*i + 30);
sum = p.snd[1].x + p.snd[1].y + p.snd[1].z;
assertEq(sum, 3*i + 39);
sum = p.snd[2].x + p.snd[2].y + p.snd[2].z;
assertEq(sum, 3*i + 48);
}
}
foo();

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

@ -0,0 +1,30 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.StructType({x: TypedObject.uint16,
y: TypedObject.uint16,
z: TypedObject.uint16});
var VecPointType = new TypedObject.ArrayType(PointType, 3);
function foo() {
for (var i = 0; i < 10000; i += 9) {
var vec = new VecPointType([
{x: i, y:i+1, z:i+2},
{x: i+3, y:i+4, z:i+5},
{x: i+6, y:i+7, z:i+8}]);
var sum = vec[0].x + vec[0].y + vec[0].z;
assertEq(sum, 3*i + 3);
sum = vec[1].x + vec[1].y + vec[1].z;
assertEq(sum, 3*i + 12);
sum = vec[2].x + vec[2].y + vec[2].z;
assertEq(sum, 3*i + 21);
}
}
foo();

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

@ -0,0 +1,24 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var Vec3u16Type = new TypedObject.ArrayType(TypedObject.uint16, 3);
var PairVec3u16Type = new TypedObject.StructType({fst: Vec3u16Type,
snd: Vec3u16Type});
function foo_u16() {
for (var i = 0; i < 15000; i += 6) {
var p = new PairVec3u16Type({fst: [i, i+1, i+2],
snd: [i+3,i+4,i+5]});
var sum = p.fst[0] + p.fst[1] + p.fst[2];
assertEq(sum, 3*i + 3);
sum = p.snd[0] + p.snd[1] + p.snd[2];
assertEq(sum, 3*i + 12);
}
}
foo_u16();

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

@ -0,0 +1,19 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var Vec3u16Type = new TypedObject.ArrayType(TypedObject.uint16, 3);
function foo_u16() {
for (var i = 0; i < 30000; i += 3) {
var vec = new Vec3u16Type([i, i+1, i+2]);
var sum = vec[0] + vec[1] + vec[2];
assertEq(sum, 3*i + 3);
}
}
foo_u16();

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

@ -0,0 +1,27 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.ArrayType(TypedObject.uint32, 3);
var VecPointType = new TypedObject.ArrayType(PointType, 3);
function foo() {
for (var i = 0; i < 10000; i += 9) {
var vec = new VecPointType([
[i, i+1, i+2],
[i+3, i+4, i+5],
[i+6, i+7, i+8]]);
var sum = vec[0][0] + vec[0][1] + vec[0][2];
assertEq(sum, 3*i + 3);
sum = vec[1][0] + vec[1][1] + vec[1][2];
assertEq(sum, 3*i + 12);
sum = vec[2][0] + vec[2][1] + vec[2][2];
assertEq(sum, 3*i + 21);
}
}
foo();

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

@ -0,0 +1,45 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.StructType({x: TypedObject.uint32,
y: TypedObject.uint32,
z: TypedObject.uint32});
var VecPointType = new TypedObject.ArrayType(PointType, 3);
var PairVecType = new TypedObject.StructType({fst: VecPointType,
snd: VecPointType});
function foo() {
for (var i = 0; i < 5000; i += 9) {
var p = new PairVecType({fst: [{x: i, y: i+1, z:i+2},
{x: i+3, y: i+4, z:i+5},
{x: i+6, y: i+7, z:i+8}],
snd: [{x: i+9, y:i+10, z:i+11},
{x: i+12, y:i+13, z:i+14},
{x: i+15, y:i+16, z:i+17}]
});
var sum;
sum = p.fst[0].x + p.fst[0].y + p.fst[0].z;
assertEq(sum, 3*i + 3);
sum = p.fst[1].x + p.fst[1].y + p.fst[1].z;
assertEq(sum, 3*i + 12);
sum = p.fst[2].x + p.fst[2].y + p.fst[2].z;
assertEq(sum, 3*i + 21);
sum = p.snd[0].x + p.snd[0].y + p.snd[0].z;
assertEq(sum, 3*i + 30);
sum = p.snd[1].x + p.snd[1].y + p.snd[1].z;
assertEq(sum, 3*i + 39);
sum = p.snd[2].x + p.snd[2].y + p.snd[2].z;
assertEq(sum, 3*i + 48);
}
}
foo();

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

@ -0,0 +1,30 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var PointType = new TypedObject.StructType({x: TypedObject.uint32,
y: TypedObject.uint32,
z: TypedObject.uint32});
var VecPointType = new TypedObject.ArrayType(PointType, 3);
function foo() {
for (var i = 0; i < 10000; i += 9) {
var vec = new VecPointType([
{x: i, y:i+1, z:i+2},
{x: i+3, y:i+4, z:i+5},
{x: i+6, y:i+7, z:i+8}]);
var sum = vec[0].x + vec[0].y + vec[0].z;
assertEq(sum, 3*i + 3);
sum = vec[1].x + vec[1].y + vec[1].z;
assertEq(sum, 3*i + 12);
sum = vec[2].x + vec[2].y + vec[2].z;
assertEq(sum, 3*i + 21);
}
}
foo();

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

@ -0,0 +1,24 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var Vec3u32Type = new TypedObject.ArrayType(TypedObject.uint32, 3);
var PairVec3u32Type = new TypedObject.StructType({fst: Vec3u32Type,
snd: Vec3u32Type});
function foo_u32() {
for (var i = 0; i < 15000; i += 6) {
var p = new PairVec3u32Type({fst: [i, i+1, i+2],
snd: [i+3,i+4,i+5]});
var sum = p.fst[0] + p.fst[1] + p.fst[2];
assertEq(sum, 3*i + 3);
sum = p.snd[0] + p.snd[1] + p.snd[2];
assertEq(sum, 3*i + 12);
}
}
foo_u32();

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

@ -0,0 +1,19 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
if (!this.hasOwnProperty("TypedObject"))
quit();
var Vec3u32Type = new TypedObject.ArrayType(TypedObject.uint32, 3);
function foo_u32() {
for (var i = 0; i < 30000; i += 3) {
var vec = new Vec3u32Type([i, i+1, i+2]);
var sum = vec[0] + vec[1] + vec[2];
assertEq(sum, 3*i + 3);
}
}
foo_u32();

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

@ -1,3 +1,5 @@
loadRelativeToScript("../../../tests/ecma_6/Math/shell.js");
for (var i = -20; i < 20; i++) {
assertEq(Math.hypot(+0, i), Math.abs(i));
assertEq(Math.hypot(-0, i), Math.abs(i));
@ -21,5 +23,3 @@ assertNear(Math.hypot(1e3, 1e-3, 1e3, 1e-3), 1414.2135623738021555);
for (var i = 1, j = 1; i < 2; i += 0.05, j += 0.05)
assertNear(Math.hypot(i, j), Math.sqrt(i * i + j * j));
reportCompare(0, 0, "ok");

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

@ -55,6 +55,3 @@ assertEq(Math.hypot(+0, +0, -0), +0);
// The length property of the hypot function is 2.
assertEq(Math.hypot.length, 2);
reportCompare(0, 0, "ok");

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

@ -0,0 +1,3 @@
x = ParallelArray([1942], function() {})
x + watch.call(x, "length", (function() {}));

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

@ -3001,6 +3001,21 @@ bool CodeGenerator::visitAtan2D(LAtan2D *lir)
return true;
}
bool CodeGenerator::visitHypot(LHypot *lir)
{
Register temp = ToRegister(lir->temp());
FloatRegister x = ToFloatRegister(lir->x());
FloatRegister y = ToFloatRegister(lir->y());
masm.setupUnalignedABICall(2, temp);
masm.passABIArg(x);
masm.passABIArg(y);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ecmaHypot), MacroAssembler::DOUBLE);
JS_ASSERT(ToFloatRegister(lir->output()) == ReturnFloatReg);
return true;
}
bool
CodeGenerator::visitNewParallelArray(LNewParallelArray *lir)
{

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

@ -179,6 +179,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT *ins);
bool visitAbsI(LAbsI *lir);
bool visitAtan2D(LAtan2D *lir);
bool visitHypot(LHypot *lir);
bool visitPowI(LPowI *lir);
bool visitPowD(LPowD *lir);
bool visitRandom(LRandom *lir);

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

@ -1635,7 +1635,7 @@ IonCompile(JSContext *cx, JSScript *script,
if (!constraints)
return AbortReason_Alloc;
IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, constraints,
IonBuilder *builder = alloc->new_<IonBuilder>((JSContext *) nullptr, cx->compartment(), temp, graph, constraints,
&inspector, info, baselineFrame);
if (!builder)
return AbortReason_Alloc;

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

@ -2105,7 +2105,7 @@ jit::AnalyzeNewScriptProperties(JSContext *cx, HandleFunction fun,
types::CompilerConstraintList *constraints = types::NewCompilerConstraintList();
BaselineInspector inspector(script);
IonBuilder builder(cx, &temp, &graph, constraints,
IonBuilder builder(cx, cx->compartment(), &temp, &graph, constraints,
&inspector, &info, /* baselineFrame = */ nullptr);
if (!builder.build()) {

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

@ -37,13 +37,13 @@ using namespace js::jit;
using mozilla::DebugOnly;
using mozilla::Maybe;
IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
IonBuilder::IonBuilder(JSContext *analysisContext, JSCompartment *comp, TempAllocator *temp, MIRGraph *graph,
types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame,
size_t inliningDepth, uint32_t loopDepth)
: MIRGenerator(cx->compartment(), temp, graph, info),
: MIRGenerator(comp, temp, graph, info),
backgroundCodegen_(nullptr),
cx(cx),
analysisContext(analysisContext),
baselineFrame_(baselineFrame),
abortReason_(AbortReason_Disable),
reprSetHash_(nullptr),
@ -69,12 +69,13 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
pc = info->startPC();
JS_ASSERT(script()->hasBaselineScript());
JS_ASSERT(!!analysisContext == (info->executionMode() == DefinitePropertiesAnalysis));
}
void
IonBuilder::clearForBackEnd()
{
cx = nullptr;
JS_ASSERT(!analysisContext);
baselineFrame_ = nullptr;
// The GSN cache allocates data from the malloc heap. Release this before
@ -282,12 +283,12 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
// Allow constructing lazy scripts when performing the definite properties
// analysis, as baseline has not been used to warm the caller up yet.
if (target->isInterpreted() && info().executionMode() == DefinitePropertiesAnalysis) {
if (!target->getOrCreateScript(context()))
if (!target->getOrCreateScript(analysisContext))
return false;
RootedScript script(context(), target->nonLazyScript());
RootedScript script(analysisContext, target->nonLazyScript());
if (!script->hasBaselineScript() && script->canBaselineCompile()) {
MethodStatus status = BaselineCompile(context(), script);
MethodStatus status = BaselineCompile(analysisContext, script);
if (status != Method_Compiled)
return false;
}
@ -3817,11 +3818,12 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
AutoAccumulateExits aae(graph(), saveExits);
// Build the graph.
JS_ASSERT(!cx->isExceptionPending());
IonBuilder inlineBuilder(cx, &temp(), &graph(), constraints(), &inspector, info, nullptr,
JS_ASSERT_IF(analysisContext, !analysisContext->isExceptionPending());
IonBuilder inlineBuilder(analysisContext, compartment,
&temp(), &graph(), constraints(), &inspector, info, nullptr,
inliningDepth_ + 1, loopDepth_);
if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) {
if (cx->isExceptionPending()) {
if (analysisContext && analysisContext->isExceptionPending()) {
IonSpew(IonSpew_Abort, "Inline builder raised exception.");
abortReason_ = AbortReason_Error;
return false;
@ -5974,10 +5976,13 @@ IonBuilder::testSingletonProperty(JSObject *obj, PropertyName *name)
return nullptr;
types::TypeObjectKey *objType = types::TypeObjectKey::get(obj);
if (analysisContext)
objType->ensureTrackedProperty(analysisContext, NameToId(name));
if (objType->unknownProperties())
return nullptr;
types::HeapTypeSetKey property = objType->property(NameToId(name), context());
types::HeapTypeSetKey property = objType->property(NameToId(name));
if (property.isOwnProperty(constraints())) {
if (obj->hasSingletonType())
return property.singleton(constraints());
@ -6049,10 +6054,12 @@ IonBuilder::testSingletonPropertyTypes(MDefinition *obj, JSObject *singleton, Pr
types::TypeObjectKey *object = types->getObject(i);
if (!object)
continue;
if (analysisContext)
object->ensureTrackedProperty(analysisContext, NameToId(name));
if (object->unknownProperties())
return false;
types::HeapTypeSetKey property = object->property(NameToId(name), context());
types::HeapTypeSetKey property = object->property(NameToId(name));
if (property.isOwnProperty(constraints()))
return false;
@ -6187,12 +6194,15 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
}
types::TypeObjectKey *staticType = types::TypeObjectKey::get(staticObject);
if (analysisContext)
staticType->ensureTrackedProperty(analysisContext, NameToId(name));
if (staticType->unknownProperties()) {
*psucceeded = false;
return true;
}
types::HeapTypeSetKey property = staticType->property(id, context());
types::HeapTypeSetKey property = staticType->property(id);
if (!property.maybeTypes() ||
!property.maybeTypes()->definiteProperty() ||
property.configured(constraints(), staticType))
@ -6204,7 +6214,7 @@ IonBuilder::getStaticName(JSObject *staticObject, PropertyName *name, bool *psuc
}
types::TemporaryTypeSet *types = bytecodeTypes(pc);
bool barrier = PropertyReadNeedsTypeBarrier(context(), constraints(), staticType,
bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), staticType,
name, types, /* updateObserved = */ true);
JSObject *singleton = types->getSingleton();
@ -6423,13 +6433,16 @@ IonBuilder::jsop_getelem()
bool emitted = false;
if (!getElemTryTypedObject(&emitted, obj, index) || emitted)
return emitted;
if (!getElemTryDense(&emitted, obj, index) || emitted)
return emitted;
if (!getElemTryTypedStatic(&emitted, obj, index) || emitted)
return emitted;
if (!getElemTryTyped(&emitted, obj, index) || emitted)
if (!getElemTryTypedArray(&emitted, obj, index) || emitted)
return emitted;
if (!getElemTryString(&emitted, obj, index) || emitted)
@ -6460,6 +6473,213 @@ IonBuilder::jsop_getelem()
return pushTypeBarrier(ins, types, true);
}
bool
IonBuilder::getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *index)
{
JS_ASSERT(*emitted == false);
TypeRepresentationSet objTypeReprs;
if (!lookupTypeRepresentationSet(obj, &objTypeReprs))
return false;
if (!objTypeReprs.allOfArrayKind())
return true;
TypeRepresentationSet elemTypeReprs;
if (!objTypeReprs.arrayElementType(*this, &elemTypeReprs))
return false;
size_t elemSize;
if (!elemTypeReprs.allHaveSameSize(&elemSize))
return true;
switch (elemTypeReprs.kind()) {
case TypeRepresentation::Struct:
case TypeRepresentation::Array:
return getElemTryComplexElemOfTypedObject(emitted,
obj,
index,
objTypeReprs,
elemTypeReprs,
elemSize);
case TypeRepresentation::Scalar:
return getElemTryScalarElemOfTypedObject(emitted,
obj,
index,
objTypeReprs,
elemTypeReprs,
elemSize);
}
MOZ_ASSUME_UNREACHABLE("Bad kind");
}
static MIRType
MIRTypeForTypedArrayRead(ScalarTypeRepresentation::Type arrayType,
bool observedDouble);
bool
IonBuilder::getElemTryScalarElemOfTypedObject(bool *emitted,
MDefinition *obj,
MDefinition *index,
TypeRepresentationSet objTypeReprs,
TypeRepresentationSet elemTypeReprs,
size_t elemSize)
{
JS_ASSERT(objTypeReprs.allOfArrayKind());
// Must always be loading the same scalar type
if (elemTypeReprs.length() != 1)
return true;
ScalarTypeRepresentation *elemTypeRepr = elemTypeReprs.get(0)->asScalar();
// Get the length.
size_t lenOfAll = objTypeReprs.arrayLength();
if (lenOfAll >= size_t(INT_MAX)) // int32 max is bound
return true;
MInstruction *length = MConstant::New(Int32Value(int32_t(lenOfAll)));
*emitted = true;
current->add(length);
// Ensure index is an integer.
MInstruction *idInt32 = MToInt32::New(index);
current->add(idInt32);
index = idInt32;
// Typed-object accesses usually in bounds (bail out otherwise).
index = addBoundsCheck(index, length);
// Find location within the owner object.
MDefinition *owner;
MDefinition *indexFromOwner;
if (obj->isNewDerivedTypedObject()) {
MNewDerivedTypedObject *ins = obj->toNewDerivedTypedObject();
MDefinition *ownerOffset = ins->offset();
// Typed array offsets are expressed in units of the (array)
// element alignment. The binary data uses byte units for
// offsets (such as the owner offset here).
MConstant *alignment = MConstant::New(Int32Value(elemTypeRepr->alignment()));
current->add(alignment);
MDiv *scaledOffset = MDiv::NewAsmJS(ownerOffset, alignment, MIRType_Int32);
current->add(scaledOffset);
MAdd *scaledOffsetPlusIndex = MAdd::NewAsmJS(scaledOffset, index,
MIRType_Int32);
current->add(scaledOffsetPlusIndex);
owner = ins->owner();
indexFromOwner = scaledOffsetPlusIndex;
} else {
owner = obj;
indexFromOwner = index;
}
// Load the element data.
MTypedObjectElements *elements = MTypedObjectElements::New(owner);
current->add(elements);
// Load the element.
MLoadTypedArrayElement *load = MLoadTypedArrayElement::New(elements, indexFromOwner, elemTypeRepr->type());
current->add(load);
current->push(load);
// If we are reading in-bounds elements, we can use knowledge about
// the array type to determine the result type, even if the opcode has
// never executed. The known pushed type is only used to distinguish
// uint32 reads that may produce either doubles or integers.
types::TemporaryTypeSet *resultTypes = bytecodeTypes(pc);
bool allowDouble = resultTypes->hasType(types::Type::DoubleType());
MIRType knownType = MIRTypeForTypedArrayRead(elemTypeRepr->type(), allowDouble);
// Note: we can ignore the type barrier here, we know the type must
// be valid and unbarriered.
load->setResultType(knownType);
load->setResultTypeSet(resultTypes);
return true;
}
bool
IonBuilder::getElemTryComplexElemOfTypedObject(bool *emitted,
MDefinition *obj,
MDefinition *index,
TypeRepresentationSet objTypeReprs,
TypeRepresentationSet elemTypeReprs,
size_t elemSize)
{
JS_ASSERT(objTypeReprs.allOfArrayKind());
MDefinition *type = loadTypedObjectType(obj);
MInstruction *elemType = MLoadFixedSlot::New(type, JS_TYPEOBJ_SLOT_ARRAY_ELEM_TYPE);
current->add(elemType);
// Get the length.
size_t lenOfAll = objTypeReprs.arrayLength();
if (lenOfAll >= size_t(INT_MAX)) // int32 max is bound
return true;
MInstruction *length = MConstant::New(Int32Value(int32_t(lenOfAll)));
*emitted = true;
current->add(length);
// Ensure index is an integer.
MInstruction *idInt32 = MToInt32::New(index);
current->add(idInt32);
index = idInt32;
// Typed-object accesses usually in bounds (bail out otherwise).
index = addBoundsCheck(index, length);
// Convert array index to element data offset.
MConstant *alignment = MConstant::New(Int32Value(elemSize));
current->add(alignment);
// Since we passed the bounds check, it is impossible for the
// result of multiplication to overflow; so enable imul path.
MMul *indexAsByteOffset = MMul::New(index, alignment, MIRType_Int32,
MMul::Integer);
current->add(indexAsByteOffset);
// Find location within the owner object.
MDefinition *owner;
MDefinition *indexAsByteOffsetFromOwner;
if (obj->isNewDerivedTypedObject()) {
MNewDerivedTypedObject *ins = obj->toNewDerivedTypedObject();
MDefinition *ownerOffset = ins->offset();
MAdd *offsetPlusScaledIndex = MAdd::NewAsmJS(ownerOffset,
indexAsByteOffset,
MIRType_Int32);
current->add(offsetPlusScaledIndex);
owner = ins->owner();
indexAsByteOffsetFromOwner = offsetPlusScaledIndex;
} else {
owner = obj;
indexAsByteOffsetFromOwner = indexAsByteOffset;
}
// Load the element data.
MTypedObjectElements *elements = MTypedObjectElements::New(owner);
current->add(elements);
// Create the derived type object.
MInstruction *derived = new MNewDerivedTypedObject(elemTypeReprs,
elemType,
owner,
indexAsByteOffsetFromOwner);
types::TemporaryTypeSet *resultTypes = bytecodeTypes(pc);
derived->setResultTypeSet(resultTypes);
current->add(derived);
current->push(derived);
return true;
}
bool
IonBuilder::getElemTryDense(bool *emitted, MDefinition *obj, MDefinition *index)
{
@ -6548,7 +6768,7 @@ IonBuilder::getElemTryTypedStatic(bool *emitted, MDefinition *obj, MDefinition *
}
bool
IonBuilder::getElemTryTyped(bool *emitted, MDefinition *obj, MDefinition *index)
IonBuilder::getElemTryTypedArray(bool *emitted, MDefinition *obj, MDefinition *index)
{
JS_ASSERT(*emitted == false);
@ -6703,7 +6923,7 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index)
// Emit GetElementCache.
types::TemporaryTypeSet *types = bytecodeTypes(pc);
bool barrier = PropertyReadNeedsTypeBarrier(context(), constraints(), obj, nullptr, types);
bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj, nullptr, types);
// Always add a barrier if the index might be a string, so that the cache
// can attach stubs for particular properties.
@ -6751,7 +6971,7 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index)
return false;
}
bool barrier = PropertyReadNeedsTypeBarrier(context(), constraints(), obj, nullptr, types);
bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj, nullptr, types);
bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
// Reads which are on holes in the object do not have to bail out if
@ -7601,11 +7821,14 @@ IonBuilder::objectsHaveCommonPrototype(types::TemporaryTypeSet *types, PropertyN
if (!isGetter && clasp->ops.setGeneric)
return false;
// Note: freezePropertiesForCommonPropFunc will freeze the property
// type sets later on if optimizing.
// Test for isOwnProperty() without freezing. If we end up
// optimizing, freezePropertiesForCommonPropFunc will freeze the
// property type sets later on.
types::HeapTypeSetKey property = type->property(NameToId(name));
if (property.maybeTypes() && !property.maybeTypes()->empty())
if (types::TypeSet *types = property.maybeTypes()) {
if (!types->empty() || types->configuredProperty())
return false;
}
if (JSObject *obj = type->singleton()) {
if (types::CanHaveEmptyPropertyTypesForOwnProperty(obj))
return false;
@ -7856,7 +8079,7 @@ IonBuilder::jsop_getprop(PropertyName *name)
return emitted;
types::TemporaryTypeSet *types = bytecodeTypes(pc);
bool barrier = PropertyReadNeedsTypeBarrier(context(), constraints(),
bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
current->peek(-1), name, types);
// Always use a call if we are doing the definite properties analysis and

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

@ -205,7 +205,7 @@ class IonBuilder : public MIRGenerator
static int CmpSuccessors(const void *a, const void *b);
public:
IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
IonBuilder(JSContext *analysisContext, JSCompartment *comp, TempAllocator *temp, MIRGraph *graph,
types::CompilerConstraintList *constraints,
BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame,
size_t inliningDepth = 0, uint32_t loopDepth = 0);
@ -435,11 +435,24 @@ class IonBuilder : public MIRGenerator
// jsop_getelem() helpers.
bool getElemTryDense(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryTypedStatic(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryTyped(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryTypedArray(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryTypedObject(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryString(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryArguments(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index);
bool getElemTryScalarElemOfTypedObject(bool *emitted,
MDefinition *obj,
MDefinition *index,
TypeRepresentationSet objTypeReprs,
TypeRepresentationSet elemTypeReprs,
size_t elemSize);
bool getElemTryComplexElemOfTypedObject(bool *emitted,
MDefinition *obj,
MDefinition *index,
TypeRepresentationSet objTypeReprs,
TypeRepresentationSet elemTypeReprs,
size_t elemSize);
// Typed array helpers.
MInstruction *getTypedArrayLength(MDefinition *obj);
@ -550,6 +563,7 @@ class IonBuilder : public MIRGenerator
InliningStatus inlineMathRound(CallInfo &callInfo);
InliningStatus inlineMathSqrt(CallInfo &callInfo);
InliningStatus inlineMathAtan2(CallInfo &callInfo);
InliningStatus inlineMathHypot(CallInfo &callInfo);
InliningStatus inlineMathMinMax(CallInfo &callInfo, bool max);
InliningStatus inlineMathPow(CallInfo &callInfo);
InliningStatus inlineMathRandom(CallInfo &callInfo);
@ -696,22 +710,12 @@ class IonBuilder : public MIRGenerator
return callerBuilder_ != nullptr;
}
JSContext *context() {
// JSContexts are only available to IonBuilder when running on the main
// thread, which after bug 785905 will only occur when doing eager
// analyses with no available baseline information. Until this bug is
// completed, both the |cx| member and |context()| may be used.
if (info().executionMode() == DefinitePropertiesAnalysis)
return cx;
return nullptr;
}
JSAtomState &names() { return compartment->runtimeFromAnyThread()->atomState; }
private:
bool init();
JSContext *cx;
JSContext *analysisContext;
BaselineFrame *baselineFrame_;
AbortReason abortReason_;
TypeRepresentationSetHash *reprSetHash_;

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

@ -2369,6 +2369,33 @@ class LAtan2D : public LCallInstructionHelper<1, 2, 1>
}
};
class LHypot : public LCallInstructionHelper<1, 2, 1>
{
public:
LIR_HEADER(Hypot)
LHypot(const LAllocation &x, const LAllocation &y, const LDefinition &temp) {
setOperand(0, x);
setOperand(1, y);
setTemp(0, temp);
}
const LAllocation *x() {
return getOperand(0);
}
const LAllocation *y() {
return getOperand(1);
}
const LDefinition *temp() {
return getTemp(0);
}
const LDefinition *output() {
return getDef(0);
}
};
// Double raised to an integer power.
class LPowI : public LCallInstructionHelper<1, 2, 1>
{

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

@ -105,6 +105,7 @@
_(SqrtD) \
_(SqrtF) \
_(Atan2D) \
_(Hypot) \
_(PowI) \
_(PowD) \
_(Random) \

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

@ -1221,6 +1221,19 @@ LIRGenerator::visitAtan2(MAtan2 *ins)
return defineReturn(lir, ins);
}
bool
LIRGenerator::visitHypot(MHypot *ins)
{
MDefinition *x = ins->x();
JS_ASSERT(x->type() == MIRType_Double);
MDefinition *y = ins->y();
JS_ASSERT(y->type() == MIRType_Double);
LHypot *lir = new LHypot(useRegisterAtStart(x), useRegisterAtStart(y), tempFixed(CallTempReg0));
return defineReturn(lir, ins);
}
bool
LIRGenerator::visitPow(MPow *ins)
{

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

@ -136,6 +136,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitAbs(MAbs *ins);
bool visitSqrt(MSqrt *ins);
bool visitAtan2(MAtan2 *ins);
bool visitHypot(MHypot *ins);
bool visitPow(MPow *ins);
bool visitRandom(MRandom *ins);
bool visitMathFunction(MMathFunction *ins);

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

@ -47,6 +47,8 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSNative native)
return inlineMathSqrt(callInfo);
if (native == math_atan2)
return inlineMathAtan2(callInfo);
if (native == js::math_hypot)
return inlineMathHypot(callInfo);
if (native == js_math_max)
return inlineMathMinMax(callInfo, true /* max */);
if (native == js_math_min)
@ -326,7 +328,7 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED);
bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType());
bool barrier = PropertyReadNeedsTypeBarrier(context(), constraints(),
bool barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
callInfo.thisArg(), nullptr, returnTypes);
if (barrier)
returnType = MIRType_Value;
@ -675,6 +677,32 @@ IonBuilder::inlineMathAtan2(CallInfo &callInfo)
return InliningStatus_Inlined;
}
IonBuilder::InliningStatus
IonBuilder::inlineMathHypot(CallInfo &callInfo)
{
if (callInfo.constructing())
return InliningStatus_NotInlined;
if (callInfo.argc() != 2)
return InliningStatus_NotInlined;
if (getInlineReturnType() != MIRType_Double)
return InliningStatus_NotInlined;
MIRType argType0 = callInfo.getArg(0)->type();
MIRType argType1 = callInfo.getArg(1)->type();
if (!IsNumberType(argType0) || !IsNumberType(argType1))
return InliningStatus_NotInlined;
callInfo.unwrapArgs();
MHypot *hypot = MHypot::New(callInfo.getArg(0), callInfo.getArg(1));
current->add(hypot);
current->push(hypot);
return InliningStatus_Inlined;
}
IonBuilder::InliningStatus
IonBuilder::inlineMathPow(CallInfo &callInfo)
{
@ -855,32 +883,36 @@ IonBuilder::inlineMathFRound(CallInfo &callInfo)
IonBuilder::InliningStatus
IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max)
{
if (callInfo.argc() != 2 || callInfo.constructing())
if (callInfo.argc() < 2 || callInfo.constructing())
return InliningStatus_NotInlined;
MIRType returnType = getInlineReturnType();
if (!IsNumberType(returnType))
return InliningStatus_NotInlined;
MIRType arg0Type = callInfo.getArg(0)->type();
if (!IsNumberType(arg0Type))
return InliningStatus_NotInlined;
MIRType arg1Type = callInfo.getArg(1)->type();
if (!IsNumberType(arg1Type))
for (unsigned i = 0; i < callInfo.argc(); i++) {
MIRType argType = callInfo.getArg(i)->type();
if (!IsNumberType(argType))
return InliningStatus_NotInlined;
if (returnType == MIRType_Int32 &&
(arg0Type == MIRType_Double || arg1Type == MIRType_Double))
{
// We would need to inform TI, if we happen to return a double.
// We would need to inform TI if we happen to return a double.
if (returnType == MIRType_Int32 && IsFloatingPointType(argType))
return InliningStatus_NotInlined;
}
callInfo.unwrapArgs();
MMinMax *ins = MMinMax::New(callInfo.getArg(0), callInfo.getArg(1), returnType, max);
// Chain N-1 MMinMax instructions to compute the MinMax.
MMinMax *last = MMinMax::New(callInfo.getArg(0), callInfo.getArg(1), returnType, max);
current->add(last);
for (unsigned i = 2; i < callInfo.argc(); i++) {
MMinMax *ins = MMinMax::New(last, callInfo.getArg(i), returnType, max);
current->add(ins);
current->push(ins);
last = ins;
}
current->push(last);
return InliningStatus_Inlined;
}
@ -1469,7 +1501,8 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo)
current->push(load);
// We don't track reserved slot types, so always emit a barrier.
pushTypeBarrier(load, getInlineReturnTypeSet(), true);
if (!pushTypeBarrier(load, getInlineReturnTypeSet(), true))
return InliningStatus_Error;
return InliningStatus_Inlined;
}

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

@ -2928,8 +2928,11 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *propertycx,
break;
types::TypeObjectKey *typeObj = types::TypeObjectKey::get(obj);
if (propertycx)
typeObj->ensureTrackedProperty(propertycx, NameToId(name));
if (!typeObj->unknownProperties()) {
types::HeapTypeSetKey property = typeObj->property(NameToId(name), propertycx);
types::HeapTypeSetKey property = typeObj->property(NameToId(name));
if (property.maybeTypes()) {
types::TypeSet::TypeList types;
if (!property.maybeTypes()->enumerateTypes(&types))

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

@ -3586,6 +3586,49 @@ class MAtan2
}
};
// Inline implementation of Math.hypot().
class MHypot
: public MBinaryInstruction,
public MixPolicy<DoublePolicy<0>, DoublePolicy<1> >
{
MHypot(MDefinition *y, MDefinition *x)
: MBinaryInstruction(x, y)
{
setResultType(MIRType_Double);
setMovable();
}
public:
INSTRUCTION_HEADER(Hypot)
static MHypot *New(MDefinition *x, MDefinition *y) {
return new MHypot(y, x);
}
MDefinition *x() const {
return getOperand(0);
}
MDefinition *y() const {
return getOperand(1);
}
TypePolicy *typePolicy() {
return this;
}
bool congruentTo(MDefinition *ins) const {
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
bool possiblyCalls() const {
return true;
}
};
// Inline implementation of Math.pow().
class MPow
: public MBinaryInstruction,

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

@ -59,6 +59,7 @@ namespace jit {
_(Abs) \
_(Sqrt) \
_(Atan2) \
_(Hypot) \
_(Pow) \
_(PowHalf) \
_(Random) \

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

@ -153,6 +153,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor
SAFE_OP(Abs)
SAFE_OP(Sqrt)
UNSAFE_OP(Atan2)
UNSAFE_OP(Hypot)
CUSTOM_OP(MathFunction)
SPECIALIZED_OP(Add, PERMIT_NUMERIC)
SPECIALIZED_OP(Sub, PERMIT_NUMERIC)

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

@ -178,6 +178,15 @@ TypeRepresentationSet::get(size_t i)
return entries_[i];
}
bool
TypeRepresentationSet::allOfArrayKind()
{
if (empty())
return false;
return kind() == TypeRepresentation::Array;
}
bool
TypeRepresentationSet::allOfKind(TypeRepresentation::Kind aKind)
{
@ -187,6 +196,22 @@ TypeRepresentationSet::allOfKind(TypeRepresentation::Kind aKind)
return kind() == aKind;
}
bool
TypeRepresentationSet::allHaveSameSize(size_t *out)
{
if (empty())
return false;
size_t size = get(0)->size();
for (size_t i = 1; i < length(); i++) {
if (get(i)->size() != size)
return false;
}
*out = size;
return true;
}
TypeRepresentation::Kind
TypeRepresentationSet::kind()
{

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

@ -80,6 +80,20 @@ class TypeRepresentationSet {
TypeRepresentation *get(size_t i);
bool allOfKind(TypeRepresentation::Kind kind);
// Returns true only when non-empty and `kind()` is
// `TypeRepresentation::Array`
bool allOfArrayKind();
// Returns true only if (1) non-empty, (2) for all types t in this
// set, t is sized, and (3) there is some size S such that for all
// types t in this set, `t.size() == S`. When the above holds,
// then also sets `*out` to S; otherwise leaves `*out` unchanged
// and returns false.
//
// At the moment condition (2) trivially holds. When Bug 922115
// lands, some array types will be unsized.
bool allHaveSameSize(size_t *out);
//////////////////////////////////////////////////////////////////////
// The following operations are only valid on a non-empty set:

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

@ -827,7 +827,7 @@ TypeObjectKey::unknownProperties()
}
HeapTypeSetKey
TypeObjectKey::property(jsid id, JSContext *maybecx /* = nullptr */)
TypeObjectKey::property(jsid id)
{
JS_ASSERT(!unknownProperties());
@ -837,22 +837,24 @@ TypeObjectKey::property(jsid id, JSContext *maybecx /* = nullptr */)
if (TypeObject *type = maybeType())
property.maybeTypes_ = type->maybeGetProperty(id);
return property;
}
void
TypeObjectKey::ensureTrackedProperty(JSContext *cx, jsid id)
{
#ifdef JS_ION
// If we are accessing a lazily defined property which actually exists in
// the VM and has not been instantiated yet, instantiate it now if we are
// on the main thread and able to do so.
if (maybecx && !property.maybeTypes() && !JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
JS_ASSERT(CurrentThreadCanAccessRuntime(maybecx->runtime()));
JSObject *singleton = isSingleObject() ? asSingleObject() : asTypeObject()->singleton;
if (singleton && singleton->isNative() && singleton->nativeLookupPure(id)) {
EnsureTrackPropertyTypes(maybecx, singleton, id);
if (TypeObject *type = maybeType())
property.maybeTypes_ = type->maybeGetProperty(id);
if (!JSID_IS_VOID(id) && !JSID_IS_EMPTY(id)) {
JS_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
if (JSObject *obj = singleton()) {
if (obj->isNative() && obj->nativeLookupPure(id))
EnsureTrackPropertyTypes(cx, obj, id);
}
}
#endif // JS_ION
return property;
}
bool

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

@ -1257,7 +1257,8 @@ struct TypeObjectKey
void watchStateChangeForInlinedCall(CompilerConstraintList *constraints);
void watchStateChangeForNewScriptTemplate(CompilerConstraintList *constraints);
void watchStateChangeForTypedArrayBuffer(CompilerConstraintList *constraints);
HeapTypeSetKey property(jsid id, JSContext *maybecx = nullptr);
HeapTypeSetKey property(jsid id);
void ensureTrackedProperty(JSContext *cx, jsid id);
TypeObject *maybeType();
};

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

@ -1275,11 +1275,41 @@ js::math_atanh(JSContext *cx, unsigned argc, Value *vp)
return math_function<math_atanh_impl>(cx, argc, vp);
}
/* Consistency wrapper for platform deviations in hypot() */
double
js::ecmaHypot(double x, double y)
{
#ifdef XP_WIN
/*
* Workaround MS hypot bug, where hypot(Infinity, NaN or Math.MIN_VALUE)
* is NaN, not Infinity.
*/
if (mozilla::IsInfinite(x) || mozilla::IsInfinite(y)) {
return mozilla::PositiveInfinity();
}
#endif
return hypot(x, y);
}
bool
js::math_hypot(JSContext *cx, unsigned argc, Value *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
// IonMonkey calls the system hypot function directly if two arguments are
// given. Do that here as well to get the same results.
if (args.length() == 2) {
double x, y;
if (!ToNumber(cx, args[0], &x))
return false;
if (!ToNumber(cx, args[1], &y))
return false;
double result = ecmaHypot(x, y);
args.rval().setNumber(result);
return true;
}
bool isInfinite = false;
bool isNaN = false;

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

@ -162,6 +162,9 @@ math_asinh(JSContext *cx, unsigned argc, js::Value *vp);
extern bool
math_atanh(JSContext *cx, unsigned argc, js::Value *vp);
extern double
ecmaHypot(double x, double y);
extern bool
math_hypot(JSContext *cx, unsigned argc, Value *vp);
@ -303,15 +306,6 @@ math_atanh_impl(MathCache *cache, double x);
extern double
math_atanh_uncached(double x);
// Math.hypot is disabled pending the resolution of spec issues (bug 896264).
#if 0
extern double
math_hypot_impl(double x, double y);
extern double
math_hypot_uncached(double x, double y);
#endif
extern double
math_trunc_impl(MathCache *cache, double x);

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

@ -1240,7 +1240,7 @@ skip-if(B2G) == 463952-1.html 463952-1-ref.html
== 468546-1.xhtml 468546-1-ref.xhtml
== 471356-1.html 471356-1-ref.html
== 471594-1.xhtml 471594-1-ref.html
== 472020-1a.xul 472020-1-ref.xul
fuzzy(255,15) == 472020-1a.xul 472020-1-ref.xul
fails == 472020-1b.xul 472020-1-ref.xul
fails == 472020-2.xul 472020-2-ref.xul
== 472500-1.xul 472500-1-ref.xul

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

@ -202,13 +202,24 @@ public class TabsTray extends TwoWayView
// Updates the selected position in the list so that it will be scrolled to the right place.
private void updateSelectedPosition() {
int selected = getPositionForTab(Tabs.getInstance().getSelectedTab());
for (int i=0; i < getCount(); i++)
TabsTray.this.setItemChecked(i, (i == selected));
if (selected != -1)
if (selected != -1) {
TabsTray.this.setSelection(selected);
}
updateSelectedStyle(selected);
}
/**
* Updates the selected/unselected style for the tabs.
*
* @param selected position of the selected tab
*/
private void updateSelectedStyle(int selected) {
for (int i = 0; i < getCount(); i++) {
TabsTray.this.setItemChecked(i, (i == selected));
}
}
public void clear() {
mTabs = null;
notifyDataSetChanged(); // Be sure to call this whenever mTabs changes.
@ -240,7 +251,9 @@ public class TabsTray extends TwoWayView
if (tab.isPrivate() == mIsPrivate && mTabs != null) {
mTabs.remove(tab);
notifyDataSetChanged(); // Be sure to call this whenever mTabs changes.
updateSelectedPosition();
int selected = getPositionForTab(Tabs.getInstance().getSelectedTab());
updateSelectedStyle(selected);
}
}

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

@ -147,7 +147,9 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
// the constraint string(s), treating space-separated words as separate constraints
if (!TextUtils.isEmpty(constraint)) {
String[] constraintWords = constraint.toString().split(" ");
for (int i = 0; i < constraintWords.length; i++) {
// Only create a filter query with a maximum of 10 constraint words
int constraintCount = Math.min(constraintWords.length, 10);
for (int i = 0; i < constraintCount; i++) {
selection = DBUtils.concatenateWhere(selection, "(" + Combined.URL + " LIKE ? OR " +
Combined.TITLE + " LIKE ?)");
String constraintWord = "%" + constraintWords[i] + "%";

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

@ -27,10 +27,6 @@ pref("general.useragent.compatMode.firefox", false);
// overrides by default, don't initialize UserAgentOverrides.jsm.
pref("general.useragent.site_specific_overrides", true);
// This pref controls whether or not to enable UA overrides in the
// product code that end users use (as opposed to testing code).
pref("general.useragent.enable_overrides", false);
pref("general.config.obscure_value", 13); // for MCD .cfg files
pref("general.warnOnAboutConfig", true);

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

@ -79,6 +79,10 @@ def build_dict(config, env=os.environ):
d['tests_enabled'] = substs.get('ENABLE_TESTS') == "1"
d['bin_suffix'] = substs.get('BIN_SUFFIX', '')
d['ogg'] = bool(substs.get('MOZ_OGG'))
d['webm'] = bool(substs.get('MOZ_WEBM'))
d['wave'] = bool(substs.get('MOZ_WAVE'))
return d

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

@ -41,12 +41,12 @@ groups.google.com: did not receive HSTS header
history.google.com: did not receive HSTS header
hostedtalkgadget.google.com: did not receive HSTS header
id.atlassian.com: did not receive HSTS header
iop.intuit.com: max-age too low: 86400
iop.intuit.com: could not connect to host
irccloud.com: did not receive HSTS header
jitsi.org: did not receive HSTS header
jottit.com: did not receive HSTS header
kiwiirc.com: max-age too low: 5256000
ledgerscope.net: max-age too low: 86400
ledgerscope.net: did not receive HSTS header
liberty.lavabit.com: did not receive HSTS header
lists.mayfirst.org: did not receive HSTS header
logentries.com: did not receive HSTS header
@ -102,7 +102,7 @@ www.gov.uk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR
www.greplin.com: could not connect to host
www.jitsi.org: did not receive HSTS header
www.lastpass.com: did not receive HSTS header
www.ledgerscope.net: max-age too low: 86400
www.ledgerscope.net: did not receive HSTS header
www.logentries.com: did not receive HSTS header
www.moneybookers.com: did not receive HSTS header
www.neonisi.com: could not connect to host

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

@ -8,7 +8,7 @@
/*****************************************************************************/
#include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1394273230288000);
const PRTime gPreloadListExpirationTime = INT64_C(1394881586089000);
class nsSTSPreload
{
@ -61,6 +61,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
{ "factor.cc", false },
{ "forum.linode.com", false },
{ "forum.quantifiedself.com", true },
{ "getlantern.org", true },
{ "grc.com", false },
{ "haste.ch", true },
{ "howrandom.org", true },

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

@ -10,93 +10,74 @@
* This is used for B2G content-processes.
*/
/* Frequently used syscalls specific to arm */
/* Architecture-specific frequently used syscalls */
#if defined(__arm__)
#define SECCOMP_WHITELIST_ADD_ARM_HIGH \
#define SECCOMP_WHITELIST_ARCH_HIGH \
ALLOW_SYSCALL(msgget), \
ALLOW_SYSCALL(recv), \
ALLOW_SYSCALL(mmap2),
#else
#define SECCOMP_WHITELIST_ADD_ARM_HIGH
#endif
/* Frequently used syscalls specific to i386 */
#if defined(__i386__)
#define SECCOMP_WHITELIST_ADD_i386_HIGH \
#elif defined(__i386__)
#define SECCOMP_WHITELIST_ARCH_HIGH \
ALLOW_SYSCALL(ipc), \
ALLOW_SYSCALL(mmap2),
#else
#define SECCOMP_WHITELIST_ADD_i386_HIGH
#endif
/* Frequently used syscalls specific to x86_64 */
#if defined(__x86_64__)
#define SECCOMP_WHITELIST_ADD_x86_64_HIGH \
#elif defined(__x86_64__)
#define SECCOMP_WHITELIST_ARCH_HIGH \
ALLOW_SYSCALL(msgget),
#else
#define SECCOMP_WHITELIST_ADD_x86_64_HIGH
#define SECCOMP_WHITELIST_ARCH_HIGH
#endif
/* Infrequently used syscalls specific to arm */
/* Architecture-specific infrequently used syscalls */
#if defined(__arm__)
#define SECCOMP_WHITELIST_ADD_ARM_LOW \
#define SECCOMP_WHITELIST_ARCH_LOW \
ALLOW_SYSCALL(_llseek), \
ALLOW_SYSCALL(getuid32), \
ALLOW_SYSCALL(sigreturn), \
ALLOW_SYSCALL(fcntl64),
#elif defined(__i386__)
#define SECCOMP_WHITELIST_ARCH_LOW \
ALLOW_SYSCALL(_llseek), \
ALLOW_SYSCALL(getuid32), \
ALLOW_SYSCALL(sigreturn), \
ALLOW_SYSCALL(fcntl64),
#else
#define SECCOMP_WHITELIST_ADD_ARM_LOW
#endif
/* Infrequently used syscalls specific to i386 */
#if defined(__i386__)
#define SECCOMP_WHITELIST_ADD_i386_LOW \
ALLOW_SYSCALL(_llseek), \
ALLOW_SYSCALL(getuid32), \
ALLOW_SYSCALL(sigreturn), \
ALLOW_SYSCALL(fcntl64),
#else
#define SECCOMP_WHITELIST_ADD_i386_LOW
#define SECCOMP_WHITELIST_ARCH_LOW
#endif
/* Architecture-specific very infrequently used syscalls */
#if defined(__arm__)
#define SECCOMP_WHITELIST_ADD_ARM_LAST \
#define SECCOMP_WHITELIST_ARCH_LAST \
ALLOW_ARM_SYSCALL(breakpoint), \
ALLOW_ARM_SYSCALL(cacheflush), \
ALLOW_ARM_SYSCALL(usr26), \
ALLOW_ARM_SYSCALL(usr32), \
ALLOW_ARM_SYSCALL(set_tls),
#else
#define SECCOMP_WHITELIST_ADD_ARM_LAST
#define SECCOMP_WHITELIST_ARCH_LAST
#endif
/* System calls used by the profiler */
#ifdef MOZ_PROFILING
#define PROFILING_WHITELIST_ADD \
#define SECCOMP_WHITELIST_PROFILING \
ALLOW_SYSCALL(sigaction), \
ALLOW_SYSCALL(tgkill),
#else
#define PROFILING_WHITELIST_ADD
#define SECCOMP_WHITELIST_PROFILING
#endif
/* Syscalls specific to arm that should eventually be removed */
/* Architecture-specific syscalls that should eventually be removed */
#if defined(__arm__)
#define SECCOMP_WHITELIST_REMOVE_ARM \
#define SECCOMP_WHITELIST_ARCH_TOREMOVE \
ALLOW_SYSCALL(fstat64), \
ALLOW_SYSCALL(stat64), \
ALLOW_SYSCALL(sigprocmask),
#elif defined(__i386__)
#define SECCOMP_WHITELIST_ARCH_TOREMOVE \
ALLOW_SYSCALL(fstat64), \
ALLOW_SYSCALL(stat64), \
ALLOW_SYSCALL(sigprocmask),
#else
#define SECCOMP_WHITELIST_REMOVE_ARM
#endif
/* Syscalls specific to i386 that should eventually be removed */
#if defined(__arm__)
#define SECCOMP_WHITELIST_REMOVE_i386 \
ALLOW_SYSCALL(fstat64), \
ALLOW_SYSCALL(stat64), \
ALLOW_SYSCALL(sigprocmask),
#else
#define SECCOMP_WHITELIST_REMOVE_i386
#define SECCOMP_WHITELIST_ARCH_TOREMOVE
#endif
/* Most used system calls should be at the top of the whitelist
@ -117,9 +98,7 @@
*/
#define SECCOMP_WHITELIST \
/* These are calls we're ok to allow */ \
SECCOMP_WHITELIST_ADD_ARM_HIGH \
SECCOMP_WHITELIST_ADD_i386_HIGH \
SECCOMP_WHITELIST_ADD_x86_64_HIGH \
SECCOMP_WHITELIST_ARCH_HIGH \
ALLOW_SYSCALL(gettimeofday), \
ALLOW_SYSCALL(read), \
ALLOW_SYSCALL(write), \
@ -144,13 +123,11 @@
ALLOW_SYSCALL(futex), \
ALLOW_SYSCALL(dup), \
ALLOW_SYSCALL(nanosleep), \
SECCOMP_WHITELIST_ADD_ARM_LOW \
SECCOMP_WHITELIST_ADD_i386_LOW \
SECCOMP_WHITELIST_ARCH_LOW \
/* Must remove all of the following in the future, when no longer used */ \
/* open() is for some legacy APIs such as font loading. */ \
/* See bug 906996 for removing unlink(). */ \
SECCOMP_WHITELIST_REMOVE_ARM \
SECCOMP_WHITELIST_REMOVE_i386 \
SECCOMP_WHITELIST_ARCH_TOREMOVE \
ALLOW_SYSCALL(open), \
ALLOW_SYSCALL(prctl), \
ALLOW_SYSCALL(access), \
@ -160,9 +137,9 @@
ALLOW_SYSCALL(getpriority), \
ALLOW_SYSCALL(setpriority), \
ALLOW_SYSCALL(sched_setscheduler), \
PROFILING_WHITELIST_ADD \
SECCOMP_WHITELIST_PROFILING \
/* Always last and always OK calls */ \
SECCOMP_WHITELIST_ADD_ARM_LAST \
SECCOMP_WHITELIST_ARCH_LAST \
/* restart_syscall is called internally, generally when debugging */ \
ALLOW_SYSCALL(restart_syscall), \
ALLOW_SYSCALL(exit_group), \

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

@ -4,6 +4,7 @@
[browser_bug295977_autoscroll_overflow.js]
[browser_bug594509.js]
[browser_default_image_filename.js]
[browser_findbar.js]
[browser_input_file_tooltips.js]
[browser_keyevents_during_autoscrolling.js]
[browser_save_resend_postdata.js]

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

@ -0,0 +1,91 @@
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/commonjs/sdk/core/promise.js");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
Components.utils.import("resource://gre/modules/Timer.jsm", this);
let gTabs = [];
registerCleanupFunction(function() {
for (let tab of gTabs) {
if (!tab)
continue;
gBrowser.removeTab(tab);
}
});
function test() {
waitForExplicitFinish();
Task.spawn(function() {
info("Check correct 'Phrase not found' on new tab");
// Create a tab to run the test.
yield promiseAboutHomeLoad();
// Search for the first word.
yield promiseFindFinished("--- THIS SHOULD NEVER MATCH ---", false);
let findbar = gBrowser.getFindBar();
is(findbar._findStatusDesc.textContent, findbar._notFoundStr,
"Findbar status text should be 'Phrase not found'");
// Create second tab.
yield promiseAboutHomeLoad();
// Search for a string that WILL be found, with 'Highlight All' on
yield promiseFindFinished("s", true);
ok(!gBrowser.getFindBar()._findStatusDesc.textContent,
"Findbar status should be empty");
finish();
});
}
function promiseAboutHomeLoad() {
let deferred = Promise.defer();
let tab = gBrowser.selectedTab = gBrowser.addTab("about:home");
gTabs.push(tab);
let browser = gBrowser.selectedBrowser;
browser.addEventListener("load", function listener() {
if (browser.currentURI.spec == "about:blank")
return;
info("Page loaded: " + browser.currentURI.spec);
browser.removeEventListener("load", listener, true);
deferred.resolve();
}, true);
return deferred.promise;
}
function promiseFindFinished(searchText, highlightOn) {
let deferred = Promise.defer();
let findbar = gBrowser.getFindBar();
findbar.startFind(findbar.FIND_NORMAL);
let highlightElement = findbar.getElement("highlight");
if (highlightElement.checked != highlightOn)
highlightElement.click();
executeSoon(() => {
findbar._findField.value = searchText;
let resultListener;
let findTimeout = setTimeout(() => foundOrTimedout(true), 2000);
let foundOrTimedout = function(timedOut) {
if (timedOut)
info("Result listener not called, timeout reached.");
clearTimeout(findTimeout);
findbar.browser.finder.removeResultListener(resultListener);
deferred.resolve();
}
resultListener = {
onFindResult: foundOrTimedout
};
findbar.browser.finder.addResultListener(resultListener);
findbar._find();
});
return deferred.promise;
}

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

@ -863,7 +863,7 @@
// Only search on input if we don't have a last-failed string,
// or if the current search string doesn't start with it.
if (this._findFailedString == null ||
if (!this._findFailedString ||
!val.startsWith(this._findFailedString))
{
this._enableFindButtons(val);

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

@ -35,7 +35,8 @@ Finder.prototype = {
this._listeners = this._listeners.filter(l => l != aListener);
},
_notify: function (aResult, aFindBackwards, aDrawOutline) {
_notify: function (aSearchString, aResult, aFindBackwards, aDrawOutline) {
this._searchString = aSearchString;
this._outlineLink(aDrawOutline);
let foundLink = this._fastFind.foundLink;
@ -60,7 +61,7 @@ Finder.prototype = {
},
get searchString() {
return this._fastFind.searchString;
return this._searchString;
},
set caseSensitive(aSensitive) {
@ -76,7 +77,8 @@ Finder.prototype = {
*/
fastFind: function (aSearchString, aLinksOnly, aDrawOutline) {
let result = this._fastFind.find(aSearchString, aLinksOnly);
this._notify(result, false, aDrawOutline);
let searchString = this._fastFind.searchString;
this._notify(searchString, result, false, aDrawOutline);
},
/**
@ -90,16 +92,17 @@ Finder.prototype = {
*/
findAgain: function (aFindBackwards, aLinksOnly, aDrawOutline) {
let result = this._fastFind.findAgain(aFindBackwards, aLinksOnly);
this._notify(result, aFindBackwards, aDrawOutline);
let searchString = this._fastFind.searchString;
this._notify(searchString, result, aFindBackwards, aDrawOutline);
},
highlight: function (aHighlight, aWord) {
this._searchString = aWord;
let found = this._highlight(aHighlight, aWord, null);
if (found)
this._notify(Ci.nsITypeAheadFind.FIND_FOUND, false, false);
else
this._notify(Ci.nsITypeAheadFind.FIND_NOTFOUND, false, false);
if (aHighlight) {
let result = found ? Ci.nsITypeAheadFind.FIND_FOUND
: Ci.nsITypeAheadFind.FIND_NOTFOUND;
this._notify(aWord, result, false, false);
}
},
enableSelection: function() {
@ -283,7 +286,7 @@ Finder.prototype = {
}
}
//Removing the highlighting always succeeds, so return true.
// Removing the highlighting always succeeds, so return true.
found = true;
}