Merge
|
@ -213,6 +213,8 @@ maybe_clobber_profiledbuild:
|
|||
endif
|
||||
else
|
||||
maybe_clobber_profiledbuild:
|
||||
$(RM) $(DIST)/bin/*.pgc
|
||||
find $(DIST)/$(MOZ_APP_NAME) -name "*.pgc" -exec mv {} $(DIST)/bin \;
|
||||
endif
|
||||
|
||||
.PHONY: maybe_clobber_profiledbuild
|
||||
|
|
|
@ -1008,6 +1008,9 @@ pref("devtools.inspector.enabled", true);
|
|||
// Enable the style inspector
|
||||
pref("devtools.styleinspector.enabled", true);
|
||||
|
||||
// Enable the rules view
|
||||
pref("devtools.ruleview.enabled", true);
|
||||
|
||||
// Enable the Scratchpad tool.
|
||||
pref("devtools.scratchpad.enabled", true);
|
||||
|
||||
|
|
|
@ -3908,12 +3908,29 @@ var FullScreen = {
|
|||
}
|
||||
},
|
||||
|
||||
exitDomFullScreen : function(e) {
|
||||
document.mozCancelFullScreen();
|
||||
},
|
||||
|
||||
enterDomFullScreen : function(event) {
|
||||
if (!document.mozFullScreen) {
|
||||
// We receive "mozfullscreenchange" events for each subdocument which
|
||||
// is an ancestor of the document containing the element which requested
|
||||
// full-screen. Only add listeners and show warning etc when the event we
|
||||
// receive is targeted at the chrome document, i.e. only once every time
|
||||
// we enter DOM full-screen mode.
|
||||
if (!document.mozFullScreen || event.target.ownerDocument != document) {
|
||||
return;
|
||||
}
|
||||
this.showWarning(true);
|
||||
|
||||
// Exit DOM full-screen mode upon open, close, or change tab.
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
|
||||
|
||||
// Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
|
||||
window.addEventListener("deactivate", this.exitDomFullScreen, true);
|
||||
|
||||
// Cancel any "hide the toolbar" animation which is in progress, and make
|
||||
// the toolbar hide immediately.
|
||||
clearInterval(this._animationInterval);
|
||||
|
@ -3946,6 +3963,10 @@ var FullScreen = {
|
|||
fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
|
||||
}
|
||||
this.cancelWarning();
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
|
||||
window.removeEventListener("deactivate", this.exitDomFullScreen, true);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -8169,7 +8190,7 @@ let DownloadMonitorPanel = {
|
|||
let maxTime = -Infinity;
|
||||
let dls = gDownloadMgr.activeDownloads;
|
||||
while (dls.hasMoreElements()) {
|
||||
let dl = dls.getNext().QueryInterface(Ci.nsIDownload);
|
||||
let dl = dls.getNext();
|
||||
if (dl.state == gDownloadMgr.DOWNLOAD_DOWNLOADING) {
|
||||
// Figure out if this download takes longer
|
||||
if (dl.speed > 0 && dl.size > 0)
|
||||
|
|
|
@ -967,7 +967,7 @@
|
|||
<statuspanel id="statusbar-display" inactive="true"/>
|
||||
</vbox>
|
||||
<splitter id="devtools-side-splitter" hidden="true"/>
|
||||
<vbox id="devtools-sidebar-box" hidden="true" flex="1"
|
||||
<vbox id="devtools-sidebar-box" hidden="true"
|
||||
style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
|
||||
<toolbar id="devtools-sidebar-toolbar" nowindowdrag="true"/>
|
||||
<deck id="devtools-sidebar-deck" flex="1"/>
|
||||
|
|
|
@ -1108,6 +1108,7 @@
|
|||
<![CDATA[
|
||||
var aFromExternal;
|
||||
var aRelatedToCurrent;
|
||||
var aIsUTF8;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
|
@ -1119,6 +1120,7 @@
|
|||
aAllowThirdPartyFixup = params.allowThirdPartyFixup;
|
||||
aFromExternal = params.fromExternal;
|
||||
aRelatedToCurrent = params.relatedToCurrent;
|
||||
aIsUTF8 = params.isUTF8;
|
||||
}
|
||||
|
||||
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
|
||||
|
@ -1131,7 +1133,8 @@
|
|||
ownerTab: owner,
|
||||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
fromExternal: aFromExternal,
|
||||
relatedToCurrent: aRelatedToCurrent});
|
||||
relatedToCurrent: aRelatedToCurrent,
|
||||
isUTF8: aIsUTF8});
|
||||
if (!bgLoad)
|
||||
this.selectedTab = tab;
|
||||
|
||||
|
@ -1204,6 +1207,7 @@
|
|||
var aFromExternal;
|
||||
var aRelatedToCurrent;
|
||||
var aSkipAnimation;
|
||||
var aIsUTF8;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
|
@ -1216,6 +1220,7 @@
|
|||
aFromExternal = params.fromExternal;
|
||||
aRelatedToCurrent = params.relatedToCurrent;
|
||||
aSkipAnimation = params.skipAnimation;
|
||||
aIsUTF8 = params.isUTF8;
|
||||
}
|
||||
|
||||
this._browsers = null; // invalidate cache
|
||||
|
@ -1363,6 +1368,8 @@
|
|||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
|
||||
if (aFromExternal)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
|
||||
if (aIsUTF8)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_URI_IS_UTF8;
|
||||
try {
|
||||
b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
|
||||
} catch (ex) {
|
||||
|
|
|
@ -206,6 +206,7 @@ _BROWSER_FILES = \
|
|||
browser_tabs_isActive.js \
|
||||
browser_tabs_owner.js \
|
||||
browser_urlbarCopying.js \
|
||||
browser_urlbarEnter.js \
|
||||
browser_urlbarTrimURLs.js \
|
||||
browser_urlHighlight.js \
|
||||
browser_visibleFindSelection.js \
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TEST_VALUE = "example.com/\xF7?\xF7";
|
||||
const START_VALUE = "example.com/%C3%B7?%C3%B7";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function locationBarEnter(aEvent, aClosure) {
|
||||
executeSoon(function() {
|
||||
gURLBar.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", aEvent);
|
||||
addPageShowListener(aClosure);
|
||||
});
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
let test = gTests.shift();
|
||||
if (!test) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
info("Running test: " + test.desc);
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(START_VALUE);
|
||||
addPageShowListener(function() {
|
||||
locationBarEnter(test.event, function() {
|
||||
test.check(tab);
|
||||
|
||||
// Clean up
|
||||
while (gBrowser.tabs.length > 1)
|
||||
gBrowser.removeTab(gBrowser.selectedTab)
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let gTests = [
|
||||
{ desc: "Simple return keypress",
|
||||
event: {},
|
||||
check: checkCurrent
|
||||
},
|
||||
|
||||
{ desc: "Alt+Return keypress",
|
||||
event: { altKey: true },
|
||||
check: checkNewTab,
|
||||
},
|
||||
]
|
||||
|
||||
function checkCurrent(aTab) {
|
||||
is(gURLBar.value, TEST_VALUE, "Urlbar should preserve the value on return keypress");
|
||||
is(gBrowser.selectedTab, aTab, "New URL was loaded in the current tab");
|
||||
}
|
||||
|
||||
function checkNewTab(aTab) {
|
||||
is(gURLBar.value, TEST_VALUE, "Urlbar should preserve the value on return keypress");
|
||||
isnot(gBrowser.selectedTab, aTab, "New URL was loaded in a new tab");
|
||||
}
|
||||
|
||||
function addPageShowListener(aFunc) {
|
||||
gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
|
||||
gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
|
||||
aFunc();
|
||||
});
|
||||
}
|
||||
|
|
@ -326,6 +326,10 @@
|
|||
// keyword).
|
||||
if (!mayInheritPrincipal)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
|
||||
// If the value wasn't typed, we know that we decoded the value as
|
||||
// UTF-8 (see losslessDecodeURI)
|
||||
if (!this.valueIsTyped)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_URI_IS_UTF8;
|
||||
gBrowser.loadURIWithFlags(url, flags, null, null, postData);
|
||||
}
|
||||
|
||||
|
@ -361,6 +365,8 @@
|
|||
let params = { allowThirdPartyFixup: true, postData: postData };
|
||||
if (altEnter)
|
||||
params.inBackground = false;
|
||||
if (!this.valueIsTyped)
|
||||
params.isUTF8 = true;
|
||||
openUILinkIn(url, where, params);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -199,6 +199,8 @@ function openLinkIn(url, where, params) {
|
|||
var aRelatedToCurrent = params.relatedToCurrent;
|
||||
var aInBackground = params.inBackground;
|
||||
var aDisallowInheritPrincipal = params.disallowInheritPrincipal;
|
||||
// Currently, this parameter works only for where=="tab" or "current"
|
||||
var aIsUTF8 = params.isUTF8;
|
||||
|
||||
if (where == "save") {
|
||||
saveURL(url, null, null, true, null, aReferrerURI);
|
||||
|
@ -272,6 +274,8 @@ function openLinkIn(url, where, params) {
|
|||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
|
||||
if (aDisallowInheritPrincipal)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
|
||||
if (aIsUTF8)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_URI_IS_UTF8;
|
||||
w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData);
|
||||
break;
|
||||
case "tabshifted":
|
||||
|
@ -285,7 +289,8 @@ function openLinkIn(url, where, params) {
|
|||
postData: aPostData,
|
||||
inBackground: loadInBackground,
|
||||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
relatedToCurrent: aRelatedToCurrent});
|
||||
relatedToCurrent: aRelatedToCurrent,
|
||||
isUTF8: aIsUTF8});
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -761,6 +761,7 @@ BrowserGlue.prototype = {
|
|||
_showTelemetryNotification: function BG__showTelemetryNotification() {
|
||||
const PREF_TELEMETRY_PROMPTED = "toolkit.telemetry.prompted";
|
||||
const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
|
||||
const PREF_TELEMETRY_REJECTED = "toolkit.telemetry.rejected";
|
||||
const PREF_TELEMETRY_INFOURL = "toolkit.telemetry.infoURL";
|
||||
const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner";
|
||||
// This is used to reprompt users when privacy message changes
|
||||
|
@ -803,7 +804,9 @@ BrowserGlue.prototype = {
|
|||
label: browserBundle.GetStringFromName("telemetryNoButtonLabel"),
|
||||
accessKey: browserBundle.GetStringFromName("telemetryNoButtonAccessKey"),
|
||||
popup: null,
|
||||
callback: function(aNotificationBar, aButton) {}
|
||||
callback: function(aNotificationBar, aButton) {
|
||||
Services.prefs.setBoolPref(PREF_TELEMETRY_REJECTED, true);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -811,6 +814,7 @@ BrowserGlue.prototype = {
|
|||
Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
|
||||
|
||||
var notification = notifyBox.appendNotification(telemetryPrompt, "telemetry", null, notifyBox.PRIORITY_INFO_LOW, buttons);
|
||||
notification.setAttribute("hideclose", true);
|
||||
notification.persistence = 6; // arbitrary number, just so bar sticks around for a bit
|
||||
|
||||
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
|
|
@ -458,6 +458,9 @@ TreePanel.prototype = {
|
|||
editorInput.value = aAttrVal;
|
||||
editorInput.select();
|
||||
|
||||
// remove tree key navigation events
|
||||
this.treeIFrame.removeEventListener("keypress", this.IUI, false);
|
||||
|
||||
// listen for editor specific events
|
||||
this.bindEditorEvent(editor, "click", function(aEvent) {
|
||||
aEvent.stopPropagation();
|
||||
|
@ -515,8 +518,12 @@ TreePanel.prototype = {
|
|||
{
|
||||
if (aEvent.which == this.window.KeyEvent.DOM_VK_RETURN) {
|
||||
this.saveEditor();
|
||||
aEvent.preventDefault();
|
||||
aEvent.stopPropagation();
|
||||
} else if (aEvent.keyCode == this.window.KeyEvent.DOM_VK_ESCAPE) {
|
||||
this.closeEditor();
|
||||
aEvent.preventDefault();
|
||||
aEvent.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -546,6 +553,9 @@ TreePanel.prototype = {
|
|||
this.editingContext = null;
|
||||
this.editingEvents = {};
|
||||
|
||||
// re-add navigation listener
|
||||
this.treeIFrame.addEventListener("keypress", this.IUI, false);
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED,
|
||||
null);
|
||||
|
@ -567,6 +577,7 @@ TreePanel.prototype = {
|
|||
this.editingContext.attrObj.innerHTML = editorInput.value;
|
||||
|
||||
this.IUI.isDirty = true;
|
||||
this.IUI.nodeChanged(this.registrationObject);
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_SAVED,
|
||||
|
|
|
@ -50,6 +50,7 @@ var EXPORTED_SYMBOLS = ["InspectorUI"];
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/TreePanel.jsm");
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
|
||||
|
||||
const INSPECTOR_INVISIBLE_ELEMENTS = {
|
||||
"head": true,
|
||||
|
@ -78,9 +79,15 @@ const INSPECTOR_NOTIFICATIONS = {
|
|||
// Fires once the Inspector is closed.
|
||||
CLOSED: "inspector-closed",
|
||||
|
||||
// Fires when the Inspector is reopened after tab-switch.
|
||||
STATE_RESTORED: "inspector-state-restored",
|
||||
|
||||
// Fires when the Tree Panel is opened and initialized.
|
||||
TREEPANELREADY: "inspector-treepanel-ready",
|
||||
|
||||
// Fires when the CSS Rule View is opened and initialized.
|
||||
RULEVIEWREADY: "inspector-ruleview-ready",
|
||||
|
||||
// Event notifications for the attribute-value editor
|
||||
EDITOR_OPENED: "inspector-editor-opened",
|
||||
EDITOR_CLOSED: "inspector-editor-closed",
|
||||
|
@ -740,6 +747,7 @@ InspectorUI.prototype = {
|
|||
toolEvents: null,
|
||||
inspecting: false,
|
||||
treePanelEnabled: true,
|
||||
ruleViewEnabled: true,
|
||||
isDirty: false,
|
||||
store: null,
|
||||
|
||||
|
@ -891,6 +899,11 @@ InspectorUI.prototype = {
|
|||
this.treePanel = new TreePanel(this.chromeWin, this);
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("devtools.ruleview.enabled") &&
|
||||
!this.toolRegistered("ruleview")) {
|
||||
this.registerRuleView();
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("devtools.styleinspector.enabled") &&
|
||||
!this.toolRegistered("styleinspector")) {
|
||||
this.stylePanel = new StyleInspector(this.chromeWin, this);
|
||||
|
@ -910,6 +923,31 @@ InspectorUI.prototype = {
|
|||
this.initializeHighlighter();
|
||||
},
|
||||
|
||||
/**
|
||||
* Register the Rule View in the Sidebar.
|
||||
*/
|
||||
registerRuleView: function IUI_registerRuleView()
|
||||
{
|
||||
let isOpen = this.isRuleViewOpen.bind(this);
|
||||
|
||||
this.ruleViewObject = {
|
||||
id: "ruleview",
|
||||
label: this.strings.GetStringFromName("ruleView.label"),
|
||||
tooltiptext: this.strings.GetStringFromName("ruleView.tooltiptext"),
|
||||
accesskey: this.strings.GetStringFromName("ruleView.accesskey"),
|
||||
context: this,
|
||||
get isOpen() isOpen(),
|
||||
show: this.openRuleView,
|
||||
hide: this.closeRuleView,
|
||||
onSelect: this.selectInRuleView,
|
||||
panel: null,
|
||||
unregister: this.destroyRuleView,
|
||||
sidebar: true,
|
||||
};
|
||||
|
||||
this.registerTool(this.ruleViewObject);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register and initialize any included tools.
|
||||
*/
|
||||
|
@ -1120,6 +1158,19 @@ InspectorUI.prototype = {
|
|||
this.toolsSelect(aScroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the highlighted node is changed by a tool.
|
||||
*
|
||||
* @param object aUpdater
|
||||
* The tool that triggered the update (if any), that tool's
|
||||
* onChanged will not be called.
|
||||
*/
|
||||
nodeChanged: function IUI_nodeChanged(aUpdater)
|
||||
{
|
||||
this.highlighter.highlight();
|
||||
this.toolsOnChanged(aUpdater);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Event Handling
|
||||
|
||||
|
@ -1271,6 +1322,94 @@ InspectorUI.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// CssRuleView methods
|
||||
|
||||
/**
|
||||
* Is the cssRuleView open?
|
||||
*/
|
||||
isRuleViewOpen: function IUI_isRuleViewOpen()
|
||||
{
|
||||
return this.isSidebarOpen && this.ruleButton.hasAttribute("checked") &&
|
||||
(this.sidebarDeck.selectedPanel == this.getToolIframe(this.ruleViewObject));
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience getter to retrieve the Rule Button.
|
||||
*/
|
||||
get ruleButton()
|
||||
{
|
||||
return this.chromeDoc.getElementById(
|
||||
this.getToolbarButtonId(this.ruleViewObject.id));
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the CssRuleView.
|
||||
*/
|
||||
openRuleView: function IUI_openRuleView()
|
||||
{
|
||||
let iframe = this.getToolIframe(this.ruleViewObject);
|
||||
let boundLoadListener = function() {
|
||||
iframe.removeEventListener("load", boundLoadListener, true);
|
||||
let doc = iframe.contentDocument;
|
||||
this.ruleView = new CssRuleView(doc);
|
||||
this.boundRuleViewChanged = this.ruleViewChanged.bind(this);
|
||||
this.ruleView.element.addEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
|
||||
doc.documentElement.appendChild(this.ruleView.element);
|
||||
this.ruleView.highlight(this.selection);
|
||||
Services.obs.notifyObservers(null,
|
||||
INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, null);
|
||||
}.bind(this);
|
||||
|
||||
iframe.addEventListener("load", boundLoadListener, true);
|
||||
|
||||
iframe.setAttribute("src", "chrome://browser/content/devtools/cssruleview.xul");
|
||||
},
|
||||
|
||||
/**
|
||||
* Stub to Close the CSS Rule View. Does nothing currently because the
|
||||
* Rule View lives in the sidebar.
|
||||
*/
|
||||
closeRuleView: function IUI_closeRuleView()
|
||||
{
|
||||
// do nothing for now
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the selected node in the Css Rule View.
|
||||
* @param {nsIDOMnode} the selected node.
|
||||
*/
|
||||
selectInRuleView: function IUI_selectInRuleView(aNode)
|
||||
{
|
||||
if (this.ruleView)
|
||||
this.ruleView.highlight(aNode);
|
||||
},
|
||||
|
||||
ruleViewChanged: function IUI_ruleViewChanged()
|
||||
{
|
||||
this.isDirty = true;
|
||||
this.nodeChanged(this.ruleViewObject);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the rule view.
|
||||
*/
|
||||
destroyRuleView: function IUI_destroyRuleView()
|
||||
{
|
||||
let iframe = this.getToolIframe(this.ruleViewObject);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
|
||||
if (this.ruleView) {
|
||||
this.ruleView.element.removeEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
delete boundRuleViewChanged;
|
||||
this.ruleView.clear();
|
||||
delete this.ruleView;
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// Utility Methods
|
||||
|
||||
|
@ -1552,10 +1691,6 @@ InspectorUI.prototype = {
|
|||
|
||||
// wire up button to show the iframe
|
||||
this.bindToolEvent(btn, "click", function showIframe() {
|
||||
let visible = this.sidebarDeck.selectedPanel == iframe;
|
||||
if (!visible) {
|
||||
sidebarDeck.selectedPanel = iframe;
|
||||
}
|
||||
this.toolShow(aRegObj);
|
||||
}.bind(this));
|
||||
},
|
||||
|
@ -1576,10 +1711,18 @@ InspectorUI.prototype = {
|
|||
*/
|
||||
toolShow: function IUI_toolShow(aTool)
|
||||
{
|
||||
aTool.show.call(aTool.context, this.selection);
|
||||
|
||||
let btn = this.chromeDoc.getElementById(this.getToolbarButtonId(aTool.id));
|
||||
btn.setAttribute("checked", "true");
|
||||
if (aTool.sidebar) {
|
||||
this.sidebarDeck.selectedPanel = this.getToolIframe(aTool);
|
||||
this.sidebarTools.forEach(function(other) {
|
||||
if (other != aTool)
|
||||
this.chromeDoc.getElementById(
|
||||
this.getToolbarButtonId(other.id)).removeAttribute("checked");
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
aTool.show.call(aTool.context, this.selection);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1689,16 +1832,24 @@ InspectorUI.prototype = {
|
|||
restoreToolState: function IUI_restoreToolState(aWinID)
|
||||
{
|
||||
let openTools = this.store.getValue(aWinID, "openTools");
|
||||
let activeSidebarTool;
|
||||
if (openTools) {
|
||||
this.toolsDo(function IUI_toolsOnShow(aTool) {
|
||||
if (aTool.id in openTools) {
|
||||
if (aTool.sidebar && !this.isSidebarOpen) {
|
||||
this.showSidebar();
|
||||
activeSidebarTool = aTool;
|
||||
}
|
||||
this.toolShow(aTool);
|
||||
}
|
||||
}.bind(this));
|
||||
this.sidebarTools.forEach(function(tool) {
|
||||
if (tool != activeSidebarTool)
|
||||
this.chromeDoc.getElementById(
|
||||
this.getToolbarButtonId(tool.id)).removeAttribute("checked");
|
||||
}.bind(this));
|
||||
}
|
||||
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.STATE_RESTORED, null);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1723,13 +1874,29 @@ InspectorUI.prototype = {
|
|||
*/
|
||||
toolsDim: function IUI_toolsDim(aState)
|
||||
{
|
||||
this.toolsDo(function IUI_toolsOnSelect(aTool) {
|
||||
this.toolsDo(function IUI_toolsDim(aTool) {
|
||||
if (aTool.isOpen && "dim" in aTool) {
|
||||
aTool.dim.call(aTool.context, aState);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify registered tools of changes to the highlighted element.
|
||||
*
|
||||
* @param object aUpdater
|
||||
* The tool that triggered the update (if any), that tool's
|
||||
* onChanged will not be called.
|
||||
*/
|
||||
toolsOnChanged: function IUI_toolsChanged(aUpdater)
|
||||
{
|
||||
this.toolsDo(function IUI_toolsOnChanged(aTool) {
|
||||
if (aTool.isOpen && ("onChanged" in aTool) && aTool != aUpdater) {
|
||||
aTool.onChanged.call(aTool.context);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Loop through all registered tools and pass each into the provided function
|
||||
* @param aFunction The function to which each tool is to be passed
|
||||
|
@ -1937,8 +2104,13 @@ InspectorProgressListener.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// Skip non-start states.
|
||||
if (!(aFlag & Ci.nsIWebProgressListener.STATE_START)) {
|
||||
let isStart = aFlag & Ci.nsIWebProgressListener.STATE_START;
|
||||
let isDocument = aFlag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
|
||||
let isNetwork = aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
|
||||
let isRequest = aFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST;
|
||||
|
||||
// Skip non-interesting states.
|
||||
if (!isStart || !isDocument || !isRequest || !isNetwork) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ _BROWSER_FILES = \
|
|||
browser_inspector_keybindings.js \
|
||||
browser_inspector_breadcrumbs.html \
|
||||
browser_inspector_breadcrumbs.js \
|
||||
browser_inspector_bug_699308_iframe_navigation.js \
|
||||
browser_inspector_changes.js \
|
||||
$(NULL)
|
||||
|
||||
# Disabled due to constant failures
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let iframe;
|
||||
let iframeLoads = 0;
|
||||
let checksAfterLoads = false;
|
||||
|
||||
function startTest() {
|
||||
ok(window.InspectorUI, "InspectorUI variable exists");
|
||||
Services.obs.addObserver(runInspectorTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, null);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runInspectorTests() {
|
||||
Services.obs.removeObserver(runInspectorTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, null);
|
||||
|
||||
iframe = content.document.querySelector("iframe");
|
||||
ok(iframe, "found the iframe element");
|
||||
|
||||
ok(InspectorUI.inspecting, "Inspector is highlighting");
|
||||
ok(InspectorUI.isInspectorOpen, "Inspector is open");
|
||||
|
||||
Services.obs.addObserver(finishTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
|
||||
iframe.addEventListener("load", onIframeLoad, false);
|
||||
|
||||
executeSoon(function() {
|
||||
iframe.contentWindow.location = "javascript:location.reload()";
|
||||
});
|
||||
}
|
||||
|
||||
function onIframeLoad() {
|
||||
if (++iframeLoads != 2) {
|
||||
executeSoon(function() {
|
||||
iframe.contentWindow.location = "javascript:location.reload()";
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.removeEventListener("load", onIframeLoad, false);
|
||||
|
||||
ok(InspectorUI.inspecting, "Inspector is highlighting after iframe nav");
|
||||
ok(InspectorUI.isInspectorOpen, "Inspector Panel is open after iframe nav");
|
||||
|
||||
checksAfterLoads = true;
|
||||
|
||||
InspectorUI.closeInspectorUI();
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
Services.obs.removeObserver(finishTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
|
||||
|
||||
is(iframeLoads, 2, "iframe loads");
|
||||
ok(checksAfterLoads, "the Inspector tests got the chance to run after iframe reloads");
|
||||
ok(!InspectorUI.isInspectorOpen, "Inspector Panel is not open");
|
||||
|
||||
iframe = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<p>bug 699308 - test iframe navigation" +
|
||||
"<iframe src='data:text/html,hello world'></iframe>";
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Inspect Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
let doc;
|
||||
let testDiv;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="testdiv">Test div!</div>';
|
||||
doc.title = "Inspector Change Test";
|
||||
startInspectorTests();
|
||||
}
|
||||
|
||||
|
||||
function getInspectorProp(aName)
|
||||
{
|
||||
for each (let view in InspectorUI.stylePanel.cssHtmlTree.propertyViews) {
|
||||
if (view.name == aName) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function startInspectorTests()
|
||||
{
|
||||
ok(InspectorUI, "InspectorUI variable exists");
|
||||
Services.obs.addObserver(runInspectorTests,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runInspectorTests()
|
||||
{
|
||||
Services.obs.removeObserver(runInspectorTests, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
|
||||
testDiv = doc.getElementById("testdiv");
|
||||
|
||||
testDiv.style.fontSize = "10px";
|
||||
|
||||
InspectorUI.inspectNode(testDiv);
|
||||
InspectorUI.stopInspecting();
|
||||
|
||||
// Start up the style inspector panel...
|
||||
Services.obs.addObserver(stylePanelTests, "StyleInspector-populated", false);
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.showSidebar();
|
||||
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
|
||||
});
|
||||
}
|
||||
|
||||
function stylePanelTests()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelTests, "StyleInspector-populated");
|
||||
|
||||
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
|
||||
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "10px", "Style inspector should be showing the correct font size.");
|
||||
|
||||
Services.obs.addObserver(stylePanelAfterChange, "StyleInspector-populated", false);
|
||||
|
||||
testDiv.style.fontSize = "15px";
|
||||
InspectorUI.nodeChanged();
|
||||
}
|
||||
|
||||
function stylePanelAfterChange()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelAfterChange, "StyleInspector-populated");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "15px", "Style inspector should be showing the new font size.");
|
||||
|
||||
stylePanelNotActive();
|
||||
}
|
||||
|
||||
function stylePanelNotActive()
|
||||
{
|
||||
// Tests changes made while the style panel is not active.
|
||||
InspectorUI.ruleButton.click();
|
||||
executeSoon(function() {
|
||||
testDiv.style.fontSize = "20px";
|
||||
Services.obs.addObserver(stylePanelAfterSwitch, "StyleInspector-populated", false);
|
||||
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
|
||||
});
|
||||
}
|
||||
|
||||
function stylePanelAfterSwitch()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelAfterSwitch, "StyleInspector-populated");
|
||||
|
||||
let propView = getInspectorProp("font-size");
|
||||
is(propView.value, "20px", "Style inspector should be showing the newest font size.");
|
||||
|
||||
Services.obs.addObserver(finishTest, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
executeSoon(function() {
|
||||
InspectorUI.closeInspectorUI(true);
|
||||
});
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
Services.obs.removeObserver(finishTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for inspector";
|
||||
}
|
||||
|
|
@ -34,13 +34,14 @@ function setupHTMLPanel()
|
|||
{
|
||||
Services.obs.removeObserver(setupHTMLPanel, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
|
||||
Services.obs.addObserver(runEditorTests, InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, false);
|
||||
InspectorUI.treePanel.open();
|
||||
InspectorUI.toolShow(InspectorUI.treePanel.registrationObject);
|
||||
}
|
||||
|
||||
function runEditorTests()
|
||||
{
|
||||
Services.obs.removeObserver(runEditorTests, InspectorUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY);
|
||||
InspectorUI.stopInspecting();
|
||||
InspectorUI.inspectNode(doc.body, true);
|
||||
|
||||
// setup generator for async test steps
|
||||
editorTestSteps = doEditorTestSteps();
|
||||
|
@ -54,6 +55,14 @@ function runEditorTests()
|
|||
doNextStep();
|
||||
}
|
||||
|
||||
function highlighterTrap()
|
||||
{
|
||||
// bug 696107
|
||||
Services.obs.removeObserver(highlighterTrap, InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
|
||||
ok(false, "Highlighter moved. Shouldn't be here!");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function doEditorTestSteps()
|
||||
{
|
||||
let treePanel = InspectorUI.treePanel;
|
||||
|
@ -78,6 +87,9 @@ function doEditorTestSteps()
|
|||
|
||||
// Step 2: validate editing session, enter new attribute value into editor, and save input
|
||||
ok(InspectorUI.treePanel.editingContext, "Step 2: editor session started");
|
||||
let selection = InspectorUI.selection;
|
||||
|
||||
ok(selection, "Selection is: " + selection);
|
||||
|
||||
let editorVisible = editor.classList.contains("editing");
|
||||
ok(editorVisible, "editor popup visible");
|
||||
|
@ -103,8 +115,13 @@ function doEditorTestSteps()
|
|||
editorInput.value = "Hello World";
|
||||
editorInput.focus();
|
||||
|
||||
// hit <enter> to save the inputted value
|
||||
Services.obs.addObserver(highlighterTrap,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
|
||||
|
||||
// hit <enter> to save the textbox value
|
||||
executeSoon(function() {
|
||||
// Extra key to test that keyboard handlers have been removed. bug 696107.
|
||||
EventUtils.synthesizeKey("VK_LEFT", {}, attrValNode_id.ownerDocument.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, attrValNode_id.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
|
@ -112,6 +129,8 @@ function doEditorTestSteps()
|
|||
yield;
|
||||
yield; // End of Step 2
|
||||
|
||||
// remove this from previous step
|
||||
Services.obs.removeObserver(highlighterTrap, InspectorUI.INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
|
||||
|
||||
// Step 3: validate that the previous editing session saved correctly, then open editor on `class` attribute value
|
||||
ok(!treePanel.editingContext, "Step 3: editor session ended");
|
||||
|
@ -210,16 +229,14 @@ function doEditorTestSteps()
|
|||
is(attrValNode_id.innerHTML, "Hello World", "attribute-value node in HTML panel *not* updated");
|
||||
|
||||
// End of Step 8
|
||||
|
||||
// end of all steps, so clean up
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_OPENED, false);
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED, false);
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_SAVED, false);
|
||||
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
// end of all steps, so clean up
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_OPENED, false);
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED, false);
|
||||
Services.obs.removeObserver(doNextStep, InspectorUI.INSPECTOR_NOTIFICATIONS.EDITOR_SAVED, false);
|
||||
doc = div = null;
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
|
|
|
@ -95,22 +95,34 @@ function treePanelTests()
|
|||
|
||||
executeSoon(function() {
|
||||
InspectorUI.showSidebar();
|
||||
document.getElementById(InspectorUI.getToolbarButtonId("styleinspector")).click();
|
||||
});
|
||||
}
|
||||
|
||||
function stylePanelTests()
|
||||
{
|
||||
Services.obs.removeObserver(stylePanelTests, "StyleInspector-opened");
|
||||
Services.obs.addObserver(runContextMenuTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
|
||||
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
|
||||
ok(InspectorUI.stylePanel.cssHtmlTree, "Style Panel has a cssHtmlTree");
|
||||
|
||||
InspectorUI.ruleButton.click();
|
||||
executeSoon(function() {
|
||||
ruleViewTests();
|
||||
});
|
||||
}
|
||||
|
||||
function ruleViewTests()
|
||||
{
|
||||
Services.obs.addObserver(runContextMenuTest,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
|
||||
|
||||
ok(InspectorUI.isRuleViewOpen(), "Rule View is open");
|
||||
ok(InspectorUI.ruleView, "InspectorUI has a cssRuleView");
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.closeInspectorUI();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function runContextMenuTest()
|
||||
|
@ -193,6 +205,10 @@ function finishInspectorTests()
|
|||
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
|
||||
ok(!InspectorUI.inspecting, "Inspector is not inspecting");
|
||||
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is closed");
|
||||
ok(!InspectorUI.stylePanel, "Inspector Style Panel is gone");
|
||||
ok(!InspectorUI.ruleView, "Inspector Rule View is gone");
|
||||
is(InspectorUI.sidebarToolbar.children.length, 0, "No items in the Sidebar toolbar");
|
||||
is(InspectorUI.sidebarDeck.children.length, 0, "No items in the Sidebar deck");
|
||||
ok(!InspectorUI.toolbar, "toolbar is hidden");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
|
|
|
@ -62,6 +62,7 @@ function inspectorUIOpen1()
|
|||
// 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");
|
||||
|
||||
|
@ -88,6 +89,7 @@ function inspectorTabOpen2()
|
|||
// Make sure the inspector is closed.
|
||||
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
|
||||
ok(!InspectorUI.treePanel, "Inspector Tree Panel is closed");
|
||||
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
|
||||
is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
|
||||
|
||||
// Activate the inspector again.
|
||||
|
@ -147,6 +149,26 @@ function inspectorOpenTreePanelTab1()
|
|||
is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
|
||||
is(InspectorUI.selection, div, "selection matches the div element");
|
||||
|
||||
Services.obs.addObserver(inspectorSidebarStyleView1, "StyleInspector-opened", false);
|
||||
|
||||
executeSoon(function() {
|
||||
InspectorUI.showSidebar();
|
||||
InspectorUI.toolShow(InspectorUI.stylePanel.registrationObject);
|
||||
});
|
||||
}
|
||||
|
||||
function inspectorSidebarStyleView1()
|
||||
{
|
||||
Services.obs.removeObserver(inspectorSidebarStyleView1, "StyleInspector-opened");
|
||||
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
|
||||
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance");
|
||||
InspectorUI.sidebarTools.forEach(function(aTool) {
|
||||
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id));
|
||||
is(btn.hasAttribute("checked"),
|
||||
(aTool == InspectorUI.stylePanel.registrationObject),
|
||||
"Button " + btn.id + " has correct checked attribute");
|
||||
});
|
||||
|
||||
// Switch back to tab 2.
|
||||
Services.obs.addObserver(inspectorFocusTab2,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
|
@ -161,6 +183,7 @@ function inspectorFocusTab2()
|
|||
// Make sure the inspector is still open.
|
||||
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
|
||||
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
|
||||
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
|
||||
is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
|
||||
isnot(InspectorUI.selection, div, "selection does not match the div element");
|
||||
|
||||
|
@ -180,6 +203,15 @@ function inspectorSecondFocusTab1()
|
|||
is(InspectorUI.store.length, 2, "Inspector.store.length = 2");
|
||||
is(InspectorUI.selection, div, "selection matches the div element");
|
||||
|
||||
ok(InspectorUI.isSidebarOpen, "Inspector Sidebar is open");
|
||||
ok(InspectorUI.stylePanel, "Inspector Has a Style Panel Instance");
|
||||
InspectorUI.sidebarTools.forEach(function(aTool) {
|
||||
let btn = document.getElementById(InspectorUI.getToolbarButtonId(aTool.id));
|
||||
is(btn.hasAttribute("checked"),
|
||||
(aTool == InspectorUI.stylePanel.registrationObject),
|
||||
"Button " + btn.id + " has correct checked attribute");
|
||||
});
|
||||
|
||||
// Switch back to tab 2.
|
||||
Services.obs.addObserver(inspectorSecondFocusTab2,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
|
@ -194,6 +226,8 @@ function inspectorSecondFocusTab2()
|
|||
// Make sure the inspector is still open.
|
||||
ok(!InspectorUI.inspecting, "Inspector is not highlighting");
|
||||
ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
|
||||
ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
|
||||
|
||||
is(InspectorUI.store.length, 2, "Inspector.store.length is 2");
|
||||
isnot(InspectorUI.selection, div, "selection does not match the div element");
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ browser.jar:
|
|||
content/browser/NetworkPanel.xhtml (webconsole/NetworkPanel.xhtml)
|
||||
* content/browser/scratchpad.xul (scratchpad/scratchpad.xul)
|
||||
* content/browser/scratchpad.js (scratchpad/scratchpad.js)
|
||||
content/browser/csshtmltree.xhtml (styleinspector/csshtmltree.xhtml)
|
||||
content/browser/devtools/cssruleview.xhtml (styleinspector/cssruleview.xhtml)
|
||||
content/browser/devtools/csshtmltree.xul (styleinspector/csshtmltree.xul)
|
||||
content/browser/devtools/cssruleview.xul (styleinspector/cssruleview.xul)
|
||||
content/browser/devtools/styleinspector.css (styleinspector/styleinspector.css)
|
||||
content/browser/orion.js (sourceeditor/orion/orion.js)
|
||||
content/browser/orion.css (sourceeditor/orion/orion.css)
|
||||
|
|
|
@ -798,6 +798,8 @@ var Scratchpad = {
|
|||
*/
|
||||
onEditPopupShowing: function SP_onEditPopupShowing()
|
||||
{
|
||||
goUpdateGlobalEditMenuItems();
|
||||
|
||||
let undo = document.getElementById("sp-cmd-undo");
|
||||
undo.setAttribute("disabled", !this.editor.canUndo());
|
||||
|
||||
|
|
|
@ -290,7 +290,8 @@
|
|||
</menubar>
|
||||
|
||||
<popupset id="scratchpad-popups">
|
||||
<menupopup id="scratchpad-text-popup">
|
||||
<menupopup id="scratchpad-text-popup"
|
||||
onpopupshowing="goUpdateGlobalEditMenuItems()">
|
||||
<menuitem id="menu_cut"/>
|
||||
<menuitem id="menu_copy"/>
|
||||
<menuitem id="menu_paste"/>
|
||||
|
|
|
@ -56,6 +56,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_scratchpad_open.js \
|
||||
browser_scratchpad_restore.js \
|
||||
browser_scratchpad_bug_679467_falsy.js \
|
||||
browser_scratchpad_bug_699130_edit_ui_updates.js \
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource:///modules/source-editor.jsm");
|
||||
|
||||
// Reference to the Scratchpad chrome window object.
|
||||
let gScratchpadWindow;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
|
||||
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
|
||||
waitForFocus(runTests, gScratchpadWindow);
|
||||
}, false);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,test Edit menu updates Scratchpad - bug 699130";
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
let sp = gScratchpadWindow.Scratchpad;
|
||||
let doc = gScratchpadWindow.document;
|
||||
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
let OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||
|
||||
info("will test the Edit menu");
|
||||
|
||||
let pass = 0;
|
||||
|
||||
sp.setText("bug 699130: hello world! (edit menu)");
|
||||
|
||||
let editMenu = doc.getElementById("sp-edit-menu");
|
||||
ok(editMenu, "the Edit menu");
|
||||
let menubar = editMenu.parentNode;
|
||||
ok(menubar, "menubar found");
|
||||
|
||||
let editMenuIndex = -1;
|
||||
for (let i = 0; i < menubar.children.length; i++) {
|
||||
if (menubar.children[i] === editMenu) {
|
||||
editMenuIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
isnot(editMenuIndex, -1, "Edit menu index is correct");
|
||||
|
||||
let menuPopup = editMenu.menupopup;
|
||||
ok(menuPopup, "the Edit menupopup");
|
||||
let cutItem = doc.getElementById("sp-menu-cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
let pasteItem = doc.getElementById("sp-menu-paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
let anchor = doc.documentElement;
|
||||
let isContextMenu = false;
|
||||
|
||||
let openMenu = function(aX, aY, aCallback) {
|
||||
if (!editMenu || OS != "Darwin") {
|
||||
menuPopup.addEventListener("popupshown", function onPopupShown() {
|
||||
menuPopup.removeEventListener("popupshown", onPopupShown, false);
|
||||
executeSoon(aCallback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
executeSoon(function() {
|
||||
if (editMenu) {
|
||||
if (OS == "Darwin") {
|
||||
winUtils.forceUpdateNativeMenuAt(editMenuIndex);
|
||||
executeSoon(aCallback);
|
||||
} else {
|
||||
editMenu.open = true;
|
||||
}
|
||||
} else {
|
||||
menuPopup.openPopup(anchor, "overlap", aX, aY, isContextMenu, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let closeMenu = function(aCallback) {
|
||||
if (!editMenu || OS != "Darwin") {
|
||||
menuPopup.addEventListener("popuphidden", function onPopupHidden() {
|
||||
menuPopup.removeEventListener("popuphidden", onPopupHidden, false);
|
||||
executeSoon(aCallback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
executeSoon(function() {
|
||||
if (editMenu) {
|
||||
if (OS == "Darwin") {
|
||||
winUtils.forceUpdateNativeMenuAt(editMenuIndex);
|
||||
executeSoon(aCallback);
|
||||
} else {
|
||||
editMenu.open = false;
|
||||
}
|
||||
} else {
|
||||
menuPopup.hidePopup();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
let firstShow = function() {
|
||||
ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled");
|
||||
closeMenu(firstHide);
|
||||
};
|
||||
|
||||
let firstHide = function() {
|
||||
sp.selectRange(0, 10);
|
||||
openMenu(11, 11, showAfterSelect);
|
||||
};
|
||||
|
||||
let showAfterSelect = function() {
|
||||
ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after select");
|
||||
closeMenu(hideAfterSelect);
|
||||
};
|
||||
|
||||
let hideAfterSelect = function() {
|
||||
sp.editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onCut);
|
||||
EventUtils.synthesizeKey("x", {accelKey: true}, gScratchpadWindow);
|
||||
};
|
||||
|
||||
let onCut = function() {
|
||||
sp.editor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onCut);
|
||||
openMenu(12, 12, showAfterCut);
|
||||
};
|
||||
|
||||
let showAfterCut = function() {
|
||||
ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled after cut");
|
||||
ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after cut");
|
||||
closeMenu(hideAfterCut);
|
||||
};
|
||||
|
||||
let hideAfterCut = function() {
|
||||
sp.editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onPaste);
|
||||
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
|
||||
};
|
||||
|
||||
let onPaste = function() {
|
||||
sp.editor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onPaste);
|
||||
openMenu(13, 13, showAfterPaste);
|
||||
};
|
||||
|
||||
let showAfterPaste = function() {
|
||||
ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled after paste");
|
||||
ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after paste");
|
||||
closeMenu(hideAfterPaste);
|
||||
};
|
||||
|
||||
let hideAfterPaste = function() {
|
||||
if (pass == 0) {
|
||||
pass++;
|
||||
testContextMenu();
|
||||
} else {
|
||||
finishTest();
|
||||
}
|
||||
};
|
||||
|
||||
let testContextMenu = function() {
|
||||
info("will test the context menu");
|
||||
|
||||
editMenu = null;
|
||||
isContextMenu = true;
|
||||
|
||||
menuPopup = doc.getElementById("scratchpad-text-popup");
|
||||
ok(menuPopup, "the context menupopup");
|
||||
cutItem = doc.getElementById("menu_cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
pasteItem = doc.getElementById("menu_paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
sp.setText("bug 699130: hello world! (context menu)");
|
||||
openMenu(10, 10, firstShow);
|
||||
};
|
||||
|
||||
let finishTest = function() {
|
||||
gScratchpadWindow.close();
|
||||
gScratchpadWindow = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
};
|
||||
|
||||
openMenu(10, 10, firstShow);
|
||||
}
|
|
@ -22,6 +22,9 @@ Orion version: git clone from 2011-10-26
|
|||
+ patch for Eclipse Bug 362428 - _getXToOffset() throws:
|
||||
https://github.com/mihaisucan/orion.client/tree/bug-362428
|
||||
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362428
|
||||
+ patch for Eclipse Bug 362835 - Pasted HTML shows twice:
|
||||
https://github.com/mihaisucan/orion.client/tree/bug-362835
|
||||
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362835
|
||||
|
||||
# License
|
||||
|
||||
|
|
|
@ -1952,7 +1952,7 @@ if (typeof window !== "undefined" && typeof window.define !== "undefined") {
|
|||
* Contributors:
|
||||
* Felipe Heidrich (IBM Corporation) - initial API and implementation
|
||||
* Silenio Quarti (IBM Corporation) - initial API and implementation
|
||||
* Mihai Sucan (Mozilla Foundation) - fix for Bug#334583 Bug#348471 Bug#349485 Bug#350595 Bug#360726 Bug#361180 Bug#358623 Bug#362286 Bug#362107 Bug#362428
|
||||
* Mihai Sucan (Mozilla Foundation) - fix for Bug#334583 Bug#348471 Bug#349485 Bug#350595 Bug#360726 Bug#361180 Bug#358623 Bug#362286 Bug#362107 Bug#362428 Bug#362835
|
||||
******************************************************************************/
|
||||
|
||||
/*global window document navigator setTimeout clearTimeout XMLHttpRequest define */
|
||||
|
@ -5673,7 +5673,10 @@ orion.textview.TextView = (function() {
|
|||
this._ignorePaste = true;
|
||||
try {
|
||||
result = document.execCommand("paste", false, null);
|
||||
} catch (ex) {}
|
||||
} catch (ex) {
|
||||
// Firefox can throw even when execCommand() works, see bug 362835
|
||||
result = clipboardDiv.childNodes.length > 1 || clipboardDiv.firstChild && clipboardDiv.firstChild.childNodes.length > 0;
|
||||
}
|
||||
this._ignorePaste = false;
|
||||
if (!result) {
|
||||
/*
|
||||
|
|
|
@ -73,7 +73,10 @@ function editorLoaded()
|
|||
let text = editor.getText();
|
||||
ok(text, "editor has content after paste");
|
||||
|
||||
isnot(text.indexOf("foobarBug684862"), -1, "editor content is correct");
|
||||
let pos = text.indexOf("foobarBug684862");
|
||||
isnot(pos, -1, "editor content is correct");
|
||||
// Test for bug 699541 - Pasted HTML shows twice in Orion.
|
||||
is(text.lastIndexOf("foobarBug684862"), pos, "editor content is correct (no duplicate)");
|
||||
|
||||
executeSoon(function() {
|
||||
editor.setCaretOffset(4);
|
||||
|
@ -82,7 +85,7 @@ function editorLoaded()
|
|||
|
||||
text = editor.getText();
|
||||
|
||||
isnot(text.indexOf("foobarBug684862"), -1,
|
||||
is(text.indexOf("foobarBug684862"), pos + 1,
|
||||
"editor content is correct after navigation");
|
||||
is(editor.getCaretOffset(), 6, "caret location");
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ function CssHtmlTree(aStyleInspector)
|
|||
this.getRTLAttr = this.win.getComputedStyle(this.win.gBrowser).direction;
|
||||
this.propertyViews = [];
|
||||
|
||||
// The document in which we display the results (csshtmltree.xhtml).
|
||||
// The document in which we display the results (csshtmltree.xul).
|
||||
this.styleDocument = this.styleWin.contentWindow.document;
|
||||
|
||||
// Nodes used in templating
|
||||
|
@ -81,6 +81,9 @@ function CssHtmlTree(aStyleInspector)
|
|||
this.templateProperty = this.styleDocument.getElementById("templateProperty");
|
||||
this.panel = aStyleInspector.panel;
|
||||
|
||||
// No results text.
|
||||
this.noResults = this.styleDocument.getElementById("noResults");
|
||||
|
||||
// The element that we're inspecting, and the document that it comes from.
|
||||
this.viewedElement = null;
|
||||
this.createStyleViews();
|
||||
|
@ -133,20 +136,30 @@ XPCOMUtils.defineLazyGetter(CssHtmlTree, "_strings", function() Services.strings
|
|||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
|
||||
|
||||
CssHtmlTree.prototype = {
|
||||
// Cache the list of properties that have matched and unmatched properties.
|
||||
_matchedProperties: null,
|
||||
_unmatchedProperties: null,
|
||||
|
||||
htmlComplete: false,
|
||||
|
||||
// Used for cancelling timeouts in the style filter.
|
||||
filterChangedTimeout: null,
|
||||
_filterChangedTimeout: null,
|
||||
|
||||
// The search filter
|
||||
searchField: null,
|
||||
|
||||
|
||||
// Reference to the "Only user Styles" checkbox.
|
||||
onlyUserStylesCheckbox: null,
|
||||
|
||||
// Holds the ID of the panelRefresh timeout.
|
||||
_panelRefreshTimeout: null,
|
||||
|
||||
// Toggle for zebra striping
|
||||
_darkStripe: true,
|
||||
|
||||
// Number of visible properties
|
||||
numVisibleProperties: 0,
|
||||
|
||||
get showOnlyUserStyles()
|
||||
{
|
||||
return this.onlyUserStylesCheckbox.checked;
|
||||
|
@ -159,17 +172,19 @@ CssHtmlTree.prototype = {
|
|||
*/
|
||||
highlight: function CssHtmlTree_highlight(aElement)
|
||||
{
|
||||
if (this.viewedElement == aElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewedElement = aElement;
|
||||
this._unmatchedProperties = null;
|
||||
this._matchedProperties = null;
|
||||
|
||||
CssHtmlTree.processTemplate(this.templatePath, this.path, this);
|
||||
|
||||
if (this.htmlComplete) {
|
||||
this.refreshPanel();
|
||||
} else {
|
||||
if (this._panelRefreshTimeout) {
|
||||
this.win.clearTimeout(this._panelRefreshTimeout);
|
||||
}
|
||||
|
||||
CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
|
||||
|
||||
// We use a setTimeout loop to display the properties in batches of 15 at a
|
||||
|
@ -185,21 +200,27 @@ CssHtmlTree.prototype = {
|
|||
let propView = new PropertyView(this, name);
|
||||
CssHtmlTree.processTemplate(this.templateProperty,
|
||||
this.propertyContainer, propView, true);
|
||||
propView.refreshMatchedSelectors();
|
||||
propView.refreshUnmatchedSelectors();
|
||||
if (propView.visible) {
|
||||
this.numVisibleProperties++;
|
||||
}
|
||||
propView.refreshAllSelectors();
|
||||
this.propertyViews.push(propView);
|
||||
}
|
||||
if (i < max) {
|
||||
// There are still some properties to display. We loop here to display
|
||||
// the next batch of 15.
|
||||
this.win.setTimeout(displayProperties.bind(this), 50);
|
||||
this._panelRefreshTimeout =
|
||||
this.win.setTimeout(displayProperties.bind(this), 15);
|
||||
} else {
|
||||
this.htmlComplete = true;
|
||||
this._panelRefreshTimeout = null;
|
||||
this.noResults.hidden = this.numVisibleProperties > 0;
|
||||
Services.obs.notifyObservers(null, "StyleInspector-populated", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.win.setTimeout(displayProperties.bind(this), 50);
|
||||
this._panelRefreshTimeout =
|
||||
this.win.setTimeout(displayProperties.bind(this), 15);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -208,7 +229,17 @@ CssHtmlTree.prototype = {
|
|||
*/
|
||||
refreshPanel: function CssHtmlTree_refreshPanel()
|
||||
{
|
||||
this.win.clearTimeout(this._panelRefreshTimeout);
|
||||
if (this._panelRefreshTimeout) {
|
||||
this.win.clearTimeout(this._panelRefreshTimeout);
|
||||
}
|
||||
|
||||
this.noResults.hidden = true;
|
||||
|
||||
// Reset visible property count
|
||||
this.numVisibleProperties = 0;
|
||||
|
||||
// Reset zebra striping.
|
||||
this._darkStripe = true;
|
||||
|
||||
// We use a setTimeout loop to display the properties in batches of 15 at a
|
||||
// time. This results in a perceptibly more responsive UI.
|
||||
|
@ -223,12 +254,14 @@ CssHtmlTree.prototype = {
|
|||
if (i < max) {
|
||||
// There are still some property views to refresh. We loop here to
|
||||
// display the next batch of 15.
|
||||
this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 0);
|
||||
this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 15);
|
||||
} else {
|
||||
this._panelRefreshTimeout = null;
|
||||
this.noResults.hidden = this.numVisibleProperties > 0;
|
||||
Services.obs.notifyObservers(null, "StyleInspector-populated", null);
|
||||
}
|
||||
}
|
||||
this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 0);
|
||||
this._panelRefreshTimeout = this.win.setTimeout(refreshView.bind(this), 15);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -254,13 +287,13 @@ CssHtmlTree.prototype = {
|
|||
{
|
||||
let win = this.styleWin.contentWindow;
|
||||
|
||||
if (this.filterChangedTimeout) {
|
||||
win.clearTimeout(this.filterChangedTimeout);
|
||||
this.filterChangeTimeout = null;
|
||||
if (this._filterChangedTimeout) {
|
||||
win.clearTimeout(this._filterChangedTimeout);
|
||||
}
|
||||
|
||||
this.filterChangedTimeout = win.setTimeout(function() {
|
||||
this._filterChangedTimeout = win.setTimeout(function() {
|
||||
this.refreshPanel();
|
||||
this._filterChangeTimeout = null;
|
||||
}.bind(this), FILTER_CHANGED_TIMEOUT);
|
||||
},
|
||||
|
||||
|
@ -275,6 +308,7 @@ CssHtmlTree.prototype = {
|
|||
*/
|
||||
onlyUserStylesChanged: function CssHtmltree_onlyUserStylesChanged(aEvent)
|
||||
{
|
||||
this._matchedProperties = null;
|
||||
this.cssLogic.sourceFilter = this.showOnlyUserStyles ?
|
||||
CssLogic.FILTER.ALL :
|
||||
CssLogic.FILTER.UA;
|
||||
|
@ -305,8 +339,8 @@ CssHtmlTree.prototype = {
|
|||
CssHtmlTree.propertyNames = [];
|
||||
|
||||
// Here we build and cache a list of css properties supported by the browser
|
||||
// We could use any element but let's use the main document's body
|
||||
let styles = this.styleWin.contentWindow.getComputedStyle(this.styleDocument.body);
|
||||
// We could use any element but let's use the main document's root element
|
||||
let styles = this.styleWin.contentWindow.getComputedStyle(this.styleDocument.documentElement);
|
||||
let mozProps = [];
|
||||
for (let i = 0, numStyles = styles.length; i < numStyles; i++) {
|
||||
let prop = styles.item(i);
|
||||
|
@ -322,6 +356,56 @@ CssHtmlTree.prototype = {
|
|||
mozProps.sort());
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a list of properties that have matched selectors.
|
||||
*
|
||||
* @return {object} the object maps property names (keys) to booleans (values)
|
||||
* that tell if the given property has matched selectors or not.
|
||||
*/
|
||||
get matchedProperties()
|
||||
{
|
||||
if (!this._matchedProperties) {
|
||||
this._matchedProperties =
|
||||
this.cssLogic.hasMatchedSelectors(CssHtmlTree.propertyNames);
|
||||
}
|
||||
return this._matchedProperties;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a property has unmatched selectors. Result is cached.
|
||||
*
|
||||
* @param {string} aProperty the name of the property you want to check.
|
||||
* @return {boolean} true if the property has unmatched selectors, false
|
||||
* otherwise.
|
||||
*/
|
||||
hasUnmatchedSelectors: function CssHtmlTree_hasUnmatchedSelectors(aProperty)
|
||||
{
|
||||
// Initially check all of the properties that return false for
|
||||
// hasMatchedSelectors(). This speeds-up the UI.
|
||||
if (!this._unmatchedProperties) {
|
||||
let properties = [];
|
||||
CssHtmlTree.propertyNames.forEach(function(aName) {
|
||||
if (!this.matchedProperties[aName]) {
|
||||
properties.push(aName);
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (properties.indexOf(aProperty) == -1) {
|
||||
properties.push(aProperty);
|
||||
}
|
||||
|
||||
this._unmatchedProperties = this.cssLogic.hasUnmatchedSelectors(properties);
|
||||
}
|
||||
|
||||
// Lazy-get the result for properties we do not have cached.
|
||||
if (!(aProperty in this._unmatchedProperties)) {
|
||||
let result = this.cssLogic.hasUnmatchedSelectors([aProperty]);
|
||||
this._unmatchedProperties[aProperty] = result[aProperty];
|
||||
}
|
||||
|
||||
return this._unmatchedProperties[aProperty];
|
||||
},
|
||||
|
||||
/**
|
||||
* Destructor for CssHtmlTree.
|
||||
*/
|
||||
|
@ -329,16 +413,20 @@ CssHtmlTree.prototype = {
|
|||
{
|
||||
delete this.viewedElement;
|
||||
|
||||
// Remove event listeners
|
||||
this.onlyUserStylesCheckbox.removeEventListener("command",
|
||||
this.onlyUserStylesChanged);
|
||||
this.searchField.removeEventListener("command", this.filterChanged);
|
||||
|
||||
// Nodes used in templating
|
||||
delete this.root;
|
||||
delete this.path;
|
||||
delete this.templateRoot;
|
||||
delete this.templatePath;
|
||||
delete this.propertyContainer;
|
||||
delete this.templateProperty;
|
||||
delete this.panel;
|
||||
|
||||
// The document in which we display the results (csshtmltree.xhtml).
|
||||
// The document in which we display the results (csshtmltree.xul).
|
||||
delete this.styleDocument;
|
||||
|
||||
// The element that we're inspecting, and the document that it comes from.
|
||||
|
@ -368,13 +456,15 @@ function PropertyView(aTree, aName)
|
|||
this.link = "https://developer.mozilla.org/en/CSS/" + aName;
|
||||
|
||||
this.templateMatchedSelectors = aTree.styleDocument.getElementById("templateMatchedSelectors");
|
||||
this.templateUnmatchedSelectors = aTree.styleDocument.getElementById("templateUnmatchedSelectors");
|
||||
}
|
||||
|
||||
PropertyView.prototype = {
|
||||
// The parent element which contains the open attribute
|
||||
element: null,
|
||||
|
||||
// Property header node
|
||||
propertyHeader: null,
|
||||
|
||||
// Destination for property values
|
||||
valueNode: null,
|
||||
|
||||
|
@ -384,29 +474,23 @@ PropertyView.prototype = {
|
|||
// Are unmatched rules expanded?
|
||||
unmatchedExpanded: false,
|
||||
|
||||
// Unmatched selector table
|
||||
unmatchedSelectorTable: null,
|
||||
|
||||
// Matched selector container
|
||||
matchedSelectorsContainer: null,
|
||||
|
||||
// Unmatched selector container
|
||||
unmatchedSelectorsContainer: null,
|
||||
|
||||
// Matched selector expando
|
||||
matchedExpander: null,
|
||||
|
||||
// Unmatched selector expando
|
||||
unmatchedExpander: null,
|
||||
|
||||
// Container for X matched selectors
|
||||
matchedSelectorsTitleNode: null,
|
||||
// Unmatched selector container
|
||||
unmatchedSelectorsContainer: null,
|
||||
|
||||
// Container for X unmatched selectors
|
||||
unmatchedSelectorsTitleNode: null,
|
||||
|
||||
// Matched selectors table
|
||||
matchedSelectorTable: null,
|
||||
|
||||
// Unmatched selectors table
|
||||
unmatchedSelectorTable: null,
|
||||
// Unmatched title block
|
||||
unmatchedTitleBlock: null,
|
||||
|
||||
// Cache for matched selector views
|
||||
_matchedSelectorViews: null,
|
||||
|
@ -441,7 +525,7 @@ PropertyView.prototype = {
|
|||
*/
|
||||
get hasMatchedSelectors()
|
||||
{
|
||||
return this.propertyInfo.hasMatchedSelectors();
|
||||
return this.name in this.tree.matchedProperties;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -449,7 +533,7 @@ PropertyView.prototype = {
|
|||
*/
|
||||
get hasUnmatchedSelectors()
|
||||
{
|
||||
return this.propertyInfo.hasUnmatchedSelectors();
|
||||
return this.name in this.tree.hasUnmatchedSelectors;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -472,10 +556,18 @@ PropertyView.prototype = {
|
|||
|
||||
/**
|
||||
* Returns the className that should be assigned to the propertyView.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
get className()
|
||||
{
|
||||
return this.visible ? "property-view" : "property-view-hidden";
|
||||
if (this.visible) {
|
||||
this.tree._darkStripe = !this.tree._darkStripe;
|
||||
let darkValue = this.tree._darkStripe ?
|
||||
"property-view darkrow" : "property-view";
|
||||
return darkValue;
|
||||
}
|
||||
return "property-view-hidden";
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -494,18 +586,14 @@ PropertyView.prototype = {
|
|||
if (!this.tree.viewedElement || !this.visible) {
|
||||
this.valueNode.innerHTML = "";
|
||||
this.matchedSelectorsContainer.hidden = true;
|
||||
this.unmatchedSelectorsContainer.hidden = true;
|
||||
this.matchedSelectorTable.innerHTML = "";
|
||||
this.unmatchedSelectorTable.innerHTML = "";
|
||||
this.matchedSelectorsContainer.innerHTML = "";
|
||||
this.matchedExpander.removeAttribute("open");
|
||||
this.unmatchedExpander.removeAttribute("open");
|
||||
return;
|
||||
}
|
||||
|
||||
this.tree.numVisibleProperties++;
|
||||
this.valueNode.innerHTML = this.propertyInfo.value;
|
||||
|
||||
this.refreshMatchedSelectors();
|
||||
this.refreshUnmatchedSelectors();
|
||||
this.refreshAllSelectors();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -516,12 +604,18 @@ PropertyView.prototype = {
|
|||
let hasMatchedSelectors = this.hasMatchedSelectors;
|
||||
this.matchedSelectorsContainer.hidden = !hasMatchedSelectors;
|
||||
|
||||
if (hasMatchedSelectors) {
|
||||
this.propertyHeader.classList.add("expandable");
|
||||
} else {
|
||||
this.propertyHeader.classList.remove("expandable");
|
||||
}
|
||||
|
||||
if (this.matchedExpanded && hasMatchedSelectors) {
|
||||
CssHtmlTree.processTemplate(this.templateMatchedSelectors,
|
||||
this.matchedSelectorTable, this);
|
||||
this.matchedSelectorsContainer, this);
|
||||
this.matchedExpander.setAttribute("open", "");
|
||||
} else {
|
||||
this.matchedSelectorTable.innerHTML = "";
|
||||
this.matchedSelectorsContainer.innerHTML = "";
|
||||
this.matchedExpander.removeAttribute("open");
|
||||
}
|
||||
},
|
||||
|
@ -531,17 +625,44 @@ PropertyView.prototype = {
|
|||
*/
|
||||
refreshUnmatchedSelectors: function PropertyView_refreshUnmatchedSelectors()
|
||||
{
|
||||
let hasUnmatchedSelectors = this.hasUnmatchedSelectors;
|
||||
this.unmatchedSelectorsContainer.hidden = !hasUnmatchedSelectors;
|
||||
let hasMatchedSelectors = this.hasMatchedSelectors;
|
||||
|
||||
if (this.unmatchedExpanded && hasUnmatchedSelectors) {
|
||||
CssHtmlTree.processTemplate(this.templateUnmatchedSelectors,
|
||||
this.unmatchedSelectorTable, this);
|
||||
this.unmatchedExpander.setAttribute("open", "");
|
||||
this.unmatchedSelectorTable.hidden = !this.unmatchedExpanded;
|
||||
|
||||
if (hasMatchedSelectors) {
|
||||
this.unmatchedSelectorsContainer.hidden = !this.matchedExpanded ||
|
||||
!this.hasUnmatchedSelectors;
|
||||
this.unmatchedTitleBlock.hidden = false;
|
||||
} else {
|
||||
this.unmatchedSelectorTable.innerHTML = "";
|
||||
this.unmatchedExpander.removeAttribute("open");
|
||||
this.unmatchedSelectorsContainer.hidden = !this.unmatchedExpanded;
|
||||
this.unmatchedTitleBlock.hidden = true;
|
||||
}
|
||||
|
||||
if (this.unmatchedExpanded && this.hasUnmatchedSelectors) {
|
||||
CssHtmlTree.processTemplate(this.templateUnmatchedSelectors,
|
||||
this.unmatchedSelectorTable, this);
|
||||
if (!hasMatchedSelectors) {
|
||||
this.matchedExpander.setAttribute("open", "");
|
||||
this.unmatchedSelectorTable.classList.add("only-unmatched");
|
||||
} else {
|
||||
this.unmatchedExpander.setAttribute("open", "");
|
||||
this.unmatchedSelectorTable.classList.remove("only-unmatched");
|
||||
}
|
||||
} else {
|
||||
if (!hasMatchedSelectors) {
|
||||
this.matchedExpander.removeAttribute("open");
|
||||
}
|
||||
this.unmatchedExpander.removeAttribute("open");
|
||||
this.unmatchedSelectorTable.innerHTML = "";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the panel matched and unmatched rules
|
||||
*/
|
||||
refreshAllSelectors: function PropertyView_refreshAllSelectors()
|
||||
{
|
||||
this.refreshMatchedSelectors();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -580,12 +701,18 @@ PropertyView.prototype = {
|
|||
|
||||
/**
|
||||
* The action when a user expands matched selectors.
|
||||
*
|
||||
* @param {Event} aEvent Used to determine the class name of the targets click
|
||||
* event. If the class name is "helplink" then the event is allowed to bubble
|
||||
* to the mdn link icon.
|
||||
*/
|
||||
matchedSelectorsClick: function PropertyView_matchedSelectorsClick(aEvent)
|
||||
propertyHeaderClick: function PropertyView_propertyHeaderClick(aEvent)
|
||||
{
|
||||
this.matchedExpanded = !this.matchedExpanded;
|
||||
this.refreshMatchedSelectors();
|
||||
aEvent.preventDefault();
|
||||
if (aEvent.target.className != "helplink") {
|
||||
this.matchedExpanded = !this.matchedExpanded;
|
||||
this.refreshAllSelectors();
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -597,6 +724,15 @@ PropertyView.prototype = {
|
|||
this.refreshUnmatchedSelectors();
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
/**
|
||||
* The action when a user clicks on the MDN help link for a property.
|
||||
*/
|
||||
mdnLinkClick: function PropertyView_mdnLinkClick(aEvent)
|
||||
{
|
||||
this.tree.win.openUILinkIn(this.link, "tab");
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,6 +151,7 @@ CssLogic.prototype = {
|
|||
// in processUnmatchedSelectors().
|
||||
_matchId: 0,
|
||||
|
||||
_matchedRules: null,
|
||||
_matchedSelectors: null,
|
||||
_unmatchedSelectors: null,
|
||||
|
||||
|
@ -166,6 +167,7 @@ CssLogic.prototype = {
|
|||
this._sheetIndex = 0;
|
||||
this._sheets = {};
|
||||
this._sheetsCached = false;
|
||||
this._matchedRules = null;
|
||||
this._matchedSelectors = null;
|
||||
this._unmatchedSelectors = null;
|
||||
},
|
||||
|
@ -200,6 +202,7 @@ CssLogic.prototype = {
|
|||
this._propertyInfos = {};
|
||||
}
|
||||
|
||||
this._matchedRules = null;
|
||||
this._matchedSelectors = null;
|
||||
this._unmatchedSelectors = null;
|
||||
let win = this.viewedDocument.defaultView;
|
||||
|
@ -242,6 +245,7 @@ CssLogic.prototype = {
|
|||
aValue == CssLogic.FILTER.UA);
|
||||
|
||||
if (needFullUpdate) {
|
||||
this._matchedRules = null;
|
||||
this._matchedSelectors = null;
|
||||
this._unmatchedSelectors = null;
|
||||
this._propertyInfos = {};
|
||||
|
@ -289,7 +293,7 @@ CssLogic.prototype = {
|
|||
// styleSheets isn't an array, but forEach can work on it anyway
|
||||
Array.prototype.forEach.call(this.viewedDocument.styleSheets,
|
||||
this._cacheSheet, this);
|
||||
|
||||
|
||||
this._sheetsCached = true;
|
||||
},
|
||||
|
||||
|
@ -309,19 +313,19 @@ CssLogic.prototype = {
|
|||
}
|
||||
|
||||
// Only work with stylesheets that have their media allowed.
|
||||
if (!CssLogic.sheetMediaAllowed(aDomSheet)) {
|
||||
if (!this.mediaMatches(aDomSheet)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache the sheet.
|
||||
let cssSheet = this.getSheet(aDomSheet, false, this._sheetIndex++);
|
||||
let cssSheet = this.getSheet(aDomSheet, this._sheetIndex++);
|
||||
if (cssSheet._passId != this._passId) {
|
||||
cssSheet._passId = this._passId;
|
||||
|
||||
// Find import rules.
|
||||
Array.prototype.forEach.call(aDomSheet.cssRules, function(aDomRule) {
|
||||
if (aDomRule.type == Ci.nsIDOMCSSRule.IMPORT_RULE && aDomRule.styleSheet &&
|
||||
CssLogic.sheetMediaAllowed(aDomRule)) {
|
||||
this.mediaMatches(aDomRule)) {
|
||||
this._cacheSheet(aDomRule.styleSheet);
|
||||
}
|
||||
}, this);
|
||||
|
@ -355,20 +359,18 @@ CssLogic.prototype = {
|
|||
* otherwise the new CSSStyleSheet object is cached.
|
||||
*
|
||||
* @param {CSSStyleSheet} aDomSheet the CSSStyleSheet object you want.
|
||||
* @param {boolean} aSystemSheet tells if the stylesheet is a browser-provided
|
||||
* sheet or not.
|
||||
* @param {number} aIndex the index, within the document, of the stylesheet.
|
||||
*
|
||||
* @return {CssSheet} the CssSheet object for the given CSSStyleSheet object.
|
||||
*/
|
||||
getSheet: function CL_getSheet(aDomSheet, aSystemSheet, aIndex)
|
||||
getSheet: function CL_getSheet(aDomSheet, aIndex)
|
||||
{
|
||||
let cacheId = aSystemSheet ? "1" : "0";
|
||||
let cacheId = "";
|
||||
|
||||
if (aDomSheet.href) {
|
||||
cacheId += aDomSheet.href;
|
||||
cacheId = aDomSheet.href;
|
||||
} else if (aDomSheet.ownerNode && aDomSheet.ownerNode.ownerDocument) {
|
||||
cacheId += aDomSheet.ownerNode.ownerDocument.location;
|
||||
cacheId = aDomSheet.ownerNode.ownerDocument.location;
|
||||
}
|
||||
|
||||
let sheet = null;
|
||||
|
@ -377,8 +379,10 @@ CssLogic.prototype = {
|
|||
if (cacheId in this._sheets) {
|
||||
for (let i = 0, numSheets = this._sheets[cacheId].length; i < numSheets; i++) {
|
||||
sheet = this._sheets[cacheId][i];
|
||||
if (sheet.domSheet == aDomSheet) {
|
||||
sheet.index = aIndex;
|
||||
if (sheet.domSheet === aDomSheet) {
|
||||
if (aIndex != -1) {
|
||||
sheet.index = aIndex;
|
||||
}
|
||||
sheetFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -390,8 +394,8 @@ CssLogic.prototype = {
|
|||
this._sheets[cacheId] = [];
|
||||
}
|
||||
|
||||
sheet = new CssSheet(this, aDomSheet, aSystemSheet, aIndex);
|
||||
if (sheet.sheetAllowed && !aSystemSheet) {
|
||||
sheet = new CssSheet(this, aDomSheet, aIndex);
|
||||
if (sheet.sheetAllowed && !sheet.systemSheet) {
|
||||
this._ruleCount += sheet.ruleCount;
|
||||
}
|
||||
|
||||
|
@ -486,77 +490,54 @@ CssLogic.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this._matchedRules) {
|
||||
this._buildMatchedRules();
|
||||
}
|
||||
|
||||
this._matchedSelectors = [];
|
||||
this._unmatchedSelectors = null;
|
||||
this._passId++;
|
||||
this._matchId++;
|
||||
|
||||
let element = this.viewedElement;
|
||||
let filter = this.sourceFilter;
|
||||
let sheetIndex = 0;
|
||||
let domRules = null;
|
||||
do {
|
||||
try {
|
||||
domRules = this.domUtils.getCSSStyleRules(element);
|
||||
} catch (ex) {
|
||||
Services.console.
|
||||
logStringMessage("CssLogic_processMatchedSelectors error: " + ex);
|
||||
continue;
|
||||
}
|
||||
for (let i = 0; i < this._matchedRules.length; i++) {
|
||||
let rule = this._matchedRules[i][0];
|
||||
let status = this._matchedRules[i][1];
|
||||
|
||||
let status = (this.viewedElement == element) ?
|
||||
CssLogic.STATUS.MATCHED : CssLogic.STATUS.PARENT_MATCH;
|
||||
|
||||
for (let i = 0, numRules = domRules.Count(); i < numRules; i++) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
if (domRule.type !== Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let domSheet = domRule.parentStyleSheet;
|
||||
let systemSheet = CssLogic.isSystemStyleSheet(domSheet);
|
||||
if (filter !== CssLogic.FILTER.UA && systemSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sheet = this.getSheet(domSheet, systemSheet, sheetIndex);
|
||||
let rule = sheet.getRule(domRule);
|
||||
|
||||
rule.selectors.forEach(function (aSelector) {
|
||||
if (aSelector._matchId !== this._matchId &&
|
||||
element.mozMatchesSelector(aSelector)) {
|
||||
aSelector._matchId = this._matchId;
|
||||
this._matchedSelectors.push([ aSelector, status ]);
|
||||
if (aCallback) {
|
||||
aCallback.call(aScope, aSelector, status);
|
||||
}
|
||||
rule.selectors.forEach(function (aSelector) {
|
||||
if (aSelector._matchId !== this._matchId &&
|
||||
(aSelector.elementStyle ||
|
||||
this._selectorMatchesElement(aSelector))) {
|
||||
aSelector._matchId = this._matchId;
|
||||
this._matchedSelectors.push([ aSelector, status ]);
|
||||
if (aCallback) {
|
||||
aCallback.call(aScope, aSelector, status);
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (sheet._passId !== this._passId) {
|
||||
sheetIndex++;
|
||||
sheet._passId = this._passId;
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (rule._passId !== this._passId) {
|
||||
rule._passId = this._passId;
|
||||
}
|
||||
}
|
||||
rule._passId = this._passId;
|
||||
}
|
||||
},
|
||||
|
||||
// Add element.style information.
|
||||
if (element.style.length > 0) {
|
||||
let rule = new CssRule(null, { style: element.style }, element);
|
||||
let selector = rule.selectors[0];
|
||||
selector._matchId = this._matchId;
|
||||
|
||||
this._matchedSelectors.push([ selector, status ]);
|
||||
if (aCallback) {
|
||||
aCallback.call(aScope, selector, status);
|
||||
}
|
||||
rule._passId = this._passId;
|
||||
/**
|
||||
* Check if the given selector matches the highlighted element or any of its
|
||||
* parents.
|
||||
*
|
||||
* @private
|
||||
* @param {string} aSelector the selector string you want to check.
|
||||
* @return {boolean} true if the given selector matches the highlighted
|
||||
* element or any of its parents, otherwise false is returned.
|
||||
*/
|
||||
_selectorMatchesElement: function CL__selectorMatchesElement(aSelector)
|
||||
{
|
||||
let element = this.viewedElement;
|
||||
do {
|
||||
if (element.mozMatchesSelector(aSelector)) {
|
||||
return true;
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -573,9 +554,6 @@ CssLogic.prototype = {
|
|||
*/
|
||||
processUnmatchedSelectors: function CL_processUnmatchedSelectors(aCallback, aScope)
|
||||
{
|
||||
if (!this._matchedSelectors) {
|
||||
this.processMatchedSelectors();
|
||||
}
|
||||
if (this._unmatchedSelectors) {
|
||||
if (aCallback) {
|
||||
this._unmatchedSelectors.forEach(aCallback, aScope);
|
||||
|
@ -583,17 +561,21 @@ CssLogic.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this._matchedSelectors) {
|
||||
this.processMatchedSelectors();
|
||||
}
|
||||
|
||||
this._unmatchedSelectors = [];
|
||||
|
||||
this.forEachSheet(function (aSheet) {
|
||||
// We do not show unmatched selectors from system stylesheets
|
||||
if (aSheet.systemSheet) {
|
||||
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
return;
|
||||
}
|
||||
|
||||
aSheet.forEachRule(function (aRule) {
|
||||
aRule.selectors.forEach(function (aSelector) {
|
||||
if (aSelector._matchId != this._matchId) {
|
||||
if (aSelector._matchId !== this._matchId) {
|
||||
this._unmatchedSelectors.push(aSelector);
|
||||
if (aCallback) {
|
||||
aCallback.call(aScope, aSelector);
|
||||
|
@ -607,88 +589,205 @@ CssLogic.prototype = {
|
|||
/**
|
||||
* Check if the highlighted element or it's parents have matched selectors.
|
||||
*
|
||||
* @param {function} [aCallback] Simple callback method. If aCallback is
|
||||
* provided then the domRules for each element in the loop are passed to
|
||||
* the callback function. When the element has .style properties, the callback
|
||||
* receives {style: element.style}. If the callback returns true then the
|
||||
* element has matched rules, otherwise not.
|
||||
* @return {Boolean} true if the current element or it's parents have
|
||||
* matching CssSelector objects, false otherwise
|
||||
* @param {array} aProperties The list of properties you want to check if they
|
||||
* have matched selectors or not.
|
||||
* @return {object} An object that tells for each property if it has matched
|
||||
* selectors or not. Object keys are property names and values are booleans.
|
||||
*/
|
||||
hasMatchedSelectors: function CL_hasMatchedSelectors(aCallback)
|
||||
hasMatchedSelectors: function CL_hasMatchedSelectors(aProperties)
|
||||
{
|
||||
if (!this._matchedRules) {
|
||||
this._buildMatchedRules();
|
||||
}
|
||||
|
||||
let result = {};
|
||||
|
||||
this._matchedRules.some(function(aValue) {
|
||||
let rule = aValue[0];
|
||||
aProperties = aProperties.filter(function(aProperty) {
|
||||
if (rule.getPropertyValue(aProperty)) {
|
||||
// We just need to find if a rule has this property while it matches
|
||||
// the viewedElement (or its parents).
|
||||
result[aProperty] = true;
|
||||
return false;
|
||||
}
|
||||
return true; // Keep the property for the next rule.
|
||||
});
|
||||
return aProperties.length == 0;
|
||||
}, this);
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Build the array of matched rules for the currently highlighted element.
|
||||
* The array will hold rules that match the viewedElement and its parents.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_buildMatchedRules: function CL__buildMatchedRules()
|
||||
{
|
||||
let domRules;
|
||||
let element = this.viewedElement;
|
||||
let matched = false;
|
||||
let filter = this.sourceFilter;
|
||||
let sheetIndex = 0;
|
||||
|
||||
this._matchId++;
|
||||
this._passId++;
|
||||
this._matchedRules = [];
|
||||
|
||||
do {
|
||||
let status = this.viewedElement === element ?
|
||||
CssLogic.STATUS.MATCHED : CssLogic.STATUS.PARENT_MATCH;
|
||||
|
||||
try {
|
||||
domRules = this.domUtils.getCSSStyleRules(element);
|
||||
} catch (ex) {
|
||||
Services.console.
|
||||
logStringMessage("CssLogic_hasMatchedSelectors error: " + ex);
|
||||
logStringMessage("CL__buildMatchedRules error: " + ex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the are DOM rules that we can consider as matched rules
|
||||
// (depending on the callback).
|
||||
if (domRules.Count() && (!aCallback || aCallback(domRules))) {
|
||||
matched = true;
|
||||
for (let i = 0, n = domRules.Count(); i < n; i++) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
if (domRule.type !== Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let sheet = this.getSheet(domRule.parentStyleSheet, -1);
|
||||
if (sheet._passId !== this._passId) {
|
||||
sheet.index = sheetIndex++;
|
||||
sheet._passId = this._passId;
|
||||
}
|
||||
|
||||
if (filter !== CssLogic.FILTER.UA && sheet.systemSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let rule = sheet.getRule(domRule);
|
||||
if (rule._passId === this._passId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rule._matchId = this._matchId;
|
||||
rule._passId = this._passId;
|
||||
this._matchedRules.push([rule, status]);
|
||||
}
|
||||
|
||||
// Check if the element has any element.style properties that we can
|
||||
// consider as "matched" (depending on the callback).
|
||||
if (element.style.length > 0 &&
|
||||
(!aCallback || aCallback({style: element.style}))) {
|
||||
matched = true;
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
break;
|
||||
// Add element.style information.
|
||||
if (element.style.length > 0) {
|
||||
let rule = new CssRule(null, { style: element.style }, element);
|
||||
rule._matchId = this._matchId;
|
||||
rule._passId = this._passId;
|
||||
this._matchedRules.push([rule, status]);
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
return matched;
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the highlighted element or it's parents have unmatched selectors.
|
||||
*
|
||||
* @param {String} aProperty The CSS property to check against
|
||||
* @return {Boolean} true if the current element or it's parents have
|
||||
* unmatched CssSelector objects, false otherwise
|
||||
* Please note that this method is far slower than hasMatchedSelectors()
|
||||
* because it needs to do a lot more checks in the DOM.
|
||||
*
|
||||
* @param {array} aProperties The list of properties you want to check if they
|
||||
* have unmatched selectors or not.
|
||||
* @return {object} An object that tells for each property if it has unmatched
|
||||
* selectors or not. Object keys are property names and values are booleans.
|
||||
*/
|
||||
hasUnmatchedSelectors: function CL_hasUnmatchedSelectors(aProperty)
|
||||
hasUnmatchedSelectors: function CL_hasUnmatchedSelectors(aProperties)
|
||||
{
|
||||
return this.forSomeSheets(function (aSheet) {
|
||||
// We do not show unmatched selectors from system stylesheets
|
||||
if (aSheet.systemSheet) {
|
||||
if (!this._matchedRules) {
|
||||
this._buildMatchedRules();
|
||||
}
|
||||
|
||||
let result = {};
|
||||
|
||||
this.forSomeSheets(function (aSheet) {
|
||||
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return aSheet.forSomeRules(function (aRule) {
|
||||
if (aRule.getPropertyValue(aProperty)) {
|
||||
let element = this.viewedElement;
|
||||
let selectorText = aRule._domRule.selectorText;
|
||||
let matches = false;
|
||||
let unmatched = aRule._matchId !== this._matchId ||
|
||||
this._ruleHasUnmatchedSelector(aRule);
|
||||
if (!unmatched) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (element.mozMatchesSelector(selectorText)) {
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
if (!matches) {
|
||||
// Now we know that there are rules but none match.
|
||||
aProperties = aProperties.filter(function(aProperty) {
|
||||
if (!aRule.getPropertyValue(aProperty)) {
|
||||
// Keep this property for the next rule. We need to find a rule
|
||||
// which has the property.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result[aProperty] = true;
|
||||
|
||||
// We found a rule that has the current property while it does not
|
||||
// match the current element. We can remove this property from the
|
||||
// array.
|
||||
return false;
|
||||
});
|
||||
|
||||
return aProperties.length == 0;
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
aProperties.forEach(function(aProperty) { result[aProperty] = false; });
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a CssRule has an unmatched selector for the highlighted element or
|
||||
* its parents.
|
||||
*
|
||||
* @private
|
||||
* @param {CssRule} aRule The rule you want to check if it has an unmatched
|
||||
* selector.
|
||||
* @return {boolean} True if the rule has an unmatched selector, false
|
||||
* otherwise.
|
||||
*/
|
||||
_ruleHasUnmatchedSelector: function CL__ruleHasUnmatchedSelector(aRule)
|
||||
{
|
||||
if (!aRule._cssSheet && aRule.sourceElement) {
|
||||
// CssRule wraps element.style, which never has unmatched selectors.
|
||||
return false;
|
||||
}
|
||||
|
||||
let element = this.viewedElement;
|
||||
let selectors = aRule.selectors;
|
||||
|
||||
do {
|
||||
selectors = selectors.filter(function(aSelector) {
|
||||
return !element.mozMatchesSelector(aSelector);
|
||||
});
|
||||
|
||||
if (selectors.length == 0) {
|
||||
break;
|
||||
}
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
return selectors.length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the given DOM CSS object matches the current view media.
|
||||
*
|
||||
* @param {object} aDomObject The DOM CSS object to check.
|
||||
* @return {boolean} True if the DOM CSS object matches the current view
|
||||
* media, or false otherwise.
|
||||
*/
|
||||
mediaMatches: function CL_mediaMatches(aDomObject)
|
||||
{
|
||||
let mediaText = aDomObject.media.mediaText;
|
||||
return !mediaText || this.viewedDocument.defaultView.
|
||||
matchMedia(mediaText).matches;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -789,37 +888,6 @@ CssLogic.isSystemStyleSheet = function CssLogic_isSystemStyleSheet(aSheet)
|
|||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given DOM CSS object holds an allowed media. Currently we only
|
||||
* allow media screen or all.
|
||||
*
|
||||
* @param {CSSStyleSheet|CSSImportRule|CSSMediaRule} aDomObject the
|
||||
* DOM object you want checked.
|
||||
* @return {boolean} true if the media description is allowed, or false
|
||||
* otherwise.
|
||||
*/
|
||||
CssLogic.sheetMediaAllowed = function CssLogic_sheetMediaAllowed(aDomObject)
|
||||
{
|
||||
let result = false;
|
||||
let media = aDomObject.media;
|
||||
|
||||
if (media.length > 0) {
|
||||
let mediaItem = null;
|
||||
for (let m = 0, mediaLen = media.length; m < mediaLen; m++) {
|
||||
mediaItem = media.item(m).toLowerCase();
|
||||
if (mediaItem === CssLogic.MEDIA.SCREEN ||
|
||||
mediaItem === CssLogic.MEDIA.ALL) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a shortened version of a style sheet's source.
|
||||
*
|
||||
|
@ -827,27 +895,33 @@ CssLogic.sheetMediaAllowed = function CssLogic_sheetMediaAllowed(aDomObject)
|
|||
*/
|
||||
CssLogic.shortSource = function CssLogic_shortSource(aSheet)
|
||||
{
|
||||
// Use a string like "inline" if there is no source href
|
||||
if (!aSheet || !aSheet.href) {
|
||||
return CssLogic.l10n("rule.sourceInline");
|
||||
}
|
||||
// Use a string like "inline" if there is no source href
|
||||
if (!aSheet || !aSheet.href) {
|
||||
return CssLogic.l10n("rule.sourceInline");
|
||||
}
|
||||
|
||||
// We try, in turn, the filename, filePath, query string, whole thing
|
||||
let url = Services.io.newURI(aSheet.href, null, null);
|
||||
// We try, in turn, the filename, filePath, query string, whole thing
|
||||
let url = {};
|
||||
try {
|
||||
url = Services.io.newURI(aSheet.href, null, null);
|
||||
url = url.QueryInterface(Ci.nsIURL);
|
||||
if (url.fileName) {
|
||||
return url.fileName;
|
||||
}
|
||||
} catch (ex) {
|
||||
// Some UA-provided stylesheets are not valid URLs.
|
||||
}
|
||||
|
||||
if (url.filePath) {
|
||||
return url.filePath;
|
||||
}
|
||||
if (url.fileName) {
|
||||
return url.fileName;
|
||||
}
|
||||
|
||||
if (url.query) {
|
||||
return url.query;
|
||||
}
|
||||
if (url.filePath) {
|
||||
return url.filePath;
|
||||
}
|
||||
|
||||
return this.domSheet.href;
|
||||
if (url.query) {
|
||||
return url.query;
|
||||
}
|
||||
|
||||
return aSheet.href;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -857,15 +931,13 @@ CssLogic.shortSource = function CssLogic_shortSource(aSheet)
|
|||
* @param {CssLogic} aCssLogic pointer to the CssLogic instance working with
|
||||
* this CssSheet object.
|
||||
* @param {CSSStyleSheet} aDomSheet reference to a DOM CSSStyleSheet object.
|
||||
* @param {boolean} aSystemSheet tells if the stylesheet is system-provided.
|
||||
* @param {number} aIndex tells the index/position of the stylesheet within the
|
||||
* main document.
|
||||
*/
|
||||
function CssSheet(aCssLogic, aDomSheet, aSystemSheet, aIndex)
|
||||
function CssSheet(aCssLogic, aDomSheet, aIndex)
|
||||
{
|
||||
this._cssLogic = aCssLogic;
|
||||
this.domSheet = aDomSheet;
|
||||
this.systemSheet = aSystemSheet;
|
||||
this.index = this.systemSheet ? -100 * aIndex : aIndex;
|
||||
|
||||
// Cache of the sheets href. Cached by the getter.
|
||||
|
@ -884,6 +956,44 @@ function CssSheet(aCssLogic, aDomSheet, aSystemSheet, aIndex)
|
|||
|
||||
CssSheet.prototype = {
|
||||
_passId: null,
|
||||
_systemSheet: null,
|
||||
_mediaMatches: null,
|
||||
|
||||
/**
|
||||
* Tells if the stylesheet is provided by the browser or not.
|
||||
*
|
||||
* @return {boolean} true if this is a browser-provided stylesheet, or false
|
||||
* otherwise.
|
||||
*/
|
||||
get systemSheet()
|
||||
{
|
||||
if (this._systemSheet === null) {
|
||||
this._systemSheet = CssLogic.isSystemStyleSheet(this.domSheet);
|
||||
}
|
||||
return this._systemSheet;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the stylesheet is disabled or not.
|
||||
* @return {boolean} true if this stylesheet is disabled, or false otherwise.
|
||||
*/
|
||||
get disabled()
|
||||
{
|
||||
return this.domSheet.disabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the stylesheet matches the current browser view media.
|
||||
* @return {boolean} true if this stylesheet matches the current browser view
|
||||
* media, or false otherwise.
|
||||
*/
|
||||
get mediaMatches()
|
||||
{
|
||||
if (this._mediaMatches === null) {
|
||||
this._mediaMatches = this._cssLogic.mediaMatches(this.domSheet);
|
||||
}
|
||||
return this._mediaMatches;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a source for a stylesheet, taking into account embedded stylesheets
|
||||
|
@ -976,7 +1086,7 @@ CssSheet.prototype = {
|
|||
if (cacheId in this._rules) {
|
||||
for (let i = 0, rulesLen = this._rules[cacheId].length; i < rulesLen; i++) {
|
||||
rule = this._rules[cacheId][i];
|
||||
if (rule._domRule == aDomRule) {
|
||||
if (rule._domRule === aDomRule) {
|
||||
ruleFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1018,7 +1128,7 @@ CssSheet.prototype = {
|
|||
aCallback.call(aScope, this.getRule(aDomRule));
|
||||
ruleCount++;
|
||||
} else if (aDomRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE &&
|
||||
aDomRule.cssRules && CssLogic.sheetMediaAllowed(aDomRule)) {
|
||||
aDomRule.cssRules && this._cssLogic.mediaMatches(aDomRule)) {
|
||||
Array.prototype.forEach.call(aDomRule.cssRules, _iterator, this);
|
||||
}
|
||||
}
|
||||
|
@ -1051,7 +1161,7 @@ CssSheet.prototype = {
|
|||
if (aDomRule.type == Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
return aCallback.call(aScope, this.getRule(aDomRule));
|
||||
} else if (aDomRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE &&
|
||||
aDomRule.cssRules && CssLogic.sheetMediaAllowed(aDomRule)) {
|
||||
aDomRule.cssRules && this._cssLogic.mediaMatches(aDomRule)) {
|
||||
return Array.prototype.some.call(aDomRule.cssRules, _iterator, this);
|
||||
}
|
||||
}
|
||||
|
@ -1409,8 +1519,6 @@ function CssPropertyInfo(aCssLogic, aProperty)
|
|||
// that have sheetAllowed = false).
|
||||
this._matchedSelectors = null;
|
||||
this._unmatchedSelectors = null;
|
||||
this._hasMatchedSelectors = null;
|
||||
this._hasUnmatchedSelectors = null;
|
||||
}
|
||||
|
||||
CssPropertyInfo.prototype = {
|
||||
|
@ -1508,60 +1616,6 @@ CssPropertyInfo.prototype = {
|
|||
return this._unmatchedSelectors;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the property has any matched selectors.
|
||||
*
|
||||
* @return {Boolean} true if the current element or it's parents have
|
||||
* matching CssSelector objects, false otherwise
|
||||
*/
|
||||
hasMatchedSelectors: function CssPropertyInfo_hasMatchedSelectors()
|
||||
{
|
||||
if (this._hasMatchedSelectors === null) {
|
||||
this._hasMatchedSelectors = this._cssLogic.hasMatchedSelectors(function(aDomRules) {
|
||||
if (!aDomRules.Count) {
|
||||
// For element.style.
|
||||
return !!aDomRules.style.getPropertyValue(this.property);
|
||||
}
|
||||
|
||||
for (let i = 0; i < aDomRules.Count(); i++) {
|
||||
let domRule = aDomRules.GetElementAt(i);
|
||||
|
||||
if (domRule.type !== Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let domSheet = domRule.parentStyleSheet;
|
||||
let systemSheet = CssLogic.isSystemStyleSheet(domSheet);
|
||||
let filter = this._cssLogic.sourceFilter;
|
||||
if (filter !== CssLogic.FILTER.UA && systemSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (domRule.style.getPropertyValue(this.property)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return this._hasMatchedSelectors;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the property has any matched selectors.
|
||||
*
|
||||
* @return {Boolean} true if the current element or it's parents have
|
||||
* unmatched CssSelector objects, false otherwise
|
||||
*/
|
||||
hasUnmatchedSelectors: function CssPropertyInfo_hasUnmatchedSelectors()
|
||||
{
|
||||
if (this._hasUnmatchedSelectors === null) {
|
||||
this._hasUnmatchedSelectors = this._cssLogic.hasUnmatchedSelectors(this.property);
|
||||
}
|
||||
return this._hasUnmatchedSelectors;
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the selectors that match the highlighted element and its parents.
|
||||
* Uses CssLogic.processMatchedSelectors() to find the matched selectors,
|
||||
|
|
|
@ -117,6 +117,17 @@ ElementStyle.prototype = {
|
|||
|
||||
domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils),
|
||||
|
||||
/**
|
||||
* Called by the Rule object when it has been changed through the
|
||||
* setProperty* methods.
|
||||
*/
|
||||
_changed: function ElementStyle_changed()
|
||||
{
|
||||
if (this.onChanged) {
|
||||
this.onChanged();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the list of rules to be displayed for the active element.
|
||||
* Upon completion, this.rules[] will hold a list of Rule objects.
|
||||
|
@ -125,19 +136,29 @@ ElementStyle.prototype = {
|
|||
{
|
||||
this.rules = [];
|
||||
|
||||
let element = this.element;
|
||||
do {
|
||||
this._addElementRules(element);
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
// Mark overridden computed styles.
|
||||
this.markOverridden();
|
||||
},
|
||||
|
||||
_addElementRules: function ElementStyle_addElementRules(aElement)
|
||||
{
|
||||
let inherited = aElement !== this.element ? aElement : null;
|
||||
|
||||
// Include the element's style first.
|
||||
this.rules.push(new Rule(this, {
|
||||
style: this.element.style,
|
||||
selectorText: CssLogic.l10n("rule.sourceElement")
|
||||
}));
|
||||
this._maybeAddRule({
|
||||
style: aElement.style,
|
||||
selectorText: CssLogic.l10n("rule.sourceElement"),
|
||||
inherited: inherited
|
||||
});
|
||||
|
||||
// Get the styles that apply to the element.
|
||||
try {
|
||||
var domRules = this.domUtils.getCSSStyleRules(this.element);
|
||||
} catch (ex) {
|
||||
Services.console.logStringMessage("ElementStyle_populate error: " + ex);
|
||||
return;
|
||||
}
|
||||
var domRules = this.domUtils.getCSSStyleRules(aElement);
|
||||
|
||||
// getCSStyleRules returns ordered from least-specific to
|
||||
// most-specific.
|
||||
|
@ -150,14 +171,43 @@ ElementStyle.prototype = {
|
|||
continue;
|
||||
}
|
||||
|
||||
// XXX: non-style rules.
|
||||
if (domRule.type === Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
this.rules.push(new Rule(this, { domRule: domRule }));
|
||||
if (domRule.type !== Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this._maybeAddRule({
|
||||
domRule: domRule,
|
||||
inherited: inherited
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a rule if it's one we care about. Filters out duplicates and
|
||||
* inherited styles with no inherited properties.
|
||||
*
|
||||
* @param {object} aOptions
|
||||
* Options for creating the Rule, see the Rule constructor.
|
||||
*
|
||||
* @return true if we added the rule.
|
||||
*/
|
||||
_maybeAddRule: function ElementStyle_maybeAddRule(aOptions)
|
||||
{
|
||||
// If we've already included this domRule (for example, when a
|
||||
// common selector is inherited), ignore it.
|
||||
if (aOptions.domRule &&
|
||||
this.rules.some(function(rule) rule.domRule === aOptions.domRule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mark overridden computed styles.
|
||||
this.markOverridden();
|
||||
let rule = new Rule(this, aOptions);
|
||||
|
||||
// Ignore inherited rules with no properties.
|
||||
if (aOptions.inherited && rule.textProps.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.rules.push(rule);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -178,7 +228,7 @@ ElementStyle.prototype = {
|
|||
let computedProps = [];
|
||||
for each (let textProp in textProps) {
|
||||
computedProps = computedProps.concat(textProp.computed);
|
||||
};
|
||||
}
|
||||
|
||||
// Walk over the computed properties. As we see a property name
|
||||
// for the first time, mark that property's name as taken by this
|
||||
|
@ -214,7 +264,7 @@ ElementStyle.prototype = {
|
|||
|
||||
computedProp._overriddenDirty = (!!computedProp.overridden != overridden);
|
||||
computedProp.overridden = overridden;
|
||||
if (!computedProp.overridden) {
|
||||
if (!computedProp.overridden && computedProp.textProp.enabled) {
|
||||
taken[computedProp.name] = computedProp;
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +323,8 @@ ElementStyle.prototype = {
|
|||
* the domRule's style will be used.
|
||||
* selectorText: selector text to display. If omitted, the domRule's
|
||||
* selectorText will be used.
|
||||
* inherited: An element this rule was inherited from. If omitted,
|
||||
* the rule applies directly to the current element.
|
||||
* @constructor
|
||||
*/
|
||||
function Rule(aElementStyle, aOptions)
|
||||
|
@ -281,7 +333,7 @@ function Rule(aElementStyle, aOptions)
|
|||
this.domRule = aOptions.domRule || null;
|
||||
this.style = aOptions.style || this.domRule.style;
|
||||
this.selectorText = aOptions.selectorText || this.domRule.selectorText;
|
||||
|
||||
this.inherited = aOptions.inherited || null;
|
||||
this._getTextProperties();
|
||||
}
|
||||
|
||||
|
@ -297,6 +349,17 @@ Rule.prototype = {
|
|||
let line = this.elementStyle.domUtils.getRuleLine(this.domRule);
|
||||
this._title += ":" + line;
|
||||
}
|
||||
|
||||
if (this.inherited) {
|
||||
let eltText = this.inherited.tagName.toLowerCase();
|
||||
if (this.inherited.id) {
|
||||
eltText += "#" + this.inherited.id;
|
||||
}
|
||||
let args = [eltText, this._title];
|
||||
this._title = CssLogic._strings.formatStringFromName("rule.inheritedSource",
|
||||
args, args.length);
|
||||
}
|
||||
|
||||
return this._title;
|
||||
},
|
||||
|
||||
|
@ -336,6 +399,7 @@ Rule.prototype = {
|
|||
prop.priority = this.style.getPropertyPriority(prop.name);
|
||||
prop.updateComputed();
|
||||
}
|
||||
this.elementStyle._changed();
|
||||
|
||||
this.elementStyle.markOverridden();
|
||||
},
|
||||
|
@ -416,7 +480,13 @@ Rule.prototype = {
|
|||
if(!matches || !matches[2])
|
||||
continue;
|
||||
|
||||
let prop = new TextProperty(this, matches[1], matches[2], matches[3] || "");
|
||||
let name = matches[1];
|
||||
if (this.inherited &&
|
||||
!this.elementStyle.domUtils.isInheritedProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let prop = new TextProperty(this, name, matches[2], matches[3] || "");
|
||||
this.textProps.push(prop);
|
||||
}
|
||||
},
|
||||
|
@ -478,6 +548,7 @@ TextProperty.prototype = {
|
|||
for (let i = 0, n = dummyStyle.length; i < n; i++) {
|
||||
let prop = dummyStyle.item(i);
|
||||
this.computed.push({
|
||||
textProp: this,
|
||||
name: prop,
|
||||
value: dummyStyle.getPropertyValue(prop),
|
||||
priority: dummyStyle.getPropertyPriority(prop),
|
||||
|
@ -568,7 +639,15 @@ CssRuleView.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this._elementStyle) {
|
||||
delete this._elementStyle.onChanged;
|
||||
}
|
||||
|
||||
this._elementStyle = new ElementStyle(aElement);
|
||||
this._elementStyle.onChanged = function() {
|
||||
this._changed();
|
||||
}.bind(this);
|
||||
|
||||
this._createEditors();
|
||||
},
|
||||
|
||||
|
@ -584,6 +663,17 @@ CssRuleView.prototype = {
|
|||
this._elementStyle = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user has made changes to the ElementStyle.
|
||||
* Emits an event that clients can listen to.
|
||||
*/
|
||||
_changed: function CssRuleView_changed()
|
||||
{
|
||||
var evt = this.doc.createEvent("Events");
|
||||
evt.initEvent("CssRuleViewChanged", true, false);
|
||||
this.element.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates editor UI for each of the rules in _elementStyle.
|
||||
*/
|
||||
|
@ -944,10 +1034,12 @@ TextPropertyEditor.prototype = {
|
|||
*/
|
||||
_parseValue: function TextPropertyEditor_parseValue(aValue)
|
||||
{
|
||||
let [value, priority] = aValue.split("!", 2);
|
||||
let pieces = aValue.split("!", 2);
|
||||
let value = pieces[0];
|
||||
let priority = pieces.length > 1 ? pieces[1] : "";
|
||||
return {
|
||||
value: value.trim(),
|
||||
priority: (priority ? priority.trim() : "")
|
||||
value: pieces[0].trim(),
|
||||
priority: (pieces.length > 1 ? pieces[1].trim() : "")
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ StyleInspector.prototype = {
|
|||
context: this,
|
||||
get isOpen() isOpen(),
|
||||
onSelect: this.selectNode,
|
||||
onChanged: this.updateNode,
|
||||
show: this.open,
|
||||
hide: this.close,
|
||||
dim: this.dimTool,
|
||||
|
@ -112,7 +113,7 @@ StyleInspector.prototype = {
|
|||
let boundIframeOnLoad = function loadedInitializeIframe() {
|
||||
if (this.iframe &&
|
||||
this.iframe.getAttribute("src") ==
|
||||
"chrome://browser/content/csshtmltree.xhtml") {
|
||||
"chrome://browser/content/devtools/csshtmltree.xul") {
|
||||
let selectedNode = this.selectedNode || null;
|
||||
this.cssHtmlTree = new CssHtmlTree(this);
|
||||
this.cssLogic.highlight(selectedNode);
|
||||
|
@ -152,10 +153,6 @@ StyleInspector.prototype = {
|
|||
panel.setAttribute("width", 350);
|
||||
panel.setAttribute("height", this.window.screen.height / 2);
|
||||
|
||||
let vbox = this.document.createElement("vbox");
|
||||
vbox.setAttribute("flex", "1");
|
||||
panel.appendChild(vbox);
|
||||
|
||||
let iframe = this.document.createElement("iframe");
|
||||
let boundIframeOnLoad = function loadedInitializeIframe()
|
||||
{
|
||||
|
@ -165,24 +162,12 @@ StyleInspector.prototype = {
|
|||
aCallback(this);
|
||||
}.bind(this);
|
||||
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.flex = 1;
|
||||
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
||||
iframe.addEventListener("load", boundIframeOnLoad, true);
|
||||
iframe.setAttribute("src", "chrome://browser/content/csshtmltree.xhtml");
|
||||
iframe.setAttribute("src", "chrome://browser/content/devtools/csshtmltree.xul");
|
||||
|
||||
vbox.appendChild(iframe);
|
||||
|
||||
let hbox = this.document.createElement("hbox");
|
||||
hbox.setAttribute("class", "resizerbox");
|
||||
vbox.appendChild(hbox);
|
||||
|
||||
let spacer = this.document.createElement("spacer");
|
||||
spacer.setAttribute("flex", "1");
|
||||
hbox.appendChild(spacer);
|
||||
|
||||
let resizer = this.document.createElement("resizer");
|
||||
resizer.setAttribute("dir", "bottomend");
|
||||
hbox.appendChild(resizer);
|
||||
panel.appendChild(iframe);
|
||||
popupSet.appendChild(panel);
|
||||
|
||||
this._boundPopupShown = this.popupShown.bind(this);
|
||||
|
@ -263,6 +248,17 @@ StyleInspector.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the display for the currently-selected node.
|
||||
*/
|
||||
updateNode: function SI_updateNode()
|
||||
{
|
||||
if (this.isOpen() && !this.dimmed) {
|
||||
this.cssLogic.highlight(this.selectedNode);
|
||||
this.cssHtmlTree.refreshPanel();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dim or undim a panel by setting or removing a dimmed attribute.
|
||||
* @param aState
|
||||
|
@ -282,7 +278,7 @@ StyleInspector.prototype = {
|
|||
this.selectNode(aSelection);
|
||||
if (this.openDocked) {
|
||||
if (!this.iframeReady) {
|
||||
this.iframe.setAttribute("src", "chrome://browser/content/csshtmltree.xhtml");
|
||||
this.iframe.setAttribute("src", "chrome://browser/content/devtools/csshtmltree.xul");
|
||||
}
|
||||
} else {
|
||||
this.panel.openPopup(this.window.gBrowser.selectedBrowser, "end_before", 0, 0,
|
||||
|
|
|
@ -1,20 +1,4 @@
|
|||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/devtools/styleinspector.dtd">
|
||||
%inspectorDTD;
|
||||
<!ELEMENT loop ANY>
|
||||
<!ATTLIST li foreach CDATA #IMPLIED>
|
||||
<!ATTLIST div foreach CDATA #IMPLIED>
|
||||
<!ATTLIST loop foreach CDATA #IMPLIED>
|
||||
<!ATTLIST a target CDATA #IMPLIED>
|
||||
<!ATTLIST a __pathElement CDATA #IMPLIED>
|
||||
<!ATTLIST div _id CDATA #IMPLIED>
|
||||
<!ATTLIST div save CDATA #IMPLIED>
|
||||
<!ATTLIST table save CDATA #IMPLIED>
|
||||
<!ATTLIST loop if CDATA #IMPLIED>
|
||||
<!ATTLIST tr if CDATA #IMPLIED>
|
||||
]>
|
||||
<?xml version="1.0"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
|
@ -35,9 +19,10 @@
|
|||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Joe Walker (jwalker@mozilla.com) (original author)
|
||||
- Joe Walker <jwalker@mozilla.com> (original author)
|
||||
- Mihai Șucan <mihai.sucan@gmail.com>
|
||||
- Michael Ratcliffe <mratcliffe@mozilla.com>
|
||||
- Dão Gottwald <dao@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -52,28 +37,52 @@
|
|||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="application/xhtml+xml; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://browser/skin/devtools/csshtmltree.css" />
|
||||
</head>
|
||||
<body role="application">
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/csshtmltree.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/devtools/styleinspector.dtd">
|
||||
%inspectorDTD;
|
||||
<!ELEMENT loop ANY>
|
||||
<!ATTLIST li foreach CDATA #IMPLIED>
|
||||
<!ATTLIST div foreach CDATA #IMPLIED>
|
||||
<!ATTLIST loop foreach CDATA #IMPLIED>
|
||||
<!ATTLIST a target CDATA #IMPLIED>
|
||||
<!ATTLIST a __pathElement CDATA #IMPLIED>
|
||||
<!ATTLIST div _id CDATA #IMPLIED>
|
||||
<!ATTLIST div save CDATA #IMPLIED>
|
||||
<!ATTLIST table save CDATA #IMPLIED>
|
||||
<!ATTLIST loop if CDATA #IMPLIED>
|
||||
<!ATTLIST tr if CDATA #IMPLIED>
|
||||
]>
|
||||
|
||||
<xul:window xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<!-- The output from #templateRoot (below) is inserted here. -->
|
||||
<div id="root">
|
||||
</div>
|
||||
<div id="root"></div>
|
||||
|
||||
<!-- The output from #templatePath (below) is inserted here. -->
|
||||
<div id="path">
|
||||
</div>
|
||||
|
||||
<!-- When no properties are found the following block is displayed. -->
|
||||
<div id="noResults" hidden="">
|
||||
&noPropertiesFound;
|
||||
</div>
|
||||
|
||||
<!-- The output from #templateProperty (below) is appended here. -->
|
||||
<div id="propertyContainer">
|
||||
</div>
|
||||
|
||||
<xul:hbox id="footer">
|
||||
<xul:label class="legendKey bestmatch">&bestMatch;</xul:label>
|
||||
<xul:label class="legendKey matched">&matched;</xul:label>
|
||||
<xul:label class="legendKey parentmatch">&parentMatch;</xul:label>
|
||||
<xul:spacer flex="1"/>
|
||||
<xul:resizer dir="bottomright"/>
|
||||
</xul:hbox>
|
||||
<!--
|
||||
To visually debug the templates without running firefox, alter the display:none
|
||||
-->
|
||||
|
@ -83,15 +92,16 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
styles" checkbox. For data it needs an instance of CssHtmlTree.
|
||||
-->
|
||||
<div id="templateRoot">
|
||||
<div class="filters">
|
||||
<label class="userStylesLabel" dir="${getRTLAttr}">
|
||||
<xul:hbox class="headerControls" flex="1">
|
||||
<label class="userStylesLabel">
|
||||
<input class="onlyuserstyles" save="${onlyUserStylesCheckbox}"
|
||||
type="checkbox" onchange="${onlyUserStylesChanged}" checked=""/>
|
||||
&userStylesLabel;
|
||||
<input class="userStyles" save="${onlyUserStylesCheckbox}" type="checkbox"
|
||||
onchange="${onlyUserStylesChanged}" checked=""/>
|
||||
</label>
|
||||
<input save="${searchField}" class="searchfield" type="text"
|
||||
oninput="${filterChanged}"/>
|
||||
</div>
|
||||
<xul:textbox class="searchfield" type="search" save="${searchField}"
|
||||
placeholder="&userStylesSearch;"
|
||||
oncommand="${filterChanged}"/>
|
||||
</xul:hbox>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
|
@ -99,16 +109,17 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
at. For data it needs an instance of CssHtmlTree.
|
||||
-->
|
||||
<div id="templatePath">
|
||||
<p class="path">
|
||||
<label dir="${getRTLAttr}">&lookingAtLabel;</label>
|
||||
<ol>
|
||||
<li foreach="item in ${pathElements}" dir="${getRTLAttr}">
|
||||
<a href="#" onclick="${pathClick}" __pathElement="${item.element}">
|
||||
${__element.pathElement = item.element; item.display}
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</p>
|
||||
<span class="selectedElementLabel">
|
||||
&selectedElementLabel;
|
||||
</span>
|
||||
<!-- following broken in RTL mode, see bug 699900 -->
|
||||
<ol>
|
||||
<li foreach="item in ${pathElements}">
|
||||
<a href="#" onclick="${pathClick}" __pathElement="${item.element}">
|
||||
${__element.pathElement = item.element; item.display}
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
|
@ -118,29 +129,20 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
}
|
||||
-->
|
||||
<div id="templateProperty">
|
||||
<div class="${className}" save="${element}" dir="${getRTLAttr}">
|
||||
<div class="property-header">
|
||||
<div class="property-name" dir="${getRTLAttr}">
|
||||
<a class="link" target="_blank" title="&helpLinkTitle;"
|
||||
href="${link}">${name}</a>
|
||||
<div class="${className}" save="${element}">
|
||||
<xul:hbox class="property-header" save="${propertyHeader}"
|
||||
onclick="${propertyHeaderClick}">
|
||||
<div save="${matchedExpander}" class="match expander"/>
|
||||
<div class="property-name">${name}</div>
|
||||
<div class="helplink-container">
|
||||
<a href="${link}" class="helplink" title="&helpLinkTitle;" onclick="${mdnLinkClick}">
|
||||
&helpLinkTitle;
|
||||
</a>
|
||||
</div>
|
||||
<div save="${valueNode}" class="property-value" dir="ltr">${value}</div>
|
||||
</div>
|
||||
</xul:hbox>
|
||||
|
||||
<div save="${matchedSelectorsContainer}" class="rulelink" dir="${getRTLAttr}">
|
||||
<div onclick="${matchedSelectorsClick}" class="rule-matched">
|
||||
<div save="${matchedExpander}" class="expander"></div>
|
||||
<div save="${matchedSelectorsTitleNode}">&matchedSelectors;</div>
|
||||
</div>
|
||||
<table save="${matchedSelectorTable}" dir="${getRTLAttr}"></table>
|
||||
</div>
|
||||
|
||||
<div save="${unmatchedSelectorsContainer}" class="rulelink" dir="${getRTLAttr}">
|
||||
<div onclick="${unmatchedSelectorsClick}" class="rule-unmatched">
|
||||
<div save="${unmatchedExpander}" class="expander"></div>
|
||||
<div save="${unmatchedSelectorsTitleNode}">&unmatchedSelectors;</div>
|
||||
</div>
|
||||
<table save="${unmatchedSelectorTable}" dir="${getRTLAttr}"></table>
|
||||
<div save="${matchedSelectorsContainer}" class="rulelink">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -163,32 +165,7 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
</td>
|
||||
<td class="rule-link">
|
||||
<a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link"
|
||||
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</loop>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
A templateUnmatchedSelectors sits inside each templateProperties showing the
|
||||
list of selectors that fail to affect that property. Each needs data like this:
|
||||
{
|
||||
unmatchedSelectorViews: ..., // from cssHtmlTree.propertyViews[name].unmatchedSelectorViews
|
||||
}
|
||||
This is a template so the parent does not need to be a table, except that
|
||||
using a div as the parent causes the DOM to muck with the tr elements
|
||||
-->
|
||||
<div id="templateUnmatchedSelectors">
|
||||
<table>
|
||||
<loop foreach="selector in ${unmatchedSelectorViews}">
|
||||
<tr>
|
||||
<td dir="ltr" class="rule-text unmatched">
|
||||
${selector.humanReadableText(__element)}
|
||||
</td>
|
||||
<td class="rule-link">
|
||||
<a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link"
|
||||
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
|
||||
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</loop>
|
||||
|
@ -196,5 +173,4 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</xul:window>
|
|
@ -1,9 +1,4 @@
|
|||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/styleinspector.dtd">
|
||||
%inspectorDTD;
|
||||
]>
|
||||
<?xml version="1.0"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
|
@ -39,15 +34,11 @@
|
|||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="application/xhtml+xml; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://browser/content/devtools/styleinspector.css" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://browser/skin/devtools/csshtmltree.css" />
|
||||
</head>
|
||||
<body role="application" id="ruleview-body"></body>
|
||||
</html>
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/devtools/styleinspector.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/csshtmltree.css" type="text/css"?>
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % inspectorDTD SYSTEM "chrome://browser/locale/devtools/styleinspector.dtd">
|
||||
%inspectorDTD;
|
||||
]>
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
|
|
@ -51,8 +51,10 @@ _BROWSER_TEST_FILES = \
|
|||
browser_bug683672.js \
|
||||
browser_styleinspector_bug_672746_default_styles.js \
|
||||
browser_styleinspector_bug_672744_search_filter.js \
|
||||
browser_styleinspector_bug_689759_no_results_placeholder.js \
|
||||
browser_bug_692400_element_style.js \
|
||||
browser_ruleview_editor.js \
|
||||
browser_ruleview_inherit.js \
|
||||
browser_ruleview_manipulation.js \
|
||||
browser_ruleview_override.js \
|
||||
browser_ruleview_ui.js \
|
||||
|
|
|
@ -38,7 +38,7 @@ function runTests()
|
|||
ok(stylePanel.isOpen(), "style inspector is open");
|
||||
|
||||
testMatchedSelectors();
|
||||
testUnmatchedSelectors();
|
||||
//testUnmatchedSelectors();
|
||||
|
||||
info("finishing up");
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
|
@ -65,7 +65,7 @@ function testMatchedSelectors()
|
|||
is(numMatchedSelectors, 6,
|
||||
"CssLogic returns the correct number of matched selectors for div");
|
||||
|
||||
is(propertyView.propertyInfo.hasMatchedSelectors(), true,
|
||||
is(propertyView.hasMatchedSelectors, true,
|
||||
"hasMatchedSelectors returns true");
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ function testUnmatchedSelectors()
|
|||
is(numUnmatchedSelectors, 13,
|
||||
"CssLogic returns the correct number of unmatched selectors for body");
|
||||
|
||||
is(propertyView.propertyInfo.hasUnmatchedSelectors(), true,
|
||||
is(propertyView.hasUnmatchedSelectors, true,
|
||||
"hasUnmatchedSelectors returns true");
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ function SI_checkText()
|
|||
propertyView.matchedExpanded = true;
|
||||
propertyView.refreshMatchedSelectors();
|
||||
|
||||
let td = propertyView.matchedSelectorTable.querySelector("td.rule-text");
|
||||
let td = propertyView.matchedSelectorsContainer.querySelector("td.rule-text");
|
||||
ok(td, "found the first table row");
|
||||
|
||||
let selector = propertyView.matchedSelectorViews[0];
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
|
||||
|
||||
let doc;
|
||||
|
||||
function simpleInherit()
|
||||
{
|
||||
let style = '' +
|
||||
'#test2 {' +
|
||||
' background-color: green;' +
|
||||
' color: purple;' +
|
||||
'}';
|
||||
|
||||
let styleNode = addStyle(doc, style);
|
||||
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
let inheritRule = elementStyle.rules[1];
|
||||
is(inheritRule.selectorText, "#test2", "Inherited rule should be the one that includes inheritable properties.");
|
||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||
let inheritProp = inheritRule.textProps[0];
|
||||
is(inheritProp.name, "color", "color should have been inherited.");
|
||||
|
||||
styleNode.parentNode.removeChild(styleNode);
|
||||
|
||||
emptyInherit();
|
||||
}
|
||||
|
||||
function emptyInherit()
|
||||
{
|
||||
// No inheritable styles, this rule shouldn't show up.
|
||||
let style = '' +
|
||||
'#test2 {' +
|
||||
' background-color: green;' +
|
||||
'}';
|
||||
|
||||
let styleNode = addStyle(doc, style);
|
||||
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 1, "Should have 1 rule.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
styleNode.parentNode.removeChild(styleNode);
|
||||
|
||||
elementStyleInherit();
|
||||
}
|
||||
|
||||
function elementStyleInherit()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
let inheritRule = elementStyle.rules[1];
|
||||
ok(!inheritRule.domRule, "Inherited rule should be an element style, not a rule.");
|
||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||
let inheritProp = inheritRule.textProps[0];
|
||||
is(inheritProp.name, "color", "color should have been inherited.");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
doc = 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(simpleInherit, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic style inspector tests";
|
||||
}
|
|
@ -110,6 +110,33 @@ function importantOverride()
|
|||
ok(classProp.overridden, "New important prop should override class property.");
|
||||
ok(!elementProp.overridden, "New important prop should not be overriden.");
|
||||
|
||||
disableOverride();
|
||||
}
|
||||
|
||||
function disableOverride()
|
||||
{
|
||||
let style = '' +
|
||||
'#testid {' +
|
||||
' background-color: blue;' +
|
||||
'}' +
|
||||
'.testclass {' +
|
||||
' background-color: green;' +
|
||||
'}';
|
||||
let styleNode = addStyle(doc, style);
|
||||
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("testid"));
|
||||
|
||||
let idRule = elementStyle.rules[1];
|
||||
let idProp = idRule.textProps[0];
|
||||
idProp.setEnabled(false);
|
||||
|
||||
let classRule = elementStyle.rules[2];
|
||||
let classProp = classRule.textProps[0];
|
||||
ok(!classProp.overridden, "Class prop should not be overridden after id prop was disabled.");
|
||||
|
||||
styleNode.parentNode.removeChild(styleNode);
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,18 @@ function waitForEditorBlur(aEditor, aCallback)
|
|||
}, false);
|
||||
}
|
||||
|
||||
var gRuleViewChanged = false;
|
||||
function ruleViewChanged()
|
||||
{
|
||||
gRuleViewChanged = true;
|
||||
}
|
||||
|
||||
function expectChange()
|
||||
{
|
||||
ok(gRuleViewChanged, "Rule view should have fired a change event.");
|
||||
gRuleViewChanged = false;
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
let style = '' +
|
||||
|
@ -46,15 +58,15 @@ function startTest()
|
|||
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||
let testElement = doc.getElementById("testid");
|
||||
|
||||
ruleDialog = openDialog("chrome://browser/content/devtools/cssruleview.xhtml",
|
||||
ruleDialog = openDialog("chrome://browser/content/devtools/cssruleview.xul",
|
||||
"cssruleviewtest",
|
||||
"width=200,height=350");
|
||||
ruleDialog.addEventListener("load", function onLoad(evt) {
|
||||
ruleDialog.removeEventListener("load", onLoad);
|
||||
let doc = ruleDialog.document;
|
||||
let body = doc.getElementById("ruleview-body");
|
||||
ruleView = new CssRuleView(doc);
|
||||
body.appendChild(ruleView.element);
|
||||
doc.documentElement.appendChild(ruleView.element);
|
||||
ruleView.element.addEventListener("CssRuleViewChanged", ruleViewChanged, false);
|
||||
ruleView.highlight(testElement);
|
||||
waitForFocus(testCancelNew, ruleDialog);
|
||||
}, true);
|
||||
|
@ -70,6 +82,7 @@ function testCancelNew()
|
|||
is(elementRuleEditor.newPropSpan.inplaceEditor, aEditor, "Next focused editor should be the new property editor.");
|
||||
let input = aEditor.input;
|
||||
waitForEditorBlur(aEditor, function () {
|
||||
ok(!gRuleViewChanged, "Shouldn't get a change event after a cancel.");
|
||||
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
||||
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
||||
testCreateNew();
|
||||
|
@ -92,6 +105,7 @@ function testCreateNew()
|
|||
input.value = "background-color";
|
||||
|
||||
waitForEditorFocus(elementRuleEditor.element, function onNewValue(aEditor) {
|
||||
expectChange();
|
||||
is(elementRuleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
||||
is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
||||
let textProp = elementRuleEditor.rule.textProps[0];
|
||||
|
@ -99,6 +113,7 @@ function testCreateNew()
|
|||
|
||||
aEditor.input.value = "purple";
|
||||
waitForEditorBlur(aEditor, function() {
|
||||
expectChange();
|
||||
is(textProp.value, "purple", "Text prop should have been changed.");
|
||||
testEditProperty();
|
||||
});
|
||||
|
@ -121,10 +136,12 @@ function testEditProperty()
|
|||
is(propEditor.nameSpan.inplaceEditor, aEditor, "Next focused editor should be the name editor.");
|
||||
let input = aEditor.input;
|
||||
waitForEditorFocus(propEditor.element, function onNewName(aEditor) {
|
||||
expectChange();
|
||||
input = aEditor.input;
|
||||
is(propEditor.valueSpan.inplaceEditor, aEditor, "Focus should have moved to the value.");
|
||||
|
||||
waitForEditorBlur(aEditor, function() {
|
||||
expectChange();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "red",
|
||||
"border-color should have been set.");
|
||||
testDisableProperty();
|
||||
|
@ -151,14 +168,20 @@ function testDisableProperty()
|
|||
|
||||
propEditor.enable.click();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "", "Border-color should have been unset.");
|
||||
expectChange();
|
||||
|
||||
propEditor.enable.click();
|
||||
is(idRuleEditor.rule.style.getPropertyValue("border-color"), "red",
|
||||
"Border-color should have been reset.");
|
||||
expectChange();
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
ruleView.element.removeEventListener("CssRuleViewChanged", ruleViewChanged, false);
|
||||
ruleView.clear();
|
||||
ruleDialog.close();
|
||||
ruleDialog = ruleView = null;
|
||||
doc = null;
|
||||
|
|
|
@ -64,7 +64,7 @@ function SI_CheckProperty()
|
|||
let cssLogic = stylePanel.cssLogic;
|
||||
let propertyInfo = cssLogic.getPropertyInfo("color");
|
||||
ok(propertyInfo.matchedRuleCount > 0, "color property has matching rules");
|
||||
ok(propertyInfo.unmatchedRuleCount > 0, "color property has unmatched rules");
|
||||
//ok(propertyInfo.unmatchedRuleCount > 0, "color property has unmatched rules");
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
|
|
|
@ -52,8 +52,9 @@ function SI_toggleDefaultStyles()
|
|||
Services.obs.removeObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false);
|
||||
|
||||
info("clearing \"only user styles\" checkbox");
|
||||
|
||||
let iframe = stylePanel.iframe;
|
||||
let checkbox = iframe.contentDocument.querySelector(".userStyles");
|
||||
let checkbox = iframe.contentDocument.querySelector(".onlyuserstyles");
|
||||
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false);
|
||||
EventUtils.synthesizeMouse(checkbox, 5, 5, {}, iframe.contentWindow);
|
||||
}
|
||||
|
@ -64,7 +65,6 @@ function SI_AddFilterText()
|
|||
|
||||
let iframe = stylePanel.iframe;
|
||||
let searchbar = iframe.contentDocument.querySelector(".searchfield");
|
||||
|
||||
Services.obs.addObserver(SI_checkFilter, "StyleInspector-populated", false);
|
||||
info("setting filter text to \"color\"");
|
||||
searchbar.focus();
|
||||
|
|
|
@ -62,7 +62,7 @@ function SI_toggleDefaultStyles()
|
|||
{
|
||||
// Click on the checkbox.
|
||||
let iframe = stylePanel.iframe;
|
||||
let checkbox = iframe.contentDocument.querySelector(".userStyles");
|
||||
let checkbox = iframe.contentDocument.querySelector(".onlyuserstyles");
|
||||
Services.obs.addObserver(SI_checkDefaultStyles, "StyleInspector-populated", false);
|
||||
EventUtils.synthesizeMouse(checkbox, 5, 5, {}, iframe.contentWindow);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ function propertyVisible(aName)
|
|||
let propertyViews = stylePanel.cssHtmlTree.propertyViews;
|
||||
for each (let propView in propertyViews) {
|
||||
if (propView.name == aName) {
|
||||
return propView.className == "property-view";
|
||||
return propView.visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/* 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/ */
|
||||
|
||||
// Tests that the no results placeholder works properly.
|
||||
|
||||
let doc;
|
||||
let stylePanel;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||
'.matches {color: #F00;}</style>' +
|
||||
'<span id="matches" class="matches">Some styled text</span>';
|
||||
doc.title = "Tests that the no results placeholder works properly";
|
||||
ok(window.StyleInspector, "StyleInspector exists");
|
||||
stylePanel = new StyleInspector(window);
|
||||
Services.obs.addObserver(runStyleInspectorTests, "StyleInspector-opened", false);
|
||||
stylePanel.createPanel(false, function() {
|
||||
stylePanel.open(doc.body);
|
||||
});
|
||||
}
|
||||
|
||||
function runStyleInspectorTests()
|
||||
{
|
||||
Services.obs.removeObserver(runStyleInspectorTests, "StyleInspector-opened", false);
|
||||
|
||||
ok(stylePanel.isOpen(), "style inspector is open");
|
||||
|
||||
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false);
|
||||
|
||||
let span = doc.querySelector("#matches");
|
||||
ok(span, "captain, we have the matches span");
|
||||
|
||||
let htmlTree = stylePanel.cssHtmlTree;
|
||||
stylePanel.selectNode(span);
|
||||
|
||||
is(span, htmlTree.viewedElement,
|
||||
"style inspector node matches the selected node");
|
||||
is(htmlTree.viewedElement, stylePanel.cssLogic.viewedElement,
|
||||
"cssLogic node matches the cssHtmlTree node");
|
||||
}
|
||||
|
||||
function SI_AddFilterText()
|
||||
{
|
||||
Services.obs.removeObserver(SI_AddFilterText, "StyleInspector-populated", false);
|
||||
|
||||
let iframe = stylePanel.iframe;
|
||||
let searchbar = stylePanel.cssHtmlTree.searchField;
|
||||
let searchTerm = "xxxxx";
|
||||
|
||||
Services.obs.addObserver(SI_checkPlaceholderVisible, "StyleInspector-populated", false);
|
||||
info("setting filter text to \"" + searchTerm + "\"");
|
||||
searchbar.focus();
|
||||
for each (let c in searchTerm) {
|
||||
EventUtils.synthesizeKey(c, {}, iframe.contentWindow);
|
||||
}
|
||||
}
|
||||
|
||||
function SI_checkPlaceholderVisible()
|
||||
{
|
||||
Services.obs.removeObserver(SI_checkPlaceholderVisible, "StyleInspector-populated", false);
|
||||
info("SI_checkPlaceholderVisible called");
|
||||
let placeholder = stylePanel.cssHtmlTree.noResults;
|
||||
let iframe = stylePanel.iframe;
|
||||
let display = iframe.contentWindow.getComputedStyle(placeholder).display;
|
||||
|
||||
is(display, "block", "placeholder is visible");
|
||||
|
||||
SI_ClearFilterText();
|
||||
}
|
||||
|
||||
function SI_ClearFilterText()
|
||||
{
|
||||
let iframe = stylePanel.iframe;
|
||||
let searchbar = stylePanel.cssHtmlTree.searchField;
|
||||
|
||||
Services.obs.addObserver(SI_checkPlaceholderHidden, "StyleInspector-populated", false);
|
||||
info("clearing filter text");
|
||||
searchbar.focus();
|
||||
searchbar.value = "";
|
||||
EventUtils.synthesizeKey("c", {}, iframe.contentWindow);
|
||||
}
|
||||
|
||||
function SI_checkPlaceholderHidden()
|
||||
{
|
||||
Services.obs.removeObserver(SI_checkPlaceholderHidden, "StyleInspector-populated", false);
|
||||
let placeholder = stylePanel.cssHtmlTree.noResults;
|
||||
let iframe = stylePanel.iframe;
|
||||
let display = iframe.contentWindow.getComputedStyle(placeholder).display;
|
||||
|
||||
is(display, "none", "placeholder is hidden");
|
||||
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
stylePanel.close();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
|
||||
ok(!stylePanel.isOpen(), "style inspector is closed");
|
||||
doc = stylePanel = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,no results placeholder test";
|
||||
}
|
|
@ -198,7 +198,9 @@ const LEVELS = {
|
|||
dir: SEVERITY_LOG,
|
||||
group: SEVERITY_LOG,
|
||||
groupCollapsed: SEVERITY_LOG,
|
||||
groupEnd: SEVERITY_LOG
|
||||
groupEnd: SEVERITY_LOG,
|
||||
time: SEVERITY_LOG,
|
||||
timeEnd: SEVERITY_LOG
|
||||
};
|
||||
|
||||
// The lowest HTTP response code (inclusive) that is considered an error.
|
||||
|
@ -2094,6 +2096,30 @@ HUD_SERVICE.prototype =
|
|||
}
|
||||
return;
|
||||
|
||||
case "time":
|
||||
if (!args) {
|
||||
return;
|
||||
}
|
||||
if (args.error) {
|
||||
Cu.reportError(this.getStr(args.error));
|
||||
return;
|
||||
}
|
||||
body = this.getFormatStr("timerStarted", [args.name]);
|
||||
clipboardText = body;
|
||||
sourceURL = aMessage.filename;
|
||||
sourceLine = aMessage.lineNumber;
|
||||
break;
|
||||
|
||||
case "timeEnd":
|
||||
if (!args) {
|
||||
return;
|
||||
}
|
||||
body = this.getFormatStr("timeEnd", [args.name, args.duration]);
|
||||
clipboardText = body;
|
||||
sourceURL = aMessage.filename;
|
||||
sourceLine = aMessage.lineNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
Cu.reportError("Unknown Console API log level: " + level);
|
||||
return;
|
||||
|
@ -4622,7 +4648,7 @@ function JSTermHelper(aJSTerm)
|
|||
});
|
||||
|
||||
let iframe = createAndAppendElement(panel, "iframe", {
|
||||
src: "chrome://browser/content/devtools/cssruleview.xhtml",
|
||||
src: "chrome://browser/content/devtools/cssruleview.xul",
|
||||
flex: "1",
|
||||
});
|
||||
|
||||
|
@ -4630,8 +4656,7 @@ function JSTermHelper(aJSTerm)
|
|||
panel.removeEventListener("load", onLoad, true);
|
||||
let doc = iframe.contentDocument;
|
||||
let view = new CssRuleView(doc);
|
||||
let body = doc.getElementById("ruleview-body");
|
||||
body.appendChild(view.element);
|
||||
doc.documentElement.appendChild(view.element);
|
||||
view.highlight(aNode);
|
||||
}, true);
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_gcli_integrate.js \
|
||||
browser_gcli_require.js \
|
||||
browser_gcli_web.js \
|
||||
browser_webconsole_bug_658368_time_methods.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -220,6 +221,7 @@ _BROWSER_TEST_PAGES = \
|
|||
test-bug-678816-content.js \
|
||||
test-file-location.js \
|
||||
browser_gcli_inspect.html \
|
||||
test-bug-658368-time-methods.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that the Console API implements the time() and timeEnd() methods.
|
||||
|
||||
function test() {
|
||||
addTab("http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/browser/test-bug-658368-time-methods.html");
|
||||
openConsole();
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
}
|
||||
|
||||
function onLoad(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, onLoad, true);
|
||||
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let hud = HUDService.hudReferences[hudId];
|
||||
outputNode = hud.outputNode;
|
||||
|
||||
executeSoon(function() {
|
||||
findLogEntry("aTimer: timer started");
|
||||
findLogEntry("ms");
|
||||
|
||||
// The next test makes sure that timers with the same name but in separate
|
||||
// tabs, do not contain the same value.
|
||||
addTab("data:text/html,<script type='text/javascript'>" +
|
||||
"console.timeEnd('bTimer');</script>");
|
||||
openConsole();
|
||||
browser.addEventListener("load", testTimerIndependenceInTabs, true);
|
||||
});
|
||||
}
|
||||
|
||||
function testTimerIndependenceInTabs(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, testTimerIndependenceInTabs, true);
|
||||
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let hud = HUDService.hudReferences[hudId];
|
||||
outputNode = hud.outputNode;
|
||||
|
||||
executeSoon(function() {
|
||||
testLogEntry(outputNode, "bTimer: timer started", "bTimer was not started",
|
||||
false, true);
|
||||
|
||||
// The next test makes sure that timers with the same name but in separate
|
||||
// pages, do not contain the same value.
|
||||
browser.addEventListener("load", testTimerIndependenceInSameTab, true);
|
||||
content.location = "data:text/html,<script type='text/javascript'>" +
|
||||
"console.time('bTimer');</script>";
|
||||
});
|
||||
}
|
||||
|
||||
function testTimerIndependenceInSameTab(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, testTimerIndependenceInSameTab, true);
|
||||
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let hud = HUDService.hudReferences[hudId];
|
||||
outputNode = hud.outputNode;
|
||||
|
||||
executeSoon(function() {
|
||||
findLogEntry("bTimer: timer started");
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
// Now the following console.timeEnd() call shouldn't display anything,
|
||||
// if the timers in different pages are not related.
|
||||
browser.addEventListener("load", testTimerIndependenceInSameTabAgain, true);
|
||||
content.location = "data:text/html,<script type='text/javascript'>" +
|
||||
"console.timeEnd('bTimer');</script>";
|
||||
});
|
||||
}
|
||||
|
||||
function testTimerIndependenceInSameTabAgain(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, testTimerIndependenceInSameTabAgain, true);
|
||||
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let hud = HUDService.hudReferences[hudId];
|
||||
outputNode = hud.outputNode;
|
||||
|
||||
executeSoon(function() {
|
||||
testLogEntry(outputNode, "bTimer: timer started", "bTimer was not started",
|
||||
false, true);
|
||||
|
||||
finishTest();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<title>Test for bug 658368: Expand console object with time and timeEnd
|
||||
methods</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test for bug 658368: Expand console object with time and timeEnd
|
||||
methods</h1>
|
||||
|
||||
<script type="text/javascript">
|
||||
function foo() {
|
||||
console.timeEnd("aTimer");
|
||||
}
|
||||
console.time("aTimer");
|
||||
foo();
|
||||
console.time("bTimer");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -4,8 +4,6 @@
|
|||
<script type="text/javascript">
|
||||
function test() {
|
||||
console.log("start");
|
||||
console.time();
|
||||
console.timeEnd()
|
||||
console.exception()
|
||||
console.assert()
|
||||
console.clear()
|
||||
|
|
|
@ -278,8 +278,6 @@
|
|||
@BINPATH@/components/toolkitsearch.manifest
|
||||
@BINPATH@/components/nsSearchService.js
|
||||
@BINPATH@/components/nsSearchSuggestions.js
|
||||
@BINPATH@/components/nsTryToClose.manifest
|
||||
@BINPATH@/components/nsTryToClose.js
|
||||
@BINPATH@/components/passwordmgr.manifest
|
||||
@BINPATH@/components/nsLoginInfo.js
|
||||
@BINPATH@/components/nsLoginManager.js
|
||||
|
@ -481,9 +479,7 @@
|
|||
; svg
|
||||
@BINPATH@/res/svg.css
|
||||
@BINPATH@/components/dom_svg.xpt
|
||||
#ifdef MOZ_SMIL
|
||||
@BINPATH@/components/dom_smil.xpt
|
||||
#endif
|
||||
|
||||
; [Personal Security Manager]
|
||||
;
|
||||
|
|
|
@ -23,3 +23,8 @@ htmlPanel.tooltiptext=HTML panel
|
|||
# toolbar button.
|
||||
htmlPanel.accesskey=H
|
||||
|
||||
# LOCALIZATION NOTE (ruleView.*): Button label, accesskey and tooltip text
|
||||
# associated with the Highlighter's CSS Rule View in the Style Sidebar.
|
||||
ruleView.label=Rules
|
||||
ruleView.accesskey=R
|
||||
ruleView.tooltiptext=View and Edit CSS
|
|
@ -3,10 +3,14 @@
|
|||
- should be displayed or not. -->
|
||||
<!ENTITY userStylesLabel "Only user styles">
|
||||
|
||||
<!-- LOCALIZATION NOTE (lookingAtLabel): This is the label for the path of
|
||||
<!-- LOCALIZATION NOTE (userStylesSearch): This is the placeholder that goes in
|
||||
- the search box when no search term has been entered. -->
|
||||
<!ENTITY userStylesSearch "Search">
|
||||
|
||||
<!-- LOCALIZATION NOTE (selectedElementLabel): This is the label for the path of
|
||||
- the highlighted element in the web page. This path is based on the document
|
||||
- tree. -->
|
||||
<!ENTITY lookingAtLabel "Looking at:">
|
||||
<!ENTITY selectedElementLabel "Selected element:">
|
||||
|
||||
<!-- LOCALIZATION NOTE (helpLinkTitle): For each style property
|
||||
- the user can hover it and get a help link button which allows one to
|
||||
|
@ -14,12 +18,22 @@
|
|||
- This is the link title shown in the hover tooltip. -->
|
||||
<!ENTITY helpLinkTitle "Read the documentation for this property">
|
||||
|
||||
<!-- LOCALIZATION NOTE (matchedSelectors): For each style property the
|
||||
- panel shows whether there are any selectors that match the currently
|
||||
- selected element. -->
|
||||
<!ENTITY matchedSelectors "Matched selectors">
|
||||
<!-- LOCALIZATION NOTE (noPropertiesFound): In the case where there are no CSS
|
||||
- properties to display e.g. due to search criteria this message is
|
||||
- displayed. -->
|
||||
<!ENTITY noPropertiesFound "No CSS properties found.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (unmatchedSelectors): For each style property
|
||||
- the panel shows whether there are any selectors that do not match the
|
||||
- currently selected element. -->
|
||||
<!ENTITY unmatchedSelectors "Unmatched selectors">
|
||||
|
||||
<!-- LOCALIZATION NOTE (bestMatch, matched, parentMatch & unmatched): For each
|
||||
- style property the panel shows the rules which hold that specific property.
|
||||
- For every rule, the rule status is also displayed: a rule can be the best
|
||||
- match, a match, a parent match, or a rule did not match the element the
|
||||
- user has highlighted. -->
|
||||
<!ENTITY bestMatch "Best Match">
|
||||
<!ENTITY matched "Matched">
|
||||
<!ENTITY parentMatch "Parent Match">
|
||||
<!ENTITY unmatched "Unmatched">
|
||||
|
|
|
@ -19,6 +19,12 @@ rule.status.UNMATCHED=Unmatched
|
|||
rule.sourceInline=inline
|
||||
rule.sourceElement=element
|
||||
|
||||
# LOCALIZATION NOTE (rule.inheritedSource): Shown for CSS rules
|
||||
# that were inherited from a parent node. Will be passed a node
|
||||
# identifier and a source location.
|
||||
# e.g "Inherited from body#bodyID (styles.css:20)"
|
||||
rule.inheritedSource=Inherited from %S (%S)
|
||||
|
||||
# LOCALIZATION NOTE (group): Style properties are displayed in categories and
|
||||
# these are the category names.
|
||||
group.Text_Fonts_and_Color=Text, Fonts & Color
|
||||
|
@ -34,3 +40,4 @@ group.Effects_and_Other=Effects and Other
|
|||
style.highlighter.button.label1=Properties
|
||||
style.highlighter.accesskey1=P
|
||||
style.highlighter.button.tooltip=Inspect element styles
|
||||
|
||||
|
|
|
@ -172,3 +172,15 @@ stacktrace.anonymousFunction=<anonymous>
|
|||
# to console.trace(). The stack trace of JavaScript function calls is displayed.
|
||||
# In this minimal message we only show the last call.
|
||||
stacktrace.outputMessage=Stack trace from %S, function %S, line %S.
|
||||
|
||||
# LOCALIZATION NOTE (timerStarted):
|
||||
# This string is used to display the result of the console.time() call.
|
||||
# %S=name of timer
|
||||
timerStarted=%S: timer started
|
||||
|
||||
# LOCALIZATION NOTE (timeEnd):
|
||||
# This string is used to display the result of the console.timeEnd() call.
|
||||
# %1$S=name of timer, %2$S=number of milliseconds
|
||||
timeEnd=%1$S: %2$Sms
|
||||
|
||||
maxTimersExceeded=The maximum allowed number of timers in this page was exceeded.
|
||||
|
|
|
@ -1904,6 +1904,16 @@ panel[dimmed="true"] {
|
|||
|
||||
#status-bar {
|
||||
min-height: 0;
|
||||
-moz-appearance: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#addon-bar[customizing] > #status-bar {
|
||||
opacity: .5;
|
||||
background-image: -moz-repeating-linear-gradient(-45deg,
|
||||
rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
|
||||
rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
|
||||
}
|
||||
|
||||
#status-bar > statusbarpanel {
|
||||
|
|
Двоичные данные
browser/themes/gnomestripe/browser/devtools/arrows.png
До Ширина: | Высота: | Размер: 933 B После Ширина: | Высота: | Размер: 882 B |
|
@ -22,6 +22,7 @@
|
|||
* Joe Walker <jwalker@mozilla.com> (original author)
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
* Michael Ratcliffe <mratcliffe@mozilla.com>
|
||||
* Dão Gottwald <dao@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,114 +38,135 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
background: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
.path,
|
||||
.filters {
|
||||
|
||||
#root {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#path {
|
||||
font-size: 11px;
|
||||
word-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding: 4px 5px 0;
|
||||
}
|
||||
.path ol {
|
||||
#path ol {
|
||||
list-style: none outside none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.path li {
|
||||
#path li {
|
||||
border-radius: 3px;
|
||||
padding: 2px 3px;
|
||||
text-shadow: #FFF 0 1px 0;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
background: -moz-linear-gradient(top, #F6F6FF, #E3E3FF);
|
||||
display: inline-block;
|
||||
}
|
||||
.path li:after {
|
||||
#path li:after {
|
||||
content: " > ";
|
||||
}
|
||||
.path li:last-child {
|
||||
background: -moz-linear-gradient(top, #FFC, #DD8);
|
||||
#path li:last-child {
|
||||
font-weight: bold;
|
||||
color: #0091ff;
|
||||
}
|
||||
.path li:last-child:after {
|
||||
color: red;
|
||||
#path li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
|
||||
color: #666;
|
||||
padding: 4px;
|
||||
-moz-padding-start: 0;
|
||||
-moz-padding-end: 5px;
|
||||
}
|
||||
|
||||
.property-name,
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
-moz-padding-start: 4px;
|
||||
-moz-padding-end: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
.link {
|
||||
color: #55A;
|
||||
}
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #55A;
|
||||
color: #0091ff;
|
||||
}
|
||||
a.link {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
a.link:visited {
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
padding: 2px 0;
|
||||
white-space: nowrap;
|
||||
.helplink-container {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
height: 14px;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
-moz-padding-start: 14px;
|
||||
background-image: url("chrome://browser/skin/devtools/goto-mdn.png");
|
||||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
||||
.property-header:not(:hover) > .helplink-container {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.unmatchedSelectorTable {
|
||||
-moz-margin-start: 15px;
|
||||
}
|
||||
|
||||
.rulelink {
|
||||
color: #55A;
|
||||
color: -moz-dialogtext;
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
.expander {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
float: left;
|
||||
-moz-margin-start: 15px;
|
||||
-moz-appearance: treetwisty;
|
||||
-moz-margin-start: 10px;
|
||||
-moz-margin-end: 5px;
|
||||
margin-top: 3px;
|
||||
background: url("chrome://browser/skin/devtools/arrows.png");
|
||||
background-position: 24px 0;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
|
||||
border-radius: 5px;
|
||||
-moz-padding-start: 20px;
|
||||
width: 135px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.expander[dir="rtl"] {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
.expander[open] {
|
||||
background-position: 8px 0;
|
||||
-moz-appearance: treetwistyopen;
|
||||
}
|
||||
|
||||
.expandable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.match {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.expandable > .match {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.only-unmatched {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
color: -moz-FieldText;
|
||||
width: 220px;
|
||||
}
|
||||
.property-value {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.property-view-hidden {
|
||||
|
@ -159,11 +181,7 @@ a.link:visited {
|
|||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
.rule-text {
|
||||
direction: ltr;
|
||||
-moz-padding-start: 10px;
|
||||
}
|
||||
|
||||
.resizerbox {
|
||||
background-color: window;
|
||||
-moz-padding-start: 15px;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
@ -179,16 +197,68 @@ a.link:visited {
|
|||
color: brown;
|
||||
}
|
||||
|
||||
.userStyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
#propertyContainer {
|
||||
display: -moz-box;
|
||||
-moz-box-orient: vertical;
|
||||
-moz-box-flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.userStyles,
|
||||
.selectedElementLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.darkrow {
|
||||
background-color: rgba(0,0,0,.022);
|
||||
}
|
||||
|
||||
#noResults {
|
||||
font-size: 18px;
|
||||
margin-top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.headerControls {
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.onlyuserstyles,
|
||||
.userStylesLabel {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.userStylesLabel {
|
||||
display: -moz-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.onlyuserstyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.styleinspector-legend {
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
border-top: 1px solid -moz-dialog;
|
||||
}
|
||||
|
||||
.legendKey {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS Rule View
|
||||
*/
|
||||
|
@ -229,7 +299,7 @@ a.link:visited {
|
|||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
.ruleview-expander[dir="rtl"] {
|
||||
.ruleview-expander:-moz-locale-dir(rtl) {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 661 B |
Двоичные данные
browser/themes/gnomestripe/browser/devtools/search.png
До Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -79,12 +79,12 @@ browser.jar:
|
|||
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
|
||||
skin/classic/browser/tabview/search.png (tabview/search.png)
|
||||
skin/classic/browser/tabview/search.png (tabview/search.png)
|
||||
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
|
||||
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
|
||||
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/search.png (devtools/search.png)
|
||||
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
|
||||
skin/classic/browser/devtools/gcli.css (devtools/gcli.css)
|
||||
skin/classic/browser/devtools/breadcrumbs/ltr-end-pressed.png (devtools/breadcrumbs/ltr-end-pressed.png)
|
||||
|
|
|
@ -2469,6 +2469,13 @@ panel[dimmed="true"] {
|
|||
padding-right: 0;
|
||||
}
|
||||
|
||||
#addon-bar[customizing] > #status-bar {
|
||||
opacity: .5;
|
||||
background-image: -moz-repeating-linear-gradient(-45deg,
|
||||
rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
|
||||
rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
|
||||
}
|
||||
|
||||
#status-bar > statusbarpanel {
|
||||
border-width: 0;
|
||||
-moz-appearance: none;
|
||||
|
|
Двоичные данные
browser/themes/pinstripe/browser/devtools/arrows.png
До Ширина: | Высота: | Размер: 933 B После Ширина: | Высота: | Размер: 882 B |
|
@ -22,6 +22,7 @@
|
|||
* Joe Walker <jwalker@mozilla.com> (original author)
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
* Michael Ratcliffe <mratcliffe@mozilla.com>
|
||||
* Dão Gottwald <dao@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,114 +38,137 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
background: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
.path,
|
||||
.filters {
|
||||
|
||||
#root {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#path {
|
||||
font-size: 11px;
|
||||
word-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding: 4px 5px 0;
|
||||
}
|
||||
.path ol {
|
||||
#path ol {
|
||||
list-style: none outside none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.path li {
|
||||
#path li {
|
||||
border-radius: 3px;
|
||||
padding: 2px 3px;
|
||||
text-shadow: #FFF 0 1px 0;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
background: -moz-linear-gradient(top, #F6F6FF, #E3E3FF);
|
||||
display: inline-block;
|
||||
}
|
||||
.path li:after {
|
||||
#path li:after {
|
||||
content: " > ";
|
||||
}
|
||||
.path li:last-child {
|
||||
background: -moz-linear-gradient(top, #FFC, #DD8);
|
||||
#path li:last-child {
|
||||
font-weight: bold;
|
||||
color: #0091ff;
|
||||
}
|
||||
.path li:last-child:after {
|
||||
color: red;
|
||||
#path li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
|
||||
color: #666;
|
||||
padding: 4px;
|
||||
-moz-padding-start: 0;
|
||||
-moz-padding-end: 5px;
|
||||
}
|
||||
|
||||
.property-name,
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
-moz-padding-start: 4px;
|
||||
-moz-padding-end: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
.link {
|
||||
color: #55A;
|
||||
}
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #55A;
|
||||
color: #0091ff;
|
||||
}
|
||||
a.link {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
a.link:visited {
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
padding: 2px 0;
|
||||
white-space: nowrap;
|
||||
.helplink-container {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
height: 14px;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
-moz-padding-start: 14px;
|
||||
background-image: url("chrome://browser/skin/devtools/goto-mdn.png");
|
||||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
||||
.property-header:not(:hover) > .helplink-container {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.unmatchedSelectorTable {
|
||||
-moz-margin-start: 15px;
|
||||
}
|
||||
|
||||
.rulelink {
|
||||
color: #55A;
|
||||
color: -moz-dialogtext;
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
.expander {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
float: left;
|
||||
-moz-margin-start: 15px;
|
||||
-moz-appearance: treetwisty;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
margin-top: 3px;
|
||||
background: url("chrome://browser/skin/devtools/arrows.png");
|
||||
background-position: 24px 0;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
|
||||
border-radius: 5px;
|
||||
-moz-padding-start: 20px;
|
||||
width: 135px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.expander[dir="rtl"] {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
.expander[open] {
|
||||
background-position: 8px 0;
|
||||
-moz-appearance: treetwistyopen;
|
||||
}
|
||||
|
||||
.expandable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.match {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.expandable > .match {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.only-unmatched {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
color: -moz-FieldText;
|
||||
width: 220px;
|
||||
}
|
||||
.property-value {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.property-view-hidden {
|
||||
|
@ -159,11 +183,7 @@ a.link:visited {
|
|||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
.rule-text {
|
||||
direction: ltr;
|
||||
-moz-padding-start: 10px;
|
||||
}
|
||||
|
||||
.resizerbox {
|
||||
background-color: window;
|
||||
-moz-padding-start: 15px;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
@ -179,16 +199,68 @@ a.link:visited {
|
|||
color: brown;
|
||||
}
|
||||
|
||||
.userStyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
#propertyContainer {
|
||||
display: -moz-box;
|
||||
-moz-box-orient: vertical;
|
||||
-moz-box-flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.userStyles,
|
||||
.selectedElementLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.darkrow {
|
||||
background-color: rgba(0,0,0,.022);
|
||||
}
|
||||
|
||||
#noResults {
|
||||
font-size: 18px;
|
||||
margin-top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.headerControls {
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.onlyuserstyles,
|
||||
.userStylesLabel {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.userStylesLabel {
|
||||
display: -moz-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.onlyuserstyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.styleinspector-legend {
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
border-top: 1px solid -moz-dialog;
|
||||
}
|
||||
|
||||
.legendKey {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS Rule View
|
||||
*/
|
||||
|
@ -229,7 +301,7 @@ a.link:visited {
|
|||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
.ruleview-expander[dir="rtl"] {
|
||||
.ruleview-expander:-moz-locale-dir(rtl) {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 661 B |
Двоичные данные
browser/themes/pinstripe/browser/devtools/search.png
До Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -123,7 +123,7 @@ browser.jar:
|
|||
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
|
||||
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/search.png (devtools/search.png)
|
||||
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
|
||||
skin/classic/browser/devtools/gcli.css (devtools/gcli.css)
|
||||
skin/classic/browser/devtools/toolbarbutton-close.png (devtools/toolbarbutton-close.png)
|
||||
|
|
|
@ -2568,6 +2568,13 @@ panel[dimmed="true"] {
|
|||
min-height: 0;
|
||||
}
|
||||
|
||||
#addon-bar[customizing] > #status-bar {
|
||||
opacity: .5;
|
||||
background-image: -moz-repeating-linear-gradient(-45deg,
|
||||
rgba(255,255,255,.3), rgba(255,255,255,.3) 5px,
|
||||
rgba(0,0,0,.3) 5px, rgba(0,0,0,.3) 10px);
|
||||
}
|
||||
|
||||
#status-bar > statusbarpanel {
|
||||
border-width: 0;
|
||||
-moz-appearance: none;
|
||||
|
|
Двоичные данные
browser/themes/winstripe/browser/devtools/arrows.png
До Ширина: | Высота: | Размер: 933 B После Ширина: | Высота: | Размер: 882 B |
|
@ -22,6 +22,7 @@
|
|||
* Joe Walker <jwalker@mozilla.com> (original author)
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
* Michael Ratcliffe <mratcliffe@mozilla.com>
|
||||
* Dão Gottwald <dao@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,114 +38,137 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
:root {
|
||||
-moz-appearance: none;
|
||||
background: -moz-Field;
|
||||
color: -moz-FieldText;
|
||||
}
|
||||
.path,
|
||||
.filters {
|
||||
|
||||
#root {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
#path {
|
||||
font-size: 11px;
|
||||
word-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding: 4px 5px 0;
|
||||
}
|
||||
.path ol {
|
||||
#path ol {
|
||||
list-style: none outside none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.path li {
|
||||
#path li {
|
||||
border-radius: 3px;
|
||||
padding: 2px 3px;
|
||||
text-shadow: #FFF 0 1px 0;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
background: -moz-linear-gradient(top, #F6F6FF, #E3E3FF);
|
||||
display: inline-block;
|
||||
}
|
||||
.path li:after {
|
||||
#path li:after {
|
||||
content: " > ";
|
||||
}
|
||||
.path li:last-child {
|
||||
background: -moz-linear-gradient(top, #FFC, #DD8);
|
||||
#path li:last-child {
|
||||
font-weight: bold;
|
||||
color: #0091ff;
|
||||
}
|
||||
.path li:last-child:after {
|
||||
color: red;
|
||||
#path li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #F8F8F8, #E8E8E8);
|
||||
color: #666;
|
||||
padding: 4px;
|
||||
-moz-padding-start: 0;
|
||||
-moz-padding-end: 5px;
|
||||
}
|
||||
|
||||
.property-name,
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
-moz-padding-start: 4px;
|
||||
-moz-padding-end: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
.link {
|
||||
color: #55A;
|
||||
}
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #55A;
|
||||
color: #0091ff;
|
||||
}
|
||||
a.link {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
a.link:visited {
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.rule-matched,
|
||||
.rule-unmatched {
|
||||
padding: 2px 0;
|
||||
white-space: nowrap;
|
||||
.helplink-container {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
height: 14px;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
-moz-padding-start: 14px;
|
||||
background-image: url("chrome://browser/skin/devtools/goto-mdn.png");
|
||||
-moz-margin-end: 2px;
|
||||
}
|
||||
|
||||
.property-header:not(:hover) > .helplink-container {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.unmatchedSelectorTable {
|
||||
-moz-margin-start: 15px;
|
||||
}
|
||||
|
||||
.rulelink {
|
||||
color: #55A;
|
||||
color: -moz-dialogtext;
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
.expander {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
float: left;
|
||||
-moz-margin-start: 15px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
margin-top: 3px;
|
||||
background: url("chrome://browser/skin/devtools/arrows.png");
|
||||
background-position: 24px 0;
|
||||
background: url("chrome://global/skin/tree/twisty-clsd.png") center center no-repeat;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
background: url("chrome://browser/skin/devtools/search.png") no-repeat #FFF;
|
||||
border-radius: 5px;
|
||||
-moz-padding-start: 20px;
|
||||
width: 135px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.expander[dir="rtl"] {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
.expander[open] {
|
||||
background-position: 8px 0;
|
||||
background-image: url("chrome://global/skin/tree/twisty-open.png");
|
||||
}
|
||||
|
||||
.expandable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.match {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.expandable > .match {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.only-unmatched {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
color: -moz-FieldText;
|
||||
width: 220px;
|
||||
}
|
||||
.property-value {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.property-view-hidden {
|
||||
|
@ -159,11 +183,7 @@ a.link:visited {
|
|||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
.rule-text {
|
||||
direction: ltr;
|
||||
-moz-padding-start: 10px;
|
||||
}
|
||||
|
||||
.resizerbox {
|
||||
background-color: window;
|
||||
-moz-padding-start: 15px;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
@ -179,16 +199,68 @@ a.link:visited {
|
|||
color: brown;
|
||||
}
|
||||
|
||||
.userStyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
#propertyContainer {
|
||||
display: -moz-box;
|
||||
-moz-box-orient: vertical;
|
||||
-moz-box-flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.userStyles,
|
||||
.selectedElementLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.darkrow {
|
||||
background-color: rgba(0,0,0,.022);
|
||||
}
|
||||
|
||||
#noResults {
|
||||
font-size: 18px;
|
||||
margin-top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.headerControls {
|
||||
color: -moz-dialogtext;
|
||||
background-color: -moz-dialog;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.onlyuserstyles,
|
||||
.userStylesLabel {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.userStylesLabel {
|
||||
display: -moz-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.onlyuserstyles {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.searchfield {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.styleinspector-legend {
|
||||
-moz-margin-start: 12px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
border-top: 1px solid -moz-dialog;
|
||||
}
|
||||
|
||||
.legendKey {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS Rule View
|
||||
*/
|
||||
|
@ -229,7 +301,7 @@ a.link:visited {
|
|||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
.ruleview-expander[dir="rtl"] {
|
||||
.ruleview-expander:-moz-locale-dir(rtl) {
|
||||
background-position: 16px 0;
|
||||
}
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 661 B |
Двоичные данные
browser/themes/winstripe/browser/devtools/search.png
До Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -107,7 +107,7 @@ browser.jar:
|
|||
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
|
||||
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
skin/classic/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/browser/devtools/search.png (devtools/search.png)
|
||||
skin/classic/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
|
||||
skin/classic/browser/devtools/gcli.css (devtools/gcli.css)
|
||||
skin/classic/browser/devtools/toolbarbutton-close.png (devtools/toolbarbutton-close.png)
|
||||
|
@ -259,7 +259,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
|
||||
skin/classic/aero/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
skin/classic/aero/browser/devtools/arrows.png (devtools/arrows.png)
|
||||
skin/classic/aero/browser/devtools/search.png (devtools/search.png)
|
||||
skin/classic/aero/browser/devtools/goto-mdn.png (devtools/goto-mdn.png)
|
||||
skin/classic/aero/browser/devtools/csshtmltree.css (devtools/csshtmltree.css)
|
||||
skin/classic/aero/browser/devtools/gcli.css (devtools/gcli.css)
|
||||
skin/classic/aero/browser/devtools/toolbarbutton-close.png (devtools/toolbarbutton-close.png)
|
||||
|
|
|
@ -215,9 +215,13 @@ class PythonJob(Job):
|
|||
print >>sys.stderr, e
|
||||
return e.exitcode
|
||||
except:
|
||||
print >>sys.stderr, sys.exc_info()[1]
|
||||
print >>sys.stderr, traceback.print_exc()
|
||||
return -127
|
||||
e = sys.exc_info()[1]
|
||||
if isinstance(e, SystemExit) and (e.code == 0 or e.code == '0'):
|
||||
pass # sys.exit(0) is not a failure
|
||||
else:
|
||||
print >>sys.stderr, e
|
||||
print >>sys.stderr, traceback.print_exc()
|
||||
return -127
|
||||
finally:
|
||||
os.environ = oldenv
|
||||
return 0
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#T gmake skip
|
||||
|
||||
CMD = %pycmd asplode
|
||||
PYCOMMANDPATH = $(TESTPATH) $(TESTPATH)/subdir
|
||||
|
||||
all:
|
||||
$(CMD) 0
|
||||
@echo TEST-PASS
|
|
@ -1,4 +1,4 @@
|
|||
import os
|
||||
import os, sys
|
||||
|
||||
def writetofile(args):
|
||||
with open(args[0], 'w') as f:
|
||||
|
@ -7,3 +7,7 @@ def writetofile(args):
|
|||
def writeenvtofile(args):
|
||||
with open(args[0], 'w') as f:
|
||||
f.write(os.environ[args[1]])
|
||||
|
||||
def asplode(args):
|
||||
sys.exit(args[0])
|
||||
return 0
|
||||
|
|
|
@ -253,7 +253,6 @@ MOZ_PERMISSIONS = @MOZ_PERMISSIONS@
|
|||
MOZ_XTF = @MOZ_XTF@
|
||||
MOZ_SVG_DLISTS = @MOZ_SVG_DLISTS@
|
||||
MOZ_CAIRO_CFLAGS = @MOZ_CAIRO_CFLAGS@
|
||||
MOZ_SMIL = @MOZ_SMIL@
|
||||
|
||||
MOZ_PREF_EXTENSIONS = @MOZ_PREF_EXTENSIONS@
|
||||
|
||||
|
|
|
@ -805,11 +805,11 @@ ifneq (,$(SHARED_LIBRARY)$(PROGRAM))
|
|||
export::
|
||||
ifdef PROGRAM
|
||||
$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
|
||||
$(PROGRAM:$(BIN_SUFFIX)=) $(DIST)/$(MOZ_APP_NAME)
|
||||
$(PROGRAM:$(BIN_SUFFIX)=) $(DIST)/bin
|
||||
endif
|
||||
ifdef SHARED_LIBRARY
|
||||
$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
|
||||
$(SHARED_LIBRARY_NAME) $(DIST)/$(MOZ_APP_NAME)
|
||||
$(SHARED_LIBRARY_NAME) $(DIST)/bin
|
||||
endif
|
||||
endif # SHARED_LIBRARY || PROGRAM
|
||||
endif # WINNT_
|
||||
|
@ -1469,7 +1469,7 @@ $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
|||
$(PYTHON_PATH) \
|
||||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
$(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(topsrcdir)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
|
||||
$(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
|
||||
@if test -n "$(findstring $*.h, $(EXPORTS))"; \
|
||||
then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
|
||||
|
||||
|
@ -1482,7 +1482,7 @@ $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
|
|||
-I$(topsrcdir)/other-licenses/ply \
|
||||
-I$(topsrcdir)/xpcom/idl-parser \
|
||||
-I$(topsrcdir)/xpcom/typelib/xpt/tools \
|
||||
$(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(topsrcdir)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
|
||||
$(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
|
||||
|
||||
# no need to link together if XPIDLSRCS contains only XPIDL_MODULE
|
||||
ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
|
||||
|
|
13
configure.in
|
@ -6190,18 +6190,6 @@ if test -n "$MOZ_SVG_DLISTS"; then
|
|||
AC_DEFINE(MOZ_SVG_DLISTS)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl SMIL
|
||||
dnl ========================================================
|
||||
MOZ_SMIL=1
|
||||
MOZ_ARG_DISABLE_BOOL(smil,
|
||||
[ --disable-smil Disable SMIL animation support],
|
||||
MOZ_SMIL=,
|
||||
MOZ_SMIL=1 )
|
||||
if test -n "$MOZ_SMIL"; then
|
||||
AC_DEFINE(MOZ_SMIL)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Build Freetype in the tree
|
||||
dnl ========================================================
|
||||
|
@ -8294,7 +8282,6 @@ AC_SUBST(MOZ_AUTH_EXTENSION)
|
|||
AC_SUBST(MOZ_PERMISSIONS)
|
||||
AC_SUBST(MOZ_XTF)
|
||||
AC_SUBST(MOZ_PREF_EXTENSIONS)
|
||||
AC_SUBST(MOZ_SMIL)
|
||||
AC_SUBST(MOZ_JS_LIBS)
|
||||
AC_SUBST(MOZ_PSM)
|
||||
AC_SUBST(MOZ_DEBUG)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
function boom() {
|
||||
select = document.createElementNS("http://www.w3.org/1999/xhtml", "select");
|
||||
text = document.body.childNodes[0];
|
||||
select.setAttribute("onDOMSubtreeModified", "text.parentNode.removeChild(text);");
|
||||
select.appendChild(text);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom()">
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -96,4 +96,5 @@ load 667336-1.html
|
|||
load 679459.html
|
||||
load 679689-1.html
|
||||
load 682463.html
|
||||
load 693212.xhtml
|
||||
load 698974-1.html
|
||||
|
|
|
@ -57,10 +57,8 @@ class nsAttrName;
|
|||
class nsTextFragment;
|
||||
class nsIDocShell;
|
||||
class nsIFrame;
|
||||
#ifdef MOZ_SMIL
|
||||
class nsISMILAttr;
|
||||
class nsIDOMCSSStyleDeclaration;
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
@ -891,7 +889,6 @@ public:
|
|||
mPrimaryFrame = aFrame;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
/*
|
||||
* Returns a new nsISMILAttr that allows the caller to animate the given
|
||||
* attribute on this element.
|
||||
|
@ -924,7 +921,6 @@ public:
|
|||
*/
|
||||
virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
|
||||
bool aNotify) = 0;
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
||||
nsAString& aNamespaceURI) const;
|
||||
|
|
|
@ -61,9 +61,7 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILAnimationController.h"
|
||||
#endif // MOZ_SMIL
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIAnimationFrameListener.h"
|
||||
|
@ -745,10 +743,10 @@ public:
|
|||
virtual Element* GetFullScreenElement() = 0;
|
||||
|
||||
/**
|
||||
* Requests that the document make aElement the full-screen element,
|
||||
* and move into full-screen mode.
|
||||
* Asynchronously requests that the document make aElement the full-screen
|
||||
* element, and move into full-screen mode.
|
||||
*/
|
||||
virtual void RequestFullScreen(Element* aElement) = 0;
|
||||
virtual void AsyncRequestFullScreen(Element* aElement) = 0;
|
||||
|
||||
/**
|
||||
* Requests that the document, and all documents in its hierarchy exit
|
||||
|
@ -1326,7 +1324,6 @@ public:
|
|||
void EnumerateFreezableElements(FreezableElementEnumerator aEnumerator,
|
||||
void* aData);
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Indicates whether mAnimationController has been (lazily) initialized.
|
||||
// If this returns true, we're promising that GetAnimationController()
|
||||
// will have a non-null return value.
|
||||
|
@ -1336,7 +1333,6 @@ public:
|
|||
// initialization, if this document supports animation and if
|
||||
// mAnimationController isn't yet initialized.
|
||||
virtual nsSMILAnimationController* GetAnimationController() = 0;
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// Makes the images on this document capable of having their animation
|
||||
// active or suspended. An Image will animate as long as at least one of its
|
||||
|
@ -1649,10 +1645,8 @@ protected:
|
|||
// themselves when they go away.
|
||||
nsAutoPtr<nsTHashtable<nsPtrHashKey<nsIContent> > > mFreezableElements;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// SMIL Animation Controller, lazily-initialized in GetAnimationController
|
||||
nsRefPtr<nsSMILAnimationController> mAnimationController;
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// Table of element properties for this document.
|
||||
nsPropertyTable mPropertyTable;
|
||||
|
|
|
@ -284,9 +284,7 @@ private:
|
|||
// 0 is global.
|
||||
#define DOM_USER_DATA 1
|
||||
#define DOM_USER_DATA_HANDLER 2
|
||||
#ifdef MOZ_SMIL
|
||||
#define SMIL_MAPPED_ATTR_ANIMVAL 3
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
|
|
|
@ -185,11 +185,9 @@
|
|||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsEventStateManager.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsSMILAnimationController.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
|
@ -214,8 +212,13 @@ using namespace mozilla::dom;
|
|||
|
||||
typedef nsTArray<Link*> LinkArray;
|
||||
|
||||
// Reference to the document which requested DOM full-screen mode.
|
||||
nsWeakPtr nsDocument::sFullScreenDoc = nsnull;
|
||||
|
||||
// Reference to the root document of the branch containing the document
|
||||
// which requested DOM full-screen mode.
|
||||
nsWeakPtr nsDocument::sFullScreenRootDoc = nsnull;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gDocumentLeakPRLog;
|
||||
static PRLogModuleInfo* gCspPRLog;
|
||||
|
@ -1586,11 +1589,9 @@ nsDocument::~nsDocument()
|
|||
mStyleSheetSetList->Disconnect();
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
if (mAnimationController) {
|
||||
mAnimationController->Disconnect();
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
mParentDocument = nsnull;
|
||||
|
||||
|
@ -1873,12 +1874,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
|||
cb.NoteXPCOMChild(tmp->mAnimationFrameListeners[i]);
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Traverse animation components
|
||||
if (tmp->mAnimationController) {
|
||||
tmp->mAnimationController->Traverse(&cb);
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
|
||||
PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
|
||||
|
@ -1950,11 +1949,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
|||
|
||||
tmp->mIdentifierMap.Clear();
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
if (tmp->mAnimationController) {
|
||||
tmp->mAnimationController->Unlink();
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
tmp->mInUnlinkOrDeletion = false;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -3763,13 +3760,11 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
"Script global object must be an inner window!");
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_SMIL
|
||||
NS_ABORT_IF_FALSE(aScriptGlobalObject || !mAnimationController ||
|
||||
mAnimationController->IsPausedByType(
|
||||
nsSMILTimeContainer::PAUSE_PAGEHIDE |
|
||||
nsSMILTimeContainer::PAUSE_BEGIN),
|
||||
"Clearing window pointer while animations are unpaused");
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
if (mScriptGlobalObject && !aScriptGlobalObject) {
|
||||
// We're detaching from the window. We need to grab a pointer to
|
||||
|
@ -5530,7 +5525,6 @@ nsDocument::EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData)
|
|||
mExternalResourceMap.EnumerateResources(aCallback, aData);
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsSMILAnimationController*
|
||||
nsDocument::GetAnimationController()
|
||||
{
|
||||
|
@ -5565,7 +5559,6 @@ nsDocument::GetAnimationController()
|
|||
|
||||
return mAnimationController;
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
struct DirTable {
|
||||
const char* mName;
|
||||
|
@ -7274,11 +7267,9 @@ nsDocument::OnPageShow(bool aPersisted,
|
|||
mIsShowing = true;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
if (mAnimationController) {
|
||||
mAnimationController->OnPageShow();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aPersisted) {
|
||||
SetImagesNeedAnimating(true);
|
||||
|
@ -7301,6 +7292,21 @@ NotifyPageHide(nsIDocument* aDocument, void* aData)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SetFullScreenState(nsIDocument* aDoc, Element* aElement, bool aIsFullScreen);
|
||||
|
||||
static void
|
||||
SetWindowFullScreen(nsIDocument* aDoc, bool aValue);
|
||||
|
||||
static bool
|
||||
ResetFullScreen(nsIDocument* aDocument, void* aData) {
|
||||
if (aDocument->IsFullScreenDoc()) {
|
||||
::SetFullScreenState(aDocument, nsnull, false);
|
||||
aDocument->EnumerateSubDocuments(ResetFullScreen, nsnull);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::OnPageHide(bool aPersisted,
|
||||
nsIDOMEventTarget* aDispatchStartTarget)
|
||||
|
@ -7329,11 +7335,9 @@ nsDocument::OnPageHide(bool aPersisted,
|
|||
mIsShowing = false;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
if (mAnimationController) {
|
||||
mAnimationController->OnPageHide();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aPersisted) {
|
||||
SetImagesNeedAnimating(false);
|
||||
|
@ -7352,6 +7356,29 @@ nsDocument::OnPageHide(bool aPersisted,
|
|||
|
||||
EnumerateExternalResources(NotifyPageHide, &aPersisted);
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nsnull);
|
||||
|
||||
if (IsFullScreenDoc()) {
|
||||
// A full-screen doc has been hidden. We need to ensure we exit
|
||||
// full-screen, i.e. remove full-screen state from all full-screen
|
||||
// documents, and exit the top-level window from full-screen mode.
|
||||
// Unfortunately by the time a doc is hidden, it has been removed
|
||||
// from the doc tree, so we can't just call CancelFullScreen()...
|
||||
|
||||
// So firstly reset full-screen state in *this* document. OnPageHide()
|
||||
// is called in every hidden document, so doing this ensures all hidden
|
||||
// documents have their state reset.
|
||||
::SetFullScreenState(this, nsnull, false);
|
||||
|
||||
// Next walk the document tree of still visible documents, and reset
|
||||
// their full-screen state. We then move the top-level window out
|
||||
// of full-screen mode.
|
||||
nsCOMPtr<nsIDocument> fullScreenRoot(do_QueryReferent(sFullScreenRootDoc));
|
||||
if (fullScreenRoot) {
|
||||
fullScreenRoot->EnumerateSubDocuments(ResetFullScreen, nsnull);
|
||||
SetWindowFullScreen(fullScreenRoot, false);
|
||||
sFullScreenRootDoc = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8456,6 +8483,7 @@ nsDocument::CancelFullScreen()
|
|||
doc = doc->GetParentDocument();
|
||||
}
|
||||
sFullScreenDoc = nsnull;
|
||||
sFullScreenRootDoc = nsnull;
|
||||
|
||||
// Move the window out of full-screen mode.
|
||||
SetWindowFullScreen(this, false);
|
||||
|
@ -8500,18 +8528,66 @@ GetCommonAncestor(nsIDocument* aDoc1, nsIDocument* aDoc2)
|
|||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RequestFullScreen(Element* aElement)
|
||||
// Returns the root document in a document hierarchy.
|
||||
static nsIDocument*
|
||||
GetRootDocument(nsIDocument* aDoc)
|
||||
{
|
||||
if (!aElement || !nsContentUtils::IsFullScreenApiEnabled() || !GetWindow()) {
|
||||
if (aElement) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(aElement,
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
if (!aDoc)
|
||||
return nsnull;
|
||||
nsIDocument* doc = aDoc;
|
||||
while (doc->GetParentDocument()) {
|
||||
doc = doc->GetParentDocument();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
class nsCallRequestFullScreen : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsCallRequestFullScreen(Element* aElement)
|
||||
: mElement(aElement),
|
||||
mDoc(aElement->OwnerDoc()),
|
||||
mWasCallerChrome(nsContentUtils::IsCallerChrome())
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
|
||||
doc->RequestFullScreen(mElement, mWasCallerChrome);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<Element> mElement;
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
bool mWasCallerChrome;
|
||||
};
|
||||
|
||||
void
|
||||
nsDocument::AsyncRequestFullScreen(Element* aElement)
|
||||
{
|
||||
if (!aElement) {
|
||||
return;
|
||||
}
|
||||
// Request full-screen asynchronously.
|
||||
nsCOMPtr<nsIRunnable> event(new nsCallRequestFullScreen(aElement));
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
{
|
||||
if (!aElement ||
|
||||
!aElement->IsInDoc() ||
|
||||
aElement->OwnerDoc() != this ||
|
||||
!IsFullScreenEnabled(aWasCallerChrome) ||
|
||||
!GetWindow()) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(this,
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8538,6 +8614,10 @@ nsDocument::RequestFullScreen(Element* aElement)
|
|||
SetWindowFullScreen(fullScreenDoc, false);
|
||||
}
|
||||
|
||||
// Remember the root document, so that if a full-screen document is hidden
|
||||
// we can reset full-screen state the remaining visible full-screen documents.
|
||||
sFullScreenRootDoc = do_GetWeakReference(GetRootDocument(this));
|
||||
|
||||
// Set the full-screen element. This sets the full-screen style on the
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
// in this document.
|
||||
|
@ -8602,20 +8682,25 @@ NS_IMETHODIMP
|
|||
nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFullScreen);
|
||||
*aFullScreen = false;
|
||||
*aFullScreen = IsFullScreenEnabled(nsContentUtils::IsCallerChrome());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (nsContentUtils::IsCallerChrome() &&
|
||||
nsContentUtils::IsFullScreenApiEnabled()) {
|
||||
bool
|
||||
nsDocument::IsFullScreenEnabled(bool aCallerIsChrome)
|
||||
{
|
||||
if (nsContentUtils::IsFullScreenApiEnabled() && aCallerIsChrome) {
|
||||
// Chrome code can always use the full-screen API, provided it's not
|
||||
// explicitly disabled.
|
||||
*aFullScreen = true;
|
||||
return NS_OK;
|
||||
// explicitly disabled. Note IsCallerChrome() returns true when running
|
||||
// in an nsRunnable, so don't use GetMozFullScreenEnabled() from an
|
||||
// nsRunnable!
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
||||
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this) ||
|
||||
!IsVisible()) {
|
||||
return NS_OK;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure that all ancestor <iframe> elements have the mozallowfullscreen
|
||||
|
@ -8628,13 +8713,12 @@ nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
|
|||
// The node requesting fullscreen, or one of its crossdoc ancestors,
|
||||
// is an iframe which doesn't have the "mozalllowfullscreen" attribute.
|
||||
// This request is not authorized by the parent document.
|
||||
return NS_OK;
|
||||
return false;
|
||||
}
|
||||
node = nsContentUtils::GetCrossDocParentNode(node);
|
||||
} while (node);
|
||||
|
||||
*aFullScreen = true;
|
||||
return NS_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRInt64
|
||||
|
|
|
@ -865,11 +865,9 @@ public:
|
|||
|
||||
nsTArray<nsCString> mFileDataUris;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Returns our (lazily-initialized) animation controller.
|
||||
// If HasAnimationController is true, this is guaranteed to return non-null.
|
||||
nsSMILAnimationController* GetAnimationController();
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
void SetImagesNeedAnimating(bool aAnimating);
|
||||
|
||||
|
@ -952,10 +950,16 @@ public:
|
|||
virtual Element* FindImageMap(const nsAString& aNormalizedMapName);
|
||||
|
||||
virtual Element* GetFullScreenElement();
|
||||
virtual void RequestFullScreen(Element* aElement);
|
||||
virtual void AsyncRequestFullScreen(Element* aElement);
|
||||
virtual void CancelFullScreen();
|
||||
virtual bool IsFullScreenDoc();
|
||||
|
||||
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
|
||||
// to move document into full-screen mode if allowed. aWasCallerChrome
|
||||
// should be true when nsIDocument::AsyncRequestFullScreen() was called
|
||||
// by chrome code.
|
||||
void RequestFullScreen(Element* aElement, bool aWasCallerChrome);
|
||||
|
||||
// Returns true if making this change results in a change in the full-screen
|
||||
// state of this document.
|
||||
bool SetFullScreenState(Element* aElement, bool aIsFullScreen);
|
||||
|
@ -969,6 +973,13 @@ public:
|
|||
protected:
|
||||
friend class nsNodeUtils;
|
||||
|
||||
// Returns true if a request for DOM full-screen is currently enabled in
|
||||
// this document. This returns true if there are no windowed plugins in this
|
||||
// doc tree, and if the document is visible, and if the api is not
|
||||
// disabled by pref. aIsCallerChrome must contain the return value of
|
||||
// nsContentUtils::IsCallerChrome() from the context we're checking.
|
||||
bool IsFullScreenEnabled(bool aIsCallerChrome);
|
||||
|
||||
/**
|
||||
* Check that aId is not empty and log a message to the console
|
||||
* service if it is.
|
||||
|
@ -1083,6 +1094,13 @@ protected:
|
|||
// of this document will also be full-screen.
|
||||
static nsWeakPtr sFullScreenDoc;
|
||||
|
||||
// The root document of the doctree containing the document which requested
|
||||
// full-screen. This root document will also be in full-screen state, as will
|
||||
// all the descendents down to the document which requested full-screen. This
|
||||
// reference allows us to reset full-screen state on all documents when a
|
||||
// document is hidden/navigation occurs.
|
||||
static nsWeakPtr sFullScreenRootDoc;
|
||||
|
||||
nsRefPtr<nsEventListenerManager> mListenerManager;
|
||||
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
|
||||
nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
|
||||
|
|
|
@ -928,7 +928,6 @@ nsGenericDOMDataNode::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsIDOMCSSStyleDeclaration*
|
||||
nsGenericDOMDataNode::GetSMILOverrideStyle()
|
||||
{
|
||||
|
@ -948,7 +947,6 @@ nsGenericDOMDataNode::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
|
|||
NS_NOTREACHED("How come we're setting SMILOverrideStyle on a non-element?");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
css::StyleRule*
|
||||
nsGenericDOMDataNode::GetInlineStyleRule()
|
||||
|
|
|
@ -52,9 +52,7 @@
|
|||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsDOMMemoryReporter.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsISMILAttr.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// This bit is set to indicate that if the text node changes to
|
||||
// non-whitespace, we may need to create a frame for it. This bit must
|
||||
|
@ -228,7 +226,6 @@ public:
|
|||
virtual void DestroyContent();
|
||||
virtual void SaveSubtreeState();
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
|
||||
{
|
||||
return nsnull;
|
||||
|
@ -237,7 +234,6 @@ public:
|
|||
virtual mozilla::css::StyleRule* GetSMILOverrideStyleRule();
|
||||
virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
|
||||
bool aNotify);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||
|
|
|
@ -2293,10 +2293,8 @@ nsGenericElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, b
|
|||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mStyle");
|
||||
cb.NoteXPCOMChild(mStyle.get());
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mSMILOverrideStyle");
|
||||
cb.NoteXPCOMChild(mSMILOverrideStyle.get());
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mAttributeMap");
|
||||
cb.NoteXPCOMChild(mAttributeMap.get());
|
||||
|
@ -2314,9 +2312,7 @@ void
|
|||
nsGenericElement::nsDOMSlots::Unlink(bool aIsXUL)
|
||||
{
|
||||
mStyle = nsnull;
|
||||
#ifdef MOZ_SMIL
|
||||
mSMILOverrideStyle = nsnull;
|
||||
#endif // MOZ_SMIL
|
||||
if (mAttributeMap) {
|
||||
mAttributeMap->DropReference();
|
||||
mAttributeMap = nsnull;
|
||||
|
@ -2456,13 +2452,11 @@ nsGenericElement::InternalIsSupported(nsISupports* aObject,
|
|||
*aReturn = true;
|
||||
}
|
||||
}
|
||||
#ifdef MOZ_SMIL
|
||||
else if (NS_SMILEnabled() && PL_strcasecmp(f, "TimeControl") == 0) {
|
||||
if (aVersion.IsEmpty() || PL_strcmp(v, "1.0") == 0) {
|
||||
*aReturn = true;
|
||||
}
|
||||
}
|
||||
#endif /* MOZ_SMIL */
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3355,7 +3349,6 @@ nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsIDOMCSSStyleDeclaration*
|
||||
nsGenericElement::GetSMILOverrideStyle()
|
||||
{
|
||||
|
@ -3398,7 +3391,6 @@ nsGenericElement::SetSMILOverrideStyleRule(css::StyleRule* aStyleRule,
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
css::StyleRule*
|
||||
nsGenericElement::GetInlineStyleRule()
|
||||
|
|
|
@ -67,9 +67,7 @@
|
|||
#include "nsIDOMTouchEvent.h"
|
||||
#include "nsIInlineEventHandlers.h"
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
#include "nsISMILAttr.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
class nsIDOMAttr;
|
||||
class nsIDOMEventListener;
|
||||
|
@ -349,7 +347,6 @@ public:
|
|||
virtual void DestroyContent();
|
||||
virtual void SaveSubtreeState();
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
|
||||
{
|
||||
return nsnull;
|
||||
|
@ -358,7 +355,6 @@ public:
|
|||
virtual mozilla::css::StyleRule* GetSMILOverrideStyleRule();
|
||||
virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
|
||||
bool aNotify);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out, PRInt32 aIndent) const
|
||||
|
|
|
@ -1368,7 +1368,6 @@ GK_ATOM(yChannelSelector, "yChannelSelector")
|
|||
GK_ATOM(z, "z")
|
||||
GK_ATOM(zoomAndPan, "zoomAndPan")
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
GK_ATOM(accumulate, "accumulate")
|
||||
GK_ATOM(additive, "additive")
|
||||
GK_ATOM(attributeName, "attributeName")
|
||||
|
@ -1395,7 +1394,6 @@ GK_ATOM(repeatEvent, "repeatEvent")
|
|||
GK_ATOM(restart, "restart")
|
||||
GK_ATOM(to, "to")
|
||||
GK_ATOM(XML, "XML")
|
||||
#endif
|
||||
|
||||
// internal MathML attributes: different from columnalign_, columnlines_,
|
||||
// fontstyle_, rowalign_ and rowlines_
|
||||
|
|
|
@ -307,8 +307,6 @@ nsPlainTextSerializer::AppendText(nsIContent* aText,
|
|||
NS_ENSURE_ARG(aText);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
PRInt32 length = 0;
|
||||
nsAutoString textstr;
|
||||
|
||||
nsIContent* content = aText;
|
||||
const nsTextFragment* frag;
|
||||
|
@ -319,16 +317,19 @@ nsPlainTextSerializer::AppendText(nsIContent* aText,
|
|||
PRInt32 endoffset = (aEndOffset == -1) ? frag->GetLength() : aEndOffset;
|
||||
NS_ASSERTION(aStartOffset <= endoffset, "A start offset is beyond the end of the text fragment!");
|
||||
|
||||
length = endoffset - aStartOffset;
|
||||
PRInt32 length = endoffset - aStartOffset;
|
||||
if (length <= 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString textstr;
|
||||
if (frag->Is2b()) {
|
||||
textstr.Assign(frag->Get2b() + aStartOffset, length);
|
||||
}
|
||||
else {
|
||||
textstr.AssignWithConversion(frag->Get1b()+aStartOffset, length);
|
||||
// AssignASCII is for 7-bit character only, so don't use it
|
||||
const char *data = frag->Get1b();
|
||||
CopyASCIItoUTF16(Substring(data + aStartOffset, data + endoffset), textstr);
|
||||
}
|
||||
|
||||
mOutputString = &aStr;
|
||||
|
|
|
@ -271,11 +271,7 @@ nsStyledElementNotElementCSSInlineStyle::GetStyle(nsresult* retval)
|
|||
// Just in case...
|
||||
ReparseStyleAttribute(true);
|
||||
|
||||
slots->mStyle = new nsDOMCSSAttributeDeclaration(this
|
||||
#ifdef MOZ_SMIL
|
||||
, false
|
||||
#endif // MOZ_SMIL
|
||||
);
|
||||
slots->mStyle = new nsDOMCSSAttributeDeclaration(this, false);
|
||||
SetMayHaveStyle();
|
||||
}
|
||||
|
||||
|
|
|
@ -323,7 +323,6 @@ nsIAtom** const kURLAttributesHTML[] = {
|
|||
};
|
||||
|
||||
nsIAtom** const kElementsSVG[] = {
|
||||
#ifdef MOZ_SVG
|
||||
&nsGkAtoms::a, // a
|
||||
&nsGkAtoms::altGlyph, // altGlyph
|
||||
&nsGkAtoms::altGlyphDef, // altGlyphDef
|
||||
|
@ -407,39 +406,29 @@ nsIAtom** const kElementsSVG[] = {
|
|||
&nsGkAtoms::use, // use
|
||||
&nsGkAtoms::view, // view
|
||||
&nsGkAtoms::vkern, // vkern
|
||||
#endif
|
||||
nsnull
|
||||
};
|
||||
|
||||
nsIAtom** const kAttributesSVG[] = {
|
||||
#ifdef MOZ_SVG
|
||||
// accent-height
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::accumulate, // accumulate
|
||||
&nsGkAtoms::additive, // additive
|
||||
#endif
|
||||
&nsGkAtoms::alignment_baseline, // alignment-baseline
|
||||
// alphabetic
|
||||
&nsGkAtoms::amplitude, // amplitude
|
||||
// arabic-form
|
||||
// ascent
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::attributeName, // attributeName
|
||||
&nsGkAtoms::attributeType, // attributeType
|
||||
#endif
|
||||
&nsGkAtoms::azimuth, // azimuth
|
||||
&nsGkAtoms::baseFrequency, // baseFrequency
|
||||
&nsGkAtoms::baseline_shift, // baseline-shift
|
||||
// baseProfile
|
||||
// bbox
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::begin, // begin
|
||||
#endif
|
||||
&nsGkAtoms::bias, // bias
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::by, // by
|
||||
&nsGkAtoms::calcMode, // calcMode
|
||||
#endif
|
||||
// cap-height
|
||||
&nsGkAtoms::_class, // class
|
||||
&nsGkAtoms::clip_path, // clip-path
|
||||
|
@ -460,17 +449,13 @@ nsIAtom** const kAttributesSVG[] = {
|
|||
&nsGkAtoms::display, // display
|
||||
&nsGkAtoms::divisor, // divisor
|
||||
&nsGkAtoms::dominant_baseline, // dominant-baseline
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::dur, // dur
|
||||
#endif
|
||||
&nsGkAtoms::dx, // dx
|
||||
&nsGkAtoms::dy, // dy
|
||||
&nsGkAtoms::edgeMode, // edgeMode
|
||||
&nsGkAtoms::elevation, // elevation
|
||||
// enable-background
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::end, // end
|
||||
#endif
|
||||
&nsGkAtoms::fill, // fill
|
||||
&nsGkAtoms::fill_opacity, // fill-opacity
|
||||
&nsGkAtoms::fill_rule, // fill-rule
|
||||
|
@ -518,11 +503,9 @@ nsIAtom** const kAttributesSVG[] = {
|
|||
&nsGkAtoms::kerning, // kerning
|
||||
&nsGkAtoms::kernelMatrix, // kernelMatrix
|
||||
&nsGkAtoms::kernelUnitLength, // kernelUnitLength
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::keyPoints, // keyPoints
|
||||
&nsGkAtoms::keySplines, // keySplines
|
||||
&nsGkAtoms::keyTimes, // keyTimes
|
||||
#endif
|
||||
&nsGkAtoms::lang, // lang
|
||||
// lengthAdjust
|
||||
&nsGkAtoms::letter_spacing, // letter-spacing
|
||||
|
@ -575,15 +558,11 @@ nsIAtom** const kAttributesSVG[] = {
|
|||
&nsGkAtoms::radius, // radius
|
||||
&nsGkAtoms::refX, // refX
|
||||
&nsGkAtoms::refY, // refY
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::repeatCount, // repeatCount
|
||||
&nsGkAtoms::repeatDur, // repeatDur
|
||||
#endif
|
||||
&nsGkAtoms::requiredExtensions, // requiredExtensions
|
||||
&nsGkAtoms::requiredFeatures, // requiredFeatures
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::restart, // restart
|
||||
#endif
|
||||
&nsGkAtoms::result, // result
|
||||
&nsGkAtoms::rotate, // rotate
|
||||
&nsGkAtoms::rx, // rx
|
||||
|
@ -625,9 +604,7 @@ nsIAtom** const kAttributesSVG[] = {
|
|||
// textLength
|
||||
&nsGkAtoms::text_rendering, // text-rendering
|
||||
&nsGkAtoms::title, // title
|
||||
#ifdef MOZ_SMIL
|
||||
&nsGkAtoms::to, // to
|
||||
#endif
|
||||
&nsGkAtoms::transform, // transform
|
||||
&nsGkAtoms::type, // type
|
||||
// u1
|
||||
|
@ -664,7 +641,6 @@ nsIAtom** const kAttributesSVG[] = {
|
|||
&nsGkAtoms::yChannelSelector, // yChannelSelector
|
||||
&nsGkAtoms::z, // z
|
||||
&nsGkAtoms::zoomAndPan, // zoomAndPan
|
||||
#endif
|
||||
nsnull
|
||||
};
|
||||
|
||||
|
|
|
@ -648,7 +648,6 @@ NON_IDL_EVENT(zoom,
|
|||
NS_SVG_ZOOM,
|
||||
EventNameType_SVGSVG,
|
||||
NS_EVENT_NULL)
|
||||
#ifdef MOZ_SMIL
|
||||
NON_IDL_EVENT(begin,
|
||||
NS_SMIL_BEGIN,
|
||||
EventNameType_SMIL,
|
||||
|
@ -673,7 +672,6 @@ NON_IDL_EVENT(repeatEvent,
|
|||
NS_SMIL_REPEAT,
|
||||
EventNameType_None,
|
||||
NS_SMIL_TIME_EVENT)
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
NON_IDL_EVENT(MozAudioAvailable,
|
||||
NS_MOZAUDIOAVAILABLE,
|
||||
|
|
|
@ -105,10 +105,8 @@ nsresult
|
|||
NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsGUIEvent* aEvent);
|
||||
#ifdef MOZ_SMIL
|
||||
nsresult
|
||||
NS_NewDOMTimeEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
#endif // MOZ_SMIL
|
||||
nsresult
|
||||
NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsInputEvent* aEvent);
|
||||
nsresult
|
||||
|
|
|
@ -85,9 +85,7 @@ static const char* const sEventNames[] = {
|
|||
"offline", "online", "copy", "cut", "paste", "open", "message", "show",
|
||||
"SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
|
||||
"SVGZoom",
|
||||
#ifdef MOZ_SMIL
|
||||
"beginEvent", "endEvent", "repeatEvent",
|
||||
#endif // MOZ_SMIL
|
||||
#ifdef MOZ_MEDIA
|
||||
"loadstart", "progress", "suspend", "emptied", "stalled", "play", "pause",
|
||||
"loadedmetadata", "loadeddata", "waiting", "playing", "canplay",
|
||||
|
@ -422,6 +420,14 @@ nsDOMEvent::StopPropagation()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::StopImmediatePropagation()
|
||||
{
|
||||
mEvent->flags |=
|
||||
(NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY | NS_EVENT_FLAG_STOP_DISPATCH);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIDocument* GetDocumentForReport(nsEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aEvent->currentTarget);
|
||||
|
@ -796,7 +802,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
|||
newEvent->eventStructType = NS_SVGZOOM_EVENT;
|
||||
break;
|
||||
}
|
||||
#ifdef MOZ_SMIL
|
||||
case NS_SMIL_TIME_EVENT:
|
||||
{
|
||||
newEvent = new nsUIEvent(false, msg, 0);
|
||||
|
@ -804,7 +809,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
|||
newEvent->eventStructType = NS_SMIL_TIME_EVENT;
|
||||
break;
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
case NS_SIMPLE_GESTURE_EVENT:
|
||||
{
|
||||
nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
|
||||
|
@ -1287,14 +1291,12 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_SVGScroll];
|
||||
case NS_SVG_ZOOM:
|
||||
return sEventNames[eDOMEvents_SVGZoom];
|
||||
#ifdef MOZ_SMIL
|
||||
case NS_SMIL_BEGIN:
|
||||
return sEventNames[eDOMEvents_beginEvent];
|
||||
case NS_SMIL_END:
|
||||
return sEventNames[eDOMEvents_endEvent];
|
||||
case NS_SMIL_REPEAT:
|
||||
return sEventNames[eDOMEvents_repeatEvent];
|
||||
#endif // MOZ_SMIL
|
||||
#ifdef MOZ_MEDIA
|
||||
case NS_LOADSTART:
|
||||
return sEventNames[eDOMEvents_loadstart];
|
||||
|
|
|
@ -149,11 +149,9 @@ public:
|
|||
eDOMEvents_SVGResize,
|
||||
eDOMEvents_SVGScroll,
|
||||
eDOMEvents_SVGZoom,
|
||||
#ifdef MOZ_SMIL
|
||||
eDOMEvents_beginEvent,
|
||||
eDOMEvents_endEvent,
|
||||
eDOMEvents_repeatEvent,
|
||||
#endif // MOZ_SMIL
|
||||
#ifdef MOZ_MEDIA
|
||||
eDOMEvents_loadstart,
|
||||
eDOMEvents_progress,
|
||||
|
|
|
@ -376,9 +376,9 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor
|
|||
|
||||
if (!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
// Dispatch to the system event group. Make sure to clear the
|
||||
// STOP_DISPATCH flag since this resets for each event group
|
||||
// per DOM3 Events.
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
// STOP_DISPATCH flag since this resets for each event group.
|
||||
aVisitor.mEvent->flags &=
|
||||
~(NS_EVENT_FLAG_STOP_DISPATCH | NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY);
|
||||
|
||||
// Setting back the original target of the event.
|
||||
aVisitor.mEvent->target = aVisitor.mEvent->originalTarget;
|
||||
|
@ -396,6 +396,11 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor
|
|||
aCallback,
|
||||
createdELMs != nsEventListenerManager::sCreatedCount,
|
||||
aPusher);
|
||||
|
||||
// After dispatch, clear all the propagation flags so that
|
||||
// system group listeners don't affect to the event.
|
||||
aVisitor.mEvent->flags &=
|
||||
~(NS_EVENT_FLAG_STOP_DISPATCH | NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -787,10 +792,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
case NS_SVGZOOM_EVENT:
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsGUIEvent*>(aEvent));
|
||||
#ifdef MOZ_SMIL
|
||||
case NS_SMIL_TIME_EVENT:
|
||||
return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, aEvent);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
case NS_COMMAND_EVENT:
|
||||
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
|
||||
|
@ -854,11 +857,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#ifdef MOZ_SMIL
|
||||
if (aEventType.LowerCaseEqualsLiteral("timeevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("timeevents"))
|
||||
return NS_NewDOMTimeEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#endif // MOZ_SMIL
|
||||
if (aEventType.LowerCaseEqualsLiteral("xulcommandevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("xulcommandevents"))
|
||||
return NS_NewDOMXULCommandEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
|
|
@ -624,14 +624,12 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
|
|||
attrName = nsGkAtoms::onscroll;
|
||||
else if (aListenerStruct->mTypeAtom == nsGkAtoms::onSVGZoom)
|
||||
attrName = nsGkAtoms::onzoom;
|
||||
#ifdef MOZ_SMIL
|
||||
else if (aListenerStruct->mTypeAtom == nsGkAtoms::onbeginEvent)
|
||||
attrName = nsGkAtoms::onbegin;
|
||||
else if (aListenerStruct->mTypeAtom == nsGkAtoms::onrepeatEvent)
|
||||
attrName = nsGkAtoms::onrepeat;
|
||||
else if (aListenerStruct->mTypeAtom == nsGkAtoms::onendEvent)
|
||||
attrName = nsGkAtoms::onend;
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
content->GetAttr(kNameSpaceID_None, attrName, handlerBody);
|
||||
body = &handlerBody;
|
||||
|
@ -764,6 +762,9 @@ nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||
nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent));
|
||||
bool hasListener = false;
|
||||
while (iter.HasMore()) {
|
||||
if (aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY) {
|
||||
break;
|
||||
}
|
||||
nsListenerStruct* ls = &iter.GetNext();
|
||||
// Check that the phase is same in event and event listener.
|
||||
// Handle only trusted events, except when listener permits untrusted events.
|
||||
|
|
|
@ -111,6 +111,7 @@ _TEST_FILES = \
|
|||
test_bug667612.html \
|
||||
empty.js \
|
||||
test_bug689564.html \
|
||||
test_bug698929.html \
|
||||
$(NULL)
|
||||
|
||||
#bug 585630
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=698929
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 698929</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=698929">Mozilla Bug 698929</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 698929 **/
|
||||
|
||||
var e = document.createEvent("Event");
|
||||
e.initEvent("foo", true, true);
|
||||
var c = 0;
|
||||
var b = 0;
|
||||
document.addEventListener("foo",
|
||||
function() {
|
||||
++c;
|
||||
});
|
||||
document.body.addEventListener("foo", function(e) {
|
||||
++b;
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
document.body.addEventListener("foo", function(e) {
|
||||
++b;
|
||||
});
|
||||
document.body.dispatchEvent(e);
|
||||
document.documentElement.dispatchEvent(e);
|
||||
is(c, 1, "Listener in the document should have been called once.");
|
||||
is(b, 1, "Listener in the body should have been called once.");
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -3404,11 +3404,9 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
// This stops the full-screen from being abused similar to the popups of old,
|
||||
// and it also makes it harder for bad guys' script to go full-screen and
|
||||
// spoof the browser chrome/window and phish logins etc.
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed() ||
|
||||
!IsInDoc()) {
|
||||
if (!nsContentUtils::IsRequestFullScreenAllowed()) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(this,
|
||||
new nsPLDOMEvent(OwnerDoc(),
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
|
@ -3416,27 +3414,8 @@ nsresult nsGenericHTMLElement::MozRequestFullScreen()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(doc));
|
||||
NS_ENSURE_STATE(domDocument);
|
||||
bool fullScreenEnabled;
|
||||
domDocument->GetMozFullScreenEnabled(&fullScreenEnabled);
|
||||
if (!fullScreenEnabled) {
|
||||
nsRefPtr<nsPLDOMEvent> e =
|
||||
new nsPLDOMEvent(this,
|
||||
NS_LITERAL_STRING("mozfullscreenerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
return NS_OK;
|
||||
}
|
||||
OwnerDoc()->AsyncRequestFullScreen(this);
|
||||
|
||||
doc->RequestFullScreen(this);
|
||||
#ifdef DEBUG
|
||||
bool fullscreen;
|
||||
domDocument->GetMozFullScreen(&fullscreen);
|
||||
NS_ASSERTION(fullscreen, "Document should report fullscreen");
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be in full screen state!");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|