mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
5925d611df
@ -1014,6 +1014,7 @@ pref("devtools.inspector.htmlHeight", 112);
|
||||
pref("devtools.inspector.htmlPanelOpen", false);
|
||||
pref("devtools.inspector.sidebarOpen", false);
|
||||
pref("devtools.inspector.activeSidebar", "ruleview");
|
||||
pref("devtools.inspector.markupPreview", true);
|
||||
|
||||
// Enable the Layout View
|
||||
pref("devtools.layoutview.enabled", true);
|
||||
|
@ -86,7 +86,9 @@ var tabPreviews = {
|
||||
this._pendingUpdate = true;
|
||||
setTimeout(function (self, aTab) {
|
||||
self._pendingUpdate = false;
|
||||
if (aTab.parentNode && !aTab.hasAttribute("busy"))
|
||||
if (aTab.parentNode &&
|
||||
!aTab.hasAttribute("busy") &&
|
||||
!aTab.hasAttribute("pending"))
|
||||
self.capture(aTab, true);
|
||||
}, 2000, this, this._selectedTab);
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ const TAB_STATE_RESTORING = 2;
|
||||
function test() {
|
||||
/** Test for Bug 586068 - Cascade page loads when restoring **/
|
||||
waitForExplicitFinish();
|
||||
// Too many uncaught exceptions, see bug 789003.
|
||||
ignoreAllUncaughtExceptions();
|
||||
// This test does a lot of window opening / closing and waiting for loads.
|
||||
// In order to prevent timeouts, we'll extend the default that mochitest uses.
|
||||
requestLongerTimeout(4);
|
||||
|
@ -93,7 +93,7 @@ function GroupItem(listOfEls, options) {
|
||||
// ___ Titlebar
|
||||
var html =
|
||||
"<div class='title-container'>" +
|
||||
"<input class='name' placeholder='" + this.defaultName + "'/>" +
|
||||
"<input class='name' />" +
|
||||
"<div class='title-shield' />" +
|
||||
"</div>";
|
||||
|
||||
@ -112,7 +112,7 @@ function GroupItem(listOfEls, options) {
|
||||
|
||||
// ___ Title
|
||||
this.$titleContainer = iQ('.title-container', this.$titlebar);
|
||||
this.$title = iQ('.name', this.$titlebar);
|
||||
this.$title = iQ('.name', this.$titlebar).attr('placeholder', this.defaultName);
|
||||
this.$titleShield = iQ('.title-shield', this.$titlebar);
|
||||
this.setTitle(options.title);
|
||||
|
||||
|
@ -146,9 +146,11 @@ gcli.addCommand({
|
||||
|
||||
let trans = Cc["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Ci.nsITransferable);
|
||||
if ("init" in trans) {
|
||||
trans.init(null);
|
||||
}
|
||||
let loadContext = document.defaultView
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsILoadContext);
|
||||
trans.init(loadContext);
|
||||
trans.addDataFlavor(channel.contentType);
|
||||
trans.setTransferData(channel.contentType, wrapped, -1);
|
||||
|
||||
@ -214,7 +216,8 @@ gcli.addCommand({
|
||||
let source = ioService.newURI(data, "UTF8", null);
|
||||
persist.saveURI(source, null, null, null, null, file);
|
||||
|
||||
div.textContent = gcli.lookup("screenshotSavedToFile") + " " + filename;
|
||||
div.textContent = gcli.lookup("screenshotSavedToFile") + " \"" + filename +
|
||||
"\"";
|
||||
div.addEventListener("click", function openFile() {
|
||||
div.removeEventListener("click", openFile);
|
||||
file.reveal();
|
||||
@ -224,6 +227,7 @@ gcli.addCommand({
|
||||
let previewHeight = parseInt(256*height/width);
|
||||
image.setAttribute("style",
|
||||
"width:256px; height:" + previewHeight + "px;" +
|
||||
"max-height: 256px;" +
|
||||
"background-image: url('" + data + "');" +
|
||||
"background-size: 256px " + previewHeight + "px;" +
|
||||
"margin: 4px; display: block");
|
||||
|
@ -10,6 +10,8 @@ let tempScope = {};
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm", tempScope);
|
||||
let FileUtils = tempScope.FileUtils;
|
||||
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"]
|
||||
.getService(Ci.nsIPrivateBrowsingService);
|
||||
function test() {
|
||||
DeveloperToolbarTest.test(TEST_URI, [ testInput, testCapture ]);
|
||||
}
|
||||
@ -79,31 +81,19 @@ function testCapture() {
|
||||
}
|
||||
}
|
||||
|
||||
function clearClipboard() {
|
||||
let clipid = Ci.nsIClipboard;
|
||||
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
|
||||
clip.emptyClipboard(clipid.kGlobalClipboard);
|
||||
}
|
||||
|
||||
function checkClipboard() {
|
||||
try {
|
||||
let clipid = Ci.nsIClipboard;
|
||||
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
|
||||
let trans = Cc["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Ci.nsITransferable);
|
||||
if ("init" in trans) {
|
||||
trans.init(null);
|
||||
}
|
||||
let io = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
let contentType = io.newChannel("", null, null).contentType;
|
||||
trans.addDataFlavor(contentType);
|
||||
trans.init(null);
|
||||
trans.addDataFlavor("image/png");
|
||||
clip.getData(trans, clipid.kGlobalClipboard);
|
||||
let str = new Object();
|
||||
let strLength = new Object();
|
||||
trans.getTransferData(contentType, str, strLength);
|
||||
if (str && strLength > 0) {
|
||||
clip.emptyClipboard(clipid.kGlobalClipboard);
|
||||
trans.getTransferData("image/png", str, strLength);
|
||||
if (str.value && strLength.value > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -111,6 +101,41 @@ function testCapture() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let PBEntered = DeveloperToolbarTest.checkCalled(function() {
|
||||
Services.obs.removeObserver(PBEntered,
|
||||
"private-browsing-transition-complete",
|
||||
false);
|
||||
|
||||
Services.obs.addObserver(PBLeft, "last-pb-context-exited", false);
|
||||
|
||||
DeveloperToolbarTest.exec({
|
||||
typed: "screenshot --clipboard",
|
||||
args: {
|
||||
delay: 0,
|
||||
filename: " ",
|
||||
fullpage: false,
|
||||
clipboard: true,
|
||||
node: null,
|
||||
chrome: false,
|
||||
},
|
||||
outputMatch: new RegExp("^Copied to clipboard.$"),
|
||||
});
|
||||
|
||||
ok(checkClipboard(), "Screenshot present in clipboard in private browsing");
|
||||
|
||||
pb.privateBrowsingEnabled = false;
|
||||
});
|
||||
|
||||
let PBLeft = DeveloperToolbarTest.checkCalled(function() {
|
||||
Services.obs.removeObserver(PBLeft, "last-pb-context-exited", false);
|
||||
executeSoon(function() {
|
||||
ok(!checkClipboard(), "Screenshot taken in private browsing mode is not" +
|
||||
" present outside of it in the clipboard");
|
||||
Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
pb = null;
|
||||
});
|
||||
});
|
||||
|
||||
let path = FileUtils.getFile("TmpD", ["TestScreenshotFile.png"]).path;
|
||||
|
||||
DeveloperToolbarTest.exec({
|
||||
@ -126,23 +151,29 @@ function testCapture() {
|
||||
outputMatch: new RegExp("^Saved to "),
|
||||
});
|
||||
|
||||
ok(checkTemporaryFile, "Screenshot got created");
|
||||
Services.obs.addObserver(PBEntered, "private-browsing-transition-complete",
|
||||
false);
|
||||
|
||||
clearClipboard();
|
||||
executeSoon(function() {
|
||||
ok(checkTemporaryFile(), "Screenshot got created");
|
||||
|
||||
DeveloperToolbarTest.exec({
|
||||
typed: "screenshot --fullpage --clipboard",
|
||||
args: {
|
||||
delay: 0,
|
||||
filename: " ",
|
||||
fullpage: true,
|
||||
clipboard: true,
|
||||
node: null,
|
||||
chrome: false,
|
||||
},
|
||||
outputMatch: new RegExp("^Copied to clipboard.$"),
|
||||
DeveloperToolbarTest.exec({
|
||||
typed: "screenshot --fullpage --clipboard",
|
||||
args: {
|
||||
delay: 0,
|
||||
filename: " ",
|
||||
fullpage: true,
|
||||
clipboard: true,
|
||||
node: null,
|
||||
chrome: false,
|
||||
},
|
||||
outputMatch: new RegExp("^Copied to clipboard.$"),
|
||||
});
|
||||
|
||||
ok(checkClipboard(), "Screenshot got created and copied");
|
||||
|
||||
Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
|
||||
|
||||
pb.privateBrowsingEnabled = true;
|
||||
});
|
||||
|
||||
ok(checkClipboard, "Screenshot got created and copied");
|
||||
}
|
||||
|
||||
|
@ -11,12 +11,15 @@ const Ci = Components.interfaces;
|
||||
// Page size for pageup/pagedown
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
const PREVIEW_AREA = 700;
|
||||
|
||||
var EXPORTED_SYMBOLS = ["MarkupView"];
|
||||
|
||||
Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
|
||||
Cu.import("resource:///modules/devtools/Templater.jsm");
|
||||
Cu.import("resource:///modules/devtools/Undo.jsm")
|
||||
Cu.import("resource:///modules/devtools/Undo.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* Vocabulary for the purposes of this file:
|
||||
@ -59,6 +62,8 @@ function MarkupView(aInspector, aFrame)
|
||||
|
||||
this._boundFocus = this._onFocus.bind(this);
|
||||
this._frame.addEventListener("focus", this._boundFocus, false);
|
||||
|
||||
this._initPreview();
|
||||
}
|
||||
|
||||
MarkupView.prototype = {
|
||||
@ -473,9 +478,15 @@ MarkupView.prototype = {
|
||||
this.undo.destroy();
|
||||
delete this.undo;
|
||||
|
||||
this._frame.addEventListener("focus", this._boundFocus, false);
|
||||
this._frame.removeEventListener("focus", this._boundFocus, false);
|
||||
delete this._boundFocus;
|
||||
|
||||
this._frame.contentWindow.removeEventListener("scroll", this._boundUpdatePreview, true);
|
||||
this._frame.contentWindow.removeEventListener("resize", this._boundUpdatePreview, true);
|
||||
this._frame.contentWindow.removeEventListener("overflow", this._boundResizePreview, true);
|
||||
this._frame.contentWindow.removeEventListener("underflow", this._boundResizePreview, true);
|
||||
delete this._boundUpdatePreview;
|
||||
|
||||
this._frame.removeEventListener("keydown", this._boundKeyDown, true);
|
||||
delete this._boundKeyDown;
|
||||
|
||||
@ -487,7 +498,85 @@ MarkupView.prototype = {
|
||||
delete this._containers;
|
||||
this._observer.disconnect();
|
||||
delete this._observer;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the preview panel.
|
||||
*/
|
||||
_initPreview: function MT_initPreview()
|
||||
{
|
||||
if (!Services.prefs.getBoolPref("devtools.inspector.markupPreview")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._previewBar = this.doc.querySelector("#previewbar");
|
||||
this._preview = this.doc.querySelector("#preview");
|
||||
this._viewbox = this.doc.querySelector("#viewbox");
|
||||
|
||||
this._previewBar.classList.remove("disabled");
|
||||
|
||||
this._previewWidth = this._preview.getBoundingClientRect().width;
|
||||
|
||||
this._boundResizePreview = this._resizePreview.bind(this);
|
||||
this._frame.contentWindow.addEventListener("resize", this._boundResizePreview, true);
|
||||
this._frame.contentWindow.addEventListener("overflow", this._boundResizePreview, true);
|
||||
this._frame.contentWindow.addEventListener("underflow", this._boundResizePreview, true);
|
||||
|
||||
this._boundUpdatePreview = this._updatePreview.bind(this);
|
||||
this._frame.contentWindow.addEventListener("scroll", this._boundUpdatePreview, true);
|
||||
this._updatePreview();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Move the preview viewbox.
|
||||
*/
|
||||
_updatePreview: function MT_updatePreview()
|
||||
{
|
||||
let win = this._frame.contentWindow;
|
||||
|
||||
if (win.scrollMaxY == 0) {
|
||||
this._previewBar.classList.add("disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
this._previewBar.classList.remove("disabled");
|
||||
|
||||
let ratio = this._previewWidth / PREVIEW_AREA;
|
||||
let width = ratio * win.innerWidth;
|
||||
|
||||
let height = ratio * (win.scrollMaxY + win.innerHeight);
|
||||
let scrollTo
|
||||
if (height >= win.innerHeight) {
|
||||
scrollTo = -(height - win.innerHeight) * (win.scrollY / win.scrollMaxY);
|
||||
this._previewBar.setAttribute("style", "height:" + height + "px;transform:translateY(" + scrollTo + "px)");
|
||||
} else {
|
||||
this._previewBar.setAttribute("style", "height:100%");
|
||||
}
|
||||
|
||||
let bgSize = ~~width + "px " + ~~height + "px";
|
||||
this._preview.setAttribute("style", "background-size:" + bgSize);
|
||||
|
||||
let height = ~~(win.innerHeight * ratio) + "px";
|
||||
let top = ~~(win.scrollY * ratio) + "px";
|
||||
this._viewbox.setAttribute("style", "height:" + height + ";transform: translateY(" + top + ")");
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the preview while resizing, to avoid slowness.
|
||||
*/
|
||||
_resizePreview: function MT_resizePreview()
|
||||
{
|
||||
let win = this._frame.contentWindow;
|
||||
this._previewBar.classList.add("hide");
|
||||
win.clearTimeout(this._resizePreviewTimeout);
|
||||
|
||||
win.setTimeout(function() {
|
||||
this._updatePreview();
|
||||
this._previewBar.classList.remove("hide");
|
||||
}.bind(this), 1000);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,3 +19,45 @@ ul.children:not([expanded]) {
|
||||
width: 1em;
|
||||
height: 1ex;
|
||||
}
|
||||
|
||||
#root {
|
||||
margin-right: 80px;
|
||||
}
|
||||
|
||||
/* Preview */
|
||||
|
||||
#previewbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 90px;
|
||||
background: black;
|
||||
border-left: 1px solid #333;
|
||||
border-bottom: 1px solid #333;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 5px;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background-image: -moz-element(#root);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#previewbar.hide,
|
||||
#previewbar.disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#viewbox {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 5px;
|
||||
width: 80px;
|
||||
border: 1px dashed #888;
|
||||
background: rgba(205,205,255,0.2);
|
||||
outline: 1px solid transparent;
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
<body role="application">
|
||||
<div id="root"></div>
|
||||
<div id="templates" style="display:none">
|
||||
<ul>
|
||||
<li id="template-container" save="${elt}" class="container"><span save="${expander}" class="expander"></span><span save="${codeBox}" class="codebox"><ul save="${children}" class="children"></ul></span></li>
|
||||
<ul>
|
||||
<li id="template-container" save="${elt}" class="container"><span save="${expander}" class="expander"></span><span save="${codeBox}" class="codebox"><ul save="${children}" class="children"></ul></span></li>
|
||||
</ul>
|
||||
|
||||
<span id="template-element" save="${elt}" class="editor"><span><</span><span save="${tag}" class="tagname"></span><span save="${attrList}"></span><span save="${newAttr}" class="newattr" tabindex="0"></span>></span>
|
||||
@ -31,5 +31,9 @@
|
||||
|
||||
<span id="template-elementClose" save="${closeElt}"></<span save="${closeTag}" class="tagname"></span>></span>
|
||||
</div>
|
||||
<div id="previewbar" class="disabled">
|
||||
<div id="preview"/>
|
||||
<div id="viewbox"/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -105,29 +105,30 @@ function ResponsiveUI(aWindow, aTab)
|
||||
}
|
||||
}
|
||||
|
||||
this.customPreset = {key: "custom", custom: true};
|
||||
|
||||
if (Array.isArray(presets)) {
|
||||
this.presets = [{key: "custom", custom: true}].concat(presets)
|
||||
this.presets = [this.customPreset].concat(presets);
|
||||
} else {
|
||||
Cu.reportError("Presets value (devtools.responsiveUI.presets) is malformated.");
|
||||
this.presets = [{key: "custom", custom: true}];
|
||||
this.presets = [this.customPreset];
|
||||
}
|
||||
|
||||
try {
|
||||
let width = Services.prefs.getIntPref("devtools.responsiveUI.customWidth");
|
||||
let height = Services.prefs.getIntPref("devtools.responsiveUI.customHeight");
|
||||
this.presets[0].width = Math.min(MAX_WIDTH, width);
|
||||
this.presets[0].height = Math.min(MAX_HEIGHT, height);
|
||||
this.customPreset.width = Math.min(MAX_WIDTH, width);
|
||||
this.customPreset.height = Math.min(MAX_HEIGHT, height);
|
||||
|
||||
let key = Services.prefs.getCharPref("devtools.responsiveUI.currentPreset");
|
||||
let idx = this.getPresetIdx(key);
|
||||
this.currentPreset = (idx == -1 ? 0 : idx);
|
||||
this.currentPresetKey = Services.prefs.getCharPref("devtools.responsiveUI.currentPreset");
|
||||
} catch(e) {
|
||||
// Default size. The first preset (custom) is the one that will be used.
|
||||
let bbox = this.stack.getBoundingClientRect();
|
||||
|
||||
this.presets[0].width = bbox.width - 40; // horizontal padding of the container
|
||||
this.presets[0].height = bbox.height - 80; // vertical padding + toolbar height
|
||||
this.currentPreset = 0; // Custom
|
||||
this.customPreset.width = bbox.width - 40; // horizontal padding of the container
|
||||
this.customPreset.height = bbox.height - 80; // vertical padding + toolbar height
|
||||
|
||||
this.currentPresetKey = this.customPreset.key;
|
||||
}
|
||||
|
||||
this.container.setAttribute("responsivemode", "true");
|
||||
@ -135,6 +136,8 @@ function ResponsiveUI(aWindow, aTab)
|
||||
|
||||
// Let's bind some callbacks.
|
||||
this.bound_presetSelected = this.presetSelected.bind(this);
|
||||
this.bound_addPreset = this.addPreset.bind(this);
|
||||
this.bound_removePreset = this.removePreset.bind(this);
|
||||
this.bound_rotate = this.rotate.bind(this);
|
||||
this.bound_startResizing = this.startResizing.bind(this);
|
||||
this.bound_stopResizing = this.stopResizing.bind(this);
|
||||
@ -189,14 +192,14 @@ ResponsiveUI.prototype = {
|
||||
if (this.isResizing)
|
||||
this.stopResizing();
|
||||
|
||||
this.saveCurrentPreset();
|
||||
|
||||
// Remove listeners.
|
||||
this.mainWindow.document.removeEventListener("keypress", this.bound_onKeypress, false);
|
||||
this.menulist.removeEventListener("select", this.bound_presetSelected, true);
|
||||
this.tab.removeEventListener("TabClose", this);
|
||||
this.tabContainer.removeEventListener("TabSelect", this);
|
||||
this.rotatebutton.removeEventListener("command", this.bound_rotate, true);
|
||||
this.addbutton.removeEventListener("command", this.bound_addPreset, true);
|
||||
this.removebutton.removeEventListener("command", this.bound_removePreset, true);
|
||||
|
||||
// Removed elements.
|
||||
this.container.removeChild(this.toolbar);
|
||||
@ -210,21 +213,6 @@ ResponsiveUI.prototype = {
|
||||
delete this.tab.__responsiveUI;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve a preset from its key.
|
||||
*
|
||||
* @param aKey preset's key.
|
||||
* @returns the index of the preset, -1 if not found.
|
||||
*/
|
||||
getPresetIdx: function RUI_getPresetIdx(aKey) {
|
||||
for (let i = 0; i < this.presets.length; i++) {
|
||||
if (this.presets[i].key == aKey) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle keypressed.
|
||||
*
|
||||
@ -304,10 +292,24 @@ ResponsiveUI.prototype = {
|
||||
|
||||
this.menulist.addEventListener("select", this.bound_presetSelected, true);
|
||||
|
||||
this.menuitems = new Map();
|
||||
|
||||
let menupopup = this.chromeDoc.createElement("menupopup");
|
||||
this.registerPresets(menupopup);
|
||||
this.menulist.appendChild(menupopup);
|
||||
|
||||
this.addbutton = this.chromeDoc.createElement("menuitem");
|
||||
this.addbutton.setAttribute("label", this.strings.GetStringFromName("responsiveUI.addPreset"));
|
||||
this.addbutton.addEventListener("command", this.bound_addPreset, true);
|
||||
|
||||
this.removebutton = this.chromeDoc.createElement("menuitem");
|
||||
this.removebutton.setAttribute("label", this.strings.GetStringFromName("responsiveUI.removePreset"));
|
||||
this.removebutton.addEventListener("command", this.bound_removePreset, true);
|
||||
|
||||
menupopup.appendChild(this.chromeDoc.createElement("menuseparator"));
|
||||
menupopup.appendChild(this.addbutton);
|
||||
menupopup.appendChild(this.removebutton);
|
||||
|
||||
this.rotatebutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.rotatebutton.setAttribute("tabindex", "0");
|
||||
this.rotatebutton.setAttribute("label", this.strings.GetStringFromName("responsiveUI.rotate"));
|
||||
@ -344,11 +346,20 @@ ResponsiveUI.prototype = {
|
||||
let fragment = this.chromeDoc.createDocumentFragment();
|
||||
let doc = this.chromeDoc;
|
||||
|
||||
for (let i = 0; i < this.presets.length; i++) {
|
||||
for (let preset of this.presets) {
|
||||
let menuitem = doc.createElement("menuitem");
|
||||
if (i == this.currentPreset)
|
||||
menuitem.setAttribute("ispreset", true);
|
||||
this.menuitems.set(menuitem, preset);
|
||||
|
||||
if (preset.key === this.currentPresetKey) {
|
||||
menuitem.setAttribute("selected", "true");
|
||||
this.setMenuLabel(menuitem, this.presets[i]);
|
||||
this.selectedItem = menuitem;
|
||||
}
|
||||
|
||||
if (preset.custom)
|
||||
this.customMenuitem = menuitem;
|
||||
|
||||
this.setMenuLabel(menuitem, preset);
|
||||
fragment.appendChild(menuitem);
|
||||
}
|
||||
aParent.appendChild(fragment);
|
||||
@ -365,6 +376,9 @@ ResponsiveUI.prototype = {
|
||||
if (aPreset.custom) {
|
||||
let str = this.strings.formatStringFromName("responsiveUI.customResolution", [size], 1);
|
||||
aMenuitem.setAttribute("label", str);
|
||||
} else if (aPreset.name != null && aPreset.name !== "") {
|
||||
let str = this.strings.formatStringFromName("responsiveUI.namedResolution", [size, aPreset.name], 2);
|
||||
aMenuitem.setAttribute("label", str);
|
||||
} else {
|
||||
aMenuitem.setAttribute("label", size);
|
||||
}
|
||||
@ -374,10 +388,24 @@ ResponsiveUI.prototype = {
|
||||
* When a preset is selected, apply it.
|
||||
*/
|
||||
presetSelected: function RUI_presetSelected() {
|
||||
this.rotateValue = false;
|
||||
this.currentPreset = this.menulist.selectedIndex;
|
||||
let preset = this.presets[this.currentPreset];
|
||||
this.loadPreset(preset);
|
||||
if (this.menulist.selectedItem.getAttribute("ispreset") === "true") {
|
||||
this.selectedItem = this.menulist.selectedItem;
|
||||
|
||||
this.rotateValue = false;
|
||||
let selectedPreset = this.menuitems.get(this.selectedItem);
|
||||
this.loadPreset(selectedPreset);
|
||||
this.currentPresetKey = selectedPreset.key;
|
||||
this.saveCurrentPreset();
|
||||
|
||||
// Update the buttons hidden status according to the new selected preset
|
||||
if (selectedPreset == this.customPreset) {
|
||||
this.addbutton.hidden = false;
|
||||
this.removebutton.hidden = true;
|
||||
} else {
|
||||
this.addbutton.hidden = true;
|
||||
this.removebutton.hidden = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -389,15 +417,103 @@ ResponsiveUI.prototype = {
|
||||
this.setSize(aPreset.width, aPreset.height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a preset to the list and the memory
|
||||
*/
|
||||
addPreset: function RUI_addPreset() {
|
||||
let w = this.customPreset.width;
|
||||
let h = this.customPreset.height;
|
||||
let newName = {};
|
||||
|
||||
let title = this.strings.GetStringFromName("responsiveUI.customNamePromptTitle");
|
||||
let message = this.strings.formatStringFromName("responsiveUI.customNamePromptMsg", [w, h], 2);
|
||||
Services.prompt.prompt(null, title, message, newName, null, {});
|
||||
|
||||
let newPreset = {
|
||||
key: w + "x" + h,
|
||||
name: newName.value,
|
||||
width: w,
|
||||
height: h
|
||||
};
|
||||
|
||||
this.presets.push(newPreset);
|
||||
|
||||
// Sort the presets according to width/height ascending order
|
||||
this.presets.sort(function RUI_sortPresets(aPresetA, aPresetB) {
|
||||
// We keep custom preset at first
|
||||
if (aPresetA.custom && !aPresetB.custom) {
|
||||
return 1;
|
||||
}
|
||||
if (!aPresetA.custom && aPresetB.custom) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aPresetA.width === aPresetB.width) {
|
||||
if (aPresetA.height === aPresetB.height) {
|
||||
return 0;
|
||||
} else {
|
||||
return aPresetA.height > aPresetB.height;
|
||||
}
|
||||
} else {
|
||||
return aPresetA.width > aPresetB.width;
|
||||
}
|
||||
});
|
||||
|
||||
this.savePresets();
|
||||
|
||||
let newMenuitem = this.chromeDoc.createElement("menuitem");
|
||||
newMenuitem.setAttribute("ispreset", true);
|
||||
this.setMenuLabel(newMenuitem, newPreset);
|
||||
|
||||
this.menuitems.set(newMenuitem, newPreset);
|
||||
let idx = this.presets.indexOf(newPreset);
|
||||
let beforeMenuitem = this.menulist.firstChild.childNodes[idx + 1];
|
||||
this.menulist.firstChild.insertBefore(newMenuitem, beforeMenuitem);
|
||||
|
||||
this.menulist.selectedItem = newMenuitem;
|
||||
this.currentPresetKey = newPreset.key;
|
||||
this.saveCurrentPreset();
|
||||
},
|
||||
|
||||
/**
|
||||
* remove a preset from the list and the memory
|
||||
*/
|
||||
removePreset: function RUI_removePreset() {
|
||||
let selectedPreset = this.menuitems.get(this.selectedItem);
|
||||
let w = selectedPreset.width;
|
||||
let h = selectedPreset.height;
|
||||
|
||||
this.presets.splice(this.presets.indexOf(selectedPreset), 1);
|
||||
this.menulist.firstChild.removeChild(this.selectedItem);
|
||||
this.menuitems.delete(this.selectedItem);
|
||||
|
||||
this.customPreset.width = w;
|
||||
this.customPreset.height = h;
|
||||
let menuitem = this.customMenuitem;
|
||||
this.setMenuLabel(menuitem, this.customPreset);
|
||||
this.menulist.selectedItem = menuitem;
|
||||
this.currentPresetKey = this.customPreset.key;
|
||||
|
||||
this.setSize(w, h);
|
||||
|
||||
this.savePresets();
|
||||
},
|
||||
|
||||
/**
|
||||
* Swap width and height.
|
||||
*/
|
||||
rotate: function RUI_rotate() {
|
||||
this.setSize(this.currentHeight, this.currentWidth);
|
||||
if (this.currentPreset == 0) {
|
||||
let selectedPreset = this.menuitems.get(this.selectedItem);
|
||||
let width = this.rotateValue ? selectedPreset.height : selectedPreset.width;
|
||||
let height = this.rotateValue ? selectedPreset.width : selectedPreset.height;
|
||||
|
||||
this.setSize(height, width);
|
||||
|
||||
if (selectedPreset.custom) {
|
||||
this.saveCustomSize();
|
||||
} else {
|
||||
this.rotateValue = !this.rotateValue;
|
||||
this.saveCurrentPreset();
|
||||
}
|
||||
},
|
||||
|
||||
@ -408,8 +524,8 @@ ResponsiveUI.prototype = {
|
||||
* @param aHeight height of the browser.
|
||||
*/
|
||||
setSize: function RUI_setSize(aWidth, aHeight) {
|
||||
this.currentWidth = Math.min(Math.max(aWidth, MIN_WIDTH), MAX_WIDTH);
|
||||
this.currentHeight = Math.min(Math.max(aHeight, MIN_HEIGHT), MAX_WIDTH);
|
||||
aWidth = Math.min(Math.max(aWidth, MIN_WIDTH), MAX_WIDTH);
|
||||
aHeight = Math.min(Math.max(aHeight, MIN_HEIGHT), MAX_WIDTH);
|
||||
|
||||
// We resize the containing stack.
|
||||
let style = "max-width: %width;" +
|
||||
@ -417,22 +533,22 @@ ResponsiveUI.prototype = {
|
||||
"max-height: %height;" +
|
||||
"min-height: %height;";
|
||||
|
||||
style = style.replace(/%width/g, this.currentWidth + "px");
|
||||
style = style.replace(/%height/g, this.currentHeight + "px");
|
||||
style = style.replace(/%width/g, aWidth + "px");
|
||||
style = style.replace(/%height/g, aHeight + "px");
|
||||
|
||||
this.stack.setAttribute("style", style);
|
||||
|
||||
if (!this.ignoreY)
|
||||
this.resizeBar.setAttribute("top", Math.round(this.currentHeight / 2));
|
||||
this.resizeBar.setAttribute("top", Math.round(aHeight / 2));
|
||||
|
||||
// We uptate the Custom menuitem if we are not using a preset.
|
||||
if (this.presets[this.currentPreset].custom) {
|
||||
let preset = this.presets[this.currentPreset];
|
||||
preset.width = this.currentWidth;
|
||||
preset.height = this.currentHeight;
|
||||
let selectedPreset = this.menuitems.get(this.selectedItem);
|
||||
|
||||
let menuitem = this.menulist.firstChild.childNodes[this.currentPreset];
|
||||
this.setMenuLabel(menuitem, preset);
|
||||
// We uptate the custom menuitem if we are using it
|
||||
if (selectedPreset.custom) {
|
||||
selectedPreset.width = aWidth;
|
||||
selectedPreset.height = aHeight;
|
||||
|
||||
this.setMenuLabel(this.selectedItem, selectedPreset);
|
||||
}
|
||||
},
|
||||
|
||||
@ -442,15 +558,17 @@ ResponsiveUI.prototype = {
|
||||
* @param aEvent
|
||||
*/
|
||||
startResizing: function RUI_startResizing(aEvent) {
|
||||
let preset = this.presets[this.currentPreset];
|
||||
if (!preset.custom) {
|
||||
this.currentPreset = 0;
|
||||
preset = this.presets[0];
|
||||
preset.width = this.currentWidth;
|
||||
preset.height = this.currentHeight;
|
||||
let menuitem = this.menulist.firstChild.childNodes[0];
|
||||
this.setMenuLabel(menuitem, preset);
|
||||
this.menulist.selectedIndex = 0;
|
||||
let selectedPreset = this.menuitems.get(this.selectedItem);
|
||||
|
||||
if (!selectedPreset.custom) {
|
||||
this.customPreset.width = this.rotateValue ? selectedPreset.height : selectedPreset.width;
|
||||
this.customPreset.height = this.rotateValue ? selectedPreset.width : selectedPreset.height;
|
||||
|
||||
let menuitem = this.customMenuitem;
|
||||
this.setMenuLabel(menuitem, this.customPreset);
|
||||
|
||||
this.currentPresetKey = this.customPreset.key;
|
||||
this.menulist.selectedItem = menuitem;
|
||||
}
|
||||
this.mainWindow.addEventListener("mouseup", this.bound_stopResizing, true);
|
||||
this.mainWindow.addEventListener("mousemove", this.bound_onDrag, true);
|
||||
@ -479,8 +597,8 @@ ResponsiveUI.prototype = {
|
||||
if (this.ignoreY)
|
||||
deltaY = 0;
|
||||
|
||||
let width = this.currentWidth + deltaX;
|
||||
let height = this.currentHeight + deltaY;
|
||||
let width = this.customPreset.width + deltaX;
|
||||
let height = this.customPreset.height + deltaY;
|
||||
|
||||
if (width < MIN_WIDTH) {
|
||||
width = MIN_WIDTH;
|
||||
@ -520,18 +638,29 @@ ResponsiveUI.prototype = {
|
||||
* Store the custom size as a pref.
|
||||
*/
|
||||
saveCustomSize: function RUI_saveCustomSize() {
|
||||
Services.prefs.setIntPref("devtools.responsiveUI.customWidth", this.currentWidth);
|
||||
Services.prefs.setIntPref("devtools.responsiveUI.customHeight", this.currentHeight);
|
||||
Services.prefs.setIntPref("devtools.responsiveUI.customWidth", this.customPreset.width);
|
||||
Services.prefs.setIntPref("devtools.responsiveUI.customHeight", this.customPreset.height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Store the current preset as a pref.
|
||||
*/
|
||||
saveCurrentPreset: function RUI_saveCurrentPreset() {
|
||||
let key = this.presets[this.currentPreset].key;
|
||||
Services.prefs.setCharPref("devtools.responsiveUI.currentPreset", key);
|
||||
Services.prefs.setCharPref("devtools.responsiveUI.currentPreset", this.currentPresetKey);
|
||||
Services.prefs.setBoolPref("devtools.responsiveUI.rotate", this.rotateValue);
|
||||
},
|
||||
|
||||
/**
|
||||
* Store the list of all registered presets as a pref.
|
||||
*/
|
||||
savePresets: function RUI_savePresets() {
|
||||
// We exclude the custom one
|
||||
let registeredPresets = this.presets.filter(function (aPreset) {
|
||||
return !aPreset.custom;
|
||||
});
|
||||
|
||||
Services.prefs.setCharPref("devtools.responsiveUI.presets", JSON.stringify(registeredPresets));
|
||||
},
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(ResponsiveUI.prototype, "strings", function () {
|
||||
|
@ -49,6 +49,7 @@ _BROWSER_FILES = \
|
||||
browser_responsiveruleview.js \
|
||||
browser_responsive_cmd.js \
|
||||
browser_responsivecomputedview.js \
|
||||
browser_responsiveuiaddcustompreset.js \
|
||||
head.js \
|
||||
helpers.js \
|
||||
$(NULL)
|
||||
|
@ -50,7 +50,8 @@ function test() {
|
||||
|
||||
testOnePreset(c - 1);
|
||||
}
|
||||
testOnePreset(instance.menulist.firstChild.childNodes.length - 1);
|
||||
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
|
||||
testOnePreset(instance.menulist.firstChild.childNodes.length - 4);
|
||||
}
|
||||
|
||||
function extractSizeFromString(str) {
|
||||
|
@ -0,0 +1,162 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance, deletedPresetA, deletedPresetB, oldPrompt;
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,foo";
|
||||
|
||||
function startTest() {
|
||||
// Mocking prompt
|
||||
oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
|
||||
aValue.value = "Testing preset";
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
executeSoon(onUIOpen);
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
testAddCustomPreset();
|
||||
}
|
||||
|
||||
function testAddCustomPreset() {
|
||||
let customHeight = 123, customWidth = 456;
|
||||
instance.setSize(customWidth, customHeight);
|
||||
|
||||
// Adds the custom preset with "Testing preset" as label (look at mock upper)
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 1;
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
executeSoon(restart);
|
||||
}
|
||||
|
||||
function restart() {
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
|
||||
testCustomPresetInList();
|
||||
}
|
||||
|
||||
function testCustomPresetInList() {
|
||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||
|
||||
instance.menulist.selectedIndex = customPresetIndex;
|
||||
|
||||
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
|
||||
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
|
||||
|
||||
testDeleteCustomPresets();
|
||||
}
|
||||
|
||||
function testDeleteCustomPresets() {
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
executeSoon(restartAgain);
|
||||
}
|
||||
|
||||
function restartAgain() {
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
executeSoon(testCustomPresetsNotInListAnymore);
|
||||
}
|
||||
|
||||
function testCustomPresetsNotInListAnymore() {
|
||||
let customPresetIndex = getPresetIndex(deletedPresetA);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetB);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
|
||||
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
delete instance;
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
Services.prompt = oldPrompt;
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function getPresetIndex(presetLabel) {
|
||||
function testOnePreset(c) {
|
||||
if (c == 0) {
|
||||
return -1;
|
||||
}
|
||||
instance.menulist.selectedIndex = c;
|
||||
|
||||
let item = instance.menulist.firstChild.childNodes[c];
|
||||
if (item.getAttribute("label") === presetLabel) {
|
||||
return c;
|
||||
} else {
|
||||
return testOnePreset(c - 1);
|
||||
}
|
||||
}
|
||||
return testOnePreset(instance.menulist.firstChild.childNodes.length - 4);
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
title="&window.title;"
|
||||
windowtype="devtools:scratchpad"
|
||||
macanimationtype="document"
|
||||
fullscreenbutton="true"
|
||||
screenX="4" screenY="4"
|
||||
width="640" height="480"
|
||||
persist="screenX screenY width height sizemode">
|
||||
|
@ -11,7 +11,26 @@
|
||||
# LOCALIZATION NOTE (responsiveUI.rotate): label of the rotate button.
|
||||
responsiveUI.rotate=rotate
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.addPreset): label of the add preset button.
|
||||
responsiveUI.addPreset=Add Preset
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.removePreset): label of the remove preset button.
|
||||
responsiveUI.removePreset=Remove Preset
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.customResolution): label of the first item
|
||||
# in the menulist at the beginning of the toolbar. For %S is replace with the
|
||||
# current size of the page. For example: "400x600".
|
||||
responsiveUI.customResolution=%S (custom)
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.namedResolution): label of custom items with a name
|
||||
# in the menulist of the toolbar.
|
||||
# For example: "320x480 (phone)".
|
||||
responsiveUI.namedResolution=%S (%S)
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.customNamePromptTitle): prompt title when asking
|
||||
# the user to specify a name for a new custom preset.
|
||||
responsiveUI.customNamePromptTitle=Responsive Design View
|
||||
|
||||
# LOCALIZATION NOTE (responsiveUI.customNamePromptMsg): prompt message when asking
|
||||
# the user to specify a name for a new custom preset.
|
||||
responsiveUI.customNamePromptMsg=Give a name to the %Sx%S preset
|
@ -159,14 +159,7 @@
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 793615
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:sqlite3MemMalloc
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 793616
|
||||
Bug 793608 variant 2
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:make_request
|
||||
@ -178,6 +171,13 @@
|
||||
fun:start_thread
|
||||
fun:clone
|
||||
}
|
||||
{
|
||||
Bug 793615
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:sqlite3MemMalloc
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 794350
|
||||
Memcheck:Leak
|
||||
@ -217,13 +217,6 @@
|
||||
fun:_ZN2js4mjit2ic10GetElementERNS_7VMFrameEPNS1_12GetElementICE
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 794365
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:_ZN14JSInlineString8uninlineEP9JSContext
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 794369
|
||||
Memcheck:Leak
|
||||
|
Loading…
Reference in New Issue
Block a user