{"id":15428392,"url":"https://github.com/egust/xml-plus","last_synced_at":"2025-04-19T16:05:53.470Z","repository":{"id":40943858,"uuid":"161951952","full_name":"eGust/xml-plus","owner":"eGust","description":"Chrome Extension to display XML files","archived":false,"fork":false,"pushed_at":"2022-12-10T20:39:50.000Z","size":3708,"stargazers_count":15,"open_issues_count":30,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-28T21:35:44.427Z","etag":null,"topics":["chrome-extension","vue","vue-cli","vuejs2","xml"],"latest_commit_sha":null,"homepage":null,"language":"Vue","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/eGust.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-15T23:28:32.000Z","updated_at":"2024-03-22T22:12:53.000Z","dependencies_parsed_at":"2023-01-26T09:00:13.468Z","dependency_job_id":null,"html_url":"https://github.com/eGust/xml-plus","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eGust%2Fxml-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eGust%2Fxml-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eGust%2Fxml-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eGust%2Fxml-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eGust","download_url":"https://codeload.github.com/eGust/xml-plus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228419510,"owners_count":17916772,"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":["chrome-extension","vue","vue-cli","vuejs2","xml"],"created_at":"2024-10-01T18:04:29.088Z","updated_at":"2024-12-06T06:11:54.600Z","avatar_url":"https://github.com/eGust.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# XML Plus\n\nChrome Extension to display XML files built with Vue\n\n## Features\n\n1. Supports both `CSS` and `XPath` selectors.\n2. Supports text search and `Regular Expression` search.\n3. Both `querySelectorAll` and `jQuery` flavors of CSS selectors are available.\n4. `RegEx` is the only **CASE-INSENSITIVE** one.\n5. Highly optimized for large XML files ( \u003e 1MB ).\n6. Stand-alone version - extremely fast because of avoiding Chrome's slow loading process.\n7. Global `x` variable (`window.x`) is available in DevTools which includes:\n    * `doc` - raw XML document object\n    * `root` - root XML element object\n    * `cur` - current selected node\n    * `$` - jQuery bound on root element\n    * `history` - search results\n    * `$q` - helper for jQuery search\n    * `cs` - helper for CSS search\n    * `re` - helper for RegEx search\n    * `tx` - helper for Text search\n    * `xp` - helper for XPath search\n\n    \u003e Above helpers are `(expression, baseElement = root) =\u003e []` and searching on `baseElement` which is `x.root` by default.\n\n### Links\n\n* [Online Demo](https://sad-fermi-5b5e4f.netlify.com/) - Remote links are very **UNLIKELY** working due to [same-origin policy](https://developer.mozilla.org/docs/Web/Security/Same-origin_policy). Local files should be fine.\n* [Github Repo](https://github.com/eGust/xml-plus)\n* [Report Bug](https://github.com/eGust/xml-plus/issues)\n* [Chrome Extension](https://chrome.google.com/webstore/detail/xml-plus/jmhicemblbmkcbonbhkjmflehkmkiidj)\n\n## TO-DOs\n\n* [ ] Add some themes\n* [ ] Able to customize CSS\n* [ ] More optimization\n\n---\n\n## Development\n\n## Libraries and techs used\n\n1. `Vue`\n2. `Vuex`\n3. `lodash/debounce`\n4. `jQuery`\n5. `document.querySelectorAll`\n6. `document.evaluate` for `XPath`\n7. `bestzip` for packaging\n\n### Dev Mode\n\n1. `yarn dev` or `npm run dev`\n2. Open `http://localhost:8080/` to start debugging.\n3. Folder `tests/` will be served at the same time with CORS, so `http://localhost:8080/xml/default.xml` is available.\n\n### Test as Chrome Extension\n\n1. `yarn watch` or `npm run watch`\n2. Drag and drop `dist` folder into Chrome's Extensions page\n\n### Build Static Website\n\n`yarn website` or `npm run website`\n\n\u003e Target folder is `public`\n\n\u003cdetails\u003e\u003csummary\u003eAdvanced\u003c/summary\u003e\n\n#### Proxy\n\n You can also pass `PROXY` env variable to enable proxy. For example,\n\n```bash\nPROXY=\"https://my.proxy/get?url=\" yarn website\n```\n\nWhen fetching `https://foo.bar/baz.xml`, it will get `https://my.proxy/get?url=https%3A%2F%2Ffoo.bar%2Fbaz.xml` instead. You can implement your own proxy with [CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS).\n\nThere is an example for [webtask](https://webtask.io):\n\n```js\nconst zlib = require('zlib');\nconst fetch = require('node-fetch'); // 3rd-party\n\nmodule.exports = async (context, req, res) =\u003e {\n  const { url } = context.query;\n  if (!url) {\n    res.writeHead(400, { 'Content-Type': 'text/plain'});\n    res.end('Required query string `url`');\n    return;\n  }\n\n  try {\n    const response = await fetch(url);\n    const { headers } = response;\n    Array.from(headers.keys()).forEach((key) =\u003e {\n      if (key === 'content-type') {\n        res.setHeader('Content-Type', headers.get(key));\n      }\n    });\n\n    res.writeHead(response.status, {\n      'Access-Control-Allow-Origin': '*', // IMPORTANT: enables CORS. You can restrict it to your own domain names.\n      'Content-Encoding': 'deflate',\n      'Cache-Control': 'max-age=3600',\n    });\n\n    zlib.deflate(await response.buffer(), (err, buff) =\u003e {\n      if (err) throw err;\n      res.end(buff);\n    });\n  } catch (err) {\n    res.writeHead(500, { 'Content-Type': 'text/plain' });\n    res.end(err.message);\n  }\n};\n```\n\n\u003c/details\u003e\n\n### Chrome Extension\n\n* `yarn watch` or `npm run watch` to build dev in `dist` folder\n* `yarn build` or `npm run build` to build prod version\n* `yarn deploy` or `npm run deploy` will build and get `deploy/xml-plus.zip` ready for Chrome store\n\n---\n\n\u003cdetails\u003e\u003csummary\u003eOthers\u003c/summary\u003e\n\n## Benchmarks\n\n### Candidates\n\n1. Chrome - the browser itself\n2. `** * *** ****` - Another Extension available on Chrome Store and open-sourced on Github. Will use `X` to represent it.\n3. XML Plus\n\n### Method\n\n1. Serve XML files on localhost\n2. Open Chrome Developer Tools\n3. Turn-on/off Extension to test\n4. Kill the tab in Chrome Task Manager to avoid memory operation\n5. Empty Cache and Hard Reload XML file via local network\n6. Repeat step 4 to 5 and skip the first read.\n\n\u003e Since Extension `X` needs more time to render the page, I put some extra code to calculate real time. The code is something like:\n\n    ```js\n    document.addEventListener('readystatechange', function() {\n      console.time('ready');\n      // ... main code\n    });\n\n    // Inside another function\n    function xxx() {\n      sendMessage(..., function () {\n        // ...\n        sendMessage(..., function () {\n          // ... it will generate DOM here\n          setTimeout(() =\u003e {\n            console.timeEnd('ready');\n          }, 0);\n        });\n      });\n    }\n    ```\n\n### Results\n\n1. Round 1: 2MiB XML file (Total 41248 nodes; Max Depth: 5)\n    * Chrome: 14.55s, 14.34s, 15.19s\n    * X: 3.54s + 1141ms, 3.46s + 738ms, 2.94s + 898ms\n    * XML Plus: 4.12s, 3.89s. 4.18s\n\n2. Round 2: 5.2MiB XML file (Total 113126 nodes; Max Depth: 4)\n    * Chrome: 34.10s, 34.82s, 33.9s (7.7s~8.0s `DOMContentLoaded`)\n    * X: 8.50s + 3968ms, 8.74s + 3976ms, 8.44s + 3965ms (7.7s~8.0s `DOMContentLoaded`)\n    * XML Plus: 7.32s, 7.30s, 7.50s (4.8s~5.0s `DOMContentLoaded`)\n\n3. Round 3: 14.4MiB XML file (Total 307067 nodes; Max Depth: 4)\n    * Chrome: 3.2min (~42s `DOMContentLoaded`)\n    * X: 43.72s + 17449ms (~42s `DOMContentLoaded`)\n    * XML Plus: 22.32s, 24.01s, 22.04s (13.6s~15.8s `DOMContentLoaded`)\n\n* Some Conclusions:\n    1. `DOMContentLoaded` is not avoidable.\n    2. `text/xml` and `application/xml` take much longer time than `text/plain` which I used. If you know a better way to make Chrome avoid rendering while processing responses, please let me know!\n    3. Chrome will take 1.1min+ If you don't End Process in Task Manager. It will take much longer if the tab used too much memory.\n    4. In Round 2 you can see the styles of X will be applied after `ready`, while in Round 3 it took 7s+ to apply styles.\n\n### Environment\n\n```text\nWindows 10 1803 x64\nIntel i7-6700K\n32G RAM\nChrome v71.0.3578.98 x64\n```\n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegust%2Fxml-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegust%2Fxml-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegust%2Fxml-plus/lists"}