mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-19 14:57:32 +09:00
Issue #889 - Clean up the Pale Moon tree - Part 1b: Move newtab to components
This commit is contained in:
parent
36d7d6d67a
commit
a07ec61fe6
20 changed files with 17 additions and 3 deletions
222
application/palemoon/components/newtab/dropPreview.js
Normal file
222
application/palemoon/components/newtab/dropPreview.js
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
#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 provides the ability to re-arrange the current grid to
|
||||
* indicate the transformation that results from dropping a cell at a certain
|
||||
* position.
|
||||
*/
|
||||
var gDropPreview = {
|
||||
/**
|
||||
* Rearranges the sites currently contained in the grid when a site would be
|
||||
* dropped onto the given cell.
|
||||
* @param aCell The drop target cell.
|
||||
* @return The re-arranged array of sites.
|
||||
*/
|
||||
rearrange: function DropPreview_rearrange(aCell) {
|
||||
let sites = gGrid.sites;
|
||||
|
||||
// Insert the dragged site into the current grid.
|
||||
this._insertDraggedSite(sites, aCell);
|
||||
|
||||
// After the new site has been inserted we need to correct the positions
|
||||
// of all pinned tabs that have been moved around.
|
||||
this._repositionPinnedSites(sites, aCell);
|
||||
|
||||
return sites;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts the currently dragged site into the given array of sites.
|
||||
* @param aSites The array of sites to insert into.
|
||||
* @param aCell The drop target cell.
|
||||
*/
|
||||
_insertDraggedSite: function DropPreview_insertDraggedSite(aSites, aCell) {
|
||||
let dropIndex = aCell.index;
|
||||
let draggedSite = gDrag.draggedSite;
|
||||
|
||||
// We're currently dragging a site.
|
||||
if (draggedSite) {
|
||||
let dragCell = draggedSite.cell;
|
||||
let dragIndex = dragCell.index;
|
||||
|
||||
// Move the dragged site into its new position.
|
||||
if (dragIndex != dropIndex) {
|
||||
aSites.splice(dragIndex, 1);
|
||||
aSites.splice(dropIndex, 0, draggedSite);
|
||||
}
|
||||
// We're handling an external drag item.
|
||||
} else {
|
||||
aSites.splice(dropIndex, 0, null);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Correct the position of all pinned sites that might have been moved to
|
||||
* different positions after the dragged site has been inserted.
|
||||
* @param aSites The array of sites containing the dragged site.
|
||||
* @param aCell The drop target cell.
|
||||
*/
|
||||
_repositionPinnedSites:
|
||||
function DropPreview_repositionPinnedSites(aSites, aCell) {
|
||||
|
||||
// Collect all pinned sites.
|
||||
let pinnedSites = this._filterPinnedSites(aSites, aCell);
|
||||
|
||||
// Correct pinned site positions.
|
||||
pinnedSites.forEach(function (aSite) {
|
||||
aSites[aSites.indexOf(aSite)] = aSites[aSite.cell.index];
|
||||
aSites[aSite.cell.index] = aSite;
|
||||
}, this);
|
||||
|
||||
// There might be a pinned cell that got pushed out of the grid, try to
|
||||
// sneak it in by removing a lower-priority cell.
|
||||
if (this._hasOverflowedPinnedSite(aSites, aCell))
|
||||
this._repositionOverflowedPinnedSite(aSites, aCell);
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter pinned sites out of the grid that are still on their old positions
|
||||
* and have not moved.
|
||||
* @param aSites The array of sites to filter.
|
||||
* @param aCell The drop target cell.
|
||||
* @return The filtered array of sites.
|
||||
*/
|
||||
_filterPinnedSites: function DropPreview_filterPinnedSites(aSites, aCell) {
|
||||
let draggedSite = gDrag.draggedSite;
|
||||
|
||||
// When dropping on a cell that contains a pinned site make sure that all
|
||||
// pinned cells surrounding the drop target are moved as well.
|
||||
let range = this._getPinnedRange(aCell);
|
||||
|
||||
return aSites.filter(function (aSite, aIndex) {
|
||||
// The site must be valid, pinned and not the dragged site.
|
||||
if (!aSite || aSite == draggedSite || !aSite.isPinned())
|
||||
return false;
|
||||
|
||||
let index = aSite.cell.index;
|
||||
|
||||
// If it's not in the 'pinned range' it's a valid pinned site.
|
||||
return (index > range.end || index < range.start);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines the range of pinned sites surrounding the drop target cell.
|
||||
* @param aCell The drop target cell.
|
||||
* @return The range of pinned cells.
|
||||
*/
|
||||
_getPinnedRange: function DropPreview_getPinnedRange(aCell) {
|
||||
let dropIndex = aCell.index;
|
||||
let range = {start: dropIndex, end: dropIndex};
|
||||
|
||||
// We need a pinned range only when dropping on a pinned site.
|
||||
if (aCell.containsPinnedSite()) {
|
||||
let links = gPinnedLinks.links;
|
||||
|
||||
// Find all previous siblings of the drop target that are pinned as well.
|
||||
while (range.start && links[range.start - 1])
|
||||
range.start--;
|
||||
|
||||
let maxEnd = links.length - 1;
|
||||
|
||||
// Find all next siblings of the drop target that are pinned as well.
|
||||
while (range.end < maxEnd && links[range.end + 1])
|
||||
range.end++;
|
||||
}
|
||||
|
||||
return range;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the given array of sites contains a pinned site that has
|
||||
* been pushed out of the grid.
|
||||
* @param aSites The array of sites to check.
|
||||
* @param aCell The drop target cell.
|
||||
* @return Whether there is an overflowed pinned cell.
|
||||
*/
|
||||
_hasOverflowedPinnedSite:
|
||||
function DropPreview_hasOverflowedPinnedSite(aSites, aCell) {
|
||||
|
||||
// If the drop target isn't pinned there's no way a pinned site has been
|
||||
// pushed out of the grid so we can just exit here.
|
||||
if (!aCell.containsPinnedSite())
|
||||
return false;
|
||||
|
||||
let cells = gGrid.cells;
|
||||
|
||||
// No cells have been pushed out of the grid, nothing to do here.
|
||||
if (aSites.length <= cells.length)
|
||||
return false;
|
||||
|
||||
let overflowedSite = aSites[cells.length];
|
||||
|
||||
// Nothing to do if the site that got pushed out of the grid is not pinned.
|
||||
return (overflowedSite && overflowedSite.isPinned());
|
||||
},
|
||||
|
||||
/**
|
||||
* We have a overflowed pinned site that we need to re-position so that it's
|
||||
* visible again. We try to find a lower-priority cell (empty or containing
|
||||
* an unpinned site) that we can move it to.
|
||||
* @param aSites The array of sites.
|
||||
* @param aCell The drop target cell.
|
||||
*/
|
||||
_repositionOverflowedPinnedSite:
|
||||
function DropPreview_repositionOverflowedPinnedSite(aSites, aCell) {
|
||||
|
||||
// Try to find a lower-priority cell (empty or containing an unpinned site).
|
||||
let index = this._indexOfLowerPrioritySite(aSites, aCell);
|
||||
|
||||
if (index > -1) {
|
||||
let cells = gGrid.cells;
|
||||
let dropIndex = aCell.index;
|
||||
|
||||
// Move all pinned cells to their new positions to let the overflowed
|
||||
// site fit into the grid.
|
||||
for (let i = index + 1, lastPosition = index; i < aSites.length; i++) {
|
||||
if (i != dropIndex) {
|
||||
aSites[lastPosition] = aSites[i];
|
||||
lastPosition = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, remove the overflowed site from its previous position.
|
||||
aSites.splice(cells.length, 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds the index of the last cell that is empty or contains an unpinned
|
||||
* site. These are considered to be of a lower priority.
|
||||
* @param aSites The array of sites.
|
||||
* @param aCell The drop target cell.
|
||||
* @return The cell's index.
|
||||
*/
|
||||
_indexOfLowerPrioritySite:
|
||||
function DropPreview_indexOfLowerPrioritySite(aSites, aCell) {
|
||||
|
||||
let cells = gGrid.cells;
|
||||
let dropIndex = aCell.index;
|
||||
|
||||
// Search (beginning with the last site in the grid) for a site that is
|
||||
// empty or unpinned (an thus lower-priority) and can be pushed out of the
|
||||
// grid instead of the pinned site.
|
||||
for (let i = cells.length - 1; i >= 0; i--) {
|
||||
// The cell that is our drop target is not a good choice.
|
||||
if (i == dropIndex)
|
||||
continue;
|
||||
|
||||
let site = aSites[i];
|
||||
|
||||
// We can use the cell only if it's empty or the site is un-pinned.
|
||||
if (!site || !site.isPinned())
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue