Full Code of edwinm/carbonium for AI

master e6fa92369015 cached
22 files
47.2 KB
12.6k tokens
25 symbols
1 requests
Download .txt
Repository: edwinm/carbonium
Branch: master
Commit: e6fa92369015
Files: 22
Total size: 47.2 KB

Directory structure:
gitextract_aeet774x/

├── .github/
│   └── workflows/
│       ├── codeql.yml
│       ├── coveralls.yml
│       └── scorecard.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .prettierignore
├── .prettierrc.json
├── LICENSE
├── README.md
├── demo/
│   ├── demo.js
│   └── index.html
├── dist/
│   ├── bundle.js
│   ├── carbonium.d.ts
│   └── src/
│       └── carbonium.d.ts
├── eslint.config.js
├── package.json
├── playwright.config.ts
├── rollup.config.js
├── src/
│   └── carbonium.ts
├── test/
│   └── test.ts
├── tests/
│   └── carbonium.spec.ts
└── tsconfig.json

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

================================================
FILE: .github/workflows/codeql.yml
================================================
name: "CodeQL"

on:
  push:
    branches: ["master"]
  pull_request:
    branches: ["master"]
  schedule:
    - cron: "11 3 * * 3"

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [javascript]

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: +security-and-quality

      - name: Autobuild
        uses: github/codeql-action/autobuild@v3

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"


================================================
FILE: .github/workflows/coveralls.yml
================================================
name: Coveralls

on: ["push", "pull_request"]

jobs:
  test:
    name: Run units tests
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
      - name: Install
        run: npm install
      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium firefox
      - name: Lint
        run: npm run lint
      - name: Test
        run: npm test


================================================
FILE: .github/workflows/scorecard.yml
================================================
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.

name: Scorecard supply-chain security
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: "38 20 * * 1"
  push:
    branches: ["master"]

# Declare default permissions as read only.
permissions:
  contents: read
  actions: read

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write
      contents: read
      actions: read

    steps:
      - name: "Checkout code"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
        with:
          results_file: results.sarif
          results_format: sarif
          repo_token: ${{ secrets.GITHUB_TOKEN }}

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories:
          #   - `publish_results` will always be set to `false`, regardless
          #     of the value entered here.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
        with:
          name: sarif-results
          path: results.sarif
          retention-days: 5

      # Upload the results to GitHub's code scanning dashboard (optional).
      # Commenting out will disable upload of results to your repo's Code Scanning dashboard
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif


================================================
FILE: .gitignore
================================================
node_modules
coverage
.idea
/playwright-report/


================================================
FILE: .husky/pre-commit
================================================
npx pretty-quick --staged
npm run lint


================================================
FILE: .prettierignore
================================================
dist


