зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound on a CLOSED TREE.
This commit is contained in:
Коммит
6df7229f81
|
@ -415,7 +415,7 @@ pref("dom.navigator-property.disable.mozContacts", false);
|
|||
pref("dom.global-constructor.disable.mozContact", false);
|
||||
|
||||
// Shortnumber matching needed for e.g. Brazil:
|
||||
// 01187654321 can be found with 87654321
|
||||
// 03187654321 can be found with 87654321
|
||||
pref("dom.phonenumber.substringmatching.BR", 8);
|
||||
pref("dom.phonenumber.substringmatching.CO", 10);
|
||||
pref("dom.phonenumber.substringmatching.VE", 7);
|
||||
|
|
|
@ -118,11 +118,7 @@ let developerHUD = {
|
|||
if (this._targets.has(frame))
|
||||
return;
|
||||
|
||||
let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner)
|
||||
.frameLoader
|
||||
.messageManager;
|
||||
|
||||
DebuggerServer.connectToChild(this._conn, mm).then(actor => {
|
||||
DebuggerServer.connectToChild(this._conn, frame).then(actor => {
|
||||
let target = new Target(frame, actor);
|
||||
this._targets.set(frame, target);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="70b698c2e8d1764a1e27527a102df6452e405b9a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="70b698c2e8d1764a1e27527a102df6452e405b9a"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "ac34484ce7f6a5ba71784e03a683bc91a3ebc6e4",
|
||||
"revision": "1c4cb51103918927ba1431bd2c26b0506ce7402e",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="70b698c2e8d1764a1e27527a102df6452e405b9a"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d9a574284d672f532f7c562a091bb01f531202b1"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3c917f7ca3d5988d0e6f6b545008643da1217fc5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -48,10 +48,12 @@ def process_package_overload(src, dst, version, app_buildid):
|
|||
# First replace numeric version like '1.3'
|
||||
# Then replace with 'slashed' version like '1_4'
|
||||
# Finally set the full length addon version like 1.3.20131230
|
||||
# (reduce the app build id to only the build date
|
||||
# as addon manager doesn't handle big ints in addon versions)
|
||||
defines = {
|
||||
"NUM_VERSION": version,
|
||||
"SLASH_VERSION": version.replace(".", "_"),
|
||||
"FULL_VERSION": ("%s.%s" % (version, app_buildid))
|
||||
"FULL_VERSION": ("%s.%s" % (version, app_buildid[:8]))
|
||||
}
|
||||
pp = Preprocessor(defines=defines)
|
||||
pp.do_filter("substitution")
|
||||
|
|
|
@ -145,8 +145,10 @@ exports.SimulatorProcess = Class({
|
|||
Linux: "b2g-bin",
|
||||
};
|
||||
|
||||
console.log("bin url: "+bin+"/"+executables[Runtime.OS]);
|
||||
let path = bin + "/" + executables[Runtime.OS];
|
||||
let path = bin;
|
||||
path += Runtime.OS == "WINNT" ? "\\" : "/";
|
||||
path += executables[Runtime.OS];
|
||||
console.log("simulator path: " + path);
|
||||
|
||||
let executable = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
executable.initWithPath(path);
|
||||
|
|
|
@ -281,6 +281,11 @@ function openPrefs() {
|
|||
|
||||
function init() {
|
||||
fxAccounts.getSignedInUser().then(user => {
|
||||
// tests in particular might cause the window to start closing before
|
||||
// getSignedInUser has returned.
|
||||
if (window.closed) {
|
||||
return;
|
||||
}
|
||||
if (window.location.href.contains("action=signin")) {
|
||||
if (user) {
|
||||
// asking to sign-in when already signed in just shows manage.
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
replaceWithHost(node.childNodes[i]);
|
||||
};
|
||||
replaceWithHost(intro);
|
||||
|
||||
|
||||
if (getCSSClass() == "expertBadCert") {
|
||||
toggle('technicalContent');
|
||||
toggle('expertContent');
|
||||
|
@ -90,14 +90,14 @@
|
|||
// certerror is in a frame (bug 633691).
|
||||
if (getCSSClass() == "badStsCert" || window != top)
|
||||
document.getElementById("expertContent").setAttribute("hidden", "true");
|
||||
|
||||
|
||||
var tech = document.getElementById("technicalContentText");
|
||||
if (tech)
|
||||
tech.textContent = getDescription();
|
||||
|
||||
|
||||
addDomainErrorLink();
|
||||
}
|
||||
|
||||
|
||||
/* In the case of SSL error pages about domain mismatch, see if
|
||||
we can hyperlink the user to the correct site. We don't want
|
||||
to do this generically since it allows MitM attacks to redirect
|
||||
|
@ -109,29 +109,29 @@
|
|||
var sd = document.getElementById("technicalContentText");
|
||||
if (sd) {
|
||||
var desc = getDescription();
|
||||
|
||||
|
||||
// sanitize description text - see bug 441169
|
||||
|
||||
|
||||
// First, find the index of the <a> tag we care about, being careful not to
|
||||
// use an over-greedy regex
|
||||
var re = /<a id="cert_domain_link" title="([^"]+)">/;
|
||||
var result = re.exec(desc);
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
|
||||
// Remove sd's existing children
|
||||
sd.textContent = "";
|
||||
|
||||
// Everything up to the link should be text content
|
||||
sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
|
||||
|
||||
|
||||
// Now create the link itself
|
||||
var anchorEl = document.createElement("a");
|
||||
anchorEl.setAttribute("id", "cert_domain_link");
|
||||
anchorEl.setAttribute("title", result[1]);
|
||||
anchorEl.appendChild(document.createTextNode(result[1]));
|
||||
sd.appendChild(anchorEl);
|
||||
|
||||
|
||||
// Finally, append text for anything after the closing </a>
|
||||
sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
|
||||
}
|
||||
|
@ -139,7 +139,7 @@
|
|||
var link = document.getElementById('cert_domain_link');
|
||||
if (!link)
|
||||
return;
|
||||
|
||||
|
||||
var okHost = link.getAttribute("title");
|
||||
var thisHost = document.location.hostname;
|
||||
var proto = document.location.protocol;
|
||||
|
@ -149,7 +149,7 @@
|
|||
// get anyone anywhere useful. bug 432491
|
||||
okHost = okHost.replace(/^\*\./, "www.");
|
||||
|
||||
/* case #1:
|
||||
/* case #1:
|
||||
* example.com uses an invalid security certificate.
|
||||
*
|
||||
* The certificate is only valid for www.example.com
|
||||
|
@ -172,13 +172,13 @@
|
|||
*/
|
||||
if (endsWith(thisHost, "." + okHost))
|
||||
link.href = proto + okHost;
|
||||
|
||||
|
||||
// If we set a link, meaning there's something helpful for
|
||||
// the user here, expand the section by default
|
||||
if (link.href && getCSSClass() != "expertBadCert")
|
||||
toggle("technicalContent");
|
||||
}
|
||||
|
||||
|
||||
function endsWith(haystack, needle) {
|
||||
return haystack.slice(-needle.length) == needle;
|
||||
}
|
||||
|
@ -197,19 +197,19 @@
|
|||
|
||||
<!-- PAGE CONTAINER (for styling purposes only) -->
|
||||
<div id="errorPageContainer">
|
||||
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 id="errorTitleText">&certerror.longpagetitle;</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- LONG CONTENT (the section most likely to require scrolling) -->
|
||||
<div id="errorLongContent">
|
||||
<div id="introContent">
|
||||
<p id="introContentP1">&certerror.introPara1;</p>
|
||||
<p>&certerror.introPara2;</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="whatShouldIDoContent">
|
||||
<h2>&certerror.whatShouldIDo.heading;</h2>
|
||||
<div id="whatShouldIDoContentText">
|
||||
|
@ -217,14 +217,14 @@
|
|||
<button id='getMeOutOfHereButton'>&certerror.getMeOutOfHere.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- The following sections can be unhidden by default by setting the
|
||||
"browser.xul.error_pages.expert_bad_cert" pref to true -->
|
||||
<h2 id="technicalContent" class="expander" collapsed="true">
|
||||
<button onclick="toggle('technicalContent');">&certerror.technical.heading;</button>
|
||||
</h2>
|
||||
<p id="technicalContentText"/>
|
||||
|
||||
|
||||
<h2 id="expertContent" class="expander" collapsed="true">
|
||||
<button onclick="toggle('expertContent');">&certerror.expert.heading;</button>
|
||||
</h2>
|
|
@ -929,6 +929,7 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
|
|||
|
||||
/* Customize mode */
|
||||
#navigator-toolbox,
|
||||
#browser-bottombox,
|
||||
#content-deck {
|
||||
transition-property: margin-left, margin-right;
|
||||
transition-duration: 200ms;
|
||||
|
|
|
@ -547,7 +547,7 @@
|
|||
defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabs-closebutton"
|
||||
collapsed="true">
|
||||
|
||||
#ifdef XP_LINUX
|
||||
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
|
||||
<hbox id="private-browsing-indicator"
|
||||
skipintoolbarset="true"/>
|
||||
#endif
|
||||
|
|
|
@ -127,6 +127,8 @@ skip-if = true # bug 428712
|
|||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_bug427559.js]
|
||||
skip-if = e10s # Bug ?????? - "content window is focused - Got [object ChromeWindow], expected [object XrayWrapper [object Window]]"
|
||||
[browser_bug431826.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
|
||||
[browser_bug432599.js]
|
||||
[browser_bug435035.js]
|
||||
[browser_bug435325.js]
|
||||
|
@ -225,6 +227,8 @@ skip-if = e10s # Bug ?????? - URLBar issues (apparently issues with redirection)
|
|||
[browser_bug623893.js]
|
||||
skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
|
||||
[browser_bug624734.js]
|
||||
[browser_bug633691.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
|
||||
[browser_bug647886.js]
|
||||
skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
|
||||
[browser_bug655584.js]
|
||||
|
|
|
@ -63,6 +63,9 @@ browser.jar:
|
|||
content/browser/aboutaccounts/images/graphic_sync_intro.png (content/aboutaccounts/images/graphic_sync_intro.png)
|
||||
content/browser/aboutaccounts/images/graphic_sync_intro@2x.png (content/aboutaccounts/images/graphic_sync_intro@2x.png)
|
||||
|
||||
content/browser/certerror/aboutCertError.xhtml (content/aboutcerterror/aboutCertError.xhtml)
|
||||
content/browser/certerror/aboutCertError.css (content/aboutcerterror/aboutCertError.css)
|
||||
|
||||
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
|
||||
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
|
||||
content/browser/aboutSocialError.xhtml (content/aboutSocialError.xhtml)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
browser.jar:
|
||||
content/browser/certerror/aboutCertError.xhtml (content/aboutCertError.xhtml)
|
||||
content/browser/certerror/aboutCertError.css (content/aboutCertError.css)
|
|
@ -1,11 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
'test/browser.ini',
|
||||
]
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
|
@ -1,5 +0,0 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s # Bug ?????? - tests directly manipulate content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
|
||||
|
||||
[browser_bug431826.js]
|
||||
[browser_bug633691.js]
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
PARALLEL_DIRS += [
|
||||
'about',
|
||||
'certerror',
|
||||
'customizableui',
|
||||
'dirprovider',
|
||||
'downloads',
|
||||
|
@ -49,4 +48,3 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
|
||||
if CONFIG['MOZ_SAFE_BROWSING']:
|
||||
BROWSER_CHROME_MANIFESTS += ['safebrowsing/content/test/browser.ini']
|
||||
|
||||
|
|
|
@ -54,11 +54,7 @@
|
|||
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
<preference id="toolkit.telemetry.enabled"
|
||||
#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
|
||||
name="toolkit.telemetry.enabledPreRelease"
|
||||
#else
|
||||
name="toolkit.telemetry.enabled"
|
||||
#endif
|
||||
type="bool"/>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,11 +54,7 @@
|
|||
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
<preference id="toolkit.telemetry.enabled"
|
||||
#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
|
||||
name="toolkit.telemetry.enabledPreRelease"
|
||||
#else
|
||||
name="toolkit.telemetry.enabled"
|
||||
#endif
|
||||
type="bool"/>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -365,7 +365,8 @@ let DebuggerController = {
|
|||
_startTracingTab: function(aTraceActor, aCallback) {
|
||||
this.client.attachTracer(aTraceActor, (response, traceClient) => {
|
||||
if (!traceClient) {
|
||||
DevToolsUtils.reportError(new Error("Failed to attach to tracing actor."));
|
||||
DevToolsUtils.reportException("DebuggerController._startTracingTab",
|
||||
new Error("Failed to attach to tracing actor."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -594,37 +595,43 @@ StackFrames.prototype = {
|
|||
let waitForNextPause = false;
|
||||
let breakLocation = this._currentBreakpointLocation;
|
||||
let watchExpressions = this._currentWatchExpressions;
|
||||
let client = DebuggerController.activeThread.client;
|
||||
|
||||
// Conditional breakpoints are { breakpoint, expression } tuples. The
|
||||
// boolean evaluation of the expression decides if the active thread
|
||||
// automatically resumes execution or not.
|
||||
// TODO: handle all of this server-side: Bug 812172.
|
||||
if (breakLocation) {
|
||||
// Make sure a breakpoint actually exists at the specified url and line.
|
||||
let breakpointPromise = DebuggerController.Breakpoints._getAdded(breakLocation);
|
||||
if (breakpointPromise) {
|
||||
breakpointPromise.then(({ conditionalExpression: e }) => { if (e) {
|
||||
// Evaluating the current breakpoint's conditional expression will
|
||||
// cause the stack frames to be cleared and active thread to pause,
|
||||
// sending a 'clientEvaluated' packed and adding the frames again.
|
||||
this.evaluate(e, { depth: 0, meta: FRAME_TYPE.CONDITIONAL_BREAKPOINT_EVAL });
|
||||
waitForNextPause = true;
|
||||
}});
|
||||
// We moved conditional breakpoint handling to the server, but
|
||||
// need to support it in the client for a while until most of the
|
||||
// server code in production is updated with it. bug 990137 is
|
||||
// filed to mark this code to be removed.
|
||||
if (!client.mainRoot.traits.conditionalBreakpoints) {
|
||||
// Conditional breakpoints are { breakpoint, expression } tuples. The
|
||||
// boolean evaluation of the expression decides if the active thread
|
||||
// automatically resumes execution or not.
|
||||
if (breakLocation) {
|
||||
// Make sure a breakpoint actually exists at the specified url and line.
|
||||
let breakpointPromise = DebuggerController.Breakpoints._getAdded(breakLocation);
|
||||
if (breakpointPromise) {
|
||||
breakpointPromise.then(({ conditionalExpression: e }) => { if (e) {
|
||||
// Evaluating the current breakpoint's conditional expression will
|
||||
// cause the stack frames to be cleared and active thread to pause,
|
||||
// sending a 'clientEvaluated' packed and adding the frames again.
|
||||
this.evaluate(e, { depth: 0, meta: FRAME_TYPE.CONDITIONAL_BREAKPOINT_EVAL });
|
||||
waitForNextPause = true;
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
// We'll get our evaluation of the current breakpoint's conditional
|
||||
// expression the next time the thread client pauses...
|
||||
if (waitForNextPause) {
|
||||
return;
|
||||
}
|
||||
if (this._currentFrameDescription == FRAME_TYPE.CONDITIONAL_BREAKPOINT_EVAL) {
|
||||
this._currentFrameDescription = FRAME_TYPE.NORMAL;
|
||||
// If the breakpoint's conditional expression evaluation is falsy,
|
||||
// automatically resume execution.
|
||||
if (VariablesView.isFalsy({ value: this._currentEvaluation.return })) {
|
||||
this.activeThread.resume(DebuggerController._ensureResumptionOrder);
|
||||
// We'll get our evaluation of the current breakpoint's conditional
|
||||
// expression the next time the thread client pauses...
|
||||
if (waitForNextPause) {
|
||||
return;
|
||||
}
|
||||
if (this._currentFrameDescription == FRAME_TYPE.CONDITIONAL_BREAKPOINT_EVAL) {
|
||||
this._currentFrameDescription = FRAME_TYPE.NORMAL;
|
||||
// If the breakpoint's conditional expression evaluation is falsy,
|
||||
// automatically resume execution.
|
||||
if (VariablesView.isFalsy({ value: this._currentEvaluation.return })) {
|
||||
this.activeThread.resume(DebuggerController._ensureResumptionOrder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Watch expressions are evaluated in the context of the topmost frame,
|
||||
|
@ -1817,6 +1824,8 @@ Breakpoints.prototype = {
|
|||
* This object must have two properties:
|
||||
* - url: the breakpoint's source location.
|
||||
* - line: the breakpoint's line number.
|
||||
* It can also have the following optional properties:
|
||||
* - condition: only pause if this condition evaluates truthy
|
||||
* @param object aOptions [optional]
|
||||
* Additional options or flags supported by this operation:
|
||||
* - openPopup: tells if the expression popup should be shown.
|
||||
|
@ -1874,10 +1883,10 @@ Breakpoints.prototype = {
|
|||
// so that they may not be forgotten across target navigations.
|
||||
let disabledPromise = this._disabled.get(identifier);
|
||||
if (disabledPromise) {
|
||||
disabledPromise.then(({ conditionalExpression: previousValue }) => {
|
||||
// Setting a falsy conditional expression is redundant.
|
||||
if (previousValue) {
|
||||
aBreakpointClient.conditionalExpression = previousValue;
|
||||
disabledPromise.then((aPrevBreakpointClient) => {
|
||||
let condition = aPrevBreakpointClient.getCondition();
|
||||
if (condition) {
|
||||
aBreakpointClient.setCondition(gThreadClient, condition);
|
||||
}
|
||||
});
|
||||
this._disabled.delete(identifier);
|
||||
|
@ -2006,6 +2015,31 @@ Breakpoints.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the condition of a breakpoint.
|
||||
*
|
||||
* @param object aLocation
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
* @param string aClients
|
||||
* The condition to set on the breakpoint
|
||||
* @return object
|
||||
* A promise that will be resolved with the breakpoint client
|
||||
*/
|
||||
updateCondition: function(aLocation, aCondition) {
|
||||
let addedPromise = this._getAdded(aLocation);
|
||||
if (!addedPromise) {
|
||||
return promise.reject(new Error('breakpoint does not exist ' +
|
||||
'in specified location'));
|
||||
}
|
||||
|
||||
return addedPromise.then(aBreakpointClient => {
|
||||
return aBreakpointClient.setCondition(gThreadClient, aCondition);
|
||||
}, err => {
|
||||
DevToolsUtils.reportException("Breakpoints.prototype.updateCondition",
|
||||
err);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the editor and breakpoints pane to show a specified breakpoint.
|
||||
*
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
// Used to detect minification for automatic pretty printing
|
||||
const SAMPLE_SIZE = 50; // no of lines
|
||||
const INDENT_COUNT_THRESHOLD = 5; // percentage
|
||||
|
@ -37,7 +40,6 @@ function SourcesView() {
|
|||
this._onConditionalPopupShowing = this._onConditionalPopupShowing.bind(this);
|
||||
this._onConditionalPopupShown = this._onConditionalPopupShown.bind(this);
|
||||
this._onConditionalPopupHiding = this._onConditionalPopupHiding.bind(this);
|
||||
this._onConditionalTextboxInput = this._onConditionalTextboxInput.bind(this);
|
||||
this._onConditionalTextboxKeyPress = this._onConditionalTextboxKeyPress.bind(this);
|
||||
|
||||
this.updateToolbarButtonsState = this.updateToolbarButtonsState.bind(this);
|
||||
|
@ -87,7 +89,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this._cbPanel.addEventListener("popupshowing", this._onConditionalPopupShowing, false);
|
||||
this._cbPanel.addEventListener("popupshown", this._onConditionalPopupShown, false);
|
||||
this._cbPanel.addEventListener("popuphiding", this._onConditionalPopupHiding, false);
|
||||
this._cbTextbox.addEventListener("input", this._onConditionalTextboxInput, false);
|
||||
this._cbTextbox.addEventListener("keypress", this._onConditionalTextboxKeyPress, false);
|
||||
|
||||
this.autoFocusOnSelection = false;
|
||||
|
@ -112,7 +113,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShowing, false);
|
||||
this._cbPanel.removeEventListener("popupshowing", this._onConditionalPopupShown, false);
|
||||
this._cbPanel.removeEventListener("popuphiding", this._onConditionalPopupHiding, false);
|
||||
this._cbTextbox.removeEventListener("input", this._onConditionalTextboxInput, false);
|
||||
this._cbTextbox.removeEventListener("keypress", this._onConditionalTextboxKeyPress, false);
|
||||
},
|
||||
|
||||
|
@ -560,15 +560,14 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
_openConditionalPopup: function() {
|
||||
let breakpointItem = this._selectedBreakpointItem;
|
||||
let attachment = breakpointItem.attachment;
|
||||
|
||||
// Check if this is an enabled conditional breakpoint, and if so,
|
||||
// retrieve the current conditional epression.
|
||||
let breakpointPromise = DebuggerController.Breakpoints._getAdded(attachment);
|
||||
if (breakpointPromise) {
|
||||
breakpointPromise.then(aBreakpointClient => {
|
||||
let isConditionalBreakpoint = "conditionalExpression" in aBreakpointClient;
|
||||
let conditionalExpression = aBreakpointClient.conditionalExpression;
|
||||
doOpen.call(this, isConditionalBreakpoint ? conditionalExpression : "")
|
||||
let isConditionalBreakpoint = aBreakpointClient.hasCondition();
|
||||
let condition = aBreakpointClient.getCondition();
|
||||
doOpen.call(this, isConditionalBreakpoint ? condition : "")
|
||||
});
|
||||
} else {
|
||||
doOpen.call(this, "")
|
||||
|
@ -845,7 +844,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let breakpointPromise = DebuggerController.Breakpoints._getAdded(attachment);
|
||||
if (breakpointPromise) {
|
||||
breakpointPromise.then(aBreakpointClient => {
|
||||
doHighlight.call(this, "conditionalExpression" in aBreakpointClient);
|
||||
doHighlight.call(this, aBreakpointClient.hasCondition());
|
||||
});
|
||||
} else {
|
||||
doHighlight.call(this, false);
|
||||
|
@ -901,15 +900,8 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
/**
|
||||
* The popup hiding listener for the breakpoints conditional expression panel.
|
||||
*/
|
||||
_onConditionalPopupHiding: function() {
|
||||
_onConditionalPopupHiding: Task.async(function*() {
|
||||
this._conditionalPopupVisible = false; // Used in tests.
|
||||
window.emit(EVENTS.CONDITIONAL_BREAKPOINT_POPUP_HIDING);
|
||||
},
|
||||
|
||||
/**
|
||||
* The input listener for the breakpoints conditional expression textbox.
|
||||
*/
|
||||
_onConditionalTextboxInput: function() {
|
||||
let breakpointItem = this._selectedBreakpointItem;
|
||||
let attachment = breakpointItem.attachment;
|
||||
|
||||
|
@ -917,11 +909,15 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
// save the current conditional epression.
|
||||
let breakpointPromise = DebuggerController.Breakpoints._getAdded(attachment);
|
||||
if (breakpointPromise) {
|
||||
breakpointPromise.then(aBreakpointClient => {
|
||||
aBreakpointClient.conditionalExpression = this._cbTextbox.value;
|
||||
});
|
||||
let breakpointClient = yield breakpointPromise;
|
||||
yield DebuggerController.Breakpoints.updateCondition(
|
||||
breakpointClient.location,
|
||||
this._cbTextbox.value
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
window.emit(EVENTS.CONDITIONAL_BREAKPOINT_POPUP_HIDING);
|
||||
}),
|
||||
|
||||
/**
|
||||
* The keypress listener for the breakpoints conditional expression textbox.
|
||||
|
@ -935,7 +931,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
/**
|
||||
* Called when the add breakpoint key sequence was pressed.
|
||||
*/
|
||||
_onCmdAddBreakpoint: function() {
|
||||
_onCmdAddBreakpoint: function(e) {
|
||||
let url = DebuggerView.Sources.selectedValue;
|
||||
let line = DebuggerView.editor.getCursor().line + 1;
|
||||
let location = { url: url, line: line };
|
||||
|
@ -1811,6 +1807,12 @@ VariableBubbleView.prototype = {
|
|||
this._editorContainer.removeEventListener("mouseleave", this._onMouseLeave, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies whether literals can be (redundantly) inspected in a popup.
|
||||
* This behavior is deprecated, but still tested in a few places.
|
||||
*/
|
||||
_ignoreLiterals: true,
|
||||
|
||||
/**
|
||||
* Searches for an identifier underneath the specified position in the
|
||||
* source editor, and if found, opens a VariablesView inspection popup.
|
||||
|
@ -1850,7 +1852,8 @@ VariableBubbleView.prototype = {
|
|||
let identifierInfo = parsedSource.getIdentifierAt({
|
||||
line: scriptLine + 1,
|
||||
column: scriptColumn,
|
||||
scriptIndex: scriptInfo.index
|
||||
scriptIndex: scriptInfo.index,
|
||||
ignoreLiterals: this._ignoreLiterals
|
||||
});
|
||||
|
||||
// If the info is null, we're not hovering any identifier.
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<command id="globalSearchCommand"
|
||||
oncommand="DebuggerView.Filtering._doGlobalSearch()"/>
|
||||
<command id="functionSearchCommand"
|
||||
oncommand="DebuggerView.Filtering._doFunctionSearch()"/>
|
||||
oncommand="DepbuggerView.Filtering._doFunctionSearch()"/>
|
||||
<command id="tokenSearchCommand"
|
||||
oncommand="DebuggerView.Filtering._doTokenSearch()"/>
|
||||
<command id="lineSearchCommand"
|
||||
|
@ -434,7 +434,7 @@
|
|||
<tabpanels flex="1">
|
||||
<tabpanel id="variables-tabpanel">
|
||||
<vbox id="expressions"/>
|
||||
<splitter class="devtools-horizontal-splitter devtools-invisible-splitter"/>
|
||||
<splitter class="devtools-horizontal-splitter"/>
|
||||
<vbox id="variables" flex="1"/>
|
||||
</tabpanel>
|
||||
<tabpanel id="events-tabpanel">
|
||||
|
|
|
@ -128,6 +128,10 @@ support-files =
|
|||
[browser_dbg_conditional-breakpoints-02.js]
|
||||
[browser_dbg_conditional-breakpoints-03.js]
|
||||
[browser_dbg_conditional-breakpoints-04.js]
|
||||
[browser_dbg_server-conditional-bp-01.js]
|
||||
[browser_dbg_server-conditional-bp-02.js]
|
||||
[browser_dbg_server-conditional-bp-03.js]
|
||||
[browser_dbg_server-conditional-bp-04.js]
|
||||
[browser_dbg_controller-evaluate-01.js]
|
||||
[browser_dbg_controller-evaluate-02.js]
|
||||
[browser_dbg_debugger-statement.js]
|
||||
|
@ -274,6 +278,7 @@ support-files =
|
|||
[browser_dbg_variables-view-popup-12.js]
|
||||
[browser_dbg_variables-view-popup-13.js]
|
||||
[browser_dbg_variables-view-popup-14.js]
|
||||
[browser_dbg_variables-view-popup-15.js]
|
||||
[browser_dbg_variables-view-reexpand-01.js]
|
||||
[browser_dbg_variables-view-reexpand-02.js]
|
||||
[browser_dbg_variables-view-webidl.js]
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
const ADDON3_URL = EXAMPLE_URL + "addon3.xpi";
|
||||
|
||||
let gAddon, gClient, gThreadClient, gDebugger, gSources;
|
||||
|
||||
let PREFS = [
|
||||
"devtools.canvasdebugger.enabled",
|
||||
"devtools.shadereditor.enabled",
|
||||
"devtools.profiler.enabled",
|
||||
"devtools.netmonitor.enabled"
|
||||
];
|
||||
function test() {
|
||||
Task.spawn(function () {
|
||||
if (!DebuggerServer.initialized) {
|
||||
|
@ -15,6 +20,13 @@ function test() {
|
|||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
// Store and enable all optional dev tools panels
|
||||
let originalPrefs = PREFS.map(pref => {
|
||||
let original = Services.prefs.getBoolPref(pref);
|
||||
Services.prefs.setBoolPref(pref, true)
|
||||
return original;
|
||||
});
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
let iframe = document.createElement("iframe");
|
||||
document.documentElement.appendChild(iframe);
|
||||
|
@ -37,6 +49,9 @@ function test() {
|
|||
yield closeConnection();
|
||||
yield debuggerPanel._toolbox.destroy();
|
||||
iframe.remove();
|
||||
|
||||
PREFS.forEach((pref, i) => Services.prefs.setBoolPref(pref, originalPrefs[i]));
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
* Tests that a chrome debugger can be created in a new process.
|
||||
*/
|
||||
|
||||
// Enable logging for this test, bug 860349.
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
|
||||
let gProcess;
|
||||
|
||||
function test() {
|
||||
|
|
|
@ -25,6 +25,11 @@ function test() {
|
|||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => addBreakpoints())
|
||||
.then(() => initialChecks())
|
||||
|
|
|
@ -22,6 +22,11 @@ function test() {
|
|||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => initialChecks())
|
||||
.then(() => addBreakpoint1())
|
||||
|
|
|
@ -19,6 +19,11 @@ function test() {
|
|||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
gLocation = { url: gSources.selectedValue, line: 18 };
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
|
|
|
@ -20,6 +20,11 @@ function test() {
|
|||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
gLocation = { url: gSources.selectedValue, line: 18 };
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: Test adding conditional breakpoints (with server-side support)
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
// Linux debug test slaves are a bit slow at this test sometimes.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => addBreakpoints())
|
||||
.then(() => initialChecks())
|
||||
.then(() => resumeAndTestBreakpoint(20))
|
||||
.then(() => resumeAndTestBreakpoint(21))
|
||||
.then(() => resumeAndTestBreakpoint(22))
|
||||
.then(() => resumeAndTestBreakpoint(23))
|
||||
.then(() => resumeAndTestBreakpoint(24))
|
||||
.then(() => resumeAndTestBreakpoint(25))
|
||||
.then(() => resumeAndTestBreakpoint(27))
|
||||
.then(() => resumeAndTestBreakpoint(28))
|
||||
.then(() => resumeAndTestBreakpoint(29))
|
||||
.then(() => resumeAndTestNoBreakpoint())
|
||||
.then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN, 13))
|
||||
.then(() => testAfterReload())
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function addBreakpoints() {
|
||||
return promise.resolve(null)
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 18,
|
||||
condition: "undefined"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 19,
|
||||
condition: "null"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 20,
|
||||
condition: "42"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 21,
|
||||
condition: "true"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 22,
|
||||
condition: "'nasu'"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 23,
|
||||
condition: "/regexp/"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 24,
|
||||
condition: "({})"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 25,
|
||||
condition: "(function() {})"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 26,
|
||||
condition: "(function() { return false; })()"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 27,
|
||||
condition: "a"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 28,
|
||||
condition: "a !== undefined"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 29,
|
||||
condition: "a !== null"
|
||||
}))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue,
|
||||
line: 30,
|
||||
condition: "b"
|
||||
}));
|
||||
}
|
||||
|
||||
function initialChecks() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 13,
|
||||
"13 breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 13,
|
||||
"13 breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
}
|
||||
|
||||
function resumeAndTestBreakpoint(aLine) {
|
||||
let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine));
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function resumeAndTestNoBreakpoint() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.")
|
||||
ok(!gSources._selectedBreakpointItem,
|
||||
"There should be no selected breakpoint in the sources pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"There should be no visible stackframes.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-breakpoint").length, 13,
|
||||
"There should be thirteen visible breakpoints.");
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(aLine, aHighlightBreakpoint) {
|
||||
// Highlight the breakpoint only if required.
|
||||
if (aHighlightBreakpoint) {
|
||||
let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine));
|
||||
gSources.highlightBreakpoint({ url: gSources.selectedValue, line: aLine });
|
||||
return finished;
|
||||
}
|
||||
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected brekapoint in the sources pane.");
|
||||
|
||||
is(selectedBreakpoint.attachment.url, selectedUrl,
|
||||
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
|
||||
is(selectedBreakpoint.attachment.line, aLine,
|
||||
"The breakpoint on line " + aLine + " wasn't found.");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint on line " + aLine + " should be enabled.");
|
||||
is(!!selectedBreakpoint.attachment.openPopup, false,
|
||||
"The breakpoint on line " + aLine + " should not have opened a popup.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not have been shown.");
|
||||
|
||||
return gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
|
||||
is(aBreakpointClient.location.url, selectedUrl,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, aLine,
|
||||
"The breakpoint's client line is correct");
|
||||
isnot(aBreakpointClient.condition, undefined,
|
||||
"The breakpoint on line " + aLine + " should have a conditional expression.");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
});
|
||||
}
|
||||
|
||||
function testAfterReload() {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane after reload.");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected brekapoint in the sources pane after reload.");
|
||||
|
||||
return promise.resolve(null)
|
||||
.then(() => testBreakpoint(18, true))
|
||||
.then(() => testBreakpoint(19, true))
|
||||
.then(() => testBreakpoint(20, true))
|
||||
.then(() => testBreakpoint(21, true))
|
||||
.then(() => testBreakpoint(22, true))
|
||||
.then(() => testBreakpoint(23, true))
|
||||
.then(() => testBreakpoint(24, true))
|
||||
.then(() => testBreakpoint(25, true))
|
||||
.then(() => testBreakpoint(26, true))
|
||||
.then(() => testBreakpoint(27, true))
|
||||
.then(() => testBreakpoint(28, true))
|
||||
.then(() => testBreakpoint(29, true))
|
||||
.then(() => testBreakpoint(30, true))
|
||||
.then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded again.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.")
|
||||
ok(gSources._selectedBreakpointItem,
|
||||
"There should be a selected breakpoint in the sources pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 812172: Test adding and modifying conditional breakpoints (with server-side support)
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => initialChecks())
|
||||
.then(() => addBreakpoint1())
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => addBreakpoint2())
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => modBreakpoint2())
|
||||
.then(() => testBreakpoint(19, false, true, undefined))
|
||||
.then(() => addBreakpoint3())
|
||||
.then(() => testBreakpoint(20, true, false, undefined))
|
||||
.then(() => modBreakpoint3())
|
||||
.then(() => testBreakpoint(20, true, false, "bamboocha"))
|
||||
.then(() => addBreakpoint4())
|
||||
.then(() => testBreakpoint(21, false, false, undefined))
|
||||
.then(() => delBreakpoint4())
|
||||
.then(() => setCaretPosition(18))
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => setCaretPosition(19))
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => setCaretPosition(20))
|
||||
.then(() => testBreakpoint(20, true, false, "bamboocha"))
|
||||
.then(() => setCaretPosition(17))
|
||||
.then(() => testNoBreakpoint(17))
|
||||
.then(() => setCaretPosition(21))
|
||||
.then(() => testNoBreakpoint(21))
|
||||
.then(() => clickOnBreakpoint(0))
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => clickOnBreakpoint(1))
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => clickOnBreakpoint(2))
|
||||
.then(() => testBreakpoint(20, true, true, "bamboocha"))
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function initialChecks() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
}
|
||||
|
||||
function addBreakpoint1() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 18 });
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint2() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setCaretPosition(19);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function modBreakpoint2() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
|
||||
setCaretPosition(19);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint3() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setCaretPosition(20);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function modBreakpoint3() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_HIDING);
|
||||
typeText(gSources._cbTextbox, "bamboocha");
|
||||
EventUtils.sendKey("RETURN", gDebugger);
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint4() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setCaretPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function delBreakpoint4() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
|
||||
setCaretPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(aLine, aOpenPopupFlag, aPopupVisible, aConditionalExpression) {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected brekapoint in the sources pane.");
|
||||
|
||||
is(selectedBreakpoint.attachment.url, selectedUrl,
|
||||
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
|
||||
is(selectedBreakpoint.attachment.line, aLine,
|
||||
"The breakpoint on line " + aLine + " wasn't found.");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint on line " + aLine + " should be enabled.");
|
||||
is(!!selectedBreakpoint.attachment.openPopup, aOpenPopupFlag,
|
||||
"The breakpoint on line " + aLine + " should have a correct popup state (1).");
|
||||
is(gSources._conditionalPopupVisible, aPopupVisible,
|
||||
"The breakpoint on line " + aLine + " should have a correct popup state (2).");
|
||||
|
||||
return gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
|
||||
is(aBreakpointClient.location.url, selectedUrl,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, aLine,
|
||||
"The breakpoint's client line is correct");
|
||||
is(aBreakpointClient.condition, aConditionalExpression,
|
||||
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
|
||||
is("condition" in aBreakpointClient, !!aConditionalExpression,
|
||||
"The breakpoint on line " + aLine + " should have a correct conditional state.");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
});
|
||||
}
|
||||
|
||||
function testNoBreakpoint(aLine) {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane for line " + aLine + ".");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected brekapoint in the sources pane for line " + aLine + ".");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
}
|
||||
|
||||
function setCaretPosition(aLine) {
|
||||
gEditor.setCursor({ line: aLine - 1, ch: 0 });
|
||||
}
|
||||
|
||||
function clickOnBreakpoint(aIndex) {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
|
||||
gDebugger);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that conditional breakpoints survive disabled breakpoints
|
||||
* (with server-side support)
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints, gLocation;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
|
||||
gLocation = { url: gSources.selectedValue, line: 18 };
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(addBreakpoint)
|
||||
.then(setConditional)
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
|
||||
toggleBreakpoint();
|
||||
return finished;
|
||||
})
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
toggleBreakpoint();
|
||||
return finished;
|
||||
})
|
||||
.then(testConditionalExpressionOnClient)
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
|
||||
openConditionalPopup();
|
||||
return finished;
|
||||
})
|
||||
.then(testConditionalExpressionInPopup)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function addBreakpoint() {
|
||||
return gPanel.addBreakpoint(gLocation);
|
||||
}
|
||||
|
||||
function setConditional(aClient) {
|
||||
aClient.condition = "hello";
|
||||
}
|
||||
|
||||
function toggleBreakpoint() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function openConditionalPopup() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testConditionalExpressionOnClient() {
|
||||
return gBreakpoints._getAdded(gLocation).then(aClient => {
|
||||
is(aClient.condition, "hello", "The expression is correct (1).");
|
||||
});
|
||||
}
|
||||
|
||||
function testConditionalExpressionInPopup() {
|
||||
let textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
|
||||
is(textbox.value, "hello", "The expression is correct (2).")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that conditional breakpoints with undefined expressions
|
||||
* are stored as plain breakpoints when re-enabling them (with
|
||||
* server-side support)
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints, gLocation;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
|
||||
gLocation = { url: gSources.selectedValue, line: 18 };
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(addBreakpoint)
|
||||
.then(setDummyConditional)
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
|
||||
toggleBreakpoint();
|
||||
return finished;
|
||||
})
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
toggleBreakpoint();
|
||||
return finished;
|
||||
})
|
||||
.then(testConditionalExpressionOnClient)
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
|
||||
openConditionalPopup();
|
||||
finished.then(() => ok(false, "The popup shouldn't have opened."));
|
||||
return waitForTime(1000);
|
||||
})
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function addBreakpoint() {
|
||||
return gPanel.addBreakpoint(gLocation);
|
||||
}
|
||||
|
||||
function setDummyConditional(aClient) {
|
||||
// This happens when a conditional expression input popup is shown
|
||||
// but the user doesn't type anything into it.
|
||||
aClient.condition = "";
|
||||
}
|
||||
|
||||
function toggleBreakpoint() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function openConditionalPopup() {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testConditionalExpressionOnClient() {
|
||||
return gBreakpoints._getAdded(gLocation).then(aClient => {
|
||||
if ("condition" in aClient) {
|
||||
ok(false, "A conditional expression shouldn't have been set.");
|
||||
} else {
|
||||
ok(true, "The conditional expression wasn't set, as expected.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ function test() {
|
|||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
bubble._ignoreLiterals = false;
|
||||
|
||||
function verifyContents(textContent, className) {
|
||||
is(tooltip.querySelectorAll(".variables-view-container").length, 0,
|
||||
"There should be no variables view containers added to the tooltip.");
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests opening the variable inspection popup directly on literals.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let bubble = win.DebuggerView.VariableBubble;
|
||||
let tooltip = bubble._tooltip.panel;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.start());
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
|
||||
|
||||
yield openVarPopup(panel, { line: 15, ch: 12 });
|
||||
ok(true, "The variable inspection popup was shown for the real variable.");
|
||||
|
||||
once(tooltip, "popupshown").then(() => {
|
||||
ok(false, "The variable inspection popup shouldn't have been opened.");
|
||||
});
|
||||
|
||||
reopenVarPopup(panel, { line: 17, ch: 27 });
|
||||
yield waitForTime(1000);
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
});
|
||||
}
|
|
@ -12,9 +12,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/event-emitter.js");
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
||||
var ProfilerController = devtools.require("devtools/profiler/controller");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise");
|
||||
|
||||
const FORBIDDEN_IDS = new Set(["toolbox", ""]);
|
||||
const MAX_ORDINAL = 99;
|
||||
|
@ -804,6 +802,8 @@ let gDevToolsBrowser = {
|
|||
* Connects to the SPS profiler when the developer tools are open.
|
||||
*/
|
||||
_connectToProfiler: function DT_connectToProfiler() {
|
||||
let ProfilerController = devtools.require("devtools/profiler/controller");
|
||||
|
||||
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
|
||||
if (devtools.TargetFactory.isKnownTab(win.gBrowser.selectedTab)) {
|
||||
let target = devtools.TargetFactory.forTab(win.gBrowser.selectedTab);
|
||||
|
|
|
@ -6,20 +6,15 @@ let doc = null, toolbox = null, panelWin = null, modifiedPrefs = [];
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
gDevTools.showToolbox(target)
|
||||
.then(testSelectTool)
|
||||
.then(testOptionsShortcut)
|
||||
.then(testOptions)
|
||||
.then(testToggleTools)
|
||||
.then(cleanup, errorHandler);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test for dynamically registering and unregistering tools";
|
||||
const URL = "data:text/html;charset=utf8,test for dynamically registering and unregistering tools";
|
||||
Task.spawn(function* () {
|
||||
let { target } = yield addTab(URL);
|
||||
let toolbox = yield gDevTools.showToolbox(target);
|
||||
yield testSelectTool(toolbox);
|
||||
yield testOptionsShortcut();
|
||||
yield testOptions();
|
||||
yield testToggleTools();
|
||||
}).then(cleanup, errorHandler);
|
||||
}
|
||||
|
||||
function testSelectTool(aToolbox) {
|
||||
|
@ -39,17 +34,18 @@ function testSelectTool(aToolbox) {
|
|||
function testOptionsShortcut() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
toolbox.once("options-selected", (event, tool) => {
|
||||
ok(true, "Toolbox selected via shortcut key");
|
||||
deferred.resolve(tool);
|
||||
});
|
||||
toolbox.selectTool("webconsole")
|
||||
.then(() => synthesizeKeyFromKeyTag("toolbox-options-key", doc));
|
||||
.then(() => synthesizeKeyFromKeyTag("toolbox-options-key", doc))
|
||||
.then(() => {
|
||||
ok(true, "Toolbox selected via shortcut key");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testOptions(tool) {
|
||||
function testOptions() {
|
||||
let tool = toolbox.getPanel("options");
|
||||
panelWin = tool.panelWin;
|
||||
let prefNodes = tool.panelDoc.querySelectorAll("checkbox[data-pref]");
|
||||
|
||||
|
@ -105,10 +101,10 @@ function testToggleTools() {
|
|||
let toolNodes = panelWin.document.querySelectorAll("#default-tools-box > checkbox:not([unsupported])");
|
||||
let enabledTools = Array.prototype.filter.call(toolNodes, node => node.checked);
|
||||
|
||||
let toggleableTools = gDevTools.getDefaultTools().filter(tool=>tool.visibilityswitch);
|
||||
let toggleableTools = gDevTools.getDefaultTools().filter(tool => tool.visibilityswitch);
|
||||
for (let node of toolNodes) {
|
||||
let id = node.getAttribute("id");
|
||||
ok (toggleableTools.some(tool=>tool.id === id),
|
||||
ok (toggleableTools.some(tool => tool.id === id),
|
||||
"There should be a toggle checkbox for: " + id);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ let TargetFactory = gDevTools.TargetFactory;
|
|||
let tempScope = {};
|
||||
Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
|
||||
let console = tempScope.console;
|
||||
Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js", tempScope);
|
||||
Components.utils.import("resource://gre/modules/Promise.jsm", tempScope);
|
||||
let promise = tempScope.Promise;
|
||||
|
||||
let {devtools} = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
"use strict";
|
||||
|
||||
const {Cu, Cc, Ci} = require("chrome");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const {Promise: promise} = require("resource://gre/modules/Promise.jsm");
|
||||
const Services = require("Services");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
exports.OptionsPanel = OptionsPanel;
|
||||
|
||||
|
@ -38,6 +36,7 @@ function OptionsPanel(iframeWindow, toolbox) {
|
|||
this.toolbox = toolbox;
|
||||
this.isReady = false;
|
||||
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
|
@ -158,8 +157,9 @@ OptionsPanel.prototype = {
|
|||
|
||||
// Populating the default tools lists
|
||||
let toggleableTools = gDevTools.getDefaultTools().filter(tool => {
|
||||
return tool.visibilityswitch
|
||||
return tool.visibilityswitch;
|
||||
});
|
||||
|
||||
for (let tool of toggleableTools) {
|
||||
defaultToolsBox.appendChild(createToolCheckbox(tool));
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ Tools.canvasDebugger = {
|
|||
tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
return true;
|
||||
return !target.isAddon;
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
|
|
|
@ -55,9 +55,9 @@ SimpleTest.registerCleanupFunction(() => {
|
|||
// All tests are asynchronous.
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Enable logging for all the relevant tests.
|
||||
const gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
// To enable logging for try runs, just set the pref to true.
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
// Always reset some prefs to their original values after the test finishes.
|
||||
const gDefaultFilters = Services.prefs.getCharPref("devtools.netmonitor.filters");
|
||||
|
|
|
@ -6,10 +6,9 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
|||
|
||||
let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
// Enable logging for all the tests. Both the debugger server and frontend will
|
||||
// be affected by this pref.
|
||||
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
// To enable logging for try runs, just set the pref to true.
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
|
|
@ -136,8 +136,8 @@ SyntaxTreesPool.prototype = {
|
|||
/**
|
||||
* @see SyntaxTree.prototype.getIdentifierAt
|
||||
*/
|
||||
getIdentifierAt: function({ line, column, scriptIndex }) {
|
||||
return this._call("getIdentifierAt", scriptIndex, line, column)[0];
|
||||
getIdentifierAt: function({ line, column, scriptIndex, ignoreLiterals }) {
|
||||
return this._call("getIdentifierAt", scriptIndex, line, column, ignoreLiterals)[0];
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -256,11 +256,13 @@ SyntaxTree.prototype = {
|
|||
* The line in the source.
|
||||
* @param number aColumn
|
||||
* The column in the source.
|
||||
* @param boolean aIgnoreLiterals
|
||||
* Specifies if alone literals should be ignored.
|
||||
* @return object
|
||||
* An object containing identifier information as { name, location,
|
||||
* evalString } properties, or null if nothing is found.
|
||||
*/
|
||||
getIdentifierAt: function(aLine, aColumn) {
|
||||
getIdentifierAt: function(aLine, aColumn, aIgnoreLiterals) {
|
||||
let info = null;
|
||||
|
||||
SyntaxTreeVisitor.walk(this.AST, {
|
||||
|
@ -286,7 +288,9 @@ SyntaxTree.prototype = {
|
|||
* @param Node aNode
|
||||
*/
|
||||
onLiteral: function(aNode) {
|
||||
this.onIdentifier(aNode);
|
||||
if (!aIgnoreLiterals) {
|
||||
this.onIdentifier(aNode);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -705,11 +709,7 @@ let ParserHelpers = {
|
|||
case "Identifier":
|
||||
return aNode.name;
|
||||
case "Literal":
|
||||
if (typeof aNode.value == "string") {
|
||||
return "\"" + aNode.value + "\"";
|
||||
} else {
|
||||
return aNode.value + "";
|
||||
}
|
||||
return uneval(aNode.value);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
|
|||
"resource:///modules/devtools/VariablesView.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController",
|
||||
"resource:///modules/devtools/VariablesViewController.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
const GRADIENT_RE = /\b(repeating-)?(linear|radial)-gradient\(((rgb|hsl)a?\(.+?\)|[^\)])+\)/gi;
|
||||
const BORDERCOLOR_RE = /^border-[-a-z]*color$/ig;
|
||||
|
@ -34,6 +36,7 @@ const SPECTRUM_FRAME = "chrome://browser/content/devtools/spectrum-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"];
|
||||
const FONT_FAMILY_PREVIEW_TEXT = "(ABCabc123&@%)";
|
||||
|
||||
/**
|
||||
* Tooltip widget.
|
||||
|
@ -419,7 +422,8 @@ Tooltip.prototype = {
|
|||
return false;
|
||||
});
|
||||
} else {
|
||||
return res ? promise.resolve(res) : promise.reject(false);
|
||||
let newTarget = res instanceof Ci.nsIDOMNode ? res : target;
|
||||
return res ? promise.resolve(newTarget) : promise.reject(false);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -586,26 +590,24 @@ Tooltip.prototype = {
|
|||
* Uses the provided inspectorFront's getImageDataFromURL method to resolve
|
||||
* the relative URL on the server-side, in the page context, and then sets the
|
||||
* tooltip content with the resulting image just like |setImageContent| does.
|
||||
*
|
||||
* @return a promise that resolves when the image is shown in the tooltip
|
||||
* @return a promise that resolves when the image is shown in the tooltip or
|
||||
* resolves when the broken image tooltip content is ready, but never rejects.
|
||||
*/
|
||||
setRelativeImageContent: function(imageUrl, inspectorFront, maxDim) {
|
||||
setRelativeImageContent: Task.async(function*(imageUrl, inspectorFront, maxDim) {
|
||||
if (imageUrl.startsWith("data:")) {
|
||||
// If the imageUrl already is a data-url, save ourselves a round-trip
|
||||
this.setImageContent(imageUrl, {maxDim: maxDim});
|
||||
return promise.resolve();
|
||||
} else if (inspectorFront) {
|
||||
return inspectorFront.getImageDataFromURL(imageUrl, maxDim).then(res => {
|
||||
res.size.maxDim = maxDim;
|
||||
return res.data.string().then(str => {
|
||||
this.setImageContent(str, res.size);
|
||||
});
|
||||
}, () => {
|
||||
try {
|
||||
let {data, size} = yield inspectorFront.getImageDataFromURL(imageUrl, maxDim);
|
||||
size.maxDim = maxDim;
|
||||
let str = yield data.string();
|
||||
this.setImageContent(str, size);
|
||||
} catch (e) {
|
||||
this.setBrokenImageContent();
|
||||
});
|
||||
}
|
||||
}
|
||||
return promise.resolve();
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Fill the tooltip with a message explaining the the image is missing
|
||||
|
@ -732,71 +734,57 @@ Tooltip.prototype = {
|
|||
* @param {NodeActor} node
|
||||
* The NodeActor for the currently selected node
|
||||
* @return A promise that resolves when the tooltip content is ready, or
|
||||
* rejects if no transform is provided or is invalid
|
||||
* rejects if no transform is provided or the transform is invalid
|
||||
*/
|
||||
setCssTransformContent: function(transform, pageStyle, node) {
|
||||
let def = promise.defer();
|
||||
|
||||
if (transform) {
|
||||
// Look into the computed styles to find the width and height and possibly
|
||||
// the origin if it hadn't been provided
|
||||
pageStyle.getComputed(node, {
|
||||
filter: "user",
|
||||
markMatched: false,
|
||||
onlyMatched: false
|
||||
}).then(styles => {
|
||||
let origin = styles["transform-origin"].value;
|
||||
let width = parseInt(styles["width"].value);
|
||||
let height = parseInt(styles["height"].value);
|
||||
|
||||
let root = this.doc.createElementNS(XHTML_NS, "div");
|
||||
let previewer = new CSSTransformPreviewer(root);
|
||||
this.content = root;
|
||||
if (!previewer.preview(transform, origin, width, height)) {
|
||||
def.reject();
|
||||
} else {
|
||||
def.resolve();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
def.reject();
|
||||
setCssTransformContent: Task.async(function*(transform, pageStyle, node) {
|
||||
if (!transform) {
|
||||
throw "Missing transform";
|
||||
}
|
||||
|
||||
return def.promise;
|
||||
},
|
||||
// Look into the computed styles to find the width and height and possibly
|
||||
// the origin if it hadn't been provided
|
||||
let styles = yield pageStyle.getComputed(node, {
|
||||
filter: "user",
|
||||
markMatched: false,
|
||||
onlyMatched: false
|
||||
});
|
||||
|
||||
let origin = styles["transform-origin"].value;
|
||||
let width = parseInt(styles["width"].value);
|
||||
let height = parseInt(styles["height"].value);
|
||||
|
||||
let root = this.doc.createElementNS(XHTML_NS, "div");
|
||||
let previewer = new CSSTransformPreviewer(root);
|
||||
this.content = root;
|
||||
if (!previewer.preview(transform, origin, width, height)) {
|
||||
throw "Invalid transform";
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* 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
|
||||
* for more info.
|
||||
*
|
||||
* @param {String} font
|
||||
* The font family value.
|
||||
* @param {String} font The font family value.
|
||||
*/
|
||||
setFontFamilyContent: function(font) {
|
||||
let def = promise.defer();
|
||||
|
||||
if (font) {
|
||||
// Main container
|
||||
let vbox = this.doc.createElement("vbox");
|
||||
vbox.setAttribute("flex", "1");
|
||||
|
||||
// Display the font family previewer
|
||||
let previewer = this.doc.createElement("description");
|
||||
previewer.setAttribute("flex", "1");
|
||||
previewer.style.fontFamily = font;
|
||||
previewer.classList.add("devtools-tooltip-font-previewer-text");
|
||||
previewer.textContent = "(ABCabc123&@%)";
|
||||
vbox.appendChild(previewer);
|
||||
|
||||
this.content = vbox;
|
||||
|
||||
def.resolve();
|
||||
} else {
|
||||
def.reject();
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
|
||||
return def.promise;
|
||||
// Main container
|
||||
let vbox = this.doc.createElement("vbox");
|
||||
vbox.setAttribute("flex", "1");
|
||||
|
||||
// Display the font family previewer
|
||||
let previewer = this.doc.createElement("description");
|
||||
previewer.setAttribute("flex", "1");
|
||||
previewer.style.fontFamily = font;
|
||||
previewer.classList.add("devtools-tooltip-font-previewer-text");
|
||||
previewer.textContent = FONT_FAMILY_PREVIEW_TEXT;
|
||||
vbox.appendChild(previewer);
|
||||
|
||||
this.content = vbox;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -843,6 +831,7 @@ SwatchBasedEditorTooltip.prototype = {
|
|||
show: function() {
|
||||
if (this.activeSwatch) {
|
||||
this.tooltip.show(this.activeSwatch, "topcenter bottomleft");
|
||||
this.tooltip.once("hidden", () => this.activeSwatch = null);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -860,6 +849,13 @@ SwatchBasedEditorTooltip.prototype = {
|
|||
* @param {object} callbacks
|
||||
* Callbacks that will be executed when the editor wants to preview a
|
||||
* value change, or revert a change, or commit a change.
|
||||
* - onPreview: will be called when one of the sub-classes calls preview
|
||||
* - onRevert: will be called when the user ESCapes out of the tooltip
|
||||
* - onCommit: will be called when the user presses ENTER or clicks
|
||||
* outside the tooltip. If the user-defined onCommit returns a value,
|
||||
* it will be used to replace originalValue, so that the swatch-based
|
||||
* tooltip always knows what is the current originalValue and can use
|
||||
* it when reverting
|
||||
* @param {object} originalValue
|
||||
* The original value before the editor in the tooltip makes changes
|
||||
* This can be of any type, and will be passed, as is, in the revert
|
||||
|
@ -923,7 +919,10 @@ SwatchBasedEditorTooltip.prototype = {
|
|||
commit: function() {
|
||||
if (this.activeSwatch) {
|
||||
let swatch = this.swatches.get(this.activeSwatch);
|
||||
swatch.callbacks.onCommit();
|
||||
let newValue = swatch.callbacks.onCommit();
|
||||
if (typeof newValue !== "undefined") {
|
||||
swatch.originalValue = newValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -965,6 +964,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
|||
SwatchBasedEditorTooltip.prototype.show.call(this);
|
||||
// Then set spectrum's color and listen to color changes to preview them
|
||||
if (this.activeSwatch) {
|
||||
this.currentSwatchColor = this.activeSwatch.nextSibling;
|
||||
let swatch = this.swatches.get(this.activeSwatch);
|
||||
let color = this.activeSwatch.style.backgroundColor;
|
||||
this.spectrum.then(spectrum => {
|
||||
|
@ -979,7 +979,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
|||
_onSpectrumColorChange: function(event, rgba, cssColor) {
|
||||
if (this.activeSwatch) {
|
||||
this.activeSwatch.style.backgroundColor = cssColor;
|
||||
this.activeSwatch.nextSibling.textContent = cssColor;
|
||||
this.currentSwatchColor.textContent = cssColor;
|
||||
this.preview(cssColor);
|
||||
}
|
||||
},
|
||||
|
@ -992,6 +992,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
|||
|
||||
destroy: function() {
|
||||
SwatchBasedEditorTooltip.prototype.destroy.call(this);
|
||||
this.currentSwatchColor = null;
|
||||
this.spectrum.then(spectrum => {
|
||||
spectrum.off("changed", this._onSpectrumColorChange);
|
||||
spectrum.destroy();
|
||||
|
|
|
@ -2494,15 +2494,11 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
|||
|
||||
let valueLabel = this._valueLabel = document.createElement("label");
|
||||
valueLabel.className = "plain value";
|
||||
valueLabel.setAttribute("flex", "1");
|
||||
valueLabel.setAttribute("crop", "center");
|
||||
|
||||
let spacer = this._spacer = document.createElement("spacer");
|
||||
spacer.setAttribute("optional-visibility", "");
|
||||
spacer.setAttribute("flex", "1");
|
||||
|
||||
this._title.appendChild(separatorLabel);
|
||||
this._title.appendChild(valueLabel);
|
||||
this._title.appendChild(spacer);
|
||||
|
||||
if (VariablesView.isPrimitive(descriptor)) {
|
||||
this.hideArrow();
|
||||
|
@ -3867,6 +3863,7 @@ Editable.prototype = {
|
|||
let input = this._input = this._variable.document.createElement("textbox");
|
||||
input.className = "plain " + this.className;
|
||||
input.setAttribute("value", initialString);
|
||||
input.setAttribute("flex", "1");
|
||||
|
||||
// Replace the specified label with a textbox input element.
|
||||
label.parentNode.replaceChild(input, label);
|
||||
|
|
|
@ -172,14 +172,16 @@ StyleSheetEditor.prototype = {
|
|||
let relatedSheet = this.styleSheet.relatedStyleSheet;
|
||||
|
||||
let path;
|
||||
var uri = NetUtil.newURI(relatedSheet.href);
|
||||
let href = removeQuery(relatedSheet.href);
|
||||
let uri = NetUtil.newURI(href);
|
||||
|
||||
if (uri.scheme == "file") {
|
||||
var file = uri.QueryInterface(Ci.nsIFileURL).file;
|
||||
let file = uri.QueryInterface(Ci.nsIFileURL).file;
|
||||
path = file.path;
|
||||
}
|
||||
else if (this.savedFile) {
|
||||
let origUri = NetUtil.newURI(this.styleSheet.href);
|
||||
let origHref = removeQuery(this.styleSheet.href);
|
||||
let origUri = NetUtil.newURI(origHref);
|
||||
path = findLinkedFilePath(uri, origUri, this.savedFile);
|
||||
}
|
||||
else {
|
||||
|
@ -700,3 +702,15 @@ function findUnsharedBranches(origUri, uri) {
|
|||
origBranch: origUri
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the query string from a url.
|
||||
*
|
||||
* @param {string} href
|
||||
* Url to remove query string from
|
||||
* @return {string}
|
||||
* Url without query string
|
||||
*/
|
||||
function removeQuery(href) {
|
||||
return href.replace(/\?.*/, "");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>testcase for testing CSS source maps</title>
|
||||
<link rel="stylesheet" type="text/css" href="simple.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="sourcemap-css/sourcemaps.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="sourcemap-css/sourcemaps.css?test=1"/>
|
||||
</head>
|
||||
<body>
|
||||
<div>source maps <span>testcase</span></div>
|
||||
|
|
|
@ -543,7 +543,8 @@ CssHtmlTree.prototype = {
|
|||
|
||||
// Test for font family
|
||||
if (propName.textContent === "font-family") {
|
||||
return this.tooltip.setFontFamilyContent(propValue.textContent);
|
||||
this.tooltip.setFontFamilyContent(propValue.textContent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -541,8 +541,8 @@ Rule.prototype = {
|
|||
|
||||
/**
|
||||
* Reapply all the properties in this rule, and update their
|
||||
* computed styles. Store disabled properties in the element
|
||||
* style's store. Will re-mark overridden properties.
|
||||
* computed styles. Store disabled properties in the element
|
||||
* style's store. Will re-mark overridden properties.
|
||||
*
|
||||
* @param {string} [aName]
|
||||
* A text property name (such as "background" or "border-top") used
|
||||
|
@ -645,7 +645,7 @@ Rule.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Sets the value and priority of a property.
|
||||
* Sets the value and priority of a property, then reapply all properties.
|
||||
*
|
||||
* @param {TextProperty} aProperty
|
||||
* The property to manipulate.
|
||||
|
@ -664,8 +664,29 @@ Rule.prototype = {
|
|||
this.applyProperties(null, aProperty.name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Just sets the value and priority of a property, in order to preview its
|
||||
* effect on the content document.
|
||||
*
|
||||
* @param {TextProperty} aProperty
|
||||
* The property which value will be previewed
|
||||
* @param {String} aValue
|
||||
* The value to be used for the preview
|
||||
* @param {String} aPriority
|
||||
* The property's priority (either "important" or an empty string).
|
||||
*/
|
||||
previewPropertyValue: function(aProperty, aValue, aPriority) {
|
||||
let modifications = this.style.startModifyingProperties();
|
||||
modifications.setProperty(aProperty.name, aValue, aPriority);
|
||||
modifications.apply();
|
||||
},
|
||||
|
||||
/**
|
||||
* Disables or enables given TextProperty.
|
||||
*
|
||||
* @param {TextProperty} aProperty
|
||||
* The property to enable/disable
|
||||
* @param {Boolean} aValue
|
||||
*/
|
||||
setPropertyEnabled: function(aProperty, aValue) {
|
||||
aProperty.enabled = !!aValue;
|
||||
|
@ -679,6 +700,9 @@ Rule.prototype = {
|
|||
/**
|
||||
* Remove a given TextProperty from the rule and update the rule
|
||||
* accordingly.
|
||||
*
|
||||
* @param {TextProperty} aProperty
|
||||
* The property to be removed
|
||||
*/
|
||||
removeProperty: function(aProperty) {
|
||||
this.textProps = this.textProps.filter(function(prop) prop != aProperty);
|
||||
|
@ -1114,66 +1138,80 @@ CssRuleView.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Executed by the tooltip when the pointer hovers over an element of the view.
|
||||
* Used to decide whether the tooltip should be shown or not and to actually
|
||||
* put content in it.
|
||||
* Checks if the hovered target is a css value we support tooltips for.
|
||||
* Which type of hover-tooltip should be shown for the given element?
|
||||
* This depends on the element: does it contain an image URL, a CSS transform,
|
||||
* a font-family, ...
|
||||
* @param {DOMNode} el The element to test
|
||||
* @return {String} The type of hover-tooltip
|
||||
*/
|
||||
_onTooltipTargetHover: function(target) {
|
||||
let property = target.textProperty, def = promise.defer(), hasTooltip = false;
|
||||
_getHoverTooltipTypeForTarget: function(el) {
|
||||
let prop = el.textProperty;
|
||||
|
||||
// Test for css transform
|
||||
if (property && property.name === "transform") {
|
||||
this.previewTooltip.setCssTransformContent(property.value, this.pageStyle,
|
||||
this._viewedElement).then(def.resolve, def.reject);
|
||||
hasTooltip = true;
|
||||
if (prop && prop.name === "transform") {
|
||||
return "transform";
|
||||
}
|
||||
|
||||
// Test for image
|
||||
if (this.inspector.hasUrlToImageDataResolver) {
|
||||
let isImageHref = target.classList.contains("theme-link") &&
|
||||
target.parentNode.classList.contains("ruleview-propertyvalue");
|
||||
if (isImageHref) {
|
||||
property = target.parentNode.textProperty;
|
||||
|
||||
let maxDim = Services.prefs.getIntPref("devtools.inspector.imagePreviewTooltipSize");
|
||||
let uri = CssLogic.getBackgroundImageUriFromProperty(property.value,
|
||||
property.rule.domRule.href);
|
||||
this.previewTooltip.setRelativeImageContent(uri,
|
||||
this.inspector.inspector, maxDim).then(def.resolve);
|
||||
hasTooltip = true;
|
||||
}
|
||||
let isUrl = el.classList.contains("theme-link") &&
|
||||
el.parentNode.classList.contains("ruleview-propertyvalue");
|
||||
if (this.inspector.hasUrlToImageDataResolver && isUrl) {
|
||||
return "image";
|
||||
}
|
||||
|
||||
// Get the nodes containing the property name and property value,
|
||||
// and test for font family
|
||||
let propertyRoot = target.parentNode;
|
||||
// Test for font-family
|
||||
let propertyRoot = el.parentNode;
|
||||
let propertyNameNode = propertyRoot.querySelector(".ruleview-propertyname");
|
||||
|
||||
if (!propertyNameNode) {
|
||||
propertyRoot = propertyRoot.parentNode;
|
||||
propertyNameNode = propertyRoot.querySelector(".ruleview-propertyname");
|
||||
}
|
||||
|
||||
let propertyName;
|
||||
if (propertyNameNode) {
|
||||
propertyName = propertyNameNode.textContent;
|
||||
}
|
||||
if (propertyName === "font-family" && el.classList.contains("ruleview-propertyvalue")) {
|
||||
return "font";
|
||||
}
|
||||
},
|
||||
|
||||
if (propertyName === "font-family" &&
|
||||
target.classList.contains("ruleview-propertyvalue")) {
|
||||
this.previewTooltip.setFontFamilyContent(target.textContent).then(def.resolve);
|
||||
hasTooltip = true;
|
||||
/**
|
||||
* Executed by the tooltip when the pointer hovers over an element of the view.
|
||||
* Used to decide whether the tooltip should be shown or not and to actually
|
||||
* put content in it.
|
||||
* Checks if the hovered target is a css value we support tooltips for.
|
||||
* @param {DOMNode} target
|
||||
* @return {Boolean|Promise} Either a boolean or a promise, used by the
|
||||
* Tooltip class to wait for the content to be put in the tooltip and finally
|
||||
* decide whether or not the tooltip should be shown.
|
||||
*/
|
||||
_onTooltipTargetHover: function(target) {
|
||||
let tooltipType = this._getHoverTooltipTypeForTarget(target);
|
||||
if (!tooltipType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasTooltip) {
|
||||
def.reject();
|
||||
} else if (this.colorPicker.tooltip.isShown()) {
|
||||
if (this.colorPicker.tooltip.isShown()) {
|
||||
this.colorPicker.revert();
|
||||
this.colorPicker.hide();
|
||||
}
|
||||
|
||||
return def.promise;
|
||||
if (tooltipType === "transform") {
|
||||
return this.previewTooltip.setCssTransformContent(target.textProperty.value,
|
||||
this.pageStyle, this._viewedElement);
|
||||
}
|
||||
if (tooltipType === "image") {
|
||||
let prop = target.parentNode.textProperty;
|
||||
let dim = Services.prefs.getIntPref("devtools.inspector.imagePreviewTooltipSize");
|
||||
let uri = CssLogic.getBackgroundImageUriFromProperty(prop.value, prop.rule.domRule.href);
|
||||
return this.previewTooltip.setRelativeImageContent(uri, this.inspector.inspector, dim);
|
||||
}
|
||||
if (tooltipType === "font") {
|
||||
this.previewTooltip.setFontFamilyContent(target.textContent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1937,7 +1975,7 @@ function TextPropertyEditor(aRuleEditor, aProperty) {
|
|||
this._onStartEditing = this._onStartEditing.bind(this);
|
||||
this._onNameDone = this._onNameDone.bind(this);
|
||||
this._onValueDone = this._onValueDone.bind(this);
|
||||
this._onValidate = throttle(this._livePreview, 10, this);
|
||||
this._onValidate = throttle(this._previewValue, 10, this);
|
||||
this.update = this.update.bind(this);
|
||||
|
||||
this._create();
|
||||
|
@ -2188,18 +2226,15 @@ TextPropertyEditor.prototype = {
|
|||
|
||||
// Attach the color picker tooltip to the color swatches
|
||||
this._swatchSpans = this.valueSpan.querySelectorAll("." + swatchClass);
|
||||
if (this._swatchSpans.length) {
|
||||
for (let span of this._swatchSpans) {
|
||||
// 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.colorPicker.addSwatch(span, {
|
||||
onPreview: () => this._livePreview(this.valueSpan.textContent),
|
||||
onCommit: () => this._applyNewValue(this.valueSpan.textContent),
|
||||
onRevert: () => this._applyNewValue(originalValue)
|
||||
});
|
||||
}
|
||||
for (let span of this._swatchSpans) {
|
||||
// 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.colorPicker.addSwatch(span, {
|
||||
onPreview: () => this._previewValue(this.valueSpan.textContent),
|
||||
onCommit: () => this._applyNewValue(this.valueSpan.textContent),
|
||||
onRevert: () => this._applyNewValue(originalValue)
|
||||
});
|
||||
}
|
||||
|
||||
// Populate the computed styles.
|
||||
|
@ -2208,7 +2243,7 @@ TextPropertyEditor.prototype = {
|
|||
|
||||
_onStartEditing: function() {
|
||||
this.element.classList.remove("ruleview-overridden");
|
||||
this._livePreview(this.prop.value);
|
||||
this._previewValue(this.prop.value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2328,7 +2363,6 @@ TextPropertyEditor.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Remove property from style and the editors from DOM.
|
||||
* Begin editing next available property.
|
||||
|
@ -2440,34 +2474,25 @@ TextPropertyEditor.prototype = {
|
|||
|
||||
_applyNewValue: function(aValue) {
|
||||
let val = parseSingleValue(aValue);
|
||||
// Any property should be removed if has an empty value.
|
||||
if (val.value.trim() === "") {
|
||||
this.remove();
|
||||
} else {
|
||||
this.prop.setValue(val.value, val.priority);
|
||||
this.removeOnRevert = false;
|
||||
this.committed.value = this.prop.value;
|
||||
this.committed.priority = this.prop.priority;
|
||||
}
|
||||
|
||||
this.prop.setValue(val.value, val.priority);
|
||||
this.removeOnRevert = false;
|
||||
this.committed.value = this.prop.value;
|
||||
this.committed.priority = this.prop.priority;
|
||||
},
|
||||
|
||||
/**
|
||||
* Live preview this property, without committing changes.
|
||||
*
|
||||
* @param {string} [aValue]
|
||||
* The value to set the current property to.
|
||||
* @param {string} aValue The value to set the current property to.
|
||||
*/
|
||||
_livePreview: function(aValue) {
|
||||
_previewValue: function(aValue) {
|
||||
// Since function call is throttled, we need to make sure we are still editing
|
||||
if (!this.editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
let val = parseSingleValue(aValue);
|
||||
|
||||
// Live previewing the change without committing just yet, that'll be done in _onValueDone
|
||||
// If it was not a valid value, apply an empty string to reset the live preview
|
||||
this.ruleEditor.rule.setPropertyValue(this.prop, val.value, val.priority);
|
||||
this.ruleEditor.rule.previewPropertyValue(this.prop, val.value, val.priority);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,7 +55,6 @@ support-files = browser_ruleview_pseudoelement.html
|
|||
[browser_computedview_bug835808_keyboard_nav.js]
|
||||
[browser_bug913014_matched_expand.js]
|
||||
[browser_bug765105_background_image_tooltip.js]
|
||||
[browser_bug889638_rule_view_color_picker.js]
|
||||
[browser_bug726427_csstransform_tooltip.js]
|
||||
[browser_bug702577_fontfamily_tooltip_shorthand.js]
|
||||
[browser_bug702577_fontfamily_tooltip_longhand.js]
|
||||
|
@ -71,3 +70,11 @@ support-files =
|
|||
[browser_bug942297_user_property_reset.js]
|
||||
[browser_styleinspector_outputparser.js]
|
||||
[browser_bug970532_mathml_element.js]
|
||||
[browser_ruleview_colorpicker-swatch-displayed.js]
|
||||
[browser_ruleview_colorpicker-appears-on-swatch-click.js]
|
||||
[browser_ruleview_colorpicker-hides-on-tooltip.js]
|
||||
[browser_ruleview_colorpicker-revert-on-ESC.js]
|
||||
[browser_ruleview_colorpicker-commit-on-ENTER.js]
|
||||
[browser_ruleview_colorpicker-and-image-tooltip_01.js]
|
||||
[browser_ruleview_colorpicker-and-image-tooltip_02.js]
|
||||
[browser_ruleview_colorpicker-multiple-changes.js]
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||
|
||||
let contentDoc;
|
||||
let contentWin;
|
||||
let inspector;
|
||||
let ruleView;
|
||||
let swatches = [];
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' color: red;',
|
||||
' background-color: #ededed;',
|
||||
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||
contentDoc = content.document;
|
||||
contentWin = contentDoc.defaultView;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((aInspector, aRuleView) => {
|
||||
inspector = aInspector;
|
||||
ruleView = aRuleView;
|
||||
startTests();
|
||||
});
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
inspector.selection.setNode(contentDoc.body);
|
||||
inspector.once("inspector-updated", testColorSwatchesAreDisplayed);
|
||||
}
|
||||
|
||||
function endTests() {
|
||||
executeSoon(function() {
|
||||
gDevTools.once("toolbox-destroyed", () => {
|
||||
contentDoc = contentWin = inspector = ruleView = swatches = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
inspector._toolbox.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
function testColorSwatchesAreDisplayed() {
|
||||
let cSwatch = getRuleViewProperty("color").valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(cSwatch, "Color swatch is displayed for the color property");
|
||||
|
||||
let bgSwatch = getRuleViewProperty("background-color").valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(bgSwatch, "Color swatch is displayed for the bg-color property");
|
||||
|
||||
let bSwatch = getRuleViewProperty("border").valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(bSwatch, "Color swatch is displayed for the border property");
|
||||
|
||||
swatches = [cSwatch, bgSwatch, bSwatch];
|
||||
|
||||
testColorPickerAppearsOnColorSwatchClick();
|
||||
}
|
||||
|
||||
function testColorPickerAppearsOnColorSwatchClick() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
let cPickerPanel = cPicker.tooltip.panel;
|
||||
ok(cPickerPanel, "The XUL panel for the color picker exists");
|
||||
|
||||
function clickOnSwatch(index, cb) {
|
||||
if (index === swatches.length) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
let swatch = swatches[index];
|
||||
cPicker.tooltip.once("shown", () => {
|
||||
ok(true, "The color picker was shown on click of the color swatch");
|
||||
ok(!inplaceEditor(swatch.parentNode),
|
||||
"The inplace editor wasn't shown as a result of the color swatch click");
|
||||
cPicker.hide();
|
||||
clickOnSwatch(index + 1, cb);
|
||||
});
|
||||
swatch.click();
|
||||
}
|
||||
|
||||
clickOnSwatch(0, testColorPickerHidesWhenImageTooltipAppears);
|
||||
}
|
||||
|
||||
function testColorPickerHidesWhenImageTooltipAppears() {
|
||||
Task.spawn(function*() {
|
||||
let swatch = swatches[0];
|
||||
let bgImageSpan = getRuleViewProperty("background-image").valueSpan;
|
||||
let uriSpan = bgImageSpan.querySelector(".theme-link");
|
||||
let tooltip = ruleView.colorPicker.tooltip;
|
||||
|
||||
info("Showing the color picker tooltip by clicking on the color swatch");
|
||||
let onShown = tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Now showing the image preview tooltip to hide the color picker");
|
||||
let onHidden = tooltip.once("hidden");
|
||||
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||
yield onHidden;
|
||||
|
||||
ok(true, "The color picker closed when the image preview tooltip appeared");
|
||||
}).then(testPressingEscapeRevertsChanges);
|
||||
}
|
||||
|
||||
function testPressingEscapeRevertsChanges() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
let swatch = swatches[1];
|
||||
|
||||
cPicker.tooltip.once("shown", () => {
|
||||
simulateColorChange(cPicker, [0, 0, 0, 1]);
|
||||
|
||||
is(swatch.style.backgroundColor, "rgb(0, 0, 0)",
|
||||
"The color swatch's background was updated");
|
||||
is(getRuleViewProperty("background-color").valueSpan.textContent, "rgba(0, 0, 0, 1)",
|
||||
"The text of the background-color css property was updated");
|
||||
|
||||
// The change to the content element is done async, via the protocol,
|
||||
// that's why we need to let it go first
|
||||
executeSoon(() => {
|
||||
is(contentWin.getComputedStyle(contentDoc.body).backgroundColor,
|
||||
"rgb(0, 0, 0)", "The element's background-color was changed");
|
||||
|
||||
cPicker.spectrum.then(spectrum => {
|
||||
// ESC out of the color picker
|
||||
EventUtils.sendKey("ESCAPE", spectrum.element.ownerDocument.defaultView);
|
||||
executeSoon(() => {
|
||||
is(contentWin.getComputedStyle(contentDoc.body).backgroundColor,
|
||||
"rgb(237, 237, 237)", "The element's background-color was reverted");
|
||||
|
||||
testPressingEnterCommitsChanges();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
swatch.click();
|
||||
}
|
||||
|
||||
function testPressingEnterCommitsChanges() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
let swatch = swatches[2]; // That's the border css declaration
|
||||
|
||||
cPicker.tooltip.once("shown", () => {
|
||||
simulateColorChange(cPicker, [0, 255, 0, .5]);
|
||||
|
||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||
"The color swatch's background was updated");
|
||||
is(getRuleViewProperty("border").valueSpan.textContent,
|
||||
"2em solid rgba(0, 255, 0, 0.5)",
|
||||
"The text of the border css property was updated");
|
||||
|
||||
// The change to the content element is done async, via the protocol,
|
||||
// that's why we need to let it go first
|
||||
executeSoon(() => {
|
||||
is(contentWin.getComputedStyle(contentDoc.body).borderLeftColor,
|
||||
"rgba(0, 255, 0, 0.5)", "The element's border was changed");
|
||||
|
||||
cPicker.tooltip.once("hidden", () => {
|
||||
is(contentWin.getComputedStyle(contentDoc.body).borderLeftColor,
|
||||
"rgba(0, 255, 0, 0.5)", "The element's border was kept after RETURN");
|
||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||
"The color swatch's background was kept after RETURN");
|
||||
is(getRuleViewProperty("border").valueSpan.textContent,
|
||||
"2em solid rgba(0, 255, 0, 0.5)",
|
||||
"The text of the border css property was kept after RETURN");
|
||||
|
||||
endTests();
|
||||
});
|
||||
|
||||
cPicker.spectrum.then(spectrum => {
|
||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
swatch.click();
|
||||
}
|
||||
|
||||
function simulateColorChange(colorPicker, newRgba) {
|
||||
// Note that this test isn't concerned with simulating events to test how the
|
||||
// spectrum color picker reacts, see browser_spectrum.js for this.
|
||||
// This test only cares about the color swatch <-> color picker <-> rule view
|
||||
// interactions. That's why there's no event simulations here
|
||||
colorPicker.spectrum.then(spectrum => {
|
||||
spectrum.rgb = newRgba;
|
||||
spectrum.updateUI();
|
||||
spectrum.onChange();
|
||||
});
|
||||
}
|
||||
|
||||
function getRuleViewProperty(name) {
|
||||
let prop = null;
|
||||
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
|
||||
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||
|
||||
if (nameSpan.textContent === name) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
}
|
||||
});
|
||||
return prop;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/* 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 after a color change, the image preview tooltip in the same
|
||||
// property is displayed and positioned correctly.
|
||||
// See bug 979292
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' background: url("chrome://global/skin/icons/warning-64.png"), linear-gradient(white, #F06 400px);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, ruleView) => {
|
||||
inspector.once("inspector-updated", () => {
|
||||
let value = getRuleViewProperty("background", ruleView).valueSpan;
|
||||
let swatch = value.querySelector(".ruleview-colorswatch");
|
||||
let url = value.querySelector(".theme-link");
|
||||
testImageTooltipAfterColorChange(swatch, url, ruleView);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testImageTooltipAfterColorChange(swatch, url, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
info("First, verify that the image preview tooltip works");
|
||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||
ok(anchor, "The image preview tooltip is shown on the url span");
|
||||
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
||||
|
||||
info("Open the color picker tooltip and change the color");
|
||||
let picker = ruleView.colorPicker;
|
||||
let onShown = picker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
yield simulateColorChange(picker, [0, 0, 0, 1], {
|
||||
element: content.document.body,
|
||||
name: "backgroundImage",
|
||||
value: 'url("chrome://global/skin/icons/warning-64.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 0, 102) 400px)'
|
||||
});
|
||||
|
||||
let spectrum = yield picker.spectrum;
|
||||
let onHidden = picker.tooltip.once("hidden");
|
||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
info("Verify again that the image preview tooltip works");
|
||||
// After a color change, the property is re-populated, we need to get the new
|
||||
// dom node
|
||||
url = getRuleViewProperty("background", ruleView).valueSpan.querySelector(".theme-link");
|
||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||
ok(anchor, "The image preview tooltip is shown on the url span");
|
||||
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
||||
}).then(finish);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* 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 after a color change, opening another tooltip, like the image
|
||||
// preview doesn't revert the color change in the ruleView.
|
||||
// This used to happen when the activeSwatch wasn't reset when the colorpicker
|
||||
// would hide.
|
||||
// See bug 979292
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' background: red url("chrome://global/skin/icons/warning-64.png") no-repeat center center;',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, ruleView) => {
|
||||
inspector.once("inspector-updated", () => {
|
||||
testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
|
||||
Task.spawn(function*() {
|
||||
let swatch = getRuleViewProperty("background", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
|
||||
info("Open the color picker tooltip and change the color");
|
||||
let picker = ruleView.colorPicker;
|
||||
let onShown = picker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
yield simulateColorChange(picker, [0, 0, 0, 1], {
|
||||
element: content.document.body,
|
||||
name: "backgroundColor",
|
||||
value: "rgb(0, 0, 0)"
|
||||
});
|
||||
let spectrum = yield picker.spectrum;
|
||||
let onHidden = picker.tooltip.once("hidden");
|
||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
info("Open the image preview tooltip");
|
||||
let value = getRuleViewProperty("background", ruleView).valueSpan;
|
||||
let url = value.querySelector(".theme-link");
|
||||
let onShown = ruleView.previewTooltip.once("shown");
|
||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||
ruleView.previewTooltip.show(anchor);
|
||||
yield onShown;
|
||||
|
||||
info("Image tooltip is shown, verify that the swatch is still correct");
|
||||
let swatch = value.querySelector(".ruleview-colorswatch");
|
||||
is(swatch.style.backgroundColor, "rgb(0, 0, 0)", "The swatch's color is correct");
|
||||
is(swatch.nextSibling.textContent, "#000", "The color name is correct");
|
||||
}).then(finish);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* 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 color pickers appear when clicking on color swatches
|
||||
|
||||
let ruleView, swatches;
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' color: red;',
|
||||
' background-color: #ededed;',
|
||||
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, view) => {
|
||||
ruleView = view;
|
||||
inspector.once("inspector-updated", () => {
|
||||
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
swatches = [cSwatch, bgSwatch, bSwatch];
|
||||
|
||||
testColorPickerAppearsOnColorSwatchClick();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testColorPickerAppearsOnColorSwatchClick() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
let cPickerPanel = cPicker.tooltip.panel;
|
||||
ok(cPickerPanel, "The XUL panel for the color picker exists");
|
||||
|
||||
function clickOnSwatch(index, cb) {
|
||||
if (index === swatches.length) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
let swatch = swatches[index];
|
||||
cPicker.tooltip.once("shown", () => {
|
||||
ok(true, "The color picker was shown on click of the color swatch");
|
||||
ok(!inplaceEditor(swatch.parentNode),
|
||||
"The inplace editor wasn't shown as a result of the color swatch click");
|
||||
cPicker.hide();
|
||||
clickOnSwatch(index + 1, cb);
|
||||
});
|
||||
swatch.click();
|
||||
}
|
||||
|
||||
clickOnSwatch(0, () => {
|
||||
ruleView = swatches = null;
|
||||
finish();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* 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 color change in the color picker is committed when ENTER is pressed
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, ruleView) => {
|
||||
inspector.once("inspector-updated", () => {
|
||||
let swatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
testPressingEnterCommitsChanges(swatch, ruleView);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testPressingEnterCommitsChanges(swatch, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
|
||||
let onShown = cPicker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
yield simulateColorChange(cPicker, [0, 255, 0, .5], {
|
||||
element: content.document.body,
|
||||
name: "borderLeftColor",
|
||||
value: "rgba(0, 255, 0, 0.5)"
|
||||
});
|
||||
|
||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||
"The color swatch's background was updated");
|
||||
is(getRuleViewProperty("border", ruleView).valueSpan.textContent,
|
||||
"2em solid rgba(0, 255, 0, 0.5)",
|
||||
"The text of the border css property was updated");;
|
||||
|
||||
let spectrum = yield cPicker.spectrum;
|
||||
let onHidden = cPicker.tooltip.once("hidden");
|
||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
is(content.getComputedStyle(content.document.body).borderLeftColor,
|
||||
"rgba(0, 255, 0, 0.5)", "The element's border was kept after RETURN");
|
||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||
"The color swatch's background was kept after RETURN");
|
||||
is(getRuleViewProperty("border", ruleView).valueSpan.textContent,
|
||||
"2em solid rgba(0, 255, 0, 0.5)",
|
||||
"The text of the border css property was kept after RETURN");
|
||||
}).then(finish);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/* 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 the color picker tooltip hides when an image or transform
|
||||
// tooltip appears
|
||||
|
||||
let ruleView, swatches;
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' color: red;',
|
||||
' background-color: #ededed;',
|
||||
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||
' transform: skew(-16deg);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, view) => {
|
||||
ruleView = view;
|
||||
inspector.once("inspector-updated", () => {
|
||||
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
swatches = [cSwatch, bgSwatch, bSwatch];
|
||||
|
||||
testColorPickerHidesWhenImageTooltipAppears();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testColorPickerHidesWhenImageTooltipAppears() {
|
||||
Task.spawn(function*() {
|
||||
let swatch = swatches[0];
|
||||
let bgImageSpan = getRuleViewProperty("background-image", ruleView).valueSpan;
|
||||
let uriSpan = bgImageSpan.querySelector(".theme-link");
|
||||
let tooltip = ruleView.colorPicker.tooltip;
|
||||
|
||||
info("Showing the color picker tooltip by clicking on the color swatch");
|
||||
let onShown = tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Now showing the image preview tooltip to hide the color picker");
|
||||
let onHidden = tooltip.once("hidden");
|
||||
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||
yield onHidden;
|
||||
|
||||
ok(true, "The color picker closed when the image preview tooltip appeared");
|
||||
}).then(testColorPickerHidesWhenTransformTooltipAppears);
|
||||
}
|
||||
|
||||
function testColorPickerHidesWhenTransformTooltipAppears() {
|
||||
Task.spawn(function*() {
|
||||
let swatch = swatches[0];
|
||||
let transformSpan = getRuleViewProperty("transform", ruleView).valueSpan;
|
||||
let tooltip = ruleView.colorPicker.tooltip;
|
||||
|
||||
info("Showing the color picker tooltip by clicking on the color swatch");
|
||||
let onShown = tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Now showing the transform preview tooltip to hide the color picker");
|
||||
let onHidden = tooltip.once("hidden");
|
||||
yield assertTooltipShownOn(ruleView.previewTooltip, transformSpan);
|
||||
yield onHidden;
|
||||
|
||||
ok(true, "The color picker closed when the transform preview tooltip appeared");
|
||||
}).then(() => {
|
||||
swatches = ruleView = null;
|
||||
finish();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/* 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 the color in the colorpicker tooltip can be changed several times
|
||||
// without causing error in various cases:
|
||||
// - simple single-color property (color)
|
||||
// - color and image property (background-image)
|
||||
// - overridden property
|
||||
// See bug 979292 and bug 980225
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' color: green;',
|
||||
' background: red url("chrome://global/skin/icons/warning-64.png") no-repeat center center;',
|
||||
' }',
|
||||
' p {',
|
||||
' color: blue;',
|
||||
' }',
|
||||
'</style>',
|
||||
'<p>Testing the color picker tooltip!</p>'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, ruleView) => {
|
||||
inspector.once("inspector-updated", () => {
|
||||
testSimpleMultipleColorChanges(inspector, ruleView);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSimpleMultipleColorChanges(inspector, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Getting the <p> tag's color property");
|
||||
let swatch = getRuleViewSelectorProperty("p", "color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
|
||||
info("Opening the color picker");
|
||||
let picker = ruleView.colorPicker;
|
||||
let onShown = picker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Changing the color several times");
|
||||
let colors = [
|
||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||
];
|
||||
for (let {rgba, computed} of colors) {
|
||||
yield simulateColorChange(picker, rgba, {
|
||||
element: content.document.querySelector("p"),
|
||||
name: "color",
|
||||
value: computed
|
||||
});
|
||||
}
|
||||
}).then(() => {
|
||||
testComplexMultipleColorChanges(inspector, ruleView);
|
||||
});
|
||||
}
|
||||
|
||||
function testComplexMultipleColorChanges(inspector, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
yield selectNode("body", inspector);
|
||||
|
||||
info("Getting the <body> tag's color property");
|
||||
let swatch = getRuleViewSelectorProperty("body", "background", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
|
||||
info("Opening the color picker");
|
||||
let picker = ruleView.colorPicker;
|
||||
let onShown = picker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Changing the color several times");
|
||||
let colors = [
|
||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||
];
|
||||
for (let {rgba, computed} of colors) {
|
||||
yield simulateColorChange(picker, rgba, {
|
||||
element: content.document.body,
|
||||
name: "backgroundColor",
|
||||
value: computed
|
||||
});
|
||||
}
|
||||
|
||||
info("Closing the color picker");
|
||||
let onHidden = picker.tooltip.once("hidden");
|
||||
picker.tooltip.hide();
|
||||
yield onHidden;
|
||||
}).then(() => {
|
||||
testOverriddenMultipleColorChanges(inspector, ruleView);
|
||||
});
|
||||
}
|
||||
|
||||
function testOverriddenMultipleColorChanges(inspector, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
info("Getting the <body> tag's color property");
|
||||
let swatch = getRuleViewSelectorProperty("body", "color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
|
||||
info("Opening the color picker");
|
||||
let picker = ruleView.colorPicker;
|
||||
let onShown = picker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
info("Changing the color several times");
|
||||
let colors = [
|
||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||
];
|
||||
for (let {rgba, computed} of colors) {
|
||||
yield simulateColorChange(picker, rgba, {
|
||||
element: content.document.body,
|
||||
name: "color",
|
||||
value: computed
|
||||
});
|
||||
is(content.getComputedStyle(content.document.querySelector("p")).color,
|
||||
"rgb(200, 200, 200)", "The color of the P tag is still correct");
|
||||
}
|
||||
}).then(finish);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* 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 color change in the color picker is reverted when ESC is pressed
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' background-color: #ededed;',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, ruleView) => {
|
||||
inspector.once("inspector-updated", () => {
|
||||
let swatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
testPressingEscapeRevertsChanges(swatch, ruleView);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testPressingEscapeRevertsChanges(swatch, ruleView) {
|
||||
Task.spawn(function*() {
|
||||
let cPicker = ruleView.colorPicker;
|
||||
|
||||
let onShown = cPicker.tooltip.once("shown");
|
||||
swatch.click();
|
||||
yield onShown;
|
||||
|
||||
yield simulateColorChange(cPicker, [0, 0, 0, 1], {
|
||||
element: content.document.body,
|
||||
name: "backgroundColor",
|
||||
value: "rgb(0, 0, 0)"
|
||||
});
|
||||
|
||||
is(swatch.style.backgroundColor, "rgb(0, 0, 0)",
|
||||
"The color swatch's background was updated");
|
||||
is(getRuleViewProperty("background-color", ruleView).valueSpan.textContent,
|
||||
"rgba(0, 0, 0, 1)", "The text of the background-color css property was updated");
|
||||
|
||||
let spectrum = yield cPicker.spectrum;
|
||||
|
||||
// ESC out of the color picker
|
||||
let onHidden = cPicker.tooltip.once("hidden");
|
||||
EventUtils.sendKey("ESCAPE", spectrum.element.ownerDocument.defaultView);
|
||||
yield onHidden;
|
||||
|
||||
yield waitForSuccess({
|
||||
validatorFn: () => {
|
||||
return content.getComputedStyle(content.document.body).backgroundColor === "rgb(237, 237, 237)";
|
||||
},
|
||||
name: "The element's background-color was reverted"
|
||||
});
|
||||
}).then(finish);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/* 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 color swatches are displayed next to colors in the rule-view
|
||||
|
||||
let ruleView;
|
||||
|
||||
const PAGE_CONTENT = [
|
||||
'<style type="text/css">',
|
||||
' body {',
|
||||
' color: red;',
|
||||
' background-color: #ededed;',
|
||||
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||
' }',
|
||||
'</style>',
|
||||
'Testing the color picker tooltip!'
|
||||
].join("\n");
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,rule view color picker tooltip test";
|
||||
}
|
||||
|
||||
function createDocument() {
|
||||
content.document.body.innerHTML = PAGE_CONTENT;
|
||||
|
||||
openRuleView((inspector, view) => {
|
||||
ruleView = view;
|
||||
inspector.once("inspector-updated", testColorSwatchesAreDisplayed);
|
||||
});
|
||||
}
|
||||
|
||||
function testColorSwatchesAreDisplayed() {
|
||||
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(cSwatch, "Color swatch is displayed for the color property");
|
||||
|
||||
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(bgSwatch, "Color swatch is displayed for the bg-color property");
|
||||
|
||||
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||
.querySelector(".ruleview-colorswatch");
|
||||
ok(bSwatch, "Color swatch is displayed for the border property");
|
||||
|
||||
ruleView = null;
|
||||
finish();
|
||||
}
|
|
@ -249,9 +249,9 @@ function getComputedPropertyValue(aName)
|
|||
* milliseconds to check if the result is true. When it is true, succesFn
|
||||
* is called and polling stops. If validatorFn never returns true, then
|
||||
* polling timeouts after several tries and a failure is recorded.
|
||||
* - successFn
|
||||
* - successFn Optional
|
||||
* A function called when the validator function returns true.
|
||||
* - failureFn
|
||||
* - failureFn Optional
|
||||
* A function called if the validator function timeouts - fails to return
|
||||
* true in the given time.
|
||||
* - name
|
||||
|
@ -259,9 +259,12 @@ function getComputedPropertyValue(aName)
|
|||
* messages.
|
||||
* - timeout
|
||||
* Timeout for validator function, in milliseconds. Default is 5000.
|
||||
* @return a promise that resolves when the condition is met, or rejects if the
|
||||
* timeout is reached
|
||||
*/
|
||||
function waitForSuccess(aOptions)
|
||||
{
|
||||
let def = promise.defer();
|
||||
let start = Date.now();
|
||||
let timeout = aOptions.timeout || 5000;
|
||||
|
||||
|
@ -270,20 +273,26 @@ function waitForSuccess(aOptions)
|
|||
if ((Date.now() - start) > timeout) {
|
||||
// Log the failure.
|
||||
ok(false, "Timed out while waiting for: " + aOptions.name);
|
||||
failureFn(aOptions);
|
||||
if (failureFn) {
|
||||
failureFn(aOptions);
|
||||
}
|
||||
def.reject(aOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (validatorFn(aOptions)) {
|
||||
ok(true, aOptions.name);
|
||||
successFn();
|
||||
}
|
||||
else {
|
||||
if (successFn) {
|
||||
successFn();
|
||||
}
|
||||
def.resolve();
|
||||
} else {
|
||||
setTimeout(function() wait(validatorFn, successFn, failureFn), 100);
|
||||
}
|
||||
}
|
||||
|
||||
wait(aOptions.validatorFn, aOptions.successFn, aOptions.failureFn);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(tearDown);
|
||||
|
@ -317,3 +326,86 @@ function isHoverTooltipTarget(tooltip, target) {
|
|||
// when calling isValidHoverTarget
|
||||
return tooltip.isValidHoverTarget(target);
|
||||
}
|
||||
|
||||
function getRuleViewProperty(name, ruleView) {
|
||||
let prop = null;
|
||||
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
|
||||
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||
|
||||
if (nameSpan.textContent === name) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
}
|
||||
});
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* selector and property name in the rule-view
|
||||
* @return an object {nameSpan, valueSpan}
|
||||
*/
|
||||
function getRuleViewSelectorProperty(selectorText, propertyName, ruleView) {
|
||||
let rule, property;
|
||||
|
||||
for (let r of ruleView.doc.querySelectorAll(".ruleview-rule")) {
|
||||
let selector = r.querySelector(".ruleview-selector-matched");
|
||||
if (selector && selector.textContent === selectorText) {
|
||||
rule = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rule) {
|
||||
// Look for the propertyName in that rule element
|
||||
for (let p of rule.querySelectorAll(".ruleview-property")) {
|
||||
let nameSpan = p.querySelector(".ruleview-propertyname");
|
||||
let valueSpan = p.querySelector(".ruleview-propertyvalue");
|
||||
if (nameSpan.textContent === propertyName) {
|
||||
property = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a color change in a given color picker tooltip, and optionally wait
|
||||
* for a given element in the page to have its style changed as a result
|
||||
* @param {SwatchColorPickerTooltip} colorPicker
|
||||
* @param {Array} newRgba The new color to be set [r, g, b, a]
|
||||
* @param {Object} expectedChange Optional object that needs the following props:
|
||||
* - {DOMNode} element The element in the page that will have its
|
||||
* style changed.
|
||||
* - {String} name The style name that will be changed
|
||||
* - {String} value The expected style value
|
||||
* The style will be checked like so: getComputedStyle(element)[name] === value
|
||||
*/
|
||||
function simulateColorChange(colorPicker, newRgba, expectedChange) {
|
||||
// Note that this test isn't concerned with simulating events to test how the
|
||||
// spectrum color picker reacts, see browser_spectrum.js for this.
|
||||
// This test only cares about the color swatch <-> color picker <-> rule view
|
||||
// interactions. That's why there's no event simulations here
|
||||
return Task.spawn(function*() {
|
||||
info("Getting the spectrum colorpicker object");
|
||||
let spectrum = yield colorPicker.spectrum;
|
||||
info("Setting the new color");
|
||||
spectrum.rgb = newRgba;
|
||||
info("Applying the change");
|
||||
spectrum.updateUI();
|
||||
spectrum.onChange();
|
||||
|
||||
if (expectedChange) {
|
||||
info("Waiting for the style to be applied on the page");
|
||||
yield waitForSuccess({
|
||||
validatorFn: () => {
|
||||
let {element, name, value} = expectedChange;
|
||||
return content.getComputedStyle(element)[name] === value;
|
||||
},
|
||||
name: "Color picker change applied on the page"
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ const PREF_HEALTHREPORT_ENABLED = "datareporting.healthreport.service.enabled";
|
|||
|
||||
const PREF_BRANCH_TELEMETRY = "toolkit.telemetry.";
|
||||
const PREF_TELEMETRY_ENABLED = "enabled";
|
||||
const PREF_TELEMETRY_PRERELEASE = "enabledPreRelease";
|
||||
|
||||
const TELEMETRY_LOG = {
|
||||
// log(key, [kind, experimentId, details])
|
||||
|
@ -167,8 +166,7 @@ function loadJSONAsync(file, options) {
|
|||
}
|
||||
|
||||
function telemetryEnabled() {
|
||||
return gPrefsTelemetry.get(PREF_TELEMETRY_ENABLED, false) ||
|
||||
gPrefsTelemetry.get(PREF_TELEMETRY_PRERELEASE, false);
|
||||
return gPrefsTelemetry.get(PREF_TELEMETRY_ENABLED, false);
|
||||
}
|
||||
|
||||
// Returns a promise that is resolved with the AddonInstall for that URL.
|
||||
|
@ -254,7 +252,7 @@ Experiments.Policy.prototype = {
|
|||
if (pref !== undefined) {
|
||||
let val = Number.parseFloat(pref);
|
||||
this._log.debug("random sample forced: " + val);
|
||||
if (IsNaN(val) || val < 0) {
|
||||
if (isNaN(val) || val < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (val > 1) {
|
||||
|
@ -357,7 +355,6 @@ Experiments.Experiments.prototype = {
|
|||
gPrefs.observe(PREF_ENABLED, this._toggleExperimentsEnabled, this);
|
||||
|
||||
gPrefsTelemetry.observe(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this);
|
||||
gPrefsTelemetry.observe(PREF_TELEMETRY_PRERELEASE, this._telemetryStatusChanged, this);
|
||||
|
||||
AsyncShutdown.profileBeforeChange.addBlocker("Experiments.jsm shutdown",
|
||||
this.uninit.bind(this));
|
||||
|
@ -390,7 +387,6 @@ Experiments.Experiments.prototype = {
|
|||
gPrefs.ignore(PREF_ENABLED, this._toggleExperimentsEnabled, this);
|
||||
|
||||
gPrefsTelemetry.ignore(PREF_TELEMETRY_ENABLED, this._telemetryStatusChanged, this);
|
||||
gPrefsTelemetry.ignore(PREF_TELEMETRY_PRERELEASE, this._telemetryStatusChanged, this);
|
||||
|
||||
if (this._timer) {
|
||||
this._timer.clear();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.8.1181
|
||||
Current extension version is: 0.8.1334
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@ const PDF_CONTENT_TYPE = 'application/pdf';
|
|||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://pdf.js/PdfStreamConverter.jsm');
|
||||
Cu.import('resource://pdf.js/PdfRedirector.jsm');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
|
@ -62,7 +60,13 @@ function getIntPref(aPref, aDefaultValue) {
|
|||
}
|
||||
|
||||
function initializeDefaultPreferences() {
|
||||
Cu.import('resource://pdf.js/default_preferences.js');
|
||||
|
||||
var DEFAULT_PREFERENCES = {
|
||||
showPreviousViewOnLoad: true,
|
||||
defaultZoomValue: '',
|
||||
ifAvailableShowOutlineOnLoad: false
|
||||
};
|
||||
|
||||
|
||||
var defaultBranch = Services.prefs.getDefaultBranch(PREF_PREFIX + '.');
|
||||
var defaultValue;
|
||||
|
@ -246,10 +250,13 @@ let PdfJs = {
|
|||
return;
|
||||
|
||||
this._pdfStreamConverterFactory = new Factory();
|
||||
Cu.import('resource://pdf.js/PdfStreamConverter.jsm');
|
||||
this._pdfStreamConverterFactory.register(PdfStreamConverter);
|
||||
|
||||
this._pdfRedirectorFactory = new Factory();
|
||||
Cu.import('resource://pdf.js/PdfRedirector.jsm');
|
||||
this._pdfRedirectorFactory.register(PdfRedirector);
|
||||
|
||||
Svc.pluginHost.registerPlayPreviewMimeType(PDF_CONTENT_TYPE, true,
|
||||
'data:application/x-moz-playpreview-pdfjs;,');
|
||||
|
||||
|
@ -261,12 +268,16 @@ let PdfJs = {
|
|||
return;
|
||||
|
||||
this._pdfStreamConverterFactory.unregister();
|
||||
Cu.unload('resource://pdf.js/PdfStreamConverter.jsm');
|
||||
delete this._pdfStreamConverterFactory;
|
||||
|
||||
this._pdfRedirectorFactory.unregister();
|
||||
Cu.unload('resource://pdf.js/PdfRedirector.jsm');
|
||||
delete this._pdfRedirectorFactory;
|
||||
|
||||
Svc.pluginHost.unregisterPlayPreviewMimeType(PDF_CONTENT_TYPE);
|
||||
|
||||
this._registered = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@ const MAX_STRING_PREF_LENGTH = 128;
|
|||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
Cu.import('resource://pdf.js/network.js');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'NetworkManager',
|
||||
'resource://pdf.js/network.js');
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
|
||||
'resource://gre/modules/PrivateBrowsingUtils.jsm');
|
||||
|
|
|
@ -21,8 +21,8 @@ if (typeof PDFJS === 'undefined') {
|
|||
(typeof window !== 'undefined' ? window : this).PDFJS = {};
|
||||
}
|
||||
|
||||
PDFJS.version = '0.8.1181';
|
||||
PDFJS.build = '31ea4e0';
|
||||
PDFJS.version = '0.8.1334';
|
||||
PDFJS.build = 'b97127a';
|
||||
|
||||
(function pdfjsWrapper() {
|
||||
// Use strict in our context only - users might not want it
|
||||
|
@ -179,7 +179,10 @@ var OPS = PDFJS.OPS = {
|
|||
paintImageMaskXObjectGroup: 84,
|
||||
paintImageXObject: 85,
|
||||
paintInlineImageXObject: 86,
|
||||
paintInlineImageXObjectGroup: 87
|
||||
paintInlineImageXObjectGroup: 87,
|
||||
paintImageXObjectRepeat: 88,
|
||||
paintImageMaskXObjectRepeat: 89,
|
||||
paintSolidColorImageMask: 90,
|
||||
};
|
||||
|
||||
// A notice for devs. These are good for things that are helpful to devs, such
|
||||
|
@ -437,6 +440,24 @@ function stringToBytes(str) {
|
|||
return bytes;
|
||||
}
|
||||
|
||||
// Lazy test the endianness of the platform
|
||||
// NOTE: This will be 'true' for simulated TypedArrays
|
||||
function isLittleEndian() {
|
||||
var buffer8 = new Uint8Array(2);
|
||||
buffer8[0] = 1;
|
||||
var buffer16 = new Uint16Array(buffer8.buffer);
|
||||
return (buffer16[0] === 1);
|
||||
}
|
||||
|
||||
Object.defineProperty(PDFJS, 'isLittleEndian', {
|
||||
configurable: true,
|
||||
get: function PDFJS_isLittleEndian() {
|
||||
return shadow(PDFJS, 'isLittleEndian', isLittleEndian());
|
||||
}
|
||||
});
|
||||
|
||||
PDFJS.hasCanvasTypedArrays = true;
|
||||
|
||||
var IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
||||
|
||||
var Util = PDFJS.Util = (function UtilClosure() {
|
||||
|
@ -3572,24 +3593,38 @@ var LinkAnnotation = (function LinkAnnotationClosure() {
|
|||
* above this value will not be drawn. Use -1 for no limit.
|
||||
* @var {number}
|
||||
*/
|
||||
PDFJS.maxImageSize = PDFJS.maxImageSize === undefined ? -1 : PDFJS.maxImageSize;
|
||||
PDFJS.maxImageSize = (PDFJS.maxImageSize === undefined ?
|
||||
-1 : PDFJS.maxImageSize);
|
||||
|
||||
/**
|
||||
* The url of where the predefined Adobe CMaps are located. Include trailing
|
||||
* slash.
|
||||
* @var {string}
|
||||
*/
|
||||
PDFJS.cMapUrl = (PDFJS.cMapUrl === undefined ? null : PDFJS.cMapUrl);
|
||||
|
||||
/**
|
||||
* Specifies if CMaps are binary packed.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.cMapPacked = PDFJS.cMapPacked === undefined ? false : PDFJS.cMapPacked;
|
||||
|
||||
/*
|
||||
* By default fonts are converted to OpenType fonts and loaded via font face
|
||||
* rules. If disabled, the font will be rendered using a built in font renderer
|
||||
* that constructs the glyphs with primitive path commands.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.disableFontFace = PDFJS.disableFontFace === undefined ?
|
||||
false : PDFJS.disableFontFace;
|
||||
PDFJS.disableFontFace = (PDFJS.disableFontFace === undefined ?
|
||||
false : PDFJS.disableFontFace);
|
||||
|
||||
/**
|
||||
* Path for image resources, mainly for annotation icons. Include trailing
|
||||
* slash.
|
||||
* @var {string}
|
||||
*/
|
||||
PDFJS.imageResourcesPath = PDFJS.imageResourcesPath === undefined ?
|
||||
'' : PDFJS.imageResourcesPath;
|
||||
PDFJS.imageResourcesPath = (PDFJS.imageResourcesPath === undefined ?
|
||||
'' : PDFJS.imageResourcesPath);
|
||||
|
||||
/**
|
||||
* Disable the web worker and run all code on the main thread. This will happen
|
||||
|
@ -3597,8 +3632,8 @@ PDFJS.imageResourcesPath = PDFJS.imageResourcesPath === undefined ?
|
|||
* to workers.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.disableWorker = PDFJS.disableWorker === undefined ?
|
||||
false : PDFJS.disableWorker;
|
||||
PDFJS.disableWorker = (PDFJS.disableWorker === undefined ?
|
||||
false : PDFJS.disableWorker);
|
||||
|
||||
/**
|
||||
* Path and filename of the worker file. Required when the worker is enabled in
|
||||
|
@ -3606,7 +3641,7 @@ PDFJS.disableWorker = PDFJS.disableWorker === undefined ?
|
|||
* loaded based on the location of the pdf.js file.
|
||||
* @var {string}
|
||||
*/
|
||||
PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
|
||||
PDFJS.workerSrc = (PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc);
|
||||
|
||||
/**
|
||||
* Disable range request loading of PDF files. When enabled and if the server
|
||||
|
@ -3614,8 +3649,8 @@ PDFJS.workerSrc = PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc;
|
|||
* Enabled (false) by default.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.disableRange = PDFJS.disableRange === undefined ?
|
||||
false : PDFJS.disableRange;
|
||||
PDFJS.disableRange = (PDFJS.disableRange === undefined ?
|
||||
false : PDFJS.disableRange);
|
||||
|
||||
/**
|
||||
* Disable pre-fetching of PDF file data. When range requests are enabled PDF.js
|
||||
|
@ -3623,28 +3658,28 @@ PDFJS.disableRange = PDFJS.disableRange === undefined ?
|
|||
* the current page. This default behavior can be disabled.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.disableAutoFetch = PDFJS.disableAutoFetch === undefined ?
|
||||
false : PDFJS.disableAutoFetch;
|
||||
PDFJS.disableAutoFetch = (PDFJS.disableAutoFetch === undefined ?
|
||||
false : PDFJS.disableAutoFetch);
|
||||
|
||||
/**
|
||||
* Enables special hooks for debugging PDF.js.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.pdfBug = PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug;
|
||||
PDFJS.pdfBug = (PDFJS.pdfBug === undefined ? false : PDFJS.pdfBug);
|
||||
|
||||
/**
|
||||
* Enables transfer usage in postMessage for ArrayBuffers.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.postMessageTransfers = PDFJS.postMessageTransfers === undefined ?
|
||||
true : PDFJS.postMessageTransfers;
|
||||
PDFJS.postMessageTransfers = (PDFJS.postMessageTransfers === undefined ?
|
||||
true : PDFJS.postMessageTransfers);
|
||||
|
||||
/**
|
||||
* Disables URL.createObjectURL usage.
|
||||
* @var {boolean}
|
||||
*/
|
||||
PDFJS.disableCreateObjectURL = PDFJS.disableCreateObjectURL === undefined ?
|
||||
false : PDFJS.disableCreateObjectURL;
|
||||
PDFJS.disableCreateObjectURL = (PDFJS.disableCreateObjectURL === undefined ?
|
||||
false : PDFJS.disableCreateObjectURL);
|
||||
|
||||
/**
|
||||
* Controls the logging level.
|
||||
|
@ -3654,8 +3689,8 @@ PDFJS.disableCreateObjectURL = PDFJS.disableCreateObjectURL === undefined ?
|
|||
* - infos
|
||||
* @var {number}
|
||||
*/
|
||||
PDFJS.verbosity = PDFJS.verbosity === undefined ?
|
||||
PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity;
|
||||
PDFJS.verbosity = (PDFJS.verbosity === undefined ?
|
||||
PDFJS.VERBOSITY_LEVELS.warnings : PDFJS.verbosity);
|
||||
|
||||
/**
|
||||
* Document initialization / loading parameters object.
|
||||
|
@ -3710,8 +3745,9 @@ PDFJS.getDocument = function getDocument(source,
|
|||
'string or a parameter object');
|
||||
}
|
||||
|
||||
if (!source.url && !source.data)
|
||||
if (!source.url && !source.data) {
|
||||
error('Invalid parameter array, need either .data or .url');
|
||||
}
|
||||
|
||||
// copy/use all keys as is except 'url' -- full path is required
|
||||
var params = {};
|
||||
|
@ -3725,8 +3761,8 @@ PDFJS.getDocument = function getDocument(source,
|
|||
|
||||
workerInitializedPromise = new PDFJS.LegacyPromise();
|
||||
workerReadyPromise = new PDFJS.LegacyPromise();
|
||||
transport = new WorkerTransport(workerInitializedPromise,
|
||||
workerReadyPromise, pdfDataRangeTransport, progressCallback);
|
||||
transport = new WorkerTransport(workerInitializedPromise, workerReadyPromise,
|
||||
pdfDataRangeTransport, progressCallback);
|
||||
workerInitializedPromise.then(function transportInitialized() {
|
||||
transport.passwordCallback = passwordCallback;
|
||||
transport.fetchDocument(params);
|
||||
|
@ -3825,7 +3861,7 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
|
|||
var metadata = this.pdfInfo.metadata;
|
||||
promise.resolve({
|
||||
info: info,
|
||||
metadata: metadata ? new PDFJS.Metadata(metadata) : null
|
||||
metadata: (metadata ? new PDFJS.Metadata(metadata) : null)
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
@ -3925,8 +3961,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
* with transforms required for rendering.
|
||||
*/
|
||||
getViewport: function PDFPageProxy_getViewport(scale, rotate) {
|
||||
if (arguments.length < 2)
|
||||
if (arguments.length < 2) {
|
||||
rotate = this.rotate;
|
||||
}
|
||||
return new PDFJS.PageViewport(this.view, scale, rotate, 0, 0);
|
||||
},
|
||||
/**
|
||||
|
@ -3934,8 +3971,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
* annotation objects.
|
||||
*/
|
||||
getAnnotations: function PDFPageProxy_getAnnotations() {
|
||||
if (this.annotationsPromise)
|
||||
if (this.annotationsPromise) {
|
||||
return this.annotationsPromise;
|
||||
}
|
||||
|
||||
var promise = new PDFJS.LegacyPromise();
|
||||
this.annotationsPromise = promise;
|
||||
|
@ -3967,9 +4005,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
// this call to render.
|
||||
this.pendingDestroy = false;
|
||||
|
||||
var renderingIntent = 'intent' in params ?
|
||||
(params.intent == 'print' ? 'print' : 'display') :
|
||||
'display';
|
||||
var renderingIntent = ('intent' in params ?
|
||||
(params.intent == 'print' ? 'print' : 'display') : 'display');
|
||||
|
||||
if (!this.intentStates[renderingIntent]) {
|
||||
this.intentStates[renderingIntent] = {};
|
||||
|
@ -3995,9 +4032,10 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
}
|
||||
|
||||
var internalRenderTask = new InternalRenderTask(complete, params,
|
||||
this.objs, this.commonObjs,
|
||||
intentState.operatorList,
|
||||
this.pageNumber);
|
||||
this.objs,
|
||||
this.commonObjs,
|
||||
intentState.operatorList,
|
||||
this.pageNumber);
|
||||
if (!intentState.renderTasks) {
|
||||
intentState.renderTasks = [];
|
||||
}
|
||||
|
@ -4073,8 +4111,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
if (!this.pendingDestroy ||
|
||||
Object.keys(this.intentStates).some(function(intent) {
|
||||
var intentState = this.intentStates[intent];
|
||||
return intentState.renderTasks.length !== 0 ||
|
||||
intentState.receivingOperatorList;
|
||||
return (intentState.renderTasks.length !== 0 ||
|
||||
intentState.receivingOperatorList);
|
||||
}, this)) {
|
||||
return;
|
||||
}
|
||||
|
@ -4129,7 +4167,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
|
|||
*/
|
||||
var WorkerTransport = (function WorkerTransportClosure() {
|
||||
function WorkerTransport(workerInitializedPromise, workerReadyPromise,
|
||||
pdfDataRangeTransport, progressCallback) {
|
||||
pdfDataRangeTransport, progressCallback) {
|
||||
this.pdfDataRangeTransport = pdfDataRangeTransport;
|
||||
|
||||
this.workerReadyPromise = workerReadyPromise;
|
||||
|
@ -4343,8 +4381,9 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||
messageHandler.on('commonobj', function transportObj(data) {
|
||||
var id = data[0];
|
||||
var type = data[1];
|
||||
if (this.commonObjs.hasData(id))
|
||||
if (this.commonObjs.hasData(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'Font':
|
||||
|
@ -4421,17 +4460,19 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||
messageHandler.on('PageError', function transportError(data, intent) {
|
||||
var page = this.pageCache[data.pageNum - 1];
|
||||
var intentState = page.intentStates[intent];
|
||||
if (intentState.displayReadyPromise)
|
||||
if (intentState.displayReadyPromise) {
|
||||
intentState.displayReadyPromise.reject(data.error);
|
||||
else
|
||||
} else {
|
||||
error(data.error);
|
||||
}
|
||||
}, this);
|
||||
|
||||
messageHandler.on('JpegDecode', function(data, deferred) {
|
||||
var imageUrl = data[0];
|
||||
var components = data[1];
|
||||
if (components != 3 && components != 1)
|
||||
if (components != 3 && components != 1) {
|
||||
error('Only 3 component or 1 component can be returned');
|
||||
}
|
||||
|
||||
var img = new Image();
|
||||
img.onload = (function messageHandler_onloadClosure() {
|
||||
|
@ -4469,6 +4510,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||
source: source,
|
||||
disableRange: PDFJS.disableRange,
|
||||
maxImageSize: PDFJS.maxImageSize,
|
||||
cMapUrl: PDFJS.cMapUrl,
|
||||
cMapPacked: PDFJS.cMapPacked,
|
||||
disableFontFace: PDFJS.disableFontFace,
|
||||
disableCreateObjectURL: PDFJS.disableCreateObjectURL,
|
||||
verbosity: PDFJS.verbosity
|
||||
|
@ -4490,8 +4533,9 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
|||
}
|
||||
|
||||
var pageIndex = pageNumber - 1;
|
||||
if (pageIndex in this.pagePromises)
|
||||
if (pageIndex in this.pagePromises) {
|
||||
return this.pagePromises[pageIndex];
|
||||
}
|
||||
var promise = new PDFJS.LegacyPromise();
|
||||
this.pagePromises[pageIndex] = promise;
|
||||
this.messageHandler.send('GetPageRequest', { pageIndex: pageIndex });
|
||||
|
@ -4560,8 +4604,9 @@ var PDFObjects = (function PDFObjectsClosure() {
|
|||
* Ensures there is an object defined for `objId`.
|
||||
*/
|
||||
ensureObj: function PDFObjects_ensureObj(objId) {
|
||||
if (this.objs[objId])
|
||||
if (this.objs[objId]) {
|
||||
return this.objs[objId];
|
||||
}
|
||||
|
||||
var obj = {
|
||||
promise: new LegacyPromise(),
|
||||
|
@ -4596,8 +4641,9 @@ var PDFObjects = (function PDFObjectsClosure() {
|
|||
|
||||
// If there isn't an object yet or the object isn't resolved, then the
|
||||
// data isn't ready yet!
|
||||
if (!obj || !obj.resolved)
|
||||
if (!obj || !obj.resolved) {
|
||||
error('Requesting object that isn\'t resolved yet ' + objId);
|
||||
}
|
||||
|
||||
return obj.data;
|
||||
},
|
||||
|
@ -5140,7 +5186,9 @@ function compileType3Glyph(imgData) {
|
|||
var type = points[p], p0 = p, pp;
|
||||
do {
|
||||
var step = steps[type];
|
||||
do { p += step; } while (!points[p]);
|
||||
do {
|
||||
p += step;
|
||||
} while (!points[p]);
|
||||
|
||||
pp = points[p];
|
||||
if (pp !== 5 && pp !== 10) {
|
||||
|
@ -5304,45 +5352,48 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
// Grayscale, 1 bit per pixel (i.e. black-and-white).
|
||||
var destDataLength = dest.length;
|
||||
var srcLength = src.byteLength;
|
||||
for (var i = 3; i < destDataLength; i += 4) {
|
||||
dest[i] = 255;
|
||||
}
|
||||
var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) :
|
||||
new Uint32ArrayView(dest);
|
||||
var dest32DataLength = dest32.length;
|
||||
var fullSrcDiff = (width + 7) >> 3;
|
||||
var white = 0xFFFFFFFF;
|
||||
var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ?
|
||||
0xFF000000 : 0x000000FF;
|
||||
for (var i = 0; i < totalChunks; i++) {
|
||||
var thisChunkHeight =
|
||||
(i < fullChunks) ? fullChunkHeight : partialChunkHeight;
|
||||
var destPos = 0;
|
||||
for (var j = 0; j < thisChunkHeight; j++) {
|
||||
var srcDiff = srcLength - srcPos;
|
||||
var k = 0;
|
||||
var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7;
|
||||
var kEndUnrolled = kEnd & ~7;
|
||||
var mask = 0;
|
||||
var srcByte = 0;
|
||||
for (var k = 0; k < width; k++, destPos += 4) {
|
||||
if (mask === 0) {
|
||||
if (srcPos >= srcLength) {
|
||||
break;
|
||||
}
|
||||
srcByte = src[srcPos++];
|
||||
mask = 128;
|
||||
}
|
||||
|
||||
if ((srcByte & mask)) {
|
||||
dest[destPos] = 255;
|
||||
dest[destPos + 1] = 255;
|
||||
dest[destPos + 2] = 255;
|
||||
} else {
|
||||
dest[destPos] = 0;
|
||||
dest[destPos + 1] = 0;
|
||||
dest[destPos + 2] = 0;
|
||||
}
|
||||
for (; k < kEndUnrolled; k += 8) {
|
||||
srcByte = src[srcPos++];
|
||||
dest32[destPos++] = (srcByte & 128) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 64) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 32) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 16) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 8) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 4) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 2) ? white : black;
|
||||
dest32[destPos++] = (srcByte & 1) ? white : black;
|
||||
}
|
||||
for (; k < kEnd; k++) {
|
||||
if (mask === 0) {
|
||||
srcByte = src[srcPos++];
|
||||
mask = 128;
|
||||
}
|
||||
|
||||
dest32[destPos++] = (srcByte & mask) ? white : black;
|
||||
mask >>= 1;
|
||||
}
|
||||
}
|
||||
if (destPos < destDataLength) {
|
||||
// We ran out of input. Make all remaining pixels transparent.
|
||||
destPos += 3;
|
||||
do {
|
||||
dest[destPos] = 0;
|
||||
destPos += 4;
|
||||
} while (destPos < destDataLength);
|
||||
// We ran out of input. Make all remaining pixels transparent.
|
||||
while (destPos < dest32DataLength) {
|
||||
dest32[destPos++] = 0;
|
||||
}
|
||||
|
||||
ctx.putImageData(chunkImgData, 0, i * fullChunkHeight);
|
||||
|
@ -5813,14 +5864,22 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
this.ctx.closePath();
|
||||
},
|
||||
rectangle: function CanvasGraphics_rectangle(x, y, width, height) {
|
||||
if (width === 0) {
|
||||
width = this.getSinglePixelWidth();
|
||||
}
|
||||
if (height === 0) {
|
||||
height = this.getSinglePixelWidth();
|
||||
}
|
||||
|
||||
this.ctx.rect(x, y, width, height);
|
||||
},
|
||||
stroke: function CanvasGraphics_stroke(consumePath) {
|
||||
consumePath = typeof consumePath !== 'undefined' ? consumePath : true;
|
||||
var ctx = this.ctx;
|
||||
var strokeColor = this.current.strokeColor;
|
||||
if (this.current.lineWidth === 0)
|
||||
if (this.current.lineWidth === 0) {
|
||||
ctx.lineWidth = this.getSinglePixelWidth();
|
||||
}
|
||||
// For stroke we want to temporarily change the global alpha to the
|
||||
// stroking alpha.
|
||||
ctx.globalAlpha = this.current.strokeAlpha;
|
||||
|
@ -5835,8 +5894,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
} else {
|
||||
ctx.stroke();
|
||||
}
|
||||
if (consumePath)
|
||||
if (consumePath) {
|
||||
this.consumePath();
|
||||
}
|
||||
// Restore the global alpha to the fill alpha
|
||||
ctx.globalAlpha = this.current.fillAlpha;
|
||||
},
|
||||
|
@ -5960,11 +6020,12 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
var fontObj = this.commonObjs.get(fontRefName);
|
||||
var current = this.current;
|
||||
|
||||
if (!fontObj)
|
||||
if (!fontObj) {
|
||||
error('Can\'t find font for ' + fontRefName);
|
||||
}
|
||||
|
||||
current.fontMatrix = fontObj.fontMatrix ? fontObj.fontMatrix :
|
||||
FONT_IDENTITY_MATRIX;
|
||||
current.fontMatrix = (fontObj.fontMatrix ?
|
||||
fontObj.fontMatrix : FONT_IDENTITY_MATRIX);
|
||||
|
||||
// A valid matrix needs all main diagonal elements to be non-zero
|
||||
// This also ensures we bypass FF bugzilla bug #719844.
|
||||
|
@ -5985,8 +6046,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
this.current.font = fontObj;
|
||||
this.current.fontSize = size;
|
||||
|
||||
if (fontObj.coded)
|
||||
if (fontObj.coded) {
|
||||
return; // we don't need ctx.font for Type3 fonts
|
||||
}
|
||||
|
||||
var name = fontObj.loadedName || 'sans-serif';
|
||||
var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
|
||||
|
@ -6205,13 +6267,15 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
var lineWidth = current.lineWidth;
|
||||
var a1 = current.textMatrix[0], b1 = current.textMatrix[1];
|
||||
var scale = Math.sqrt(a1 * a1 + b1 * b1);
|
||||
if (scale === 0 || lineWidth === 0)
|
||||
if (scale === 0 || lineWidth === 0) {
|
||||
lineWidth = this.getSinglePixelWidth();
|
||||
else
|
||||
} else {
|
||||
lineWidth /= scale;
|
||||
}
|
||||
|
||||
if (textSelection)
|
||||
if (textSelection) {
|
||||
geom = this.createTextGeometry();
|
||||
}
|
||||
|
||||
if (fontSizeScale != 1.0) {
|
||||
ctx.scale(fontSizeScale, fontSizeScale);
|
||||
|
@ -6243,38 +6307,37 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
var accent = glyph.accent;
|
||||
|
||||
var scaledX, scaledY, scaledAccentX, scaledAccentY;
|
||||
if (!glyph.disabled) {
|
||||
if (vertical) {
|
||||
scaledX = vx / fontSizeScale;
|
||||
scaledY = (x + vy) / fontSizeScale;
|
||||
} else {
|
||||
scaledX = x / fontSizeScale;
|
||||
scaledY = 0;
|
||||
}
|
||||
|
||||
if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) {
|
||||
// some standard fonts may not have the exact width, trying to
|
||||
// rescale per character
|
||||
var measuredWidth = ctx.measureText(character).width * 1000 /
|
||||
current.fontSize * current.fontSizeScale;
|
||||
var characterScaleX = width / measuredWidth;
|
||||
restoreNeeded = true;
|
||||
ctx.save();
|
||||
ctx.scale(characterScaleX, 1);
|
||||
scaledX /= characterScaleX;
|
||||
if (accent) {
|
||||
scaledAccentX /= characterScaleX;
|
||||
}
|
||||
}
|
||||
if (vertical) {
|
||||
scaledX = vx / fontSizeScale;
|
||||
scaledY = (x + vy) / fontSizeScale;
|
||||
} else {
|
||||
scaledX = x / fontSizeScale;
|
||||
scaledY = 0;
|
||||
}
|
||||
|
||||
this.paintChar(character, scaledX, scaledY);
|
||||
if (font.remeasure && width > 0 && this.isFontSubpixelAAEnabled) {
|
||||
// some standard fonts may not have the exact width, trying to
|
||||
// rescale per character
|
||||
var measuredWidth = ctx.measureText(character).width * 1000 /
|
||||
current.fontSize * current.fontSizeScale;
|
||||
var characterScaleX = width / measuredWidth;
|
||||
restoreNeeded = true;
|
||||
ctx.save();
|
||||
ctx.scale(characterScaleX, 1);
|
||||
scaledX /= characterScaleX;
|
||||
if (accent) {
|
||||
scaledAccentX = scaledX + accent.offset.x / fontSizeScale;
|
||||
scaledAccentY = scaledY - accent.offset.y / fontSizeScale;
|
||||
this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY);
|
||||
scaledAccentX /= characterScaleX;
|
||||
}
|
||||
}
|
||||
|
||||
this.paintChar(character, scaledX, scaledY);
|
||||
if (accent) {
|
||||
scaledAccentX = scaledX + accent.offset.x / fontSizeScale;
|
||||
scaledAccentY = scaledY - accent.offset.y / fontSizeScale;
|
||||
this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY);
|
||||
}
|
||||
|
||||
x += charWidth;
|
||||
|
||||
canvasWidth += charWidth;
|
||||
|
@ -6334,8 +6397,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
current.x += spacingLength;
|
||||
}
|
||||
|
||||
if (textSelection)
|
||||
if (textSelection) {
|
||||
spacingAccumulator += spacingLength;
|
||||
}
|
||||
} else {
|
||||
var shownCanvasWidth = this.showText(e, true);
|
||||
|
||||
|
@ -6539,8 +6603,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
this.save();
|
||||
this.baseTransformStack.push(this.baseTransform);
|
||||
|
||||
if (matrix && isArray(matrix) && 6 == matrix.length)
|
||||
if (matrix && isArray(matrix) && 6 == matrix.length) {
|
||||
this.transform.apply(this, matrix);
|
||||
}
|
||||
|
||||
this.baseTransform = this.ctx.mozCurrentTransform;
|
||||
|
||||
|
@ -6768,6 +6833,39 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
this.paintInlineImageXObject(maskCanvas.canvas);
|
||||
},
|
||||
|
||||
paintImageMaskXObjectRepeat:
|
||||
function CanvasGraphics_paintImageMaskXObjectRepeat(imgData, scaleX,
|
||||
scaleY, positions) {
|
||||
var width = imgData.width;
|
||||
var height = imgData.height;
|
||||
var ctx = this.ctx;
|
||||
|
||||
var maskCanvas = CachedCanvases.getCanvas('maskCanvas', width, height);
|
||||
var maskCtx = maskCanvas.context;
|
||||
maskCtx.save();
|
||||
|
||||
putBinaryImageMask(maskCtx, imgData);
|
||||
|
||||
maskCtx.globalCompositeOperation = 'source-in';
|
||||
|
||||
var fillColor = this.current.fillColor;
|
||||
maskCtx.fillStyle = (fillColor && fillColor.hasOwnProperty('type') &&
|
||||
fillColor.type === 'Pattern') ?
|
||||
fillColor.getPattern(maskCtx, this) : fillColor;
|
||||
maskCtx.fillRect(0, 0, width, height);
|
||||
|
||||
maskCtx.restore();
|
||||
|
||||
for (var i = 0, ii = positions.length; i < ii; i += 2) {
|
||||
ctx.save();
|
||||
ctx.transform(scaleX, 0, 0, scaleY, positions[i], positions[i + 1]);
|
||||
ctx.scale(1, -1);
|
||||
ctx.drawImage(maskCanvas.canvas, 0, 0, width, height,
|
||||
0, -1, 1, 1);
|
||||
ctx.restore();
|
||||
}
|
||||
},
|
||||
|
||||
paintImageMaskXObjectGroup:
|
||||
function CanvasGraphics_paintImageMaskXObjectGroup(images) {
|
||||
var ctx = this.ctx;
|
||||
|
@ -6803,12 +6901,31 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
|
||||
paintImageXObject: function CanvasGraphics_paintImageXObject(objId) {
|
||||
var imgData = this.objs.get(objId);
|
||||
if (!imgData)
|
||||
if (!imgData) {
|
||||
error('Dependent image isn\'t ready yet');
|
||||
}
|
||||
|
||||
this.paintInlineImageXObject(imgData);
|
||||
},
|
||||
|
||||
paintImageXObjectRepeat:
|
||||
function CanvasGraphics_paintImageXObjectRepeat(objId, scaleX, scaleY,
|
||||
positions) {
|
||||
var imgData = this.objs.get(objId);
|
||||
if (!imgData) {
|
||||
error('Dependent image isn\'t ready yet');
|
||||
}
|
||||
|
||||
var width = imgData.width;
|
||||
var height = imgData.height;
|
||||
var map = [];
|
||||
for (var i = 0, ii = positions.length; i < ii; i += 2) {
|
||||
map.push({transform: [scaleX, 0, 0, scaleY, positions[i],
|
||||
positions[i + 1]], x: 0, y: 0, w: width, h: height});
|
||||
}
|
||||
this.paintInlineImageXObjectGroup(imgData, map);
|
||||
},
|
||||
|
||||
paintInlineImageXObject:
|
||||
function CanvasGraphics_paintInlineImageXObject(imgData) {
|
||||
var width = imgData.width;
|
||||
|
@ -6910,6 +7027,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||
}
|
||||
},
|
||||
|
||||
paintSolidColorImageMask:
|
||||
function CanvasGraphics_paintSolidColorImageMask() {
|
||||
this.ctx.fillRect(0, 0, 1, 1);
|
||||
},
|
||||
|
||||
// Marked content
|
||||
|
||||
markPoint: function CanvasGraphics_markPoint(tag) {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,27 +0,0 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* Copyright 2013 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals */
|
||||
|
||||
'use strict';
|
||||
|
||||
var EXPORTED_SYMBOLS = ['DEFAULT_PREFERENCES'];
|
||||
|
||||
var DEFAULT_PREFERENCES = {
|
||||
showPreviousViewOnLoad: true,
|
||||
defaultZoomValue: '',
|
||||
ifAvailableShowOutlineOnLoad: false
|
||||
};
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче