Bug 1065265 - Improve infrastructure dealing with moz-action: autocomplete results. r=mak

--HG--
extra : transplant_source : %C9%C8x%E6%A3%E5%89%7F%B05%F2%82%FE%05%EF%E7%F5%0E%C0.
This commit is contained in:
Blair McBride 2014-09-11 22:50:08 +12:00
Родитель bf26e6a10b
Коммит ee1474e7da
15 изменённых файлов: 147 добавлений и 67 удалений

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

@ -393,7 +393,8 @@ panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .a
visibility: visible; visibility: visible;
} }
#urlbar:not([actiontype]) > #urlbar-display-box { #urlbar:not([actiontype]) > #urlbar-display-box,
#urlbar:not([actiontype="switchtab"]) > #urlbar-display-box > .urlbar-display-switchtab {
display: none; display: none;
} }

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

@ -756,7 +756,7 @@
</hbox> </hbox>
</box> </box>
<box id="urlbar-display-box" align="center"> <box id="urlbar-display-box" align="center">
<label id="urlbar-display" value="&urlbar.switchToTab.label;"/> <label class="urlbar-display urlbar-display-switchtab" value="&urlbar.switchToTab.label;"/>
</box> </box>
<hbox id="urlbar-icons"> <hbox id="urlbar-icons">
<image id="page-report-button" <image id="page-report-button"

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

@ -34,7 +34,7 @@ function test() {
"The test tab doesn't have the busy attribute"); "The test tab doesn't have the busy attribute");
// Set the urlbar to include the moz-action // Set the urlbar to include the moz-action
gURLBar.value = "moz-action:switchtab," + testURL; gURLBar.value = "moz-action:switchtab," + JSON.stringify({url: testURL});
// Focus the urlbar so we can press enter // Focus the urlbar so we can press enter
gURLBar.focus(); gURLBar.focus();

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

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html"; let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
let testActionURL = "moz-action:switchtab," + testURL; let testActionURL = "moz-action:switchtab," + JSON.stringify({url: testURL});
testURL = gURLBar.trimValue(testURL); testURL = gURLBar.trimValue(testURL);
let testTab; let testTab;

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

@ -72,7 +72,7 @@ function test() {
"The test tab doesn't have the busy attribute"); "The test tab doesn't have the busy attribute");
// Set the urlbar to include the moz-action // Set the urlbar to include the moz-action
aDestWindow.gURLBar.value = "moz-action:switchtab," + testURL; aDestWindow.gURLBar.value = "moz-action:switchtab," + JSON.stringify({url: testURL});
// Focus the urlbar so we can press enter // Focus the urlbar so we can press enter
aDestWindow.gURLBar.focus(); aDestWindow.gURLBar.focus();

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

@ -150,7 +150,12 @@
var action = this._parseActionUrl(aValue); var action = this._parseActionUrl(aValue);
if (action) { if (action) {
returnValue = action.param; switch (action.type) {
case "switchtab": {
returnValue = action.params.url;
break;
}
}
} }
// Set the actiontype only if the user is not overriding actions. // Set the actiontype only if the user is not overriding actions.
@ -279,9 +284,9 @@
let matchLastLocationChange = true; let matchLastLocationChange = true;
if (action) { if (action) {
url = action.param;
if (this.hasAttribute("actiontype")) { if (this.hasAttribute("actiontype")) {
if (action.type == "switchtab") { if (action.type == "switchtab") {
url = action.params.url;
this.handleRevert(); this.handleRevert();
let prevTab = gBrowser.selectedTab; let prevTab = gBrowser.selectedTab;
if (switchToTabHavingURI(url) && if (switchToTabHavingURI(url) &&
@ -717,9 +722,28 @@
if (!aUrl.startsWith("moz-action:")) if (!aUrl.startsWith("moz-action:"))
return null; return null;
// url is in the format moz-action:ACTION,PARAM // URL is in the format moz-action:ACTION,PARAMS
let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/); // Where PARAMS is a JSON encoded object.
return {type: action, param: param}; aUrl = decodeURI(aUrl);
let [, type, params] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
let action = {
type: type,
};
try {
action.params = JSON.parse(params);
} catch (e) {
// If this failed, we assume that params is not a JSON object, and
// is instead just a flat string. This will happen when
// UnifiedComplete is disabled - in which case, the param is always
// a URL.
action.params = {
url: params,
}
}
return action;
]]></body> ]]></body>
</method> </method>
@ -888,13 +912,13 @@
var where = whereToOpenLink(aEvent, false, true); var where = whereToOpenLink(aEvent, false, true);
searchBar.doSearch(search, where); searchBar.doSearch(search, where);
} }
]]></body> ]]></body>
</method> </method>
</implementation> </implementation>
</binding> </binding>
<binding id="urlbar-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup"> <binding id="urlbar-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup">
<implementation> <implementation>
<field name="_maxResults">0</field> <field name="_maxResults">0</field>
<field name="_bundle" readonly="true"> <field name="_bundle" readonly="true">

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

@ -64,7 +64,7 @@ function switchToURL(groupItemOne, groupItemTwo) {
* switch. The tab should be opened in group two and not in group one. * switch. The tab should be opened in group two and not in group one.
*/ */
// Set the urlbar to include the moz-action. // Set the urlbar to include the moz-action.
gURLBar.value = "moz-action:switchtab,about:mozilla"; gURLBar.value = "moz-action:switchtab," + JSON.stringify({url: "about:mozilla"});
// Focus the urlbar so we can press enter. // Focus the urlbar so we can press enter.
gURLBar.focus(); gURLBar.focus();
// Press enter. // Press enter.

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

@ -67,7 +67,7 @@ function switchToURL(groupItemOne, groupItemTwo) {
* switch. The selected group should be group one. * switch. The selected group should be group one.
*/ */
// Set the urlbar to include the moz-action. // Set the urlbar to include the moz-action.
gURLBar.value = "moz-action:switchtab,about:mozilla"; gURLBar.value = "moz-action:switchtab," + JSON.stringify({url: "about:mozilla"});
// Focus the urlbar so we can press enter. // Focus the urlbar so we can press enter.
gURLBar.focus(); gURLBar.focus();
// Press enter. // Press enter.

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

@ -901,7 +901,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
-moz-margin-end: 3px; -moz-margin-end: 3px;
} }
#urlbar-display { .urlbar-display {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
-moz-margin-start: 0; -moz-margin-start: 0;

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

@ -2054,7 +2054,7 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
-moz-margin-end: 3px; -moz-margin-end: 3px;
} }
#urlbar-display { .urlbar-display {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
color: GrayText; color: GrayText;

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

@ -1247,7 +1247,7 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
-moz-margin-end: 3px; -moz-margin-end: 3px;
} }
#urlbar-display { .urlbar-display {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
-moz-margin-start: 0; -moz-margin-start: 0;

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

@ -492,6 +492,23 @@ function stripHttpAndTrim(spec) {
return spec; return spec;
} }
/**
* Make a moz-action: URL for a given action and set of parameters.
*
* @param action
* Name of the action
* @param params
* Object, whose keys are parameter names and values are the
* corresponding parameter values.
* @return String representation of the built moz-action: URL
*/
function makeActionURL(action, params) {
let url = "moz-action:" + action + "," + JSON.stringify(params);
// Make a nsIURI out of this to ensure it's encoded properly.
return NetUtil.newURI(url).spec;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// Search Class //// Search Class
//// Manages a single instance of an autocomplete search. //// Manages a single instance of an autocomplete search.
@ -934,9 +951,12 @@ Search.prototype = {
// If actions are enabled and the page is open, add only the switch-to-tab // If actions are enabled and the page is open, add only the switch-to-tab
// result. Otherwise, add the normal result. // result. Otherwise, add the normal result.
let [url, action] = this._enableActions && openPageCount > 0 ? let url = escapedURL;
["moz-action:switchtab," + escapedURL, "switchtab"] : let action = null;
[escapedURL, null]; if (this._enableActions && openPageCount > 0) {
url = makeActionURL("switchtab", {url: escapedURL});
action = "switchtab";
}
// Always prefer the bookmark title unless it is empty // Always prefer the bookmark title unless it is empty
let title = bookmarkTitle || historyTitle; let title = bookmarkTitle || historyTitle;

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

@ -281,3 +281,8 @@ function stripPrefix(spec)
} }
return spec; return spec;
} }
function makeActionURI(action, params) {
let url = "moz-action:" + action + "," + JSON.stringify(params);
return NetUtil.newURI(url);
}

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

