{"id":21565119,"url":"https://github.com/cfware/history-state","last_synced_at":"2025-03-18T05:17:26.827Z","repository":{"id":57101030,"uuid":"176766399","full_name":"cfware/history-state","owner":"cfware","description":"Browser History API state manager.","archived":false,"fork":false,"pushed_at":"2023-10-16T21:58:36.000Z","size":82,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-27T12:13:58.902Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cfware.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-20T15:44:00.000Z","updated_at":"2022-08-13T16:50:34.000Z","dependencies_parsed_at":"2025-01-24T11:43:54.804Z","dependency_job_id":"a854e184-f87d-47b4-a9fb-d4a4b2338cbd","html_url":"https://github.com/cfware/history-state","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfware%2Fhistory-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfware%2Fhistory-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfware%2Fhistory-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfware%2Fhistory-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cfware","download_url":"https://codeload.github.com/cfware/history-state/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244160055,"owners_count":20408021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T10:18:29.099Z","updated_at":"2025-03-18T05:17:26.799Z","avatar_url":"https://github.com/cfware.png","language":"JavaScript","readme":"# @cfware/history-state [![NPM Version][npm-image]][npm-url]\n\nBrowser History API state manager.\n\n## Usage\n\n```js\nimport historyState, * as historyFunctions from '@cfware/history-state';\n\nhistoryState.addEventListener('update', () =\u003e {\n  /* An internal navigation has occurred with history API. */\n});\n\nhistoryState.addEventListener('refuse', () =\u003e {\n  /* An internal navigation has been refused due to dirty state. */\n  if (window.confirm('Do you really want to leave this page without saving?')) {\n    /* honor the back/forward/link click requested by the user. */\n    historyFunctions.bypassDirty();\n  }\n});\n```\n\n### historyState.state\n\nThis should be used instead of `history.state` which will contain additional fields\nthat are internal to `@cfware/history-state`.\n\nUse `historyState.pushState` or `historyState.replaceState` to modify.  `historyState.state`\nshould be treated as if it is frozen.\n\nDefault `null`\n\n### historyState.pushState(state, title, url)\n\nThis must be used in place of `history.pushState`.  This function causes an `update` or\n`refuse` event to be dispatched depending on `historyFunctions.isDirty()`.\n\n### historyState.replaceState(state, title, url)\n\nThis must be used in place of `history.replaceState`.  This replaces the current history\nentry.\n\nUnlike `historyState.pushState` this function does not cause `update` or `refuse` to be\ndispatched.  This function succeeds regardless of `dirty` status.\n\n### historyState Events\n\n#### update\n\nThis is dispatched when the current location is changed, including upon window `onload`.\n\n#### refuse\n\nThis is dispatched when a location change is refused due to `historyState.dirty` being\ntrue.  This will happen when the user hits back/forward without leaving the SPA or when\nan internal link is clicked.\n\n### historyFunctions.bypassDirty()\n\nCalling this function after a `refuse` event will allow navigation that was blocked\nby the dirty status.\n\n### historyFunctions.setDirty(value)\n\nThis can be set true or false to indicate if the current page has unsaved changes.\n\nDefault `false`\n\n### historyFunctions.isDirty()\n\nRetrieve the current dirty status.\n\n### historyFunctions.linkInterceptor(element, listenerOptions)\n\nThis attaches a `click` event listener to `element` which intercepts normal clicks\non any `\u003ca\u003e` element visible from `element`.  During startup this is run for `document`\nso in most cases you will not need to run `historyFunctions.linkInterceptor` manually.  The\nexception is closed shadow roots, for example:\n```js\nconst shadowRoot = this.attachShadow({mode: 'closed'});\nthis.shadowRoot.innerHTML = '\u003ca href=\"/link/\"\u003elink\u003c/a\u003e';\n\n/* The `\u003ca\u003e` inside shadowRoot is not visible to document because of\n * closed mode, so we have to add an interceptor directly.\n */\nhistoryFunctions.linkInterceptor(shadowRoot);\n```\n\nAny link click that is intercepted results in a call to `historyState.pushState`.\n\nThe `listenerOptions` argument is passed to `element.addEventListener` as the second\nargument.\n\n### window.onbeforeunload\n\nThis component listens for `beforeunload`.  If `historyState.isDirty()` is true the unload\nwill be canceled.\n\n### \u003ca\u003e links\n\nBy default this module will intercept clicks on `\u003ca\u003e` links.  Links to pages within\n`document.baseURI` will be treated as part of the SPA.  This is disabled per link by\nadding the `target`, `download` or `no-history-state` attributes.\n\nThe default click listener can be disabled by calling `historyFunctions.setDefaultInterceptOptions(false)`\nbefore window.onload occurs.  Values other than `false` will be used as the options argument to\nthe default interceptor.\n\nThe link interceptor will not take any action if `event.preventDefault()` has already\nbeen run by another listener.\n\n### window.onpopstate\n\nThis event should be ignored, monitor the `update` event of `historyState` instead.\n\n\n[npm-image]: https://img.shields.io/npm/v/@cfware/history-state.svg\n[npm-url]: https://npmjs.org/package/@cfware/history-state\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfware%2Fhistory-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcfware%2Fhistory-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfware%2Fhistory-state/lists"}