================================================
FILE: .prettierrc.json
================================================
{
  "trailingComma": "es5",
  "arrowParens": "always"
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Edwin Martin

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
================================================
[![Scorecard supply-chain security](https://github.com/edwinm/carbonium/actions/workflows/scorecard.yml/badge.svg)](https://github.com/edwinm/carbonium/actions/workflows/scorecard.yml) [![CodeQL](https://github.com/edwinm/carbonium/actions/workflows/codeql.yml/badge.svg)](https://github.com/edwinm/carbonium/actions/workflows/codeql.yml) [![Coverage Status](https://coveralls.io/repos/github/edwinm/carbonium/badge.svg?branch=master)](https://coveralls.io/github/edwinm/carbonium?branch=master) [![Socket Badge](https://socket.dev/api/badge/npm/package/carbonium)](https://socket.dev/npm/package/carbonium) [![CodeFactor](https://www.codefactor.io/repository/github/edwinm/carbonium/badge)](https://www.codefactor.io/repository/github/edwinm/carbonium) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=edwinm_carbonium&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=edwinm_carbonium) [![Snyk test results](https://snyk.io/test/github/edwinm/carbonium/badge.svg)](https://snyk.io/test/github/edwinm/carbonium) [![Size](https://badgen.net/bundlephobia/minzip/carbonium)](https://bundlephobia.com/package/carbonium) [![npm version](https://badge.fury.io/js/carbonium.svg)](https://www.npmjs.com/package/carbonium) [![GitHub](https://img.shields.io/github/license/edwinm/carbonium.svg)](https://github.com/edwinm/carbonium/blob/master/LICENSE) ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/edwinm/carbonium?utm_source=oss&utm_medium=github&utm_campaign=edwinm%2Fcarbonium&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews)

[![Carbonium](https://raw.githubusercontent.com/edwinm/carbonium/master/assets/carbonium.svg)](#readme)

> One kilobyte library for easy DOM manipulation

With carbonium, you can call `$(selector)` and the result can be accessed as both an DOM element and an array of matched elements.
DOM element operations are applied to all matched elements.

## Examples

To set the `left` CSS property of all elements with the class `indent` to 40 pixels:

```javascript
$(".indent").style.left = "40px";
```

To add the class `important` to all div's with "priority" as content:

```javascript
$("div")
  .filter((el) => el.textContent == "priority")
  .classList.add("important");
```

You can use carbonium to create elements:

```javascript
const error = $("<div class='error'>An error has occured!</div>")[0];
```

## Installation

```bash
npm install --save-dev carbonium
```

Now you can import carbonium:

```javascript
import { $ } from "carbonium";
```

If you don't want to install or use a bundler like webpack or rollup.js, you can import carbonium like this:

```javascript
const { $ } = await import(
  "https://cdn.jsdelivr.net/npm/carbonium@1/dist/bundle.min.js"
);
```

## API

### Select elements

### `$(selector [, parentNode])`

#### Parameters

| Name       | Type                           | Description                                                                |
| ---------- | ------------------------------ | -------------------------------------------------------------------------- |
| selector   | string                         | Selector to select elements                                                |
| parentNode | Document \| Element (optional) | Document or element in which to apply the selector, defaults to `document` |

#### Returns

An array of the matched elements, which can also be accessed as a single element.

### Create element

### `$(html [, parentNode])`

#### Parameters

| Name       | Type                           | Description                                                                |
| ---------- | ------------------------------ | -------------------------------------------------------------------------- |
| html       | string                         | HTML of element to create, starting with "<"                               |
| parentNode | Document \| Element (optional) | Document or element in which to apply the selector, defaults to `document` |

#### Returns

An array with one created element.

## TypeScript

If you use TypeScript, it's good to know Carbonium is written in TypeScript and provides all typings.
You can use generics to declare a specific type of element,
for example `HTMLInputElement` to make the `disabled` property available:

```typescript
$<HTMLInputElement>("input, select, button").disabled = true;
```

## Why?

You might find most frameworks are quite bulky and bad for performance ([1](https://css-tricks.com/radeventlistener-a-tale-of-client-side-framework-performance/)).
On the other side, you might find using native DOM and writing `document.querySelectorAll(selector)` each time you want to do some DOM operations to become tedious.
You can write your own helper function, but that only takes part of the pain away.

Carbonium seeks to find the sweet spot between using a framework and using the native DOM.

## jQuery

Isn't this just jQuery and isn't that obsolete and bad practice?

No. Carbonium doesn't have the disadvantages of jQuery:

1. Carbonium is very small: just around one kilobyte.
2. There's no new API to learn, carbonium provides only standard DOM API's.

## Browser support

Carbonium is supported by all modern browsers. It is tested to work on desktop and mobile with Firefox 79, Chrome 84, Safari 13 and Edge 84.
It should work with all browsers supporting Proxy, see [Can I use Proxy](https://caniuse.com/#feat=proxy) for support tables.

## Name

[<img src="https://raw.githubusercontent.com/edwinm/carbonium/master/assets/Diamond_and_graphite.jpg" align="right"
     alt="Photo of diamond and graphite" width="178" height="120">](https://commons.wikimedia.org/wiki/File:Diamond_and_graphite_without_structures.jpg)

Carbonium is the Latin name for carbon. Carbon has two forms (allotropes): graphite and diamond.
Just like this library, in which the result presents itself both as one element and as a list of elements.

[Photo CC BY-SA 3.0](https://commons.wikimedia.org/wiki/File:Diamond_and_graphite_without_structures.jpg)

## License

Copyright 2023 [Edwin Martin](https://bitstorm.org/) and released under the MIT license.


================================================
FILE: demo/demo.js
================================================
const importPromise = import(
  "https://cdn.jsdelivr.net/npm/carbonium/dist/bundle.min.js"
);

const loadPromise = new Promise((resolve) => {
  document.addEventListener("DOMContentLoaded", resolve);
});

// Start code when both carbonium and the page are loaded
Promise.all([importPromise, loadPromise]).then(([{ $ }]) => {
  $("#out").innerText = "Demo.";
  $("#hello-button").addEventListener("click", () => {
    $("#out").innerText = "Hello. It is working!";
  });
});


================================================
FILE: demo/index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Demo</title>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1"
    />
    <script src="demo.js"></script>
  </head>
  <body>
    <h1>Demo</h1>

    <div id="out">…</div>

    <button id="hello-button">Say hello</button>
  </body>
</html>


================================================
FILE: dist/bundle.js
================================================
/**
 Carbonium 1.3.0
 @copyright 2020 Edwin Martin
 @license MIT
 */
function $(selectors, parentNode) {
    let nodelist;
    // If the first parameter starts with "<", create a DOM node
    if (selectors.startsWith("<")) {
        nodelist = [
            new DOMParser().parseFromString(selectors, "text/html").body.firstChild,
        ];
    }
    else {
        // Else, do querySelectorAll
        nodelist = (parentNode || document).querySelectorAll(selectors);
    }
    // Wrap it in a Proxy
    return new Proxy(nodelist, proxyHandler);
}
// Used by style, classList and relList
// When setting one of these, remember the elements to apply to
let currentListNodelist;
let propList;
const proxyHandler = {
    get(target, prop) {
        let propValue = null;
        // Return iterator when asked for iterator, only used in ES2015+
        if (prop == Symbol.iterator) {
            return function* () {
                for (const element of target) {
                    yield element;
                }
            };
        }
        // Special case for style, classList and relList
        if (prop == "style" || prop == "classList" || prop == "relList") {
            currentListNodelist = target;
            propList = prop;
            // Matched elements can be a list of any element or an empty list
            // Use getter of, for example, document.body.style
            const propValue = Reflect.get(document.body, prop);
            return new Proxy(propValue, proxyHandler);
        }
        // style.setProperty, getPropertyValue…, classList.add, contains, remove…, relList…
        if (target instanceof CSSStyleDeclaration ||
            target instanceof DOMTokenList) {
            // Matched elements can be a list of any element or an empty list
            // Use getter of, for example, document.body.style.color
            propValue = Reflect.get(document.body[propList], prop);
            // When getter is a function, apply it to all matched elements
            if (typeof propValue == "function") {
                return new Proxy(propValue, {
                    apply: function (target, thisArg, argumentsList) {
                        currentListNodelist.forEach((el) => {
                            Reflect.apply(target, el[propList], argumentsList);
                        });
                        return new Proxy(currentListNodelist, proxyHandler);
                    },
                });
            }
            else {
                return propValue;
            }
        }
        // Are we dealing with an Array function like forEach, map and filter?
        if (Array.prototype.hasOwnProperty(prop)) {
            const propValue = Reflect.get(Array.prototype, prop);
            if (typeof propValue == "function") {
                return new Proxy(propValue, {
                    apply: function (target, thisArg, argumentsList) {
                        const ret = Reflect.apply(target, thisArg, argumentsList);
                        // When function returns undefined (like forEach),
                        // return all matched elements, so calls can be chained
                        // For example forEach(…).setAttribute(…)
                        const newTarget = typeof ret != "undefined" ? ret : thisArg;
                        return new Proxy(newTarget, proxyHandler);
                    },
                });
            }
        }
        // Get property or call function on DOM elements
        if (target.length > 0) {
            // Might be DOM element specific, like input.select(),
            // so use first array element to get reference
            if (prop in target[0]) {
                propValue = Reflect.get(target[0], prop);
            }
        }
        else {
            // Empty list, targeted DOM element unknown,
            // use getter of document.body
            if (prop in document.body) {
                propValue = Reflect.get(document.body, prop);
            }
        }
        // Propagate DOM prop value
        if (propValue) {
            if (typeof propValue == "function") {
                return new Proxy(propValue, {
                    apply: function (target, thisArg, argumentsList) {
                        let retFirst = null;
                        let first = true;
                        // Apply on individual elements
                        for (const el of thisArg) {
                            const ret = Reflect.apply(target, el, argumentsList);
                            if (first) {
                                retFirst = ret;
                                first = false;
                            }
                        }
                        return retFirst !== null && retFirst !== void 0 ? retFirst : thisArg;
                    },
                });
            }
            else {
                return propValue;
            }
        }
        // Default
        return Reflect.get(target, prop);
    },
    // DOM property is set
    set(target, prop, value) {
        if ("forEach" in target && !(target instanceof CSSStyleDeclaration)) {
            target.forEach((el) => {
                Reflect.set(el, prop, value);
            });
        }
        else {
            Reflect.set(target, prop, value);
        }
        return true;
    },
    deleteProperty(target, prop) {
        if (prop in target) {
            return delete target[prop];
        }
        return false;
    },
};

export { $ };
//# sourceMappingURL=bundle.js.map


================================================
FILE: dist/carbonium.d.ts
================================================
/**
 Carbonium __buildVersion__
 @copyright 2020 Edwin Martin
 @license MIT
 */
export declare function $<T extends HTMLElement = HTMLElement>(selectors: string, parentNode?: Document | ShadowRoot | HTMLElement): CarboniumType<T>;
export type CarboniumType<T extends HTMLElement = HTMLElement> = CarboniumList<T> & T;
interface CarboniumList<T extends HTMLElement> extends Array<T> {
    concat(...items: ConcatArray<T>[]): CarboniumType<T>;
    concat(...items: (T | ConcatArray<T>)[]): CarboniumType<T>;
    reverse(): CarboniumType<T>;
    slice(start?: number, end?: number): CarboniumType<T>;
    splice(start: number, deleteCount?: number): CarboniumType<T>;
    splice(start: number, deleteCount: number, ...items: T[]): CarboniumType<T>;
    forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): CarboniumType<T>;
    filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): CarboniumType<T>;
    setAttribute(qualifiedName: string, value: string): CarboniumType<T>;
    classList: CarboniumClassList<T>;
    style: CarboniumStyleList<T>;
}
interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
    add(...tokens: string[]): CarboniumType<T>;
    remove(...tokens: string[]): CarboniumType<T>;
    replace(oldToken: string, newToken: string): boolean;
    forEach(callbackfn: (value: string, key: number, parent: DOMTokenList) => void, thisArg?: any): CarboniumType<T>;
}
interface CarboniumStyleList<T extends HTMLElement> extends CSSStyleDeclaration {
    removeProperty(property: string): CarboniumList<T> & string;
    setProperty(property: string, value: string | null, priority?: string): CarboniumType<T>;
}
export {};


================================================
FILE: dist/src/carbonium.d.ts
================================================
/**
 Carbonium __buildVersion__
 @copyright 2020 Edwin Martin
 @license MIT
 */
export declare function $<T extends HTMLElement = HTMLElement>(selectors: string, parentNode?: Document | ShadowRoot | HTMLElement): CarboniumType<T>;
export type CarboniumType<T extends HTMLElement = HTMLElement> = CarboniumList<T> & T;
interface CarboniumList<T extends HTMLElement> extends Array<T> {
    concat(...items: ConcatArray<T>[]): CarboniumType<T>;
    concat(...items: (T | ConcatArray<T>)[]): CarboniumType<T>;
    reverse(): CarboniumType<T>;
    slice(start?: number, end?: number): CarboniumType<T>;
    splice(start: number, deleteCount?: number): CarboniumType<T>;
    splice(start: number, deleteCount: number, ...items: T[]): CarboniumType<T>;
    forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): CarboniumType<T>;
    filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): CarboniumType<T>;
    setAttribute(qualifiedName: string, value: string): CarboniumType<T>;
    classList: CarboniumClassList<T>;
    style: CarboniumStyleList<T>;
}
interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
    add(...tokens: string[]): CarboniumType<T>;
    remove(...tokens: string[]): CarboniumType<T>;
    replace(oldToken: string, newToken: string): boolean;
    forEach(callbackfn: (value: string, key: number, parent: DOMTokenList) => void, thisArg?: any): CarboniumType<T>;
}
interface CarboniumStyleList<T extends HTMLElement> extends CSSStyleDeclaration {
    removeProperty(property: string): CarboniumList<T> & string;
    setProperty(property: string, value: string | null, priority?: string): CarboniumType<T>;
}
export {};


================================================
FILE: eslint.config.js
================================================
import tseslint from "typescript-eslint";
import js from "@eslint/js";
import prettier from "eslint-config-prettier";
import globals from "globals";

export default tseslint.config(
  {
    ignores: [
      "dist/**",
      "demo/**",
      "coverage/**",
      "iteratortest/**",
      "karma.conf.cjs",
    ],
  },
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.es2021,
      },
    },
    rules: {
      "no-prototype-builtins": "off",
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-unsafe-function-type": "off",
    },
  },
  prettier
);


================================================
FILE: package.json
================================================
{
  "name": "carbonium",
  "version": "1.3.0",
  "description": "One kilobyte library for easy DOM manipulation",
  "type": "module",
  "browser": "dist/bundle.iife.min.js",
  "module": "dist/bundle.min.js",
  "types": "dist/carbonium.d.ts",
  "sideEffects": false,
  "scripts": {
    "prepare": "husky",
    "start": "http-server -o demo/ --silent",
    "build": "rollup --config --sourcemap",
    "dev": "rollup --config --sourcemap --watch",
    "release": "npm i --package-lock && npm run lint && npm test && npm publish",
    "pretest": "npm run build",
    "test": "playwright test",
    "lint": "npx eslint .",
    "prettier": "prettier --config .prettierrc.json src/**/*.ts *.json --write"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/edwinm/carbonium.git"
  },
  "files": [
    "src/carbonium.ts",
    "dist/carbonium.d.ts",
    "dist/bundle.min.js",
    "dist/bundle.min.js.map",
    "dist/bundle.iife.min.js",
    "dist/bundle.iife.min.js.map"
  ],
  "keywords": [
    "front-end",
    "dom",
    "qsa",
    "jquery",
    "typescript",
    "front-end",
    "lightweight",
    "micro"
  ],
  "author": {
    "name": "Edwin Martin",
    "email": "edwin@bitstorm.org",
    "url": "https://bitstorm.org/"
  },
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/edwinm/carbonium/issues"
  },
  "homepage": "https://github.com/edwinm/carbonium#readme",
  "devDependencies": {
    "@eslint/js": "^9.39.4",
    "@playwright/test": "^1.59.1",
    "@rollup/plugin-replace": "^6.0.3",
    "@rollup/plugin-terser": "^1.0.0",
    "@rollup/plugin-typescript": "^12.3.0",
    "@types/node": "^22.19.17",
    "@typescript-eslint/eslint-plugin": "^8.58.0",
    "@typescript-eslint/parser": "^8.58.0",
    "eslint": "^9.39.4",
    "eslint-config-prettier": "^10.1.8",
    "globals": "^17.4.0",
    "http-server": "^14.1.1",
    "husky": "^9.1.7",
    "prettier": "^3.8.1",
    "pretty-quick": "^4.2.2",
    "rollup": "^4.60.1",
    "tslib": "^2.8.1",
    "typescript": "^6.0.2",
    "typescript-eslint": "^8.58.0"
  }
}


================================================
FILE: playwright.config.ts
================================================
import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./tests",
  fullyParallel: true,
  retries: 0,
  reporter: [["html", { open: "never" }]],
  projects: [
    { name: "chromium", use: { ...devices["Desktop Chrome"] } },
    { name: "firefox", use: { ...devices["Desktop Firefox"] } },
  ],
});


================================================
FILE: rollup.config.js
================================================
import { createRequire } from "module";
import typescript from "@rollup/plugin-typescript";
import terser from "@rollup/plugin-terser";
import replace from "@rollup/plugin-replace";

const require = createRequire(import.meta.url);
const pkg = require("./package.json");

export default {
  input: "src/carbonium.ts",
  output: [
    {
      file: "dist/bundle.min.js",
      format: "es",
      name: "bundle",
      sourcemap: true,
      plugins: [terser()],
    },
    {
      file: "dist/bundle.js",
      format: "es",
      name: "bundle",
      sourcemap: true,
    },
    {
      file: "dist/bundle.iife.min.js",
      format: "iife",
      name: "carbonium",
      sourcemap: true,
      plugins: [terser()],
    },
  ],
  plugins: [
    replace({
      preventAssignment: false,
      __buildVersion__: pkg.version,
    }),
    typescript({ declarationDir: "dist" }),
  ],
};


================================================
FILE: src/carbonium.ts
================================================
/**
 Carbonium __buildVersion__
 @copyright 2020 Edwin Martin
 @license MIT
 */

export function $<T extends HTMLElement = HTMLElement>(
  selectors: string,
  parentNode?: Document | ShadowRoot | HTMLElement
): CarboniumType<T> {
  let nodelist: NodeListOf<T>;

  // If the first parameter starts with "<", create a DOM node
  if (selectors.startsWith("<")) {
    nodelist = <NodeListOf<T>>(
      (<unknown>[
        new DOMParser().parseFromString(selectors, "text/html").body.firstChild,
      ])
    );
  } else {
    // Else, do querySelectorAll
    nodelist = (parentNode || document).querySelectorAll(selectors);
  }

  // Wrap it in a Proxy
  return <CarboniumType<T>>(
    (<unknown>new Proxy<NodeListOf<T>>(nodelist, proxyHandler))
  );
}

// Used by style, classList and relList
// When setting one of these, remember the elements to apply to
let currentListNodelist: NodeListOf<HTMLElement>;
let propList: "style" | "classList" | "relList";

const proxyHandler: ProxyHandler<NodeListOf<HTMLElement>> = {
  get(target, prop) {
    let propValue = null;

    // Return iterator when asked for iterator, only used in ES2015+
    if (prop == Symbol.iterator) {
      return function* () {
        for (const element of target) {
          yield element;
        }
      };
    }

    // Special case for style, classList and relList
    if (prop == "style" || prop == "classList" || prop == "relList") {
      currentListNodelist = target;
      propList = prop;
      // Matched elements can be a list of any element or an empty list
      // Use getter of, for example, document.body.style
      const propValue = Reflect.get(document.body, prop);
      return new Proxy(propValue, proxyHandler);
    }

    // style.setProperty, getPropertyValue…, classList.add, contains, remove…, relList…
    if (
      target instanceof CSSStyleDeclaration ||
      target instanceof DOMTokenList
    ) {
      // Matched elements can be a list of any element or an empty list
      // Use getter of, for example, document.body.style.color
      propValue = Reflect.get((document.body as any)[propList], prop);

      // When getter is a function, apply it to all matched elements
      if (typeof propValue == "function") {
        return new Proxy<Function>(propValue, {
          apply: function (target, thisArg, argumentsList) {
            currentListNodelist.forEach((el) => {
              Reflect.apply(target, (el as any)[propList], argumentsList);
            });
            return new Proxy(currentListNodelist, proxyHandler);
          },
        });
      } else {
        return propValue;
      }
    }

    // Are we dealing with an Array function like forEach, map and filter?
    if (Array.prototype.hasOwnProperty(prop)) {
      const propValue = Reflect.get(Array.prototype, prop);
      if (typeof propValue == "function") {
        return new Proxy<Function>(propValue, {
          apply: function (target, thisArg, argumentsList) {
            const ret = Reflect.apply(target, thisArg, argumentsList);
            // When function returns undefined (like forEach),
            // return all matched elements, so calls can be chained
            // For example forEach(…).setAttribute(…)
            const newTarget = typeof ret != "undefined" ? ret : thisArg;
            return new Proxy(newTarget, proxyHandler);
          },
        });
      }
    }

    // Get property or call function on DOM elements
    if (target.length > 0) {
      // Might be DOM element specific, like input.select(),
      // so use first array element to get reference
      if (prop in target[0]) {
        propValue = Reflect.get(target[0], prop);
      }
    } else {
      // Empty list, targeted DOM element unknown,
      // use getter of document.body
      if (prop in document.body) {
        propValue = Reflect.get(document.body, prop);
      }
    }

    // Propagate DOM prop value
    if (propValue) {
      if (typeof propValue == "function") {
        return new Proxy<Function>(propValue, {
          apply: function (target, thisArg, argumentsList) {
            let retFirst = null;
            let first = true;
            // Apply on individual elements
            for (const el of thisArg) {
              const ret = Reflect.apply(target, el, argumentsList);
              if (first) {
                retFirst = ret;
                first = false;
              }
            }
            return retFirst ?? thisArg;
          },
        });
      } else {
        return propValue;
      }
    }

    // Default
    return Reflect.get(target, prop);
  },

  // DOM property is set
  set(target, prop, value) {
    if ("forEach" in target && !(target instanceof CSSStyleDeclaration)) {
      target.forEach((el) => {
        Reflect.set(el, prop, value);
      });
    } else {
      Reflect.set(target, prop, value);
    }
    return true;
  },

  deleteProperty(target, prop) {
    if (prop in target) {
      return delete (target as any)[prop];
    }
    return false;
  },
};

export type CarboniumType<T extends HTMLElement = HTMLElement> =
  CarboniumList<T> & T;

// Interface definitions

interface CarboniumList<T extends HTMLElement> extends Array<T> {
  concat(...items: ConcatArray<T>[]): CarboniumType<T>;

  concat(...items: (T | ConcatArray<T>)[]): CarboniumType<T>;

  reverse(): CarboniumType<T>;

  slice(start?: number, end?: number): CarboniumType<T>;

  splice(start: number, deleteCount?: number): CarboniumType<T>;

  /* tslint:disable:unified-signatures */
  splice(start: number, deleteCount: number, ...items: T[]): CarboniumType<T>;

  forEach(
    callbackfn: (value: T, index: number, array: T[]) => void,
    thisArg?: any
  ): CarboniumType<T>;

  filter(
    callbackfn: (value: T, index: number, array: T[]) => boolean,
    thisArg?: any
  ): CarboniumType<T>;

  setAttribute(qualifiedName: string, value: string): CarboniumType<T>;

  classList: CarboniumClassList<T>;
  style: CarboniumStyleList<T>;
}

interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
  add(...tokens: string[]): CarboniumType<T>;

  remove(...tokens: string[]): CarboniumType<T>;

  replace(oldToken: string, newToken: string): boolean;

  forEach(
    callbackfn: (value: string, key: number, parent: DOMTokenList) => void,
    thisArg?: any
  ): CarboniumType<T>;
}

interface CarboniumStyleList<
  T extends HTMLElement,
> extends CSSStyleDeclaration {
  removeProperty(property: string): CarboniumList<T> & string;

  setProperty(
    property: string,
    value: string | null,
    priority?: string
  ): CarboniumType<T>;
}


================================================
FILE: test/test.ts
================================================
import * as assert from "assert";
import { $, CarboniumType } from "../src/carbonium";
// TODO: this should work - find out why not
// import { $, CarboniumType } from "../";
import "@webcomponents/webcomponentsjs/custom-elements-es5-adapter";

/**
 * Test framework used:
 * Mocha https://mochajs.org/
 * Assert https://nodejs.org/api/assert.html
 */

describe("$", () => {
  beforeEach(() => {
    document.body.textContent = "";
    for (let i = 0; i < 6; i++) {
      const div = document.createElement("div");
      div.textContent = `item${i}`;
      document.body.appendChild(div);
    }
  });

  it("textContent one element", () => {
    $("div:first-child").textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].textContent, "hello");
  });

  it("textContent one element", () => {
    const div: CarboniumType = $("div:first-child");
    div.textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].textContent, "hello");
  });

  it("textContent all elements", () => {
    $("div").textContent = "hello";
    assert.equal(document.body.textContent, "hellohellohellohellohellohello");
  });

  it("length", () => {
    assert.equal($("div").length, 6);
  });

  it("forEach", () => {
    const divs = $("div");
    divs.forEach((div, i) => {
      div.textContent = `div ${i}`;
    });
    assert.equal(divs[0].textContent, "div 0");
    assert.equal(divs[5].textContent, "div 5");
  });

  it("for of", () => {
    const divs = $("div");
    let i = 0;
    for (const div of divs) {
      div.textContent = `div ${i++}`;
    }
    assert.equal(divs[0].textContent, "div 0");
    assert.equal(divs[5].textContent, "div 5");
  });

  it("setAttribute all elements", () => {
    $("div").setAttribute("aria-label", "List item");
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].getAttribute("aria-label"), "List item");
    assert.equal(divs[1].getAttribute("aria-label"), "List item");
    assert.equal(divs[5].getAttribute("aria-label"), "List item");
  });

  it("filter", () => {
    $("div").filter((el) => el.textContent == "item1").textContent = "hello";
    assert.equal(document.body.textContent, "item0helloitem2item3item4item5");
  });

  it("class add method", () => {
    $("div").classList.add("some-class");
    const divs = document.getElementsByTagName("div");
    assert.ok(divs[0].classList.contains("some-class"));
    assert.ok(divs[5].classList.contains("some-class"));
  });

  it("rel add and contains method", () => {
    const a = document.createElement("a");
    a.relList.add("some-class");
    assert.ok(a.relList.contains("some-class"));
  });

  it("class value property", () => {
    $("div").classList.add("some-class");
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].classList.value, "some-class");
  });

  it("class add method and textContent property", () => {
    $("div:first-child").classList.add("some-class").textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.ok(divs[0].classList.contains("some-class"));
    assert.ok(!divs[5].classList.contains("some-class"));
    assert.equal(divs[0].textContent, "hello");
    assert.equal(divs[5].textContent, "item5");
  });

  it("filter and class add method and textContent property", () => {
    $("div")
      .filter((el) => el.textContent == "item0")
      .classList.add("some-class").textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.ok(divs[0].classList.contains("some-class"));
    assert.ok(!divs[5].classList.contains("some-class"));
    assert.equal(divs[0].textContent, "hello");
    assert.equal(divs[5].textContent, "item5");
  });

  it("filter and style setProperty method and textContent property", () => {
    $("div")
      .filter((el) => el.textContent == "item0")
      .style.setProperty("--leftmargin", "10px").textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].style.getPropertyValue("--leftmargin"), "10px");
    assert.equal(divs[5].style.getPropertyValue("--leftmargin"), "");
    assert.equal(divs[0].textContent, "hello");
    assert.equal(divs[5].textContent, "item5");
  });

  it("combined", () => {
    $("div")
      .forEach((el) => (el.title = `A div with content ${el.textContent}`))
      .setAttribute("aria-label", "List item")
      .filter((el) => el.textContent == "item1").textContent = "hello";
    const divs = document.getElementsByTagName("div");
    assert.equal(divs[0].getAttribute("aria-label"), "List item");
    assert.equal(divs[5].getAttribute("aria-label"), "List item");
    assert.equal(divs[0].getAttribute("title"), "A div with content item0");
    assert.equal(divs[5].getAttribute("title"), "A div with content item5");
    assert.equal(document.body.textContent, "item0helloitem2item3item4item5");
  });

  it("textContent empty list", () => {
    assert.doesNotThrow(() => {
      $("div.non-existent").textContent = "hello";
    });
  });

  it("setAttribute empty list", () => {
    assert.doesNotThrow(() => {
      $("div.non-existent").setAttribute("aria-label", "List item");
    });
  });

  it("call element specific function", () => {
    const input = document.createElement("input");
    document.querySelector("div:first-child").appendChild(input);
    assert.doesNotThrow(() => {
      $<HTMLInputElement>("input").select();
    });
  });

  it("addEventListener", (done) => {
    $("div:first-child").addEventListener("click", () => {
      done();
    });
    $("div:first-child").click();
  });

  it("canvas", () => {
    const canvas = document.createElement("canvas");
    $("div:nth-child(1)").appendChild(canvas);
    const ctx = $<HTMLCanvasElement>("canvas").getContext("2d", {
      alpha: false,
    });
    ctx.fillRect(0, 0, 100, 100);
  });

  it("style set/get", () => {
    $("div:nth-child(1)").style.color = "red";
    assert.equal($("div:nth-child(1)").style.color, "red");
  });

  it("Parse HTML", () => {
    const div$ = $("<div class='a1'>b1</div>");
    assert.ok(div$.classList.contains("a1"));
    $("div:first-child").appendChild(div$[0]);
    assert.equal($(".a1").length, 1);
    assert.equal($(".a1").textContent, "b1");
  });

  it("Set", () => {
    const set = new Set(["1a", "2a", "3a"]);
    let result = "";
    set.forEach((item) => {
      result += `[${item}]`;
    });
    assert.equal(result, "[1a][2a][3a]");
  });
  it("Custom Element", () => {
    class GolInfo extends HTMLElement {
      connectedCallback() {
        $("nnn").addEventListener("click", () => {
          console.log("click");
        });
      }
    }
    customElements.define("gol-info", GolInfo);

    const i = document.createElement("gol-info");
    // const i = new GolInfo();
    document.body.appendChild(i);
  });
});


================================================
FILE: tests/carbonium.spec.ts
================================================
import { test, expect, Page } from "@playwright/test";
import path from "path";

declare global {
  function $(
    selector: string,
    parent?: Document | ShadowRoot | HTMLElement
  ): any;
}

const bundlePath = path.resolve("./dist/bundle.iife.min.js");

async function checkFirstClassAndText(page: Page) {
  const results = await page.evaluate(() => {
    const divs = document.getElementsByTagName("div");
    return [
      divs[0].classList.contains("some-class"),
      divs[5].classList.contains("some-class"),
      divs[0].textContent,
      divs[5].textContent,
    ] as [boolean, boolean, string | null, string | null];
  });
  expect(results[0]).toBeTruthy();
  expect(results[1]).toBeFalsy();
  expect(results[2]).toBe("hello");
  expect(results[3]).toBe("item5");
}

test.beforeEach(async ({ page }) => {
  await page.goto("about:blank");
  await page.addScriptTag({ path: bundlePath });
  await page.evaluate(() => {
    window.$ = (window as any).carbonium.$;
    document.body.innerHTML = "";
    for (let i = 0; i < 6; i++) {
      const div = document.createElement("div");
      div.textContent = `item${i}`;
      document.body.appendChild(div);
    }
  });
});

test.describe("$", () => {
  test("textContent one element", async ({ page }) => {
    const text = await page.evaluate(() => {
      $("div:first-child").textContent = "hello";
      return document.getElementsByTagName("div")[0].textContent;
    });
    expect(text).toBe("hello");
  });

  test("textContent one element with type", async ({ page }) => {
    const text = await page.evaluate(() => {
      const div = $("div:first-child");
      div.textContent = "hello";
      return document.getElementsByTagName("div")[0].textContent;
    });
    expect(text).toBe("hello");
  });

  test("textContent all elements", async ({ page }) => {
    const text = await page.evaluate(() => {
      $("div").textContent = "hello";
      return document.body.textContent;
    });
    expect(text).toBe("hellohellohellohellohellohello");
  });

  test("length", async ({ page }) => {
    const length = await page.evaluate(() => {
      return $("div").length;
    });
    expect(length).toBe(6);
  });

  test("forEach", async ({ page }) => {
    const texts = await page.evaluate(() => {
      const divs = $("div");
      divs.forEach((div: HTMLElement, i: number) => {
        div.textContent = `div ${i}`;
      });
      return [divs[0].textContent, divs[5].textContent];
    });
    expect(texts[0]).toBe("div 0");
    expect(texts[1]).toBe("div 5");
  });

  test("for of", async ({ page }) => {
    const texts = await page.evaluate(() => {
      const divs = $("div");
      let i = 0;
      for (const div of divs) {
        (div as HTMLElement).textContent = `div ${i++}`;
      }
      return [divs[0].textContent, divs[5].textContent];
    });
    expect(texts[0]).toBe("div 0");
    expect(texts[1]).toBe("div 5");
  });

  test("setAttribute all elements", async ({ page }) => {
    const attrs = await page.evaluate(() => {
      $("div").setAttribute("aria-label", "List item");
      const divs = document.getElementsByTagName("div");
      return [
        divs[0].getAttribute("aria-label"),
        divs[1].getAttribute("aria-label"),
        divs[5].getAttribute("aria-label"),
      ];
    });
    expect(attrs[0]).toBe("List item");
    expect(attrs[1]).toBe("List item");
    expect(attrs[2]).toBe("List item");
  });

  test("filter", async ({ page }) => {
    const text = await page.evaluate(() => {
      $("div").filter(
        (el: HTMLElement) => el.textContent == "item1"
      ).textContent = "hello";
      return document.body.textContent;
    });
    expect(text).toBe("item0helloitem2item3item4item5");
  });

  test("class add method", async ({ page }) => {
    const results = await page.evaluate(() => {
      $("div").classList.add("some-class");
      const divs = document.getElementsByTagName("div");
      return [
        divs[0].classList.contains("some-class"),
        divs[5].classList.contains("some-class"),
      ];
    });
    expect(results[0]).toBeTruthy();
    expect(results[1]).toBeTruthy();
  });

  test("rel add and contains method", async ({ page }) => {
    const result = await page.evaluate(() => {
      const a = document.createElement("a");
      a.relList.add("some-class");
      return a.relList.contains("some-class");
    });
    expect(result).toBeTruthy();
  });

  test("class value property", async ({ page }) => {
    const value = await page.evaluate(() => {
      $("div").classList.add("some-class");
      const divs = document.getElementsByTagName("div");
      return divs[0].classList.value;
    });
    expect(value).toBe("some-class");
  });

  test("class add method and textContent property", async ({ page }) => {
    await page.evaluate(() => {
      $("div:first-child").classList.add("some-class").textContent = "hello";
    });
    await checkFirstClassAndText(page);
  });

  test("filter and class add method and textContent property", async ({
    page,
  }) => {
    await page.evaluate(() => {
      $("div")
        .filter((el: HTMLElement) => el.textContent == "item0")
        .classList.add("some-class").textContent = "hello";
    });
    await checkFirstClassAndText(page);
  });

  test("filter and style setProperty method and textContent property", async ({
    page,
  }) => {
    const results = await page.evaluate(() => {
      $("div")
        .filter((el: HTMLElement) => el.textContent == "item0")
        .style.setProperty("--leftmargin", "10px").textContent = "hello";
      const divs = document.getElementsByTagName("div");
      return [
        divs[0].style.getPropertyValue("--leftmargin"),
        divs[5].style.getPropertyValue("--leftmargin"),
        divs[0].textContent,
        divs[5].textContent,
      ];
    });
    expect(results[0]).toBe("10px");
    expect(results[1]).toBe("");
    expect(results[2]).toBe("hello");
    expect(results[3]).toBe("item5");
  });

  test("combined", async ({ page }) => {
    const results = await page.evaluate(() => {
      $("div")
        .forEach(
          (el: HTMLElement) =>
            (el.title = `A div with content ${el.textContent}`)
        )
        .setAttribute("aria-label", "List item")
        .filter((el: HTMLElement) => el.textContent == "item1").textContent =
        "hello";
      const divs = document.getElementsByTagName("div");
      return [
        divs[0].getAttribute("aria-label"),
        divs[5].getAttribute("aria-label"),
        divs[0].getAttribute("title"),
        divs[5].getAttribute("title"),
        document.body.textContent,
      ];
    });
    expect(results[0]).toBe("List item");
    expect(results[1]).toBe("List item");
    expect(results[2]).toBe("A div with content item0");
    expect(results[3]).toBe("A div with content item5");
    expect(results[4]).toBe("item0helloitem2item3item4item5");
  });

  test("textContent empty list", async ({ page }) => {
    await page.evaluate(() => {
      $("div.non-existent").textContent = "hello";
    });
  });

  test("setAttribute empty list", async ({ page }) => {
    await page.evaluate(() => {
      $("div.non-existent").setAttribute("aria-label", "List item");
    });
  });

  test("call element specific function", async ({ page }) => {
    await page.evaluate(() => {
      const input = document.createElement("input");
      document.querySelector("div:first-child")!.appendChild(input);
      $("input").select();
    });
  });

  test("addEventListener", async ({ page }) => {
    const fired = await page.evaluate(
      () =>
        new Promise<boolean>((resolve) => {
          $("div:first-child").addEventListener("click", () => resolve(true));
          $("div:first-child").click();
        })
    );
    expect(fired).toBe(true);
  });

  test("canvas", async ({ page }) => {
    await page.evaluate(() => {
      const canvas = document.createElement("canvas");
      $("div:nth-child(1)").appendChild(canvas);
      const ctx = $("canvas").getContext("2d", { alpha: false });
      ctx.fillRect(0, 0, 100, 100);
    });
  });

  test("style set/get", async ({ page }) => {
    const color = await page.evaluate(() => {
      $("div:nth-child(1)").style.color = "red";
      return $("div:nth-child(1)").style.color;
    });
    expect(color).toBe("red");
  });

  test("Parse HTML", async ({ page }) => {
    const results = await page.evaluate(() => {
      const div$ = $("<div class='a1'>b1</div>");
      const hasClass = div$.classList.contains("a1");
      $("div:first-child").appendChild(div$[0]);
      return [hasClass, $(".a1").length, $(".a1").textContent];
    });
    expect(results[0]).toBeTruthy();
    expect(results[1]).toBe(1);
    expect(results[2]).toBe("b1");
  });

  test("Set", async ({ page }) => {
    const result = await page.evaluate(() => {
      const set = new Set(["1a", "2a", "3a"]);
      let result = "";
      set.forEach((item) => {
        result += `[${item}]`;
      });
      return result;
    });
    expect(result).toBe("[1a][2a][3a]");
  });

  test("Custom Element", async ({ page }) => {
    await page.evaluate(() => {
      class GolInfo extends HTMLElement {
        connectedCallback() {
          $("nnn").addEventListener("click", () => {
            console.log("click");
          });
        }
      }
      customElements.define("gol-info", GolInfo);
      const i = document.createElement("gol-info");
      document.body.appendChild(i);
    });
  });
});


