зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to b2g-inbound a=merge
This commit is contained in:
Коммит
26bf315c56
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1038799 - And be wary of your ccache too.
|
||||
Clobber to work around bug 959928.
|
||||
|
|
|
@ -29,8 +29,9 @@ XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
|||
|
||||
this.EXPORTED_SYMBOLS = ['EventManager'];
|
||||
|
||||
this.EventManager = function EventManager(aContentScope) {
|
||||
this.EventManager = function EventManager(aContentScope, aContentControl) {
|
||||
this.contentScope = aContentScope;
|
||||
this.contentControl = aContentControl;
|
||||
this.addEventListener = this.contentScope.addEventListener.bind(
|
||||
this.contentScope);
|
||||
this.removeEventListener = this.contentScope.removeEventListener.bind(
|
||||
|
@ -99,7 +100,7 @@ this.EventManager.prototype = {
|
|||
{
|
||||
let attempts = 0;
|
||||
let delta = aEvent.deltaX || aEvent.deltaY;
|
||||
this.contentScope.contentControl.autoMove(
|
||||
this.contentControl.autoMove(
|
||||
null,
|
||||
{ moveMethod: delta > 0 ? 'moveNext' : 'movePrevious',
|
||||
onScreenOnly: true, noOpIfOnScreen: true, delay: 500 });
|
||||
|
@ -183,7 +184,7 @@ this.EventManager.prototype = {
|
|||
}
|
||||
case Events.SCROLLING_START:
|
||||
{
|
||||
this.contentScope.contentControl.autoMove(aEvent.accessible);
|
||||
this.contentControl.autoMove(aEvent.accessible);
|
||||
break;
|
||||
}
|
||||
case Events.TEXT_CARET_MOVED:
|
||||
|
@ -254,7 +255,7 @@ this.EventManager.prototype = {
|
|||
if (vc.position &&
|
||||
(Utils.getState(vc.position).contains(States.DEFUNCT) ||
|
||||
Utils.isInSubtree(vc.position, aEvent.accessible))) {
|
||||
this.contentScope.contentControl.autoMove(
|
||||
this.contentControl.autoMove(
|
||||
evt.targetPrevSibling || evt.targetParent,
|
||||
{ moveToFocused: true, delay: 500 });
|
||||
}
|
||||
|
@ -279,19 +280,19 @@ this.EventManager.prototype = {
|
|||
let acc = aEvent.accessible;
|
||||
let doc = aEvent.accessibleDocument;
|
||||
if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) {
|
||||
this.contentScope.contentControl.autoMove(acc);
|
||||
this.contentControl.autoMove(acc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Events.DOCUMENT_LOAD_COMPLETE:
|
||||
{
|
||||
this.contentScope.contentControl.autoMove(
|
||||
this.contentControl.autoMove(
|
||||
aEvent.accessible, { delay: 500 });
|
||||
break;
|
||||
}
|
||||
case Events.VALUE_CHANGE:
|
||||
{
|
||||
let position = this.contentScope.contentControl.vc.position;
|
||||
let position = this.contentControl.vc.position;
|
||||
let target = aEvent.accessible;
|
||||
if (position === target ||
|
||||
Utils.getEmbeddedControl(position) === target) {
|
||||
|
|
|
@ -140,16 +140,16 @@ addMessageListener(
|
|||
addMessageListener('AccessFu:Scroll', scroll);
|
||||
addMessageListener('AccessFu:AdjustRange', adjustRange);
|
||||
|
||||
if (!eventManager) {
|
||||
eventManager = new EventManager(this);
|
||||
}
|
||||
eventManager.start();
|
||||
|
||||
if (!contentControl) {
|
||||
contentControl = new ContentControl(this);
|
||||
}
|
||||
contentControl.start();
|
||||
|
||||
if (!eventManager) {
|
||||
eventManager = new EventManager(this, contentControl);
|
||||
}
|
||||
eventManager.start();
|
||||
|
||||
sendAsyncMessage('AccessFu:ContentStarted');
|
||||
});
|
||||
|
||||
|
|
|
@ -124,14 +124,9 @@ else # MOZ_WIDGET_TOOLKIT != cocoa
|
|||
libs::
|
||||
ifdef LIBXUL_SDK
|
||||
cp $(LIBXUL_DIST)/bin/xulrunner-stub$(BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY)
|
||||
endif
|
||||
ifndef SKIP_COPY_XULRUNNER
|
||||
ifdef LIBXUL_SDK
|
||||
$(NSINSTALL) -D $(DIST)/bin/xulrunner
|
||||
(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
|
||||
endif
|
||||
endif # SKIP_COPY_XULRUNNER
|
||||
|
||||
$(NSINSTALL) -D $(DIST)/bin/chrome/icons/default
|
||||
|
||||
# Copy the app icon for b2g-desktop
|
||||
|
|
|
@ -473,17 +473,6 @@ pref("services.push.adaptive.gap", 60000); // 1 minute
|
|||
pref("services.push.adaptive.upperLimit", 1740000); // 29 min
|
||||
// enable udp wakeup support
|
||||
pref("services.push.udp.wakeupEnabled", true);
|
||||
// This value should be the prefix to be added to the current PDP context[1]
|
||||
// domain or a full-qualified domain name.
|
||||
// If finished with a dot, it will be added as a prefix to the PDP context
|
||||
// domain. If not, will be used as the DNS query.
|
||||
// If the DNS query is unsuccessful, the push agent will send a null netid and
|
||||
// is a server decision what to do with the device. If the MCC-MNC identifies a
|
||||
// unique network the server will change to UDP mode. Otherwise, a websocket
|
||||
// connection will be maintained.
|
||||
// [1] Packet Data Protocol
|
||||
// http://en.wikipedia.org/wiki/GPRS_core_network#PDP_context
|
||||
pref("services.push.udp.well-known_netidAddress", "_wakeup_.");
|
||||
|
||||
// NetworkStats
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
|
|
@ -10,4 +10,5 @@ support-files =
|
|||
[test_filepicker_path.html]
|
||||
[test_permission_deny.html]
|
||||
[test_permission_gum_remember.html]
|
||||
skip-if = (toolkit == 'gonk' && debug) # Bug 1019572 - debug-only timeout
|
||||
[test_systemapp.html]
|
||||
|
|
|
@ -135,7 +135,6 @@ tools repackage:: $(PROGRAM)
|
|||
endif
|
||||
|
||||
ifdef LIBXUL_SDK #{
|
||||
ifndef SKIP_COPY_XULRUNNER #{
|
||||
libs::
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
|
||||
rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(dist_dest)/Contents/Frameworks
|
||||
|
@ -143,5 +142,4 @@ else
|
|||
$(NSINSTALL) -D $(DIST)/bin/xulrunner
|
||||
(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
|
||||
endif #} cocoa
|
||||
endif #} SKIP_COPY_XULRUNNER
|
||||
endif #} LIBXUL_SDK
|
||||
|
|
|
@ -1519,6 +1519,7 @@ pref("loop.enabled", false);
|
|||
#endif
|
||||
|
||||
pref("loop.server", "https://loop.services.mozilla.com");
|
||||
pref("loop.seenToS", "unseen");
|
||||
pref("loop.do_not_disturb", false);
|
||||
pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");
|
||||
|
||||
|
@ -1606,3 +1607,6 @@ pref("experiments.manifest.certs.1.commonName", "*.cdn.mozilla.net");
|
|||
pref("experiments.manifest.certs.1.issuerName", "CN=Cybertrust Public SureServer SV CA,O=Cybertrust Inc");
|
||||
// Whether experiments are supported by the current application profile.
|
||||
pref("experiments.supported", true);
|
||||
|
||||
// Enable the OpenH264 plugin support in the addon manager.
|
||||
pref("media.openh264.providerEnabled", true);
|
||||
|
|
|
@ -578,12 +578,18 @@ SocialShare = {
|
|||
}
|
||||
},
|
||||
|
||||
_onclick: function() {
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(0);
|
||||
},
|
||||
|
||||
onShowing: function() {
|
||||
this.anchor.setAttribute("open", "true");
|
||||
this.iframe.addEventListener("click", this._onclick, true);
|
||||
},
|
||||
|
||||
onHidden: function() {
|
||||
this.anchor.removeAttribute("open");
|
||||
this.iframe.removeEventListener("click", this._onclick, true);
|
||||
this.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
this.currentShare = null;
|
||||
},
|
||||
|
@ -704,10 +710,13 @@ SocialShare = {
|
|||
let anchor = document.getAnonymousElementByAttribute(this.anchor, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
|
||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(0);
|
||||
}
|
||||
};
|
||||
|
||||
SocialSidebar = {
|
||||
_openStartTime: 0,
|
||||
|
||||
// Whether the sidebar can be shown for this window.
|
||||
get canShow() {
|
||||
if (!SocialUI.enabled || document.mozFullScreen)
|
||||
|
@ -780,6 +789,11 @@ SocialSidebar = {
|
|||
"hidden": broadcaster.hidden,
|
||||
"origin": sidebarOrigin
|
||||
};
|
||||
if (broadcaster.hidden) {
|
||||
Services.telemetry.getHistogramById("SOCIAL_SIDEBAR_OPEN_DURATION").add(Date.now() / 1000 - this._openStartTime);
|
||||
} else {
|
||||
this._openStartTime = Date.now() / 1000;
|
||||
}
|
||||
|
||||
// Save a global state for users who do not restore state.
|
||||
if (broadcaster.hidden)
|
||||
|
@ -877,11 +891,16 @@ SocialSidebar = {
|
|||
this._updateCheckedMenuItems(this.opened && this.provider ? this.provider.origin : null);
|
||||
},
|
||||
|
||||
_onclick: function() {
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(3);
|
||||
},
|
||||
|
||||
_loadListener: function SocialSidebar_loadListener() {
|
||||
let sbrowser = document.getElementById("social-sidebar-browser");
|
||||
sbrowser.removeEventListener("load", SocialSidebar._loadListener, true);
|
||||
document.getElementById("social-sidebar-button").removeAttribute("loading");
|
||||
SocialSidebar.setSidebarVisibilityState(true);
|
||||
sbrowser.addEventListener("click", SocialSidebar._onclick, true);
|
||||
},
|
||||
|
||||
unloadSidebar: function SocialSidebar_unloadSidebar() {
|
||||
|
@ -889,6 +908,7 @@ SocialSidebar = {
|
|||
if (!sbrowser.hasAttribute("origin"))
|
||||
return;
|
||||
|
||||
sbrowser.removeEventListener("click", SocialSidebar._onclick, true);
|
||||
sbrowser.stop();
|
||||
sbrowser.removeAttribute("origin");
|
||||
sbrowser.setAttribute("src", "about:blank");
|
||||
|
@ -989,6 +1009,7 @@ SocialSidebar = {
|
|||
else
|
||||
SocialSidebar.update();
|
||||
this.saveWindowState();
|
||||
Services.telemetry.getHistogramById("SOCIAL_SIDEBAR_STATE").add(true);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
|
@ -998,6 +1019,7 @@ SocialSidebar = {
|
|||
this.clearProviderMenus();
|
||||
SocialSidebar.update();
|
||||
this.saveWindowState();
|
||||
Services.telemetry.getHistogramById("SOCIAL_SIDEBAR_STATE").add(false);
|
||||
},
|
||||
|
||||
toggleSidebar: function SocialSidebar_toggle() {
|
||||
|
@ -1219,13 +1241,29 @@ SocialStatus = {
|
|||
}
|
||||
},
|
||||
|
||||
_onclose: function() {
|
||||
let notificationFrameId = "social-status-" + origin;
|
||||
let frame = document.getElementById(notificationFrameId);
|
||||
frame.removeEventListener("close", this._onclose, true);
|
||||
frame.removeEventListener("click", this._onclick, true);
|
||||
},
|
||||
|
||||
_onclick: function() {
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(1);
|
||||
},
|
||||
|
||||
showPopup: function(aToolbarButton) {
|
||||
// attach our notification panel if necessary
|
||||
let origin = aToolbarButton.getAttribute("origin");
|
||||
let provider = Social._getProviderFromOrigin(origin);
|
||||
|
||||
PanelFrame.showPopup(window, PanelUI, aToolbarButton, "social", origin,
|
||||
provider.statusURL, provider.getPageSize("status"));
|
||||
provider.statusURL, provider.getPageSize("status"),
|
||||
(frame) => {
|
||||
frame.addEventListener("close", this._onclose, true);
|
||||
frame.addEventListener("click", this._onclick, true);
|
||||
});
|
||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(1);
|
||||
},
|
||||
|
||||
setPanelErrorMessage: function(aNotificationFrame) {
|
||||
|
|
|
@ -540,7 +540,7 @@ var gPopupBlockerObserver = {
|
|||
// xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
|
||||
if (!blockedPopup.popupWindowURI)
|
||||
continue;
|
||||
var popupURIspec = blockedPopup.popupWindowURI;
|
||||
var popupURIspec = blockedPopup.popupWindowURI.spec;
|
||||
|
||||
// Sometimes the popup URI that we get back from the blockedPopup
|
||||
// isn't useful (for instance, netscape.com's popup URI ends up
|
||||
|
@ -5133,14 +5133,14 @@ function handleLinkClick(event, href, linkNode) {
|
|||
// if the mixedContentChannel is present and the referring URI passes
|
||||
// a same origin check with the target URI, we can preserve the users
|
||||
// decision of disabling MCB on a page for it's child tabs.
|
||||
var persistDisableMCBInChildTab = false;
|
||||
var persistAllowMixedContentInChildTab = false;
|
||||
|
||||
if (where == "tab" && gBrowser.docShell.mixedContentChannel) {
|
||||
const sm = Services.scriptSecurityManager;
|
||||
try {
|
||||
var targetURI = makeURI(href);
|
||||
sm.checkSameOriginURI(referrerURI, targetURI, false);
|
||||
persistDisableMCBInChildTab = true;
|
||||
persistAllowMixedContentInChildTab = true;
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
|
@ -5148,7 +5148,7 @@ function handleLinkClick(event, href, linkNode) {
|
|||
urlSecurityCheck(href, doc.nodePrincipal);
|
||||
openLinkIn(href, where, { referrerURI: referrerURI,
|
||||
charset: doc.characterSet,
|
||||
disableMCB: persistDisableMCBInChildTab});
|
||||
allowMixedContent: persistAllowMixedContentInChildTab });
|
||||
event.preventDefault();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -563,8 +563,7 @@
|
|||
#endif
|
||||
#endif
|
||||
context="toolbar-context-menu">
|
||||
<toolbaritem id="menubar-items" align="center"
|
||||
cui-areatype="toolbar">
|
||||
<toolbaritem id="menubar-items" align="center">
|
||||
# The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
|
||||
# hiddenWindow.xul.
|
||||
#include browser-menubar.inc
|
||||
|
@ -601,7 +600,6 @@
|
|||
flex="1"
|
||||
setfocus="false"
|
||||
tooltip="tabbrowser-tab-tooltip"
|
||||
cui-areatype="toolbar"
|
||||
stopwatchid="FX_TAB_CLICK_MS">
|
||||
<tab class="tabbrowser-tab" selected="true" fadein="true"/>
|
||||
</tabs>
|
||||
|
@ -682,12 +680,10 @@
|
|||
<hbox id="nav-bar-customization-target" flex="1">
|
||||
<toolbaritem id="urlbar-container" flex="400" persist="width"
|
||||
title="&locationItem.title;" removable="false"
|
||||
cui-areatype="toolbar"
|
||||
class="chromeclass-location" overflows="false">
|
||||
<toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&backCmd.label;"
|
||||
command="Browser:BackOrBackDuplicate"
|
||||
cui-areatype="toolbar"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
tooltip="back-button-tooltip"
|
||||
context="backForwardMenu"/>
|
||||
|
@ -695,7 +691,6 @@
|
|||
<toolbarbutton id="forward-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&forwardCmd.label;"
|
||||
command="Browser:ForwardOrForwardDuplicate"
|
||||
cui-areatype="toolbar"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
tooltip="forward-button-tooltip"
|
||||
context="backForwardMenu"/>
|
||||
|
@ -798,7 +793,6 @@
|
|||
orient="horizontal"
|
||||
label="&webrtcIndicatorButton.label;"
|
||||
tooltiptext="&webrtcIndicatorButton.tooltip;"
|
||||
cui-areatype="toolbar"
|
||||
overflows="false">
|
||||
<menupopup onpopupshowing="WebrtcIndicator.fillPopup(this);"
|
||||
onpopuphiding="WebrtcIndicator.clearPopup(this);"
|
||||
|
@ -962,17 +956,14 @@
|
|||
|
||||
<toolbarbutton id="nav-bar-overflow-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional overflow-button"
|
||||
cui-areatype="toolbar"
|
||||
skipintoolbarset="true"
|
||||
tooltiptext="&navbarOverflow.label;"/>
|
||||
|
||||
<toolbaritem id="PanelUI-button"
|
||||
class="chromeclass-toolbar-additional"
|
||||
cui-areatype="toolbar"
|
||||
removable="false">
|
||||
<toolbarbutton id="PanelUI-menu-button"
|
||||
class="toolbarbutton-1"
|
||||
cui-areatype="toolbar"
|
||||
consumeanchor="PanelUI-button"
|
||||
label="&brandShortName;"
|
||||
tooltiptext="&appmenu.tooltip;"/>
|
||||
|
@ -989,7 +980,6 @@
|
|||
# Prior to 10.7 there wasn't a native fullscreen button so we use #restore-button
|
||||
# to exit fullscreen and want it to behave like other toolbar buttons.
|
||||
class="toolbarbutton-1"
|
||||
cui-areatype="toolbar"
|
||||
#endif
|
||||
tooltiptext="&fullScreenRestore.tooltip;"
|
||||
oncommand="BrowserFullScreen();"/>
|
||||
|
|
|
@ -857,14 +857,14 @@ nsContextMenu.prototype = {
|
|||
// if the mixedContentChannel is present and the referring URI passes
|
||||
// a same origin check with the target URI, we can preserve the users
|
||||
// decision of disabling MCB on a page for it's child tabs.
|
||||
var persistDisableMCBInChildTab = false;
|
||||
var persistAllowMixedContentInChildTab = false;
|
||||
|
||||
if (this.browser.docShell && this.browser.docShell.mixedContentChannel) {
|
||||
const sm = Services.scriptSecurityManager;
|
||||
try {
|
||||
var targetURI = this.linkURI;
|
||||
sm.checkSameOriginURI(referrerURI, targetURI, false);
|
||||
persistDisableMCBInChildTab = true;
|
||||
persistAllowMixedContentInChildTab = true;
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
|
@ -872,7 +872,7 @@ nsContextMenu.prototype = {
|
|||
openLinkIn(this.linkURL, "tab",
|
||||
{ charset: doc.characterSet,
|
||||
referrerURI: referrerURI,
|
||||
disableMCB: persistDisableMCBInChildTab});
|
||||
allowMixedContent: persistAllowMixedContentInChildTab });
|
||||
},
|
||||
|
||||
// open URL in current tab
|
||||
|
|
|
@ -235,6 +235,7 @@
|
|||
setTimeout(() => {
|
||||
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
}, 0);
|
||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(2);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -330,6 +331,9 @@
|
|||
this.setAttribute("image", uri.spec);
|
||||
}
|
||||
break;
|
||||
case "click":
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(2);
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -338,6 +342,7 @@
|
|||
<handlers>
|
||||
<handler event="popupshowing"><![CDATA[
|
||||
this._anchor.setAttribute("open", "true");
|
||||
this.content.addEventListener("click", this);
|
||||
]]></handler>
|
||||
<handler event="popupshown"><![CDATA[
|
||||
this.onShown();
|
||||
|
@ -346,6 +351,7 @@
|
|||
this.dispatchPanelEvent("socialFrameHide");
|
||||
this._anchor.removeAttribute("open");
|
||||
this.update();
|
||||
this.content.removeEventListener("click", this);
|
||||
]]></handler>
|
||||
<handler event="command"><![CDATA[
|
||||
this.markCurrentPage();
|
||||
|
|
|
@ -1024,7 +1024,7 @@
|
|||
this._appendStatusPanel();
|
||||
|
||||
if (updateBlockedPopups)
|
||||
this.mCurrentBrowser.updateBlockedPopups(false);
|
||||
this.mCurrentBrowser.updateBlockedPopups();
|
||||
|
||||
// Update the URL bar.
|
||||
var loc = this.mCurrentBrowser.currentURI;
|
||||
|
@ -1284,7 +1284,7 @@
|
|||
<![CDATA[
|
||||
var aFromExternal;
|
||||
var aRelatedToCurrent;
|
||||
var aDisableMCB;
|
||||
var aAllowMixedContent;
|
||||
var aSkipAnimation;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
|
@ -1297,7 +1297,7 @@
|
|||
aAllowThirdPartyFixup = params.allowThirdPartyFixup;
|
||||
aFromExternal = params.fromExternal;
|
||||
aRelatedToCurrent = params.relatedToCurrent;
|
||||
aDisableMCB = params.disableMCB;
|
||||
aAllowMixedContent = params.allowMixedContent;
|
||||
aSkipAnimation = params.skipAnimation;
|
||||
}
|
||||
|
||||
|
@ -1313,7 +1313,7 @@
|
|||
fromExternal: aFromExternal,
|
||||
relatedToCurrent: aRelatedToCurrent,
|
||||
skipAnimation: aSkipAnimation,
|
||||
disableMCB: aDisableMCB});
|
||||
allowMixedContent: aAllowMixedContent });
|
||||
if (!bgLoad)
|
||||
this.selectedTab = tab;
|
||||
|
||||
|
@ -1472,7 +1472,7 @@
|
|||
var aFromExternal;
|
||||
var aRelatedToCurrent;
|
||||
var aSkipAnimation;
|
||||
var aDisableMCB;
|
||||
var aAllowMixedContent;
|
||||
if (arguments.length == 2 &&
|
||||
typeof arguments[1] == "object" &&
|
||||
!(arguments[1] instanceof Ci.nsIURI)) {
|
||||
|
@ -1485,7 +1485,7 @@
|
|||
aFromExternal = params.fromExternal;
|
||||
aRelatedToCurrent = params.relatedToCurrent;
|
||||
aSkipAnimation = params.skipAnimation;
|
||||
aDisableMCB = params.disableMCB;
|
||||
aAllowMixedContent = params.allowMixedContent;
|
||||
}
|
||||
|
||||
// if we're adding tabs, we're past interrupt mode, ditch the owner
|
||||
|
@ -1656,7 +1656,7 @@
|
|||
}
|
||||
if (aFromExternal)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
|
||||
if (aDisableMCB)
|
||||
if (aAllowMixedContent)
|
||||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT;
|
||||
try {
|
||||
b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
|
||||
|
|
|
@ -8,7 +8,7 @@ add_task(function* checkIdentityOfAboutSupport() {
|
|||
allowThirdPartyFixup: false,
|
||||
relatedToCurrent: false,
|
||||
skipAnimation: true,
|
||||
disableMCB: false
|
||||
allowMixedContent: false
|
||||
});
|
||||
|
||||
yield promiseTabLoaded(tab);
|
||||
|
|
|
@ -13,7 +13,7 @@ let crash = function() { // this will crash when called.
|
|||
};
|
||||
|
||||
|
||||
TestHelper = {
|
||||
let TestHelper = {
|
||||
init: function() {
|
||||
addMessageListener("social-test:crash", this);
|
||||
},
|
||||
|
|
|
@ -214,7 +214,7 @@ function openLinkIn(url, where, params) {
|
|||
var aCharset = params.charset;
|
||||
var aReferrerURI = params.referrerURI;
|
||||
var aRelatedToCurrent = params.relatedToCurrent;
|
||||
var aDisableMCB = params.disableMCB;
|
||||
var aAllowMixedContent = params.allowMixedContent;
|
||||
var aInBackground = params.inBackground;
|
||||
var aDisallowInheritPrincipal = params.disallowInheritPrincipal;
|
||||
var aInitiatingDoc = params.initiatingDoc;
|
||||
|
@ -337,7 +337,7 @@ function openLinkIn(url, where, params) {
|
|||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
relatedToCurrent: aRelatedToCurrent,
|
||||
skipAnimation: aSkipTabAnimation,
|
||||
disableMCB: aDisableMCB});
|
||||
allowMixedContent: aAllowMixedContent });
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -619,7 +619,6 @@ let CustomizableUIInternal = {
|
|||
container.removeChild(node);
|
||||
}
|
||||
} else {
|
||||
this.setLocationAttributes(currentNode, aArea);
|
||||
node.setAttribute("removable", false);
|
||||
LOG("Adding non-removable widget to placements of " + aArea + ": " +
|
||||
node.id);
|
||||
|
|
|
@ -70,7 +70,6 @@ function updateCombinedWidgetStyle(aNode, aArea, aModifyCloseMenu) {
|
|||
if (aModifyCloseMenu) {
|
||||
attrs.closemenu = inPanel ? "none" : null;
|
||||
}
|
||||
attrs["cui-areatype"] = aArea ? CustomizableUI.getAreaType(aArea) : null;
|
||||
for (let i = 0, l = aNode.childNodes.length; i < l; ++i) {
|
||||
if (aNode.childNodes[i].localName == "separator")
|
||||
continue;
|
||||
|
|
|
@ -113,7 +113,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
"privacy_notice_url": "www.mozilla.org/privacy/"
|
||||
});
|
||||
|
||||
if (!this.state.seenToS) {
|
||||
if (this.state.seenToS == "unseen") {
|
||||
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
|
||||
return React.DOM.p( {className:"terms-service",
|
||||
dangerouslySetInnerHTML:{__html: tosHTML}});
|
||||
|
|
|
@ -113,7 +113,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
"privacy_notice_url": "www.mozilla.org/privacy/"
|
||||
});
|
||||
|
||||
if (!this.state.seenToS) {
|
||||
if (this.state.seenToS == "unseen") {
|
||||
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
|
||||
return <p className="terms-service"
|
||||
dangerouslySetInnerHTML={{__html: tosHTML}}></p>;
|
||||
|
|
|
@ -220,10 +220,6 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.props.model.startSession();
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.listenTo(this.props.model, "session:connected",
|
||||
this.startPublishing);
|
||||
this.listenTo(this.props.model, "session:stream-created",
|
||||
|
@ -232,9 +228,13 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
"session:network-disconnected",
|
||||
"session:ended"].join(" "),
|
||||
this.stopPublishing);
|
||||
|
||||
this.props.model.startSession();
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
// Unregister all local event listeners
|
||||
this.stopListening();
|
||||
this.hangup();
|
||||
},
|
||||
|
||||
|
@ -279,20 +279,19 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
outgoing, this.publisherConfig);
|
||||
|
||||
// Suppress OT GuM custom dialog, see bug 1018875
|
||||
function preventOpeningAccessDialog(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
this.publisher.on("accessDialogOpened", preventOpeningAccessDialog);
|
||||
this.publisher.on("accessDenied", preventOpeningAccessDialog);
|
||||
this.listenTo(this.publisher, "accessDialogOpened accessDenied",
|
||||
function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
this.publisher.on("streamCreated", function(event) {
|
||||
this.listenTo(this.publisher, "streamCreated", function(event) {
|
||||
this.setState({
|
||||
audio: {enabled: event.stream.hasAudio},
|
||||
video: {enabled: event.stream.hasVideo}
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
this.publisher.on("streamDestroyed", function() {
|
||||
this.listenTo(this.publisher, "streamDestroyed", function() {
|
||||
this.setState({
|
||||
audio: {enabled: false},
|
||||
video: {enabled: false}
|
||||
|
@ -322,9 +321,8 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
* Unpublishes local stream.
|
||||
*/
|
||||
stopPublishing: function() {
|
||||
// Unregister access OT GuM custom dialog listeners, see bug 1018875
|
||||
this.publisher.off("accessDialogOpened");
|
||||
this.publisher.off("accessDenied");
|
||||
// Unregister listeners for publisher events
|
||||
this.stopListening(this.publisher);
|
||||
|
||||
this.props.model.session.unpublish(this.publisher);
|
||||
},
|
||||
|
|
|
@ -220,10 +220,6 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.props.model.startSession();
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this.listenTo(this.props.model, "session:connected",
|
||||
this.startPublishing);
|
||||
this.listenTo(this.props.model, "session:stream-created",
|
||||
|
@ -232,9 +228,13 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
"session:network-disconnected",
|
||||
"session:ended"].join(" "),
|
||||
this.stopPublishing);
|
||||
|
||||
this.props.model.startSession();
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
// Unregister all local event listeners
|
||||
this.stopListening();
|
||||
this.hangup();
|
||||
},
|
||||
|
||||
|
@ -279,20 +279,19 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
outgoing, this.publisherConfig);
|
||||
|
||||
// Suppress OT GuM custom dialog, see bug 1018875
|
||||
function preventOpeningAccessDialog(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
this.publisher.on("accessDialogOpened", preventOpeningAccessDialog);
|
||||
this.publisher.on("accessDenied", preventOpeningAccessDialog);
|
||||
this.listenTo(this.publisher, "accessDialogOpened accessDenied",
|
||||
function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
this.publisher.on("streamCreated", function(event) {
|
||||
this.listenTo(this.publisher, "streamCreated", function(event) {
|
||||
this.setState({
|
||||
audio: {enabled: event.stream.hasAudio},
|
||||
video: {enabled: event.stream.hasVideo}
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
this.publisher.on("streamDestroyed", function() {
|
||||
this.listenTo(this.publisher, "streamDestroyed", function() {
|
||||
this.setState({
|
||||
audio: {enabled: false},
|
||||
video: {enabled: false}
|
||||
|
@ -322,9 +321,8 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
* Unpublishes local stream.
|
||||
*/
|
||||
stopPublishing: function() {
|
||||
// Unregister access OT GuM custom dialog listeners, see bug 1018875
|
||||
this.publisher.off("accessDialogOpened");
|
||||
this.publisher.off("accessDenied");
|
||||
// Unregister listeners for publisher events
|
||||
this.stopListening(this.publisher);
|
||||
|
||||
this.props.model.session.unpublish(this.publisher);
|
||||
},
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
# Run from topsrcdir, no args
|
||||
|
||||
set -e
|
||||
|
||||
# Main tests
|
||||
./mach xpcshell-test browser/components/loop/
|
||||
./mach marionette-test browser/components/loop/manifest.ini
|
||||
|
||||
# The browser_parsable_css.js can fail if we add some css that isn't parsable.
|
||||
./mach mochitest browser/components/loop/test/mochitest browser/base/content/test/general/browser_parsable_css.js
|
|
@ -48,7 +48,7 @@ describe("loop.panel", function() {
|
|||
return "en-US";
|
||||
},
|
||||
setLoopCharPref: sandbox.stub(),
|
||||
getLoopCharPref: sandbox.stub()
|
||||
getLoopCharPref: sandbox.stub().returns("unseen")
|
||||
};
|
||||
|
||||
document.mozL10n.initialize(navigator.mozLoop);
|
||||
|
|
|
@ -194,12 +194,10 @@ describe("loop.shared.views", function() {
|
|||
unpublish: sandbox.spy(),
|
||||
subscribe: sandbox.spy()
|
||||
}, Backbone.Events);
|
||||
fakePublisher = {
|
||||
on: sandbox.spy(),
|
||||
off: sandbox.spy(),
|
||||
fakePublisher = _.extend({
|
||||
publishAudio: sandbox.spy(),
|
||||
publishVideo: sandbox.spy()
|
||||
};
|
||||
}, Backbone.Events);
|
||||
fakeSDK = {
|
||||
initPublisher: sandbox.stub().returns(fakePublisher),
|
||||
initSession: sandbox.stub().returns(fakeSession)
|
||||
|
@ -248,6 +246,10 @@ describe("loop.shared.views", function() {
|
|||
});
|
||||
|
||||
describe("#startPublishing", function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(fakePublisher, "on");
|
||||
});
|
||||
|
||||
it("should publish local stream", function() {
|
||||
comp.startPublishing();
|
||||
|
||||
|
@ -261,13 +263,14 @@ describe("loop.shared.views", function() {
|
|||
comp.startPublishing();
|
||||
|
||||
sinon.assert.called(fakePublisher.on);
|
||||
sinon.assert.calledWith(fakePublisher.on, "accessDialogOpened");
|
||||
sinon.assert.calledWith(fakePublisher.on, "accessDenied");
|
||||
sinon.assert.calledWith(fakePublisher.on,
|
||||
"accessDialogOpened accessDenied");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#stopPublishing", function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(fakePublisher, "off");
|
||||
comp.startPublishing();
|
||||
});
|
||||
|
||||
|
@ -277,13 +280,12 @@ describe("loop.shared.views", function() {
|
|||
sinon.assert.calledOnce(fakeSession.unpublish);
|
||||
});
|
||||
|
||||
it("should unsubscribe from accessDialogOpened and accessDenied events",
|
||||
it("should unsubscribe from publisher events",
|
||||
function() {
|
||||
comp.stopPublishing();
|
||||
|
||||
sinon.assert.calledTwice(fakePublisher.off);
|
||||
sinon.assert.calledWith(fakePublisher.off, "accessDialogOpened");
|
||||
sinon.assert.calledWith(fakePublisher.off, "accessDenied");
|
||||
// Note: Backbone.Events#stopListening calls off() on passed object.
|
||||
sinon.assert.calledOnce(fakePublisher.off);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -367,6 +369,35 @@ describe("loop.shared.views", function() {
|
|||
sinon.assert.calledOnce(fakeSession.unpublish);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Publisher events", function() {
|
||||
beforeEach(function() {
|
||||
comp.startPublishing();
|
||||
});
|
||||
|
||||
it("should set audio state on streamCreated", function() {
|
||||
fakePublisher.trigger("streamCreated", {stream: {hasAudio: true}});
|
||||
expect(comp.state.audio.enabled).eql(true);
|
||||
|
||||
fakePublisher.trigger("streamCreated", {stream: {hasAudio: false}});
|
||||
expect(comp.state.audio.enabled).eql(false);
|
||||
});
|
||||
|
||||
it("should set video state on streamCreated", function() {
|
||||
fakePublisher.trigger("streamCreated", {stream: {hasVideo: true}});
|
||||
expect(comp.state.video.enabled).eql(true);
|
||||
|
||||
fakePublisher.trigger("streamCreated", {stream: {hasVideo: false}});
|
||||
expect(comp.state.video.enabled).eql(false);
|
||||
});
|
||||
|
||||
it("should set media state on streamDestroyed", function() {
|
||||
fakePublisher.trigger("streamDestroyed");
|
||||
|
||||
expect(comp.state.audio.enabled).eql(false);
|
||||
expect(comp.state.video.enabled).eql(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ add_task(function() {
|
|||
|
||||
add_task(function () {
|
||||
const FRAME_SCRIPT = "data:," +
|
||||
"docShell.QueryInterface%28Ci.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
|
||||
"docShell.QueryInterface%28Components.interfaces.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
|
||||
|
||||
// Clear the list of closed windows.
|
||||
while (ss.getClosedWindowCount()) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
/**
|
||||
* This frame script is only loaded for sessionstore mochitests. It contains
|
||||
* a bunch of utility functions used to test form data collection and
|
||||
|
|
|
@ -596,8 +596,8 @@ HTMLBreadcrumbs.prototype = {
|
|||
if (this.currentIndex == this.nodeHierarchy.length - 1) {
|
||||
let node = this.nodeHierarchy[this.currentIndex].node;
|
||||
return this.getInterestingFirstNode(node).then(child => {
|
||||
// If the node has a child
|
||||
if (child) {
|
||||
// If the node has a child and we've not been destroyed in the meantime
|
||||
if (child && !this.isDestroyed) {
|
||||
// Show this child
|
||||
this.expand(child);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
doc_markup_edit.html
|
||||
|
@ -19,8 +18,11 @@ support-files =
|
|||
[browser_markupview_copy_image_data.js]
|
||||
[browser_markupview_css_completion_style_attribute.js]
|
||||
[browser_markupview_highlight_hover_01.js]
|
||||
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
|
||||
[browser_markupview_highlight_hover_02.js]
|
||||
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
|
||||
[browser_markupview_highlight_hover_03.js]
|
||||
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
|
||||
[browser_markupview_html_edit_01.js]
|
||||
[browser_markupview_html_edit_02.js]
|
||||
[browser_markupview_html_edit_03.js]
|
||||
|
@ -32,10 +34,12 @@ support-files =
|
|||
[browser_markupview_node_not_displayed_02.js]
|
||||
[browser_markupview_pagesize_01.js]
|
||||
[browser_markupview_pagesize_02.js]
|
||||
skip-if = e10s # Bug 1036409 - The last selected node isn't reselected
|
||||
[browser_markupview_search_01.js]
|
||||
[browser_markupview_tag_edit_01.js]
|
||||
[browser_markupview_tag_edit_02.js]
|
||||
[browser_markupview_tag_edit_03.js]
|
||||
skip-if = e10s # Bug 1036421 - Tag editing isn't remote-safe
|
||||
[browser_markupview_tag_edit_04.js]
|
||||
[browser_markupview_tag_edit_05.js]
|
||||
[browser_markupview_tag_edit_06.js]
|
||||
|
|
|
@ -69,15 +69,16 @@ let test = asyncTest(function*() {
|
|||
|
||||
yield inspector.markup.expandAll();
|
||||
|
||||
let node = getContainerForRawNode("#node14", inspector).editor;
|
||||
let attr = node.newAttr;
|
||||
let nodeFront = yield getNodeFront("#node14", inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
let attr = container.editor.newAttr;
|
||||
attr.focus();
|
||||
EventUtils.sendKey("return", inspector.panelWin);
|
||||
let editor = inplaceEditor(attr);
|
||||
|
||||
for (let i = 0; i < TEST_DATA.length; i ++) {
|
||||
yield enterData(i, editor, inspector);
|
||||
checkData(i, editor, inspector);
|
||||
yield checkData(i, editor, inspector);
|
||||
}
|
||||
|
||||
while (inspector.markup.undo.canUndo()) {
|
||||
|
@ -122,7 +123,7 @@ function enterData(index, editor, inspector) {
|
|||
return def.promise;
|
||||
}
|
||||
|
||||
function checkData(index, editor, inspector) {
|
||||
function* checkData(index, editor, inspector) {
|
||||
let [key, completion, selStart, selEnd, popupOpen] = TEST_DATA[index];
|
||||
info("Test data " + index + " entered. Checking state.");
|
||||
|
||||
|
@ -137,7 +138,8 @@ function checkData(index, editor, inspector) {
|
|||
"Popup is closed");
|
||||
}
|
||||
} else {
|
||||
let editor = getContainerForRawNode("#node14", inspector).editor;
|
||||
let nodeFront = yield getNodeFront("#node14", inspector);
|
||||
let editor = getContainerForNodeFront(nodeFront, inspector).editor;
|
||||
let attr = editor.attrs["style"].querySelector(".editable");
|
||||
is(attr.textContent, completion, "Correct value is persisted after pressing Enter");
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ let test = asyncTest(function*() {
|
|||
let p = getNode("p");
|
||||
|
||||
info("hovering over the <p> line in the markup-view");
|
||||
yield hoverContainer(p, inspector);
|
||||
yield hoverContainer("p", inspector);
|
||||
ok(isHighlighterVisible(), "the highlighter is still visible");
|
||||
|
||||
info("selecting the <p> line by clicking in the markup-view");
|
||||
yield clickContainer(p, inspector);
|
||||
yield clickContainer("p", inspector);
|
||||
|
||||
p.textContent = "wait for it ....";
|
||||
info("wait and see if the highlighter stays visible even after the node was selected");
|
||||
|
|
|
@ -29,13 +29,14 @@ let test = asyncTest(function*() {
|
|||
return promise.resolve();
|
||||
};
|
||||
|
||||
function isHighlighting(node, desc) {
|
||||
is(highlightedNode, getContainerForRawNode(node, inspector).node, desc);
|
||||
function* isHighlighting(selector, desc) {
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
is(highlightedNode, nodeFront, desc);
|
||||
}
|
||||
|
||||
info("Hover over <p#one> line in the markup-view");
|
||||
yield hoverContainer("#one", inspector);
|
||||
isHighlighting(getNode("#one"), "<p#one> is highlighted");
|
||||
yield isHighlighting("#one", "<p#one> is highlighted");
|
||||
|
||||
info("Navigate to <p#two> with the keyboard");
|
||||
let onUpdated = inspector.once("inspector-updated");
|
||||
|
@ -44,11 +45,11 @@ let test = asyncTest(function*() {
|
|||
let onUpdated = inspector.once("inspector-updated");
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
yield onUpdated;
|
||||
isHighlighting(getNode("#two"), "<p#two> is highlighted");
|
||||
yield isHighlighting("#two", "<p#two> is highlighted");
|
||||
|
||||
info("Navigate back to <p#one> with the keyboard");
|
||||
let onUpdated = inspector.once("inspector-updated");
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
yield onUpdated;
|
||||
isHighlighting(getNode("#one"), "<p#one> is highlighted again");
|
||||
yield isHighlighting("#one", "<p#one> is highlighted again");
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ const TEST_DATA = [
|
|||
selector: "#one",
|
||||
oldHTML: '<div id="one">First <em>Div</em></div>',
|
||||
newHTML: '<div id="one">First Div</div>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront) {
|
||||
is(pageNode.textContent, "First Div", "New div has expected text content");
|
||||
ok(!getNode("#one em"), "No em remaining")
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ const TEST_DATA = [
|
|||
selector: "#addedAttribute",
|
||||
oldHTML: '<div id="addedAttribute">addedAttribute</div>',
|
||||
newHTML: '<div id="addedAttribute" class="important" disabled checked>addedAttribute</div>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
is(pageNode.outerHTML, '<div id="addedAttribute" class="important" disabled="" checked="">addedAttribute</div>',
|
||||
"Attributes have been added");
|
||||
}
|
||||
|
@ -49,14 +49,15 @@ const TEST_DATA = [
|
|||
newHTML: '<div id="siblings-before-sibling">before sibling</div>' +
|
||||
'<div id="siblings">siblings (updated)</div>' +
|
||||
'<div id="siblings-after-sibling">after sibling</div>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
let beforeSiblingNode = getNode("#siblings-before-sibling");
|
||||
let afterSiblingNode = getNode("#siblings-after-sibling");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
let beforeSibling = getNode("#siblings-before-sibling");
|
||||
let beforeSiblingFront = yield getNodeFront("#siblings-before-sibling", inspector);
|
||||
let afterSibling = getNode("#siblings-after-sibling");
|
||||
|
||||
is(beforeSiblingNode, selectedNode, "Sibling has been selected");
|
||||
is(beforeSiblingFront, selectedNodeFront, "Sibling has been selected");
|
||||
is(pageNode.textContent, "siblings (updated)", "New div has expected text content");
|
||||
is(beforeSiblingNode.textContent, "before sibling", "Sibling has been inserted");
|
||||
is(afterSiblingNode.textContent, "after sibling", "Sibling has been inserted");
|
||||
is(beforeSibling.textContent, "before sibling", "Sibling has been inserted");
|
||||
is(afterSibling.textContent, "after sibling", "Sibling has been inserted");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -13,8 +13,8 @@ const TEST_DATA = [
|
|||
selector: "#badMarkup1",
|
||||
oldHTML: '<div id="badMarkup1">badMarkup1</div>',
|
||||
newHTML: '<div id="badMarkup1">badMarkup1</div> hanging</div>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
|
||||
let textNode = pageNode.nextSibling;
|
||||
|
||||
|
@ -26,8 +26,8 @@ const TEST_DATA = [
|
|||
selector: "#badMarkup2",
|
||||
oldHTML: '<div id="badMarkup2">badMarkup2</div>',
|
||||
newHTML: '<div id="badMarkup2">badMarkup2</div> hanging<div></div></div></div></body>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
|
||||
let textNode = pageNode.nextSibling;
|
||||
|
||||
|
@ -39,8 +39,8 @@ const TEST_DATA = [
|
|||
selector: "#badMarkup3",
|
||||
oldHTML: '<div id="badMarkup3">badMarkup3</div>',
|
||||
newHTML: '<div id="badMarkup3">badMarkup3 <em>Emphasized <strong> and strong</div>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
|
||||
let em = getNode("#badMarkup3 em");
|
||||
let strong = getNode("#badMarkup3 strong");
|
||||
|
@ -53,8 +53,8 @@ const TEST_DATA = [
|
|||
selector: "#badMarkup4",
|
||||
oldHTML: '<div id="badMarkup4">badMarkup4</div>',
|
||||
newHTML: '<div id="badMarkup4">badMarkup4</p>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
|
||||
let div = getNode("#badMarkup4");
|
||||
let p = getNode("#badMarkup4 p");
|
||||
|
@ -69,8 +69,8 @@ const TEST_DATA = [
|
|||
selector: "#badMarkup5",
|
||||
oldHTML: '<p id="badMarkup5">badMarkup5</p>',
|
||||
newHTML: '<p id="badMarkup5">badMarkup5 <div>with a nested div</div></p>',
|
||||
validate: function(pageNode, selectedNode) {
|
||||
is(pageNode, selectedNode, "Original element is selected");
|
||||
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
|
||||
is(pageNodeFront, selectedNodeFront, "Original element is selected");
|
||||
|
||||
let p = getNode("#badMarkup5");
|
||||
let nodiv = getNode("#badMarkup5 div");
|
||||
|
|
|
@ -46,7 +46,7 @@ function testEscapeCancels(inspector) {
|
|||
let def = promise.defer();
|
||||
let node = getNode(SELECTOR);
|
||||
|
||||
selectNode(node, inspector).then(() => {
|
||||
selectNode(SELECTOR, inspector).then(() => {
|
||||
inspector.markup.htmlEditor.on("popupshown", function onPopupShown() {
|
||||
inspector.markup.htmlEditor.off("popupshown", onPopupShown);
|
||||
|
||||
|
@ -101,80 +101,82 @@ function testF2Commits(inspector) {
|
|||
return def.promise;
|
||||
}
|
||||
|
||||
function testBody(inspector) {
|
||||
function* testBody(inspector) {
|
||||
let body = getNode("body");
|
||||
let bodyHTML = '<body id="updated"><p></p></body>';
|
||||
let bodyFront = inspector.markup.walker.frontForRawNode(body);
|
||||
let bodyFront = yield getNodeFront("body", inspector);
|
||||
let doc = content.document;
|
||||
|
||||
let mutated = inspector.once("markupmutation");
|
||||
inspector.markup.updateNodeOuterHTML(bodyFront, bodyHTML, body.outerHTML);
|
||||
|
||||
return mutated.then(mutations => {
|
||||
is(getNode("body").outerHTML, bodyHTML, "<body> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
return inspector.once("inspector-updated");
|
||||
});
|
||||
let mutations = yield mutated;
|
||||
|
||||
is(getNode("body").outerHTML, bodyHTML, "<body> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
|
||||
yield inspector.once("inspector-updated");
|
||||
}
|
||||
|
||||
function testHead(inspector) {
|
||||
function* testHead(inspector) {
|
||||
let head = getNode("head");
|
||||
let headHTML = '<head id="updated"><title>New Title</title><script>window.foo="bar";</script></head>';
|
||||
let headFront = inspector.markup.walker.frontForRawNode(head);
|
||||
let headFront = yield getNodeFront("head", inspector);
|
||||
let doc = content.document;
|
||||
|
||||
let mutated = inspector.once("markupmutation");
|
||||
inspector.markup.updateNodeOuterHTML(headFront, headHTML, head.outerHTML);
|
||||
|
||||
return mutated.then(mutations => {
|
||||
is(doc.title, "New Title", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.querySelector("head").outerHTML, headHTML, "<head> HTML has been updated");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
return inspector.once("inspector-updated");
|
||||
});
|
||||
let mutations = yield mutated;
|
||||
|
||||
is(doc.title, "New Title", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.querySelector("head").outerHTML, headHTML, "<head> HTML has been updated");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
|
||||
yield inspector.once("inspector-updated");
|
||||
}
|
||||
|
||||
function testDocumentElement(inspector) {
|
||||
function* testDocumentElement(inspector) {
|
||||
let doc = content.document;
|
||||
let docElement = doc.documentElement;
|
||||
let docElementHTML = '<html id="updated" foo="bar"><head><title>Updated from document element</title><script>window.foo="bar";</script></head><body><p>Hello</p></body></html>';
|
||||
let docElementFront = inspector.markup.walker.frontForRawNode(docElement);
|
||||
let docElementFront = yield inspector.markup.walker.documentElement();
|
||||
|
||||
let mutated = inspector.once("markupmutation");
|
||||
inspector.markup.updateNodeOuterHTML(docElementFront, docElementHTML, docElement.outerHTML);
|
||||
|
||||
return mutated.then(mutations => {
|
||||
is(doc.title, "Updated from document element", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.documentElement.id, "updated", "<html> ID has been updated");
|
||||
is(doc.documentElement.className, "", "<html> class has been updated");
|
||||
is(doc.documentElement.getAttribute("foo"), "bar", "<html> attribute has been updated");
|
||||
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
is(doc.body.textContent, "Hello", "document.body.textContent has been updated");
|
||||
});
|
||||
let mutations = yield mutated;
|
||||
|
||||
is(doc.title, "Updated from document element", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.documentElement.id, "updated", "<html> ID has been updated");
|
||||
is(doc.documentElement.className, "", "<html> class has been updated");
|
||||
is(doc.documentElement.getAttribute("foo"), "bar", "<html> attribute has been updated");
|
||||
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
is(doc.body.textContent, "Hello", "document.body.textContent has been updated");
|
||||
}
|
||||
|
||||
function testDocumentElement2(inspector) {
|
||||
function* testDocumentElement2(inspector) {
|
||||
let doc = content.document;
|
||||
let docElement = doc.documentElement;
|
||||
let docElementHTML = '<html class="updated" id="somethingelse"><head><title>Updated again from document element</title><script>window.foo="bar";</script></head><body><p>Hello again</p></body></html>';
|
||||
let docElementFront = inspector.markup.walker.frontForRawNode(docElement);
|
||||
let docElementFront = yield inspector.markup.walker.documentElement();
|
||||
|
||||
let mutated = inspector.once("markupmutation");
|
||||
inspector.markup.updateNodeOuterHTML(docElementFront, docElementHTML, docElement.outerHTML);
|
||||
|
||||
return mutated.then(mutations => {
|
||||
is(doc.title, "Updated again from document element", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.documentElement.id, "somethingelse", "<html> ID has been updated");
|
||||
is(doc.documentElement.className, "updated", "<html> class has been updated");
|
||||
is(doc.documentElement.getAttribute("foo"), null, "<html> attribute has been removed");
|
||||
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
is(doc.body.textContent, "Hello again", "document.body.textContent has been updated");
|
||||
});
|
||||
let mutations = yield mutated;
|
||||
|
||||
is(doc.title, "Updated again from document element", "New title has been added");
|
||||
is(doc.defaultView.foo, undefined, "Script has not been executed");
|
||||
is(doc.documentElement.id, "somethingelse", "<html> ID has been updated");
|
||||
is(doc.documentElement.className, "updated", "<html> class has been updated");
|
||||
is(doc.documentElement.getAttribute("foo"), null, "<html> attribute has been removed");
|
||||
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
|
||||
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
|
||||
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
|
||||
is(doc.body.textContent, "Hello again", "document.body.textContent has been updated");
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ let test = asyncTest(function*() {
|
|||
yield selectNode("img", inspector);
|
||||
|
||||
for (let testNode of TEST_NODES) {
|
||||
let target = getImageTooltipTarget(testNode, inspector);
|
||||
let target = yield getImageTooltipTarget(testNode, inspector);
|
||||
yield assertTooltipShownOn(target, inspector);
|
||||
checkImageTooltip(testNode, inspector);
|
||||
}
|
||||
|
@ -55,11 +55,11 @@ function createPage() {
|
|||
context.fill();
|
||||
}
|
||||
|
||||
function getImageTooltipTarget({selector}, inspector) {
|
||||
let node = getNode(selector);
|
||||
let isImg = node.tagName.toLowerCase() === "img";
|
||||
function* getImageTooltipTarget({selector}, inspector) {
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let isImg = nodeFront.tagName.toLowerCase() === "img";
|
||||
|
||||
let container = getContainerForRawNode(node, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
|
||||
let target = container.editor.tag;
|
||||
if (isImg) {
|
||||
|
@ -68,12 +68,10 @@ function getImageTooltipTarget({selector}, inspector) {
|
|||
return target;
|
||||
}
|
||||
|
||||
function assertTooltipShownOn(element, {markup}) {
|
||||
return Task.spawn(function*() {
|
||||
info("Is the element a valid hover target");
|
||||
let isValid = yield markup.tooltip.isValidHoverTarget(element);
|
||||
ok(isValid, "The element is a valid hover target for the image tooltip");
|
||||
});
|
||||
function* assertTooltipShownOn(element, {markup}) {
|
||||
info("Is the element a valid hover target");
|
||||
let isValid = yield markup.tooltip.isValidHoverTarget(element);
|
||||
ok(isValid, "The element is a valid hover target for the image tooltip");
|
||||
}
|
||||
|
||||
function checkImageTooltip({selector, size}, {markup}) {
|
||||
|
|
|
@ -5,20 +5,25 @@
|
|||
"use strict";
|
||||
|
||||
// Tests that various mutations to the dom update the markup view correctly.
|
||||
// The test for comparing the markup view to the real dom is a bit weird:
|
||||
// - Select the text in the markup view
|
||||
// - Parse that as innerHTML in a document we've created for the purpose.
|
||||
// - Remove extraneous whitespace in that tree
|
||||
// - Compare it to the real dom with isEqualNode.
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_markup_mutation.html";
|
||||
// All the mutation types we want to test.
|
||||
|
||||
// Mutation tests. Each entry in the array has the following properties:
|
||||
// - desc: for logging only
|
||||
// - test: a function supposed to mutate the DOM
|
||||
// - check: a function supposed to test that the mutation was handled
|
||||
const TEST_DATA = [
|
||||
{
|
||||
desc: "Adding an attribute",
|
||||
test: () => {
|
||||
let node1 = getNode("#node1");
|
||||
node1.setAttribute("newattr", "newattrval");
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let {editor} = yield getContainerForSelector("#node1", inspector);
|
||||
ok([...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
|
||||
return attr.textContent.trim() === "newattr=\"newattrval\"";
|
||||
}), "newattr attribute found");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -26,6 +31,15 @@ const TEST_DATA = [
|
|||
test: () => {
|
||||
let node1 = getNode("#node1");
|
||||
node1.removeAttribute("newattr");
|
||||
},
|
||||
check: function*(inspector) {
|
||||
// The markup-view is a little weird in that it doesn't remove the
|
||||
// attribute but only hides it with display:none
|
||||
let {editor} = yield getContainerForSelector("#node1", inspector);
|
||||
ok([...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
|
||||
return attr.textContent.trim() === "newattr=\"newattrval\"" &&
|
||||
attr.style.display === "none";
|
||||
}), "newattr attribute removed");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -33,6 +47,11 @@ const TEST_DATA = [
|
|||
test: () => {
|
||||
let node1 = getNode("#node1");
|
||||
node1.textContent = "newtext";
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let {children} = yield getContainerForSelector("#node1", inspector);
|
||||
is(children.querySelector(".text").textContent.trim(), "newtext",
|
||||
"The new textcontent was updated");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -40,6 +59,17 @@ const TEST_DATA = [
|
|||
test: () => {
|
||||
let node2 = getNode("#node2");
|
||||
node2.innerHTML = "<div><span>foo</span></div>";
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let container = yield getContainerForSelector("#node2", inspector);
|
||||
|
||||
let openTags = container.children.querySelectorAll(".open .tag");
|
||||
is(openTags.length, 2, "There are 2 tags in node2");
|
||||
is(openTags[0].textContent.trim(), "div", "The first tag is a div");
|
||||
is(openTags[1].textContent.trim(), "span", "The second tag is a span");
|
||||
|
||||
is(container.children.querySelector(".text").textContent.trim(), "foo",
|
||||
"The span's textcontent is correct");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -49,14 +79,27 @@ const TEST_DATA = [
|
|||
while (node4.firstChild) {
|
||||
node4.removeChild(node4.firstChild);
|
||||
}
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let {children} = yield getContainerForSelector("#node4", inspector);
|
||||
is(children.innerHTML, "", "Children have been removed");
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: "Appending a child to a different parent",
|
||||
test: () => {
|
||||
let node17 = getNode("#node17");
|
||||
let node1 = getNode("#node2");
|
||||
node1.appendChild(node17);
|
||||
let node2 = getNode("#node2");
|
||||
node2.appendChild(node17);
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let {children} = yield getContainerForSelector("#node16", inspector);
|
||||
is(children.innerHTML, "", "Node17 has been removed from its node16 parent");
|
||||
|
||||
let container = yield getContainerForSelector("#node2", inspector);
|
||||
let openTags = container.children.querySelectorAll(".open .tag");
|
||||
is(openTags.length, 3, "There are now 3 tags in node2");
|
||||
is(openTags[2].textContent.trim(), "p", "The third tag is node17");
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -82,73 +125,46 @@ const TEST_DATA = [
|
|||
|
||||
node1.appendChild(node20);
|
||||
node20.appendChild(node18);
|
||||
},
|
||||
check: function*(inspector) {
|
||||
let {children} = yield getContainerForSelector("#node1", inspector);
|
||||
is(children.childNodes.length, 2,
|
||||
"Node1 now has 2 children (textnode and node20)");
|
||||
|
||||
let node20 = children.childNodes[1];
|
||||
let node20Children = node20.querySelector(".children")
|
||||
is(node20Children.childNodes.length, 2, "Node20 has 2 children (21 and 18)");
|
||||
|
||||
let node21 = node20Children.childNodes[0];
|
||||
is(node21.querySelector(".children").textContent.trim(), "line21",
|
||||
"Node21 only has a text node child");
|
||||
|
||||
let node18 = node20Children.childNodes[1];
|
||||
is(node18.querySelector(".open .attreditor .attr-value").textContent.trim(),
|
||||
"node18", "Node20's second child is indeed node18");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
info("Creating the helper tab for parsing");
|
||||
let parseTab = yield addTab("data:text/html,<html></html>");
|
||||
let parseDoc = content.document;
|
||||
|
||||
info("Creating the test tab");
|
||||
let contentTab = yield addTab(TEST_URL);
|
||||
let doc = content.document;
|
||||
// Strip whitespace in the document for easier comparison
|
||||
stripWhitespace(doc.documentElement);
|
||||
|
||||
let {inspector} = yield openInspector();
|
||||
let markup = inspector.markup;
|
||||
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Expanding all markup-view nodes");
|
||||
yield markup.expandAll();
|
||||
yield inspector.markup.expandAll();
|
||||
|
||||
for (let step of TEST_DATA) {
|
||||
info("Starting test: " + step.desc);
|
||||
for (let {desc, test, check} of TEST_DATA) {
|
||||
info("Starting test: " + desc);
|
||||
|
||||
info("Executing the test markup mutation, listening for inspector-updated before moving on");
|
||||
let updated = inspector.once("inspector-updated");
|
||||
step.test();
|
||||
yield updated;
|
||||
info("Executing the test markup mutation");
|
||||
let onUpdated = inspector.once("inspector-updated");
|
||||
let onMutation = inspector.once("markupmutation");
|
||||
test();
|
||||
yield onUpdated.then(onMutation);
|
||||
|
||||
info("Expanding all markup-view nodes to make sure new nodes are imported");
|
||||
yield markup.expandAll();
|
||||
yield inspector.markup.expandAll();
|
||||
|
||||
info("Comparing the markup-view markup with the content document");
|
||||
compareMarkup(parseDoc, inspector);
|
||||
info("Checking the markup-view content");
|
||||
yield check(inspector);
|
||||
}
|
||||
});
|
||||
|
||||
function stripWhitespace(node) {
|
||||
node.normalize();
|
||||
let iter = node.ownerDocument.createNodeIterator(node,
|
||||
NodeFilter.SHOW_TEXT + NodeFilter.SHOW_COMMENT, null);
|
||||
|
||||
while ((node = iter.nextNode())) {
|
||||
node.nodeValue = node.nodeValue.replace(/\s+/g, '');
|
||||
if (node.nodeType == Node.TEXT_NODE &&
|
||||
!/[^\s]/.exec(node.nodeValue)) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compareMarkup(parseDoc, inspector) {
|
||||
// Grab the text from the markup panel...
|
||||
let markupContainerEl = getContainerForRawNode("body", inspector).elt;
|
||||
let sel = markupContainerEl.ownerDocument.defaultView.getSelection();
|
||||
sel.selectAllChildren(markupContainerEl);
|
||||
|
||||
// Parse it
|
||||
let parseNode = parseDoc.querySelector("body");
|
||||
parseNode.outerHTML = sel;
|
||||
parseNode = parseDoc.querySelector("body");
|
||||
|
||||
// Pull whitespace out of text and comment nodes, there will
|
||||
// be minor unimportant differences.
|
||||
stripWhitespace(parseNode);
|
||||
|
||||
// console.log(contentNode.innerHTML, parseNode.innerHTML);
|
||||
ok(getNode("body").isEqualNode(parseNode),
|
||||
"Markup panel matches what's in the content document.");
|
||||
}
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
// corresponding DOM nodes mutate
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_markup_flashing.html";
|
||||
|
||||
// The test data contains a list of mutations to test.
|
||||
// Each item is an object:
|
||||
// - desc: a description of the test step, for better logging
|
||||
// - mutate: a function that should make changes to the content DOM
|
||||
// - shouldFlash: a function that returns the element that should be the one flashing
|
||||
// - flashedNode: [optional] the css selector of the node that is expected to
|
||||
// flash in the markup-view as a result of the mutation.
|
||||
// If missing, the rootNode (".list") will be expected to flash
|
||||
const TEST_DATA = [{
|
||||
desc: "Adding a new node should flash the new node",
|
||||
mutate: (doc, rootNode) => {
|
||||
|
@ -20,37 +23,33 @@ const TEST_DATA = [{
|
|||
newLi.textContent = "new list item";
|
||||
rootNode.appendChild(newLi);
|
||||
},
|
||||
shouldFlash: rootNode => rootNode.lastElementChild
|
||||
flashedNode: ".list li:nth-child(3)"
|
||||
}, {
|
||||
desc: "Removing a node should flash its parent",
|
||||
mutate: (doc, rootNode) => {
|
||||
rootNode.removeChild(rootNode.lastElementChild);
|
||||
},
|
||||
shouldFlash: rootNode => rootNode
|
||||
}
|
||||
}, {
|
||||
desc: "Re-appending an existing node should only flash this node",
|
||||
mutate: (doc, rootNode) => {
|
||||
rootNode.appendChild(rootNode.firstElementChild);
|
||||
},
|
||||
shouldFlash: rootNode => rootNode.lastElementChild
|
||||
flashedNode: ".list .item:last-child"
|
||||
}, {
|
||||
desc: "Adding an attribute should flash the node",
|
||||
mutate: (doc, rootNode) => {
|
||||
rootNode.setAttribute("name-" + Date.now(), "value-" + Date.now());
|
||||
},
|
||||
shouldFlash: rootNode => rootNode
|
||||
}
|
||||
}, {
|
||||
desc: "Editing an attribute should flash the node",
|
||||
mutate: (doc, rootNode) => {
|
||||
rootNode.setAttribute("class", "list value-" + Date.now());
|
||||
},
|
||||
shouldFlash: rootNode => rootNode
|
||||
}
|
||||
}, {
|
||||
desc: "Removing an attribute should flash the node",
|
||||
mutate: (doc, rootNode) => {
|
||||
rootNode.removeAttribute("class");
|
||||
},
|
||||
shouldFlash: rootNode => rootNode
|
||||
}
|
||||
}];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
|
@ -58,11 +57,12 @@ let test = asyncTest(function*() {
|
|||
|
||||
info("Getting the <ul.list> root node to test mutations on");
|
||||
let rootNode = getNode(".list");
|
||||
let rootNodeFront = yield getNodeFront(".list", inspector);
|
||||
|
||||
info("Selecting the last element of the root node before starting");
|
||||
yield selectNode(rootNode.lastElementChild, inspector);
|
||||
yield selectNode(".list .item:nth-child(2)", inspector);
|
||||
|
||||
for (let {mutate, shouldFlash, desc} of TEST_DATA) {
|
||||
for (let {mutate, flashedNode, desc} of TEST_DATA) {
|
||||
info("Starting test: " + desc);
|
||||
|
||||
info("Mutating the DOM and listening for markupmutation event");
|
||||
|
@ -72,20 +72,20 @@ let test = asyncTest(function*() {
|
|||
yield mutated;
|
||||
|
||||
info("Asserting that the correct markup-container is flashing");
|
||||
assertNodeFlashing(shouldFlash(rootNode), inspector);
|
||||
let flashingNodeFront = rootNodeFront;
|
||||
if (flashedNode) {
|
||||
flashingNodeFront = yield getNodeFront(flashedNode, inspector);
|
||||
}
|
||||
yield assertNodeFlashing(flashingNodeFront, inspector);
|
||||
|
||||
// Making sure the inspector has finished updating before moving on
|
||||
yield updated;
|
||||
}
|
||||
});
|
||||
|
||||
function assertNodeFlashing(node, inspector) {
|
||||
let container = getContainerForRawNode(node, inspector);
|
||||
|
||||
if (!container) {
|
||||
ok(false, "Node not found");
|
||||
} else {
|
||||
ok(container.tagState.classList.contains("theme-bg-contrast"),
|
||||
"Node is flashing");
|
||||
}
|
||||
function* assertNodeFlashing(nodeFront, inspector) {
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
ok(container, "Markup container for node found");
|
||||
ok(container.tagState.classList.contains("theme-bg-contrast"),
|
||||
"Markup container for node is flashing");
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ function pressKey(key) {
|
|||
}
|
||||
|
||||
function checkSelectedNode(key, className, inspector) {
|
||||
let node = inspector.selection.node;
|
||||
let node = inspector.selection.nodeFront;
|
||||
|
||||
if (className == "*comment*") {
|
||||
is(node.nodeType, Node.COMMENT_NODE, "Found a comment after pressing " + key);
|
||||
|
|
|
@ -26,7 +26,8 @@ let test = asyncTest(function*() {
|
|||
|
||||
for (let {selector, isDisplayed} of TEST_DATA) {
|
||||
info("Getting node " + selector);
|
||||
let container = getContainerForRawNode(selector, inspector);
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
is(!container.elt.classList.contains("not-displayed"), isDisplayed,
|
||||
"The container for " + selector + " is marked as displayed " + isDisplayed);
|
||||
}
|
||||
|
|
|
@ -98,35 +98,33 @@ let test = asyncTest(function*() {
|
|||
}
|
||||
});
|
||||
|
||||
function runTestData(inspector, {selector, before, changeStyle, after}) {
|
||||
let def = promise.defer();
|
||||
|
||||
function* runTestData(inspector, {selector, before, changeStyle, after}) {
|
||||
info("Getting the " + selector + " test node");
|
||||
let container = getContainerForRawNode(selector, inspector);
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
is(!container.elt.classList.contains("not-displayed"), before,
|
||||
"The container is marked as " + (before ? "shown" : "hidden"));
|
||||
|
||||
info("Listening for the display-change event");
|
||||
inspector.markup.walker.once("display-change", nodes => {
|
||||
info("Verifying that the list of changed nodes include our container");
|
||||
|
||||
ok(nodes.length, "The display-change event was received with a nodes");
|
||||
let foundContainer = false;
|
||||
for (let node of nodes) {
|
||||
if (inspector.markup.getContainer(node) === container) {
|
||||
foundContainer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(foundContainer, "Container is part of the list of changed nodes");
|
||||
|
||||
is(!container.elt.classList.contains("not-displayed"), after,
|
||||
"The container is marked as " + (after ? "shown" : "hidden"));
|
||||
def.resolve();
|
||||
});
|
||||
let onDisplayChanged = promise.defer();
|
||||
inspector.markup.walker.once("display-change", onDisplayChanged.resolve);
|
||||
|
||||
info("Making style changes");
|
||||
changeStyle(content.document, getNode(selector));
|
||||
let nodes = yield onDisplayChanged.promise;
|
||||
|
||||
return def.promise;
|
||||
info("Verifying that the list of changed nodes include our container");
|
||||
|
||||
ok(nodes.length, "The display-change event was received with a nodes");
|
||||
let foundContainer = false;
|
||||
for (let node of nodes) {
|
||||
if (getContainerForNodeFront(node, inspector) === container) {
|
||||
foundContainer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(foundContainer, "Container is part of the list of changed nodes");
|
||||
|
||||
is(!container.elt.classList.contains("not-displayed"), after,
|
||||
"The container is marked as " + (after ? "shown" : "hidden"));
|
||||
}
|
||||
|
|
|
@ -45,23 +45,23 @@ let test = asyncTest(function*() {
|
|||
info("Start test: " + step.desc);
|
||||
|
||||
if (step.forceReload) {
|
||||
forceReload(inspector);
|
||||
yield forceReload(inspector);
|
||||
}
|
||||
info("Selecting the node that corresponds to " + step.selector);
|
||||
yield selectNode(step.selector, inspector);
|
||||
|
||||
info("Checking that the right nodes are shwon");
|
||||
assertChildren(step.expected, inspector);
|
||||
yield assertChildren(step.expected, inspector);
|
||||
}
|
||||
|
||||
info("Checking that clicking the more button loads everything");
|
||||
clickShowMoreNodes(inspector);
|
||||
yield clickShowMoreNodes(inspector);
|
||||
yield inspector.markup._waitForChildren();
|
||||
assertChildren("abcdefghijklmnopqrstuvwxyz", inspector);
|
||||
yield assertChildren("abcdefghijklmnopqrstuvwxyz", inspector);
|
||||
});
|
||||
|
||||
function assertChildren(expected, inspector) {
|
||||
let container = getContainerForRawNode("body", inspector);
|
||||
function* assertChildren(expected, inspector) {
|
||||
let container = yield getContainerForSelector("body", inspector);
|
||||
let found = "";
|
||||
for (let child of container.children.children) {
|
||||
if (child.classList.contains("more-nodes")) {
|
||||
|
@ -73,13 +73,13 @@ function assertChildren(expected, inspector) {
|
|||
is(found, expected, "Got the expected children.");
|
||||
}
|
||||
|
||||
function forceReload(inspector) {
|
||||
let container = getContainerForRawNode("body", inspector);
|
||||
function* forceReload(inspector) {
|
||||
let container = yield getContainerForSelector("body", inspector);
|
||||
container.childrenDirty = true;
|
||||
}
|
||||
|
||||
function clickShowMoreNodes(inspector) {
|
||||
let container = getContainerForRawNode("body", inspector);
|
||||
function* clickShowMoreNodes(inspector) {
|
||||
let container = yield getContainerForSelector("body", inspector);
|
||||
let button = container.elt.querySelector("button");
|
||||
let win = button.ownerDocument.defaultView;
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, win);
|
||||
|
|
|
@ -25,22 +25,21 @@ let test = asyncTest(function*() {
|
|||
info("Click on the 'show all nodes' button in the UL's list of children");
|
||||
yield showAllNodes(inspector);
|
||||
|
||||
assertAllNodesAreVisible(inspector);
|
||||
yield assertAllNodesAreVisible(inspector);
|
||||
});
|
||||
|
||||
function showAllNodes(inspector) {
|
||||
let container = getContainerForRawNode("ul", inspector);
|
||||
function* showAllNodes(inspector) {
|
||||
let container = yield getContainerForSelector("ul", inspector);
|
||||
let button = container.elt.querySelector("button");
|
||||
ok(button, "All nodes button is here");
|
||||
let win = button.ownerDocument.defaultView;
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, win);
|
||||
return inspector.markup._waitForChildren();
|
||||
yield inspector.markup._waitForChildren();
|
||||
}
|
||||
|
||||
function assertAllNodesAreVisible(inspector) {
|
||||
let ul = getNode("ul");
|
||||
let container = getContainerForRawNode(ul, inspector);
|
||||
function* assertAllNodesAreVisible(inspector) {
|
||||
let container = yield getContainerForSelector("ul", inspector);
|
||||
ok(!container.elt.querySelector("button"), "All nodes button isn't here anymore");
|
||||
is(container.children.childNodes.length, ul.children.length);
|
||||
is(container.children.childNodes.length, getNode("ul").children.length);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ const TEST_URL = TEST_URL_ROOT + "doc_markup_search.html";
|
|||
let test = asyncTest(function*() {
|
||||
let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
ok(!getContainerForRawNode("em", inspector),
|
||||
"The <em> tag isn't present yet in the markup-view");
|
||||
let container = yield getContainerForSelector("em", inspector);
|
||||
ok(!container, "The <em> tag isn't present yet in the markup-view");
|
||||
|
||||
// Searching for the innermost element first makes sure that the inspector
|
||||
// back-end is able to attach the resulting node to the tree it knows at the
|
||||
|
@ -25,9 +25,11 @@ let test = asyncTest(function*() {
|
|||
searchUsingSelectorSearch("em", inspector);
|
||||
yield updated;
|
||||
|
||||
ok(getContainerForRawNode("em", inspector),
|
||||
"The <em> tag is now imported in the markup-view");
|
||||
is(inspector.selection.node, getNode("em"),
|
||||
container = yield getContainerForSelector("em", inspector);
|
||||
ok(container, "The <em> tag is now imported in the markup-view");
|
||||
|
||||
let nodeFront = yield getNodeFront("em", inspector);
|
||||
is(inspector.selection.nodeFront, nodeFront,
|
||||
"The <em> tag is the currently selected node");
|
||||
|
||||
info("searching for other nodes too");
|
||||
|
@ -35,7 +37,9 @@ let test = asyncTest(function*() {
|
|||
let updated = inspector.once("inspector-updated");
|
||||
searchUsingSelectorSearch(node, inspector);
|
||||
yield updated;
|
||||
is(inspector.selection.node, getNode(node),
|
||||
|
||||
nodeFront = yield getNodeFront(node, inspector);
|
||||
is(inspector.selection.nodeFront, nodeFront,
|
||||
"The <" + node + "> tag is the currently selected node");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -13,16 +13,15 @@ let test = asyncTest(function*() {
|
|||
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Selecting the test node");
|
||||
let node = content.document.getElementById("test-div");
|
||||
yield selectNode(node, inspector);
|
||||
yield selectNode("#test-div", inspector);
|
||||
|
||||
info("Verify attributes, only ID should be there for now");
|
||||
assertAttributes(node, {
|
||||
assertAttributes("#test-div", {
|
||||
id: "test-div"
|
||||
});
|
||||
|
||||
info("Focus the ID attribute and change its content");
|
||||
let editor = getContainerForRawNode(node, inspector).editor;
|
||||
let {editor} = yield getContainerForSelector("#test-div", inspector);
|
||||
let attr = editor.attrs["id"].querySelector(".editable");
|
||||
let mutated = inspector.once("markupmutation");
|
||||
setEditableFieldValue(attr,
|
||||
|
@ -30,7 +29,7 @@ let test = asyncTest(function*() {
|
|||
yield mutated;
|
||||
|
||||
info("Verify attributes, should have ID, class and style");
|
||||
assertAttributes(node, {
|
||||
assertAttributes("#test-div", {
|
||||
id: "test-div",
|
||||
class: "newclass",
|
||||
style: "color:green"
|
||||
|
@ -38,7 +37,7 @@ let test = asyncTest(function*() {
|
|||
|
||||
info("Trying to undo the change");
|
||||
yield undoChange(inspector);
|
||||
assertAttributes(node, {
|
||||
assertAttributes("#test-div", {
|
||||
id: "test-div"
|
||||
});
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ let test = asyncTest(function*() {
|
|||
yield inspector.markup.expandAll();
|
||||
|
||||
info("Selecting the test node");
|
||||
let node = content.document.getElementById("retag-me");
|
||||
let node = content.document.querySelector("#retag-me");
|
||||
let child = content.document.querySelector("#retag-me-2");
|
||||
yield selectNode(node, inspector);
|
||||
yield selectNode("#retag-me", inspector);
|
||||
|
||||
let container = getContainerForRawNode(node, inspector);
|
||||
let container = yield getContainerForSelector("#retag-me", inspector);
|
||||
is(node.tagName, "DIV", "We've got #retag-me element, it's a DIV");
|
||||
ok(container.expanded, "It is expanded");
|
||||
is(child.parentNode, node, "Child #retag-me-2 is inside #retag-me");
|
||||
|
@ -30,8 +30,8 @@ let test = asyncTest(function*() {
|
|||
yield mutated;
|
||||
|
||||
info("Checking that the tagname change was done");
|
||||
let node = content.document.getElementById("retag-me");
|
||||
let container = getContainerForRawNode(node, inspector);
|
||||
let node = content.document.querySelector("#retag-me");
|
||||
let container = yield getContainerForSelector("#retag-me", inspector);
|
||||
is(node.tagName, "P", "We've got #retag-me, it should now be a P");
|
||||
ok(container.expanded, "It is still expanded");
|
||||
ok(container.selected, "It is still selected");
|
||||
|
|
|
@ -12,8 +12,8 @@ let test = asyncTest(function*() {
|
|||
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Selecting the test node by clicking on it to make sure it receives focus");
|
||||
let node = content.document.getElementById("delete-me");
|
||||
yield clickContainer(node, inspector);
|
||||
let node = content.document.querySelector("#delete-me");
|
||||
yield clickContainer("#delete-me", inspector);
|
||||
|
||||
info("Deleting the element with the keyboard");
|
||||
let mutated = inspector.once("markupmutation");
|
||||
|
@ -21,10 +21,10 @@ let test = asyncTest(function*() {
|
|||
yield mutated;
|
||||
|
||||
info("Checking that it's gone, baby gone!");
|
||||
ok(!content.document.getElementById("delete-me"), "The test node does not exist");
|
||||
ok(!content.document.querySelector("#delete-me"), "The test node does not exist");
|
||||
|
||||
yield undoChange(inspector);
|
||||
ok(content.document.getElementById("delete-me"), "The test node is back!");
|
||||
ok(content.document.querySelector("#delete-me"), "The test node is back!");
|
||||
|
||||
yield inspector.once("inspector-updated");
|
||||
});
|
||||
|
|
|
@ -36,7 +36,7 @@ function* testCollapsedLongAttribute(inspector) {
|
|||
"data-long": LONG_ATTRIBUTE
|
||||
});
|
||||
|
||||
let editor = getContainerForRawNode("#node24", inspector).editor;
|
||||
let {editor} = yield getContainerForSelector("#node24", inspector);
|
||||
let attr = editor.attrs["data-long"].querySelector(".editable");
|
||||
|
||||
// Check to make sure it has expanded after focus
|
||||
|
@ -69,7 +69,7 @@ function* testModifyInlineStyleWithQuotes(inspector) {
|
|||
});
|
||||
|
||||
let onMutated = inspector.once("markupmutation");
|
||||
let editor = getContainerForRawNode("#node26", inspector).editor;
|
||||
let {editor} = yield getContainerForSelector("#node26", inspector);
|
||||
let attr = editor.attrs["style"].querySelector(".editable");
|
||||
|
||||
attr.focus();
|
||||
|
@ -105,7 +105,7 @@ function* testEditingAttributeWithMixedQuotes(inspector) {
|
|||
});
|
||||
|
||||
let onMutated = inspector.once("markupmutation");
|
||||
let editor = getContainerForRawNode("#node27", inspector).editor;
|
||||
let {editor} = yield getContainerForSelector("#node27", inspector);
|
||||
let attr = editor.attrs["class"].querySelector(".editable");
|
||||
|
||||
attr.focus();
|
||||
|
|
|
@ -13,6 +13,7 @@ let test = asyncTest(function*() {
|
|||
|
||||
info("Expanding all nodes");
|
||||
yield inspector.markup.expandAll();
|
||||
yield waitForMultipleChildrenUpdates(inspector);
|
||||
|
||||
let node = getNode(".node6").firstChild;
|
||||
is(node.nodeValue, "line6", "The test node's text content is correct");
|
||||
|
@ -21,8 +22,8 @@ let test = asyncTest(function*() {
|
|||
|
||||
info("Listening to the markupmutation event");
|
||||
let onMutated = inspector.once("markupmutation");
|
||||
let editor = getContainerForRawNode(node, inspector).editor;
|
||||
let field = editor.elt.querySelector("pre");
|
||||
let container = yield getContainerForSelector(".node6", inspector);
|
||||
let field = container.elt.querySelector("pre");
|
||||
setEditableFieldValue(field, "New text", inspector);
|
||||
yield onMutated;
|
||||
|
||||
|
@ -30,3 +31,15 @@ let test = asyncTest(function*() {
|
|||
|
||||
yield inspector.once("inspector-updated");
|
||||
});
|
||||
|
||||
// The expand all operation of the markup-view calls itself recursively and
|
||||
// there's not one event we can wait for to know when it's done
|
||||
function* waitForMultipleChildrenUpdates(inspector) {
|
||||
// As long as child updates are queued up while we wait for an update already
|
||||
// wait again
|
||||
if (inspector.markup._queuedChildUpdates &&
|
||||
inspector.markup._queuedChildUpdates.size) {
|
||||
yield waitForChildrenUpdated(inspector);
|
||||
return yield waitForMultipleChildrenUpdates(inspector);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ let test = asyncTest(function*() {
|
|||
let {inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Getting the container for the UL parent element");
|
||||
let container = getContainerForRawNode("ul", inspector);
|
||||
let container = yield getContainerForSelector("ul", inspector);
|
||||
|
||||
info("Clicking on the UL parent expander, and waiting for children");
|
||||
let onChildren = waitForChildrenUpdated(inspector);
|
||||
|
@ -23,9 +23,10 @@ let test = asyncTest(function*() {
|
|||
yield onUpdated;
|
||||
|
||||
info("Checking that child LI elements have been created");
|
||||
for (let li of content.document.querySelectorAll("li")) {
|
||||
ok(getContainerForRawNode(li, inspector),
|
||||
"A container for the child LI element was created");
|
||||
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
|
||||
let liContainer = yield getContainerForSelector(
|
||||
"li:nth-child(" + (i + 1) + ")", inspector);
|
||||
ok(liContainer, "A container for the child LI element was created");
|
||||
}
|
||||
ok(container.expanded, "Parent UL container is expanded");
|
||||
|
||||
|
@ -36,8 +37,9 @@ let test = asyncTest(function*() {
|
|||
inspector.markup.doc.defaultView);
|
||||
|
||||
info("Checking that child LI elements have been hidden");
|
||||
for (let li of content.document.querySelectorAll("li")) {
|
||||
let liContainer = getContainerForRawNode(li, inspector);
|
||||
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
|
||||
let liContainer = yield getContainerForSelector(
|
||||
"li:nth-child(" + (i + 1) + ")", inspector);
|
||||
is(liContainer.elt.getClientRects().length, 0,
|
||||
"The container for the child LI element was hidden");
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ let test = asyncTest(function*() {
|
|||
let {inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Getting the container for the UL parent element");
|
||||
let container = getContainerForRawNode("ul", inspector);
|
||||
let container = yield getContainerForSelector("ul", inspector);
|
||||
|
||||
info("Dbl-clicking on the UL parent expander, and waiting for children");
|
||||
let onChildren = waitForChildrenUpdated(inspector);
|
||||
|
@ -23,9 +23,10 @@ let test = asyncTest(function*() {
|
|||
yield onUpdated;
|
||||
|
||||
info("Checking that child LI elements have been created");
|
||||
for (let li of content.document.querySelectorAll("li")) {
|
||||
ok(getContainerForRawNode(li, inspector),
|
||||
"A container for the child LI element was created");
|
||||
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
|
||||
let liContainer = yield getContainerForSelector(
|
||||
"li:nth-child(" + (i + 1) + ")", inspector);
|
||||
ok(liContainer, "A container for the child LI element was created");
|
||||
}
|
||||
ok(container.expanded, "Parent UL container is expanded");
|
||||
|
||||
|
@ -36,8 +37,9 @@ let test = asyncTest(function*() {
|
|||
inspector.markup.doc.defaultView);
|
||||
|
||||
info("Checking that child LI elements have been hidden");
|
||||
for (let li of content.document.querySelectorAll("li")) {
|
||||
let liContainer = getContainerForRawNode(li, inspector);
|
||||
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
|
||||
let liContainer = yield getContainerForSelector(
|
||||
"li:nth-child(" + (i + 1) + ")", inspector);
|
||||
is(liContainer.elt.getClientRects().length, 0,
|
||||
"The container for the child LI element was hidden");
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ let test = asyncTest(function*() {
|
|||
let {inspector} = yield addTab(TEST_URL).then(openInspector);
|
||||
|
||||
info("Getting the container for the UL parent element");
|
||||
let container = getContainerForRawNode("ul", inspector);
|
||||
let container = yield getContainerForSelector("ul", inspector);
|
||||
|
||||
info("Alt-clicking on the UL parent expander, and waiting for children");
|
||||
let onUpdated = inspector.once("inspector-updated");
|
||||
|
@ -23,11 +23,14 @@ let test = asyncTest(function*() {
|
|||
yield waitForMultipleChildrenUpdates(inspector);
|
||||
|
||||
info("Checking that all nodes exist and are expanded");
|
||||
for (let node of content.document.querySelectorAll("ul, li, span, em")) {
|
||||
let nodeContainer = getContainerForRawNode(node, inspector);
|
||||
ok(nodeContainer, "Container for node " + node.tagName + " exists");
|
||||
let nodeList = yield inspector.walker.querySelectorAll(
|
||||
inspector.walker.rootNode, "ul, li, span, em");
|
||||
let nodeFronts = yield nodeList.items();
|
||||
for (let nodeFront of nodeFronts) {
|
||||
let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
|
||||
ok(nodeContainer, "Container for node " + nodeFront.tagName + " exists");
|
||||
ok(nodeContainer.expanded,
|
||||
"Container for node " + node.tagName + " is expanded");
|
||||
"Container for node " + nodeFront.tagName + " is expanded");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -28,19 +28,17 @@ registerCleanupFunction(() => {
|
|||
});
|
||||
|
||||
// Auto close the toolbox and close the test tabs when the test ends
|
||||
registerCleanupFunction(() => {
|
||||
try {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
} catch (ex) {
|
||||
dump(ex);
|
||||
}
|
||||
registerCleanupFunction(function*() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
});
|
||||
|
||||
const TEST_URL_ROOT = "http://mochi.test:8888/browser/browser/devtools/markupview/test/";
|
||||
const CHROME_BASE = "chrome://mochitests/content/browser/browser/devtools/markupview/test/";
|
||||
|
||||
/**
|
||||
* Define an async test based on a generator function
|
||||
|
@ -58,15 +56,19 @@ function addTab(url) {
|
|||
info("Adding a new tab with URL: '" + url + "'");
|
||||
let def = promise.defer();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
// Bug 921935 should bring waitForFocus() support to e10s, which would
|
||||
// probably cover the case of the test losing focus when the page is loading.
|
||||
// For now, we just make sure the window is focused.
|
||||
window.focus();
|
||||
|
||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
||||
let linkedBrowser = tab.linkedBrowser;
|
||||
|
||||
linkedBrowser.addEventListener("load", function onload() {
|
||||
linkedBrowser.removeEventListener("load", onload, true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
waitForFocus(() => {
|
||||
def.resolve(tab);
|
||||
}, content);
|
||||
def.resolve(tab);
|
||||
}, true);
|
||||
content.location = url;
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
|
@ -124,7 +126,8 @@ function openInspector() {
|
|||
* Simple DOM node accesor function that takes either a node or a string css
|
||||
* selector as argument and returns the corresponding node
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @return {DOMNode}
|
||||
* @return {DOMNode|CPOW} Note that in e10s mode a CPOW object is returned which
|
||||
* doesn't implement *all* of the DOMNode's properties
|
||||
*/
|
||||
function getNode(nodeOrSelector) {
|
||||
info("Getting the node for '" + nodeOrSelector + "'");
|
||||
|
@ -133,6 +136,17 @@ function getNode(nodeOrSelector) {
|
|||
nodeOrSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeFront for a given css selector, via the protocol
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {Promise} Resolves to the NodeFront instance
|
||||
*/
|
||||
function getNodeFront(selector, {walker}) {
|
||||
return walker.querySelector(walker.rootNode, selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight a node and set the inspector's current selection to the node or
|
||||
* the first match of the given css selector.
|
||||
|
@ -149,46 +163,54 @@ function selectAndHighlightNode(nodeOrSelector, inspector) {
|
|||
let updated = inspector.toolbox.once("highlighter-ready");
|
||||
inspector.selection.setNode(node, "test-highlight");
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inspector's current selection to a node or to the first match of the
|
||||
* given css selector.
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @param {String} reason
|
||||
* Defaults to "test" which instructs the inspector not to highlight the
|
||||
* node upon selection
|
||||
* @return a promise that resolves when the inspector is updated with the new
|
||||
* node
|
||||
* Set the inspector's current selection to the first match of the given css
|
||||
* selector
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @param {String} reason Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @return {Promise} Resolves when the inspector is updated with the new node
|
||||
*/
|
||||
function selectNode(nodeOrSelector, inspector, reason="test") {
|
||||
info("Selecting the node " + nodeOrSelector);
|
||||
|
||||
let node = getNode(nodeOrSelector);
|
||||
let selectNode = Task.async(function*(selector, inspector, reason="test") {
|
||||
info("Selecting the node for '" + selector + "'");
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNode(node, reason);
|
||||
return updated;
|
||||
}
|
||||
inspector.selection.setNodeFront(nodeFront, reason);
|
||||
yield updated;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the MarkupContainer object instance that corresponds to the given
|
||||
* HTML node
|
||||
* @param {DOMNode|String} nodeOrSelector The DOM node for which the
|
||||
* container is required
|
||||
* NodeFront
|
||||
* @param {NodeFront} nodeFront
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {MarkupContainer}
|
||||
*/
|
||||
function getContainerForRawNode(nodeOrSelector, {markup}) {
|
||||
let front = markup.walker.frontForRawNode(getNode(nodeOrSelector));
|
||||
let container = markup.getContainer(front);
|
||||
info("Markup-container object for " + nodeOrSelector + " " + container);
|
||||
return container;
|
||||
function getContainerForNodeFront(nodeFront, {markup}) {
|
||||
return markup.getContainer(nodeFront);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MarkupContainer object instance that corresponds to the given
|
||||
* selector
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {MarkupContainer}
|
||||
*/
|
||||
let getContainerForSelector = Task.async(function*(selector, inspector) {
|
||||
info("Getting the markup-container for node " + selector);
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
info("Found markup-container " + container);
|
||||
return container;
|
||||
});
|
||||
|
||||
/**
|
||||
* Using the markupview's _waitForChildren function, wait for all queued
|
||||
* children updates to be handled.
|
||||
|
@ -208,38 +230,46 @@ function waitForChildrenUpdated({markup}) {
|
|||
|
||||
/**
|
||||
* Simulate a mouse-over on the markup-container (a line in the markup-view)
|
||||
* that corresponds to the node or selector passed.
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @return a promise that resolves when the container is hovered and the higlighter
|
||||
* that corresponds to the selector passed.
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {Promise} Resolves when the container is hovered and the higlighter
|
||||
* is shown on the corresponding node
|
||||
*/
|
||||
function hoverContainer(nodeOrSelector, inspector) {
|
||||
info("Hovering over the markup-container for node " + nodeOrSelector);
|
||||
let hoverContainer = Task.async(function*(selector, inspector) {
|
||||
info("Hovering over the markup-container for node " + selector);
|
||||
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
|
||||
let highlit = inspector.toolbox.once("node-highlight");
|
||||
let container = getContainerForRawNode(getNode(nodeOrSelector), inspector);
|
||||
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousemove"},
|
||||
inspector.markup.doc.defaultView);
|
||||
return highlit;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Simulate a click on the markup-container (a line in the markup-view)
|
||||
* that corresponds to the node or selector passed.
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @return a promise that resolves when the node has been selected.
|
||||
* that corresponds to the selector passed.
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return {Promise} Resolves when the node has been selected.
|
||||
*/
|
||||
function clickContainer(nodeOrSelector, inspector) {
|
||||
info("Clicking on the markup-container for node " + nodeOrSelector);
|
||||
let clickContainer = Task.async(function*(selector, inspector) {
|
||||
info("Clicking on the markup-container for node " + selector);
|
||||
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
let container = getContainerForNodeFront(nodeFront, inspector);
|
||||
|
||||
let updated = inspector.once("inspector-updated");
|
||||
let container = getContainerForRawNode(getNode(nodeOrSelector), inspector);
|
||||
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousedown"},
|
||||
inspector.markup.doc.defaultView);
|
||||
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mouseup"},
|
||||
inspector.markup.doc.defaultView);
|
||||
return updated;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if the highlighter is visible currently
|
||||
|
@ -288,39 +318,39 @@ function setEditableFieldValue(field, value, inspector) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Focus the new-attribute inplace-editor field of the nodeOrSelector's markup
|
||||
* container, and enters the given text, then wait for it to be applied and the
|
||||
* for the node to mutates (when new attribute(s) is(are) created)
|
||||
* @param {DOMNode|String} nodeOrSelector The node or node selector to edit.
|
||||
* Focus the new-attribute inplace-editor field of a node's markup container
|
||||
* and enters the given text, then wait for it to be applied and the for the
|
||||
* node to mutates (when new attribute(s) is(are) created)
|
||||
* @param {String} selector The selector for the node to edit.
|
||||
* @param {String} text The new attribute text to be entered (e.g. "id='test'")
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* loaded in the toolbox
|
||||
* @return a promise that resolves when the node has mutated
|
||||
*/
|
||||
function addNewAttributes(nodeOrSelector, text, inspector) {
|
||||
info("Entering text '" + text + "' in node '" + nodeOrSelector + "''s new attribute field");
|
||||
let addNewAttributes = Task.async(function*(selector, text, inspector) {
|
||||
info("Entering text '" + text + "' in node '" + selector + "''s new attribute field");
|
||||
|
||||
let container = getContainerForRawNode(nodeOrSelector, inspector);
|
||||
ok(container, "The container for '" + nodeOrSelector + "' was found");
|
||||
let container = yield getContainerForSelector(selector, inspector);
|
||||
ok(container, "The container for '" + selector + "' was found");
|
||||
|
||||
info("Listening for the markupmutation event");
|
||||
let nodeMutated = inspector.once("markupmutation");
|
||||
setEditableFieldValue(container.editor.newAttr, text, inspector);
|
||||
return nodeMutated;
|
||||
}
|
||||
yield nodeMutated;
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks that a node has the given attributes
|
||||
*
|
||||
* @param {DOMNode|String} nodeOrSelector The node or node selector to check.
|
||||
* @param {String} selector The node or node selector to check.
|
||||
* @param {Object} attrs An object containing the attributes to check.
|
||||
* e.g. {id: "id1", class: "someclass"}
|
||||
*
|
||||
* Note that node.getAttribute() returns attribute values provided by the HTML
|
||||
* parser. The parser only provides unescaped entities so & will return &.
|
||||
*/
|
||||
function assertAttributes(nodeOrSelector, attrs) {
|
||||
let node = getNode(nodeOrSelector);
|
||||
function assertAttributes(selector, attrs) {
|
||||
let node = getNode(selector);
|
||||
|
||||
is(node.attributes.length, Object.keys(attrs).length,
|
||||
"Node has the correct number of attributes.");
|
||||
|
|
|
@ -21,11 +21,10 @@ function runAddAttributesTests(tests, nodeOrSelector, inspector) {
|
|||
info("Running " + tests.length + " add-attributes tests");
|
||||
return Task.spawn(function*() {
|
||||
info("Selecting the test node");
|
||||
let div = getNode("div");
|
||||
yield selectNode(div, inspector);
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
for (let test of tests) {
|
||||
yield runAddAttributesTest(test, div, inspector);
|
||||
yield runAddAttributesTest(test, "div", inspector);
|
||||
}
|
||||
|
||||
yield inspector.once("inspector-updated");
|
||||
|
@ -48,22 +47,22 @@ function runAddAttributesTests(tests, nodeOrSelector, inspector) {
|
|||
* - {DOMNode} The element being tested
|
||||
* - {MarkupContainer} The corresponding container in the markup-view
|
||||
* - {InspectorPanel} The instance of the InspectorPanel opened
|
||||
* @param {DOMNode|String} nodeOrSelector The node or node selector
|
||||
* corresponding to the test element
|
||||
* @param {String} selector The node selector corresponding to the test element
|
||||
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
||||
* opened
|
||||
*/
|
||||
function* runAddAttributesTest(test, nodeOrSelector, inspector) {
|
||||
let element = getNode(nodeOrSelector);
|
||||
function* runAddAttributesTest(test, selector, inspector) {
|
||||
let element = getNode(selector);
|
||||
|
||||
info("Starting add-attribute test: " + test.desc);
|
||||
yield addNewAttributes(element, test.text, inspector);
|
||||
yield addNewAttributes(selector, test.text, inspector);
|
||||
|
||||
info("Assert that the attribute(s) has/have been applied correctly");
|
||||
assertAttributes(element, test.expectedAttributes);
|
||||
|
||||
if (test.validate) {
|
||||
test.validate(element, getContainerForRawNode(element, inspector), inspector);
|
||||
let container = yield getContainerForSelector(selector, inspector);
|
||||
test.validate(element, container, inspector);
|
||||
}
|
||||
|
||||
info("Undo the change");
|
||||
|
@ -128,7 +127,7 @@ function* runEditAttributesTest(test, inspector) {
|
|||
|
||||
info("Editing attribute " + test.name + " with value " + test.value);
|
||||
|
||||
let container = getContainerForRawNode(test.node, inspector);
|
||||
let container = yield getContainerForSelector(test.node, inspector);
|
||||
ok(container && container.editor, "The markup-container for " + test.node +
|
||||
" was found");
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ function* runEditOuterHTMLTest(test, inspector) {
|
|||
yield selectNode(test.selector, inspector);
|
||||
let oldNodeFront = inspector.selection.nodeFront;
|
||||
|
||||
let onUpdated = inspector.once("inspector-updated");
|
||||
|
||||
info("Listening for the markupmutation event");
|
||||
// This event fires once the outerHTML is set, with a target as the parent node and a type of "childList".
|
||||
let mutated = inspector.once("markupmutation");
|
||||
|
@ -60,22 +62,22 @@ function* runEditOuterHTMLTest(test, inspector) {
|
|||
is(mutation.target, nodeFront, "Parent node is selected immediately after setting outerHTML");
|
||||
|
||||
// Wait for node to be reselected after outerHTML has been set
|
||||
yield inspector.selection.once("new-node");
|
||||
yield inspector.selection.once("new-node-front");
|
||||
|
||||
// Typically selectedNode will === pageNode, but if a new element has been injected in front
|
||||
// of it, this will not be the case. If this happens.
|
||||
let selectedNode = inspector.selection.node;
|
||||
let nodeFront = inspector.selection.nodeFront;
|
||||
let selectedNodeFront = inspector.selection.nodeFront;
|
||||
let pageNodeFront = yield inspector.walker.querySelector(inspector.walker.rootNode, test.selector);
|
||||
let pageNode = getNode(test.selector);
|
||||
|
||||
if (test.validate) {
|
||||
test.validate(pageNode, selectedNode);
|
||||
yield test.validate(pageNode, pageNodeFront, selectedNodeFront, inspector);
|
||||
} else {
|
||||
is(pageNode, selectedNode, "Original node (grabbed by selector) is selected");
|
||||
is(pageNodeFront, selectedNodeFront, "Original node (grabbed by selector) is selected");
|
||||
is(pageNode.outerHTML, test.newHTML, "Outer HTML has been updated");
|
||||
}
|
||||
|
||||
// Wait for the inspector to be fully updated to avoid causing errors by
|
||||
// abruptly closing hanging requests when the test ends
|
||||
yield inspector.once("inspector-updated");
|
||||
yield onUpdated;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ function* runTests([win, sp]) {
|
|||
|
||||
// Check that the information tooltips work.
|
||||
sp.setText("5");
|
||||
yield keyOnce("show-information", " ", { shiftKey: true });
|
||||
yield keyOnce("show-information", " ", { ctrlKey: true, shiftKey: true });
|
||||
|
||||
// Get the information container.
|
||||
const info = editorWin.document.querySelector(".CodeMirror-Tern-information");
|
||||
|
|
|
@ -9,6 +9,7 @@ const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
|||
const IOService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
const {Spectrum} = require("devtools/shared/widgets/Spectrum");
|
||||
const {CubicBezierWidget} = require("devtools/shared/widgets/CubicBezierWidget");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const {colorUtils} = require("devtools/css-color");
|
||||
const Heritage = require("sdk/core/heritage");
|
||||
|
@ -33,6 +34,7 @@ const BORDERCOLOR_RE = /^border-[-a-z]*color$/ig;
|
|||
const BORDER_RE = /^border(-(top|bottom|left|right))?$/ig;
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const SPECTRUM_FRAME = "chrome://browser/content/devtools/spectrum-frame.xhtml";
|
||||
const CUBIC_BEZIER_FRAME = "chrome://browser/content/devtools/cubic-bezier-frame.xhtml";
|
||||
const ESCAPE_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE;
|
||||
const RETURN_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_RETURN;
|
||||
const POPUP_EVENTS = ["shown", "hidden", "showing", "hiding"];
|
||||
|
@ -740,6 +742,52 @@ Tooltip.prototype = {
|
|||
return def.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fill the tooltip with a new instance of the cubic-bezier widget
|
||||
* initialized with the given value, and return a promise that resolves to
|
||||
* the instance of the widget
|
||||
*/
|
||||
setCubicBezierContent: function(bezier) {
|
||||
let def = promise.defer();
|
||||
|
||||
// Create an iframe to host the cubic-bezier widget
|
||||
let iframe = this.doc.createElementNS(XHTML_NS, "iframe");
|
||||
iframe.setAttribute("transparent", true);
|
||||
iframe.setAttribute("width", "200");
|
||||
iframe.setAttribute("height", "415");
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.setAttribute("class", "devtools-tooltip-iframe");
|
||||
|
||||
let panel = this.panel;
|
||||
let xulWin = this.doc.ownerGlobal;
|
||||
|
||||
// Wait for the load to initialize the widget
|
||||
function onLoad() {
|
||||
iframe.removeEventListener("load", onLoad, true);
|
||||
let win = iframe.contentWindow.wrappedJSObject;
|
||||
|
||||
let container = win.document.getElementById("container");
|
||||
let widget = new CubicBezierWidget(container, bezier);
|
||||
|
||||
// Resolve to the widget instance whenever the popup becomes visible
|
||||
if (panel.state == "open") {
|
||||
def.resolve(widget);
|
||||
} else {
|
||||
panel.addEventListener("popupshown", function shown() {
|
||||
panel.removeEventListener("popupshown", shown, true);
|
||||
def.resolve(widget);
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
iframe.addEventListener("load", onLoad, true);
|
||||
iframe.setAttribute("src", CUBIC_BEZIER_FRAME);
|
||||
|
||||
// Put the iframe in the tooltip
|
||||
this.content = iframe;
|
||||
|
||||
return def.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the content of the tooltip to display a font family preview.
|
||||
* This is based on Lea Verou's Dablet. See https://github.com/LeaVerou/dabblet
|
||||
|
@ -1022,21 +1070,63 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
|||
});
|
||||
|
||||
/**
|
||||
* Internal util, checks whether a css declaration is a gradient
|
||||
* The swatch cubic-bezier tooltip class is a specific class meant to be used
|
||||
* along with rule-view's generated cubic-bezier swatches.
|
||||
* It extends the parent SwatchBasedEditorTooltip class.
|
||||
* It just wraps a standard Tooltip and sets its content with an instance of a
|
||||
* CubicBezierWidget.
|
||||
*
|
||||
* @param {XULDocument} doc
|
||||
*/
|
||||
function isGradientRule(property, value) {
|
||||
return (property === "background" || property === "background-image") &&
|
||||
value.match(GRADIENT_RE);
|
||||
function SwatchCubicBezierTooltip(doc) {
|
||||
SwatchBasedEditorTooltip.call(this, doc);
|
||||
|
||||
// Creating a cubic-bezier instance.
|
||||
// this.widget will always be a promise that resolves to the widget instance
|
||||
this.widget = this.tooltip.setCubicBezierContent([0, 0, 1, 1]);
|
||||
this._onUpdate = this._onUpdate.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal util, checks whether a css declaration is a color
|
||||
*/
|
||||
function isColorOnly(property, value) {
|
||||
return property === "background-color" ||
|
||||
property === "color" ||
|
||||
property.match(BORDERCOLOR_RE);
|
||||
}
|
||||
module.exports.SwatchCubicBezierTooltip = SwatchCubicBezierTooltip;
|
||||
|
||||
SwatchCubicBezierTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
|
||||
/**
|
||||
* Overriding the SwatchBasedEditorTooltip.show function to set the cubic
|
||||
* bezier curve in the widget
|
||||
*/
|
||||
show: function() {
|
||||
// Call then parent class' show function
|
||||
SwatchBasedEditorTooltip.prototype.show.call(this);
|
||||
// Then set the curve and listen to changes to preview them
|
||||
if (this.activeSwatch) {
|
||||
this.currentBezierValue = this.activeSwatch.nextSibling;
|
||||
let swatch = this.swatches.get(this.activeSwatch);
|
||||
this.widget.then(widget => {
|
||||
widget.off("updated", this._onUpdate);
|
||||
widget.cssCubicBezierValue = this.currentBezierValue.textContent;
|
||||
widget.on("updated", this._onUpdate);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onUpdate: function(event, bezier) {
|
||||
if (!this.activeSwatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentBezierValue.textContent = bezier + "";
|
||||
this.preview(bezier + "");
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
SwatchBasedEditorTooltip.prototype.destroy.call(this);
|
||||
this.currentBezierValue = null;
|
||||
this.widget.then(widget => {
|
||||
widget.off("updated", this._onUpdate);
|
||||
widget.destroy();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* L10N utility class
|
||||
|
|
|
@ -76,7 +76,7 @@ function initializeAutoCompletion(ctx, options = {}) {
|
|||
});
|
||||
};
|
||||
|
||||
keyMap[Editor.keyFor("showInformation", { noaccel: true })] = (cm) => {
|
||||
keyMap[Editor.keyFor("showInformation2", { noaccel: true })] = (cm) => {
|
||||
cm.tern.showType(cm, null, () => {
|
||||
ed.emit("show-information");
|
||||
});
|
||||
|
|
|
@ -689,6 +689,8 @@ Rule.prototype = {
|
|||
* The property's priority (either "important" or an empty string).
|
||||
*/
|
||||
previewPropertyValue: function(aProperty, aValue, aPriority) {
|
||||
aProperty.value = aValue;
|
||||
|
||||
let modifications = this.style.startModifyingProperties();
|
||||
modifications.setProperty(aProperty.name, aValue, aPriority);
|
||||
modifications.apply();
|
||||
|
@ -1406,7 +1408,7 @@ CssRuleView.prototype = {
|
|||
*/
|
||||
get isEditing() {
|
||||
return this.element.querySelectorAll(".styleinspector-propertyeditor").length > 0
|
||||
|| this.tooltips.colorPicker.tooltip.isShown();
|
||||
|| this.tooltips.isEditing;
|
||||
},
|
||||
|
||||
_handlePrefChange: function(pref) {
|
||||
|
@ -2168,9 +2170,7 @@ TextPropertyEditor.prototype = {
|
|||
*/
|
||||
get editing() {
|
||||
return !!(this.nameSpan.inplaceEditor || this.valueSpan.inplaceEditor ||
|
||||
this.ruleEditor.ruleView.tooltips.colorPicker.tooltip.isShown() ||
|
||||
this.ruleEditor.ruleView.tooltips.colorPicker.eyedropperOpen) ||
|
||||
this.popup.isOpen;
|
||||
this.ruleEditor.ruleView.tooltips.isEditing) || this.popup.isOpen;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2405,11 +2405,15 @@ TextPropertyEditor.prototype = {
|
|||
this.element.removeAttribute("dirty");
|
||||
}
|
||||
|
||||
let swatchClass = "ruleview-colorswatch";
|
||||
let colorSwatchClass = "ruleview-colorswatch";
|
||||
let bezierSwatchClass = "ruleview-bezierswatch";
|
||||
|
||||
let outputParser = this.ruleEditor.ruleView._outputParser;
|
||||
let frag = outputParser.parseCssProperty(name, val, {
|
||||
colorSwatchClass: swatchClass,
|
||||
colorSwatchClass: colorSwatchClass,
|
||||
colorClass: "ruleview-color",
|
||||
bezierSwatchClass: bezierSwatchClass,
|
||||
bezierClass: "ruleview-bezier",
|
||||
defaultColorType: !propDirty,
|
||||
urlClass: "theme-link",
|
||||
baseURI: this.sheetURI
|
||||
|
@ -2418,9 +2422,9 @@ TextPropertyEditor.prototype = {
|
|||
this.valueSpan.appendChild(frag);
|
||||
|
||||
// Attach the color picker tooltip to the color swatches
|
||||
this._swatchSpans = this.valueSpan.querySelectorAll("." + swatchClass);
|
||||
this._colorSwatchSpans = this.valueSpan.querySelectorAll("." + colorSwatchClass);
|
||||
if (this.ruleEditor.isEditable) {
|
||||
for (let span of this._swatchSpans) {
|
||||
for (let span of this._colorSwatchSpans) {
|
||||
// Capture the original declaration value to be able to revert later
|
||||
let originalValue = this.valueSpan.textContent;
|
||||
// Adding this swatch to the list of swatches our colorpicker knows about
|
||||
|
@ -2432,6 +2436,21 @@ TextPropertyEditor.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Attach the cubic-bezier tooltip to the bezier swatches
|
||||
this._bezierSwatchSpans = this.valueSpan.querySelectorAll("." + bezierSwatchClass);
|
||||
if (this.ruleEditor.isEditable) {
|
||||
for (let span of this._bezierSwatchSpans) {
|
||||
// Capture the original declaration value to be able to revert later
|
||||
let originalValue = this.valueSpan.textContent;
|
||||
// Adding this swatch to the list of swatches our colorpicker knows about
|
||||
this.ruleEditor.ruleView.tooltips.cubicBezier.addSwatch(span, {
|
||||
onPreview: () => this._previewValue(this.valueSpan.textContent),
|
||||
onCommit: () => this._applyNewValue(this.valueSpan.textContent),
|
||||
onRevert: () => this._applyNewValue(originalValue)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the computed styles.
|
||||
this._updateComputed();
|
||||
},
|
||||
|
@ -2563,8 +2582,8 @@ TextPropertyEditor.prototype = {
|
|||
* Begin editing next available property.
|
||||
*/
|
||||
remove: function() {
|
||||
if (this._swatchSpans && this._swatchSpans.length) {
|
||||
for (let span of this._swatchSpans) {
|
||||
if (this._colorSwatchSpans && this._colorSwatchSpans.length) {
|
||||
for (let span of this._colorSwatchSpans) {
|
||||
this.ruleEditor.ruleView.tooltips.colorPicker.removeSwatch(span);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const {
|
||||
Tooltip,
|
||||
SwatchColorPickerTooltip
|
||||
SwatchColorPickerTooltip,
|
||||
SwatchCubicBezierTooltip
|
||||
} = require("devtools/shared/widgets/Tooltip");
|
||||
const {CssLogic} = require("devtools/styleinspector/css-logic");
|
||||
const {Promise:promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
@ -237,6 +238,12 @@ function TooltipsOverlay(view) {
|
|||
exports.TooltipsOverlay = TooltipsOverlay;
|
||||
|
||||
TooltipsOverlay.prototype = {
|
||||
get isEditing() {
|
||||
return this.colorPicker.tooltip.isShown() ||
|
||||
this.colorPicker.eyedropperOpen ||
|
||||
this.cubicBezier.tooltip.isShown();
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the tooltips overlay to the view. This will start tracking mouse
|
||||
* movements and display tooltips when needed
|
||||
|
@ -251,9 +258,11 @@ TooltipsOverlay.prototype = {
|
|||
this.previewTooltip.startTogglingOnHover(this.view.element,
|
||||
this._onPreviewTooltipTargetHover.bind(this));
|
||||
|
||||
// Color picker tooltip
|
||||
if (this.isRuleView) {
|
||||
// Color picker tooltip
|
||||
this.colorPicker = new SwatchColorPickerTooltip(this.view.inspector.panelDoc);
|
||||
// Cubic bezier tooltip
|
||||
this.cubicBezier = new SwatchCubicBezierTooltip(this.view.inspector.panelDoc);
|
||||
}
|
||||
|
||||
this._isStarted = true;
|
||||
|
@ -275,6 +284,10 @@ TooltipsOverlay.prototype = {
|
|||
this.colorPicker.destroy();
|
||||
}
|
||||
|
||||
if (this.cubicBezier) {
|
||||
this.cubicBezier.destroy();
|
||||
}
|
||||
|
||||
this._isStarted = false;
|
||||
},
|
||||
|
||||
|
@ -329,6 +342,11 @@ TooltipsOverlay.prototype = {
|
|||
this.colorPicker.hide();
|
||||
}
|
||||
|
||||
if (this.isRuleView && this.cubicBezier.tooltip.isShown()) {
|
||||
this.cubicBezier.revert();
|
||||
this.cubicBezier.hide();
|
||||
}
|
||||
|
||||
let inspector = this.view.inspector;
|
||||
|
||||
if (type === TOOLTIP_IMAGE_TYPE) {
|
||||
|
@ -353,6 +371,10 @@ TooltipsOverlay.prototype = {
|
|||
if (this.colorPicker) {
|
||||
this.colorPicker.hide();
|
||||
}
|
||||
|
||||
if (this.cubicBezier) {
|
||||
this.cubicBezier.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,6 +60,9 @@ support-files =
|
|||
[browser_ruleview_completion-new-property_02.js]
|
||||
[browser_ruleview_content_01.js]
|
||||
[browser_ruleview_content_02.js]
|
||||
[browser_ruleview_cubicbezier-appears-on-swatch-click.js]
|
||||
[browser_ruleview_cubicbezier-commit-on-ENTER.js]
|
||||
[browser_ruleview_cubicbezier-revert-on-ESC.js]
|
||||
[browser_ruleview_edit-property-commit.js]
|
||||
[browser_ruleview_edit-property-increments.js]
|
||||
[browser_ruleview_edit-property-order.js]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Tests that the checkbox to include browser styles works properly.
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,default styles test");
|
||||
yield addTab("data:text/html;charset=utf-8,default styles test");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Test computed view key bindings
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,default styles test");
|
||||
yield addTab("data:text/html;charset=utf-8,default styles test");
|
||||
|
||||
info("Adding content to the test page");
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Tests the computed-view keyboard navigation
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,computed view keyboard nav test");
|
||||
yield addTab("data:text/html;charset=utf-8,computed view keyboard nav test");
|
||||
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
'span { font-variant: small-caps; color: #000000; } ' +
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Test that the computed view properties can be expanded and collapsed with
|
||||
// either the twisty or by dbl-clicking on the container
|
||||
|
||||
const TEST_URL = "data:text/html," + encodeURIComponent([
|
||||
const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent([
|
||||
'<html>' +
|
||||
'<head>' +
|
||||
' <title>Computed view toggling test</title>',
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Tests for matched selector texts in the computed view
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,<div style='color:blue;'></div>");
|
||||
yield addTab("data:text/html;charset=utf-8,<div style='color:blue;'></div>");
|
||||
|
||||
info("Opening the computed view");
|
||||
let {toolbox, inspector, view} = yield openComputedView();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Tests that the no results placeholder works properly.
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,no results placeholder test");
|
||||
yield addTab("data:text/html;charset=utf-8,no results placeholder test");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Tests that the search filter works properly.
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,default styles test");
|
||||
yield addTab("data:text/html;charset=utf-8,default styles test");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
|
|
|
@ -11,7 +11,7 @@ XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
|||
});
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,computed view copy test");
|
||||
yield addTab("data:text/html;charset=utf-8,computed view copy test");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
||||
|
|
|
@ -11,7 +11,7 @@ const STYLESHEET_URL = "data:text/css,"+encodeURIComponent(
|
|||
"color: blue",
|
||||
"}"].join("\n"));
|
||||
|
||||
const DOCUMENT_URL = "data:text/html,"+encodeURIComponent(
|
||||
const DOCUMENT_URL = "data:text/html;charset=utf-8,"+encodeURIComponent(
|
||||
['<html>' +
|
||||
'<head>' +
|
||||
'<title>Computed view style editor link test</title>',
|
||||
|
|
|
@ -20,7 +20,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view user changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view user changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -17,7 +17,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view user changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view user changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -22,7 +22,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view user changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view user changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -62,7 +62,7 @@ function* testCreateNew(inspector, ruleView) {
|
|||
|
||||
editor.input.value = "purple";
|
||||
let onBlur = once(editor.input, "blur");
|
||||
editor.input.blur();
|
||||
EventUtils.sendKey("return", ruleView.doc.defaultView);
|
||||
yield onBlur;
|
||||
yield elementRuleEditor.rule._applyingModifications;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield testColorChangeIsntRevertedWhenOtherTooltipIsShown(view);
|
||||
|
|
|
@ -19,7 +19,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -19,7 +19,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ const PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ const TESTS = [
|
|||
];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view color picker tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ let testData = [
|
|||
["VK_ESCAPE", null, -1, 0],
|
||||
];
|
||||
|
||||
let TEST_URL = "data:text/html,<h1 style='border: 1px solid red'>Filename" +
|
||||
let TEST_URL = "data:text/html;charset=utf-8,<h1 style='border: 1px solid red'>Filename" +
|
||||
": browser_bug893965_css_property_completion_existing_property.js</h1>";
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
|
|
|
@ -36,7 +36,7 @@ let testData = [
|
|||
["VK_RETURN", {}, null, -1, 0]
|
||||
];
|
||||
|
||||
let TEST_URL = "data:text/html,<h1 style='color: red'>Filename: " +
|
||||
let TEST_URL = "data:text/html;charset=utf-8,<h1 style='color: red'>Filename: " +
|
||||
"browser_bug894376_css_value_completion_existing_property_value_pair.js</h1>";
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
|
|
|
@ -37,7 +37,7 @@ let testData = [
|
|||
["VK_ESCAPE", null, -1, 0],
|
||||
];
|
||||
|
||||
let TEST_URL = "data:text/html,<h1 style='border: 1px solid red'>Filename:" +
|
||||
let TEST_URL = "data:text/html;charset=utf-8,<h1 style='border: 1px solid red'>Filename:" +
|
||||
"browser_bug893965_css_property_completion_new_property.js</h1>";
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
|
|
|
@ -39,7 +39,7 @@ let testData = [
|
|||
["VK_ESCAPE", {}, null, -1, 0]
|
||||
];
|
||||
|
||||
let TEST_URL = "data:text/html,<style>h1{border: 1px solid red}</style>" +
|
||||
let TEST_URL = "data:text/html;charset=utf-8,<style>h1{border: 1px solid red}</style>" +
|
||||
"<h1>Test element</h1>";
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* 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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that cubic-bezier pickers appear when clicking on cubic-bezier swatches
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' div {',
|
||||
' animation: move 3s linear;',
|
||||
' transition: top 4s cubic-bezier(.1, 1.45, 1, -1.2);',
|
||||
' }',
|
||||
' .test {',
|
||||
' animation-timing-function: ease-in-out;',
|
||||
' transition-timing-function: ease-out;',
|
||||
' }',
|
||||
'</style>',
|
||||
'<div class="test">Testing the cubic-bezier tooltip!</div>'
|
||||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html;charset=utf-8,rule view cubic-bezier tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
let swatches = [];
|
||||
swatches.push(
|
||||
getRuleViewProperty(view, "div", "animation").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch")
|
||||
);
|
||||
swatches.push(
|
||||
getRuleViewProperty(view, "div", "transition").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch")
|
||||
);
|
||||
swatches.push(
|
||||
getRuleViewProperty(view, ".test", "animation-timing-function").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch")
|
||||
);
|
||||
swatches.push(
|
||||
getRuleViewProperty(view, ".test", "transition-timing-function").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch")
|
||||
);
|
||||
|
||||
for (let swatch of swatches) {
|
||||
info("Testing that the cubic-bezier appears on cubicswatch click");
|
||||
yield testAppears(view, swatch);
|
||||
}
|
||||
});
|
||||
|
||||
function* testAppears(view, swatch) {
|
||||
ok(swatch, "The cubic-swatch exists");
|
||||
|
||||
let bezier = view.tooltips.cubicBezier;
|
||||
ok(bezier, "The rule-view has the expected cubicBezier property");
|
||||
|
||||
let bezierPanel = bezier.tooltip.panel;
|
||||
ok(bezierPanel, "The XUL panel for the cubic-bezier tooltip exists");
|
||||
|
||||
let onShown = bezier.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
ok(true, "The cubic-bezier tooltip was shown on click of the cibuc swatch");
|
||||
ok(!inplaceEditor(swatch.parentNode),
|
||||
"The inplace editor wasn't shown as a result of the cibuc swatch click");
|
||||
bezier.hide();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/* 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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that a curve change in the cubic-bezier tooltip is committed when ENTER
|
||||
// is pressed
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' transition: top 2s linear;',
|
||||
' }',
|
||||
'</style>'
|
||||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html;charset=utf-8,rule view cubic-bezier tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
info("Getting the bezier swatch element");
|
||||
let swatch = getRuleViewProperty(view, "body" , "transition").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch");
|
||||
|
||||
yield testPressingEnterCommitsChanges(swatch, view);
|
||||
});
|
||||
|
||||
function* testPressingEnterCommitsChanges(swatch, ruleView) {
|
||||
let bezierTooltip = ruleView.tooltips.cubicBezier;
|
||||
|
||||
info("Showing the tooltip");
|
||||
let onShown = bezierTooltip.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
let widget = yield bezierTooltip.widget;
|
||||
info("Simulating a change of curve in the widget");
|
||||
widget.coordinates = [0.1, 2, 0.9, -1];
|
||||
let expected = "cubic-bezier(0.1, 2, 0.9, -1)";
|
||||
|
||||
yield waitForSuccess(() => {
|
||||
return content.getComputedStyle(content.document.body).transitionTimingFunction === expected;
|
||||
}, "Waiting for the change to be previewed on the element");
|
||||
|
||||
ok(getRuleViewProperty(ruleView, "body", "transition").valueSpan.textContent
|
||||
.indexOf("cubic-bezier(") !== -1,
|
||||
"The text of the timing-function was updated");
|
||||
|
||||
info("Sending RETURN key within the tooltip document");
|
||||
let onHidden = bezierTooltip.tooltip.once("hidden");
|
||||
EventUtils.sendKey("RETURN", widget.parent.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
is(content.getComputedStyle(content.document.body).transitionTimingFunction,
|
||||
expected, "The element's timing-function was kept after RETURN");
|
||||
ok(getRuleViewProperty(ruleView, "body", "transition").valueSpan.textContent
|
||||
.indexOf("cubic-bezier(") !== -1,
|
||||
"The text of the timing-function was kept after RETURN");
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* 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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that changes made to the cubic-bezier timing-function in the cubic-bezier
|
||||
// tooltip are reverted when ESC is pressed
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' animation-timing-function: linear;',
|
||||
' }',
|
||||
'</style>',
|
||||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html;charset=utf-8,rule view cubic-bezier tooltip test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
info("Getting the bezier swatch element");
|
||||
let swatch = getRuleViewProperty(view, "body", "animation-timing-function").valueSpan
|
||||
.querySelector(".ruleview-bezierswatch");
|
||||
yield testPressingEscapeRevertsChanges(swatch, view);
|
||||
});
|
||||
|
||||
function* testPressingEscapeRevertsChanges(swatch, ruleView) {
|
||||
let bezierTooltip = ruleView.tooltips.cubicBezier;
|
||||
|
||||
let onShown = bezierTooltip.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
let widget = yield bezierTooltip.widget;
|
||||
info("Simulating a change of curve in the widget");
|
||||
widget.coordinates = [0.1, 2, 0.9, -1];
|
||||
let expected = "cubic-bezier(0.1, 2, 0.9, -1)";
|
||||
|
||||
yield waitForSuccess(() => {
|
||||
return content.getComputedStyle(content.document.body).animationTimingFunction === expected;
|
||||
}, "Waiting for the change to be previewed on the element");
|
||||
|
||||
info("Pressing ESCAPE to close the tooltip");
|
||||
let onHidden = bezierTooltip.tooltip.once("hidden");
|
||||
EventUtils.sendKey("ESCAPE", widget.parent.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
yield waitForSuccess(() => {
|
||||
return content.getComputedStyle(content.document.body).animationTimingFunction === "cubic-bezier(0, 0, 1, 1)";
|
||||
}, "Waiting for the change to be reverted on the element");
|
||||
}
|
|
@ -24,7 +24,7 @@ const testData = [
|
|||
];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test escaping property change reverts back to original value");
|
||||
yield addTab("data:text/html;charset=utf-8,test escaping property change reverts back to original value");
|
||||
|
||||
info("Creating the test document");
|
||||
createDocument();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// arrow keys works correctly.
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,sample document for bug 722691");
|
||||
yield addTab("data:text/html;charset=utf-8,sample document for bug 722691");
|
||||
createDocument();
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view user changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view user changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -48,7 +48,7 @@ const TEST_DATA = [
|
|||
];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test escaping selector change reverts back to original value");
|
||||
yield addTab("data:text/html;charset=utf-8,test escaping selector change reverts back to original value");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -17,7 +17,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view selector changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view selector changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -23,7 +23,7 @@ let PAGE_CONTENT = [
|
|||
].join("\n");
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view selector changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view selector changes");
|
||||
|
||||
info("Creating the test document");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
|
|
@ -26,7 +26,7 @@ const EXPECTED_COLOR = "rgb(255, 255, 85)"; // #ff5
|
|||
// to close it, and clicking the page to select a color.
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,rule view eyedropper test");
|
||||
yield addTab("data:text/html;charset=utf-8,rule view eyedropper test");
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// (bug 719916)
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,<h1>Some header text</h1>");
|
||||
yield addTab("data:text/html;charset=utf-8,<h1>Some header text</h1>");
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
|
||||
info("Selecting the test node");
|
||||
|
|
|
@ -23,7 +23,7 @@ const TEST_DATA = [
|
|||
];
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab("data:text/html,test rule view live preview on user changes");
|
||||
yield addTab("data:text/html;charset=utf-8,test rule view live preview on user changes");
|
||||
|
||||
let style = '#testid {display:block;}';
|
||||
let styleNode = addStyle(content.document, style);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче