Full Code of juliangruber/is-mobile for AI

main e26c091f26d7 cached
11 files
10.2 KB
3.2k tokens
4 symbols
1 requests
Download .txt
Repository: juliangruber/is-mobile
Branch: main
Commit: e26c091f26d7
Files: 11
Total size: 10.2 KB

Directory structure:
gitextract_y105b012/

├── .github/
│   ├── FUNDING.yml
│   └── SECURITY.md
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── package.json
├── tea.yaml
└── test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: juliangruber
patreon: juliangruber
custom: "https://paypal.me/julianpetergruber"

================================================
FILE: .github/SECURITY.md
================================================
## Security contact information

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

================================================
FILE: .gitignore
================================================
node_modules


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - "node"


================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================

# is-mobile

Check if mobile browser, based on useragent string.

[![Build Status](https://travis-ci.org/juliangruber/is-mobile.svg?branch=master)](https://travis-ci.org/juliangruber/is-mobile)

## Example

```js
var mobile = require('is-mobile');

console.log(mobile());
// => false
```

## API

### mobile({ [ua], [tablet], [featureDetect] })

Returns true if a mobile browser is being used.

If you don't specify `opts.ua` it will use `navigator.userAgent`.

To add support for tablets, set `tablet: true`.

To enable feature detection (i.e. namely for iPad with iOS 13), set `featureDetect: true` and `tablet: true`. This will only work in browser environments.

`opts.ua` can also be an instance of a [node.js http request](http://nodejs.org/api/http.html#http_http_incomingmessage), in which
case it will read the user agent header.

Example:

```js
var http = require('http');
var mobile = require('is-mobile');

var server = http.createServer(function (req, res) {
  res.end(mobile({ ua: req }));
});

server.listen(8000);
```

## Installation

With [npm](https://npmjs.org) do:

```bash
npm install is-mobile
```

Bundle for the browser with
[browserify](https://github.com/substack/node-browserify).

## Kudos

Taken from [detectmobilebrowsers.com](http://detectmobilebrowsers.com/).

Armv7l support added by [@antongolub](https://github.com/antongolub).

## License

(MIT)

Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: index.d.ts
================================================
interface HttpRequestHeadersInterfaceMock {
    [id: string]: string | string[] | undefined
}

interface HttpRequestInterfaceMock {
    headers: HttpRequestHeadersInterfaceMock,

    [id: string]: any,
}

export interface IsMobileOptions
{
    ua?: string | HttpRequestInterfaceMock
    tablet?: boolean
    featureDetect?: boolean
}

export declare function isMobile(opts?:IsMobileOptions): boolean;
export default isMobile;


================================================
FILE: index.js
================================================
'use strict'

module.exports = isMobile
module.exports.isMobile = isMobile
module.exports.default = isMobile

const mobileRE = /(android|bb\d+|meego).+mobile|armv7l|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|redmi|series[46]0|samsungbrowser.*mobile|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i
const notMobileRE = /CrOS/

const tabletRE = /android|ipad|playbook|silk/i

function isMobile (opts) {
  if (!opts) opts = {}
  let ua = opts.ua
  if (!ua && typeof navigator !== 'undefined') ua = navigator.userAgent
  if (ua && ua.headers && typeof ua.headers['user-agent'] === 'string') {
    ua = ua.headers['user-agent']
  }
  if (typeof ua !== 'string') return false

  let result =
    (mobileRE.test(ua) && !notMobileRE.test(ua)) ||
    (!!opts.tablet && tabletRE.test(ua))

  if (
    !result &&
    opts.tablet &&
    opts.featureDetect &&
    navigator &&
    navigator.maxTouchPoints > 1 &&
    ua.indexOf('Macintosh') !== -1 &&
    ua.indexOf('Safari') !== -1
  ) {
    result = true
  }

  return result
}


================================================
FILE: package.json
================================================
{
  "name": "is-mobile",
  "description": "Check if mobile browser.",
  "version": "5.0.0",
  "repository": {
    "type": "git",
    "url": "git://github.com/juliangruber/is-mobile.git"
  },
  "homepage": "https://github.com/juliangruber/is-mobile",
  "main": "index.js",
  "types": "index.d.ts",
  "scripts": {
    "release": "np",
    "test": "prettier-standard '**/*.js' && standard && npm run test:unit",
    "test:unit": "node--test"
  },
  "devDependencies": {
    "np": "^8.0.4",
    "prettier-standard": "^16.4.1",
    "standard": "^16.0.4",
    "test": "^3.0.0",
    "user-agents": "^1.0.845"
  },
  "keywords": [
    "mobile",
    "desktop",
    "check",
    "browser"
  ],
  "author": {
    "name": "Julian Gruber",
    "email": "julian@juliangruber.com",
    "url": "http://juliangruber.com"
  },
  "license": "MIT"
}


================================================
FILE: tea.yaml
================================================
# https://tea.xyz/what-is-this-file
---
version: 1.0.0
codeOwners:
  - '0xE7DEE1B8Bb97C3065850Cf582D6DED57C6009587'
quorum: 1


================================================
FILE: test.js
================================================
'use strict'

const assert = require('assert')
const test = require('test')
const UserAgent = require('user-agents')
const isMobile = require('./')

const iphone =
  'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3'
const chrome =
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36'
const ffos = 'Mozilla/5.0 (Mobile; rv:18.0) Gecko/18.0 Firefox/18.0'
const ipad =
  'Mozilla/5.0 (iPad; CPU OS 9_3_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13F69 Safari/601.1'
const ios13ipad =
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
const ios13ipadpro =
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15'
const samsung =
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/16.0 Chrome/92.0.4515.166 Safari/537.36'
const samsungMobile =
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/16.0 Chrome/92.0.4515.166 Mobile Safari/537.36'
const chromeOS =
  'Mozilla/5.0 (X11; CrOS armv7l 12105.100.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.144 Safari/537.36'
const redmiMobile =
  'HashKey/1.20.0 (Redmi K30; Android ) Language/zh Theme/light ScreenWidth/392 ScreenHeight/856'

test('is mobile', function () {
  assert(isMobile({ ua: iphone }))
  assert(isMobile({ ua: ffos }))
  assert(!isMobile({ ua: ipad }))
  assert(isMobile({ ua: ipad, tablet: true }))
  assert(isMobile({ ua: { headers: { 'user-agent': iphone } } }))
  assert(!isMobile({ ua: chrome }))
  assert(!isMobile({ ua: { headers: { 'user-agent': chrome } } }))
  assert(!isMobile())
  assert(!isMobile({ ua: { headers: null } }))
  assert(!isMobile({ ua: { headers: { 'user-agent': null } } }))
  assert(!isMobile({ ua: samsung }))
  assert(isMobile({ ua: samsungMobile }))
  assert(isMobile({ ua: redmiMobile }))
  assert(!isMobile(chromeOS))
  assert(!isMobile(chromeOS, { tablet: true }))

  global.navigator = {}

  global.navigator.userAgent = iphone
  assert(isMobile())
  assert(isMobile({ tablet: true }))

  global.navigator.userAgent = chrome
  assert(!isMobile())
  assert(!isMobile({ tablet: true }))

  global.navigator.userAgent = ipad
  assert(!isMobile())
  assert(isMobile({ tablet: true }))

  global.navigator = { maxTouchPoints: 5 }
  assert(isMobile({ ua: ios13ipad, tablet: true, featureDetect: true }))
  assert(isMobile({ ua: ios13ipadpro, tablet: true, featureDetect: true }))
})

test('ua-bruteforce', function () {
  const limit = 300
  const checks = [
    { deviceCategory: 'mobile', result: true },
    { deviceCategory: 'tablet', result: true, tablet: true },
    { deviceCategory: 'desktop', result: false }
  ]
  const testCases = checks.reduce(
    (cases, { deviceCategory, result, tablet }) => {
      // The same user-agent string belongs to both `desktop` and `mobile` type entries. No chance to detect `deviceType` properly.
      // https://github.com/intoli/user-agents/blob/867e318bc00880ae00437e5e8efaa8e5e7ac0696/src/user-agents.json.gz
      // user-agents v1.0.843
      const exclude =
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
      const ua = new UserAgent([
        ({ userAgent }) => userAgent !== exclude,
        { deviceCategory }
      ])

      return [
        ...cases,
        ...new Array(limit).fill().map(() => ({
          ua: ua.random().toString(),
          result,
          tablet
        }))
      ]
    },
    []
  )

  testCases.forEach(({ ua, result, tablet }) => {
    test(ua, () => {
      assert.strictEqual(isMobile({ ua, tablet }), result)
    })
  })
})
Download .txt
gitextract_y105b012/

├── .github/
│   ├── FUNDING.yml
│   └── SECURITY.md
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── package.json
├── tea.yaml
└── test.js
Download .txt
SYMBOL INDEX (4 symbols across 2 files)

FILE: index.d.ts
  type HttpRequestHeadersInterfaceMock (line 1) | interface HttpRequestHeadersInterfaceMock {
  type HttpRequestInterfaceMock (line 5) | interface HttpRequestInterfaceMock {
  type IsMobileOptions (line 11) | interface IsMobileOptions

FILE: index.js
  function isMobile (line 12) | function isMobile (opts) {
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (11K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 88,
    "preview": "github: juliangruber\npatreon: juliangruber\ncustom: \"https://paypal.me/julianpetergruber\""
  },
  {
    "path": ".github/SECURITY.md",
    "chars": 192,
    "preview": "## Security contact information\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://"
  },
  {
    "path": ".gitignore",
    "chars": 13,
    "preview": "node_modules\n"
  },
  {
    "path": ".travis.yml",
    "chars": 38,
    "preview": "language: node_js\nnode_js:\n  - \"node\"\n"
  },
  {
    "path": "LICENSE",
    "chars": 1105,
    "preview": "The MIT License (MIT)\nCopyright (c) 2013 Julian Gruber <julian@juliangruber.com>\n\nPermission is hereby granted, free of "
  },
  {
    "path": "README.md",
    "chars": 2475,
    "preview": "\n# is-mobile\n\nCheck if mobile browser, based on useragent string.\n\n[![Build Status](https://travis-ci.org/juliangruber/i"
  },
  {
    "path": "index.d.ts",
    "chars": 426,
    "preview": "interface HttpRequestHeadersInterfaceMock {\n    [id: string]: string | string[] | undefined\n}\n\ninterface HttpRequestInte"
  },
  {
    "path": "index.js",
    "chars": 1204,
    "preview": "'use strict'\n\nmodule.exports = isMobile\nmodule.exports.isMobile = isMobile\nmodule.exports.default = isMobile\n\nconst mobi"
  },
  {
    "path": "package.json",
    "chars": 830,
    "preview": "{\n  \"name\": \"is-mobile\",\n  \"description\": \"Check if mobile browser.\",\n  \"version\": \"5.0.0\",\n  \"repository\": {\n    \"type\""
  },
  {
    "path": "tea.yaml",
    "chars": 126,
    "preview": "# https://tea.xyz/what-is-this-file\n---\nversion: 1.0.0\ncodeOwners:\n  - '0xE7DEE1B8Bb97C3065850Cf582D6DED57C6009587'\nquor"
  },
  {
    "path": "test.js",
    "chars": 3916,
    "preview": "'use strict'\n\nconst assert = require('assert')\nconst test = require('test')\nconst UserAgent = require('user-agents')\ncon"
  }
]

About this extraction

This page contains the full source code of the juliangruber/is-mobile GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (10.2 KB), approximately 3.2k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!