summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 10:22:43 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:36:28 +0000
commit271a6c3487a14599023a9106329505597638d793 (patch)
treee040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/chrome/browser/resources/local_ntp/most_visited_single.js
parent7b2ffa587235a47d4094787d72f38102089f402a (diff)
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/chrome/browser/resources/local_ntp/most_visited_single.js')
-rw-r--r--chromium/chrome/browser/resources/local_ntp/most_visited_single.js427
1 files changed, 208 insertions, 219 deletions
diff --git a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
index 4fc4e5d6c7f..f26d493e0c4 100644
--- a/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
+++ b/chromium/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -11,7 +11,6 @@
function MostVisited() {
'use strict';
-
/**
* Enum for key codes.
* @enum {number}
@@ -40,7 +39,6 @@ const IDS = {
MV_TILES: 'mv-tiles', // Most Visited tiles container.
};
-
/**
* Enum for classnames.
* @enum {string}
@@ -53,28 +51,24 @@ const CLASSES = {
GRID_REORDER: 'grid-reorder',
GRID_TILE: 'grid-tile',
GRID_TILE_CONTAINER: 'grid-tile-container',
+ HIDE: 'hide', // Applied when the tiles are hidden by the user.
REORDER: 'reorder', // Applied to the tile being moved while reordering.
// Applied while we are reordering. Disables hover styling.
REORDERING: 'reordering',
MAC_CHROMEOS: 'mac-chromeos', // Reduces font weight for MacOS and ChromeOS.
// Material Design classes.
MD_EMPTY_TILE: 'md-empty-tile',
- MD_ICON_BACKGROUND: 'md-icon-background',
MD_FALLBACK_LETTER: 'md-fallback-letter',
- MD_FAVICON: 'md-favicon',
MD_ICON: 'md-icon',
MD_ADD_ICON: 'md-add-icon',
MD_MENU: 'md-menu',
MD_EDIT_MENU: 'md-edit-menu',
MD_TILE: 'md-tile',
- MD_TILE_CONTAINER: 'md-tile-container',
MD_TILE_INNER: 'md-tile-inner',
MD_TITLE: 'md-title',
- MD_TITLE_CONTAINER: 'md-title-container',
NO_INITIAL_FADE: 'no-initial-fade',
};
-
/**
* The different types of events that are logged from the NTP. This enum is
* used to transfer information from the NTP JavaScript to the renderer and is
@@ -86,21 +80,12 @@ const CLASSES = {
const LOG_TYPE = {
// All NTP tiles have finished loading (successfully or failing).
NTP_ALL_TILES_LOADED: 11,
- // The data for all NTP tiles (title, URL, etc, but not the thumbnail image)
- // has been received. In contrast to NTP_ALL_TILES_LOADED, this is recorded
- // before the actual DOM elements have loaded (in particular the thumbnail
- // images).
- NTP_ALL_TILES_RECEIVED: 12,
-
- // Shortcuts have been customized.
- NTP_SHORTCUT_CUSTOMIZED: 39,
// The 'Add shortcut' link was clicked.
NTP_CUSTOMIZE_ADD_SHORTCUT_CLICKED: 44,
// The 'Edit shortcut' link was clicked.
NTP_CUSTOMIZE_EDIT_SHORTCUT_CLICKED: 45,
};
-
/**
* The different (visual) types that an NTP tile can have.
* Note: Keep in sync with components/ntp_tiles/tile_visual_type.h
@@ -116,7 +101,6 @@ const TileVisualType = {
THUMBNAIL_FAILED: 8,
};
-
/**
* Timeout delay for the window.onresize event throttle. Set to 15 frame per
* second.
@@ -124,28 +108,18 @@ const TileVisualType = {
*/
const RESIZE_TIMEOUT_DELAY = 66;
-
-/**
- * Timeout delay in ms before starting the reorder flow.
- * @const {number}
- */
-const REORDER_TIMEOUT_DELAY = 1000;
-
-
/**
* Maximum number of tiles if custom links is enabled.
* @const {number}
*/
const MD_MAX_NUM_CUSTOM_LINK_TILES = 10;
-
/**
* Maximum number of tiles per row for Material Design.
* @const {number}
*/
const MD_MAX_TILES_PER_ROW = 5;
-
/**
* Height of a tile for Material Design. Keep in sync with
* most_visited_single.css.
@@ -153,7 +127,6 @@ const MD_MAX_TILES_PER_ROW = 5;
*/
const MD_TILE_HEIGHT = 128;
-
/**
* Width of a tile for Material Design. Keep in sync with
* most_visited_single.css.
@@ -161,7 +134,6 @@ const MD_TILE_HEIGHT = 128;
*/
const MD_TILE_WIDTH = 112;
-
/**
* Number of tiles that will always be visible for Material Design. Calculated
* by dividing minimum |--content-width| (see local_ntp.css) by |MD_TILE_WIDTH|
@@ -170,7 +142,6 @@ const MD_TILE_WIDTH = 112;
*/
const MD_NUM_TILES_ALWAYS_VISIBLE = 6;
-
/**
* The origin of this request, i.e. 'https://www.google.TLD' for the remote NTP,
* or 'chrome-search://local-ntp' for the local NTP.
@@ -178,7 +149,6 @@ const MD_NUM_TILES_ALWAYS_VISIBLE = 6;
*/
const DOMAIN_ORIGIN = '{{ORIGIN}}';
-
/**
* Counter for DOM elements that we are waiting to finish loading. Starts out
* at 1 because initially we're waiting for the "show" message from the parent.
@@ -186,7 +156,6 @@ const DOMAIN_ORIGIN = '{{ORIGIN}}';
*/
let loadedCounter = 1;
-
/**
* DOM element containing the tiles we are going to present next.
* Works as a double-buffer that is shown when we receive a "show" postMessage.
@@ -194,7 +163,6 @@ let loadedCounter = 1;
*/
let tiles = null;
-
/**
* Maximum number of MostVisited tiles to show at any time. If the host page
* doesn't send enough tiles and custom links is not enabled, we fill them blank
@@ -204,21 +172,18 @@ let tiles = null;
*/
let maxNumTiles = 8;
-
/**
* List of parameters passed by query args.
* @type {Object}
*/
let queryArgs = {};
-
/**
* True if we are currently reordering the tiles.
* @type {boolean}
*/
let reordering = false;
-
/**
* The tile that is being moved during the reorder flow. Null if we are
* currently not reordering.
@@ -226,13 +191,12 @@ let reordering = false;
*/
let elementToReorder = null;
-
/**
- * True if custom links is enabled.
+ * True if the custom links feature is enabled, i.e. when this is a Google NTP.
+ * Set when the iframe is initialized.
* @type {boolean}
*/
-let isCustomLinksEnabled = false;
-
+let customLinksFeatureEnabled = false;
/**
* True if the grid layout is enabled.
@@ -240,14 +204,12 @@ let isCustomLinksEnabled = false;
*/
let isGridEnabled = false;
-
/**
* The current grid of tiles.
* @type {?Grid}
*/
let currGrid = null;
-
/**
* Called by tests to enable the grid layout.
*/
@@ -256,7 +218,6 @@ function enableGridLayoutForTesting() {
document.body.classList.add(CLASSES.GRID_LAYOUT);
}
-
/**
* Additional API for Array. Moves the item at index |from| to index |to|.
* @param {number} from Index of the item to move.
@@ -266,7 +227,6 @@ Array.prototype.move = function(from, to) {
this.splice(to, 0, this.splice(from, 1)[0]);
};
-
/**
* Class that handles layouts and animations for the tile grid. This includes
* animations for adding, deleting, and reordering.
@@ -317,8 +277,10 @@ class Grid {
this.itemToReorder_ = -1;
/** @private {number} The index to move the tile we're reordering to. */
this.newIndexOfItemToReorder_ = -1;
- }
+ /** @private {boolean} True if the user is currently touching a tile. */
+ this.touchStarted_ = false;
+ }
/**
* Sets up the grid for the new tileset in |container|. The old tileset is
@@ -353,7 +315,7 @@ class Grid {
this.order_[i] = i;
}
- if (isCustomLinksEnabled || params.enableReorder) {
+ if (isCustomLinksEnabled() || params.enableReorder) {
// Set up reordering for all tiles except the add shortcut button.
for (let i = 0; i < this.tiles_.length; i++) {
if (this.tiles_[i].getAttribute('add') !== 'true') {
@@ -365,7 +327,6 @@ class Grid {
this.updateLayout();
}
-
/**
* Returns a grid tile wrapper that contains |tile|.
* @param {!Element} tile The tile element.
@@ -385,7 +346,6 @@ class Grid {
return gridTileContainer;
}
-
/**
* Updates the layout of the tiles. This is called for new tilesets and when
* the window is resized or zoomed. Translates each tile's
@@ -424,7 +384,6 @@ class Grid {
}
}
-
/**
* Called when the window is resized/zoomed. Recalculates maximums for the new
* window size and calls |updateLayout| if necessary.
@@ -439,7 +398,6 @@ class Grid {
}
}
-
/**
* Returns the number of tiles per row. This may be balanced in order to make
* even rows.
@@ -461,7 +419,6 @@ class Grid {
}
}
-
/**
* Returns the maximum number of tiles per row allowed by the window size.
* @return {number} The maximum number of tiles per row.
@@ -471,7 +428,6 @@ class Grid {
return Math.floor(window.innerWidth / this.tileWidth_);
}
-
/**
* Returns row 2's x offset from row 1 in px. This will either be 0 or half a
* tile length.
@@ -488,7 +444,6 @@ class Grid {
return 0;
}
-
/**
* Returns true if the browser is in RTL.
* @return {boolean}
@@ -498,7 +453,6 @@ class Grid {
return document.documentElement.dir === 'rtl';
}
-
/**
* Translates the |element| by (x, y).
* @param {?Element} element The element to apply the transform to.
@@ -514,7 +468,6 @@ class Grid {
element.style.transform = 'translate(' + rtlX + 'px, ' + y + 'px)';
}
-
/**
* Sets up event listeners necessary for tile reordering.
* @param {!Element} tile Tile on which to set the event listeners.
@@ -523,30 +476,82 @@ class Grid {
*/
setupReorder_(tile, index) {
tile.setAttribute('index', index);
+
+ // Set up mouse support.
// Listen for the drag event on the tile instead of the tile container. The
// tile container remains static during the reorder flow.
tile.firstChild.draggable = true;
+ // Prevent default drag events on the shortcut link.
+ const tileItem = tile.firstChild.firstChild;
+ tileItem.draggable = false;
tile.firstChild.addEventListener('dragstart', (event) => {
- this.startReorder_(tile, event);
+ // Support link dragging (i.e. dragging the URL to the omnibox).
+ event.dataTransfer.setData('text/uri-list', tileItem.href);
+ // Remove the ghost image that appears when dragging.
+ const emptyImg = new Image();
+ event.dataTransfer.setDragImage(emptyImg, 0, 0);
+
+ this.startReorder_(tile, event, /*mouseMode=*/ true);
+ });
+ // Show a 'move' cursor while dragging the tile within the grid bounds. This
+ // is mostly intended for Windows, which will otherwise show a 'prohibited'
+ // cursor.
+ tile.addEventListener('dragover', (event) => {
+ event.preventDefault();
+ event.dataTransfer.dropEffect = 'move';
});
- // Listen for the mouseover event on the tile container. If this is placed
- // on the tile instead, it can be triggered while the tile is translated to
- // its new position.
- tile.addEventListener('mouseover', (event) => {
- this.reorderToIndex_(index);
+
+ // Set up touch support.
+ tile.firstChild.addEventListener('touchstart', (startEvent) => {
+ // Ignore subsequent touchstart events, which can be triggered if a
+ // different finger is placed on this tile.
+ if (this.touchStarted_) {
+ return;
+ }
+ this.touchStarted_ = true;
+
+ // Start the reorder flow once the user moves their finger.
+ const startReorder = (moveEvent) => {
+ // Use the cursor position from 'touchstart' as the starting location.
+ this.startReorder_(tile, startEvent, /*mouseMode=*/ false);
+ };
+ // Insert the held tile at the index we are hovering over.
+ const moveOver = (moveEvent) => {
+ // Touch events do not have a 'mouseover' equivalent, so we need to
+ // manually check if we are hovering over a tile. If so, insert the held
+ // tile there.
+ // Note: The first item in |changedTouches| is the current position.
+ const x = moveEvent.changedTouches[0].pageX;
+ const y = moveEvent.changedTouches[0].pageY;
+ this.reorderToIndexAtPoint_(x, y);
+ };
+ // Allow 'touchstart' events again when reordering stops/was never
+ // started.
+ const touchEnd = (endEvent) => {
+ tile.firstChild.removeEventListener('touchmove', startReorder);
+ tile.firstChild.removeEventListener('touchmove', moveOver);
+ tile.firstChild.removeEventListener('touchend', touchEnd);
+ tile.firstChild.removeEventListener('touchcancel', touchEnd);
+ this.touchStarted_ = false;
+ };
+
+ tile.firstChild.addEventListener('touchmove', startReorder, {once: true});
+ tile.firstChild.addEventListener('touchmove', moveOver);
+ tile.firstChild.addEventListener('touchend', touchEnd, {once: true});
+ tile.firstChild.addEventListener('touchcancel', touchEnd, {once: true});
});
}
-
/**
* Starts the reorder flow. Updates the visual style of the held tile to
* indicate that it is being moved and sets up the relevant event listeners.
* @param {!Element} tile Tile that is being moved.
- * @param {!Event} event The 'dragstart' event. Used to obtain the current
- * cursor position
+ * @param {!Event} event The 'dragstart'/'touchmove' event. Used to obtain the
+ * current cursor position
+ * @param {boolean} mouseMode True if the user is using a mouse.
* @private
*/
- startReorder_(tile, event) {
+ startReorder_(tile, event, mouseMode) {
const index = Number(tile.getAttribute('index'));
this.itemToReorder_ = index;
@@ -557,16 +562,44 @@ class Grid {
// Disable other hover/active styling for all tiles.
document.body.classList.add(CLASSES.REORDERING);
- // Set up event listeners for the reorder flow.
- const mouseMove = this.trackCursor_(tile, event.pageX, event.pageY);
- document.addEventListener('mousemove', mouseMove);
- document.addEventListener('mouseup', () => {
- document.removeEventListener('mousemove', mouseMove);
- this.stopReorder_(tile);
- }, {once: true});
+ // Set up event listeners for the reorder flow. Listen for drag events if
+ // |mouseMode|, touch events otherwise.
+ if (mouseMode) {
+ const trackCursor =
+ this.trackCursor_(tile, event.pageX, event.pageY, true);
+ // The 'dragover' event must be tracked at the document level, since the
+ // currently dragged tile will interfere with 'dragover' events on the
+ // other tiles.
+ const dragOver = (dragOverEvent) => {
+ trackCursor(dragOverEvent);
+ // Since the 'dragover' event is not tied to a specific tile, we need to
+ // manually check if we are hovering over a tile. If so, insert the held
+ // tile there.
+ this.reorderToIndexAtPoint_(dragOverEvent.pageX, dragOverEvent.pageY);
+ };
+ document.addEventListener('dragover', dragOver);
+ document.addEventListener('dragend', () => {
+ document.removeEventListener('dragover', dragOver);
+ this.stopReorder_(tile);
+ }, {once: true});
+ } else {
+ // Track the cursor on subsequent 'touchmove' events (the first
+ // 'touchmove' event that starts the reorder flow is ignored).
+ const trackCursor = this.trackCursor_(
+ tile, event.changedTouches[0].pageX, event.changedTouches[0].pageY,
+ false);
+ const touchEnd = (touchEndEvent) => {
+ tile.firstChild.removeEventListener('touchmove', trackCursor);
+ tile.firstChild.removeEventListener('touchend', touchEnd);
+ tile.firstChild.removeEventListener('touchcancel', touchEnd);
+ this.stopReorder_(tile); // Stop the reorder flow.
+ };
+ tile.firstChild.addEventListener('touchmove', trackCursor);
+ tile.firstChild.addEventListener('touchend', touchEnd, {once: true});
+ tile.firstChild.addEventListener('touchcancel', touchEnd, {once: true});
+ }
}
-
/**
* Stops the reorder flow. Resets the held tile's visual style and tells the
* EmbeddedSearchAPI that a tile has been moved.
@@ -591,6 +624,24 @@ class Grid {
this.newIndexOfItemToReorder_ = -1;
}
+ /**
+ * Attempts to insert the currently held tile at the index located at (x, y).
+ * Does nothing if there is no tile at (x, y) or the reorder flow is not
+ * ongoing.
+ * @param {number} x The x coordinate.
+ * @param {number} y The y coordinate.
+ * @private
+ */
+ reorderToIndexAtPoint_(x, y) {
+ const elements = document.elementsFromPoint(x, y);
+ for (let i = 0; i < elements.length; i++) {
+ if (elements[i].classList.contains('grid-tile-container') &&
+ elements[i].getAttribute('index') !== null) {
+ this.reorderToIndex_(Number(elements[i].getAttribute('index')));
+ return;
+ }
+ }
+ }
/**
* Executed only when the reorder flow is ongoing. Inserts the currently held
@@ -619,7 +670,6 @@ class Grid {
}
}
-
/**
* Translates the |tile|'s |CLASSES.GRID_TILE| from |index| to |newIndex|.
* This is done to prevent interference with event listeners on the |tile|'s
@@ -638,7 +688,6 @@ class Grid {
this.translate_(tile.children[0], x, y);
}
-
/**
* Moves |tile| so that it tracks the cursor's position. This is done by
* translating the |tile|'s |CLASSES.GRID_TILE|, which prevents interference
@@ -646,9 +695,10 @@ class Grid {
* @param {!Element} tile Tile that is being moved.
* @param {number} origCursorX Original x cursor position.
* @param {number} origCursorY Original y cursor position.
+ * @param {boolean} mouseMode True if the user is using a mouse.
* @private
*/
- trackCursor_(tile, origCursorX, origCursorY) {
+ trackCursor_(tile, origCursorX, origCursorY, mouseMode) {
const index = Number(tile.getAttribute('index'));
// RTL positions align with the right side of the grid. Therefore, the x
// value must be recalculated to align with the left.
@@ -668,15 +718,16 @@ class Grid {
const minY = 0 - origPosY;
return (event) => {
+ const currX = mouseMode ? event.pageX : event.changedTouches[0].pageX;
+ const currY = mouseMode ? event.pageY : event.changedTouches[0].pageY;
// Do not exceed the iframe borders.
- const x = Math.max(Math.min(event.pageX - origCursorX, maxX), minX);
- const y = Math.max(Math.min(event.pageY - origCursorY, maxY), minY);
+ const x = Math.max(Math.min(currX - origCursorX, maxX), minX);
+ const y = Math.max(Math.min(currY - origCursorY, maxY), minY);
tile.firstChild.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
};
}
}
-
/**
* Log an event on the NTP.
* @param {number} eventType Event from LOG_TYPE.
@@ -689,12 +740,12 @@ function logEvent(eventType) {
* Log impression of an NTP tile.
* @param {number} tileIndex Position of the tile, >= 0 and < |maxNumTiles|.
* @param {number} tileTitleSource The source of the tile's title as received
- * from getMostVisitedItemData.
+ * from getMostVisitedItemData.
* @param {number} tileSource The tile's source as received from
- * getMostVisitedItemData.
+ * getMostVisitedItemData.
* @param {number} tileType The tile's visual type from TileVisualType.
* @param {Date} dataGenerationTime Timestamp representing when the tile was
- * produced by a ranking algorithm.
+ * produced by a ranking algorithm.
*/
function logMostVisitedImpression(
tileIndex, tileTitleSource, tileSource, tileType, dataGenerationTime) {
@@ -706,12 +757,12 @@ function logMostVisitedImpression(
* Log click on an NTP tile.
* @param {number} tileIndex Position of the tile, >= 0 and < |maxNumTiles|.
* @param {number} tileTitleSource The source of the tile's title as received
- * from getMostVisitedItemData.
+ * from getMostVisitedItemData.
* @param {number} tileSource The tile's source as received from
- * getMostVisitedItemData.
+ * getMostVisitedItemData.
* @param {number} tileType The tile's visual type from TileVisualType.
* @param {Date} dataGenerationTime Timestamp representing when the tile was
- * produced by a ranking algorithm.
+ * produced by a ranking algorithm.
*/
function logMostVisitedNavigation(
tileIndex, tileTitleSource, tileSource, tileType, dataGenerationTime) {
@@ -720,6 +771,14 @@ function logMostVisitedNavigation(
}
/**
+ * Returns true if custom links are enabled.
+ */
+function isCustomLinksEnabled() {
+ return customLinksFeatureEnabled &&
+ !chrome.embeddedSearch.newTabPage.isUsingMostVisited;
+}
+
+/**
* Down counts the DOM elements that we are waiting for the page to load.
* When we get to 0, we send a message to the parent window.
* This is usually used as an EventListener of onload/onerror.
@@ -729,14 +788,8 @@ function countLoad() {
if (loadedCounter <= 0) {
swapInNewTiles();
logEvent(LOG_TYPE.NTP_ALL_TILES_LOADED);
- let tilesAreCustomLinks =
- isCustomLinksEnabled && chrome.embeddedSearch.newTabPage.isCustomLinks;
- // Note that it's easiest to capture this when all custom links are loaded,
- // rather than when the impression for each link is logged.
- if (tilesAreCustomLinks) {
- chrome.embeddedSearch.newTabPage.logEvent(
- LOG_TYPE.NTP_SHORTCUT_CUSTOMIZED);
- }
+ let tilesAreCustomLinks = isCustomLinksEnabled() &&
+ chrome.embeddedSearch.newTabPage.isCustomLinks;
// Tell the parent page whether to show the restore default shortcuts option
// in the menu.
window.parent.postMessage(
@@ -749,7 +802,6 @@ function countLoad() {
}
}
-
/**
* Handles postMessages coming from the host page to the iframe.
* Mostly, it dispatches every command to handleCommand.
@@ -764,7 +816,6 @@ function handlePostMessage(event) {
}
}
-
/**
* Handles a single command coming from the host page to the iframe.
* We try to keep the logic here to a minimum and just dispatch to the relevant
@@ -789,18 +840,18 @@ function handleCommand(data) {
}
}
-
/**
* Handler for the 'show' message from the host page.
* @param {!Object} info Data received in the message.
*/
function showTiles(info) {
- logEvent(LOG_TYPE.NTP_ALL_TILES_RECEIVED);
+ document.body.classList.toggle(
+ CLASSES.HIDE, !chrome.embeddedSearch.newTabPage.areShortcutsVisible);
+
utils.setPlatformClass(document.body);
countLoad();
}
-
/**
* Handler for the 'updateTheme' message from the host page.
* @param {!Object} info Data received in the message.
@@ -813,7 +864,6 @@ function updateTheme(info) {
document.body.classList.toggle('use-title-container', info.useTitleContainer);
document.body.classList.toggle('custom-background', info.customBackground);
document.body.classList.toggle('use-white-add-icon', info.useWhiteAddIcon);
- document.documentElement.setAttribute('darkmode', info.isDarkMode);
// Reduce font weight on the default(white) background for Mac and CrOS.
document.body.classList.toggle(
@@ -823,7 +873,6 @@ function updateTheme(info) {
navigator.userAgent.indexOf('CrOS') > -1));
}
-
/**
* Handler for 'focusMenu' message from the host page. Focuses the edited tile's
* menu or the add shortcut tile after closing the custom link edit dialog
@@ -831,15 +880,14 @@ function updateTheme(info) {
* @param {!Object} info Data received in the message.
*/
function focusTileMenu(info) {
- const tile = document.querySelector(`a.md-tile[data-tid="${info.tid}"]`);
- if (info.tid === -1 /* Add shortcut tile */) {
+ const tile = document.querySelector(`a.md-tile[data-rid="${info.rid}"]`);
+ if (info.rid === -1 /* Add shortcut tile */) {
tile.focus();
} else {
tile.parentNode.childNodes[1].focus();
}
}
-
/**
* Removes all old instances of |IDS.MV_TILES| that are pending for deletion.
*/
@@ -851,7 +899,6 @@ function removeAllOldTiles() {
}
}
-
/**
* Called when all tiles have finished loading (successfully or not), including
* their thumbnail images, and we are ready to show the new tiles and drop the
@@ -863,9 +910,9 @@ function swapInNewTiles() {
// Add an "add new custom link" button if we haven't reached the maximum
// number of tiles.
- if (isCustomLinksEnabled && cur.childNodes.length < maxNumTiles) {
+ if (isCustomLinksEnabled() && cur.childNodes.length < maxNumTiles) {
const data = {
- 'tid': -1,
+ 'rid': -1,
'title': queryArgs['addLink'],
'url': '',
'isAddButton': true,
@@ -903,7 +950,7 @@ function swapInNewTiles() {
// Re-balance the tiles if there are more than |MD_MAX_TILES_PER_ROW| in
// order to make even rows.
if (cur.childNodes.length > MD_MAX_TILES_PER_ROW) {
- cur.style.maxWidth = 'calc(var(--md-tile-width) * ' +
+ cur.style.maxWidth = 'calc(var(--md-tile-size) * ' +
Math.ceil(cur.childNodes.length / 2) + ')';
}
}
@@ -925,14 +972,13 @@ function swapInNewTiles() {
tiles = document.createElement('div');
}
-
/**
* Explicitly hide tiles that are not visible in order to prevent keyboard
* navigation.
*/
function updateTileVisibility() {
- const allTiles = document.querySelectorAll(
- '#' + IDS.MV_TILES + ' .' + CLASSES.MD_TILE_CONTAINER);
+ const allTiles =
+ document.querySelectorAll('#' + IDS.MV_TILES + ' .' + CLASSES.MD_TILE);
if (allTiles.length === 0) {
return;
}
@@ -945,7 +991,6 @@ function updateTileVisibility() {
}
}
-
/**
* Handler for the 'show' message from the host page, called when it wants to
* add a suggestion tile.
@@ -961,10 +1006,9 @@ function addTile(args) {
return;
}
- data.tid = data.rid;
if (!data.faviconUrl) {
data.faviconUrl = 'chrome-search://favicon/size/16@' +
- window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.tid;
+ window.devicePixelRatio + 'x/' + data.renderViewId + '/' + data.rid;
}
tiles.appendChild(renderTile(data));
} else {
@@ -980,10 +1024,10 @@ function addTile(args) {
* @param {Element} tile DOM node of the tile we want to remove.
*/
function blacklistTile(tile) {
- const tid = Number(tile.firstChild.getAttribute('data-tid'));
+ const rid = Number(tile.getAttribute('data-rid'));
- if (isCustomLinksEnabled) {
- chrome.embeddedSearch.newTabPage.deleteMostVisitedItem(tid);
+ if (isCustomLinksEnabled()) {
+ chrome.embeddedSearch.newTabPage.deleteMostVisitedItem(rid);
} else {
tile.classList.add('blacklisted');
tile.addEventListener('transitionend', function(ev) {
@@ -991,22 +1035,20 @@ function blacklistTile(tile) {
return;
}
window.parent.postMessage(
- {cmd: 'tileBlacklisted', tid: Number(tid)}, DOMAIN_ORIGIN);
+ {cmd: 'tileBlacklisted', rid: Number(rid)}, DOMAIN_ORIGIN);
});
}
}
-
/**
* Starts edit custom link flow. Tells host page to show the edit custom link
* dialog and pre-populate it with data obtained using the link's id.
- * @param {?number} tid Restricted id of the tile we want to edit.
+ * @param {?number} rid Restricted id of the tile we want to edit.
*/
-function editCustomLink(tid) {
- window.parent.postMessage({cmd: 'startEditLink', tid: tid}, DOMAIN_ORIGIN);
+function editCustomLink(rid) {
+ window.parent.postMessage({cmd: 'startEditLink', rid: rid}, DOMAIN_ORIGIN);
}
-
/**
* Starts the reorder flow. Updates the visual style of the held tile to
* indicate that it is being moved.
@@ -1025,7 +1067,6 @@ function startReorder(tile) {
}, {once: true});
}
-
/**
* Stops the reorder flow. Resets the held tile's visual style and tells the
* EmbeddedSearchAPI that a tile has been moved.
@@ -1045,50 +1086,19 @@ function stopReorder(tile) {
allTiles[i].setAttribute('data-pos', i);
}
chrome.embeddedSearch.newTabPage.reorderCustomLink(
- Number(tile.firstChild.getAttribute('data-tid')),
- Number(tile.firstChild.getAttribute('data-pos')));
+ Number(tile.getAttribute('data-rid')),
+ Number(tile.getAttribute('data-pos')));
}
-
/**
* Sets up event listeners necessary for tile reordering.
* @param {!Element} tile Tile on which to set the event listeners.
*/
function setupReorder(tile) {
- // Starts the reorder flow after the user has held the mouse button down for
- // |REORDER_TIMEOUT_DELAY|.
- tile.addEventListener('mousedown', (event) => {
- // Do not reorder if the edit menu was clicked or if ctrl/shift/alt/meta is
- // also held down.
- if (event.button == 0 /* LEFT CLICK */ && !event.ctrlKey &&
- !event.shiftKey && !event.altKey && !event.metaKey &&
- !event.target.classList.contains(CLASSES.MD_MENU)) {
- let timeout = -1;
-
- // Cancel the timeout if the user drags the mouse off the tile and
- // releases or if the mouse if released.
- const dragend = () => {
- window.clearTimeout(timeout);
- };
- document.addEventListener('dragend', dragend, {once: true});
-
- const mouseup = () => {
- if (event.button == 0 /* LEFT CLICK */) {
- window.clearTimeout(timeout);
- }
- };
- document.addEventListener('mouseup', mouseup, {once: true});
-
- const timeoutFunc = (dragend_in, mouseup_in) => {
- if (!reordering) {
- startReorder(tile);
- }
- document.removeEventListener('dragend', dragend_in);
- document.removeEventListener('mouseup', mouseup_in);
- };
- // Wait for |REORDER_TIMEOUT_DELAY| before starting the reorder flow.
- timeout = window.setTimeout(
- timeoutFunc.bind(dragend, mouseup), REORDER_TIMEOUT_DELAY);
+ // Starts the reorder flow.
+ tile.addEventListener('dragstart', (event) => {
+ if (!reordering) {
+ startReorder(tile);
}
});
@@ -1113,7 +1123,6 @@ function setupReorder(tile) {
});
}
-
/**
* Renders a MostVisited tile to the DOM.
* @param {?MostVisitedData} data Object containing rid, url, title, favicon,
@@ -1126,7 +1135,6 @@ function renderTile(data) {
return renderMaterialDesignTile(data);
}
-
/**
* Renders a MostVisited tile with Material Design styles.
* @param {?MostVisitedData} data Object containing rid, url, title, favicon,
@@ -1136,24 +1144,19 @@ function renderTile(data) {
* @return {Element}
*/
function renderMaterialDesignTile(data) {
- const mdTileContainer = document.createElement('div');
- mdTileContainer.role = 'none';
-
+ const mdTile = document.createElement('a');
if (data == null) {
- mdTileContainer.className = CLASSES.MD_EMPTY_TILE;
- return mdTileContainer;
+ mdTile.className = CLASSES.MD_EMPTY_TILE;
+ return mdTile;
}
- mdTileContainer.className = CLASSES.MD_TILE_CONTAINER;
+ mdTile.className = CLASSES.MD_TILE;
- // The tile will be appended to tiles.
+ // The tile will be appended to |tiles|.
const position = tiles.children.length;
// This is set in the load/error event for the favicon image.
let tileType = TileVisualType.NONE;
- const mdTile = document.createElement('a');
- mdTile.className = CLASSES.MD_TILE;
- mdTile.tabIndex = 0;
- mdTile.setAttribute('data-tid', data.tid);
+ mdTile.setAttribute('data-rid', data.rid);
mdTile.setAttribute('data-pos', position);
if (utils.isSchemeAllowed(data.url)) {
mdTile.href = data.url;
@@ -1177,7 +1180,7 @@ function renderMaterialDesignTile(data) {
!data.isAddButton) {
event.preventDefault();
event.stopPropagation();
- blacklistTile(mdTileContainer);
+ blacklistTile(mdTile);
} else if (
event.keyCode === KEYCODES.ENTER || event.keyCode === KEYCODES.SPACE) {
event.preventDefault();
@@ -1199,29 +1202,26 @@ function renderMaterialDesignTile(data) {
const mdTileInner = document.createElement('div');
mdTileInner.className = CLASSES.MD_TILE_INNER;
- const mdIcon = document.createElement('div');
- mdIcon.classList.add(CLASSES.MD_ICON);
- mdIcon.classList.add(CLASSES.MD_ICON_BACKGROUND);
-
if (data.isAddButton) {
- const mdAdd = document.createElement('div');
- mdAdd.className = CLASSES.MD_ADD_ICON;
- const addBackground = document.createElement('div');
- addBackground.className = CLASSES.MD_ICON_BACKGROUND;
+ mdTile.tabIndex = 0;
- addBackground.appendChild(mdAdd);
- mdIcon.appendChild(addBackground);
+ const mdIconAdd = document.createElement('div');
+ mdIconAdd.classList.add(CLASSES.MD_ICON);
+ mdIconAdd.classList.add(CLASSES.MD_ADD_ICON);
+
+ mdTileInner.appendChild(mdIconAdd);
} else {
- const fi = document.createElement('img');
+ const mdIcon = document.createElement('img');
+ mdIcon.classList.add(CLASSES.MD_ICON);
// Set title and alt to empty so screen readers won't say the image name.
- fi.title = '';
- fi.alt = '';
+ mdIcon.title = '';
+ mdIcon.alt = '';
const url = new URL('chrome-search://ntpicon/');
url.searchParams.set('size', '24@' + window.devicePixelRatio + 'x');
url.searchParams.set('url', data.url);
- fi.src = url.toString();
+ mdIcon.src = url.toString();
loadedCounter += 1;
- fi.addEventListener('load', function(ev) {
+ mdIcon.addEventListener('load', function(ev) {
// Store the type for a potential later navigation.
tileType = TileVisualType.ICON_REAL;
logMostVisitedImpression(
@@ -1232,17 +1232,16 @@ function renderMaterialDesignTile(data) {
// log.
countLoad();
});
- fi.addEventListener('error', function(ev) {
+ mdIcon.addEventListener('error', function(ev) {
const fallbackBackground = document.createElement('div');
- fallbackBackground.className = CLASSES.MD_ICON_BACKGROUND;
+ fallbackBackground.className = CLASSES.MD_ICON;
const fallbackLetter = document.createElement('div');
fallbackLetter.className = CLASSES.MD_FALLBACK_LETTER;
fallbackLetter.textContent = data.title.charAt(0).toUpperCase();
- mdIcon.classList.add(CLASSES.FAILED_FAVICON);
+ fallbackBackground.classList.add(CLASSES.FAILED_FAVICON);
fallbackBackground.appendChild(fallbackLetter);
- mdIcon.removeChild(fi);
- mdIcon.appendChild(fallbackBackground);
+ mdTileInner.replaceChild(fallbackBackground, mdIcon);
// Store the type for a potential later navigation.
tileType = TileVisualType.ICON_DEFAULT;
@@ -1255,35 +1254,29 @@ function renderMaterialDesignTile(data) {
countLoad();
});
- mdIcon.appendChild(fi);
+ mdTileInner.appendChild(mdIcon);
}
- mdTileInner.appendChild(mdIcon);
-
- const mdTitleContainer = document.createElement('div');
- mdTitleContainer.className = CLASSES.MD_TITLE_CONTAINER;
const mdTitle = document.createElement('div');
mdTitle.className = CLASSES.MD_TITLE;
+ mdTitle.style.direction = data.direction || 'ltr';
const mdTitleTextwrap = document.createElement('span');
mdTitleTextwrap.innerText = data.title;
- mdTitle.style.direction = data.direction || 'ltr';
- mdTitleContainer.appendChild(mdTitle);
- mdTileInner.appendChild(mdTitleContainer);
- mdTile.appendChild(mdTileInner);
- mdTileContainer.appendChild(mdTile);
mdTitle.appendChild(mdTitleTextwrap);
+ mdTileInner.appendChild(mdTitle);
+ mdTile.appendChild(mdTileInner);
if (!data.isAddButton) {
const mdMenu = document.createElement('button');
mdMenu.className = CLASSES.MD_MENU;
- if (isCustomLinksEnabled) {
+ if (isCustomLinksEnabled()) {
mdMenu.classList.add(CLASSES.MD_EDIT_MENU);
mdMenu.title = queryArgs['editLinkTooltip'] || '';
mdMenu.setAttribute(
'aria-label',
(queryArgs['editLinkTooltip'] || '') + ' ' + data.title);
mdMenu.addEventListener('click', function(ev) {
- editCustomLink(data.tid);
+ editCustomLink(data.rid);
ev.preventDefault();
ev.stopPropagation();
logEvent(LOG_TYPE.NTP_CUSTOMIZE_EDIT_SHORTCUT_CLICKED);
@@ -1294,7 +1287,7 @@ function renderMaterialDesignTile(data) {
'aria-label', (queryArgs['removeTooltip'] || '') + ' ' + data.title);
mdMenu.addEventListener('click', function(ev) {
removeAllOldTiles();
- blacklistTile(mdTileContainer);
+ blacklistTile(mdTile);
ev.preventDefault();
ev.stopPropagation();
});
@@ -1306,23 +1299,21 @@ function renderMaterialDesignTile(data) {
});
utils.disableOutlineOnMouseClick(mdMenu);
- mdTileContainer.appendChild(mdMenu);
+ mdTile.appendChild(mdMenu);
}
if (isGridEnabled) {
- return currGrid.createGridTile(
- mdTileContainer, data.tid, !!data.isAddButton);
+ return currGrid.createGridTile(mdTile, data.rid, !!data.isAddButton);
} else {
// Enable reordering.
- if (isCustomLinksEnabled && !data.isAddButton) {
- mdTileContainer.draggable = 'true';
- setupReorder(mdTileContainer);
+ if (isCustomLinksEnabled() && !data.isAddButton) {
+ mdTile.draggable = 'true';
+ setupReorder(mdTile);
}
- return mdTileContainer;
+ return mdTile;
}
}
-
/**
* Does some initialization and parses the query arguments passed to the iframe.
*/
@@ -1353,7 +1344,7 @@ function init() {
// Enable custom links.
if (queryArgs['enableCustomLinks'] == '1') {
- isCustomLinksEnabled = true;
+ customLinksFeatureEnabled = true;
}
// Enable grid layout.
@@ -1363,7 +1354,7 @@ function init() {
}
// Set the maximum number of tiles to show.
- if (isCustomLinksEnabled) {
+ if (isCustomLinksEnabled()) {
maxNumTiles = MD_MAX_NUM_CUSTOM_LINK_TILES;
}
@@ -1388,7 +1379,6 @@ function init() {
window.addEventListener('message', handlePostMessage);
}
-
/**
* Binds event listeners.
*/
@@ -1396,7 +1386,6 @@ function listen() {
document.addEventListener('DOMContentLoaded', init);
}
-
return {
Grid: Grid, // Exposed for testing.
init: init, // Exposed for testing.