mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound
This commit is contained in:
commit
c1cf5829da
@ -529,6 +529,14 @@ var shell = {
|
||||
content.dispatchEvent(event);
|
||||
},
|
||||
|
||||
sendCustomEvent: function shell_sendCustomEvent(type, details) {
|
||||
let content = getContentWindow();
|
||||
let event = content.document.createEvent('CustomEvent');
|
||||
let payload = details ? ObjectWrapper.wrap(details, content) : {};
|
||||
event.initCustomEvent(type, true, true, payload);
|
||||
content.dispatchEvent(event);
|
||||
},
|
||||
|
||||
sendChromeEvent: function shell_sendChromeEvent(details) {
|
||||
if (!this.isHomeLoaded) {
|
||||
if (!('pendingChromeEvents' in this)) {
|
||||
@ -545,8 +553,7 @@ var shell = {
|
||||
|
||||
openAppForSystemMessage: function shell_openAppForSystemMessage(msg) {
|
||||
let origin = Services.io.newURI(msg.manifest, null, null).prePath;
|
||||
this.sendChromeEvent({
|
||||
type: 'open-app',
|
||||
let payload = {
|
||||
url: msg.uri,
|
||||
manifestURL: msg.manifest,
|
||||
isActivity: (msg.type == 'activity'),
|
||||
@ -555,7 +562,11 @@ var shell = {
|
||||
target: msg.target,
|
||||
expectingSystemMessage: true,
|
||||
extra: msg.extra
|
||||
});
|
||||
}
|
||||
this.sendCustomEvent('open-app', payload);
|
||||
// XXX Remove once the gaia part of bug 924032 has landed.
|
||||
payload.type = 'open-app';
|
||||
this.sendChromeEvent(payload);
|
||||
},
|
||||
|
||||
receiveMessage: function shell_receiveMessage(message) {
|
||||
@ -947,12 +958,21 @@ var WebappsHelper = {
|
||||
return;
|
||||
|
||||
let manifest = new ManifestHelper(aManifest, json.origin);
|
||||
shell.sendChromeEvent({
|
||||
"type": "webapps-launch",
|
||||
"timestamp": json.timestamp,
|
||||
"url": manifest.fullLaunchPath(json.startPoint),
|
||||
"manifestURL": json.manifestURL
|
||||
});
|
||||
let payload = {
|
||||
__exposedProps__: {
|
||||
timestamp: "r",
|
||||
url: "r",
|
||||
manifestURL: "r"
|
||||
},
|
||||
timestamp: json.timestamp,
|
||||
url: manifest.fullLaunchPath(json.startPoint),
|
||||
manifestURL: json.manifestURL
|
||||
}
|
||||
shell.sendEvent(getContentWindow(), "webapps-launch", payload);
|
||||
// XXX Remove once the gaia side of bug 924032 lands.
|
||||
payload.type = "webapps-launch";
|
||||
delete payload.__exposedProps__;
|
||||
shell.sendChromeEvent(payload);
|
||||
});
|
||||
break;
|
||||
case "webapps-ask-install":
|
||||
@ -964,10 +984,14 @@ var WebappsHelper = {
|
||||
});
|
||||
break;
|
||||
case "webapps-close":
|
||||
shell.sendChromeEvent({
|
||||
"type": "webapps-close",
|
||||
"manifestURL": json.manifestURL
|
||||
});
|
||||
shell.sendEvent(shell.getContentWindow(), "webapps-close",
|
||||
{
|
||||
__exposedProps__: { "manifestURL": "r" },
|
||||
"manifestURL": json.manifestURL
|
||||
});
|
||||
// XXX Remove once the gaia side of bug 924032 lands.
|
||||
shell.sendChromeEvent({ type: "webapps-close",
|
||||
"manifestURL": json.manifestURL });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "4cdfe9307db3882da00e49361aa2f6788c9efe54",
|
||||
"revision": "4a8dcbcad9433e7cb0b619d80b041219e5946130",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -4137,7 +4137,7 @@
|
||||
* close many tabs at once.
|
||||
*/
|
||||
let target = event.originalTarget;
|
||||
if (target.className == 'tab-close-button') {
|
||||
if (target.classList.contains('tab-close-button')) {
|
||||
// We preemptively set this to allow the closing-multiple-tabs-
|
||||
// in-a-row case.
|
||||
if (this._blockDblClick) {
|
||||
|
@ -1143,7 +1143,7 @@ SourceScripts.prototype = {
|
||||
if (item) {
|
||||
DebuggerView.Sources.callMethod("checkItem", item.target, !isBlackBoxed);
|
||||
}
|
||||
DebuggerView.Sources.maybeShowBlackBoxMessage();
|
||||
DebuggerView.maybeShowBlackBoxMessage();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1153,17 +1153,27 @@ SourceScripts.prototype = {
|
||||
* The source form.
|
||||
* @param bool aBlackBoxFlag
|
||||
* True to black box the source, false to un-black box it.
|
||||
* @returns Promise
|
||||
* A promize that resolves to [aSource, isBlackBoxed] or rejects to
|
||||
* [aSource, error].
|
||||
*/
|
||||
blackBox: function(aSource, aBlackBoxFlag) {
|
||||
const sourceClient = this.activeThread.source(aSource);
|
||||
sourceClient[aBlackBoxFlag ? "blackBox" : "unblackBox"](({ error, message }) => {
|
||||
const deferred = promise.defer();
|
||||
|
||||
sourceClient[aBlackBoxFlag ? "blackBox" : "unblackBox"](aPacket => {
|
||||
const { error, message } = aPacket;
|
||||
if (error) {
|
||||
let msg = "Couldn't toggle black boxing for " + aSource.url + ": " + message;
|
||||
dumpn(msg);
|
||||
Cu.reportError(msg);
|
||||
return;
|
||||
deferred.reject([aSource, msg]);
|
||||
} else {
|
||||
deferred.resolve([aSource, sourceClient.isBlackBoxed]);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this._cmPopup = document.getElementById("sourceEditorContextMenu");
|
||||
this._cbPanel = document.getElementById("conditional-breakpoint-panel");
|
||||
this._cbTextbox = document.getElementById("conditional-breakpoint-panel-textbox");
|
||||
this._editorDeck = document.getElementById("editor-deck");
|
||||
this._stopBlackBoxButton = document.getElementById("black-boxed-message-button");
|
||||
this._prettyPrintButton = document.getElementById("pretty-print");
|
||||
|
||||
@ -383,6 +382,10 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
* Pretty print the selected source.
|
||||
*/
|
||||
prettyPrint: function() {
|
||||
if (this._prettyPrintButton.hasAttribute("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resetEditor = ([{ url }]) => {
|
||||
// Only set the text when the source is still selected.
|
||||
if (url == this.selectedValue) {
|
||||
@ -397,9 +400,11 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
return;
|
||||
}
|
||||
|
||||
let { source } = this.selectedItem.attachment;
|
||||
let prettyPrinted = DebuggerController.SourceScripts.prettyPrint(source);
|
||||
prettyPrinted.then(resetEditor, printError);
|
||||
DebuggerView.showProgressBar();
|
||||
const { source } = this.selectedItem.attachment;
|
||||
DebuggerController.SourceScripts.prettyPrint(source)
|
||||
.then(resetEditor, printError)
|
||||
.then(DebuggerView.showEditor);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -690,17 +695,21 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
let script = sourceItem.value.split(" -> ").pop();
|
||||
document.title = L10N.getFormatStr("DebuggerWindowScriptTitle", script);
|
||||
|
||||
this.maybeShowBlackBoxMessage();
|
||||
DebuggerView.maybeShowBlackBoxMessage();
|
||||
this._updatePrettyPrintButtonState();
|
||||
},
|
||||
|
||||
/**
|
||||
* Show or hide the black box message vs. source editor depending on if the
|
||||
* selected source is black boxed or not.
|
||||
* Enable or disable the pretty print button depending on whether the selected
|
||||
* source is black boxed or not.
|
||||
*/
|
||||
maybeShowBlackBoxMessage: function() {
|
||||
let sourceForm = this.selectedItem.attachment.source;
|
||||
let sourceClient = DebuggerController.activeThread.source(sourceForm);
|
||||
this._editorDeck.selectedIndex = sourceClient.isBlackBoxed ? 1 : 0;
|
||||
_updatePrettyPrintButtonState: function() {
|
||||
const { source } = this.selectedItem.attachment;
|
||||
if (gThreadClient.source(source).isBlackBoxed) {
|
||||
this._prettyPrintButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
this._prettyPrintButton.removeAttribute("disabled");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -715,8 +724,23 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
* The check listener for the sources container.
|
||||
*/
|
||||
_onSourceCheck: function({ detail: { checked }, target }) {
|
||||
let item = this.getItemForElement(target);
|
||||
DebuggerController.SourceScripts.blackBox(item.attachment.source, !checked);
|
||||
const shouldBlackBox = !checked;
|
||||
|
||||
// Be optimistic that the (un-)black boxing will succeed and enable/disable
|
||||
// the pretty print button immediately. Then, once we actually get the
|
||||
// results from the server, make sure that it is in the correct state again
|
||||
// by calling `_updatePrettyPrintButtonState`.
|
||||
|
||||
if (shouldBlackBox) {
|
||||
this._prettyPrintButton.setAttribute("disabled", true);
|
||||
} else {
|
||||
this._prettyPrintButton.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
const { source } = this.getItemForElement(target).attachment;
|
||||
DebuggerController.SourceScripts.blackBox(source, shouldBlackBox)
|
||||
.then(this._updatePrettyPrintButtonState,
|
||||
this._updatePrettyPrintButtonState);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -114,6 +114,12 @@ let DebuggerView = {
|
||||
this._instrumentsPane = document.getElementById("instruments-pane");
|
||||
this._instrumentsPaneToggleButton = document.getElementById("instruments-pane-toggle");
|
||||
|
||||
this.showEditor = this.showEditor.bind(this);
|
||||
this.showBlackBoxMessage = this.showBlackBoxMessage.bind(this);
|
||||
this.showProgressBar = this.showProgressBar.bind(this);
|
||||
this.maybeShowBlackBoxMessage = this.maybeShowBlackBoxMessage.bind(this);
|
||||
this._editorDeck = document.getElementById("editor-deck");
|
||||
|
||||
this._onTabSelect = this._onInstrumentsPaneTabSelect.bind(this);
|
||||
this._instrumentsPane.tabpanels.addEventListener("select", this._onTabSelect);
|
||||
|
||||
@ -221,6 +227,40 @@ let DebuggerView = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the source editor.
|
||||
*/
|
||||
showEditor: function() {
|
||||
this._editorDeck.selectedIndex = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the black box message.
|
||||
*/
|
||||
showBlackBoxMessage: function() {
|
||||
this._editorDeck.selectedIndex = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the progress bar.
|
||||
*/
|
||||
showProgressBar: function() {
|
||||
this._editorDeck.selectedIndex = 2;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show or hide the black box message vs. source editor depending on if the
|
||||
* selected source is black boxed or not.
|
||||
*/
|
||||
maybeShowBlackBoxMessage: function() {
|
||||
let { source } = DebuggerView.Sources.selectedItem.attachment;
|
||||
if (gThreadClient.source(source).isBlackBoxed) {
|
||||
this.showBlackBoxMessage();
|
||||
} else {
|
||||
this.showEditor();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the currently displayed text contents in the source editor.
|
||||
* This resets the mode and undo stack.
|
||||
@ -522,6 +562,7 @@ let DebuggerView = {
|
||||
_instrumentsPaneToggleButton: null,
|
||||
_collapsePaneString: "",
|
||||
_expandPaneString: "",
|
||||
_editorDeck: null,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -345,6 +345,10 @@
|
||||
image="chrome://browser/skin/devtools/blackBoxMessageEye.png"
|
||||
command="unBlackBoxCommand"/>
|
||||
</vbox>
|
||||
<vbox id="source-progress-container" align="center" pack="center">
|
||||
<progressmeter id="source-progress"
|
||||
mode="undetermined"/>
|
||||
</vbox>
|
||||
</deck>
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
<tabbox id="instruments-pane"
|
||||
|
@ -122,6 +122,7 @@ support-files =
|
||||
[browser_dbg_pretty-print-07.js]
|
||||
[browser_dbg_pretty-print-08.js]
|
||||
[browser_dbg_pretty-print-09.js]
|
||||
[browser_dbg_pretty-print-10.js]
|
||||
[browser_dbg_progress-listener-bug.js]
|
||||
[browser_dbg_reload-preferred-script-01.js]
|
||||
[browser_dbg_reload-preferred-script-02.js]
|
||||
|
@ -24,9 +24,11 @@ function test() {
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_ugly.js");
|
||||
clickPrettyPrintButton();
|
||||
testProgressBarShown();
|
||||
return finished;
|
||||
})
|
||||
.then(testSourceIsPretty)
|
||||
.then(testEditorShown)
|
||||
.then(testSourceIsStillPretty)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
@ -46,11 +48,21 @@ function clickPrettyPrintButton() {
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testProgressBarShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, 2, "The progress bar should be shown");
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
function testEditorShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, 0, "The editor should be shown");
|
||||
}
|
||||
|
||||
function testSourceIsStillPretty() {
|
||||
const deferred = promise.defer();
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that we disable the pretty print button for black boxed sources,
|
||||
* and that clicking it doesn't do anything.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceShown(gPanel, "code_ugly.js")
|
||||
.then(testSourceIsUgly)
|
||||
.then(blackBoxSource)
|
||||
.then(waitForThreadEvents.bind(null, gPanel, "blackboxchange"))
|
||||
.then(clickPrettyPrintButton)
|
||||
.then(testSourceIsStillUgly)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
function blackBoxSource() {
|
||||
const checkbox = gDebugger.document.querySelector(
|
||||
".selected .side-menu-widget-item-checkbox");
|
||||
checkbox.click();
|
||||
}
|
||||
|
||||
function clickPrettyPrintButton() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.getElementById("pretty-print"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testSourceIsStillUgly() {
|
||||
const { source } = gSources.selectedItem.attachment;
|
||||
return gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
|
||||
ok(!text.contains("\n "));
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
@ -30,4 +30,5 @@ support-files =
|
||||
[browser_bug731721_debugger_stepping.js]
|
||||
[browser_bug744021_next_prev_bracket_jump.js]
|
||||
[browser_codemirror.js]
|
||||
skip-if = os == "linux"
|
||||
[browser_sourceeditor_initialization.js]
|
||||
|
@ -26,6 +26,10 @@
|
||||
|
||||
<field name="controller">null</field>
|
||||
|
||||
<!-- collection of child items excluding empty tiles -->
|
||||
<property name="items" readonly="true" onget="return this.querySelectorAll('richgriditem');"/>
|
||||
<property name="itemCount" readonly="true" onget="return this.items.length;"/>
|
||||
|
||||
<!-- nsIDOMXULMultiSelectControlElement (not fully implemented) -->
|
||||
|
||||
<method name="clearSelection">
|
||||
@ -158,8 +162,6 @@
|
||||
|
||||
<!-- nsIDOMXULSelectControlElement -->
|
||||
|
||||
<property name="itemCount" readonly="true" onget="return this.children.length;"/>
|
||||
|
||||
<field name="_selectedItem">null</field>
|
||||
<property name="selectedItem" onget="return this._selectedItem;">
|
||||
<setter>
|
||||
@ -202,7 +204,7 @@
|
||||
<parameter name="aSkipArrange"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let addition = this.createItemElement(aLabel, aValue);
|
||||
let addition = this._createItemElement(aLabel, aValue);
|
||||
this.appendChild(addition);
|
||||
if (!aSkipArrange)
|
||||
this.arrangeItems();
|
||||
@ -232,7 +234,7 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
let existing = this.getItemAtIndex(anIndex);
|
||||
let addition = this.createItemElement(aLabel, aValue);
|
||||
let addition = this._createItemElement(aLabel, aValue);
|
||||
if (existing) {
|
||||
this.insertBefore(addition, existing);
|
||||
} else {
|
||||
@ -250,7 +252,9 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
let item = this.getItemAtIndex(anIndex);
|
||||
return item ? this.removeItem(item, aSkipArrange) : null;
|
||||
if (!item)
|
||||
return null;
|
||||
return this.removeItem(item, aSkipArrange);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -260,7 +264,9 @@
|
||||
<parameter name="aSkipArrange"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let removal = aItem.parentNode == this && this.removeChild(aItem);
|
||||
if (!aItem || Array.indexOf(this.items, aItem) < 0)
|
||||
return null;
|
||||
let removal = this.removeChild(aItem);
|
||||
if (removal && !aSkipArrange)
|
||||
this.arrangeItems();
|
||||
|
||||
@ -271,7 +277,6 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="getIndexOfItem">
|
||||
<parameter name="anItem"/>
|
||||
<body>
|
||||
@ -279,7 +284,7 @@
|
||||
if (!anItem)
|
||||
return -1;
|
||||
|
||||
return Array.indexOf(this.children, anItem);
|
||||
return Array.indexOf(this.items, anItem);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -290,7 +295,7 @@
|
||||
<![CDATA[
|
||||
if (!this._isIndexInBounds(anIndex))
|
||||
return null;
|
||||
return this.children.item(anIndex);
|
||||
return this.items.item(anIndex);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -609,16 +614,18 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="createItemElement">
|
||||
<method name="_createItemElement">
|
||||
<parameter name="aLabel"/>
|
||||
<parameter name="aValue"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let item = this.ownerDocument.createElement("richgriditem");
|
||||
item.setAttribute("label", aLabel);
|
||||
if (aValue) {
|
||||
item.setAttribute("value", aValue);
|
||||
}
|
||||
if (aLabel) {
|
||||
item.setAttribute("label", aLabel);
|
||||
}
|
||||
if(this.hasAttribute("tiletype")) {
|
||||
item.setAttribute("tiletype", this.getAttribute("tiletype"));
|
||||
}
|
||||
@ -860,7 +867,7 @@
|
||||
<property name="control">
|
||||
<getter><![CDATA[
|
||||
let parent = this.parentNode;
|
||||
while (parent) {
|
||||
while (parent && parent != this.ownerDocument.documentElement) {
|
||||
if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
|
||||
return parent;
|
||||
parent = parent.parentNode;
|
||||
|
@ -100,7 +100,7 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
case "pin":
|
||||
let pinIndices = [];
|
||||
Array.forEach(selectedTiles, function(aNode) {
|
||||
pinIndices.push( Array.indexOf(aNode.control.children, aNode) );
|
||||
pinIndices.push( Array.indexOf(aNode.control.items, aNode) );
|
||||
aNode.contextActions.delete('pin');
|
||||
aNode.contextActions.add('unpin');
|
||||
});
|
||||
@ -153,7 +153,6 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
// flush, recreate all
|
||||
this.isUpdating = true;
|
||||
// destroy and recreate all item nodes, skip calling arrangeItems
|
||||
grid.clearAll(true);
|
||||
this.populateGrid();
|
||||
}
|
||||
},
|
||||
@ -165,14 +164,18 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
let filepath = PageThumbsStorage.getFilePathForURL(aSite.url);
|
||||
if (yield OS.File.exists(filepath)) {
|
||||
aSite.backgroundImage = 'url("'+PageThumbs.getThumbnailURL(aSite.url)+'")';
|
||||
aTileNode.setAttribute("customImage", aSite.backgroundImage);
|
||||
if (aTileNode.refresh) {
|
||||
aTileNode.refresh()
|
||||
if ('backgroundImage' in aTileNode) {
|
||||
aTileNode.backgroundImage = aSite.backgroundImage;
|
||||
} else {
|
||||
aTileNode.setAttribute("customImage", aSite.backgroundImage);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
aSite.applyToTileNode(aTileNode);
|
||||
if (aTileNode.refresh) {
|
||||
aTileNode.refresh();
|
||||
}
|
||||
if (aArrangeGrid) {
|
||||
this._set.arrangeItems();
|
||||
}
|
||||
@ -182,24 +185,19 @@ TopSitesView.prototype = Util.extend(Object.create(View.prototype), {
|
||||
this.isUpdating = true;
|
||||
|
||||
let sites = TopSites.getSites();
|
||||
let length = Math.min(sites.length, this._topSitesMax || Infinity);
|
||||
let tileset = this._set;
|
||||
|
||||
// if we're updating with a collection that is smaller than previous
|
||||
// remove any extra tiles
|
||||
while (tileset.children.length > length) {
|
||||
tileset.removeChild(tileset.children[tileset.children.length -1]);
|
||||
if (this._topSitesMax) {
|
||||
sites = sites.slice(0, this._topSitesMax);
|
||||
}
|
||||
let tileset = this._set;
|
||||
tileset.clearAll(true);
|
||||
|
||||
for (let idx=0; idx < length; idx++) {
|
||||
let isNew = !tileset.children[idx],
|
||||
site = sites[idx];
|
||||
let item = isNew ? tileset.createItemElement(site.title, site.url) : tileset.children[idx];
|
||||
for (let site of sites) {
|
||||
// call to private _createItemElement is a temp measure
|
||||
// we'll eventually just request the next slot
|
||||
let item = tileset._createItemElement(site.title, site.url);
|
||||
|
||||
this.updateTile(item, site);
|
||||
if (isNew) {
|
||||
tileset.appendChild(item);
|
||||
}
|
||||
tileset.appendChild(item);
|
||||
}
|
||||
tileset.arrangeItems();
|
||||
this.isUpdating = false;
|
||||
|
@ -18,8 +18,8 @@ gTests.push({
|
||||
ok(grid, "#grid1 is found");
|
||||
is(typeof grid.clearSelection, "function", "#grid1 has the binding applied");
|
||||
|
||||
is(grid.children.length, 2, "#grid1 has a 2 items");
|
||||
is(grid.children[0].control, grid, "#grid1 item's control points back at #grid1'");
|
||||
is(grid.items.length, 2, "#grid1 has a 2 items");
|
||||
is(grid.items[0].control, grid, "#grid1 item's control points back at #grid1'");
|
||||
}
|
||||
});
|
||||
|
||||
@ -29,7 +29,7 @@ gTests.push({
|
||||
let grid = doc.querySelector("#grid1");
|
||||
is(typeof grid.handleItemClick, "function", "grid.handleItemClick is a function");
|
||||
let handleStub = stubMethod(grid, 'handleItemClick');
|
||||
let itemId = "grid1_item1"; // grid.children[0].getAttribute("id");
|
||||
let itemId = "grid1_item1"; // grid.items[0].getAttribute("id");
|
||||
|
||||
// send click to item and wait for next tick;
|
||||
EventUtils.sendMouseEvent({type: 'click'}, itemId, doc.defaultView);
|
||||
@ -114,9 +114,8 @@ gTests.push({
|
||||
grid.clearAll();
|
||||
|
||||
is(grid.itemCount, 0, "grid has 0 itemCount after clearAll");
|
||||
is(grid.children.length, 0, "grid has 0 children after clearAll");
|
||||
is(grid.rowCount, 0, "grid has 0 rows when empty");
|
||||
is(grid.columnCount, 0, "grid has 0 cols when empty");
|
||||
is(grid.items.length, 0, "grid has 0 items after clearAll");
|
||||
// now that we use slots, an empty grid may still have non-zero rows & columns
|
||||
|
||||
is(arrangeSpy.callCount, 1, "arrangeItems is called once when we clearAll");
|
||||
arrangeSpy.restore();
|
||||
@ -150,13 +149,13 @@ gTests.push({
|
||||
let grid = doc.querySelector("#emptygrid");
|
||||
|
||||
is(grid.itemCount, 0, "0 itemCount when empty");
|
||||
is(grid.children.length, 0, "0 children when empty");
|
||||
is(grid.items.length, 0, "0 items when empty");
|
||||
is(typeof grid.appendItem, "function", "appendItem is a function on the grid");
|
||||
|
||||
let arrangeStub = stubMethod(grid, "arrangeItems");
|
||||
let newItem = grid.appendItem("test title", "about:blank");
|
||||
|
||||
ok(newItem && grid.children[0]==newItem, "appendItem gives back the item");
|
||||
ok(newItem && grid.items[0]==newItem, "appendItem gives back the item");
|
||||
is(grid.itemCount, 1, "itemCount is incremented when we appendItem");
|
||||
is(newItem.getAttribute("label"), "test title", "title ends up on label attribute");
|
||||
is(newItem.getAttribute("value"), "about:blank", "url ends up on value attribute");
|
||||
@ -193,7 +192,7 @@ gTests.push({
|
||||
|
||||
ok(removedItem, "removeItemAt gives back an item");
|
||||
is(removedItem.getAttribute("id"), "grid2_item1", "removeItemAt gives back the correct item");
|
||||
is(grid.children[0].getAttribute("id"), "grid2_item2", "2nd item becomes the first item");
|
||||
is(grid.items[0].getAttribute("id"), "grid2_item2", "2nd item becomes the first item");
|
||||
is(grid.itemCount, 1, "itemCount is decremented when we removeItemAt");
|
||||
|
||||
is(arrangeStub.callCount, 1, "arrangeItems is called when we removeItemAt");
|
||||
@ -215,10 +214,10 @@ gTests.push({
|
||||
let insertedItem = grid.insertItemAt(1, "inserted item", "http://example.com/inserted");
|
||||
|
||||
ok(insertedItem, "insertItemAt gives back an item");
|
||||
is(grid.children[1], insertedItem, "item is inserted at the correct index");
|
||||
is(grid.items[1], insertedItem, "item is inserted at the correct index");
|
||||
is(insertedItem.getAttribute("label"), "inserted item", "insertItemAt creates item with the correct label");
|
||||
is(insertedItem.getAttribute("value"), "http://example.com/inserted", "insertItemAt creates item with the correct url value");
|
||||
is(grid.children[2].getAttribute("id"), "grid3_item2", "following item ends up at the correct index");
|
||||
is(grid.items[2].getAttribute("id"), "grid3_item2", "following item ends up at the correct index");
|
||||
is(grid.itemCount, 3, "itemCount is incremented when we insertItemAt");
|
||||
|
||||
is(arrangeStub.callCount, 1, "arrangeItems is called when we insertItemAt");
|
||||
@ -275,11 +274,11 @@ gTests.push({
|
||||
is(typeof grid.removeItem, "function", "removeItem is a function on the grid");
|
||||
|
||||
let arrangeStub = stubMethod(grid, "arrangeItems");
|
||||
let removedFirst = grid.removeItem( grid.children[0] );
|
||||
let removedFirst = grid.removeItem( grid.items[0] );
|
||||
|
||||
is(arrangeStub.callCount, 1, "arrangeItems is called when we removeItem");
|
||||
|
||||
let removed2nd = grid.removeItem( grid.children[0], true);
|
||||
let removed2nd = grid.removeItem( grid.items[0], true);
|
||||
is(removed2nd.getAttribute("label"), "2nd item", "the next item was returned");
|
||||
is(grid.itemCount, 2, "2 items remain");
|
||||
|
||||
@ -316,23 +315,23 @@ gTests.push({
|
||||
is(grid.itemCount, 2, "2 items initially");
|
||||
is(grid.selectedItems.length, 0, "nothing selected initially");
|
||||
|
||||
grid.toggleItemSelection(grid.children[1]);
|
||||
ok(grid.children[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
|
||||
grid.toggleItemSelection(grid.items[1]);
|
||||
ok(grid.items[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
|
||||
is(grid.selectedIndex, 1, "selectedIndex is correct");
|
||||
|
||||
grid.toggleItemSelection(grid.children[1]);
|
||||
ok(!grid.children[1].selected, "toggleItemSelection sets falsy selected prop on previously-selected item");
|
||||
grid.toggleItemSelection(grid.items[1]);
|
||||
ok(!grid.items[1].selected, "toggleItemSelection sets falsy selected prop on previously-selected item");
|
||||
is(grid.selectedIndex, -1, "selectedIndex reports correctly with nothing selected");
|
||||
|
||||
// item selection
|
||||
grid.selectItem(grid.children[1]);
|
||||
ok(grid.children[1].selected, "Item selected property is truthy after grid.selectItem");
|
||||
ok(grid.children[1].getAttribute("selected"), "Item selected attribute is truthy after grid.selectItem");
|
||||
grid.selectItem(grid.items[1]);
|
||||
ok(grid.items[1].selected, "Item selected property is truthy after grid.selectItem");
|
||||
ok(grid.items[1].getAttribute("selected"), "Item selected attribute is truthy after grid.selectItem");
|
||||
ok(grid.selectedItems.length, "There are selectedItems after grid.selectItem");
|
||||
|
||||
// clearSelection
|
||||
grid.selectItem(grid.children[0]);
|
||||
grid.selectItem(grid.children[1]);
|
||||
grid.selectItem(grid.items[0]);
|
||||
grid.selectItem(grid.items[1]);
|
||||
grid.clearSelection();
|
||||
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
|
||||
is(grid.selectedIndex, -1, "selectedIndex resets after clearSelection");
|
||||
@ -347,10 +346,10 @@ gTests.push({
|
||||
doc.defaultView.addEventListener("select", handler, false);
|
||||
info("select listener added");
|
||||
|
||||
info("calling selectItem, currently it is:" + grid.children[0].selected);
|
||||
info("calling selectItem, currently it is:" + grid.items[0].selected);
|
||||
// Note: A richgrid in seltype=single mode fires "select" events from selectItem
|
||||
grid.selectItem(grid.children[0]);
|
||||
info("calling selectItem, now it is:" + grid.children[0].selected);
|
||||
grid.selectItem(grid.items[0]);
|
||||
info("calling selectItem, now it is:" + grid.items[0].selected);
|
||||
yield waitForMs(0);
|
||||
|
||||
is(handlerStub.callCount, 1, "select event handler was called when we selected an item");
|
||||
@ -378,22 +377,22 @@ gTests.push({
|
||||
is(grid.itemCount, 2, "2 items initially");
|
||||
is(grid.selectedItems.length, 0, "nothing selected initially");
|
||||
|
||||
grid.toggleItemSelection(grid.children[1]);
|
||||
ok(grid.children[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
|
||||
grid.toggleItemSelection(grid.items[1]);
|
||||
ok(grid.items[1].selected, "toggleItemSelection sets truthy selected prop on previously-unselected item");
|
||||
is(grid.selectedItems.length, 1, "1 item selected when we first toggleItemSelection");
|
||||
is(grid.selectedItems[0], grid.children[1], "the right item is selected");
|
||||
is(grid.selectedItems[0], grid.items[1], "the right item is selected");
|
||||
is(grid.selectedIndex, 1, "selectedIndex is correct");
|
||||
|
||||
grid.toggleItemSelection(grid.children[1]);
|
||||
grid.toggleItemSelection(grid.items[1]);
|
||||
is(grid.selectedItems.length, 0, "Nothing selected when we toggleItemSelection again");
|
||||
|
||||
// clearSelection
|
||||
grid.children[0].selected=true;
|
||||
grid.children[1].selected=true;
|
||||
grid.items[0].selected=true;
|
||||
grid.items[1].selected=true;
|
||||
is(grid.selectedItems.length, 2, "Both items are selected before calling clearSelection");
|
||||
grid.clearSelection();
|
||||
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
|
||||
ok(!(grid.children[0].selected || grid.children[1].selected), "selected properties all falsy when we clearSelection");
|
||||
ok(!(grid.items[0].selected || grid.items[1].selected), "selected properties all falsy when we clearSelection");
|
||||
|
||||
// selectionchange events
|
||||
// in seltype=multiple mode, we track selected state on all items
|
||||
@ -405,10 +404,10 @@ gTests.push({
|
||||
doc.defaultView.addEventListener("selectionchange", handler, false);
|
||||
info("selectionchange listener added");
|
||||
|
||||
info("calling toggleItemSelection, currently it is:" + grid.children[0].selected);
|
||||
info("calling toggleItemSelection, currently it is:" + grid.items[0].selected);
|
||||
// Note: A richgrid in seltype=single mode fires "select" events from selectItem
|
||||
grid.toggleItemSelection(grid.children[0]);
|
||||
info("/calling toggleItemSelection, now it is:" + grid.children[0].selected);
|
||||
grid.toggleItemSelection(grid.items[0]);
|
||||
info("/calling toggleItemSelection, now it is:" + grid.items[0].selected);
|
||||
yield waitForMs(0);
|
||||
|
||||
is(handlerStub.callCount, 1, "selectionchange event handler was called when we selected an item");
|
||||
@ -418,6 +417,3 @@ gTests.push({
|
||||
doc.defaultView.removeEventListener("selectionchange", handler, false);
|
||||
}
|
||||
});
|
||||
|
||||
// implements a getItemAtIndex method (or grid.children[idx] ?)
|
||||
|
||||
|
@ -194,7 +194,7 @@ gTests.push({
|
||||
},
|
||||
run: function() {
|
||||
let grid = TopSitesTestHelper.grid;
|
||||
let items = grid.children;
|
||||
let items = grid.items;
|
||||
is(items.length, 8, "should be 8 topsites"); // i.e. not 10
|
||||
if(items.length) {
|
||||
let firstitem = items[0];
|
||||
@ -230,7 +230,7 @@ gTests.push({
|
||||
run: function() {
|
||||
// test that pinned state of each site as rendered matches our expectations
|
||||
let pins = this.pins.split(",");
|
||||
let items = TopSitesTestHelper.grid.children;
|
||||
let items = TopSitesTestHelper.grid.items;
|
||||
is(items.length, 8, "should be 8 topsites in the grid");
|
||||
|
||||
is(TopSitesTestHelper.document.querySelectorAll("#start-topsites-grid > [pinned]").length, 3, "should be 3 children with 'pinned' attribute");
|
||||
@ -273,10 +273,10 @@ gTests.push({
|
||||
// test that site is pinned as expected
|
||||
// and that sites fill positions around it
|
||||
let grid = TopSitesTestHelper.grid,
|
||||
items = grid.children;
|
||||
items = grid.items;
|
||||
is(items.length, 4, this.desc + ": should be 4 topsites");
|
||||
|
||||
let tile = grid.children[2],
|
||||
let tile = grid.items[2],
|
||||
url = tile.getAttribute("value"),
|
||||
title = tile.getAttribute("label");
|
||||
|
||||
@ -291,7 +291,7 @@ gTests.push({
|
||||
return !grid.controller.isUpdating;
|
||||
});
|
||||
|
||||
let thirdTile = grid.children[2];
|
||||
let thirdTile = grid.items[2];
|
||||
ok( thirdTile.hasAttribute("pinned"), thirdTile.getAttribute("value")+ " should look pinned" );
|
||||
|
||||
// visit some more sites
|
||||
@ -329,7 +329,7 @@ gTests.push({
|
||||
// unpin a pinned site
|
||||
// test that sites are unpinned as expected
|
||||
let grid = TopSitesTestHelper.grid,
|
||||
items = grid.children;
|
||||
items = grid.items;
|
||||
is(items.length, 8, this.desc + ": should be 8 topsites");
|
||||
let site = {
|
||||
url: items[1].getAttribute("value"),
|
||||
@ -346,7 +346,7 @@ gTests.push({
|
||||
return !grid.controller.isUpdating;
|
||||
});
|
||||
|
||||
let secondTile = grid.children[1];
|
||||
let secondTile = grid.items[1];
|
||||
ok( !secondTile.hasAttribute("pinned"), "2nd item should no longer be marked as pinned" );
|
||||
ok( !NewTabUtils.pinnedLinks.isPinned(site), "2nd item should no longer be pinned" );
|
||||
}
|
||||
@ -371,7 +371,7 @@ gTests.push({
|
||||
// block a site
|
||||
// test that sites are removed from the grid as expected
|
||||
let grid = TopSitesTestHelper.grid,
|
||||
items = grid.children;
|
||||
items = grid.items;
|
||||
is(items.length, 8, this.desc + ": should be 8 topsites");
|
||||
|
||||
let brianSite = TopSitesTestHelper.siteFromNode(items[0]);
|
||||
@ -426,7 +426,7 @@ gTests.push({
|
||||
is( grid.querySelectorAll("[value='"+dougalSite.url+"']").length, 1, "Unblocked site is back in the grid");
|
||||
// ..and that a previously pinned site is re-pinned after being blocked, then restored
|
||||
ok( NewTabUtils.pinnedLinks.isPinned(dougalSite), "Restoring previously pinned site makes it pinned again" );
|
||||
is( grid.children[1].getAttribute("value"), dougalSite.url, "Blocked Site restored to pinned index" );
|
||||
is( grid.items[1].getAttribute("value"), dougalSite.url, "Blocked Site restored to pinned index" );
|
||||
|
||||
ok( !NewTabUtils.blockedLinks.isBlocked(dylanSite), "site was unblocked" );
|
||||
is( grid.querySelectorAll("[value='"+dylanSite.url+"']").length, 1, "Unblocked site is back in the grid");
|
||||
@ -458,7 +458,7 @@ gTests.push({
|
||||
// delete a both pinned and unpinned sites
|
||||
// test that sites are removed from the grid
|
||||
let grid = TopSitesTestHelper.grid,
|
||||
items = grid.children;
|
||||
items = grid.items;
|
||||
is(items.length, 4, this.desc + ": should be 4 topsites");
|
||||
|
||||
let brianTile = grid.querySelector('richgriditem[value$="brian"]');
|
||||
|
@ -66,9 +66,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Black box message */
|
||||
/* Black box message and source progress meter */
|
||||
|
||||
#black-boxed-message {
|
||||
#black-boxed-message,
|
||||
#source-progress-container {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
@ -76,6 +77,11 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
#source-progress {
|
||||
min-height: 2em;
|
||||
min-width: 40em;
|
||||
}
|
||||
|
||||
#black-boxed-message-label,
|
||||
#black-boxed-message-button {
|
||||
text-align: center;
|
||||
|
@ -64,9 +64,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Black box message */
|
||||
/* Black box message and source progress meter */
|
||||
|
||||
#black-boxed-message {
|
||||
#black-boxed-message,
|
||||
#source-progress-container {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
@ -74,6 +75,11 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
#source-progress {
|
||||
min-height: 2em;
|
||||
min-width: 40em;
|
||||
}
|
||||
|
||||
#black-boxed-message-label,
|
||||
#black-boxed-message-button {
|
||||
text-align: center;
|
||||
|
@ -64,9 +64,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Black box message */
|
||||
/* Black box message and source progress meter */
|
||||
|
||||
#black-boxed-message {
|
||||
#black-boxed-message,
|
||||
#source-progress-container {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
@ -74,6 +75,11 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
#source-progress {
|
||||
min-height: 2em;
|
||||
min-width: 40em;
|
||||
}
|
||||
|
||||
#black-boxed-message-label,
|
||||
#black-boxed-message-button {
|
||||
text-align: center;
|
||||
|
@ -340,6 +340,26 @@ abstract public class BrowserApp extends GeckoApp
|
||||
});
|
||||
}
|
||||
|
||||
void handleReaderListStatusRequest(final String url) {
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int inReadingList = BrowserDB.isReadingListItem(getContentResolver(), url) ? 1 : 0;
|
||||
|
||||
final JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put("url", url);
|
||||
json.put("inReadingList", inReadingList);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "JSON error - failed to return inReadingList status", e);
|
||||
return;
|
||||
}
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Reader:ListStatusReturn", json.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void handleReaderAdded(int result, final String title, final String url) {
|
||||
if (result != READER_ADD_SUCCESS) {
|
||||
if (result == READER_ADD_FAILED) {
|
||||
@ -1104,6 +1124,8 @@ abstract public class BrowserApp extends GeckoApp
|
||||
Telemetry.HistogramAdd("FENNEC_THUMBNAILS_COUNT", BrowserDB.getCount(getContentResolver(), "thumbnails"));
|
||||
} else if (event.equals("Reader:ListCountRequest")) {
|
||||
handleReaderListCountRequest();
|
||||
} else if (event.equals("Reader:ListStatusRequest")) {
|
||||
handleReaderListStatusRequest(message.getString("url"));
|
||||
} else if (event.equals("Reader:Added")) {
|
||||
final int result = message.getInt("result");
|
||||
final String title = message.getString("title");
|
||||
|
@ -1461,6 +1461,7 @@ abstract public class GeckoApp
|
||||
//register for events
|
||||
registerEventListener("log");
|
||||
registerEventListener("Reader:ListCountRequest");
|
||||
registerEventListener("Reader:ListStatusRequest");
|
||||
registerEventListener("Reader:Added");
|
||||
registerEventListener("Reader:Removed");
|
||||
registerEventListener("Reader:Share");
|
||||
@ -1996,6 +1997,7 @@ abstract public class GeckoApp
|
||||
{
|
||||
unregisterEventListener("log");
|
||||
unregisterEventListener("Reader:ListCountRequest");
|
||||
unregisterEventListener("Reader:ListStatusRequest");
|
||||
unregisterEventListener("Reader:Added");
|
||||
unregisterEventListener("Reader:Removed");
|
||||
unregisterEventListener("Reader:Share");
|
||||
|
@ -33,6 +33,7 @@ public class NotificationHandler {
|
||||
* one download is in progress.
|
||||
*/
|
||||
private Notification mForegroundNotification;
|
||||
private int mForegroundNotificationId;
|
||||
|
||||
public NotificationHandler(Context context) {
|
||||
mContext = context;
|
||||
@ -168,23 +169,26 @@ public class NotificationHandler {
|
||||
}
|
||||
|
||||
protected void setForegroundNotification(int id, Notification notification) {
|
||||
mForegroundNotificationId = id;
|
||||
mForegroundNotification = notification;
|
||||
}
|
||||
|
||||
private void updateForegroundNotification(int id, Notification oldNotification) {
|
||||
if (mForegroundNotification == oldNotification) {
|
||||
private void updateForegroundNotification(int oldId, Notification oldNotification) {
|
||||
if (mForegroundNotificationId == oldId) {
|
||||
// If we're removing the notification associated with the
|
||||
// foreground, we need to pick another active notification to act
|
||||
// as the foreground notification.
|
||||
Notification foregroundNotification = null;
|
||||
for (final Notification notification : mNotifications.values()) {
|
||||
int foregroundId = 0;
|
||||
for (final Integer id : mNotifications.keySet()) {
|
||||
final Notification notification = mNotifications.get(id);
|
||||
if (isOngoing(notification)) {
|
||||
foregroundNotification = notification;
|
||||
foregroundId = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setForegroundNotification(id, foregroundNotification);
|
||||
setForegroundNotification(foregroundId, foregroundNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,13 +62,12 @@ public class ReaderModeUtils {
|
||||
return urlFromAboutReader.equals(currentUrl);
|
||||
}
|
||||
|
||||
public static String getAboutReaderForUrl(String url, boolean inReadingList) {
|
||||
return getAboutReaderForUrl(url, -1, inReadingList);
|
||||
public static String getAboutReaderForUrl(String url) {
|
||||
return getAboutReaderForUrl(url, -1);
|
||||
}
|
||||
|
||||
public static String getAboutReaderForUrl(String url, int tabId, boolean inReadingList) {
|
||||
String aboutReaderUrl = "about:reader?url=" + Uri.encode(url) +
|
||||
"&readingList=" + (inReadingList ? 1 : 0);
|
||||
public static String getAboutReaderForUrl(String url, int tabId) {
|
||||
String aboutReaderUrl = "about:reader?url=" + Uri.encode(url);
|
||||
|
||||
if (tabId >= 0)
|
||||
aboutReaderUrl += "&tabId=" + tabId;
|
||||
|
@ -464,7 +464,7 @@ public class Tab {
|
||||
Tabs.getInstance().loadUrl(ReaderModeUtils.getUrlFromAboutReader(mUrl));
|
||||
} else if (mReaderEnabled) {
|
||||
mEnteringReaderMode = true;
|
||||
Tabs.getInstance().loadUrl(ReaderModeUtils.getAboutReaderForUrl(mUrl, mId, mReadingListItem));
|
||||
Tabs.getInstance().loadUrl(ReaderModeUtils.getAboutReaderForUrl(mUrl, mId));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,6 +351,7 @@ public class Favicons {
|
||||
"/favicon.ico", null,
|
||||
null).toString();
|
||||
} catch (URISyntaxException e) {
|
||||
Log.e(LOGTAG, "URISyntaxException getting default favicon URL", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +234,10 @@ public class LoadFaviconTask extends UiAsyncTask<Void, Void, Bitmap> {
|
||||
} else {
|
||||
// If we don't have a stored one, fall back to the default.
|
||||
mFaviconUrl = Favicons.guessDefaultFaviconURL(mPageUrl);
|
||||
|
||||
if (TextUtils.isEmpty(mFaviconUrl)) {
|
||||
return null;
|
||||
}
|
||||
isUsingDefaultURL = true;
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +205,10 @@ public class FaviconCache {
|
||||
* @return true if this favicon is blacklisted, false otherwise.
|
||||
*/
|
||||
public boolean isFailedFavicon(String faviconURL) {
|
||||
if (faviconURL == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
startRead();
|
||||
|
||||
boolean isExpired = false;
|
||||
@ -241,7 +245,7 @@ public class FaviconCache {
|
||||
// Flag to prevent finally from doubly-unlocking.
|
||||
isAborting = true;
|
||||
Log.e(LOGTAG, "FaviconCache exception!", unhandled);
|
||||
return false;
|
||||
return true;
|
||||
} finally {
|
||||
if (!isAborting) {
|
||||
if (isExpired) {
|
||||
|
@ -153,7 +153,7 @@ abstract class HomeFragment extends Fragment {
|
||||
if (item.getItemId() == R.id.home_open_private_tab)
|
||||
flags |= Tabs.LOADURL_PRIVATE;
|
||||
|
||||
final String url = (info.inReadingList ? ReaderModeUtils.getAboutReaderForUrl(info.url, true) : info.url);
|
||||
final String url = (info.inReadingList ? ReaderModeUtils.getAboutReaderForUrl(info.url) : info.url);
|
||||
Tabs.getInstance().loadUrl(url, flags);
|
||||
Toast.makeText(context, R.string.new_tab_opened, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
@ -166,7 +166,7 @@ abstract class HomeFragment extends Fragment {
|
||||
}
|
||||
|
||||
if (itemId == R.id.home_open_in_reader) {
|
||||
final String url = ReaderModeUtils.getAboutReaderForUrl(info.url, true);
|
||||
final String url = ReaderModeUtils.getAboutReaderForUrl(info.url);
|
||||
Tabs.getInstance().loadUrl(url, Tabs.LOADURL_NONE);
|
||||
return true;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public class ReadingListPage extends HomeFragment {
|
||||
}
|
||||
|
||||
String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL));
|
||||
url = ReaderModeUtils.getAboutReaderForUrl(url, true);
|
||||
url = ReaderModeUtils.getAboutReaderForUrl(url);
|
||||
|
||||
// This item is a TwoLinePageRow, so we allow switch-to-tab.
|
||||
mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB));
|
||||
|
@ -58,10 +58,12 @@ public class testBookmark extends AboutHomeTest {
|
||||
boolean bookmarked = waitForTest(new BooleanTest() {
|
||||
@Override
|
||||
public boolean test() {
|
||||
return mDatabaseHelper.isBookmark(BOOKMARK_URL);
|
||||
return (isBookmarked) ?
|
||||
mDatabaseHelper.isBookmark(BOOKMARK_URL) :
|
||||
!mDatabaseHelper.isBookmark(BOOKMARK_URL);
|
||||
}
|
||||
}, WAIT_FOR_BOOKMARKED_TIMEOUT);
|
||||
mAsserter.is(bookmarked, isBookmarked, BOOKMARK_URL + " was " + (bookmarked ? "added as a bookmark" : "removed from bookmarks"));
|
||||
mAsserter.is(bookmarked, true, BOOKMARK_URL + " was " + (isBookmarked ? "added as a bookmark" : "removed from bookmarks"));
|
||||
}
|
||||
|
||||
private void setUpBookmark() {
|
||||
|
@ -33,6 +33,7 @@ let AboutReader = function(doc, win) {
|
||||
Services.obs.addObserver(this, "Reader:Remove", false);
|
||||
Services.obs.addObserver(this, "Reader:ListCountReturn", false);
|
||||
Services.obs.addObserver(this, "Reader:ListCountUpdated", false);
|
||||
Services.obs.addObserver(this, "Reader:ListStatusReturn", false);
|
||||
|
||||
this._article = null;
|
||||
|
||||
@ -119,11 +120,12 @@ let AboutReader = function(doc, win) {
|
||||
dump("Decoding query arguments");
|
||||
let queryArgs = this._decodeQueryString(win.location.href);
|
||||
|
||||
this._isReadingListItem = (queryArgs.readingList == "1");
|
||||
// Track status of reader toolbar add/remove toggle button
|
||||
this._isReadingListItem = -1;
|
||||
this._updateToggleButton();
|
||||
|
||||
// Track status of reader toolbar list button
|
||||
this._readingListCount = 0;
|
||||
this._readingListCount = -1;
|
||||
this._updateListButton();
|
||||
this._requestReadingListCount();
|
||||
|
||||
@ -192,8 +194,8 @@ AboutReader.prototype = {
|
||||
case "Reader:Add": {
|
||||
let args = JSON.parse(aData);
|
||||
if (args.url == this._article.url) {
|
||||
if (!this._isReadingListItem) {
|
||||
this._isReadingListItem = true;
|
||||
if (this._isReadingListItem != 1) {
|
||||
this._isReadingListItem = 1;
|
||||
this._updateToggleButton();
|
||||
}
|
||||
}
|
||||
@ -202,8 +204,8 @@ AboutReader.prototype = {
|
||||
|
||||
case "Reader:Remove": {
|
||||
if (aData == this._article.url) {
|
||||
if (this._isReadingListItem) {
|
||||
this._isReadingListItem = false;
|
||||
if (this._isReadingListItem != 0) {
|
||||
this._isReadingListItem = 0;
|
||||
this._updateToggleButton();
|
||||
}
|
||||
}
|
||||
@ -211,11 +213,39 @@ AboutReader.prototype = {
|
||||
}
|
||||
|
||||
case "Reader:ListCountReturn":
|
||||
case "Reader:ListCountUpdated": {
|
||||
case "Reader:ListCountUpdated": {
|
||||
let count = parseInt(aData);
|
||||
if (this._readingListCount != count) {
|
||||
let isInitialStateChange = (this._readingListCount == -1);
|
||||
this._readingListCount = count;
|
||||
this._updateListButton();
|
||||
|
||||
// Display the toolbar when all its initial component states are known
|
||||
if (isInitialStateChange) {
|
||||
this._setToolbarVisibility(true);
|
||||
}
|
||||
|
||||
// Initial readinglist count is requested before any page is displayed
|
||||
if (this._article) {
|
||||
this._requestReadingListStatus();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Reader:ListStatusReturn": {
|
||||
let args = JSON.parse(aData);
|
||||
if (args.url == this._article.url) {
|
||||
if (this._isReadingListItem != args.inReadingList) {
|
||||
let isInitialStateChange = (this._isReadingListItem == -1);
|
||||
this._isReadingListItem = args.inReadingList;
|
||||
this._updateToggleButton();
|
||||
|
||||
// Display the toolbar when all its initial component states are known
|
||||
if (isInitialStateChange) {
|
||||
this._setToolbarVisibility(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -257,6 +287,7 @@ AboutReader.prototype = {
|
||||
Services.obs.removeObserver(this, "Reader:Remove");
|
||||
Services.obs.removeObserver(this, "Reader:ListCountReturn");
|
||||
Services.obs.removeObserver(this, "Reader:ListCountUpdated");
|
||||
Services.obs.removeObserver(this, "Reader:ListStatusReturn");
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -264,7 +295,7 @@ AboutReader.prototype = {
|
||||
_updateToggleButton: function Reader_updateToggleButton() {
|
||||
let classes = this._doc.getElementById("toggle-button").classList;
|
||||
|
||||
if (this._isReadingListItem) {
|
||||
if (this._isReadingListItem == 1) {
|
||||
classes.add("on");
|
||||
} else {
|
||||
classes.remove("on");
|
||||
@ -285,14 +316,21 @@ AboutReader.prototype = {
|
||||
gChromeWin.sendMessageToJava({ type: "Reader:ListCountRequest" });
|
||||
},
|
||||
|
||||
_requestReadingListStatus: function Reader_requestReadingListStatus() {
|
||||
gChromeWin.sendMessageToJava({
|
||||
type: "Reader:ListStatusRequest",
|
||||
url: this._article.url
|
||||
});
|
||||
},
|
||||
|
||||
_onReaderToggle: function Reader_onToggle() {
|
||||
if (!this._article)
|
||||
return;
|
||||
|
||||
this._isReadingListItem = !this._isReadingListItem;
|
||||
this._isReadingListItem = (this._isReadingListItem == 1) ? 0 : 1;
|
||||
this._updateToggleButton();
|
||||
|
||||
if (this._isReadingListItem) {
|
||||
if (this._isReadingListItem == 1) {
|
||||
gChromeWin.Reader.storeArticleInCache(this._article, function(success) {
|
||||
dump("Reader:Add (in reader) success=" + success);
|
||||
|
||||
@ -324,7 +362,7 @@ AboutReader.prototype = {
|
||||
},
|
||||
|
||||
_onList: function Reader_onList() {
|
||||
if (!this._article || this._readingListCount == 0)
|
||||
if (!this._article || this._readingListCount < 1)
|
||||
return;
|
||||
|
||||
gChromeWin.sendMessageToJava({ type: "Reader:GoToReadingList" });
|
||||
@ -455,6 +493,10 @@ AboutReader.prototype = {
|
||||
if (!this._toolbarEnabled)
|
||||
return;
|
||||
|
||||
// Don't allow visible toolbar until banner state is known
|
||||
if (this._readingListCount == -1 || this._isReadingListItem == -1)
|
||||
return;
|
||||
|
||||
if (this._getToolbarVisibility() === visible)
|
||||
return;
|
||||
|
||||
@ -622,6 +664,7 @@ AboutReader.prototype = {
|
||||
this._maybeSetTextDirection(article);
|
||||
|
||||
this._contentElement.style.display = "block";
|
||||
this._requestReadingListStatus();
|
||||
|
||||
this._toolbarEnabled = true;
|
||||
this._setToolbarVisibility(true);
|
||||
|
@ -95,7 +95,8 @@ var Downloads = {
|
||||
smallIcon: URI_GENERIC_ICON_DOWNLOAD,
|
||||
text: aMessage,
|
||||
ongoing: false,
|
||||
cookie: aDownload.guid
|
||||
cookie: aDownload.guid,
|
||||
when: aDownload.startTime
|
||||
};
|
||||
|
||||
if (aOptions && aOptions.icon) {
|
||||
|
@ -163,7 +163,7 @@ FilePicker.prototype = {
|
||||
|
||||
show: function() {
|
||||
if (this._domWin) {
|
||||
PromptUtils.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
||||
this.fireDialogEvent(this._domWin, "DOMWillOpenModalDialog");
|
||||
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.enterModalState();
|
||||
}
|
||||
@ -176,6 +176,12 @@ FilePicker.prototype = {
|
||||
thread.processNextEvent(true);
|
||||
delete this._promptActive;
|
||||
|
||||
if (this._domWin) {
|
||||
let winUtils = this._domWin.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.leaveModalState();
|
||||
this.fireDialogEvent(this._domWin, "DOMModalDialogClosed");
|
||||
}
|
||||
|
||||
if (this._filePath)
|
||||
return Ci.nsIFilePicker.returnOK;
|
||||
|
||||
@ -245,6 +251,20 @@ FilePicker.prototype = {
|
||||
};
|
||||
},
|
||||
|
||||
fireDialogEvent: function(aDomWin, aEventName) {
|
||||
// accessing the document object can throw if this window no longer exists. See bug 789888.
|
||||
try {
|
||||
if (!aDomWin.document)
|
||||
return;
|
||||
let event = aDomWin.document.createEvent("Events");
|
||||
event.initEvent(aEventName, true, true);
|
||||
let winUtils = aDomWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
winUtils.dispatchEventToChromeOnly(aDomWin, event);
|
||||
} catch(ex) {
|
||||
}
|
||||
},
|
||||
|
||||
classID: Components.ID("{18a4e042-7c7c-424b-a583-354e68553a7f}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker, Ci.nsIObserver])
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user