зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
MozReview-Commit-ID: ET0qKXDqQXD
This commit is contained in:
Коммит
aa13902dde
|
@ -35,7 +35,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// Hacky stuffs
|
||||
|
||||
// This is the hack needed for searchbar work outside of browser.
|
||||
// This is the hacks needed to use a searchbar without browser.js.
|
||||
function getBrowser()
|
||||
{
|
||||
return {
|
||||
|
@ -43,6 +43,10 @@
|
|||
};
|
||||
}
|
||||
|
||||
var BrowserSearch = {
|
||||
updateOpenSearchBadge: function() {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
|
|
|
@ -62,13 +62,16 @@
|
|||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
// This is the hack needed for searchbar work outside of browser.
|
||||
// This is the hacks needed to use a searchbar without browser.js.
|
||||
function getBrowser()
|
||||
{
|
||||
return {
|
||||
mCurrentBrowser: { engines: new Array() }
|
||||
};
|
||||
}
|
||||
var BrowserSearch = {
|
||||
updateOpenSearchBadge: function() {}
|
||||
};
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
|
|
|
@ -3409,9 +3409,6 @@ const DOMLinkHandler = {
|
|||
|
||||
const BrowserSearch = {
|
||||
addEngine: function(browser, engine, uri) {
|
||||
if (!this.searchBar)
|
||||
return;
|
||||
|
||||
// Check to see whether we've already added an engine with this title
|
||||
if (browser.engines) {
|
||||
if (browser.engines.some(e => e.title == engine.title))
|
||||
|
@ -3449,11 +3446,7 @@ const BrowserSearch = {
|
|||
*/
|
||||
updateOpenSearchBadge: function() {
|
||||
var searchBar = this.searchBar;
|
||||
|
||||
// The search bar binding might not be applied even though the element is
|
||||
// in the document (e.g. when the navigation toolbar is hidden), so check
|
||||
// for .textbox specifically.
|
||||
if (!searchBar || !searchBar.textbox)
|
||||
if (!searchBar)
|
||||
return;
|
||||
|
||||
var engines = gBrowser.selectedBrowser.engines;
|
||||
|
|
|
@ -253,7 +253,7 @@ const CustomizableWidgets = [
|
|||
let elementCount = tabsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
tabsFragment.children[elementCount].classList.add("subviewbutton");
|
||||
tabsFragment.children[elementCount].classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedTabs.appendChild(tabsFragment);
|
||||
|
||||
|
@ -263,7 +263,7 @@ const CustomizableWidgets = [
|
|||
elementCount = windowsFragment.childElementCount;
|
||||
separator.hidden = !elementCount;
|
||||
while (--elementCount >= 0) {
|
||||
windowsFragment.children[elementCount].classList.add("subviewbutton");
|
||||
windowsFragment.children[elementCount].classList.add("subviewbutton", "cui-withicon");
|
||||
}
|
||||
recentlyClosedWindows.appendChild(windowsFragment);
|
||||
},
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
if (Components.isSuccessCode(aStatus)) {
|
||||
// Refresh the display (updating icon, etc)
|
||||
this.updateDisplay();
|
||||
BrowserSearch.updateOpenSearchBadge();
|
||||
} else {
|
||||
Components.utils.reportError("Cannot initialize search service, bailing out: " + aStatus);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
%include ../../shared/customizableui/panelUIOverlay.inc.css
|
||||
|
||||
:root {
|
||||
--panel-separator-color: hsla(210,4%,10%,.15);
|
||||
}
|
||||
|
||||
.panel-subviews {
|
||||
background-color: hsla(0,0%,100%,.97);
|
||||
}
|
||||
|
@ -73,4 +77,4 @@ menu.subviewbutton > .menu-right > image {
|
|||
|
||||
toolbarpaletteitem[place="palette"] > .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
padding: 3px 1px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
%include ../browser.inc
|
||||
|
||||
:root {
|
||||
--panel-separator-color: ThreeDShadow;
|
||||
--panel-ui-exit-subview-gutter-width: 38px;
|
||||
}
|
||||
|
||||
|
@ -1153,7 +1154,8 @@ menuitem.panel-subview-footer@menuStateActive@,
|
|||
.cui-widget-panelview menuseparator {
|
||||
-moz-appearance: none;
|
||||
min-height: 0;
|
||||
border-top: 1px solid hsla(210,4%,10%,.15);
|
||||
border-top: 1px solid var(--panel-separator-color);
|
||||
border-bottom: none;
|
||||
margin: 6px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -1346,7 +1348,7 @@ toolbarpaletteitem[haswideitem][place="panel"] + toolbarpaletteitem[haswideitem]
|
|||
margin: .5em 0;
|
||||
width: 1px;
|
||||
height: auto;
|
||||
background: hsla(210,4%,10%,.15);
|
||||
background: var(--panel-separator-color);
|
||||
transition-property: margin;
|
||||
transition-duration: 10ms;
|
||||
transition-timing-function: ease;
|
||||
|
|
|
@ -301,13 +301,14 @@ StyleEditorUI.prototype = {
|
|||
|
||||
let sources = yield styleSheet.getOriginalSources();
|
||||
if (sources && sources.length) {
|
||||
let parentEditorName = editor.friendlyName;
|
||||
this._removeStyleSheetEditor(editor);
|
||||
|
||||
for (let source of sources) {
|
||||
// set so the first sheet will be selected, even if it's a source
|
||||
source.styleSheetIndex = styleSheet.styleSheetIndex;
|
||||
source.relatedStyleSheet = styleSheet;
|
||||
|
||||
source.relatedEditorName = parentEditorName;
|
||||
yield this._addStyleSheetEditor(source);
|
||||
}
|
||||
}
|
||||
|
@ -803,7 +804,7 @@ StyleEditorUI.prototype = {
|
|||
}
|
||||
|
||||
let ruleCount = editor.styleSheet.ruleCount;
|
||||
if (editor.styleSheet.relatedStyleSheet && editor.linkedCSSFile) {
|
||||
if (editor.styleSheet.relatedStyleSheet) {
|
||||
ruleCount = editor.styleSheet.relatedStyleSheet.ruleCount;
|
||||
}
|
||||
if (ruleCount === undefined) {
|
||||
|
@ -828,11 +829,13 @@ StyleEditorUI.prototype = {
|
|||
label.setAttribute("tooltiptext", editor.styleSheet.href);
|
||||
}
|
||||
|
||||
let linkedCSSFile = "";
|
||||
let linkedCSSSource = "";
|
||||
if (editor.linkedCSSFile) {
|
||||
linkedCSSFile = OS.Path.basename(editor.linkedCSSFile);
|
||||
linkedCSSSource = OS.Path.basename(editor.linkedCSSFile);
|
||||
} else if (editor.styleSheet.relatedEditorName) {
|
||||
linkedCSSSource = editor.styleSheet.relatedEditorName;
|
||||
}
|
||||
text(summary, ".stylesheet-linked-file", linkedCSSFile);
|
||||
text(summary, ".stylesheet-linked-file", linkedCSSSource);
|
||||
text(summary, ".stylesheet-title", editor.styleSheet.title || "");
|
||||
text(summary, ".stylesheet-rule-count",
|
||||
PluralForm.get(ruleCount,
|
||||
|
|
|
@ -222,6 +222,9 @@ StyleSheetEditor.prototype = {
|
|||
}
|
||||
|
||||
let relatedSheet = this.styleSheet.relatedStyleSheet;
|
||||
if (!relatedSheet || !relatedSheet.href) {
|
||||
return;
|
||||
}
|
||||
|
||||
let path;
|
||||
let href = removeQuery(relatedSheet.href);
|
||||
|
|
|
@ -40,6 +40,7 @@ support-files =
|
|||
sourcemap-sass/media-rules.scss
|
||||
sourcemap-styl/test-stylus.styl
|
||||
sourcemaps.html
|
||||
sourcemaps-inline.html
|
||||
sourcemaps-large.html
|
||||
sourcemaps-watching.html
|
||||
test_private.css
|
||||
|
@ -84,6 +85,7 @@ skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
|
|||
[browser_styleeditor_sv_resize.js]
|
||||
[browser_styleeditor_selectstylesheet.js]
|
||||
[browser_styleeditor_sourcemaps.js]
|
||||
[browser_styleeditor_sourcemaps_inline.js]
|
||||
[browser_styleeditor_sourcemap_large.js]
|
||||
[browser_styleeditor_sourcemap_watching.js]
|
||||
[browser_styleeditor_sync.js]
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// https rather than chrome to improve coverage
|
||||
const TESTCASE_URI = TEST_BASE_HTTPS + "sourcemaps-inline.html";
|
||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||
|
||||
const sassContent = `body {
|
||||
background-color: black;
|
||||
& > h1 {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const cssContent = `body {
|
||||
background-color: black;
|
||||
}
|
||||
body > h1 {
|
||||
color: white;
|
||||
}
|
||||
` +
|
||||
"/*# sourceMappingURL=data:application/json;base64,ewoidmVyc2lvbiI6IDMsCiJtY" +
|
||||
"XBwaW5ncyI6ICJBQUFBLElBQUs7RUFDSCxnQkFBZ0IsRUFBRSxLQUFLO0VBQ3ZCLFNBQU87SUFD" +
|
||||
"TCxLQUFLLEVBQUUsS0FBSyIsCiJzb3VyY2VzIjogWyJ0ZXN0LnNjc3MiXSwKInNvdXJjZXNDb25" +
|
||||
"0ZW50IjogWyJib2R5IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7XG4gICYgPiBoMSB7XG" +
|
||||
"4gICAgY29sb3I6IHdoaXRlO1xuICB9XG59XG4iXSwKIm5hbWVzIjogW10sCiJmaWxlIjogInRlc" +
|
||||
"3QuY3NzIgp9Cg== */";
|
||||
|
||||
add_task(function* () {
|
||||
let {ui} = yield openStyleEditorForURL(TESTCASE_URI);
|
||||
|
||||
is(ui.editors.length, 1,
|
||||
"correct number of editors with source maps enabled");
|
||||
|
||||
yield testEditor(ui.editors[0], "test.scss", sassContent);
|
||||
|
||||
// Test disabling original sources
|
||||
yield togglePref(ui);
|
||||
|
||||
is(ui.editors.length, 1, "correct number of editors after pref toggled");
|
||||
|
||||
// Test CSS editors
|
||||
yield testEditor(ui.editors[0], "<inline style sheet #1>", cssContent);
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
});
|
||||
|
||||
function* testEditor(editor, expectedName, expectedText) {
|
||||
let name = getStylesheetNameFor(editor);
|
||||
is(expectedName, name, name + " editor name is correct");
|
||||
|
||||
yield openEditor(editor);
|
||||
let text = editor.sourceEditor.getText();
|
||||
is(text, expectedText, name + " editor contains expected text");
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
|
||||
function togglePref(UI) {
|
||||
let editorsPromise = UI.once("stylesheets-reset");
|
||||
let selectedPromise = UI.once("editor-selected");
|
||||
|
||||
Services.prefs.setBoolPref(PREF, false);
|
||||
|
||||
return promise.all([editorsPromise, selectedPromise]);
|
||||
}
|
||||
|
||||
function openEditor(editor) {
|
||||
getLinkFor(editor).click();
|
||||
|
||||
return editor.getSourceEditor();
|
||||
}
|
||||
|
||||
function getLinkFor(editor) {
|
||||
return editor.summary.querySelector(".stylesheet-name");
|
||||
}
|
||||
|
||||
function getStylesheetNameFor(editor) {
|
||||
return editor.summary.querySelector(".stylesheet-name > label")
|
||||
.getAttribute("value");
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>testcase for testing CSS source maps in inline style</title>
|
||||
<style type="text/css">body {
|
||||
background-color: black;
|
||||
}
|
||||
body > h1 {
|
||||
color: white;
|
||||
}
|
||||
/*# sourceMappingURL=data:application/json;base64,ewoidmVyc2lvbiI6IDMsCiJtYXBwaW5ncyI6ICJBQUFBLElBQUs7RUFDSCxnQkFBZ0IsRUFBRSxLQUFLO0VBQ3ZCLFNBQU87SUFDTCxLQUFLLEVBQUUsS0FBSyIsCiJzb3VyY2VzIjogWyJ0ZXN0LnNjc3MiXSwKInNvdXJjZXNDb250ZW50IjogWyJib2R5IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7XG4gICYgPiBoMSB7XG4gICAgY29sb3I6IHdoaXRlO1xuICB9XG59XG4iXSwKIm5hbWVzIjogW10sCiJmaWxlIjogInRlc3QuY3NzIgp9Cg== */</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Source maps testcase</div>
|
||||
</body>
|
||||
</html>
|
|
@ -7,7 +7,7 @@
|
|||
// Check that, even though the AnimationPlayerActor only sends the bits of its
|
||||
// state that change, the front reconstructs the whole state everytime.
|
||||
|
||||
add_task(function*() {
|
||||
add_task(function* () {
|
||||
let {client, walker, animations} =
|
||||
yield initAnimationsFrontForUrl(MAIN_DOMAIN + "animation.html");
|
||||
|
||||
|
@ -29,9 +29,9 @@ function* playerHasCompleteStateAtAllTimes(walker, animations) {
|
|||
// contains all keys.
|
||||
// Normally, only the currentTime will have changed in between 2 calls.
|
||||
for (let i = 0; i < 10; i++) {
|
||||
let state = yield player.getCurrentState();
|
||||
yield player.refreshState();
|
||||
keys.forEach(key => {
|
||||
ok(typeof state[key] !== "undefined",
|
||||
ok(typeof player.state[key] !== "undefined",
|
||||
"The state retrieved has key " + key);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -69,8 +69,6 @@ public class AppConstants {
|
|||
public static final boolean preJBMR1 = MAX_SDK_VERSION < 17 || (MIN_SDK_VERSION < 17 && Build.VERSION.SDK_INT < 17);
|
||||
public static final boolean preJB = MAX_SDK_VERSION < 16 || (MIN_SDK_VERSION < 16 && Build.VERSION.SDK_INT < 16);
|
||||
public static final boolean preICS = MAX_SDK_VERSION < 14 || (MIN_SDK_VERSION < 14 && Build.VERSION.SDK_INT < 14);
|
||||
public static final boolean preHCMR2 = MAX_SDK_VERSION < 13 || (MIN_SDK_VERSION < 13 && Build.VERSION.SDK_INT < 13);
|
||||
public static final boolean preHCMR1 = MAX_SDK_VERSION < 12 || (MIN_SDK_VERSION < 12 && Build.VERSION.SDK_INT < 12);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,199 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.animation;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.RectF;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Transformation;
|
||||
|
||||
class AnimatorProxy {
|
||||
private static final WeakHashMap<View, AnimatorProxy> PROXIES =
|
||||
new WeakHashMap<View, AnimatorProxy>();
|
||||
|
||||
private static interface AnimatorProxyImpl {
|
||||
public float getAlpha();
|
||||
public void setAlpha(float alpha);
|
||||
|
||||
public float getTranslationX();
|
||||
public void setTranslationX(float translationX);
|
||||
|
||||
public float getTranslationY();
|
||||
public void setTranslationY(float translationY);
|
||||
|
||||
public View getView();
|
||||
}
|
||||
|
||||
private final AnimatorProxyImpl mImpl;
|
||||
|
||||
private AnimatorProxy(AnimatorProxyImpl impl) {
|
||||
mImpl = impl;
|
||||
}
|
||||
|
||||
public static AnimatorProxy create(View view) {
|
||||
AnimatorProxy proxy = PROXIES.get(view);
|
||||
// If the view's animation proxy has been overridden from somewhere else, we need to
|
||||
// create a new AnimatorProxy for the view.
|
||||
if (proxy == null) {
|
||||
AnimatorProxyImpl impl = (new AnimatorProxyPostHC(view));
|
||||
|
||||
proxy = new AnimatorProxy(impl);
|
||||
PROXIES.put(view, proxy);
|
||||
}
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
View view = mImpl.getView();
|
||||
if (view != null)
|
||||
return view.getWidth();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
View view = mImpl.getView();
|
||||
if (view != null) {
|
||||
ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
lp.width = width;
|
||||
view.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
View view = mImpl.getView();
|
||||
if (view != null)
|
||||
return view.getHeight();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
View view = mImpl.getView();
|
||||
if (view != null) {
|
||||
ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
lp.height = height;
|
||||
view.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
public int getScrollX() {
|
||||
View view = mImpl.getView();
|
||||
if (view != null)
|
||||
return view.getScrollX();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getScrollY() {
|
||||
View view = mImpl.getView();
|
||||
if (view != null)
|
||||
return view.getScrollY();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void scrollTo(int scrollX, int scrollY) {
|
||||
View view = mImpl.getView();
|
||||
if (view != null)
|
||||
view.scrollTo(scrollX, scrollY);
|
||||
}
|
||||
|
||||
public float getAlpha() {
|
||||
return mImpl.getAlpha();
|
||||
}
|
||||
|
||||
public void setAlpha(float alpha) {
|
||||
mImpl.setAlpha(alpha);
|
||||
}
|
||||
|
||||
public float getTranslationX() {
|
||||
return mImpl.getTranslationX();
|
||||
}
|
||||
|
||||
public void setTranslationX(float translationX) {
|
||||
mImpl.setTranslationX(translationX);
|
||||
}
|
||||
|
||||
public float getTranslationY() {
|
||||
return mImpl.getTranslationY();
|
||||
}
|
||||
|
||||
public void setTranslationY(float translationY) {
|
||||
mImpl.setTranslationY(translationY);
|
||||
}
|
||||
|
||||
private static class AnimatorProxyPostHC implements AnimatorProxyImpl {
|
||||
private final WeakReference<View> mViewRef;
|
||||
|
||||
public AnimatorProxyPostHC(View view) {
|
||||
mViewRef = new WeakReference<View>(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAlpha() {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
return view.getAlpha();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(float alpha) {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
view.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationX() {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
return view.getTranslationX();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslationX(float translationX) {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
view.setTranslationX(translationX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationY() {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
return view.getTranslationY();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslationY(float translationY) {
|
||||
View view = mViewRef.get();
|
||||
if (view != null)
|
||||
view.setTranslationY(translationY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
return mViewRef.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@ public class PropertyAnimator implements Runnable {
|
|||
|
||||
private class ElementHolder {
|
||||
View view;
|
||||
AnimatorProxy proxy;
|
||||
Property property;
|
||||
float from;
|
||||
float to;
|
||||
|
@ -76,7 +75,6 @@ public class PropertyAnimator implements Runnable {
|
|||
ElementHolder element = new ElementHolder();
|
||||
|
||||
element.view = view;
|
||||
element.proxy = AnimatorProxy.create(view);
|
||||
element.property = property;
|
||||
element.to = to;
|
||||
|
||||
|
@ -128,19 +126,19 @@ public class PropertyAnimator implements Runnable {
|
|||
// Fix the from value based on current position and property
|
||||
for (ElementHolder element : mElementsList) {
|
||||
if (element.property == Property.ALPHA)
|
||||
element.from = element.proxy.getAlpha();
|
||||
element.from = ViewHelper.getAlpha(element.view);
|
||||
else if (element.property == Property.TRANSLATION_Y)
|
||||
element.from = element.proxy.getTranslationY();
|
||||
element.from = ViewHelper.getTranslationY(element.view);
|
||||
else if (element.property == Property.TRANSLATION_X)
|
||||
element.from = element.proxy.getTranslationX();
|
||||
element.from = ViewHelper.getTranslationX(element.view);
|
||||
else if (element.property == Property.SCROLL_Y)
|
||||
element.from = element.proxy.getScrollY();
|
||||
element.from = ViewHelper.getScrollY(element.view);
|
||||
else if (element.property == Property.SCROLL_X)
|
||||
element.from = element.proxy.getScrollX();
|
||||
element.from = ViewHelper.getScrollX(element.view);
|
||||
else if (element.property == Property.WIDTH)
|
||||
element.from = element.proxy.getWidth();
|
||||
element.from = ViewHelper.getWidth(element.view);
|
||||
else if (element.property == Property.HEIGHT)
|
||||
element.from = element.proxy.getHeight();
|
||||
element.from = ViewHelper.getHeight(element.view);
|
||||
|
||||
ViewCompat.setHasTransientState(element.view, true);
|
||||
|
||||
|
@ -254,19 +252,19 @@ public class PropertyAnimator implements Runnable {
|
|||
return;
|
||||
|
||||
if (element.property == Property.ALPHA)
|
||||
element.proxy.setAlpha(delta);
|
||||
ViewHelper.setAlpha(element.view, delta);
|
||||
else if (element.property == Property.TRANSLATION_Y)
|
||||
element.proxy.setTranslationY(delta);
|
||||
ViewHelper.setTranslationY(element.view, delta);
|
||||
else if (element.property == Property.TRANSLATION_X)
|
||||
element.proxy.setTranslationX(delta);
|
||||
ViewHelper.setTranslationX(element.view, delta);
|
||||
else if (element.property == Property.SCROLL_Y)
|
||||
element.proxy.scrollTo(element.proxy.getScrollX(), (int) delta);
|
||||
ViewHelper.scrollTo(element.view, ViewHelper.getScrollX(element.view), (int) delta);
|
||||
else if (element.property == Property.SCROLL_X)
|
||||
element.proxy.scrollTo((int) delta, element.proxy.getScrollY());
|
||||
ViewHelper.scrollTo(element.view, (int) delta, ViewHelper.getScrollY(element.view));
|
||||
else if (element.property == Property.WIDTH)
|
||||
element.proxy.setWidth((int) delta);
|
||||
ViewHelper.setWidth(element.view, (int) delta);
|
||||
else if (element.property == Property.HEIGHT)
|
||||
element.proxy.setHeight((int) delta);
|
||||
ViewHelper.setHeight(element.view, (int) delta);
|
||||
}
|
||||
|
||||
private static abstract class FramePoster {
|
||||
|
|
|
@ -5,58 +5,105 @@
|
|||
package org.mozilla.gecko.animation;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public final class ViewHelper {
|
||||
private ViewHelper() {
|
||||
}
|
||||
|
||||
public static float getTranslationX(View view) {
|
||||
AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
return proxy.getTranslationX();
|
||||
if (view != null) {
|
||||
return view.getTranslationX();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void setTranslationX(View view, float translationX) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
proxy.setTranslationX(translationX);
|
||||
if (view != null) {
|
||||
view.setTranslationX(translationX);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getTranslationY(View view) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
return proxy.getTranslationY();
|
||||
if (view != null) {
|
||||
return view.getTranslationY();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void setTranslationY(View view, float translationY) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
proxy.setTranslationY(translationY);
|
||||
if (view != null) {
|
||||
view.setTranslationY(translationY);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getAlpha(View view) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
return proxy.getAlpha();
|
||||
if (view != null) {
|
||||
return view.getAlpha();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static void setAlpha(View view, float alpha) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
proxy.setAlpha(alpha);
|
||||
if (view != null) {
|
||||
view.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getWidth(View view) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
return proxy.getWidth();
|
||||
if (view != null) {
|
||||
return view.getWidth();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void setWidth(View view, int width) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
proxy.setWidth(width);
|
||||
if (view != null) {
|
||||
ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
lp.width = width;
|
||||
view.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getHeight(View view) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
return proxy.getHeight();
|
||||
if (view != null) {
|
||||
return view.getHeight();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void setHeight(View view, int height) {
|
||||
final AnimatorProxy proxy = AnimatorProxy.create(view);
|
||||
proxy.setHeight(height);
|
||||
if (view != null) {
|
||||
ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
lp.height = height;
|
||||
view.setLayoutParams(lp);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getScrollX(View view) {
|
||||
if (view != null) {
|
||||
return view.getScrollX();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int getScrollY(View view) {
|
||||
if (view != null) {
|
||||
return view.getScrollY();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void scrollTo(View view, int scrollX, int scrollY) {
|
||||
if (view != null) {
|
||||
view.scrollTo(scrollX, scrollY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -897,7 +897,10 @@ public class Distribution {
|
|||
}
|
||||
}
|
||||
|
||||
return new String[] { baseDirectory };
|
||||
return new String[] {
|
||||
baseDirectory + "/default",
|
||||
baseDirectory
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
|
@ -305,10 +304,6 @@ class JavaPanZoomController
|
|||
/** This function MUST be called on the UI thread */
|
||||
@Override
|
||||
public boolean onKeyEvent(KeyEvent event) {
|
||||
if (Versions.preHCMR1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD
|
||||
&& event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
|
||||
|
@ -328,10 +323,6 @@ class JavaPanZoomController
|
|||
/** This function MUST be called on the UI thread */
|
||||
@Override
|
||||
public boolean onMotionEvent(MotionEvent event) {
|
||||
if (Versions.preHCMR1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.getSource() & InputDevice.SOURCE_CLASS_MASK) {
|
||||
case InputDevice.SOURCE_CLASS_POINTER:
|
||||
switch (event.getAction() & MotionEvent.ACTION_MASK) {
|
||||
|
|
|
@ -461,6 +461,17 @@ public class GeckoMenu extends ListView
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Close the menu if it is open and the hardware menu key is pressed.
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU && isShown()) {
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShortcutKey(int keyCode, KeyEvent event) {
|
||||
return true;
|
||||
|
|
|
@ -18,14 +18,6 @@ import android.view.ViewConfiguration;
|
|||
public final class HardwareUtils {
|
||||
private static final String LOGTAG = "GeckoHardwareUtils";
|
||||
|
||||
// Minimum memory threshold for a device to be considered
|
||||
// a low memory platform (see isLowMemoryPlatform). This value
|
||||
// has be in sync with Gecko's equivalent threshold (defined in
|
||||
// xpcom/base/nsMemoryImpl.cpp) and should only be used in cases
|
||||
// where we can't depend on Gecko to be up and running e.g. show/hide
|
||||
// reading list capabilities in HomePager.
|
||||
private static final int LOW_MEMORY_THRESHOLD_MB = 384;
|
||||
|
||||
private static final boolean IS_AMAZON_DEVICE = Build.MANUFACTURER.equalsIgnoreCase("Amazon");
|
||||
public static final boolean IS_KINDLE_DEVICE = IS_AMAZON_DEVICE &&
|
||||
(Build.MODEL.equals("Kindle Fire") ||
|
||||
|
@ -86,19 +78,6 @@ public final class HardwareUtils {
|
|||
return SysInfo.getMemSize();
|
||||
}
|
||||
|
||||
public static boolean isLowMemoryPlatform() {
|
||||
final int memSize = getMemSize();
|
||||
|
||||
// Fallback to false if we fail to read meminfo
|
||||
// for some reason.
|
||||
if (memSize == 0) {
|
||||
Log.w(LOGTAG, "Could not compute system memory. Falling back to isLowMemoryPlatform = false.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return memSize < LOW_MEMORY_THRESHOLD_MB;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false if the current system is not supported (e.g. APK/system ABI mismatch).
|
||||
*/
|
||||
|
|
|
@ -219,13 +219,17 @@
|
|||
<!ENTITY pref_cookies_not_accept_foreign "Enabled, excluding 3rd party">
|
||||
<!ENTITY pref_cookies_disabled "Disabled">
|
||||
|
||||
<!ENTITY pref_category_data_saver "Data saver">
|
||||
<!ENTITY pref_category_media "Media">
|
||||
<!ENTITY pref_category_developer_tools "Developer tools">
|
||||
|
||||
<!ENTITY pref_tap_to_load_images_title2 "Show images">
|
||||
<!ENTITY pref_tap_to_load_images_enabled "Always">
|
||||
<!ENTITY pref_tap_to_load_images_data "Only over Wi-Fi">
|
||||
<!ENTITY pref_tap_to_load_images_disabled2 "Blocked">
|
||||
|
||||
<!ENTITY pref_show_web_fonts "Show Web fonts">
|
||||
<!ENTITY pref_show_web_fonts_summary "Hide to use default fonts and reduce website load times">
|
||||
<!ENTITY pref_show_web_fonts "Show web fonts">
|
||||
<!ENTITY pref_show_web_fonts_summary2 "Download remote fonts when loading a page">
|
||||
|
||||
<!ENTITY pref_tracking_protection_title2 "Tracking Protection">
|
||||
<!ENTITY pref_tracking_protection_summary3 "Enabled in Private Browsing">
|
||||
|
|
|
@ -196,7 +196,6 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
|||
'AlarmReceiver.java',
|
||||
'AndroidGamepadManager.java',
|
||||
'animation/AnimationUtils.java',
|
||||
'animation/AnimatorProxy.java',
|
||||
'animation/HeightChangeAnimation.java',
|
||||
'animation/PropertyAnimator.java',
|
||||
'animation/Rotate3DAnimation.java',
|
||||
|
|
|
@ -32,42 +32,52 @@
|
|||
android:entryValues="@array/pref_restore_values"
|
||||
android:persistent="true" />
|
||||
|
||||
<ListPreference android:key="browser.image_blocking"
|
||||
android:title="@string/pref_tap_to_load_images_title2"
|
||||
android:entries="@array/pref_browser_image_blocking_entries"
|
||||
android:entryValues="@array/pref_browser_image_blocking_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<CheckBoxPreference android:key="browser.display.use_document_fonts"
|
||||
android:title="@string/pref_show_web_fonts"
|
||||
android:summary="@string/pref_show_web_fonts_summary"/>
|
||||
|
||||
<ListPreference android:key="plugin.enable"
|
||||
android:title="@string/pref_plugins"
|
||||
android:entries="@array/pref_plugins_entries"
|
||||
android:entryValues="@array/pref_plugins_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<SwitchPreference android:key="media.autoplay.enabled"
|
||||
android:title="@string/pref_media_autoplay_enabled"
|
||||
android:summary="@string/pref_media_autoplay_enabled_summary" />
|
||||
|
||||
<ListPreference android:key="browser.menu.showCharacterEncoding"
|
||||
android:title="@string/pref_char_encoding"
|
||||
android:entries="@array/pref_char_encoding_entries"
|
||||
android:entryValues="@array/pref_char_encoding_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<SwitchPreference android:key="devtools.remote.usb.enabled"
|
||||
android:title="@string/pref_developer_remotedebugging_usb" />
|
||||
<PreferenceCategory android:title="@string/pref_category_data_saver">
|
||||
|
||||
<ListPreference android:key="browser.image_blocking"
|
||||
android:title="@string/pref_tap_to_load_images_title2"
|
||||
android:entries="@array/pref_browser_image_blocking_entries"
|
||||
android:entryValues="@array/pref_browser_image_blocking_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<SwitchPreference android:key="devtools.remote.wifi.enabled"
|
||||
android:title="@string/pref_developer_remotedebugging_wifi" />
|
||||
<SwitchPreference android:key="browser.display.use_document_fonts"
|
||||
android:title="@string/pref_show_web_fonts"
|
||||
android:summary="@string/pref_show_web_fonts_summary"/>
|
||||
|
||||
<org.mozilla.gecko.preferences.AlignRightLinkPreference android:key="android.not_a_preference.remote_debugging.link"
|
||||
android:title="@string/pref_learn_more"
|
||||
android:persistent="false"
|
||||
url="https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_category_media">
|
||||
|
||||
<ListPreference android:key="plugin.enable"
|
||||
android:title="@string/pref_plugins"
|
||||
android:entries="@array/pref_plugins_entries"
|
||||
android:entryValues="@array/pref_plugins_values"
|
||||
android:persistent="false" />
|
||||
|
||||
<SwitchPreference android:key="media.autoplay.enabled"
|
||||
android:title="@string/pref_media_autoplay_enabled"
|
||||
android:summary="@string/pref_media_autoplay_enabled_summary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_category_developer_tools">
|
||||
|
||||
<SwitchPreference android:key="devtools.remote.usb.enabled"
|
||||
android:title="@string/pref_developer_remotedebugging_usb" />
|
||||
|
||||
<SwitchPreference android:key="devtools.remote.wifi.enabled"
|
||||
android:title="@string/pref_developer_remotedebugging_wifi" />
|
||||
|
||||
<org.mozilla.gecko.preferences.AlignRightLinkPreference android:key="android.not_a_preference.remote_debugging.link"
|
||||
android:title="@string/pref_learn_more"
|
||||
android:persistent="false"
|
||||
url="https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -203,13 +203,17 @@
|
|||
<string name="pref_cookies_not_accept_foreign">&pref_cookies_not_accept_foreign;</string>
|
||||
<string name="pref_cookies_disabled">&pref_cookies_disabled;</string>
|
||||
|
||||
<string name="pref_category_data_saver">&pref_category_data_saver;</string>
|
||||
<string name="pref_category_media">&pref_category_media;</string>
|
||||
<string name="pref_category_developer_tools">&pref_category_developer_tools;</string>
|
||||
|
||||
<string name="pref_tap_to_load_images_title2">&pref_tap_to_load_images_title2;</string>
|
||||
<string name="pref_tap_to_load_images_enabled">&pref_tap_to_load_images_enabled;</string>
|
||||
<string name="pref_tap_to_load_images_data">&pref_tap_to_load_images_data;</string>
|
||||
<string name="pref_tap_to_load_images_disabled2">&pref_tap_to_load_images_disabled2;</string>
|
||||
|
||||
<string name="pref_show_web_fonts">&pref_show_web_fonts;</string>
|
||||
<string name="pref_show_web_fonts_summary">&pref_show_web_fonts_summary;</string>
|
||||
<string name="pref_show_web_fonts_summary">&pref_show_web_fonts_summary2;</string>
|
||||
|
||||
<string name="pref_tracking_protection_title">&pref_tracking_protection_title2;</string>
|
||||
<string name="pref_tracking_protection_summary">&pref_tracking_protection_summary3;</string>
|
||||
|
|
|
@ -622,8 +622,8 @@ var ActionBarHandler = {
|
|||
toStringWithFormat("text/plain", flags, 0);
|
||||
}
|
||||
|
||||
// Selection text gets trimmed up.
|
||||
return selection.toString().trim();
|
||||
// Return explicitly selected text.
|
||||
return selection.toString();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1351,7 +1351,13 @@ LoginManagerPrompter.prototype = {
|
|||
// Now that we know which login to use, modify its password.
|
||||
var selectedLogin = logins[selectedIndex.value];
|
||||
this.log("Updating password for user " + selectedLogin.username);
|
||||
this._updateLogin(selectedLogin, aNewLogin);
|
||||
var newLoginWithUsername = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(Ci.nsILoginInfo);
|
||||
newLoginWithUsername.init(aNewLogin.hostname,
|
||||
aNewLogin.formSubmitURL, aNewLogin.httpRealm,
|
||||
selectedLogin.username, aNewLogin.password,
|
||||
selectedLogin.userNameField, aNewLogin.passwordField);
|
||||
this._updateLogin(selectedLogin, newLoginWithUsername);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ support-files =
|
|||
../subtst_notifications_8.html
|
||||
../subtst_notifications_9.html
|
||||
../subtst_notifications_10.html
|
||||
../subtst_notifications_change_p.html
|
||||
authenticate.sjs
|
||||
form_basic.html
|
||||
head.js
|
||||
|
@ -21,6 +22,8 @@ support-files =
|
|||
streamConverter_content.sjs
|
||||
|
||||
[browser_capture_doorhanger.js]
|
||||
[browser_username_select_dialog.js]
|
||||
skip-if = e10s # bug 1263760
|
||||
[browser_DOMFormHasPassword.js]
|
||||
[browser_DOMInputPasswordAdded.js]
|
||||
[browser_filldoorhanger.js]
|
||||
|
|
|
@ -51,6 +51,8 @@ add_task(function* test_clickNever() {
|
|||
clickDoorhangerButton(notif, NEVER_BUTTON);
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
|
||||
info("Make sure Never took effect");
|
||||
yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "notifyu1", "Checking submitted username");
|
||||
|
@ -61,6 +63,8 @@ add_task(function* test_clickNever() {
|
|||
"Checking for login saving disabled");
|
||||
Services.logins.setLoginSavingEnabled("http://mochi.test:8888", true);
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_clickRemember() {
|
||||
|
@ -74,6 +78,13 @@ add_task(function* test_clickRemember() {
|
|||
clickDoorhangerButton(notif, REMEMBER_BUTTON);
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username used on the new entry");
|
||||
is(login.password, "notifyp1", "Check the password used on the new entry");
|
||||
is(login.timesUsed, 1, "Check times used on new entry");
|
||||
|
||||
info("Make sure Remember took effect and we don't prompt for an existing login");
|
||||
yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "notifyu1", "Checking submitted username");
|
||||
|
@ -82,6 +93,13 @@ add_task(function* test_clickRemember() {
|
|||
ok(!notif, "checking for no notification popup");
|
||||
});
|
||||
|
||||
logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username used");
|
||||
is(login.password, "notifyp1", "Check the password used");
|
||||
is(login.timesUsed, 2, "Check times used incremented");
|
||||
|
||||
checkOnlyLoginWasUsedTwice({ justChanged: false });
|
||||
|
||||
// remove that login
|
||||
|
@ -100,6 +118,8 @@ add_task(function* test_rememberSignonsFalse() {
|
|||
let notif = getCaptureDoorhanger("password-save");
|
||||
ok(!notif, "checking for no notification popup");
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_rememberSignonsTrue() {
|
||||
|
@ -113,6 +133,8 @@ add_task(function* test_rememberSignonsTrue() {
|
|||
ok(notif, "got notification popup");
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
/* autocomplete=off tests... */
|
||||
|
@ -127,6 +149,8 @@ add_task(function* test_autocompleteOffUsername() {
|
|||
ok(notif, "checking for notification popup");
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_autocompleteOffPassword() {
|
||||
|
@ -139,6 +163,8 @@ add_task(function* test_autocompleteOffPassword() {
|
|||
ok(notif, "checking for notification popup");
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_autocompleteOffForm() {
|
||||
|
@ -151,6 +177,8 @@ add_task(function* test_autocompleteOffForm() {
|
|||
ok(notif, "checking for notification popup");
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
|
||||
|
@ -163,6 +191,8 @@ add_task(function* test_noPasswordField() {
|
|||
let notif = getCaptureDoorhanger("password-save");
|
||||
ok(!notif, "checking for no notification popup");
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_pwOnlyLoginMatchesForm() {
|
||||
|
@ -177,6 +207,13 @@ add_task(function* test_pwOnlyLoginMatchesForm() {
|
|||
notif.remove();
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "", "Check the username");
|
||||
is(login.password, "notifyp1", "Check the password");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login2);
|
||||
});
|
||||
|
||||
|
@ -191,6 +228,13 @@ add_task(function* test_pwOnlyFormMatchesLogin() {
|
|||
ok(!notif, "checking for no notification popup");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username");
|
||||
is(login.password, "notifyp1", "Check the password");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login1);
|
||||
});
|
||||
|
||||
|
@ -206,6 +250,13 @@ add_task(function* test_pwOnlyFormDoesntMatchExisting() {
|
|||
notif.remove();
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
||||
|
||||
|
@ -221,6 +272,13 @@ add_task(function* test_changeUPLoginOnUPForm_dont() {
|
|||
clickDoorhangerButton(notif, DONT_CHANGE_BUTTON);
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login1);
|
||||
});
|
||||
|
||||
|
@ -237,6 +295,13 @@ add_task(function* test_changeUPLoginOnUPForm_change() {
|
|||
ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "pass2", "Check the password changed");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
checkOnlyLoginWasUsedTwice({ justChanged: true });
|
||||
|
||||
// cleanup
|
||||
|
@ -257,6 +322,15 @@ add_task(function* test_changePLoginOnUPForm() {
|
|||
clickDoorhangerButton(notif, CHANGE_BUTTON);
|
||||
ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "", "Check the username unchanged");
|
||||
is(login.password, "pass2", "Check the password changed");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
// no cleanup -- saved password to be used in the next test.
|
||||
});
|
||||
|
||||
add_task(function* test_changePLoginOnPForm() {
|
||||
|
@ -270,6 +344,14 @@ add_task(function* test_changePLoginOnPForm() {
|
|||
clickDoorhangerButton(notif, CHANGE_BUTTON);
|
||||
ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password changed");
|
||||
is(login.timesUsed, 3, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login2);
|
||||
});
|
||||
|
||||
|
@ -287,6 +369,8 @@ add_task(function* test_checkUPSaveText() {
|
|||
is(expectedText, notificationText, "Checking text: " + notificationText);
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_checkPSaveText() {
|
||||
|
@ -303,6 +387,8 @@ add_task(function* test_checkPSaveText() {
|
|||
is(expectedText, notificationText, "Checking text: " + notificationText);
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_capture2pw0un() {
|
||||
|
@ -316,6 +402,8 @@ add_task(function* test_capture2pw0un() {
|
|||
ok(notif, "got notification popup");
|
||||
notif.remove();
|
||||
});
|
||||
|
||||
is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
|
||||
});
|
||||
|
||||
add_task(function* test_change2pw0unExistingDifferentUP() {
|
||||
|
@ -332,6 +420,13 @@ add_task(function* test_change2pw0unExistingDifferentUP() {
|
|||
notif.remove();
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
||||
|
||||
|
@ -349,6 +444,13 @@ add_task(function* test_change2pw0unExistingDifferentP() {
|
|||
notif.remove();
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
Services.logins.removeLogin(login2B);
|
||||
});
|
||||
|
||||
|
@ -365,11 +467,46 @@ add_task(function* test_change2pw0unExistingWithSameP() {
|
|||
ok(!notif, "checking for no notification popup");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 2, "Check times used incremented");
|
||||
|
||||
checkOnlyLoginWasUsedTwice({ justChanged: false });
|
||||
|
||||
Services.logins.removeLogin(login2);
|
||||
});
|
||||
|
||||
add_task(function* test_changeUPLoginOnPUpdateForm() {
|
||||
info("Check for change-password popup, u+p login on password update form.");
|
||||
Services.logins.addLogin(login1);
|
||||
|
||||
yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "null", "Checking submitted username");
|
||||
is(fieldValues.password, "pass2", "Checking submitted password");
|
||||
let notif = getCaptureDoorhanger("password-change");
|
||||
ok(notif, "got notification popup");
|
||||
clickDoorhangerButton(notif, CHANGE_BUTTON);
|
||||
ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "pass2", "Check the password changed");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
checkOnlyLoginWasUsedTwice({ justChanged: true });
|
||||
|
||||
// cleanup
|
||||
login1.password = "pass2";
|
||||
Services.logins.removeLogin(login1);
|
||||
login1.password = "notifyp1";
|
||||
});
|
||||
|
||||
add_task(function* test_recipeCaptureFields_NewLogin() {
|
||||
info("Check that we capture the proper fields when a field recipe is in use.");
|
||||
|
||||
|
@ -385,6 +522,13 @@ add_task(function* test_recipeCaptureFields_NewLogin() {
|
|||
|
||||
clickDoorhangerButton(notif, REMEMBER_BUTTON);
|
||||
}, "http://example.org"); // The recipe is for example.org
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
});
|
||||
|
||||
add_task(function* test_recipeCaptureFields_ExistingLogin() {
|
||||
|
@ -400,8 +544,11 @@ add_task(function* test_recipeCaptureFields_ExistingLogin() {
|
|||
|
||||
checkOnlyLoginWasUsedTwice({ justChanged: false });
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins[0].username, "notifyu1", "check .username for existing login submission");
|
||||
is(logins[0].password, "notifyp1", "check .password for existing login submission");
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 2, "Check times used incremented");
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Test username selection dialog, on password update from a p-only form,
|
||||
* when there are multiple saved logins on the domain.
|
||||
*/
|
||||
|
||||
// Copied from prompt_common.js. TODO: share the code.
|
||||
function getSelectDialogDoc() {
|
||||
// Trudge through all the open windows, until we find the one
|
||||
// that has selectDialog.xul loaded.
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator);
|
||||
//var enumerator = wm.getEnumerator("navigator:browser");
|
||||
var enumerator = wm.getXULWindowEnumerator(null);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
|
||||
|
||||
var containedDocShells = windowDocShell.getDocShellEnumerator(
|
||||
Ci.nsIDocShellTreeItem.typeChrome,
|
||||
Ci.nsIDocShell.ENUMERATE_FORWARDS);
|
||||
while (containedDocShells.hasMoreElements()) {
|
||||
// Get the corresponding document for this docshell
|
||||
var childDocShell = containedDocShells.getNext();
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
|
||||
.contentViewer
|
||||
.DOMDocument;
|
||||
|
||||
if (childDoc.location.href == "chrome://global/content/selectDialog.xul")
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
let login1 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
|
||||
"notifyu1", "notifyp1", "user", "pass");
|
||||
let login1B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
|
||||
"notifyu1B", "notifyp1B", "user", "pass");
|
||||
|
||||
add_task(function* test_changeUPLoginOnPUpdateForm_accept() {
|
||||
info("Select an u+p login from multiple logins, on password update form, and accept.");
|
||||
Services.logins.addLogin(login1);
|
||||
Services.logins.addLogin(login1B);
|
||||
|
||||
yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "null", "Checking submitted username");
|
||||
is(fieldValues.password, "pass2", "Checking submitted password");
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to be accessible.");
|
||||
|
||||
let doc = getSelectDialogDoc();
|
||||
let dialog = doc.getElementsByTagName("dialog")[0];
|
||||
let listbox = doc.getElementById("list");
|
||||
|
||||
is(listbox.selectedIndex, 0, "Checking selected index");
|
||||
is(listbox.itemCount, 2, "Checking selected length");
|
||||
['notifyu1', 'notifyu1B'].forEach((username, i) => {
|
||||
is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog");
|
||||
});
|
||||
|
||||
dialog.acceptDialog();
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return !getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to disappear.");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 2, "Should have 2 logins");
|
||||
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "pass2", "Check the password changed");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
// cleanup
|
||||
login1.password = "pass2";
|
||||
Services.logins.removeLogin(login1);
|
||||
login1.password = "notifyp1";
|
||||
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
||||
|
||||
add_task(function* test_changeUPLoginOnPUpdateForm_cancel() {
|
||||
info("Select an u+p login from multiple logins, on password update form, and cancel.");
|
||||
Services.logins.addLogin(login1);
|
||||
Services.logins.addLogin(login1B);
|
||||
|
||||
yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "null", "Checking submitted username");
|
||||
is(fieldValues.password, "pass2", "Checking submitted password");
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to be accessible.");
|
||||
|
||||
let doc = getSelectDialogDoc();
|
||||
let dialog = doc.getElementsByTagName("dialog")[0];
|
||||
let listbox = doc.getElementById("list");
|
||||
|
||||
is(listbox.selectedIndex, 0, "Checking selected index");
|
||||
is(listbox.itemCount, 2, "Checking selected length");
|
||||
['notifyu1', 'notifyu1B'].forEach((username, i) => {
|
||||
is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog");
|
||||
});
|
||||
|
||||
dialog.cancelDialog();
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return !getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to disappear.");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 2, "Should have 2 logins");
|
||||
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
// cleanup
|
||||
Services.logins.removeLogin(login1);
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
const DIRECTORY_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";
|
||||
|
||||
Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
|
||||
Cu.import("resource://testing-common/ContentTaskUtils.jsm", this);
|
||||
|
||||
registerCleanupFunction(function* cleanup_removeAllLoginsAndResetRecipes() {
|
||||
Services.logins.removeAllLogins();
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Subtest for Login Manager notifications</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Change password</h2>
|
||||
<form id="form" action="formsubmit.sjs">
|
||||
<input id="pass_current" name="pass_current" type="password" value="notifyp1">
|
||||
<input id="pass" name="pass" type="password">
|
||||
<input id="pass_confirm" name="pass_confirm" type="password">
|
||||
<button type='submit'>Submit</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function submitForm() {
|
||||
passField.value = "pass2";
|
||||
passConfirmField.value = "pass2";
|
||||
|
||||
form.submit();
|
||||
}
|
||||
|
||||
window.onload = submitForm;
|
||||
var form = document.getElementById("form");
|
||||
var userField = document.getElementById("user");
|
||||
var passField = document.getElementById("pass");
|
||||
var passConfirmField = document.getElementById("pass_confirm");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -81,7 +81,9 @@ function checkTest() {
|
|||
logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
ok(login.timesUsed, 1, "Check times used on new entry");
|
||||
is(login.username, "notifyu1", "Check the username used on the new entry");
|
||||
is(login.password, "notifyp1", "Check the password used on the new entry");
|
||||
is(login.timesUsed, 1, "Check times used on new entry");
|
||||
|
||||
// password-change with chrome hidden
|
||||
popup = getPopup(popupNotifications, "password-change");
|
||||
|
@ -95,6 +97,7 @@ function checkTest() {
|
|||
logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username");
|
||||
is(login.password, "pass2", "Check password changed");
|
||||
is(login.timesUsed, 2, "check .timesUsed incremented on change");
|
||||
ok(login.timeCreated < login.timeLastUsed, "timeLastUsed bumped");
|
||||
|
@ -120,7 +123,9 @@ function checkTest() {
|
|||
logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login now");
|
||||
login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
ok(login.timesUsed, 1, "Check times used on new entry");
|
||||
is(login.username, "notifyu2", "Check the username used on the new entry");
|
||||
is(login.password, "notifyp2", "Check the password used on the new entry");
|
||||
is(login.timesUsed, 1, "Check times used on new entry");
|
||||
|
||||
// password-change with chrome visible
|
||||
popupWin = iframe.contentWindow.popupWin;
|
||||
|
@ -139,6 +144,7 @@ function checkTest() {
|
|||
logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 1, "Should have 1 login");
|
||||
login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu2", "Check the username");
|
||||
is(login.password, "pass2", "Check password changed");
|
||||
is(login.timesUsed, 2, "check .timesUsed incremented on change");
|
||||
ok(login.timeCreated < login.timeLastUsed, "timeLastUsed bumped");
|
||||
|
|
|
@ -5103,6 +5103,34 @@
|
|||
"kind": "flag",
|
||||
"description": "Set if Telemetry failed to save the session data to disk."
|
||||
},
|
||||
"TELEMETRY_ASSEMBLE_PAYLOAD_EXCEPTION": {
|
||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||
"bug_numbers": [1250640],
|
||||
"expires_in_version": "53",
|
||||
"kind": "count",
|
||||
"description": "Count of exceptions in TelemetrySession.getSessionPayload()."
|
||||
},
|
||||
"TELEMETRY_SCHEDULER_TICK_EXCEPTION": {
|
||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||
"bug_numbers": [1250640],
|
||||
"expires_in_version": "53",
|
||||
"kind": "count",
|
||||
"description": "Count of exceptions during executing the TelemetrySession scheduler tick logic."
|
||||
},
|
||||
"TELEMETRY_SCHEDULER_WAKEUP": {
|
||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||
"bug_numbers": [1250640],
|
||||
"expires_in_version": "53",
|
||||
"kind": "count",
|
||||
"description": "Count of TelemetrySession scheduler ticks that were delayed long enough to suspect sleep."
|
||||
},
|
||||
"TELEMETRY_SCHEDULER_SEND_DAILY": {
|
||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||
"bug_numbers": [1250640],
|
||||
"expires_in_version": "53",
|
||||
"kind": "count",
|
||||
"description": "Count of TelemetrySession triggering a daily ping."
|
||||
},
|
||||
"TELEMETRY_TEST_FLAG": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "flag",
|
||||
|
|
|
@ -320,6 +320,12 @@ var TelemetryScheduler = {
|
|||
idleService.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
|
||||
},
|
||||
|
||||
_clearTimeout: function() {
|
||||
if (this._schedulerTimer) {
|
||||
Policy.clearSchedulerTickTimeout(this._schedulerTimer);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reschedules the tick timer.
|
||||
*/
|
||||
|
@ -330,9 +336,7 @@ var TelemetryScheduler = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this._schedulerTimer) {
|
||||
Policy.clearSchedulerTickTimeout(this._schedulerTimer);
|
||||
}
|
||||
this._clearTimeout();
|
||||
|
||||
const now = Policy.now();
|
||||
let timeout = SCHEDULER_TICK_INTERVAL_MS;
|
||||
|
@ -421,6 +425,10 @@ var TelemetryScheduler = {
|
|||
* operation completes.
|
||||
*/
|
||||
_onSchedulerTick: function() {
|
||||
// This call might not be triggered from a timeout. In that case we don't want to
|
||||
// leave any previously scheduled timeouts pending.
|
||||
this._clearTimeout();
|
||||
|
||||
if (this._shuttingDown) {
|
||||
this._log.warn("_onSchedulerTick - already shutdown.");
|
||||
return Promise.reject(new Error("Already shutdown."));
|
||||
|
@ -430,6 +438,7 @@ var TelemetryScheduler = {
|
|||
try {
|
||||
promise = this._schedulerTickLogic();
|
||||
} catch (e) {
|
||||
Telemetry.getHistogramById("TELEMETRY_SCHEDULER_TICK_EXCEPTION").add(1);
|
||||
this._log.error("_onSchedulerTick - There was an exception", e);
|
||||
} finally {
|
||||
this._rescheduleTimeout();
|
||||
|
@ -449,8 +458,10 @@ var TelemetryScheduler = {
|
|||
let nowDate = Policy.now();
|
||||
let now = nowDate.getTime();
|
||||
|
||||
if (now - this._lastTickTime > 1.1 * SCHEDULER_TICK_INTERVAL_MS) {
|
||||
this._log.trace("_schedulerTickLogic - First scheduler tick after sleep or startup.");
|
||||
if ((now - this._lastTickTime) > (1.1 * SCHEDULER_TICK_INTERVAL_MS) &&
|
||||
(this._lastTickTime != 0)) {
|
||||
Telemetry.getHistogramById("TELEMETRY_SCHEDULER_WAKEUP").add(1);
|
||||
this._log.trace("_schedulerTickLogic - First scheduler tick after sleep.");
|
||||
}
|
||||
this._lastTickTime = now;
|
||||
|
||||
|
@ -458,6 +469,7 @@ var TelemetryScheduler = {
|
|||
const shouldSendDaily = this._isDailyPingDue(nowDate);
|
||||
|
||||
if (shouldSendDaily) {
|
||||
Telemetry.getHistogramById("TELEMETRY_SCHEDULER_SEND_DAILY").add(1);
|
||||
this._log.trace("_schedulerTickLogic - Daily ping due.");
|
||||
this._lastDailyPingTime = now;
|
||||
return Impl._sendDailyPing();
|
||||
|
@ -1299,23 +1311,29 @@ var Impl = {
|
|||
getSessionPayload: function getSessionPayload(reason, clearSubsession) {
|
||||
this._log.trace("getSessionPayload - reason: " + reason + ", clearSubsession: " + clearSubsession);
|
||||
|
||||
const isMobile = ["gonk", "android"].includes(AppConstants.platform);
|
||||
const isSubsession = isMobile ? false : !this._isClassicReason(reason);
|
||||
let payload;
|
||||
try {
|
||||
const isMobile = ["gonk", "android"].includes(AppConstants.platform);
|
||||
const isSubsession = isMobile ? false : !this._isClassicReason(reason);
|
||||
|
||||
if (isMobile) {
|
||||
clearSubsession = false;
|
||||
}
|
||||
if (isMobile) {
|
||||
clearSubsession = false;
|
||||
}
|
||||
|
||||
let measurements =
|
||||
this.getSimpleMeasurements(reason == REASON_SAVED_SESSION, isSubsession, clearSubsession);
|
||||
let info = !Utils.isContentProcess ? this.getMetadata(reason) : null;
|
||||
let payload = this.assemblePayloadWithMeasurements(measurements, info, reason, clearSubsession);
|
||||
|
||||
if (!Utils.isContentProcess && clearSubsession) {
|
||||
this.startNewSubsession();
|
||||
// Persist session data to disk (don't wait until it completes).
|
||||
let sessionData = this._getSessionDataObject();
|
||||
TelemetryStorage.saveSessionData(sessionData);
|
||||
let measurements =
|
||||
this.getSimpleMeasurements(reason == REASON_SAVED_SESSION, isSubsession, clearSubsession);
|
||||
let info = !Utils.isContentProcess ? this.getMetadata(reason) : null;
|
||||
payload = this.assemblePayloadWithMeasurements(measurements, info, reason, clearSubsession);
|
||||
} catch (ex) {
|
||||
Telemetry.getHistogramById("TELEMETRY_ASSEMBLE_PAYLOAD_EXCEPTION").add(1);
|
||||
throw ex;
|
||||
} finally {
|
||||
if (!Utils.isContentProcess && clearSubsession) {
|
||||
this.startNewSubsession();
|
||||
// Persist session data to disk (don't wait until it completes).
|
||||
let sessionData = this._getSessionDataObject();
|
||||
TelemetryStorage.saveSessionData(sessionData);
|
||||
}
|
||||
}
|
||||
|
||||
return payload;
|
||||
|
|
Загрузка…
Ссылка в новой задаче