@ -22,14 +22,14 @@ add_task(function* test_tab_matches() {
yield check_autocomplete({ yield check_autocomplete({
search: "abc.com", search: "abc.com",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" } ] matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" } ]
}); });
do_log_info("two results, one tab match"); do_log_info("two results, one tab match");
yield check_autocomplete({ yield check_autocomplete({
search: "abc", search: "abc",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" }, matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" },
{ uri: uri2, title: "xyz.net - we're better than ABC" } ] { uri: uri2, title: "xyz.net - we're better than ABC" } ]
}); });
@ -38,8 +38,8 @@ add_task(function* test_tab_matches() {
yield check_autocomplete({ yield check_autocomplete({
search: "abc", search: "abc",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" }, matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" },
{ uri: NetUtil.newURI("moz-action:switchtab,http://xyz.net/"), title: "xyz.net - we're better than ABC" } ] { uri: makeActionURI("switchtab", {url: "http://xyz.net/"}), title: "xyz.net - we're better than ABC" } ]
}); });
do_log_info("two results, both tab matches, one has multiple tabs"); do_log_info("two results, both tab matches, one has multiple tabs");
@ -47,8 +47,8 @@ add_task(function* test_tab_matches() {
yield check_autocomplete({ yield check_autocomplete({
search: "abc", search: "abc",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" }, matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" },
{ uri: NetUtil.newURI("moz-action:switchtab,http://xyz.net/"), title: "xyz.net - we're better than ABC" } ] { uri: makeActionURI("switchtab", {url: "http://xyz.net/"}), title: "xyz.net - we're better than ABC" } ]
}); });
do_log_info("two results, no tab matches"); do_log_info("two results, no tab matches");
@ -66,30 +66,30 @@ add_task(function* test_tab_matches() {
yield check_autocomplete({ yield check_autocomplete({
search: gTabRestrictChar + " abc", search: gTabRestrictChar + " abc",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" } ] matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" } ]
}); });
do_log_info("tab match with not-addable pages"); do_log_info("tab match with not-addable pages");
yield check_autocomplete({ yield check_autocomplete({
search: "mozilla", search: "mozilla",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" } ] matches: [ { uri: makeActionURI("switchtab", {url: "about:mozilla"}), title: "about:mozilla" } ]
}); });
do_log_info("tab match with not-addable pages and restriction character"); do_log_info("tab match with not-addable pages and restriction character");
yield check_autocomplete({ yield check_autocomplete({
search: gTabRestrictChar + " mozilla", search: gTabRestrictChar + " mozilla",
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" } ] matches: [ { uri: makeActionURI("switchtab", {url: "about:mozilla"}), title: "about:mozilla" } ]
}); });
do_log_info("tab match with not-addable pages and only restriction character"); do_log_info("tab match with not-addable pages and only restriction character");
yield check_autocomplete({ yield check_autocomplete({
search: gTabRestrictChar, search: gTabRestrictChar,
searchParam: "enable-actions", searchParam: "enable-actions",
matches: [ { uri: NetUtil.newURI("moz-action:switchtab,http://abc.com/"), title: "ABC rocks" }, matches: [ { uri: makeActionURI("switchtab", {url: "http://abc.com/"}), title: "ABC rocks" },
{ uri: NetUtil.newURI("moz-action:switchtab,about:mozilla"), title: "about:mozilla" }, { uri: makeActionURI("switchtab", {url: "about:mozilla"}), title: "about:mozilla" },
{ uri: NetUtil.newURI("moz-action:switchtab,data:text/html,test"), title: "data:text/html,test" } ] { uri: makeActionURI("switchtab", {url: "data:text/html,test"}), title: "data:text/html,test" } ]
}); });
yield cleanup(); yield cleanup();

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

