mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge m-c to fx-team
This commit is contained in:
commit
45bef14fbd
@ -2090,9 +2090,6 @@ SessionStoreService.prototype = {
|
||||
_updateTextAndScrollData: function sss_updateTextAndScrollData(aWindow) {
|
||||
var browsers = aWindow.gBrowser.browsers;
|
||||
this._windows[aWindow.__SSi].tabs.forEach(function (tabData, i) {
|
||||
if (browsers[i].__SS_data &&
|
||||
browsers[i].__SS_tabStillLoading)
|
||||
return; // ignore incompletely initialized tabs
|
||||
try {
|
||||
this._updateTextAndScrollDataForTab(aWindow, browsers[i], tabData);
|
||||
}
|
||||
@ -2114,6 +2111,10 @@ SessionStoreService.prototype = {
|
||||
*/
|
||||
_updateTextAndScrollDataForTab:
|
||||
function sss_updateTextAndScrollDataForTab(aWindow, aBrowser, aTabData, aFullData) {
|
||||
// we shouldn't update data for incompletely initialized tabs
|
||||
if (aBrowser.__SS_data && aBrowser.__SS_tabStillLoading)
|
||||
return;
|
||||
|
||||
var tabIndex = (aTabData.index || aTabData.entries.length) - 1;
|
||||
// entry data needn't exist for tabs just initialized with an incomplete session state
|
||||
if (!aTabData.entries[tabIndex])
|
||||
@ -2734,6 +2735,8 @@ SessionStoreService.prototype = {
|
||||
if (aOverwriteTabs && tabbrowser.selectedTab._tPos >= newTabCount)
|
||||
tabbrowser.moveTabTo(tabbrowser.selectedTab, newTabCount - 1);
|
||||
|
||||
let numVisibleTabs = 0;
|
||||
|
||||
for (var t = 0; t < newTabCount; t++) {
|
||||
tabs.push(t < openTabCount ?
|
||||
tabbrowser.tabs[t] :
|
||||
@ -2746,10 +2749,19 @@ SessionStoreService.prototype = {
|
||||
if (winData.tabs[t].pinned)
|
||||
tabbrowser.pinTab(tabs[t]);
|
||||
|
||||
if (winData.tabs[t].hidden)
|
||||
if (winData.tabs[t].hidden) {
|
||||
tabbrowser.hideTab(tabs[t]);
|
||||
else
|
||||
}
|
||||
else {
|
||||
tabbrowser.showTab(tabs[t]);
|
||||
numVisibleTabs++;
|
||||
}
|
||||
}
|
||||
|
||||
// if all tabs to be restored are hidden, make the first one visible
|
||||
if (!numVisibleTabs && winData.tabs.length) {
|
||||
winData.tabs[0].hidden = false;
|
||||
tabbrowser.showTab(tabs[0]);
|
||||
}
|
||||
|
||||
// If overwriting tabs, we want to reset each tab's "restoring" state. Since
|
||||
@ -2879,10 +2891,7 @@ SessionStoreService.prototype = {
|
||||
|
||||
let unhiddenTabs = aTabData.filter(function (aData) !aData.hidden).length;
|
||||
|
||||
// if all tabs to be restored are hidden, make the first one visible
|
||||
if (unhiddenTabs == 0) {
|
||||
aTabData[0].hidden = false;
|
||||
} else if (aTabs.length > 1) {
|
||||
if (unhiddenTabs && aTabs.length > 1) {
|
||||
// Load hidden tabs last, by pushing them to the end of the list
|
||||
for (let t = 0, tabsToReorder = aTabs.length - unhiddenTabs; tabsToReorder > 0; ) {
|
||||
if (aTabData[t].hidden) {
|
||||
|
@ -159,8 +159,10 @@ _BROWSER_TEST_FILES = \
|
||||
browser_687710.js \
|
||||
browser_687710_2.js \
|
||||
browser_694378.js \
|
||||
browser_701377.js \
|
||||
browser_705597.js \
|
||||
browser_707862.js \
|
||||
browser_739805.js \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),Darwin)
|
||||
|
49
browser/components/sessionstore/test/browser_701377.js
Normal file
49
browser/components/sessionstore/test/browser_701377.js
Normal file
@ -0,0 +1,49 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let state = {windows:[{tabs:[
|
||||
{entries:[{url:"http://example.com#1"}]},
|
||||
{entries:[{url:"http://example.com#2"}], hidden: true}
|
||||
]}]};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state, function (aWindow) {
|
||||
let tab = aWindow.gBrowser.tabs[1];
|
||||
ok(tab.hidden, "the second tab is hidden");
|
||||
|
||||
let tabShown = false;
|
||||
let tabShowCallback = function () tabShown = true;
|
||||
tab.addEventListener("TabShow", tabShowCallback, false);
|
||||
|
||||
let tabState = ss.getTabState(tab);
|
||||
ss.setTabState(tab, tabState);
|
||||
|
||||
tab.removeEventListener("TabShow", tabShowCallback, false);
|
||||
ok(tab.hidden && !tabShown, "tab remains hidden");
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
// ----------
|
||||
function whenWindowLoaded(aWindow, aCallback) {
|
||||
aWindow.addEventListener("load", function onLoad() {
|
||||
aWindow.removeEventListener("load", onLoad, false);
|
||||
executeSoon(aCallback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
// ----------
|
||||
function newWindowWithState(aState, aCallback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
whenWindowLoaded(win, function () {
|
||||
ss.setWindowState(win, JSON.stringify(aState), true);
|
||||
executeSoon(function () aCallback(win));
|
||||
});
|
||||
}
|
56
browser/components/sessionstore/test/browser_739805.js
Normal file
56
browser/components/sessionstore/test/browser_739805.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
||||
|
||||
let tabState = {
|
||||
entries: [{url: "data:text/html,<input%20id='foo'>", formdata: {"#foo": "bar"}}]
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
if (gBrowser.tabs.length > 1)
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
});
|
||||
|
||||
let tab = gBrowser.addTab("about:blank");
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
whenBrowserLoaded(browser, function () {
|
||||
isnot(gBrowser.selectedTab, tab, "newly created tab is not selected");
|
||||
|
||||
ss.setTabState(tab, JSON.stringify(tabState));
|
||||
is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring");
|
||||
|
||||
let state = JSON.parse(ss.getTabState(tab));
|
||||
let formdata = state.entries[0].formdata;
|
||||
is(formdata && formdata["#foo"], "bar", "tab state's formdata is valid");
|
||||
|
||||
whenTabRestored(tab, function () {
|
||||
let input = browser.contentDocument.getElementById("foo");
|
||||
is(input.value, "bar", "formdata has been restored correctly");
|
||||
finish();
|
||||
});
|
||||
|
||||
// Restore the tab by selecting it.
|
||||
gBrowser.selectedTab = tab;
|
||||
});
|
||||
}
|
||||
|
||||
function whenBrowserLoaded(aBrowser, aCallback) {
|
||||
aBrowser.addEventListener("load", function onLoad() {
|
||||
aBrowser.removeEventListener("load", onLoad, true);
|
||||
executeSoon(aCallback);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function whenTabRestored(aTab, aCallback) {
|
||||
aTab.addEventListener("SSTabRestored", function onRestored() {
|
||||
aTab.removeEventListener("SSTabRestored", onRestored);
|
||||
executeSoon(aCallback);
|
||||
});
|
||||
}
|
@ -123,6 +123,20 @@ let Storage = {
|
||||
return existingData;
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: getTabState
|
||||
// Returns the current state of the given tab.
|
||||
getTabState: function Storage_getTabState(tab) {
|
||||
Utils.assert(tab, "tab");
|
||||
let tabState;
|
||||
|
||||
try {
|
||||
tabState = JSON.parse(this._sessionStore.getTabState(tab));
|
||||
} catch (e) {}
|
||||
|
||||
return tabState;
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: saveGroupItem
|
||||
// Saves the data for a single groupItem, associated with a specific window.
|
||||
|
@ -96,7 +96,6 @@ function TabItem(tab, options) {
|
||||
this._reconnected = false;
|
||||
this.isDragging = false;
|
||||
this.isStacked = false;
|
||||
this.url = "";
|
||||
|
||||
// Read off the total vertical and horizontal padding on the tab container
|
||||
// and cache this value, as it must be the same for every TabItem.
|
||||
@ -200,21 +199,14 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
// be called at browser startup with the cached data avaliable.
|
||||
//
|
||||
// Parameters:
|
||||
// tabData - the tab data
|
||||
// imageData - the image data
|
||||
showCachedData: function TabItem_showCachedData(tabData, imageData) {
|
||||
showCachedData: function TabItem_showCachedData(imageData) {
|
||||
this._cachedImageData = imageData;
|
||||
this.$cachedThumb.attr("src", this._cachedImageData).show();
|
||||
this.$canvas.css({opacity: 0});
|
||||
let label = "";
|
||||
let title;
|
||||
if (tabData.title) {
|
||||
label = tabData.title;
|
||||
title = label + "\n" + tabData.url;
|
||||
} else {
|
||||
title = tabData.url;
|
||||
}
|
||||
this.$tabTitle.text(label).attr("title", title);
|
||||
|
||||
let {title, url} = this.getTabState();
|
||||
this.$tabTitle.text(title).attr("title", title ? title + "\n" + url : url);
|
||||
|
||||
this._sendToSubscribers("showingCachedData");
|
||||
},
|
||||
@ -234,9 +226,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
// Get data to be used for persistent storage of this object.
|
||||
getStorageData: function TabItem_getStorageData() {
|
||||
let data = {
|
||||
url: this.tab.linkedBrowser.currentURI.spec,
|
||||
groupID: (this.parent ? this.parent.id : 0),
|
||||
title: this.tab.label
|
||||
groupID: (this.parent ? this.parent.id : 0)
|
||||
};
|
||||
if (this.parent && this.parent.getActiveTab() == this)
|
||||
data.active = true;
|
||||
@ -260,12 +250,46 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: _getCurrentTabStateEntry
|
||||
// Returns the current tab state's active history entry.
|
||||
_getCurrentTabStateEntry: function TabItem__getCurrentTabStateEntry() {
|
||||
let tabState = Storage.getTabState(this.tab);
|
||||
|
||||
if (tabState) {
|
||||
let index = (tabState.index || tabState.entries.length) - 1;
|
||||
if (index in tabState.entries)
|
||||
return tabState.entries[index];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: getTabState
|
||||
// Returns the current tab state, i.e. the title and URL of the active
|
||||
// history entry.
|
||||
getTabState: function TabItem_getTabState() {
|
||||
let entry = this._getCurrentTabStateEntry();
|
||||
let title = "";
|
||||
let url = "";
|
||||
|
||||
if (entry) {
|
||||
if (entry.title)
|
||||
title = entry.title;
|
||||
|
||||
url = entry.url;
|
||||
} else {
|
||||
url = this.tab.linkedBrowser.currentURI.spec;
|
||||
}
|
||||
|
||||
return {title: title, url: url};
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: loadThumbnail
|
||||
// Loads the tabItems thumbnail.
|
||||
loadThumbnail: function TabItem_loadThumbnail(tabData) {
|
||||
Utils.assert(tabData, "invalid or missing argument <tabData>");
|
||||
|
||||
loadThumbnail: function TabItem_loadThumbnail() {
|
||||
let self = this;
|
||||
|
||||
function TabItem_loadThumbnail_callback(error, imageData) {
|
||||
@ -285,11 +309,11 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
// what the cache is from, OR the loaded URL is blank, which means
|
||||
// that the page hasn't loaded yet.
|
||||
let currentUrl = self.tab.linkedBrowser.currentURI.spec;
|
||||
if (tabData.url == currentUrl || currentUrl == "about:blank")
|
||||
self.showCachedData(tabData, imageData);
|
||||
if (self.getTabState().url == currentUrl || currentUrl == "about:blank")
|
||||
self.showCachedData(imageData);
|
||||
}
|
||||
|
||||
ThumbnailStorage.loadThumbnail(tabData.url, TabItem_loadThumbnail_callback);
|
||||
ThumbnailStorage.loadThumbnail(this.getTabState().url, TabItem_loadThumbnail_callback);
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -370,7 +394,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
let groupItem;
|
||||
|
||||
if (tabData && TabItems.storageSanity(tabData)) {
|
||||
this.loadThumbnail(tabData);
|
||||
this.loadThumbnail();
|
||||
|
||||
if (this.parent)
|
||||
this.parent.remove(this, {immediately: true});
|
||||
@ -934,7 +958,7 @@ let TabItems = {
|
||||
return (
|
||||
tab.linkedBrowser.contentDocument.readyState == 'complete' &&
|
||||
!(tab.linkedBrowser.contentDocument.URL == 'about:blank' &&
|
||||
tab._tabViewTabItem.url != 'about:blank')
|
||||
tab._tabViewTabItem.getTabState().url != 'about:blank')
|
||||
);
|
||||
},
|
||||
|
||||
@ -1013,10 +1037,6 @@ let TabItems = {
|
||||
|
||||
// ___ URL
|
||||
let tabUrl = tab.linkedBrowser.currentURI.spec;
|
||||
if (tabUrl != tabItem.url) {
|
||||
tabItem.url = tabUrl;
|
||||
tabItem.save();
|
||||
}
|
||||
tabItem.$container.attr("title", label + "\n" + tabUrl);
|
||||
|
||||
// ___ Make sure the tab is complete and ready for updating.
|
||||
|
@ -77,6 +77,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_dbg_bug723069_editor-breakpoints.js \
|
||||
browser_dbg_bug731394_editor-contextmenu.js \
|
||||
browser_dbg_displayName.js \
|
||||
browser_dbg_iframes.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
@ -92,6 +93,7 @@ _BROWSER_TEST_PAGES = \
|
||||
browser_dbg_update-editor-mode.html \
|
||||
test-editor-mode \
|
||||
browser_dbg_displayName.html \
|
||||
browser_dbg_iframes.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
12
browser/devtools/debugger/test/browser_dbg_iframes.html
Normal file
12
browser/devtools/debugger/test/browser_dbg_iframes.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><title>Browser Debugger IFrame Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe src="browser_dbg_debuggerstatement.html"></iframe>
|
||||
</body>
|
||||
|
||||
</html>
|
58
browser/devtools/debugger/test/browser_dbg_iframes.js
Normal file
58
browser/devtools/debugger/test/browser_dbg_iframes.js
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that iframes can be added as debuggees.
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "browser_dbg_iframes.html";
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(TEST_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gPane = aPane;
|
||||
let gDebugger = gPane.debuggerWindow;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have one frame in the stack.");
|
||||
|
||||
gPane.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
let iframe = gTab.linkedBrowser.contentWindow.wrappedJSObject.frames[0];
|
||||
|
||||
is(iframe.document.title, "Browser Debugger Test Tab", "Found the iframe");
|
||||
|
||||
iframe.runDebuggerStatement();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
});
|
@ -1011,6 +1011,9 @@ InspectorUI.prototype = {
|
||||
* 1. Open the link in view source (for element style attributes)
|
||||
* 2. Open the link in the style editor
|
||||
*
|
||||
* Like the style editor, we only view stylesheets contained in
|
||||
* document.styleSheets.
|
||||
*
|
||||
* @param aEvent The event containing the style rule to act on
|
||||
*/
|
||||
ruleViewCSSLinkClicked: function(aEvent)
|
||||
@ -1021,12 +1024,29 @@ InspectorUI.prototype = {
|
||||
|
||||
let rule = aEvent.detail.rule;
|
||||
let styleSheet = rule.sheet;
|
||||
let doc = this.chromeWin.content.document;
|
||||
let styleSheets = doc.styleSheets;
|
||||
let contentSheet = false;
|
||||
let line = rule.ruleLine || 0;
|
||||
|
||||
if (styleSheet) {
|
||||
this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
|
||||
// Array.prototype.indexOf always returns -1 here so we loop through
|
||||
// the styleSheets object instead.
|
||||
for each (let sheet in styleSheets) {
|
||||
if (sheet == styleSheet) {
|
||||
contentSheet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contentSheet) {
|
||||
this.chromeWin.StyleEditor.openChrome(styleSheet, line);
|
||||
} else {
|
||||
let href = rule.elementStyle.element.ownerDocument.location.href;
|
||||
this.chromeWin.openUILinkIn("view-source:" + href, "window");
|
||||
let href = styleSheet ? styleSheet.href : "";
|
||||
if (rule.elementStyle.element) {
|
||||
href = rule.elementStyle.element.ownerDocument.location.href;
|
||||
}
|
||||
let viewSourceUtils = this.chromeWin.gViewSourceUtils;
|
||||
viewSourceUtils.viewSource(href, null, doc, line);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -487,7 +487,8 @@ var Scratchpad = {
|
||||
*/
|
||||
writeAsErrorComment: function SP_writeAsErrorComment(aError)
|
||||
{
|
||||
let newComment = "Exception: " + aError.message + "\n" + aError.stack.substring(0, aError.stack.length - 1);
|
||||
let stack = aError.stack || aError.fileName + ":" + aError.lineNumber;
|
||||
let newComment = "Exception: " + aError.message + "\n" + stack.replace(/\n$/, "");
|
||||
|
||||
this.writeAsComment(newComment);
|
||||
},
|
||||
|
@ -1211,18 +1211,45 @@ SelectorView.prototype = {
|
||||
* 1. Open the link in view source (for element style attributes).
|
||||
* 2. Open the link in the style editor.
|
||||
*
|
||||
* Like the style editor, we only view stylesheets contained in
|
||||
* document.styleSheets inside the style editor.
|
||||
*
|
||||
* @param aEvent The click event
|
||||
*/
|
||||
openStyleEditor: function(aEvent)
|
||||
{
|
||||
if (this.selectorInfo.selector._cssRule._cssSheet) {
|
||||
let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
|
||||
let line = this.selectorInfo.ruleLine;
|
||||
let rule = this.selectorInfo.selector._cssRule;
|
||||
let doc = this.tree.win.content.document;
|
||||
let line = this.selectorInfo.ruleLine || 0;
|
||||
let cssSheet = rule._cssSheet;
|
||||
let contentSheet = false;
|
||||
let styleSheet;
|
||||
let styleSheets;
|
||||
|
||||
if (cssSheet) {
|
||||
styleSheet = cssSheet.domSheet;
|
||||
styleSheets = doc.styleSheets;
|
||||
|
||||
// Array.prototype.indexOf always returns -1 here so we loop through
|
||||
// the styleSheets array instead.
|
||||
for each (let sheet in styleSheets) {
|
||||
if (sheet == styleSheet) {
|
||||
contentSheet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contentSheet) {
|
||||
this.tree.win.StyleEditor.openChrome(styleSheet, line);
|
||||
} else {
|
||||
let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
|
||||
this.tree.win.openUILinkIn("view-source:" + href, "window");
|
||||
let href = styleSheet ? styleSheet.href : "";
|
||||
let viewSourceUtils = this.tree.win.gViewSourceUtils;
|
||||
|
||||
if (this.selectorInfo.sourceElement) {
|
||||
href = this.selectorInfo.sourceElement.ownerDocument.location.href;
|
||||
}
|
||||
viewSourceUtils.viewSource(href, null, doc, line);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -67,6 +67,8 @@ _BROWSER_TEST_FILES = \
|
||||
browser_bug_592743_specificity.js \
|
||||
browser_ruleview_bug_703643_context_menu_copy.js \
|
||||
browser_computedview_bug_703643_context_menu_copy.js \
|
||||
browser_ruleview_734259_style_editor_link.js \
|
||||
browser_computedview_734259_style_editor_link.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -0,0 +1,161 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let doc;
|
||||
let win;
|
||||
let stylePanel;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||
'html { color: #000000; } ' +
|
||||
'span { font-variant: small-caps; color: #000000; } ' +
|
||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||
'<h1>Some header text</h1>\n' +
|
||||
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
|
||||
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
|
||||
'solely to provide some things to <span style="color: yellow">' +
|
||||
'highlight</span> and <span style="font-weight: bold">count</span> ' +
|
||||
'style list-items in the box at right. If you are reading this, ' +
|
||||
'you should go do something else instead. Maybe read a book. Or better ' +
|
||||
'yet, write some test-cases for another bit of code. ' +
|
||||
'<span style="font-style: italic">some text</span></p>\n' +
|
||||
'<p id="closing">more text</p>\n' +
|
||||
'<p>even more text</p>' +
|
||||
'</div>';
|
||||
doc.title = "Rule view style editor link test";
|
||||
|
||||
let span = doc.querySelector("span");
|
||||
ok(span, "captain, we have the span");
|
||||
|
||||
stylePanel = new StyleInspector(window);
|
||||
Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false);
|
||||
stylePanel.createPanel(false, function() {
|
||||
stylePanel.open(span);
|
||||
});
|
||||
}
|
||||
|
||||
function testInlineStyle()
|
||||
{
|
||||
Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated", false);
|
||||
|
||||
ok(stylePanel.isOpen(), "style inspector is open");
|
||||
|
||||
info("expanding property");
|
||||
expandProperty(0, function propertyExpanded() {
|
||||
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||
if (aTopic != "domwindowopened") {
|
||||
return;
|
||||
}
|
||||
info("window opened");
|
||||
win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function windowLoad() {
|
||||
win.removeEventListener("load", windowLoad);
|
||||
info("window load completed");
|
||||
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||
is(windowType, "navigator:view-source", "view source window is open");
|
||||
info("closing window");
|
||||
win.close();
|
||||
Services.ww.unregisterNotification(onWindow);
|
||||
testInlineStyleSheet();
|
||||
});
|
||||
});
|
||||
let link = getLinkByIndex(0);
|
||||
link.click();
|
||||
});
|
||||
}
|
||||
|
||||
function testInlineStyleSheet()
|
||||
{
|
||||
info("clicking an inline stylesheet");
|
||||
|
||||
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||
if (aTopic != "domwindowopened") {
|
||||
return;
|
||||
}
|
||||
info("window opened");
|
||||
win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function windowLoad() {
|
||||
win.removeEventListener("load", windowLoad);
|
||||
info("window load completed");
|
||||
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||
is(windowType, "Tools:StyleEditor", "style editor window is open");
|
||||
|
||||
win.styleEditorChrome.addChromeListener({
|
||||
onEditorAdded: function checkEditor(aChrome, aEditor) {
|
||||
if (!aEditor.sourceEditor) {
|
||||
aEditor.addActionListener({
|
||||
onAttach: function (aEditor) {
|
||||
aEditor.removeActionListener(this);
|
||||
validateStyleEditorSheet(aEditor);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
validateStyleEditorSheet(aEditor);
|
||||
}
|
||||
}
|
||||
});
|
||||
Services.ww.unregisterNotification(onWindow);
|
||||
});
|
||||
});
|
||||
let link = getLinkByIndex(1);
|
||||
link.click();
|
||||
}
|
||||
|
||||
function validateStyleEditorSheet(aEditor)
|
||||
{
|
||||
info("validating style editor stylesheet");
|
||||
|
||||
let sheet = doc.styleSheets[0];
|
||||
is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
|
||||
info("closing window");
|
||||
win.close();
|
||||
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
stylePanel.close();
|
||||
}
|
||||
|
||||
function expandProperty(aIndex, aCallback)
|
||||
{
|
||||
let iframe = stylePanel.iframe;
|
||||
let contentDoc = iframe.contentDocument;
|
||||
let contentWindow = iframe.contentWindow;
|
||||
let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
|
||||
expando.click();
|
||||
|
||||
// We use executeSoon to give the property time to expand.
|
||||
executeSoon(aCallback);
|
||||
}
|
||||
|
||||
function getLinkByIndex(aIndex)
|
||||
{
|
||||
let contentDoc = stylePanel.iframe.contentDocument;
|
||||
let links = contentDoc.querySelectorAll(".rule-link .link");
|
||||
return links[aIndex];
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
|
||||
ok(!stylePanel.isOpen(), "style inspector is closed");
|
||||
doc = win = stylePanel = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||
true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>Computed view style editor link test</p>";
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let win;
|
||||
let doc;
|
||||
let contentWindow;
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/Services.jsm", tempScope);
|
||||
let Services = tempScope.Services;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||
'html { color: #000000; } ' +
|
||||
'span { font-variant: small-caps; color: #000000; } ' +
|
||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||
'<h1>Some header text</h1>\n' +
|
||||
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
|
||||
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
|
||||
'solely to provide some things to <span style="color: yellow">' +
|
||||
'highlight</span> and <span style="font-weight: bold">count</span> ' +
|
||||
'style list-items in the box at right. If you are reading this, ' +
|
||||
'you should go do something else instead. Maybe read a book. Or better ' +
|
||||
'yet, write some test-cases for another bit of code. ' +
|
||||
'<span style="font-style: italic">some text</span></p>\n' +
|
||||
'<p id="closing">more text</p>\n' +
|
||||
'<p>even more text</p>' +
|
||||
'</div>';
|
||||
doc.title = "Rule view style editor link test";
|
||||
|
||||
openInspector();
|
||||
}
|
||||
|
||||
function openInspector()
|
||||
{
|
||||
ok(window.InspectorUI, "InspectorUI variable exists");
|
||||
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
|
||||
ok(InspectorUI.store.isEmpty(), "Inspector.store is empty");
|
||||
|
||||
Services.obs.addObserver(inspectorUIOpen,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.openInspectorUI();
|
||||
}
|
||||
|
||||
function inspectorUIOpen()
|
||||
{
|
||||
Services.obs.removeObserver(inspectorUIOpen,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
|
||||
// Make sure the inspector is open.
|
||||
ok(InspectorUI.inspecting, "Inspector is highlighting");
|
||||
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
|
||||
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
|
||||
ok(!InspectorUI.store.isEmpty(), "InspectorUI.store is not empty");
|
||||
is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
|
||||
|
||||
// Highlight a node.
|
||||
let div = content.document.getElementsByTagName("div")[0];
|
||||
InspectorUI.inspectNode(div);
|
||||
InspectorUI.stopInspecting();
|
||||
is(InspectorUI.selection, div, "selection matches the div element");
|
||||
|
||||
Services.obs.addObserver(testInlineStyle,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
|
||||
|
||||
InspectorUI.showSidebar();
|
||||
InspectorUI.openRuleView();
|
||||
}
|
||||
|
||||
function testInlineStyle()
|
||||
{
|
||||
Services.obs.removeObserver(testInlineStyle,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
|
||||
|
||||
executeSoon(function() {
|
||||
info("clicking an inline style");
|
||||
|
||||
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||
if (aTopic != "domwindowopened") {
|
||||
return;
|
||||
}
|
||||
|
||||
win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function windowLoad() {
|
||||
win.removeEventListener("load", windowLoad);
|
||||
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||
is(windowType, "navigator:view-source", "view source window is open");
|
||||
win.close();
|
||||
Services.ww.unregisterNotification(onWindow);
|
||||
testInlineStyleSheet();
|
||||
});
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(getLinkByIndex(0), { }, contentWindow);
|
||||
});
|
||||
}
|
||||
|
||||
function testInlineStyleSheet()
|
||||
{
|
||||
info("clicking an inline stylesheet");
|
||||
|
||||
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||
if (aTopic != "domwindowopened") {
|
||||
return;
|
||||
}
|
||||
|
||||
win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function windowLoad() {
|
||||
win.removeEventListener("load", windowLoad);
|
||||
|
||||
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||
is(windowType, "Tools:StyleEditor", "style editor window is open");
|
||||
|
||||
win.styleEditorChrome.addChromeListener({
|
||||
onEditorAdded: function checkEditor(aChrome, aEditor) {
|
||||
if (!aEditor.sourceEditor) {
|
||||
aEditor.addActionListener({
|
||||
onAttach: function (aEditor) {
|
||||
aEditor.removeActionListener(this);
|
||||
validateStyleEditorSheet(aEditor);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
validateStyleEditorSheet(aEditor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Services.ww.unregisterNotification(onWindow);
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.synthesizeMouse(getLinkByIndex(1), 5, 5, { }, contentWindow);
|
||||
}
|
||||
|
||||
function validateStyleEditorSheet(aEditor)
|
||||
{
|
||||
info("validating style editor stylesheet");
|
||||
|
||||
let sheet = doc.styleSheets[0];
|
||||
|
||||
is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
|
||||
win.close();
|
||||
|
||||
finishup();
|
||||
}
|
||||
|
||||
function getLinkByIndex(aIndex)
|
||||
{
|
||||
let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview");
|
||||
let contentDoc = ruleView.contentDocument;
|
||||
let links = contentDoc.querySelectorAll(".ruleview-rule-source");
|
||||
contentWindow = ruleView.contentWindow;
|
||||
return links[aIndex];
|
||||
}
|
||||
|
||||
function finishup()
|
||||
{
|
||||
InspectorUI.hideSidebar();
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
doc = contentWindow = win = null;
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||
true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>Rule view style editor link test</p>";
|
||||
}
|
@ -187,6 +187,7 @@ function checkClipboardData(aExpectedPattern)
|
||||
|
||||
function finishup()
|
||||
{
|
||||
InspectorUI.hideSidebar();
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
doc = null;
|
||||
|
@ -77,7 +77,7 @@ function testFocus()
|
||||
// If not, we'll wait here until we time out.
|
||||
waitForEditorFocus(brace.parentNode, function onNewEditor(aEditor) {
|
||||
aEditor.input.blur();
|
||||
finishTest();
|
||||
finishUp();
|
||||
});
|
||||
EventUtils.sendKey("return");
|
||||
});
|
||||
@ -89,6 +89,8 @@ function testFocus()
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
InspectorUI.hideSidebar();
|
||||
InspectorUI.closeInspectorUI();
|
||||
doc = stylePanel = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
|
@ -22,8 +22,9 @@ function test() {
|
||||
let canvas = presenter.canvas;
|
||||
|
||||
presenter._onSetupMesh = function() {
|
||||
let p = getPickablePoint(presenter);
|
||||
|
||||
presenter.pickNode(canvas.width / 2, 10, {
|
||||
presenter.pickNode(p[0], p[1], {
|
||||
onpick: function(data)
|
||||
{
|
||||
ok(data.index > 0,
|
||||
|
@ -24,7 +24,9 @@ function test() {
|
||||
Services.obs.addObserver(whenNodeRemoved, NODE_REMOVED, false);
|
||||
|
||||
presenter._onSetupMesh = function() {
|
||||
presenter.highlightNodeAt(presenter.canvas.width / 2, 10, {
|
||||
let p = getPickablePoint(presenter);
|
||||
|
||||
presenter.highlightNodeAt(p[0], p[1], {
|
||||
onpick: function()
|
||||
{
|
||||
ok(presenter._currentSelection > 0,
|
||||
|
@ -14,7 +14,6 @@ function test() {
|
||||
return;
|
||||
}
|
||||
|
||||
requestLongerTimeout(10);
|
||||
waitForExplicitFinish();
|
||||
|
||||
createTab(function() {
|
||||
|
@ -23,7 +23,7 @@ function test() {
|
||||
presenter = instance.presenter;
|
||||
Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
|
||||
|
||||
presenter._onSetupMesh = function() {
|
||||
presenter._onInitializationFinished = function() {
|
||||
let contentDocument = presenter.contentWindow.document;
|
||||
let div = contentDocument.getElementById("first-law");
|
||||
|
||||
|
@ -23,8 +23,8 @@ function test() {
|
||||
presenter = instance.presenter;
|
||||
Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
|
||||
|
||||
presenter._onSetupMesh = function() {
|
||||
presenter.highlightNodeAt(presenter.canvas.width / 2, 10);
|
||||
presenter._onInitializationFinished = function() {
|
||||
presenter.highlightNodeAt.apply(this, getPickablePoint(presenter));
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -40,7 +40,7 @@ function whenHighlighting() {
|
||||
executeSoon(function() {
|
||||
Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING);
|
||||
Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false);
|
||||
presenter.highlightNodeAt(-1, -1);
|
||||
presenter.highlightNode(null);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ function test() {
|
||||
presenter = instance.presenter;
|
||||
Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
|
||||
|
||||
presenter._onSetupMesh = function() {
|
||||
presenter.highlightNodeFor(5); // 1 = html, 2 = body, 3 = first div
|
||||
presenter._onInitializationFinished = function() {
|
||||
presenter.highlightNodeFor(3); // 1 = html, 2 = body, 3 = first div
|
||||
};
|
||||
}
|
||||
});
|
||||
|
@ -14,7 +14,6 @@ function test() {
|
||||
return;
|
||||
}
|
||||
|
||||
requestLongerTimeout(10);
|
||||
waitForExplicitFinish();
|
||||
|
||||
createTab(function() {
|
||||
|
@ -24,6 +24,7 @@ const DEFAULT_HTML = "data:text/html," +
|
||||
"<DOCTYPE html>" +
|
||||
"<html>" +
|
||||
"<head>" +
|
||||
"<meta charset='utf-8'/>" +
|
||||
"<title>Three Laws</title>" +
|
||||
"</head>" +
|
||||
"<body>" +
|
||||
@ -194,3 +195,16 @@ function createTilt(callbacks, close) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getPickablePoint(presenter) {
|
||||
let vertices = presenter._meshStacks[0].vertices.components;
|
||||
|
||||
let topLeft = vec3.create([vertices[0], vertices[1], vertices[2]]);
|
||||
let bottomRight = vec3.create([vertices[6], vertices[7], vertices[8]]);
|
||||
let center = vec3.lerp(topLeft, bottomRight, 0.5, []);
|
||||
|
||||
let renderer = presenter._renderer;
|
||||
let viewport = [0, 0, renderer.width, renderer.height];
|
||||
|
||||
return vec3.project(center, viewport, renderer.mvMatrix, renderer.projMatrix);
|
||||
}
|
||||
|
@ -357,10 +357,21 @@ BrowserTabActor.prototype = {
|
||||
this.conn.addActorPool(this._contextPool);
|
||||
|
||||
this.threadActor = new ThreadActor(this);
|
||||
this.threadActor.addDebuggee(this.browser.contentWindow.wrappedJSObject);
|
||||
this._addDebuggees(this.browser.contentWindow.wrappedJSObject);
|
||||
this._contextPool.addActor(this.threadActor);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the provided window and all windows in its frame tree as debuggees.
|
||||
*/
|
||||
_addDebuggees: function BTA__addDebuggees(aWindow) {
|
||||
this.threadActor.addDebuggee(aWindow);
|
||||
let frames = aWindow.frames;
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
this._addDebuggees(frames[i]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Exits the current thread actor and removes the context-lifetime actor pool.
|
||||
* The content window is no longer being debugged after this call.
|
||||
|
@ -428,7 +428,7 @@ ThreadActor.prototype = {
|
||||
// If that first script does not contain the line specified, it's no
|
||||
// good.
|
||||
if (i + scripts[i].lineCount < location.line) {
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
script = scripts[i];
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user