================================================
FILE: tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "es6",
    "rootDir": "./src",
    "moduleResolution": "bundler",
    "sourceMap": true,
    "declaration": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}
Download .txt
gitextract_aeet774x/

├── .github/
│   └── workflows/
│       ├── codeql.yml
│       ├── coveralls.yml
│       └── scorecard.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .prettierignore
├── .prettierrc.json
├── LICENSE
├── README.md
├── demo/
│   ├── demo.js
│   └── index.html
├── dist/
│   ├── bundle.js
│   ├── carbonium.d.ts
│   └── src/
│       └── carbonium.d.ts
├── eslint.config.js
├── package.json
├── playwright.config.ts
├── rollup.config.js
├── src/
│   └── carbonium.ts
├── test/
│   └── test.ts
├── tests/
│   └── carbonium.spec.ts
└── tsconfig.json
Download .txt
SYMBOL INDEX (25 symbols across 6 files)

FILE: dist/bundle.js
  function $ (line 6) | function $(selectors, parentNode) {
  method get (line 26) | get(target, prop) {
  method set (line 124) | set(target, prop, value) {
  method deleteProperty (line 135) | deleteProperty(target, prop) {

FILE: dist/carbonium.d.ts
  type CarboniumType (line 7) | type CarboniumType<T extends HTMLElement = HTMLElement> = CarboniumList<...
  type CarboniumList (line 8) | interface CarboniumList<T extends HTMLElement> extends Array<T> {
  type CarboniumClassList (line 21) | interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
  type CarboniumStyleList (line 27) | interface CarboniumStyleList<T extends HTMLElement> extends CSSStyleDecl...

FILE: dist/src/carbonium.d.ts
  type CarboniumType (line 7) | type CarboniumType<T extends HTMLElement = HTMLElement> = CarboniumList<...
  type CarboniumList (line 8) | interface CarboniumList<T extends HTMLElement> extends Array<T> {
  type CarboniumClassList (line 21) | interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
  type CarboniumStyleList (line 27) | interface CarboniumStyleList<T extends HTMLElement> extends CSSStyleDecl...

FILE: src/carbonium.ts
  function $ (line 7) | function $<T extends HTMLElement = HTMLElement>(
  method get (line 37) | get(target, prop) {
  method set (line 143) | set(target, prop, value) {
  method deleteProperty (line 154) | deleteProperty(target, prop) {
  type CarboniumType (line 162) | type CarboniumType<T extends HTMLElement = HTMLElement> =
  type CarboniumList (line 167) | interface CarboniumList<T extends HTMLElement> extends Array<T> {
  type CarboniumClassList (line 197) | interface CarboniumClassList<T extends HTMLElement> extends DOMTokenList {
  type CarboniumStyleList (line 210) | interface CarboniumStyleList<

FILE: test/test.ts
  class GolInfo (line 198) | class GolInfo extends HTMLElement {
    method connectedCallback (line 199) | connectedCallback() {

FILE: tests/carbonium.spec.ts
  function checkFirstClassAndText (line 13) | async function checkFirstClassAndText(page: Page) {
  class GolInfo (line 296) | class GolInfo extends HTMLElement {
    method connectedCallback (line 297) | connectedCallback() {
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (52K chars).
[
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 835,
    "preview": "name: \"CodeQL\"\n\non:\n  push:\n    branches: [\"master\"]\n  pull_request:\n    branches: [\"master\"]\n  schedule:\n    - cron: \"1"
  },
  {
    "path": ".github/workflows/coveralls.yml",
    "chars": 507,
    "preview": "name: Coveralls\n\non: [\"push\", \"pull_request\"]\n\njobs:\n  test:\n    name: Run units tests\n    runs-on: ubuntu-latest\n\n    s"
  },
  {
    "path": ".github/workflows/scorecard.yml",
    "chars": 2596,
    "preview": "# This workflow uses actions that are not certified by GitHub. They are provided\n# by a third-party and are governed by "
  },
  {
    "path": ".gitignore",
    "chars": 48,
    "preview": "node_modules\ncoverage\n.idea\n/playwright-report/\n"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 39,
    "preview": "npx pretty-quick --staged\nnpm run lint\n"
  },
  {
    "path": ".prettierignore",
    "chars": 5,
    "preview": "dist\n"
  },
  {
    "path": ".prettierrc.json",
    "chars": 56,
    "preview": "{\n  \"trailingComma\": \"es5\",\n  \"arrowParens\": \"always\"\n}\n"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2020 Edwin Martin\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 6208,
    "preview": "[![Scorecard supply-chain security](https://github.com/edwinm/carbonium/actions/workflows/scorecard.yml/badge.svg)](http"
  },
  {
    "path": "demo/demo.js",
    "chars": 475,
    "preview": "const importPromise = import(\n  \"https://cdn.jsdelivr.net/npm/carbonium/dist/bundle.min.js\"\n);\n\nconst loadPromise = new "
  },
  {
    "path": "demo/index.html",
    "chars": 371,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Demo</title>\n    <meta\n      name=\"vie"
  },
  {
    "path": "dist/bundle.js",
    "chars": 5542,
    "preview": "/**\n Carbonium 1.3.0\n @copyright 2020 Edwin Martin\n @license MIT\n */\nfunction $(selectors, parentNode) {\n    let nodelis"
  },
  {
    "path": "dist/carbonium.d.ts",
    "chars": 1712,
    "preview": "/**\n Carbonium __buildVersion__\n @copyright 2020 Edwin Martin\n @license MIT\n */\nexport declare function $<T extends HTML"
  },
  {
    "path": "dist/src/carbonium.d.ts",
    "chars": 1712,
    "preview": "/**\n Carbonium __buildVersion__\n @copyright 2020 Edwin Martin\n @license MIT\n */\nexport declare function $<T extends HTML"
  },
  {
    "path": "eslint.config.js",
    "chars": 680,
    "preview": "import tseslint from \"typescript-eslint\";\nimport js from \"@eslint/js\";\nimport prettier from \"eslint-config-prettier\";\nim"
  },
  {
    "path": "package.json",
    "chars": 2057,
    "preview": "{\n  \"name\": \"carbonium\",\n  \"version\": \"1.3.0\",\n  \"description\": \"One kilobyte library for easy DOM manipulation\",\n  \"typ"
  },
  {
    "path": "playwright.config.ts",
    "chars": 344,
    "preview": "import { defineConfig, devices } from \"@playwright/test\";\n\nexport default defineConfig({\n  testDir: \"./tests\",\n  fullyPa"
  },
  {
    "path": "rollup.config.js",
    "chars": 886,
    "preview": "import { createRequire } from \"module\";\nimport typescript from \"@rollup/plugin-typescript\";\nimport terser from \"@rollup/"
  },
  {
    "path": "src/carbonium.ts",
    "chars": 6595,
    "preview": "/**\n Carbonium __buildVersion__\n @copyright 2020 Edwin Martin\n @license MIT\n */\n\nexport function $<T extends HTMLElement"
  },
  {
    "path": "test/test.ts",
    "chars": 6902,
    "preview": "import * as assert from \"assert\";\nimport { $, CarboniumType } from \"../src/carbonium\";\n// TODO: this should work - find "
  },
  {
    "path": "tests/carbonium.spec.ts",
    "chars": 9498,
    "preview": "import { test, expect, Page } from \"@playwright/test\";\nimport path from \"path\";\n\ndeclare global {\n  function $(\n    sele"
  },
  {
    "path": "tsconfig.json",
    "chars": 206,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"rootDir\": \"./src\",\n    \"moduleResolution\": \"bundler\",\n    \"sourceMap\""
  }
]

About this extraction

This page contains the full source code of the edwinm/carbonium GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (47.2 KB), approximately 12.6k tokens, and a symbol index with 25 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!