merge m-c to fx-team

This commit is contained in:
Tim Taubert 2012-03-13 11:28:24 +01:00
commit 910f5e845d
62 changed files with 927 additions and 952 deletions

View File

@ -15,16 +15,14 @@ function Cell(aGrid, aNode) {
this._node._newtabCell = this;
// Register drag-and-drop event handlers.
["DragEnter", "DragOver", "DragExit", "Drop"].forEach(function (aType) {
let method = "on" + aType;
this[method] = this[method].bind(this);
this._node.addEventListener(aType.toLowerCase(), this[method], false);
["dragenter", "dragover", "dragexit", "drop"].forEach(function (aType) {
this._node.addEventListener(aType, this, false);
}, this);
}
Cell.prototype = {
/**
*
* The grid.
*/
_grid: null,
@ -97,41 +95,27 @@ Cell.prototype = {
},
/**
* Event handler for the 'dragenter' event.
* @param aEvent The dragenter event.
* Handles all cell events.
*/
onDragEnter: function Cell_onDragEnter(aEvent) {
if (gDrag.isValid(aEvent)) {
aEvent.preventDefault();
gDrop.enter(this, aEvent);
}
},
handleEvent: function Cell_handleEvent(aEvent) {
if (aEvent.type != "dragexit" && !gDrag.isValid(aEvent))
return;
/**
* Event handler for the 'dragover' event.
* @param aEvent The dragover event.
*/
onDragOver: function Cell_onDragOver(aEvent) {
if (gDrag.isValid(aEvent))
aEvent.preventDefault();
},
/**
* Event handler for the 'dragexit' event.
* @param aEvent The dragexit event.
*/
onDragExit: function Cell_onDragExit(aEvent) {
gDrop.exit(this, aEvent);
},
/**
* Event handler for the 'drop' event.
* @param aEvent The drop event.
*/
onDrop: function Cell_onDrop(aEvent) {
if (gDrag.isValid(aEvent)) {
aEvent.preventDefault();
gDrop.drop(this, aEvent);
switch (aEvent.type) {
case "dragenter":
aEvent.preventDefault();
gDrop.enter(this, aEvent);
break;
case "dragover":
aEvent.preventDefault();
break;
case "dragexit":
gDrop.exit(this, aEvent);
break;
case "drop":
aEvent.preventDefault();
gDrop.drop(this, aEvent);
break;
}
}
};

View File

@ -36,11 +36,11 @@ let gDrag = {
start: function Drag_start(aSite, aEvent) {
this._draggedSite = aSite;
// Prevent moz-transform for left, top.
aSite.node.setAttribute("dragged", "true");
// Make sure the dragged site is floating above the grid.
aSite.node.setAttribute("ontop", "true");
// Mark nodes as being dragged.
let selector = ".newtab-site, .newtab-control, .newtab-thumbnail";
let nodes = aSite.node.parentNode.querySelectorAll(selector);
for (let i = 0; i < nodes.length; i++)
nodes[i].setAttribute("dragged", "true");
this._setDragData(aSite, aEvent);
@ -88,13 +88,12 @@ let gDrag = {
* @param aEvent The 'dragend' event.
*/
end: function Drag_end(aSite, aEvent) {
aSite.node.removeAttribute("dragged");
let nodes = aSite.node.parentNode.querySelectorAll("[dragged]");
for (let i = 0; i < nodes.length; i++)
nodes[i].removeAttribute("dragged");
// Slide the dragged site back into its cell (may be the old or the new cell).
gTransformation.slideSiteTo(aSite, aSite.cell, {
unfreeze: true,
callback: function () aSite.node.removeAttribute("ontop")
});
gTransformation.slideSiteTo(aSite, aSite.cell, {unfreeze: true});
this._draggedSite = null;
},
@ -106,7 +105,11 @@ let gDrag = {
*/
isValid: function Drag_isValid(aEvent) {
let dt = aEvent.dataTransfer;
return dt && dt.types.contains("text/x-moz-url");
let mimeType = "text/x-moz-url";
// Check that the drag data is non-empty.
// Can happen when dragging places folders.
return dt && dt.types.contains(mimeType) && dt.getData(mimeType);
},
/**
@ -128,13 +131,13 @@ let gDrag = {
// Create and use an empty drag element. We don't want to use the default
// drag image with its default opacity.
let dragElement = document.createElementNS(HTML_NAMESPACE, "div");
dragElement.classList.add("drag-element");
let body = document.getElementById("body");
body.appendChild(dragElement);
dragElement.classList.add("newtab-drag");
let scrollbox = document.getElementById("newtab-scrollbox");
scrollbox.appendChild(dragElement);
dt.setDragImage(dragElement, 0, 0);
// After the 'dragstart' event has been processed we can remove the
// temporary drag element from the DOM.
setTimeout(function () body.removeChild(dragElement), 0);
setTimeout(function () scrollbox.removeChild(dragElement), 0);
}
};

View File

@ -26,13 +26,26 @@ let gDropTargetShim = {
init: function DropTargetShim_init() {
let node = gGrid.node;
this._dragover = this._dragover.bind(this);
// Add drag event handlers.
node.addEventListener("dragstart", this._start.bind(this), true);
// XXX bug 505521 - Don't listen for drag, it's useless at the moment.
//node.addEventListener("drag", this._drag.bind(this), false);
node.addEventListener("dragend", this._end.bind(this), true);
node.addEventListener("dragstart", this, true);
node.addEventListener("dragend", this, true);
},
/**
* Handles all shim events.
*/
handleEvent: function DropTargetShim_handleEvent(aEvent) {
switch (aEvent.type) {
case "dragstart":
this._start(aEvent);
break;
case "dragover":
this._dragover(aEvent);
break;
case "dragend":
this._end(aEvent);
break;
}
},
/**
@ -40,11 +53,11 @@ let gDropTargetShim = {
* @param aEvent The 'dragstart' event.
*/
_start: function DropTargetShim_start(aEvent) {
if (aEvent.target.classList.contains("site")) {
if (aEvent.target.classList.contains("newtab-link")) {
gGrid.lock();
// XXX bug 505521 - Listen for dragover on the document.
document.documentElement.addEventListener("dragover", this._dragover, false);
document.documentElement.addEventListener("dragover", this, false);
}
},
@ -56,12 +69,7 @@ let gDropTargetShim = {
// Let's see if we find a drop target.
let target = this._findDropTarget(aEvent);
if (target == this._lastDropTarget) {
// XXX bug 505521 - Don't fire dragover for now (causes recursion).
/*if (target)
// The last drop target is valid and didn't change.
this._dispatchEvent(aEvent, "dragover", target);*/
} else {
if (target != this._lastDropTarget) {
if (this._lastDropTarget)
// We left the last drop target.
this._dispatchEvent(aEvent, "dragexit", this._lastDropTarget);
@ -84,7 +92,7 @@ let gDropTargetShim = {
* @param aEvent The 'dragover' event.
*/
_dragover: function DropTargetShim_dragover(aEvent) {
let sourceNode = aEvent.dataTransfer.mozSourceNode;
let sourceNode = aEvent.dataTransfer.mozSourceNode.parentNode;
gDrag.drag(sourceNode._newtabSite, aEvent);
this._drag(aEvent);
@ -117,7 +125,7 @@ let gDropTargetShim = {
gGrid.unlock();
// XXX bug 505521 - Remove the document's dragover listener.
document.documentElement.removeEventListener("dragover", this._dragover, false);
document.documentElement.removeEventListener("dragover", this, false);
},
/**

View File

@ -24,7 +24,7 @@ let gGrid = {
*/
get cells() {
let cells = [];
let children = this.node.querySelectorAll("li");
let children = this.node.querySelectorAll(".newtab-cell");
for (let i = 0; i < children.length; i++)
cells.push(new Cell(this, children[i]));
@ -43,8 +43,8 @@ let gGrid = {
* Initializes the grid.
* @param aSelector The query selector of the grid.
*/
init: function Grid_init(aSelector) {
this._node = document.querySelector(aSelector);
init: function Grid_init() {
this._node = document.getElementById("newtab-grid");
this._createSiteFragment();
this._draw();
},
@ -96,21 +96,20 @@ let gGrid = {
* Creates the DOM fragment that is re-used when creating sites.
*/
_createSiteFragment: function Grid_createSiteFragment() {
let site = document.createElementNS(HTML_NAMESPACE, "a");
site.classList.add("site");
let site = document.createElementNS(HTML_NAMESPACE, "div");
site.classList.add("newtab-site");
site.setAttribute("draggable", "true");
// Create the site's inner HTML code.
site.innerHTML =
'<img class="site-img" width="' + THUMB_WIDTH +'" ' +
' height="' + THUMB_HEIGHT + '" alt=""/>' +
'<span class="site-title"/>' +
'<span class="site-strip">' +
' <input class="button strip-button strip-button-pin" type="button"' +
' tabindex="-1" title="' + newTabString("pin") + '"/>' +
' <input class="button strip-button strip-button-block" type="button"' +
' tabindex="-1" title="' + newTabString("block") + '"/>' +
'</span>';
'<a class="newtab-link">' +
' <span class="newtab-thumbnail"/>' +
' <span class="newtab-title"/>' +
'</a>' +
'<input type="button" title="' + newTabString("pin") + '"' +
' class="newtab-control newtab-control-pin"/>' +
'<input type="button" title="' + newTabString("block") + '"' +
' class="newtab-control newtab-control-block"/>';
this._siteFragment = document.createDocumentFragment();
this._siteFragment.appendChild(site);

View File

@ -1,161 +1,174 @@
:root {
-moz-appearance: none;
-moz-user-focus: normal;
}
#scrollbox:not([page-disabled]) {
input[type=button] {
cursor: pointer;
}
/* SCROLLBOX */
#newtab-scrollbox {
display: -moz-box;
position: relative;
-moz-box-flex: 1;
}
#newtab-scrollbox:not([page-disabled]) {
overflow: auto;
}
#body {
position: relative;
margin: 0;
min-width: 675px;
-moz-user-select: none;
}
.button {
cursor: pointer;
}
/* TOOLBAR */
#toolbar {
/* TOGGLE */
#newtab-toggle {
position: absolute;
top: 12px;
right: 12px;
}
#toolbar[page-disabled] {
position: fixed;
}
#toolbar:-moz-locale-dir(rtl) {
left: 8px;
#newtab-toggle:-moz-locale-dir(rtl) {
left: 12px;
right: auto;
}
.toolbar-button {
position: absolute;
cursor: pointer;
-moz-transition: opacity 200ms ease-out;
/* MARGINS */
#newtab-vertical-margin {
display: -moz-box;
position: relative;
-moz-box-flex: 1;
-moz-box-orient: vertical;
}
#toolbar-button-show,
#toolbar-button-reset {
opacity: 0;
pointer-events: none;
#newtab-margin-top {
min-height: 50px;
max-height: 80px;
-moz-box-flex: 1;
}
#toolbar-button-reset[modified],
#toolbar-button-show[page-disabled] {
opacity: 1;
pointer-events: auto;
#newtab-margin-bottom {
min-height: 40px;
max-height: 100px;
-moz-box-flex: 1;
}
#toolbar-button-hide[page-disabled],
#toolbar-button-reset[page-disabled] {
opacity: 0;
pointer-events: none;
#newtab-horizontal-margin {
display: -moz-box;
-moz-box-flex: 5;
}
.newtab-side-margin {
min-width: 40px;
max-width: 300px;
-moz-box-flex: 1;
}
/* GRID */
#grid {
width: 637px;
height: 411px;
overflow: hidden;
list-style-type: none;
-moz-transition: opacity 200ms ease-out;
#newtab-grid {
display: -moz-box;
-moz-box-flex: 5;
-moz-box-orient: vertical;
min-width: 600px;
min-height: 400px;
-moz-transition: 100ms ease-out;
-moz-transition-property: opacity;
}
#grid[page-disabled] {
#newtab-grid[page-disabled] {
opacity: 0;
}
#grid[page-disabled],
#grid[locked] {
#newtab-grid[locked],
#newtab-grid[page-disabled] {
pointer-events: none;
}
/* ROWS */
.newtab-row {
display: -moz-box;
-moz-box-orient: horizontal;
-moz-box-direction: normal;
-moz-box-flex: 1;
}
/* CELLS */
.cell {
float: left;
width: 201px;
height: 127px;
margin-bottom: 15px;
-moz-margin-end: 16px;
}
.cell:-moz-locale-dir(rtl) {
float: right;
}
.cell:nth-child(3n+3) {
-moz-margin-end: 0;
.newtab-cell {
display: -moz-box;
-moz-box-flex: 1;
}
/* SITES */
.site {
display: block;
.newtab-site {
position: relative;
width: 201px;
height: 127px;
-moz-box-flex: 1;
-moz-transition: 100ms ease-out;
-moz-transition-property: top, left, opacity;
}
.site[frozen] {
.newtab-site[frozen] {
position: absolute;
pointer-events: none;
}
.site[ontop] {
.newtab-site[dragged] {
-moz-transition-property: none;
z-index: 10;
}
/* SITE IMAGE */
.site-img {
display: block;
opacity: 0.75;
-moz-transition: opacity 200ms ease-out;
}
.site:hover > .site-img,
.site[ontop] > .site-img,
.site:-moz-focusring > .site-img {
opacity: 1;
}
.site-img[loading] {
display: none;
}
/* SITE TITLE */
.site-title {
position: absolute;
left: 0;
bottom: 0;
overflow: hidden;
}
/* SITE STRIP */
.site-strip {
/* LINK + THUMBNAILS */
.newtab-link,
.newtab-thumbnail {
position: absolute;
left: 0;
top: 0;
width: 195px;
height: 17px;
overflow: hidden;
opacity: 0;
-moz-transition: opacity 200ms ease-out;
right: 0;
bottom: 0;
}
.site:hover:not([frozen]) > .site-strip {
.newtab-thumbnail {
opacity: .8;
-moz-transition: opacity 100ms ease-out;
}
.newtab-thumbnail[dragged],
.newtab-link:-moz-focusring > .newtab-thumbnail,
.newtab-site:hover > .newtab-link > .newtab-thumbnail {
opacity: 1;
}
.strip-button-pin,
.strip-button-block:-moz-locale-dir(rtl) {
float: left;
/* TITLES */
.newtab-title {
position: absolute;
left: 0;
right: 0;
bottom: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.strip-button-block,
.strip-button-pin:-moz-locale-dir(rtl) {
float: right;
/* CONTROLS */
.newtab-control {
position: absolute;
top: 4px;
opacity: 0;
-moz-transition: opacity 100ms ease-out;
}
.newtab-control:-moz-focusring,
.newtab-site:hover > .newtab-control {
opacity: 1;
}
.newtab-control[dragged] {
opacity: 0 !important;
}
.newtab-control-pin:-moz-locale-dir(ltr),
.newtab-control-block:-moz-locale-dir(rtl) {
left: 4px;
}
.newtab-control-block:-moz-locale-dir(ltr),
.newtab-control-pin:-moz-locale-dir(rtl) {
right: 4px;
}
/* DRAG & DROP */
@ -165,7 +178,7 @@
* so that we can use custom drag images and elements. It needs an opacity of
* 0.01 so that the core code detects that it's in fact a visible element.
*/
.drag-element {
.newtab-drag {
width: 1px;
height: 1px;
background-color: #fff;

View File

@ -30,13 +30,10 @@ XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
function newTabString(name) gStringBundle.GetStringFromName('newtab.' + name);
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
const THUMB_WIDTH = 201;
const THUMB_HEIGHT = 127;
#include batch.js
#include transformations.js
#include page.js
#include toolbar.js
#include grid.js
#include cells.js
#include sites.js
@ -47,4 +44,4 @@ const THUMB_HEIGHT = 127;
#include updater.js
// Everything is loaded. Initialize the New Tab Page.
gPage.init("#toolbar", "#grid");
gPage.init();

View File

@ -4,7 +4,7 @@
# 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/.
<?xml-stylesheet href="chrome://global/skin/global.css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/newtab/newTab.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/newtab/newTab.css" type="text/css"?>
@ -13,28 +13,44 @@
%newTabDTD;
]>
<xul:window xmlns="http://www.w3.org/1999/xhtml"
<xul:window id="newtab-window" xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
disablefastfind="true" title="&newtab.pageTitle;">
<xul:vbox id="scrollbox" flex="1" title=" ">
<body id="body">
<div id="toolbar">
<input class="button toolbar-button" id="toolbar-button-show"
type="button" title="&newtab.show;"/>
<input class="button toolbar-button" id="toolbar-button-hide"
type="button" title="&newtab.hide;"/>
<input class="button toolbar-button" id="toolbar-button-reset"
type="button" title="&newtab.reset;"/>
xul:disablefastfind="true" xul:title="&newtab.pageTitle;">
<div id="newtab-scrollbox">
<div id="newtab-vertical-margin">
<div id="newtab-margin-top"/>
<div id="newtab-horizontal-margin">
<div class="newtab-side-margin"/>
<div id="newtab-grid">
<div class="newtab-row">
<div class="newtab-cell"/>
<div class="newtab-cell"/>
<div class="newtab-cell"/>
</div>
<div class="newtab-row">
<div class="newtab-cell"/>
<div class="newtab-cell"/>
<div class="newtab-cell"/>
</div>
<div class="newtab-row">
<div class="newtab-cell"/>
<div class="newtab-cell"/>
<div class="newtab-cell"/>
</div>
</div>
<div class="newtab-side-margin"/>
</div>
<ul id="grid">
<li class="cell"/><li class="cell"/><li class="cell"/>
<li class="cell"/><li class="cell"/><li class="cell"/>
<li class="cell"/><li class="cell"/><li class="cell"/>
</ul>
<div id="newtab-margin-bottom"/>
</div>
<input id="newtab-toggle" type="button"/>
</div>
<xul:script type="text/javascript;version=1.8"
src="chrome://browser/content/newtab/newTab.js"/>
</body>
</xul:vbox>
<xul:script type="text/javascript;version=1.8"
src="chrome://browser/content/newtab/newTab.js"/>
</xul:window>

View File

@ -11,25 +11,24 @@
let gPage = {
/**
* Initializes the page.
* @param aToolbarSelector The query selector for the page toolbar.
* @param aGridSelector The query selector for the grid.
*/
init: function Page_init(aToolbarSelector, aGridSelector) {
gToolbar.init(aToolbarSelector);
this._gridSelector = aGridSelector;
init: function Page_init() {
// Add ourselves to the list of pages to receive notifications.
gAllPages.register(this);
// Listen for 'unload' to unregister this page.
function unload() { gAllPages.unregister(this); }
addEventListener("unload", unload.bind(this), false);
addEventListener("unload", this, false);
// Listen for toggle button clicks.
let button = document.getElementById("newtab-toggle");
button.addEventListener("click", this, false);
// Check if the new tab feature is enabled.
if (gAllPages.enabled)
let enabled = gAllPages.enabled;
if (enabled)
this._init();
else
this._updateAttributes(false);
this._updateAttributes(enabled);
},
/**
@ -48,25 +47,9 @@ let gPage = {
* Updates the whole page and the grid when the storage has changed.
*/
update: function Page_update() {
this.updateModifiedFlag();
gGrid.refresh();
},
/**
* Checks if the page is modified and sets the CSS class accordingly
*/
updateModifiedFlag: function Page_updateModifiedFlag() {
let node = document.getElementById("toolbar-button-reset");
let modified = this._isModified();
if (modified)
node.setAttribute("modified", "true");
else
node.removeAttribute("modified");
this._updateTabIndices(gAllPages.enabled, modified);
},
/**
* Internally initializes the page. This runs only when/if the feature
* is/gets enabled.
@ -78,29 +61,27 @@ let gPage = {
this._initialized = true;
gLinks.populateCache(function () {
// Check if the grid is modified.
this.updateModifiedFlag();
// Initialize and render the grid.
gGrid.init(this._gridSelector);
gGrid.init();
// Initialize the drop target shim.
gDropTargetShim.init();
#ifdef XP_MACOSX
// Workaround to prevent a delay on MacOSX due to a slow drop animation.
document.addEventListener("dragover", this.onDragOver, false);
document.addEventListener("drop", this.onDrop, false);
document.addEventListener("dragover", this, false);
document.addEventListener("drop", this, false);
#endif
}.bind(this));
},
/**
* Updates the 'page-disabled' attributes of the respective DOM nodes.
* @param aValue Whether to set or remove attributes.
* @param aValue Whether the New Tab Page is enabled or not.
*/
_updateAttributes: function Page_updateAttributes(aValue) {
let nodes = document.querySelectorAll("#grid, #scrollbox, #toolbar, .toolbar-button");
let selector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid";
let nodes = document.querySelectorAll(selector);
// Set the nodes' states.
for (let i = 0; i < nodes.length; i++) {
@ -111,64 +92,32 @@ let gPage = {
node.setAttribute("page-disabled", "true");
}
this._updateTabIndices(aValue, this._isModified());
// Update the toggle button's title.
let toggle = document.getElementById("newtab-toggle");
toggle.setAttribute("title", newTabString(aValue ? "hide" : "show"));
},
/**
* Checks whether the page is modified.
* @return Whether the page is modified or not.
* Handles all page events.
*/
_isModified: function Page_isModified() {
// The page is considered modified only if sites have been removed.
return !gBlockedLinks.isEmpty();
},
/**
* Updates the tab indices of focusable elements.
* @param aEnabled Whether the page is currently enabled.
* @param aModified Whether the page is currently modified.
*/
_updateTabIndices: function Page_updateTabIndices(aEnabled, aModified) {
function setFocusable(aNode, aFocusable) {
if (aFocusable)
aNode.removeAttribute("tabindex");
else
aNode.setAttribute("tabindex", "-1");
}
// Sites and the 'hide' button are always focusable when the grid is shown.
let nodes = document.querySelectorAll(".site, #toolbar-button-hide");
for (let i = 0; i < nodes.length; i++)
setFocusable(nodes[i], aEnabled);
// The 'show' button is focusable when the grid is hidden.
let btnShow = document.getElementById("toolbar-button-show");
setFocusable(btnShow, !aEnabled);
// The 'reset' button is focusable when the grid is shown and modified.
let btnReset = document.getElementById("toolbar-button-reset");
setFocusable(btnReset, aEnabled && aModified);
},
/**
* Handles the 'dragover' event. Workaround to prevent a delay on MacOSX
* due to a slow drop animation.
* @param aEvent The 'dragover' event.
*/
onDragOver: function Page_onDragOver(aEvent) {
if (gDrag.isValid(aEvent) && gDrag.draggedSite)
aEvent.preventDefault();
},
/**
* Handles the 'drop' event. Workaround to prevent a delay on MacOSX due to
* a slow drop animation.
* @param aEvent The 'drop' event.
*/
onDrop: function Page_onDrop(aEvent) {
if (gDrag.isValid(aEvent) && gDrag.draggedSite) {
aEvent.preventDefault();
aEvent.stopPropagation();
handleEvent: function Page_handleEvent(aEvent) {
switch (aEvent.type) {
case "unload":
gAllPages.unregister(this);
break;
case "click":
gAllPages.enabled = !gAllPages.enabled;
break;
case "dragover":
if (gDrag.isValid(aEvent) && gDrag.draggedSite)
aEvent.preventDefault();
break;
case "drop":
if (gDrag.isValid(aEvent) && gDrag.draggedSite) {
aEvent.preventDefault();
aEvent.stopPropagation();
}
break;
}
}
};

View File

@ -91,7 +91,6 @@ Site.prototype = {
} else {
gBlockedLinks.block(this._link);
gUpdater.updateGrid(aCallback);
gPage.updateModifiedFlag();
}
},
@ -110,14 +109,14 @@ Site.prototype = {
* @param aPinned Whether this site is now pinned or unpinned.
*/
_updateAttributes: function (aPinned) {
let buttonPin = this._querySelector(".strip-button-pin");
let control = this._querySelector(".newtab-control-pin");
if (aPinned) {
this.node.setAttribute("pinned", true);
buttonPin.setAttribute("title", newTabString("unpin"));
control.setAttribute("pinned", true);
control.setAttribute("title", newTabString("unpin"));
} else {
this.node.removeAttribute("pinned");
buttonPin.setAttribute("title", newTabString("pin"));
control.removeAttribute("pinned");
control.setAttribute("title", newTabString("pin"));
}
},
@ -126,32 +125,17 @@ Site.prototype = {
*/
_render: function Site_render() {
let title = this.title || this.url;
this.node.setAttribute("title", title);
this.node.setAttribute("href", this.url);
this._querySelector(".site-title").textContent = title;
let link = this._querySelector(".newtab-link");
link.setAttribute("title", title);
link.setAttribute("href", this.url);
this._querySelector(".newtab-title").textContent = title;
if (this.isPinned())
this._updateAttributes(true);
this._renderThumbnail();
},
/**
* Renders the site's thumbnail.
*/
_renderThumbnail: function Site_renderThumbnail() {
let img = this._querySelector(".site-img")
img.setAttribute("alt", this.title || this.url);
img.setAttribute("loading", "true");
// Wait until the image has loaded.
img.addEventListener("load", function onLoad() {
img.removeEventListener("load", onLoad, false);
img.removeAttribute("loading");
}, false);
// Set the thumbnail url.
img.setAttribute("src", PageThumbs.getThumbnailURL(this.url));
let thumbnailURL = PageThumbs.getThumbnailURL(this.url);
let thumbnail = this._querySelector(".newtab-thumbnail");
thumbnail.style.backgroundImage = "url(" + thumbnailURL + ")";
},
/**
@ -159,56 +143,37 @@ Site.prototype = {
*/
_addEventHandlers: function Site_addEventHandlers() {
// Register drag-and-drop event handlers.
["DragStart", /*"Drag",*/ "DragEnd"].forEach(function (aType) {
let method = "_on" + aType;
this[method] = this[method].bind(this);
this._node.addEventListener(aType.toLowerCase(), this[method], false);
}, this);
this._node.addEventListener("dragstart", this, false);
this._node.addEventListener("dragend", this, false);
let self = this;
function pin(aEvent) {
if (aEvent)
aEvent.preventDefault();
if (self.isPinned())
self.unpin();
else
self.pin();
}
function block(aEvent) {
if (aEvent)
aEvent.preventDefault();
self.block();
}
this._querySelector(".strip-button-pin").addEventListener("click", pin, false);
this._querySelector(".strip-button-block").addEventListener("click", block, false);
let controls = this.node.querySelectorAll(".newtab-control");
for (let i = 0; i < controls.length; i++)
controls[i].addEventListener("click", this, false);
},
/**
* Event handler for the 'dragstart' event.
* @param aEvent The drag event.
* Handles all site events.
*/
_onDragStart: function Site_onDragStart(aEvent) {
gDrag.start(this, aEvent);
},
/**
* Event handler for the 'drag' event.
* @param aEvent The drag event.
*/
_onDrag: function Site_onDrag(aEvent) {
gDrag.drag(this, aEvent);
},
/**
* Event handler for the 'dragend' event.
* @param aEvent The drag event.
*/
_onDragEnd: function Site_onDragEnd(aEvent) {
gDrag.end(this, aEvent);
handleEvent: function Site_handleEvent(aEvent) {
switch (aEvent.type) {
case "click":
aEvent.preventDefault();
if (aEvent.target.classList.contains("newtab-control-block"))
this.block();
else if (this.isPinned())
this.unpin();
else
this.pin();
break;
case "dragstart":
gDrag.start(this, aEvent);
break;
case "drag":
gDrag.drag(this, aEvent);
break;
case "dragend":
gDrag.end(this, aEvent);
break;
}
}
};

View File

@ -1,87 +0,0 @@
#ifdef 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/. */
#endif
/**
* This singleton represents the page's toolbar that allows to enable/disable
* the 'New Tab Page' feature and to reset the whole page.
*/
let gToolbar = {
/**
* Initializes the toolbar.
* @param aSelector The query selector of the toolbar.
*/
init: function Toolbar_init(aSelector) {
this._node = document.querySelector(aSelector);
let buttons = this._node.querySelectorAll("input");
// Listen for 'click' events on the toolbar buttons.
["show", "hide", "reset"].forEach(function (aType, aIndex) {
let self = this;
let button = buttons[aIndex];
let handler = function () self[aType]();
button.addEventListener("click", handler, false);
#ifdef XP_MACOSX
// Per default buttons lose focus after being clicked on Mac OS X.
// So when the URL bar has focus and a toolbar button is clicked the
// URL bar regains focus and the history pops up. We need to prevent
// that by explicitly removing its focus.
button.addEventListener("mousedown", function () {
window.focus();
}, false);
#endif
}, this);
},
/**
* Enables the 'New Tab Page' feature.
*/
show: function Toolbar_show() {
this._passButtonFocus("show", "hide");
gAllPages.enabled = true;
},
/**
* Disables the 'New Tab Page' feature.
*/
hide: function Toolbar_hide() {
this._passButtonFocus("hide", "show");
gAllPages.enabled = false;
},
/**
* Resets the whole page and forces it to re-render its content.
* @param aCallback The callback to call when the page has been reset.
*/
reset: function Toolbar_reset(aCallback) {
this._passButtonFocus("reset", "hide");
let node = gGrid.node;
// animate the page reset
gTransformation.fadeNodeOut(node, function () {
NewTabUtils.reset();
gLinks.populateCache(function () {
gAllPages.update();
// Without the setTimeout() we have a strange flicker.
setTimeout(function () gTransformation.fadeNodeIn(node, aCallback));
}, true);
});
},
/**
* Passes the focus from the current button to the next.
* @param aCurrent The button that currently has focus.
* @param aNext The button that is focused next.
*/
_passButtonFocus: function Toolbar_passButtonFocus(aCurrent, aNext) {
if (document.querySelector("#toolbar-button-" + aCurrent + ":-moz-focusring"))
document.getElementById("toolbar-button-" + aNext).focus();
}
};

View File

@ -10,6 +10,24 @@
* convenience methods to work with a site's DOM node.
*/
let gTransformation = {
/**
* Returns the width of the left and top border of a cell. We need to take it
* into account when measuring and comparing site and cell positions.
*/
get _cellBorderWidths() {
let cstyle = window.getComputedStyle(gGrid.cells[0].node, null);
let widths = {
left: parseInt(cstyle.getPropertyValue("border-left-width")),
top: parseInt(cstyle.getPropertyValue("border-top-width"))
};
// Cache this value, overwrite the getter.
Object.defineProperty(this, "_cellBorderWidths",
{value: widths, enumerable: true});
return widths;
},
/**
* Gets a DOM node's position.
* @param aNode The DOM node.
@ -80,6 +98,14 @@ let gTransformation = {
* @param aSite The site to freeze.
*/
freezeSitePosition: function Transformation_freezeSitePosition(aSite) {
if (this._isFrozen(aSite))
return;
let style = aSite.node.style;
let comp = getComputedStyle(aSite.node, null);
style.width = comp.getPropertyValue("width")
style.height = comp.getPropertyValue("height");
aSite.node.setAttribute("frozen", "true");
this.setSitePosition(aSite, this.getNodePosition(aSite.node));
},
@ -89,8 +115,11 @@ let gTransformation = {
* @param aSite The site to unfreeze.
*/
unfreezeSitePosition: function Transformation_unfreezeSitePosition(aSite) {
if (!this._isFrozen(aSite))
return;
let style = aSite.node.style;
style.left = style.top = "";
style.left = style.top = style.width = style.height = "";
aSite.node.removeAttribute("frozen");
},
@ -117,8 +146,13 @@ let gTransformation = {
callback();
}
// We need to take the width of a cell's border into account.
targetPosition.left += this._cellBorderWidths.left;
targetPosition.top += this._cellBorderWidths.top;
// Nothing to do here if the positions already match.
if (currentPosition.equals(targetPosition)) {
if (currentPosition.left == targetPosition.left &&
currentPosition.top == targetPosition.top) {
finish();
} else {
this.setSitePosition(aSite, targetPosition);
@ -222,5 +256,14 @@ let gTransformation = {
_moveSite: function Transformation_moveSite(aSite, aIndex, aOptions) {
this.freezeSitePosition(aSite);
this.slideSiteTo(aSite, gGrid.cells[aIndex], aOptions);
},
/**
* Checks whether a site is currently frozen.
* @param aSite The site to check.
* @return Whether the given site is frozen.
*/
_isFrozen: function Transformation_isFrozen(aSite) {
return aSite.node.hasAttribute("frozen");
}
};

View File

@ -23,6 +23,7 @@ _BROWSER_FILES = \
browser_newtab_bug722273.js \
browser_newtab_bug723102.js \
browser_newtab_bug723121.js \
browser_newtab_bug725996.js \
browser_newtab_bug734043.js \
head.js \
$(NULL)

View File

@ -12,6 +12,7 @@ function runTests() {
yield addNewTabPageTab();
gBrowser.removeTab(firstTab);
cw.gToolbar.hide();
ok(NewTabUtils.allPages.enabled, true, "page is enabled");
NewTabUtils.allPages.enabled = false;
ok(cw.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
}

View File

@ -10,15 +10,19 @@ function runTests() {
let cell = cells[0].node;
let site = cells[0].site.node;
let link = site.querySelector(".newtab-link");
sendDragEvent(site, "dragstart");
sendDragEvent(link, "dragstart");
checkGridLocked(true, "grid is now locked");
sendDragEvent(site, "dragend");
sendDragEvent(link, "dragend");
checkGridLocked(false, "grid isn't locked anymore");
sendDragEvent(cell, "dragstart");
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
sendDragEvent(site, "dragstart");
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
}
function checkGridLocked(aLocked, aMessage) {

View File

@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function runTests() {
setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
yield addNewTabPageTab();
checkGrid("0,1,2,3,4,5,6,7,8");
let cell = cells[0].node;
sendDropEvent(cell, "about:blank#99\nblank");
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
"first cell is pinned and contains the dropped site");
yield whenPagesUpdated();
checkGrid("99p,0,1,2,3,4,5,6,7");
sendDropEvent(cell, "");
is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
"first cell is still pinned with the site we dropped before");
}
function sendDropEvent(aNode, aData) {
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
let dataTransfer = {
mozUserCancelled: false,
setData: function () null,
setDragImage: function () null,
getData: function () aData,
types: {
contains: function (aType) aType == "text/x-moz-url"
},
mozGetDataAt: function (aType, aIndex) {
if (aIndex || aType != "text/x-moz-url")
return null;
return aData;
},
};
let event = cw.document.createEvent("DragEvents");
event.initDragEvent("drop", true, true, cw, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
}

View File

@ -2,13 +2,16 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
function runTests() {
// TODO Bug 735166 - Intermittent timeout in browser_newtab_bug734043.js
return;
setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");
yield addNewTabPageTab();
let receivedError = false;
let block = cw.document.querySelector(".strip-button-block");
let block = cw.document.querySelector(".newtab-control-block");
function onError() {
receivedError = true;

View File

@ -15,7 +15,7 @@ function runTests() {
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
cw.gToolbar.hide();
NewTabUtils.allPages.enabled = false;
ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
let oldGridNode = cw.gGrid.node;
@ -28,7 +28,7 @@ function runTests() {
// check that no sites have been rendered
is(0, cw.document.querySelectorAll(".site").length, "no sites have been rendered");
cw.gToolbar.show();
NewTabUtils.allPages.enabled = true;
ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
ok(!oldGridNode.hasAttribute("page-disabled"), "old page is not disabled");
}

View File

@ -5,6 +5,9 @@
* These tests make sure that resetting the 'New Tage Page' works as expected.
*/
function runTests() {
// Disabled until bug 716543 is fixed.
return;
// create a new tab page and check its modified state after blocking a site
setLinks("0,1,2,3,4,5,6,7,8");
setPinnedLinks("");

View File

@ -8,6 +8,9 @@
* state.
*/
function runTests() {
// Disabled until bug 716543 is fixed.
return;
setLinks("0,1,2,3,4,5,6,7,8,9");
setPinnedLinks(",1");

View File

@ -188,7 +188,7 @@ function checkGrid(aSitesPattern, aSites) {
let shouldBePinned = /p$/.test(id);
let cellContainsPinned = site.isPinned();
let cssClassPinned = site.node && site.node.hasAttribute("pinned");
let cssClassPinned = site.node && site.node.querySelector(".newtab-control-pin").hasAttribute("pinned");
// Check if the site should be and is pinned.
if (shouldBePinned) {
@ -270,10 +270,15 @@ function simulateDrop(aDropTarget, aDragSource) {
* Resumes testing when all pages have been updated.
*/
function whenPagesUpdated() {
NewTabUtils.allPages.register({
let page = {
update: function () {
NewTabUtils.allPages.unregister(this);
executeSoon(TestRunner.next);
}
};
NewTabUtils.allPages.register(page);
registerCleanupFunction(function () {
NewTabUtils.allPages.unregister(page);
});
}

View File

@ -44,7 +44,23 @@ Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
return Services.prefs.getCharPref("browser.newtab.url") || "about:blank";
const PREF = "browser.newtab.url";
function getNewTabPageURL() {
return Services.prefs.getCharPref(PREF) || "about:blank";
}
function update() {
BROWSER_NEW_TAB_URL = getNewTabPageURL();
}
Services.prefs.addObserver(PREF, update, false);
addEventListener("unload", function onUnload() {
removeEventListener("unload", onUnload);
Services.prefs.removeObserver(PREF, update);
});
return getNewTabPageURL();
});
var TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";

View File

@ -18,7 +18,7 @@ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
* Hint: This is the default value because the 'New Tab Page' is the only
* client for now.
*/
const THUMBNAIL_WIDTH = 201;
const THUMBNAIL_WIDTH = 400;
/**
* The default height for page thumbnails.
@ -26,7 +26,7 @@ const THUMBNAIL_WIDTH = 201;
* Hint: This is the default value because the 'New Tab Page' is the only
* client for now.
*/
const THUMBNAIL_HEIGHT = 127;
const THUMBNAIL_HEIGHT = 225;
/**
* The default background color for page thumbnails.

View File

@ -1,6 +1,2 @@
<!-- These strings are used in the about:newtab page -->
<!ENTITY newtab.pageTitle "New Tab">
<!ENTITY newtab.show "Show the New Tab Page">
<!ENTITY newtab.hide "Hide the New Tab Page">
<!ENTITY newtab.reset "Reset the New Tab Page">

View File

@ -1,3 +1,5 @@
newtab.pin=Pin this site at its current position
newtab.unpin=Unpin this site
newtab.block=Remove this site
newtab.show=Show the new tab page
newtab.hide=Hide the new tab page

View File

@ -44,8 +44,8 @@ browser.jar:
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/strip.png (newtab/strip.png)
skin/classic/browser/newtab/toolbar.png (newtab/toolbar.png)
skin/classic/browser/newtab/controls.png (newtab/controls.png)
skin/classic/browser/newtab/noise.png (newtab/noise.png)
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)
skin/classic/browser/places/calendar.png (places/calendar.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,148 +1,131 @@
#scrollbox {
padding-bottom: 18px;
background-color: #fff;
:root {
-moz-appearance: none;
background-color: transparent;
}
#body {
padding-top: 106px;
font-family: sans-serif;
/* SCROLLBOX */
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}
.button {
/* TOGGLE */
#newtab-toggle {
width: 16px;
height: 16px;
padding: 0;
border: 0 none;
border: none;
background: -216px 0 transparent url(chrome://browser/skin/newtab/controls.png);
}
/* TOOLBAR */
#toolbar {
top: 8px;
right: 8px;
width: 13px;
height: 30px;
padding: 0;
margin: 0;
#newtab-toggle[page-disabled] {
background-position: -232px 0;
}
.toolbar-button {
background: transparent url(chrome://browser/skin/newtab/toolbar.png);
/* ROWS */
.newtab-row {
margin-bottom: 20px;
}
#toolbar-button-show {
width: 11px;
height: 11px;
background-position: -10px 0;
}
#toolbar-button-show:hover {
background-position: -10px -12px;
}
#toolbar-button-show:active {
background-position: -10px -24px;
}
#toolbar-button-hide {
width: 10px;
height: 10px;
}
#toolbar-button-hide:hover {
background-position: 0 -12px;
}
#toolbar-button-hide:active {
background-position: 0 -24px;
}
#toolbar-button-reset {
top: 17px;
width: 11px;
height: 12px;
}
#toolbar-button-reset {
background-position: -21px 0;
}
#toolbar-button-reset:hover {
background-position: -21px -12px;
}
#toolbar-button-reset:active {
background-position: -21px -24px;
}
/* GRID */
#grid {
padding: 1px;
margin: 0 auto;
.newtab-row:last-child {
margin-bottom: 0;
}
/* CELLS */
.cell {
outline: 1px dashed #ccc;
outline-offset: -1px;
.newtab-cell {
-moz-margin-end: 20px;
background-color: rgba(255,255,255,.2);
border: 1px solid;
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
border-radius: 1px;
-moz-transition: border-color 100ms ease-out;
}
.newtab-cell:empty {
border: 1px dashed;
border-color: rgba(8,22,37,.15) rgba(8,22,37,.17) rgba(8,22,37,.19);
}
.newtab-cell:last-child {
-moz-margin-end: 0;
}
.newtab-cell:hover:not(:empty) {
border-color: rgba(8,22,37,.25) rgba(8,22,37,.27) rgba(8,22,37,.3);
}
/* SITES */
.site {
background-color: #ececec;
-moz-transition: 200ms ease-out;
-moz-transition-property: top, left, box-shadow, opacity;
}
.site[dragged] {
-moz-transition-property: box-shadow;
}
.site[ontop] {
box-shadow: 0 1px 4px #000;
outline: none;
}
/* SITE TITLE */
.site-title {
height: 2.4em;
width: 189px;
padding: 0 6px;
background-color: rgba(0,0,0,0.5);
border: solid transparent;
border-width: 6px 0;
color: #fff;
.newtab-site {
text-decoration: none;
line-height: 1.2em;
font-weight: 700;
-moz-transition-property: top, left, opacity, box-shadow, background-color;
}
/* SITE STRIP */
.site-strip {
padding: 4px 3px;
background-color: rgba(0,0,0,0.5);
.newtab-site:hover,
.newtab-site[dragged] {
box-shadow: 0 0 10px rgba(8,22,37,.3);
}
.strip-button {
width: 17px;
height: 17px;
background: transparent url(chrome://browser/skin/newtab/strip.png);
.newtab-site[dragged] {
-moz-transition-property: box-shadow, background-color;
background-color: rgb(242,242,242);
}
.strip-button-pin:hover {
background-position: 0 -17px;
/* THUMBNAILS */
.newtab-thumbnail {
background-origin: padding-box;
background-clip: padding-box;
background-repeat: no-repeat;
background-size: cover;
}
.strip-button-pin:active,
.site[pinned] .strip-button-pin {
background-position: 0 -34px;
/* TITLES */
.newtab-title {
padding: 0 8px;
background-color: rgba(248,249,251,.95);
color: #1f364c;
font-size: 12px;
line-height: 24px;
}
.strip-button-block {
background-position: -17px 0;
/* CONTROLS */
.newtab-control {
width: 24px;
height: 24px;
padding: 1px 2px 3px;
border: none;
background: transparent url(chrome://browser/skin/newtab/controls.png);
}
.strip-button-block:hover {
background-position: -17px -17px;
.newtab-control-pin:hover {
background-position: -24px 0;
}
.strip-button-block:active {
background-position: -17px -34px;
.newtab-control-pin:active {
background-position: -48px 0;
}
.newtab-control-pin[pinned] {
background-position: -72px 0;
}
.newtab-control-pin[pinned]:hover {
background-position: -96px 0;
}
.newtab-control-pin[pinned]:active {
background-position: -120px 0;
}
.newtab-control-block {
background-position: -144px 0;
}
.newtab-control-block:hover {
background-position: -168px 0;
}
.newtab-control-block:active {
background-position: -192px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -54,8 +54,8 @@ browser.jar:
skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/strip.png (newtab/strip.png)
skin/classic/browser/newtab/toolbar.png (newtab/toolbar.png)
skin/classic/browser/newtab/controls.png (newtab/controls.png)
skin/classic/browser/newtab/noise.png (newtab/noise.png)
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,147 +1,131 @@
#scrollbox {
padding-bottom: 18px;
background-color: #fff;
:root {
-moz-appearance: none;
background-color: transparent;
}
#body {
padding-top: 106px;
font-family: sans-serif;
/* SCROLLBOX */
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}
.button {
/* TOGGLE */
#newtab-toggle {
width: 16px;
height: 16px;
padding: 0;
border: 0 none;
border: none;
background: -216px 0 transparent url(chrome://browser/skin/newtab/controls.png);
}
/* TOOLBAR */
#toolbar {
top: 8px;
right: 8px;
width: 13px;
height: 30px;
padding: 0;
margin: 0;
#newtab-toggle[page-disabled] {
background-position: -232px 0;
}
.toolbar-button {
background: transparent url(chrome://browser/skin/newtab/toolbar.png);
/* ROWS */
.newtab-row {
margin-bottom: 20px;
}
#toolbar-button-show {
width: 11px;
height: 11px;
background-position: -10px 0;
}
#toolbar-button-show:hover {
background-position: -10px -12px;
}
#toolbar-button-show:active {
background-position: -10px -24px;
}
#toolbar-button-hide {
width: 10px;
height: 10px;
}
#toolbar-button-hide:hover {
background-position: 0 -12px;
}
#toolbar-button-hide:active {
background-position: 0 -24px;
}
#toolbar-button-reset {
top: 17px;
width: 11px;
height: 12px;
}
#toolbar-button-reset {
background-position: -21px 0;
}
#toolbar-button-reset:hover {
background-position: -21px -12px;
}
#toolbar-button-reset:active {
background-position: -21px -24px;
}
/* GRID */
#grid {
padding: 1px;
margin: 0 auto;
.newtab-row:last-child {
margin-bottom: 0;
}
/* CELLS */
.cell {
outline: 1px dashed #ccc;
outline-offset: -1px;
.newtab-cell {
-moz-margin-end: 20px;
background-color: rgba(255,255,255,.2);
border: 1px solid;
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
border-radius: 1px;
-moz-transition: border-color 100ms ease-out;
}
.newtab-cell:empty {
border: 1px dashed;
border-color: rgba(8,22,37,.15) rgba(8,22,37,.17) rgba(8,22,37,.19);
}
.newtab-cell:last-child {
-moz-margin-end: 0;
}
.newtab-cell:hover:not(:empty) {
border-color: rgba(8,22,37,.25) rgba(8,22,37,.27) rgba(8,22,37,.3);
}
/* SITES */
.site {
background-color: #ececec;
-moz-transition: 200ms ease-out;
-moz-transition-property: top, left, box-shadow, opacity;
}
.site[dragged] {
-moz-transition-property: box-shadow;
}
.site[ontop] {
box-shadow: 0 1px 4px #000;
}
/* SITE TITLE */
.site-title {
height: 2.4em;
width: 189px;
padding: 0 6px;
background-color: rgba(0,0,0,0.5);
border: solid transparent;
border-width: 6px 0;
color: #fff;
.newtab-site {
text-decoration: none;
line-height: 1.2em;
font-weight: 700;
-moz-transition-property: top, left, opacity, box-shadow, background-color;
}
/* SITE STRIP */
.site-strip {
padding: 4px 3px;
background-color: rgba(0,0,0,0.5);
.newtab-site:hover,
.newtab-site[dragged] {
box-shadow: 0 0 10px rgba(8,22,37,.3);
}
.strip-button {
width: 17px;
height: 17px;
background: transparent url(chrome://browser/skin/newtab/strip.png);
.newtab-site[dragged] {
-moz-transition-property: box-shadow, background-color;
background-color: rgb(242,242,242);
}
.strip-button-pin:hover {
background-position: 0 -17px;
/* THUMBNAILS */
.newtab-thumbnail {
background-origin: padding-box;
background-clip: padding-box;
background-repeat: no-repeat;
background-size: cover;
}
.strip-button-pin:active,
.site[pinned] .strip-button-pin {
background-position: 0 -34px;
/* TITLES */
.newtab-title {
padding: 0 8px;
background-color: rgba(248,249,251,.95);
color: #1f364c;
font-size: 12px;
line-height: 24px;
}
.strip-button-block {
background-position: -17px 0;
/* CONTROLS */
.newtab-control {
width: 24px;
height: 24px;
padding: 1px 2px 3px;
border: none;
background: transparent url(chrome://browser/skin/newtab/controls.png);
}
.strip-button-block:hover {
background-position: -17px -17px;
.newtab-control-pin:hover {
background-position: -24px 0;
}
.strip-button-block:active {
background-position: -17px -34px;
.newtab-control-pin:active {
background-position: -48px 0;
}
.newtab-control-pin[pinned] {
background-position: -72px 0;
}
.newtab-control-pin[pinned]:hover {
background-position: -96px 0;
}
.newtab-control-pin[pinned]:active {
background-position: -120px 0;
}
.newtab-control-block {
background-position: -144px 0;
}
.newtab-control-block:hover {
background-position: -168px 0;
}
.newtab-control-block:active {
background-position: -192px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -59,8 +59,8 @@ browser.jar:
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/strip.png (newtab/strip.png)
skin/classic/browser/newtab/toolbar.png (newtab/toolbar.png)
skin/classic/browser/newtab/controls.png (newtab/controls.png)
skin/classic/browser/newtab/noise.png (newtab/noise.png)
skin/classic/browser/places/places.css (places/places.css)
* skin/classic/browser/places/organizer.css (places/organizer.css)
skin/classic/browser/places/bookmark.png (places/bookmark.png)
@ -231,8 +231,8 @@ browser.jar:
skin/classic/aero/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/aero/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
skin/classic/aero/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/aero/browser/newtab/strip.png (newtab/strip.png)
skin/classic/aero/browser/newtab/toolbar.png (newtab/toolbar.png)
skin/classic/aero/browser/newtab/controls.png (newtab/controls.png)
skin/classic/aero/browser/newtab/noise.png (newtab/noise.png)
* skin/classic/aero/browser/places/places.css (places/places-aero.css)
* skin/classic/aero/browser/places/organizer.css (places/organizer-aero.css)
skin/classic/aero/browser/places/bookmark.png (places/bookmark.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -1,148 +1,131 @@
#scrollbox {
padding-bottom: 18px;
background-color: #fff;
:root {
-moz-appearance: none;
background-color: transparent;
}
#body {
padding-top: 106px;
font-family: sans-serif;
/* SCROLLBOX */
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}
.button {
/* TOGGLE */
#newtab-toggle {
width: 16px;
height: 16px;
padding: 0;
border: 0 none;
border: none;
background: -216px 0 transparent url(chrome://browser/skin/newtab/controls.png);
}
/* TOOLBAR */
#toolbar {
top: 8px;
right: 8px;
width: 13px;
height: 30px;
padding: 0;
margin: 0;
#newtab-toggle[page-disabled] {
background-position: -232px 0;
}
.toolbar-button {
background: transparent url(chrome://browser/skin/newtab/toolbar.png);
/* ROWS */
.newtab-row {
margin-bottom: 20px;
}
#toolbar-button-show {
width: 11px;
height: 11px;
background-position: -10px 0;
}
#toolbar-button-show:hover {
background-position: -10px -12px;
}
#toolbar-button-show:active {
background-position: -10px -24px;
}
#toolbar-button-hide {
width: 10px;
height: 10px;
}
#toolbar-button-hide:hover {
background-position: 0 -12px;
}
#toolbar-button-hide:active {
background-position: 0 -24px;
}
#toolbar-button-reset {
top: 17px;
width: 11px;
height: 12px;
}
#toolbar-button-reset {
background-position: -21px 0;
}
#toolbar-button-reset:hover {
background-position: -21px -12px;
}
#toolbar-button-reset:active {
background-position: -21px -24px;
}
/* GRID */
#grid {
padding: 1px;
margin: 0 auto;
.newtab-row:last-child {
margin-bottom: 0;
}
/* CELLS */
.cell {
outline: 1px dashed #ccc;
outline-offset: -1px;
.newtab-cell {
-moz-margin-end: 20px;
background-color: rgba(255,255,255,.2);
border: 1px solid;
border-color: rgba(8,22,37,.12) rgba(8,22,37,.14) rgba(8,22,37,.16);
border-radius: 1px;
-moz-transition: border-color 100ms ease-out;
}
.newtab-cell:empty {
border: 1px dashed;
border-color: rgba(8,22,37,.15) rgba(8,22,37,.17) rgba(8,22,37,.19);
}
.newtab-cell:last-child {
-moz-margin-end: 0;
}
.newtab-cell:hover:not(:empty) {
border-color: rgba(8,22,37,.25) rgba(8,22,37,.27) rgba(8,22,37,.3);
}
/* SITES */
.site {
background-color: #ececec;
-moz-transition: 200ms ease-out;
-moz-transition-property: top, left, box-shadow, opacity;
}
.site[dragged] {
-moz-transition-property: box-shadow;
}
.site[ontop] {
box-shadow: 0 1px 4px #000;
outline: none;
}
/* SITE TITLE */
.site-title {
height: 2.4em;
width: 189px;
padding: 0 6px;
background-color: rgba(0,0,0,0.5);
border: solid transparent;
border-width: 6px 0;
color: #fff;
.newtab-site {
text-decoration: none;
line-height: 1.2em;
font-weight: 700;
-moz-transition-property: top, left, opacity, box-shadow, background-color;
}
/* SITE STRIP */
.site-strip {
padding: 4px 3px;
background-color: rgba(0,0,0,0.5);
.newtab-site:hover,
.newtab-site[dragged] {
box-shadow: 0 0 10px rgba(8,22,37,.3);
}
.strip-button {
width: 17px;
height: 17px;
background: transparent url(chrome://browser/skin/newtab/strip.png);
.newtab-site[dragged] {
-moz-transition-property: box-shadow, background-color;
background-color: rgb(242,242,242);
}
.strip-button-pin:hover {
background-position: 0 -17px;
/* THUMBNAILS */
.newtab-thumbnail {
background-origin: padding-box;
background-clip: padding-box;
background-repeat: no-repeat;
background-size: cover;
}
.strip-button-pin:active,
.site[pinned] .strip-button-pin {
background-position: 0 -34px;
/* TITLES */
.newtab-title {
padding: 0 8px;
background-color: rgba(248,249,251,.95);
color: #1f364c;
font-size: 12px;
line-height: 24px;
}
.strip-button-block {
background-position: -17px 0;
/* CONTROLS */
.newtab-control {
width: 24px;
height: 24px;
padding: 1px 2px 3px;
border: none;
background: transparent url(chrome://browser/skin/newtab/controls.png);
}
.strip-button-block:hover {
background-position: -17px -17px;
.newtab-control-pin:hover {
background-position: -24px 0;
}
.strip-button-block:active {
background-position: -17px -34px;
.newtab-control-pin:active {
background-position: -48px 0;
}
.newtab-control-pin[pinned] {
background-position: -72px 0;
}
.newtab-control-pin[pinned]:hover {
background-position: -96px 0;
}
.newtab-control-pin[pinned]:active {
background-position: -120px 0;
}
.newtab-control-block {
background-position: -144px 0;
}
.newtab-control-block:hover {
background-position: -168px 0;
}
.newtab-control-block:active {
background-position: -192px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1261,8 +1261,11 @@
let videoHeight = this.video.clientHeight;
let videoWidth = this.video.clientWidth;
if (this._overlayPlayButtonHeight > videoHeight || this._overlayPlayButtonWidth > videoWidth)
if ((this._overlayPlayButtonHeight + this._controlBarHeight) > videoHeight ||
this._overlayPlayButtonWidth > videoWidth)
this.clickToPlay.hidden = true;
else if (this.clickToPlay.hidden)
this.clickToPlay.hidden = false;
// The scrubber has |flex=1|, therefore |minScrubberWidth|
// was generated by empirical testing.

View File

@ -205,17 +205,20 @@ ThreadActor.prototype = {
onClientEvaluate: function TA_onClientEvaluate(aRequest) {
if (this.state !== "paused") {
return { type: "wrongState",
return { error: "wrongState",
message: "Debuggee must be paused to evaluate code." };
};
let frame = this._requestFrame(aRequest.frame);
if (!frame) {
// XXXspec
return { type: "unknownFrame",
return { error: "unknownFrame",
message: "Evaluation frame not found" };
}
if (!frame.environment) {
return { error: "notDebuggee",
message: "cannot access the environment of this frame." };
};
// We'll clobber the youngest frame if the eval causes a pause, so
// save our frame now to be restored after eval returns.
@ -233,18 +236,10 @@ ThreadActor.prototype = {
// Put ourselves back in the pause state.
let packet = this._paused(youngest);
packet.why = { type: "clientEvaluated" };
if ("return" in completion) {
packet.why.value = this.createValueGrip(completion["return"]);
} else if ("throw" in completion) {
packet.why.exception = this.createValueGrip(completion["throw"]);
} else {
// XXXspec
packet.why.terminated = true;
}
packet.why = { type: "clientEvaluated",
frameFinished: this.createProtocolCompletionValue(completion) };
// Return back to our previous pause's event loop.
return packet;
},
@ -269,9 +264,9 @@ ThreadActor.prototype = {
// frames if count is not defined.
let frames = [];
for (; frame && (!count || i < (start + count)); i++) {
let grip = this._createFrameActor(frame).grip();
grip.depth = i;
frames.push(grip);
let form = this._createFrameActor(frame).form();
form.depth = i;
frames.push(form);
frame = frame.older;
}
@ -279,6 +274,11 @@ ThreadActor.prototype = {
},
onReleaseMany: function TA_onReleaseMany(aRequest) {
if (!aRequest.actors) {
return { error: "missingParameter",
message: "no actors were specified" };
}
for each (let actorID in aRequest.actors) {
let actor = this.threadLifetimePool.get(actorID);
this.threadLifetimePool.objectActors.delete(actor.obj);
@ -449,8 +449,6 @@ ThreadActor.prototype = {
* Return the Debug.Frame for a frame mentioned by the protocol.
*/
_requestFrame: function TA_requestFrame(aFrameID) {
// XXXspec: doesn't actually specify how frames are named. By
// depth? By actor? Both?
if (!aFrameID) {
return this._youngestFrame;
}
@ -463,10 +461,9 @@ ThreadActor.prototype = {
},
_paused: function TA_paused(aFrame) {
// XXX: We don't handle nested pauses correctly. Don't try - if we're
// We don't handle nested pauses correctly. Don't try - if we're
// paused, just continue running whatever code triggered the pause.
// We don't want to actually have nested pauses (although we will
// We don't want to actually have nested pauses (although we
// have nested event loops). If code runs in the debuggee during
// a pause, it should cause the actor to resume (dropping
// pause-lifetime actors etc) and then repause when complete.
@ -504,7 +501,7 @@ ThreadActor.prototype = {
type: "paused",
actor: this._pauseActor.actorID };
if (aFrame) {
packet.frame = this._createFrameActor(aFrame).grip();
packet.frame = this._createFrameActor(aFrame).form();
}
if (poppedFrames) {
@ -598,13 +595,11 @@ ThreadActor.prototype = {
* The object whose lexical environment we want to extract.
* @param object aPool
* The pool where the newly-created actor will be placed.
* @return The EnvironmentActor for aObject.
* @return The EnvironmentActor for aObject or undefined for host functions or
* functions scoped to a non-debuggee global.
*/
createEnvironmentActor: function TA_createEnvironmentActor(aObject, aPool) {
let environment = aObject.environment;
// XXX: need to spec this: when the object is a function proxy or not a
// function implemented in JavaScript, we don't return a scope property at
// all.
if (!environment) {
return undefined;
}
@ -647,6 +642,25 @@ ThreadActor.prototype = {
return null;
},
/**
* Return a protocol completion value representing the given
* Debugger-provided completion value.
*/
createProtocolCompletionValue:
function TA_createProtocolCompletionValue(aCompletion) {
let protoValue = {};
if ("return" in aCompletion) {
protoValue.return = this.createValueGrip(aCompletion.return);
} else if ("yield" in aCompletion) {
protoValue.return = this.createValueGrip(aCompletion.yield);
} else if ("throw" in aCompletion) {
protoValue.throw = this.createValueGrip(aCompletion.throw);
} else {
protoValue.terminated = true;
}
return protoValue;
},
/**
* Create a grip for the given debuggee object.
*
@ -746,9 +760,7 @@ ThreadActor.prototype = {
*/
onNewScript: function TA_onNewScript(aScript, aFunction) {
// Use a sparse array for storing the scripts for each URL in order to
// optimize retrieval. XXX: in case this is not fast enough for very large
// files with too many scripts, we could sort the hash of script locations
// or use a trie.
// optimize retrieval.
if (!this._scripts[aScript.url]) {
this._scripts[aScript.url] = [];
}
@ -819,7 +831,7 @@ ObjectActor.prototype = {
*/
grip: function OA_grip() {
return { "type": "object",
"class": this.obj["class"],
"class": this.obj.class,
"actor": this.actorID };
},
@ -902,9 +914,8 @@ ObjectActor.prototype = {
if (this.threadActor.state !== "paused") {
return this.WRONG_STATE_RESPONSE;
}
// XXX: spec this.
if (!aRequest.name) {
return { error: "noPropertyName",
return { error: "missingParameter",
message: "no property name was specified" };
}
@ -945,9 +956,8 @@ ObjectActor.prototype = {
return this.WRONG_STATE_RESPONSE;
}
if (this.obj["class"] !== "Function") {
// XXXspec: Error type for this.
return { error: "unrecognizedPacketType",
if (this.obj.class !== "Function") {
return { error: "objectNotFunction",
message: "decompile request is only valid for object grips " +
"with a 'Function' class." };
}
@ -967,18 +977,21 @@ ObjectActor.prototype = {
return this.WRONG_STATE_RESPONSE;
}
if (this.obj["class"] !== "Function") {
// XXXspec: Error type for this.
return { error: "unrecognizedPacketType",
if (this.obj.class !== "Function") {
return { error: "objectNotFunction",
message: "scope request is only valid for object grips with a" +
" 'Function' class." };
}
let packet = { name: this.obj.name || null };
let envActor = this.threadActor.createEnvironmentActor(this.obj, this.registeredPool);
packet.scope = envActor ? envActor.grip() : envActor;
let envActor = this.threadActor.createEnvironmentActor(this.obj,
this.registeredPool);
if (!envActor) {
return { error: "notDebuggee",
message: "cannot access the environment of this function." };
}
return packet;
return { name: this.obj.name || null,
scope: envActor.form() };
},
/**
@ -992,10 +1005,10 @@ ObjectActor.prototype = {
return this.WRONG_STATE_RESPONSE;
}
if (this.obj["class"] !== "Function") {
// XXXspec: Error type for this.
return { error: "unrecognizedPacketType",
message: "nameAndParameters request is only valid for object grips with a 'Function' class." };
if (this.obj.class !== "Function") {
return { error: "objectNotFunction",
message: "nameAndParameters request is only valid for object " +
"grips with a 'Function' class." };
}
return { name: this.obj.name || null,
@ -1028,9 +1041,8 @@ ObjectActor.prototype = {
return this.WRONG_STATE_RESPONSE;
}
if (this.registeredPool !== this.threadActor.threadLifetimePool) {
// XXXspec: error type?
return { error: "unrecognizedPacketType",
message: "release is only recognized on thread-lifetime actors." };
return { error: "notReleasable",
message: "only thread-lifetime actors can be released." };
}
this.release();
@ -1090,19 +1102,19 @@ FrameActor.prototype = {
},
/**
* Returns a grip for this actor for returning in a protocol message.
* Returns a frame form for use in a protocol message.
*/
grip: function FA_grip() {
let grip = { actor: this.actorID,
form: function FA_form() {
let form = { actor: this.actorID,
type: this.frame.type };
if (this.frame.type === "call") {
grip.callee = this.threadActor.createValueGrip(this.frame.callee);
form.callee = this.threadActor.createValueGrip(this.frame.callee);
if (this.frame.callee.name) {
grip.calleeName = this.frame.callee.name;
form.calleeName = this.frame.callee.name;
} else {
let desc = this.frame.callee.getOwnPropertyDescriptor("displayName");
if (desc && desc.value && typeof desc.value == "string") {
grip.calleeName = desc.value;
form.calleeName = desc.value;
}
}
}
@ -1110,28 +1122,28 @@ FrameActor.prototype = {
let envActor = this.threadActor
.createEnvironmentActor(this.frame,
this.frameLifetimePool);
grip.environment = envActor ? envActor.grip() : envActor;
grip["this"] = this.threadActor.createValueGrip(this.frame["this"]);
grip.arguments = this._args();
form.environment = envActor ? envActor.form() : envActor;
form.this = this.threadActor.createValueGrip(this.frame.this);
form.arguments = this._args();
if (this.frame.script) {
grip.where = { url: this.frame.script.url,
form.where = { url: this.frame.script.url,
line: this.frame.script.getOffsetLine(this.frame.offset) };
}
if (!this.frame.older) {
grip.oldest = true;
form.oldest = true;
}
return grip;
return form;
},
_args: function FA__args() {
if (!this.frame["arguments"]) {
if (!this.frame.arguments) {
return [];
}
return [this.threadActor.createValueGrip(arg)
for each (arg in this.frame["arguments"])];
for each (arg in this.frame.arguments)];
},
/**
@ -1232,9 +1244,9 @@ EnvironmentActor.prototype = {
actorPrefix: "environment",
/**
* Returns a grip for this actor for returning in a protocol message.
* Returns an environment form for use in a protocol message.
*/
grip: function EA_grip() {
form: function EA_form() {
// Debugger.Frame might be dead by the time we get here, which will cause
// accessing its properties to throw.
if (!this.obj.live) {
@ -1247,25 +1259,29 @@ EnvironmentActor.prototype = {
.createEnvironmentActor(this.obj.environment.parent,
this.registeredPool);
}
let grip = { actor: this.actorID,
parent: parent ? parent.grip() : parent };
let form = { actor: this.actorID,
parent: parent ? parent.form() : parent };
if (this.obj.environment.type == "object") {
grip.type = "object"; // XXX: how can we tell if it's "with"?
grip.object = this.threadActor.createValueGrip(this.obj.environment.object);
} else {
if (this.obj["class"] == "Function") {
grip.type = "function";
grip["function"] = this.threadActor.createValueGrip(this.obj);
grip.functionName = this.obj.name;
if (this.obj.environment.parent) {
form.type = "with";
} else {
grip.type = "block";
form.type = "object";
}
form.object = this.threadActor.createValueGrip(this.obj.environment.object);
} else {
if (this.obj.class == "Function") {
form.type = "function";
form.function = this.threadActor.createValueGrip(this.obj);
form.functionName = this.obj.name;
} else {
form.type = "block";
}
grip.bindings = this._bindings();
form.bindings = this._bindings();
}
return grip;
return form;
},
/**
@ -1273,21 +1289,51 @@ EnvironmentActor.prototype = {
* specification.
*/
_bindings: function EA_bindings() {
let bindings = { mutable: {}, immutable: {} };
let bindings = { arguments: [], variables: {} };
// TODO: this will be redundant after bug 692984 is fixed.
if (typeof this.obj.environment.getVariableDescriptor != "function") {
return bindings;
}
for (let name in this.obj.environment.names()) {
for (let name in this.obj.parameterNames) {
let arg = {};
let desc = this.obj.environment.getVariableDescriptor(name);
// XXX: the spec doesn't say what to do with accessor properties.
if (desc.writable) {
grip.bindings.mutable[name] = desc.value;
let descForm = {
enumerable: true,
configurable: desc.configurable
};
if ("value" in desc) {
descForm.value = this.threadActor.createValueGrip(desc.value);
descForm.writable = desc.writable;
} else {
grip.bindings.immutable[name] = desc.value;
descForm.get = this.threadActor.createValueGrip(desc.get);
descForm.set = this.threadActor.createValueGrip(desc.set);
}
arg[name] = descForm;
bindings.arguments.push(arg);
}
for (let name in this.obj.environment.names()) {
if (bindings.arguments.some(function exists(element) {
return !!element[name];
})) {
continue;
}
let desc = this.obj.environment.getVariableDescriptor(name);
let descForm = {
enumerable: true,
configurable: desc.configurable
};
if ("value" in desc) {
descForm.value = this.threadActor.createValueGrip(desc.value);
descForm.writable = desc.writable;
} else {
descForm.get = this.threadActor.createValueGrip(desc.get);
descForm.set = this.threadActor.createValueGrip(desc.set);
}
bindings.variables[name] = descForm;
}
return bindings;
@ -1313,9 +1359,9 @@ EnvironmentActor.prototype = {
this.obj.environment.setVariable(aRequest.name, aRequest.value);
} catch (e) {
if (e instanceof Debugger.DebuggeeWouldRun) {
// XXX: we need to spec this. Is this a real problem?
return { error: "debuggeeWouldRun",
message: "Assigning this value would cause the debuggee to run." };
return { error: "threadWouldRun",
cause: e.cause ? e.cause : "setter",
message: "Assigning a value would cause the debuggee to run" };
}
// This should never happen, so let it complain loudly if it does.
throw e;

View File

@ -26,7 +26,7 @@ function run_test()
function test_simple_eval()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let arg1Actor = aPacket.frame["arguments"][0].actor;
let arg1Actor = aPacket.frame.arguments[0].actor;
gThreadClient.eval(null, "({ obj: true })", function(aResponse) {
do_check_eq(aResponse.type, "resumed");
// Expect a pause notification immediately.
@ -34,8 +34,8 @@ function test_simple_eval()
// Check the return value...
do_check_eq(aPacket.type, "paused");
do_check_eq(aPacket.why.type, "clientEvaluated");
do_check_eq(aPacket.why.value.type, "object");
do_check_eq(aPacket.why.value["class"], "Object");
do_check_eq(aPacket.why.frameFinished.return.type, "object");
do_check_eq(aPacket.why.frameFinished.return.class, "Object");
// Make sure the previous pause lifetime was correctly dropped.
gClient.request({ to: arg1Actor, type: "bogusRequest" }, function(aResponse) {

View File

@ -33,7 +33,7 @@ function test_throw_eval()
// Check the return value...
do_check_eq(aPacket.type, "paused");
do_check_eq(aPacket.why.type, "clientEvaluated");
do_check_eq(aPacket.why.exception, "failure");
do_check_eq(aPacket.why.frameFinished.throw, "failure");
gThreadClient.resume(function() {
finishClient(gClient);
});

View File

@ -33,8 +33,8 @@ function test_syntax_error_eval()
// Check the return value...
do_check_eq(aPacket.type, "paused");
do_check_eq(aPacket.why.type, "clientEvaluated");
do_check_eq(aPacket.why.exception.type, "object");
do_check_eq(aPacket.why.exception["class"], "Error");
do_check_eq(aPacket.why.frameFinished.throw.type, "object");
do_check_eq(aPacket.why.frameFinished.throw.class, "Error");
gThreadClient.resume(function() {
finishClient(gClient);

View File

@ -38,14 +38,14 @@ function test_syntax_error_eval()
// 'arg' should have been evaluated in frame0
do_check_eq(aPacket.type, "paused");
do_check_eq(aPacket.why.type, "clientEvaluated");
do_check_eq(aPacket.why.value, "arg0");
do_check_eq(aPacket.why.frameFinished.return, "arg0");
// Now eval against the second frame.
gThreadClient.eval(frame1.actor, "arg", function(aResponse) {
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
// 'arg' should have been evaluated in frame1
do_check_eq(aPacket.type, "paused");
do_check_eq(aPacket.why.value, "arg1");
do_check_eq(aPacket.why.frameFinished.return, "arg1");
gThreadClient.resume(function() {
finishClient(gClient);

View File

@ -34,7 +34,7 @@ function test_pause_frame()
do_check_eq(args[3].type, "null");
do_check_eq(args[4].type, "undefined");
do_check_eq(args[5].type, "object");
do_check_eq(args[5]["class"], "Object");
do_check_eq(args[5].class, "Object");
do_check_true(!!args[5].actor);
gThreadClient.resume(function() {

View File

@ -26,9 +26,9 @@ function run_test()
function test_named_function()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Function");
do_check_eq(args[0].class, "Function");
// No name for an anonymous function.
let objClient = gThreadClient.pauseGrip(args[0]);
@ -49,9 +49,9 @@ function test_named_function()
function test_anon_function() {
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Function");
do_check_eq(args[0].class, "Function");
// No name for an anonymous function.
let objClient = gThreadClient.pauseGrip(args[0]);

View File

@ -6,7 +6,7 @@ function run_test()
var dbg = new Debugger();
dbg.addDebuggee(g);
dbg.onDebuggerStatement = function(aFrame) {
let args = aFrame["arguments"];
let args = aFrame.arguments;
try {
args[0];
do_check_true(true);

View File

@ -26,9 +26,9 @@ function run_test()
function test_object_grip()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
let objClient = gThreadClient.pauseGrip(args[0]);
objClient.getOwnPropertyNames(function(aResponse) {

View File

@ -26,9 +26,9 @@ function run_test()
function test_object_grip()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
let objClient = gThreadClient.pauseGrip(args[0]);
objClient.getPrototype(function(aResponse) {

View File

@ -26,9 +26,9 @@ function run_test()
function test_object_grip()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
let objClient = gThreadClient.pauseGrip(args[0]);
objClient.getProperty("x", function(aResponse) {

View File

@ -26,9 +26,9 @@ function run_test()
function test_object_grip()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
let objClient = gThreadClient.pauseGrip(args[0]);
objClient.getPrototypeAndProperties(function(aResponse) {

View File

@ -26,7 +26,7 @@ function run_test()
function test_pause_frame()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let pauseActor = aPacket["actor"];
let pauseActor = aPacket.actor;
// Make a bogus request to the pause-liftime actor. Should get
// unrecognized-packet-type (and not no-such-actor).

View File

@ -26,9 +26,9 @@ function run_test()
function test_pause_frame()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
let objActor = args[0].actor;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
do_check_true(!!objActor);
// Make a bogus request to the grip actor. Should get

View File

@ -26,9 +26,9 @@ function run_test()
function test_pause_frame()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
let objActor = args[0].actor;
do_check_eq(args[0]["class"], "Object");
do_check_eq(args[0].class, "Object");
do_check_true(!!objActor);
let objClient = gThreadClient.pauseGrip(args[0]);

View File

@ -27,7 +27,7 @@ function run_test()
function test_pause_frame()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let args = aPacket.frame["arguments"];
let args = aPacket.frame.arguments;
let objActor1 = args[0].actor;
gThreadClient.getFrames(0, 1, function(aResponse) {

View File

@ -26,7 +26,7 @@ function run_test()
function test_thread_lifetime()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let pauseGrip = aPacket.frame["arguments"][0];
let pauseGrip = aPacket.frame.arguments[0];
gClient.request({ to: pauseGrip.actor, type: "threadGrip" }, function(aResponse) {
let threadGrip = aResponse.threadGrip;

View File

@ -26,7 +26,7 @@ function run_test()
function test_thread_lifetime()
{
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
let pauseGrip = aPacket.frame["arguments"][0];
let pauseGrip = aPacket.frame.arguments[0];
gClient.request({ to: pauseGrip.actor, type: "threadGrip" }, function(aResponse) {
let threadGrip = aResponse.threadGrip;

View File

@ -27,7 +27,7 @@ function test_thread_lifetime()
{
// Get three thread-lifetime grips.
gThreadClient.addOneTimeListener("paused", function(aEvent, aPacket) {
aPacket.frame["arguments"][0];
aPacket.frame.arguments[0];
let grips = [];
let handler = function(aResponse) {
@ -37,7 +37,7 @@ function test_thread_lifetime()
}
};
for (let i = 0; i < 3; i++) {
gClient.request({ to: aPacket.frame["arguments"][i].actor, type: "threadGrip" },
gClient.request({ to: aPacket.frame.arguments[i].actor, type: "threadGrip" },
handler);
}
});