mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-26 13:19:49 +07:00
Handle SPA navigations in reading time example. (#1496)
In the move to new infrastructure for https://developer.chrome.com/, the site became an SPA which can soft navigate outside of browser navigations. Therefore, we need to update the sample to watch for changes to content after the content script is injected.
This commit is contained in:
@@ -6,6 +6,8 @@ This sample demonstrates how to run scripts on any Chrome extension and Chrome W
|
||||
|
||||
This sample demonstrates how developers can use content scripts which employ Document Object Models to read and change the content of a page. In this instance, the extension checks to find an article element, counts all the words inside of it, and then creates a paragraph that estimates the total reading time for that article.
|
||||
|
||||
As https://developer.chrome.com/ is a SPA (Single Page Application) it also includes an example of how to use `MutationObserver` to watch for changes to article content. Using `MutationObserver` can have a performance cost, so use them sparingly and only observe the most relevant changes.
|
||||
|
||||
## Running this extension
|
||||
|
||||
1. Clone this repository.
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const article = document.querySelector('article');
|
||||
function renderReadingTime(article) {
|
||||
// If we weren't provided an article, we don't need to render anything.
|
||||
if (!article) {
|
||||
return;
|
||||
}
|
||||
|
||||
// `document.querySelector` may return null if the selector doesn't match anything.
|
||||
if (article) {
|
||||
const text = article.textContent;
|
||||
/**
|
||||
* Regular expression to find all "words" in a string.
|
||||
@@ -45,3 +47,25 @@ if (article) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement
|
||||
(date ?? heading).insertAdjacentElement('afterend', badge);
|
||||
}
|
||||
|
||||
renderReadingTime(document.querySelector('article'));
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
// If a new article was added.
|
||||
for (const node of mutation.addedNodes) {
|
||||
if (node instanceof Element && node.tagName === 'ARTICLE') {
|
||||
// Render the reading time for this particular article.
|
||||
renderReadingTime(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// https://developer.chrome.com/ is a SPA (Single Page Application) so can
|
||||
// update the address bar and render new content without reloading. Our content
|
||||
// script won't be reinjected when this happens, so we need to watch for
|
||||
// changes to the content.
|
||||
observer.observe(document.querySelector('devsite-content'), {
|
||||
childList: true
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user