зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound a=merge CLOSED TREE
This commit is contained in:
Коммит
aec31f5f75
|
@ -74,7 +74,10 @@ const WorkerSandbox = Class({
|
||||||
* Mainly used by context-menu in order to avoid breaking it.
|
* Mainly used by context-menu in order to avoid breaking it.
|
||||||
*/
|
*/
|
||||||
emitSync: function emitSync(...args) {
|
emitSync: function emitSync(...args) {
|
||||||
return emitToContent(this, args);
|
// because the arguments could be also non JSONable values,
|
||||||
|
// we need to ensure the array instance is created from
|
||||||
|
// the content's sandbox
|
||||||
|
return emitToContent(this, new modelFor(this).sandbox.Array(...args));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,10 +35,14 @@ function getWindow(anchor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the anchor is in a browser tab in this browser window.
|
// Check if the anchor is in a browser tab in this browser window.
|
||||||
let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
|
try {
|
||||||
if (browser) {
|
let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
|
||||||
window = enumWindow;
|
if (browser) {
|
||||||
break;
|
window = enumWindow;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look in other subdocuments (sidebar, etc.)?
|
// Look in other subdocuments (sidebar, etc.)?
|
||||||
|
|
|
@ -135,6 +135,7 @@ skip-if = os == "linux"
|
||||||
[browser_989751_subviewbutton_class.js]
|
[browser_989751_subviewbutton_class.js]
|
||||||
[browser_987177_destroyWidget_xul.js]
|
[browser_987177_destroyWidget_xul.js]
|
||||||
[browser_987177_xul_wrapper_updating.js]
|
[browser_987177_xul_wrapper_updating.js]
|
||||||
|
[browser_987185_syncButton.js]
|
||||||
[browser_987492_window_api.js]
|
[browser_987492_window_api.js]
|
||||||
[browser_987640_charEncoding.js]
|
[browser_987640_charEncoding.js]
|
||||||
[browser_992747_toggle_noncustomizable_toolbar.js]
|
[browser_992747_toggle_noncustomizable_toolbar.js]
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* 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/.
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let syncService = {};
|
||||||
|
Components.utils.import("resource://services-sync/service.js", syncService);
|
||||||
|
|
||||||
|
let needsSetup;
|
||||||
|
let originalSync;
|
||||||
|
let service = syncService.Service;
|
||||||
|
let syncWasCalled = false;
|
||||||
|
|
||||||
|
add_task(function* testSyncButtonFunctionality() {
|
||||||
|
info("Check Sync button functionality");
|
||||||
|
storeInitialValues();
|
||||||
|
mockFunctions();
|
||||||
|
|
||||||
|
// add the Sync button to the panel
|
||||||
|
CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
|
||||||
|
|
||||||
|
// check the button's functionality
|
||||||
|
yield PanelUI.show();
|
||||||
|
info("The panel menu was opened");
|
||||||
|
|
||||||
|
let syncButton = document.getElementById("sync-button");
|
||||||
|
ok(syncButton, "The Sync button was added to the Panel Menu");
|
||||||
|
syncButton.click();
|
||||||
|
info("The sync button was clicked");
|
||||||
|
|
||||||
|
yield waitForCondition(() => syncWasCalled);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(function* asyncCleanup() {
|
||||||
|
// reset the panel UI to the default state
|
||||||
|
yield resetCustomization();
|
||||||
|
ok(CustomizableUI.inDefaultState, "The panel UI is in default state again.");
|
||||||
|
|
||||||
|
if (isPanelUIOpen()) {
|
||||||
|
let panelHidePromise = promisePanelHidden(window);
|
||||||
|
PanelUI.hide();
|
||||||
|
yield panelHidePromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreValues();
|
||||||
|
});
|
||||||
|
|
||||||
|
function mockFunctions() {
|
||||||
|
// mock needsSetup
|
||||||
|
gSyncUI._needsSetup = function() false;
|
||||||
|
|
||||||
|
// mock service.errorHandler.syncAndReportErrors()
|
||||||
|
service.errorHandler.syncAndReportErrors = mocked_syncAndReportErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mocked_syncAndReportErrors() {
|
||||||
|
syncWasCalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreValues() {
|
||||||
|
gSyncUI._needsSetup = needsSetup;
|
||||||
|
service.sync = originalSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
function storeInitialValues() {
|
||||||
|
needsSetup = gSyncUI._needsSetup;
|
||||||
|
originalSync = service.sync;
|
||||||
|
}
|
|
@ -55,7 +55,9 @@ loop.panel = (function(_, mozL10n) {
|
||||||
}, this);
|
}, this);
|
||||||
return (
|
return (
|
||||||
React.DOM.div({className: "tab-view-container"},
|
React.DOM.div({className: "tab-view-container"},
|
||||||
React.DOM.ul({className: "tab-view"}, tabButtons),
|
!this.props.buttonsHidden
|
||||||
|
? React.DOM.ul({className: "tab-view"}, tabButtons)
|
||||||
|
: null,
|
||||||
tabs
|
tabs
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -439,6 +441,7 @@ loop.panel = (function(_, mozL10n) {
|
||||||
// Mostly used for UI components showcase and unit tests
|
// Mostly used for UI components showcase and unit tests
|
||||||
callUrl: React.PropTypes.string,
|
callUrl: React.PropTypes.string,
|
||||||
userProfile: React.PropTypes.object,
|
userProfile: React.PropTypes.object,
|
||||||
|
showTabButtons: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -475,7 +478,12 @@ loop.panel = (function(_, mozL10n) {
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStatusChanged: function() {
|
_onStatusChanged: function() {
|
||||||
this.setState({userProfile: navigator.mozLoop.userProfile});
|
var profile = navigator.mozLoop.userProfile;
|
||||||
|
if (profile != this.state.userProfile) {
|
||||||
|
// On profile change (login, logout), switch back to the default tab.
|
||||||
|
this.selectTab("call");
|
||||||
|
}
|
||||||
|
this.setState({userProfile: profile});
|
||||||
this.updateServiceErrors();
|
this.updateServiceErrors();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -508,7 +516,7 @@ loop.panel = (function(_, mozL10n) {
|
||||||
React.DOM.div(null,
|
React.DOM.div(null,
|
||||||
NotificationListView({notifications: this.props.notifications,
|
NotificationListView({notifications: this.props.notifications,
|
||||||
clearOnDocumentHidden: true}),
|
clearOnDocumentHidden: true}),
|
||||||
TabView({ref: "tabView"},
|
TabView({ref: "tabView", buttonsHidden: !this.state.userProfile && !this.props.showTabButtons},
|
||||||
Tab({name: "call"},
|
Tab({name: "call"},
|
||||||
React.DOM.div({className: "content-area"},
|
React.DOM.div({className: "content-area"},
|
||||||
CallUrlResult({client: this.props.client,
|
CallUrlResult({client: this.props.client,
|
||||||
|
|
|
@ -55,7 +55,9 @@ loop.panel = (function(_, mozL10n) {
|
||||||
}, this);
|
}, this);
|
||||||
return (
|
return (
|
||||||
<div className="tab-view-container">
|
<div className="tab-view-container">
|
||||||
<ul className="tab-view">{tabButtons}</ul>
|
{!this.props.buttonsHidden
|
||||||
|
? <ul className="tab-view">{tabButtons}</ul>
|
||||||
|
: null}
|
||||||
{tabs}
|
{tabs}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -439,6 +441,7 @@ loop.panel = (function(_, mozL10n) {
|
||||||
// Mostly used for UI components showcase and unit tests
|
// Mostly used for UI components showcase and unit tests
|
||||||
callUrl: React.PropTypes.string,
|
callUrl: React.PropTypes.string,
|
||||||
userProfile: React.PropTypes.object,
|
userProfile: React.PropTypes.object,
|
||||||
|
showTabButtons: React.PropTypes.bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -475,7 +478,12 @@ loop.panel = (function(_, mozL10n) {
|
||||||
},
|
},
|
||||||
|
|
||||||
_onStatusChanged: function() {
|
_onStatusChanged: function() {
|
||||||
this.setState({userProfile: navigator.mozLoop.userProfile});
|
var profile = navigator.mozLoop.userProfile;
|
||||||
|
if (profile != this.state.userProfile) {
|
||||||
|
// On profile change (login, logout), switch back to the default tab.
|
||||||
|
this.selectTab("call");
|
||||||
|
}
|
||||||
|
this.setState({userProfile: profile});
|
||||||
this.updateServiceErrors();
|
this.updateServiceErrors();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -508,7 +516,7 @@ loop.panel = (function(_, mozL10n) {
|
||||||
<div>
|
<div>
|
||||||
<NotificationListView notifications={this.props.notifications}
|
<NotificationListView notifications={this.props.notifications}
|
||||||
clearOnDocumentHidden={true} />
|
clearOnDocumentHidden={true} />
|
||||||
<TabView ref="tabView">
|
<TabView ref="tabView" buttonsHidden={!this.state.userProfile && !this.props.showTabButtons}>
|
||||||
<Tab name="call">
|
<Tab name="call">
|
||||||
<div className="content-area">
|
<div className="content-area">
|
||||||
<CallUrlResult client={this.props.client}
|
<CallUrlResult client={this.props.client}
|
||||||
|
|
|
@ -140,7 +140,8 @@ describe("loop.panel", function() {
|
||||||
|
|
||||||
view = TestUtils.renderIntoDocument(loop.panel.PanelView({
|
view = TestUtils.renderIntoDocument(loop.panel.PanelView({
|
||||||
notifications: notifications,
|
notifications: notifications,
|
||||||
client: fakeClient
|
client: fakeClient,
|
||||||
|
showTabButtons: true,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
[callTab, contactsTab] =
|
[callTab, contactsTab] =
|
||||||
|
|
|
@ -32,8 +32,8 @@ this.Translation = {
|
||||||
|
|
||||||
serviceUnavailable: false,
|
serviceUnavailable: false,
|
||||||
|
|
||||||
supportedSourceLanguages: ["de", "en", "es", "fr", "ja", "ko", "pt", "ru", "zh"],
|
supportedSourceLanguages: ["bg", "cs", "de", "en", "es", "fr", "ja", "ko", "nl", "no", "pl", "pt", "ru", "tr", "vi", "zh"],
|
||||||
supportedTargetLanguages: ["de", "en", "es", "fr", "ja", "ko", "pl", "pt", "ru", "tr", "vi", "zh"],
|
supportedTargetLanguages: ["bg", "cs", "de", "en", "es", "fr", "ja", "ko", "nl", "no", "pl", "pt", "ru", "tr", "vi", "zh"],
|
||||||
|
|
||||||
_defaultTargetLanguage: "",
|
_defaultTargetLanguage: "",
|
||||||
get defaultTargetLanguage() {
|
get defaultTargetLanguage() {
|
||||||
|
|
|
@ -23,6 +23,21 @@
|
||||||
<xul:hbox anonid="details" align="center" flex="1">
|
<xul:hbox anonid="details" align="center" flex="1">
|
||||||
<xul:image class="translate-infobar-element messageImage"
|
<xul:image class="translate-infobar-element messageImage"
|
||||||
anonid="messageImage"/>
|
anonid="messageImage"/>
|
||||||
|
<xul:panel anonid="welcomePanel" class="translation-welcome-panel"
|
||||||
|
type="arrow" align="start">
|
||||||
|
<xul:image class="translation-welcome-logo"/>
|
||||||
|
<xul:vbox flex="1" class="translation-welcome-content">
|
||||||
|
<xul:description class="translation-welcome-headline"
|
||||||
|
anonid="welcomeHeadline"/>
|
||||||
|
<xul:description class="translation-welcome-body" anonid="welcomeBody"/>
|
||||||
|
<xul:hbox align="center">
|
||||||
|
<xul:label anonid="learnMore" class="plain text-link"/>
|
||||||
|
<xul:spacer flex="1"/>
|
||||||
|
<xul:button class="translate-infobar-element" anonid="thanksButton"
|
||||||
|
onclick="this.parentNode.parentNode.parentNode.hidePopup();"/>
|
||||||
|
</xul:hbox>
|
||||||
|
</xul:vbox>
|
||||||
|
</xul:panel>
|
||||||
<xul:deck anonid="translationStates" selectedIndex="0">
|
<xul:deck anonid="translationStates" selectedIndex="0">
|
||||||
|
|
||||||
<!-- offer to translate -->
|
<!-- offer to translate -->
|
||||||
|
@ -198,6 +213,41 @@
|
||||||
|
|
||||||
if (aTranslation.state)
|
if (aTranslation.state)
|
||||||
this.state = aTranslation.state;
|
this.state = aTranslation.state;
|
||||||
|
|
||||||
|
const kWelcomePref = "browser.translation.ui.welcomeMessageShown";
|
||||||
|
if (Services.prefs.prefHasUserValue(kWelcomePref))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.addEventListener("transitionend", function onShown() {
|
||||||
|
this.removeEventListener("transitionend", onShown);
|
||||||
|
|
||||||
|
// These strings are hardcoded because they need to reach beta
|
||||||
|
// without riding the trains.
|
||||||
|
let localizedStrings = {
|
||||||
|
en: ["Hey look! It's something new!",
|
||||||
|
"Now the Web is even more accessible with our new in-page translation feature. Click the translate button to try it!",
|
||||||
|
"Learn more.",
|
||||||
|
"Thanks"]
|
||||||
|
};
|
||||||
|
|
||||||
|
let locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
|
||||||
|
.getService(Ci.nsIXULChromeRegistry)
|
||||||
|
.getSelectedLocale("browser");
|
||||||
|
if (!(locale in localizedStrings))
|
||||||
|
locale = "en";
|
||||||
|
let strings = localizedStrings[locale];
|
||||||
|
|
||||||
|
this._getAnonElt("welcomeHeadline").setAttribute("value", strings[0]);
|
||||||
|
this._getAnonElt("welcomeBody").textContent = strings[1];
|
||||||
|
this._getAnonElt("learnMore").setAttribute("value", strings[2]);
|
||||||
|
this._getAnonElt("thanksButton").setAttribute("label", strings[3]);
|
||||||
|
|
||||||
|
let panel = this._getAnonElt("welcomePanel");
|
||||||
|
panel.openPopup(this._getAnonElt("messageImage"),
|
||||||
|
"bottomcenter topleft");
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(kWelcomePref, true);
|
||||||
|
});
|
||||||
]]>
|
]]>
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
|
|
|
@ -19,7 +19,7 @@ importPackagedApp_title=Select Directory
|
||||||
importHostedApp_title=Open Hosted App
|
importHostedApp_title=Open Hosted App
|
||||||
importHostedApp_header=Enter Manifest URL
|
importHostedApp_header=Enter Manifest URL
|
||||||
|
|
||||||
notification_showTroubleShooting_label=troubleshooting
|
notification_showTroubleShooting_label=Troubleshooting
|
||||||
notification_showTroubleShooting_accesskey=t
|
notification_showTroubleShooting_accesskey=t
|
||||||
|
|
||||||
# LOCALIZATION NOTE (project_tab_loading): This is shown as a temporary tab
|
# LOCALIZATION NOTE (project_tab_loading): This is shown as a temporary tab
|
||||||
|
|
|
@ -64,3 +64,28 @@ notification[value="translation"] menulist > .menulist-dropmarker {
|
||||||
.translation-attribution > image {
|
.translation-attribution > image {
|
||||||
width: 70px;
|
width: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.translation-welcome-panel {
|
||||||
|
width: 305px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.translation-welcome-logo {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
list-style-image: url(chrome://browser/skin/translation-16@2x.png);
|
||||||
|
-moz-image-region: rect(0, 64px, 32px, 32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.translation-welcome-content {
|
||||||
|
-moz-margin-start: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.translation-welcome-headline {
|
||||||
|
font-size: larger;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.translation-welcome-body {
|
||||||
|
padding: 1em 0;
|
||||||
|
margin: 0 0;
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
# do ok(true, "Type not supported") and stop the test.
|
# do ok(true, "Type not supported") and stop the test.
|
||||||
|
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = buildapp == 'mulet' || contentSandbox != 'off' # contentSandbox(Bug 1042735)
|
skip-if = buildapp == 'mulet'
|
||||||
support-files =
|
support-files =
|
||||||
320x240.ogv
|
320x240.ogv
|
||||||
320x240.ogv^headers^
|
320x240.ogv^headers^
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && (toolkit != 'gonk' || debug)) || contentSandbox != 'off' #b2g-debug,b2g-desktop(bug 916135); contentSandbox(Bug 1042735)
|
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && (toolkit != 'gonk' || debug)) #b2g-debug,b2g-desktop(bug 916135)
|
||||||
support-files =
|
support-files =
|
||||||
audio-expected.wav
|
audio-expected.wav
|
||||||
audio-mono-expected-2.wav
|
audio-mono-expected-2.wav
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = contentSandbox != 'off' # contentSandbox(Bug 1042735)
|
|
||||||
support-files =
|
support-files =
|
||||||
head.js
|
head.js
|
||||||
constraints.js
|
constraints.js
|
||||||
|
|
|
@ -23,10 +23,8 @@
|
||||||
#include ../search/manifests/SearchAndroidManifest_permissions.xml.in
|
#include ../search/manifests/SearchAndroidManifest_permissions.xml.in
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RELEASE_BUILD
|
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
#endif
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
|
|
@ -7,7 +7,9 @@ package org.mozilla.gecko.home;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.AboutPages;
|
||||||
import org.mozilla.gecko.R;
|
import org.mozilla.gecko.R;
|
||||||
|
import org.mozilla.gecko.ReaderModeUtils;
|
||||||
import org.mozilla.gecko.Tab;
|
import org.mozilla.gecko.Tab;
|
||||||
import org.mozilla.gecko.Tabs;
|
import org.mozilla.gecko.Tabs;
|
||||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||||
|
@ -248,7 +250,12 @@ public class TwoLinePageRow extends LinearLayout
|
||||||
// Blank the Favicon, so we don't show the wrong Favicon if we scroll and miss DB.
|
// Blank the Favicon, so we don't show the wrong Favicon if we scroll and miss DB.
|
||||||
mFavicon.clearImage();
|
mFavicon.clearImage();
|
||||||
Favicons.cancelFaviconLoad(mLoadFaviconJobId);
|
Favicons.cancelFaviconLoad(mLoadFaviconJobId);
|
||||||
mLoadFaviconJobId = Favicons.getSizedFaviconForPageFromLocal(getContext(), url, mFaviconListener);
|
|
||||||
|
// Displayed RecentTabsPanel urls may refer to pages openned in readermode, so we
|
||||||
|
// remove the about:reader prefix to ensure the Favicon loads properly.
|
||||||
|
final String pageURL = AboutPages.isAboutReader(url) ?
|
||||||
|
ReaderModeUtils.getUrlFromAboutReader(url) : url;
|
||||||
|
mLoadFaviconJobId = Favicons.getSizedFaviconForPageFromLocal(getContext(), pageURL, mFaviconListener);
|
||||||
|
|
||||||
updateDisplayedUrl(url);
|
updateDisplayedUrl(url);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,7 @@ $(eval $(call generated_file_template,suggestedsites,suggestedsites.json))
|
||||||
|
|
||||||
$(suggestedsites-dstdir-raw)/suggestedsites.json: FORCE
|
$(suggestedsites-dstdir-raw)/suggestedsites.json: FORCE
|
||||||
$(call py_action,generate_suggestedsites, \
|
$(call py_action,generate_suggestedsites, \
|
||||||
|
--verbose \
|
||||||
--android-package-name=$(ANDROID_PACKAGE_NAME) \
|
--android-package-name=$(ANDROID_PACKAGE_NAME) \
|
||||||
--resources=$(srcdir)/../resources \
|
--resources=$(srcdir)/../resources \
|
||||||
$(if $(filter en-US,$(AB_CD)),,--srcdir=$(l10n-srcdir)) \
|
$(if $(filter en-US,$(AB_CD)),,--srcdir=$(l10n-srcdir)) \
|
||||||
|
@ -125,6 +126,7 @@ $(eval $(call generated_file_template,browsersearch,browsersearch.json))
|
||||||
|
|
||||||
$(browsersearch-dstdir-raw)/browsersearch.json: FORCE
|
$(browsersearch-dstdir-raw)/browsersearch.json: FORCE
|
||||||
$(call py_action,generate_browsersearch, \
|
$(call py_action,generate_browsersearch, \
|
||||||
|
--verbose \
|
||||||
$(if $(filter en-US,$(AB_CD)),,--srcdir=$(l10n-srcdir)) \
|
$(if $(filter en-US,$(AB_CD)),,--srcdir=$(l10n-srcdir)) \
|
||||||
--srcdir=$(topsrcdir)/mobile/locales/en-US/chrome \
|
--srcdir=$(topsrcdir)/mobile/locales/en-US/chrome \
|
||||||
$@)
|
$@)
|
||||||
|
|
|
@ -527,6 +527,21 @@ var Addons = {
|
||||||
element.setAttribute("opType", "needs-restart");
|
element.setAttribute("opType", "needs-restart");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onInstalled: function(aAddon) {
|
||||||
|
let list = document.getElementById("addons-list");
|
||||||
|
let element = this._getElementForAddon(aAddon.id);
|
||||||
|
if (!element) {
|
||||||
|
element = this._createItemForAddon(aAddon);
|
||||||
|
list.insertBefore(element, list.firstElementChild);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onUninstalled: function(aAddon) {
|
||||||
|
let list = document.getElementById("addons-list");
|
||||||
|
let element = this._getElementForAddon(aAddon.id);
|
||||||
|
list.removeChild(element);
|
||||||
|
},
|
||||||
|
|
||||||
onInstallFailed: function(aInstall) {
|
onInstallFailed: function(aInstall) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div>&aboutApps.header;</div>
|
<div>&aboutApps.header;</div>
|
||||||
<div id="header-button" role="button" aria-label="&aboutApps.browseMarketplace;" pref="app.marketplaceURL"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main-container" class="hidden">
|
<div id="main-container" class="hidden">
|
||||||
|
|
|
@ -829,6 +829,13 @@ var BrowserApp = {
|
||||||
Services.prefs.setIntPref("plugin.default.state", Ci.nsIPluginTag.STATE_ENABLED);
|
Services.prefs.setIntPref("plugin.default.state", Ci.nsIPluginTag.STATE_ENABLED);
|
||||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the search activity default pref on app upgrade if it has not been set already.
|
||||||
|
if (this._startupStatus === "upgrade" &&
|
||||||
|
!Services.prefs.prefHasUserValue("searchActivity.default.migrated")) {
|
||||||
|
Services.prefs.setBoolPref("searchActivity.default.migrated", true);
|
||||||
|
SearchEngines.migrateSearchActivityDefaultPref();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
shutdown: function shutdown() {
|
shutdown: function shutdown() {
|
||||||
|
@ -6909,6 +6916,10 @@ var SearchEngines = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
migrateSearchActivityDefaultPref: function migrateSearchActivityDefaultPref() {
|
||||||
|
Services.search.init(() => this._setSearchActivityDefaultPref(Services.search.defaultEngine));
|
||||||
|
},
|
||||||
|
|
||||||
// Updates the search activity pref when the default engine changes.
|
// Updates the search activity pref when the default engine changes.
|
||||||
_setSearchActivityDefaultPref: function _setSearchActivityDefaultPref(engine) {
|
_setSearchActivityDefaultPref: function _setSearchActivityDefaultPref(engine) {
|
||||||
// Helper function copied from nsSearchService.js. This is the logic that is used
|
// Helper function copied from nsSearchService.js. This is the logic that is used
|
||||||
|
|
|
@ -6,13 +6,6 @@
|
||||||
background-color: #febc2b;
|
background-color: #febc2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header-button {
|
|
||||||
background-image: url("chrome://browser/skin/images/marketplace-logo.png"), url("chrome://browser/skin/images/chevron.png");
|
|
||||||
background-size: 32px 32px, 8px 20px;
|
|
||||||
background-position: left, right 0.5em center;
|
|
||||||
-moz-padding-start: 2.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-container {
|
#main-container {
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
background-color: #EEF2F5;
|
background-color: #EEF2F5;
|
||||||
|
|
|
@ -23,6 +23,7 @@ PYTHON_UNIT_TESTS += [
|
||||||
'mozbuild/dumbmake/test/test_dumbmake.py',
|
'mozbuild/dumbmake/test/test_dumbmake.py',
|
||||||
'mozbuild/mozbuild/test/__init__.py',
|
'mozbuild/mozbuild/test/__init__.py',
|
||||||
'mozbuild/mozbuild/test/action/test_buildlist.py',
|
'mozbuild/mozbuild/test/action/test_buildlist.py',
|
||||||
|
'mozbuild/mozbuild/test/action/test_generate_browsersearch.py',
|
||||||
'mozbuild/mozbuild/test/backend/__init__.py',
|
'mozbuild/mozbuild/test/backend/__init__.py',
|
||||||
'mozbuild/mozbuild/test/backend/common.py',
|
'mozbuild/mozbuild/test/backend/common.py',
|
||||||
'mozbuild/mozbuild/test/backend/test_android_eclipse.py',
|
'mozbuild/mozbuild/test/backend/test_android_eclipse.py',
|
||||||
|
|
|
@ -22,9 +22,13 @@ browsersearch.json in the locale-specific raw resource directory
|
||||||
e.g. raw/browsersearch.json, raw-pt-rBR/browsersearch.json.
|
e.g. raw/browsersearch.json, raw-pt-rBR/browsersearch.json.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import (
|
||||||
|
print_function,
|
||||||
|
unicode_literals,
|
||||||
|
)
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import codecs
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
@ -72,8 +76,9 @@ def main(args):
|
||||||
engines = properties.get_list('browser.search.order')
|
engines = properties.get_list('browser.search.order')
|
||||||
|
|
||||||
if opts.verbose:
|
if opts.verbose:
|
||||||
print('Read {len} engines: {engines}'.format(len=len(engines), engines=engines))
|
writer = codecs.getwriter('utf-8')(sys.stdout)
|
||||||
print("Default engine is '{default}'.".format(default=default))
|
print('Read {len} engines: {engines}'.format(len=len(engines), engines=engines), file=writer)
|
||||||
|
print("Default engine is '{default}'.".format(default=default), file=writer)
|
||||||
|
|
||||||
browsersearch = {}
|
browsersearch = {}
|
||||||
browsersearch['default'] = default
|
browsersearch['default'] = default
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# A region.properties file with invalid unicode byte sequences. The
|
||||||
|
# sequences were cribbed from Markus Kuhn's "UTF-8 decoder capability
|
||||||
|
# and stress test", available at
|
||||||
|
# http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
|
||||||
|
|
||||||
|
# 3.5 Impossible bytes |
|
||||||
|
# |
|
||||||
|
# The following two bytes cannot appear in a correct UTF-8 string |
|
||||||
|
# |
|
||||||
|
# 3.5.1 fe = "þ" |
|
||||||
|
# 3.5.2 ff = "ÿ" |
|
||||||
|
# 3.5.3 fe fe ff ff = "þþÿÿ" |
|
|
@ -0,0 +1,37 @@
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
# Default search engine
|
||||||
|
browser.search.defaultenginename=百度
|
||||||
|
|
||||||
|
# Search engine order (order displayed in the search bar dropdown)s
|
||||||
|
browser.search.order.1=百度
|
||||||
|
browser.search.order.2=Google
|
||||||
|
|
||||||
|
# This is the default set of web based feed handlers shown in the reader
|
||||||
|
# selection UI
|
||||||
|
browser.contentHandlers.types.0.title=Bloglines
|
||||||
|
browser.contentHandlers.types.0.uri=http://www.bloglines.com/login?r=/sub/%s
|
||||||
|
|
||||||
|
# increment this number when anything gets changed in the list below. This will
|
||||||
|
# cause Firefox to re-read these prefs and inject any new handlers into the
|
||||||
|
# profile database. Note that "new" is defined as "has a different URL"; this
|
||||||
|
# means that it's not possible to update the name of existing handler, so
|
||||||
|
# don't make any spelling errors here.
|
||||||
|
gecko.handlerService.defaultHandlersVersion=3
|
||||||
|
|
||||||
|
# The default set of protocol handlers for webcal:
|
||||||
|
gecko.handlerService.schemes.webcal.0.name=30 Boxes
|
||||||
|
gecko.handlerService.schemes.webcal.0.uriTemplate=https://30boxes.com/external/widget?refer=ff&url=%s
|
||||||
|
|
||||||
|
# The default set of protocol handlers for mailto:
|
||||||
|
gecko.handlerService.schemes.mailto.0.name=Yahoo! 邮件
|
||||||
|
gecko.handlerService.schemes.mailto.0.uriTemplate=https://compose.mail.yahoo.com/?To=%s
|
||||||
|
gecko.handlerService.schemes.mailto.1.name=Gmail
|
||||||
|
gecko.handlerService.schemes.mailto.1.uriTemplate=https://mail.google.com/mail/?extsrc=mailto&url=%s
|
||||||
|
|
||||||
|
# This is the default set of web based feed handlers shown in the reader
|
||||||
|
# selection UI
|
||||||
|
browser.contentHandlers.types.0.title=My Yahoo!
|
||||||
|
browser.contentHandlers.types.0.uri=http://www.bloglines.com/login?r=/sub/%s
|
|
@ -0,0 +1,55 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import mozunit
|
||||||
|
|
||||||
|
import mozbuild.action.generate_browsersearch as generate_browsersearch
|
||||||
|
|
||||||
|
from mozfile.mozfile import (
|
||||||
|
NamedTemporaryFile,
|
||||||
|
TemporaryDirectory,
|
||||||
|
)
|
||||||
|
|
||||||
|
import mozpack.path as mozpath
|
||||||
|
|
||||||
|
|
||||||
|
test_data_path = mozpath.abspath(mozpath.dirname(__file__))
|
||||||
|
test_data_path = mozpath.join(test_data_path, 'data')
|
||||||
|
|
||||||
|
|
||||||
|
class TestGenerateBrowserSearch(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Unit tests for generate_browsersearch.py.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _test_one(self, name):
|
||||||
|
with TemporaryDirectory() as tmpdir:
|
||||||
|
with NamedTemporaryFile(mode='r+') as temp:
|
||||||
|
srcdir = os.path.join(test_data_path, name)
|
||||||
|
|
||||||
|
generate_browsersearch.main([
|
||||||
|
'--verbose',
|
||||||
|
'--srcdir', srcdir,
|
||||||
|
temp.name])
|
||||||
|
return json.load(temp)
|
||||||
|
|
||||||
|
def test_valid_unicode(self):
|
||||||
|
o = self._test_one('valid-zh-CN')
|
||||||
|
self.assertEquals(o['default'], '百度')
|
||||||
|
self.assertEquals(o['engines'], ['百度', 'Google'])
|
||||||
|
|
||||||
|
def test_invalid_unicode(self):
|
||||||
|
with self.assertRaises(UnicodeDecodeError):
|
||||||
|
self._test_one('invalid')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
mozunit.main()
|
|
@ -64,6 +64,7 @@ const SearchAutocompleteProviderInternal = {
|
||||||
case "engine-added":
|
case "engine-added":
|
||||||
case "engine-changed":
|
case "engine-changed":
|
||||||
case "engine-removed":
|
case "engine-removed":
|
||||||
|
case "engine-current":
|
||||||
this._refresh();
|
this._refresh();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,5 +31,17 @@ add_task(function*() {
|
||||||
matches: [ { uri: makeActionURI("searchengine", {engineName: "MozSearch", input: "mozzarella cheese", searchQuery: "mozzarella cheese"}), title: "MozSearch" }, ]
|
matches: [ { uri: makeActionURI("searchengine", {engineName: "MozSearch", input: "mozzarella cheese", searchQuery: "mozzarella cheese"}), title: "MozSearch" }, ]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
do_log_info("search engine, after current engine has changed");
|
||||||
|
Services.search.addEngineWithDetails("MozSearch2", "", "", "", "GET",
|
||||||
|
"http://s.example.com/search2");
|
||||||
|
engine = Services.search.getEngineByName("MozSearch2");
|
||||||
|
notEqual(Services.search.currentEngine, engine, "New engine shouldn't be the current engine yet");
|
||||||
|
Services.search.currentEngine = engine;
|
||||||
|
yield check_autocomplete({
|
||||||
|
search: "mozilla",
|
||||||
|
searchParam: "enable-actions",
|
||||||
|
matches: [ { uri: makeActionURI("searchengine", {engineName: "MozSearch2", input: "mozilla", searchQuery: "mozilla"}), title: "MozSearch2" }, ]
|
||||||
|
});
|
||||||
|
|
||||||
yield cleanup();
|
yield cleanup();
|
||||||
});
|
});
|
Загрузка…
Ссылка в новой задаче