merge m-c to fx-team

This commit is contained in:
Tim Taubert 2012-03-29 11:44:00 +02:00
commit 45bef14fbd
27 changed files with 702 additions and 59 deletions

View File

@ -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) {

View File

@ -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)

View 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));
});
}

View 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);
});
}

View File

@ -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.

View File

@ -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.

View File

@ -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)

View 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>

View 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;
});

View File

@ -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);
}
},

View File

@ -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);
},

View File

@ -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);
}
},
};

View File

@ -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)

View File

@ -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>";
}

View File

@ -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>";
}

View File

@ -187,6 +187,7 @@ function checkClipboardData(aExpectedPattern)
function finishup()
{
InspectorUI.hideSidebar();
InspectorUI.closeInspectorUI();
gBrowser.removeCurrentTab();
doc = null;

View File

@ -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();

View File

@ -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,

View File

@ -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,

View File

@ -14,7 +14,6 @@ function test() {
return;
}
requestLongerTimeout(10);
waitForExplicitFinish();
createTab(function() {

View File

@ -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");

View File

@ -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);
});
}

View File

@ -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
};
}
});

View File

@ -14,7 +14,6 @@ function test() {
return;
}
requestLongerTimeout(10);
waitForExplicitFinish();
createTab(function() {

View File

@ -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);
}

View File

@ -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.

View File

@ -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;