@ -1445,9 +1445,17 @@ extends="chrome://global/content/bindings/popup.xml#popup">
<method name="_adjustAcItem"> <method name="_adjustAcItem">
<body> <body>
<![CDATA[ <![CDATA[
var url = this.getAttribute("url"); let url = this.getAttribute("url");
var title = this.getAttribute("title"); let title = this.getAttribute("title");
var type = this.getAttribute("type"); let type = this.getAttribute("type");
let emphasiseTitle = true;
let emphasiseUrl = true;
// Hide the title's extra box by default, until we find out later if
// we need extra stuff.
this._extraBox.hidden = true;
this._titleBox.flex = 1;
this.removeAttribute("actiontype"); this.removeAttribute("actiontype");
@ -1457,34 +1465,36 @@ extends="chrome://global/content/bindings/popup.xml#popup">
// space when hidden. Setting the hidden property accomplishes that. // space when hidden. Setting the hidden property accomplishes that.
this._titleOverflowEllipsis.hidden = false; this._titleOverflowEllipsis.hidden = false;
let types = new Set(type.split(/\s+/));
// If the type includes an action, set up the item appropriately. // If the type includes an action, set up the item appropriately.
var types = type.split(/\s+/); if (types.has("action")) {
var actionIndex = types.indexOf("action"); let action = this._parseActionUrl(url);
if (actionIndex >= 0) { this.setAttribute("actiontype", action.type);
let [,action, param] = url.match(/^moz-action:([^,]+),(.*)$/);
this.setAttribute("actiontype", action); if (action.type == "switchtab") {
url = param; url = action.params.url;
let desc = this._stringBundle.GetStringFromName("switchToTab"); let desc = this._stringBundle.GetStringFromName("switchToTab");
this._setUpDescription(this._action, desc, true); this._setUpDescription(this._action, desc, true);
}
// Remove the "action" substring so that the correct style, if any, // Remove the "action" substring so that the correct style, if any,
// is applied below. // is applied below.
types.splice(actionIndex, 1); types.delete("action");
type = types.join(" ");
} }
// Check if we have a search engine name // Check if we have a search engine name
let searchEngine = ""; if (types.has("search")) {
let searchIndex = types.indexOf("search"); emphasiseUrl = false;
if (searchIndex >= 0) {
const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 "; const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
[title, searchEngine] = title.split(TITLE_SEARCH_ENGINE_SEPARATOR); [title, searchEngine] = title.split(TITLE_SEARCH_ENGINE_SEPARATOR);
url = this._stringBundle.formatStringFromName("searchWithEngine", [searchEngine], 1);
// Remove the "search" substring so that the correct style, if any, // Remove the "search" substring so that the correct style, if any,
// is applied below. // is applied below.
types.splice(searchIndex, 1); types.delete("search");
type = types.join(" ");
} }
// If we have a tag match, show the tags and icon // If we have a tag match, show the tags and icon
@ -1531,10 +1541,6 @@ extends="chrome://global/content/bindings/popup.xml#popup">
// Don't emphasize keyword searches in the title or url // Don't emphasize keyword searches in the title or url
this.setAttribute("text", ""); this.setAttribute("text", "");
} else {
// Hide the title's extra box if we don't need extra stuff
this._extraBox.hidden = true;
this._titleBox.flex = 1;
} }
// Give the image the icon style and a special one for the type // Give the image the icon style and a special one for the type
@ -1546,15 +1552,8 @@ extends="chrome://global/content/bindings/popup.xml#popup">
title = url; title = url;
// Emphasize the matching search terms for the description // Emphasize the matching search terms for the description
this._setUpDescription(this._title, title); this._setUpDescription(this._title, title, !emphasiseTitle);
if (!searchEngine) { this._setUpDescription(this._url, url, !emphasiseUrl);
this._setUpDescription(this._url, url);
} else {
let desc = this._stringBundle.formatStringFromName("searchWithEngine", [searchEngine], 1);
// The search engine name, when present, is not emphasized.
this._setUpDescription(this._url, desc, true);
}
// Set up overflow on a timeout because the contents of the box // Set up overflow on a timeout because the contents of the box
// might not have a width yet even though we just changed them // might not have a width yet even though we just changed them
@ -1564,6 +1563,37 @@ extends="chrome://global/content/bindings/popup.xml#popup">
</body> </body>
</method> </method>
<method name="_parseActionUrl">
<parameter name="aUrl"/>
<body><![CDATA[
if (!aUrl.startsWith("moz-action:"))
return null;
// URL is in the format moz-action:ACTION,PARAMS
// Where PARAMS is a JSON encoded object.
aUrl = decodeURI(aUrl);
let [, type, params] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
let action = {
type: type,
};
try {
action.params = JSON.parse(params);
} catch (e) {
// If this failed, we assume that params is not a JSON object, and
// is instead just a flat string. This will happen when
// UnifiedComplete is disabled - in which case, the param is always
// a URL.
action.params = {
url: params,
}
}
return action;
]]></body>
</method>
<method name="_setUpOverflow"> <method name="_setUpOverflow">
<parameter name="aParentBox"/> <parameter name="aParentBox"/>
<parameter name="aEllipsis"/> <parameter name="aEllipsis"/>