├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature-request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bower.json ├── package.json └── src └── Web ├── DOM.purs └── DOM ├── Attr.js ├── Attr.purs ├── AttrName.purs ├── CharacterData.js ├── CharacterData.purs ├── ChildNode.js ├── ChildNode.purs ├── ClassName.purs ├── Comment.purs ├── DOMTokenList.js ├── DOMTokenList.purs ├── Document.js ├── Document.purs ├── Document └── CompatMode.purs ├── DocumentFragment.purs ├── DocumentType.js ├── DocumentType.purs ├── Element.js ├── Element.purs ├── ElementId.purs ├── ElementName.purs ├── HTMLCollection.js ├── HTMLCollection.purs ├── Internal └── Types.purs ├── MutationObserver.js ├── MutationObserver.purs ├── MutationRecord.js ├── MutationRecord.purs ├── NamedNodeMap.js ├── NamedNodeMap.purs ├── NamespacePrefix.purs ├── NamespaceURI.purs ├── Node.js ├── Node.purs ├── NodeList.js ├── NodeList.purs ├── NodeType.purs ├── NonDocumentTypeChildNode.js ├── NonDocumentTypeChildNode.purs ├── NonElementParentNode.js ├── NonElementParentNode.purs ├── ParentNode.js ├── ParentNode.purs ├── ProcessingInstruction.js ├── ProcessingInstruction.purs ├── PropName.purs ├── ShadowRoot.js ├── ShadowRoot.purs ├── Text.js └── Text.purs /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module" 5 | }, 6 | "extends": "eslint:recommended", 7 | "env": { 8 | "browser": true 9 | }, 10 | "rules": { 11 | "strict": [2, "global"], 12 | "block-scoped-var": 2, 13 | "consistent-return": 2, 14 | "eqeqeq": [2, "smart"], 15 | "guard-for-in": 2, 16 | "no-caller": 2, 17 | "no-extend-native": 2, 18 | "no-loop-func": 2, 19 | "no-new": 2, 20 | "no-param-reassign": 2, 21 | "no-return-assign": 2, 22 | "no-unused-expressions": 2, 23 | "no-use-before-define": 2, 24 | "radix": [2, "always"], 25 | "indent": [2, 2], 26 | "quotes": [2, "double"], 27 | "semi": [2, "always"] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest types, functions, properties that may be missing 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Prerequisites 11 | 12 | - [ ] Before opening an issue, please check the DOM standard (https://dom.spec.whatwg.org/). If it doesn't appear in this spec, it may be present in the spec for one of the other `purescript-web` projects. Although MDN is a great resource, it is not a suitable reference for this project. 13 | 14 | ### Description 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Prerequisites** 2 | 3 | - [ ] Before opening a pull request, please check the DOM standard (https://dom.spec.whatwg.org/). If it doesn't appear in this spec, it may be present in the spec for one of the other `purescript-web` projects. Although MDN is a great resource, it is not a suitable reference for this project. 4 | 5 | **Description of the change** 6 | 7 | Clearly and concisely describe the purpose of the pull request. If this PR relates to an existing issue or change proposal, please link to it. Include any other background context that would help reviewers understand the motivation for this PR. 8 | 9 | --- 10 | 11 | **Checklist:** 12 | 13 | - [ ] Added the change to the changelog's "Unreleased" section with a reference to this PR (e.g. "- Made a change (#0000)") 14 | - [ ] Linked any existing issues or proposals that this pull request should close 15 | - [ ] Updated or added relevant documentation 16 | - [ ] Added a test for the contribution (if applicable) 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - uses: purescript-contrib/setup-purescript@main 16 | with: 17 | purescript: "unstable" 18 | 19 | - uses: actions/setup-node@v2 20 | with: 21 | node-version: "14" 22 | 23 | - name: Install dependencies 24 | run: | 25 | npm install -g bower 26 | npm install 27 | bower install --production 28 | 29 | - name: Build source 30 | run: npm run-script build 31 | 32 | - name: Run tests 33 | run: | 34 | bower install 35 | npm run-script test --if-present 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.* 2 | !/.gitignore 3 | !/.eslintrc.json 4 | !/.github/ 5 | package-lock.json 6 | /bower_components/ 7 | /node_modules/ 8 | /output/ 9 | /generated-docs/ 10 | /.pulp-cache/ 11 | /.psc-package/ 12 | /.psc* 13 | /.purs* 14 | /.psa* 15 | /.spago 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | Notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 4 | 5 | ## [Unreleased] 6 | 7 | Breaking changes: 8 | - The `id` function returns an `ElementId` instead of a `String`. (#58 by @nsaunders) 9 | - The `setId` function is parameterized by `ElementId` instead of `String`. (#58 by @nsaunders) 10 | - The `getElementById` function is parameterized by `ElementId` instead of `String`. (#58 by @nsaunders) 11 | - The `className` function returns a `ClassName` instead of a `String`. (#58 by @nsaunders) 12 | - The `setClassName` and `getElementsByClassName` functions are parameterized by `ClassName` instead of `String`. (#58 by @nsaunders) 13 | - The `getAttribute`, `setAttribute`, `hasAttribute`, and `removeAttribute` functions are parameterized by `AttrName` instead of `String`. (#58 by @nsaunders) 14 | 15 | New features: 16 | - `AttrName`, `ClassName`, and `PropName` types have been added, migrated from [web-html](https://github.com/purescript-web/purescript-web-html). (#58 by @nsaunders) 17 | - A new `ElementId` type, representing the value of an `id` property/attribute, has been added. (#58 by @nsaunders) 18 | 19 | Bugfixes: 20 | 21 | Other improvements: 22 | 23 | ## [v6.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v6.0.0) - 2022-04-27 24 | 25 | Breaking changes: 26 | - Migrate FFI to ES modules (#51 by @JordanMartinez) 27 | - Unwrap returned `Effect` for `doctype` (#52 by @JordanMartinez) 28 | - Port `getBoundingClientRect` from `web-html`; set arg to `Element` (#53 by @JordanMartinez) 29 | 30 | New features: 31 | 32 | Bugfixes: 33 | 34 | Other improvements: 35 | 36 | ## [v5.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v5.0.0) - 2021-02-26 37 | 38 | Breaking changes: 39 | - Added support for PureScript 0.14 and dropped support for all previous versions (#31) 40 | - Change node manipulations to return `Unit` (#32) 41 | 42 | New features: 43 | - Add support for ShadowRoot API (#34) 44 | - Add support for `Element.matches` and `Element.closest` (#39) 45 | 46 | Bugfixes: 47 | 48 | Other improvements: 49 | - Migrated CI to GitHub Actions and updated installation instructions to use Spago (#28, #30) 50 | - Added a CHANGELOG.md file and updated pull request template (#35, #36, #37) 51 | - Updated issue templates 52 | - Updated link to spec (#27) 53 | - Remove `return {}` from FFI functions for a small performance boost (#26) 54 | 55 | ## [v4.1.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v4.1.0) - 2020-06-07 56 | 57 | - Added `Show` instance for `NodeType` (@srghma) 58 | 59 | ## [v4.0.2](https://github.com/purescript-web/purescript-web-dom/releases/tag/v4.0.2) - 2020-05-18 60 | 61 | - Fixed FFI implementation for `hasAttribute` (#22, @srghma) 62 | 63 | ## [v4.0.1](https://github.com/purescript-web/purescript-web-dom/releases/tag/v4.0.1) - 2020-03-15 64 | 65 | - Add documentation explaining how to get hold of a `Document` in `Web.DOM.Document` (@hdgarrood, #19) 66 | 67 | ## [v4.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v4.0.0) - 2019-08-18 68 | 69 | - Fixed type of `mutationObserver` (@alextes) 70 | 71 | ## [v3.1.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v3.1.0) - 2019-08-18 72 | 73 | - Added `classList` for `Element` (@alextes) 74 | 75 | ## [v3.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v3.0.0) - 2019-06-02 76 | 77 | - `nodeValue` now returns `Effect (Maybe String)` as it is nullable (@bbarker) 78 | 79 | ## [v2.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v2.0.0) - 2019-02-23 80 | 81 | - Bumped `-web-events` dependency, `Event.defaultPrevented` is now effectful. 82 | 83 | ## [v1.0.0](https://github.com/purescript-web/purescript-web-dom/releases/tag/v1.0.0) - 2018-05-25 84 | 85 | - Initial release 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 PureScript 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # purescript-web-dom 2 | 3 | [![Latest release](http://img.shields.io/github/release/purescript-web/purescript-web-dom.svg)](https://github.com/purescript-web/purescript-web-dom/releases) 4 | [![Build status](https://github.com/purescript-web/purescript-web-dom/workflows/CI/badge.svg?branch=master)](https://github.com/purescript-web/purescript-web-dom/actions?query=workflow%3ACI+branch%3Amaster) 5 | [![Pursuit](https://pursuit.purescript.org/packages/purescript-web-dom/badge)](https://pursuit.purescript.org/packages/purescript-web-dom) 6 | 7 | Type definitions and low level interface implementations for the [WHATWG DOM Living Standard](https://dom.spec.whatwg.org/). 8 | 9 | ## Installation 10 | 11 | ``` 12 | spago install web-dom 13 | ``` 14 | 15 | ## Documentation 16 | 17 | Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-web-dom). 18 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-web-dom", 3 | "homepage": "https://github.com/purescript-web/purescript-web-dom", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/purescript-web/purescript-web-dom.git" 8 | }, 9 | "ignore": [ 10 | "**/.*", 11 | "bower_components", 12 | "node_modules", 13 | "output", 14 | "bower.json", 15 | "package.json" 16 | ], 17 | "dependencies": { 18 | "purescript-web-events": "^4.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "clean": "rimraf output && rimraf .pulp-cache", 5 | "build": "eslint src && pulp build -- --censor-lib --strict" 6 | }, 7 | "devDependencies": { 8 | "eslint": "^7.15.0", 9 | "pulp": "16.0.0-0", 10 | "purescript-psa": "^0.8.2", 11 | "rimraf": "^3.0.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Web/DOM.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM (module Exports) where 2 | 3 | import Web.DOM.CharacterData (CharacterData) as Exports 4 | import Web.DOM.ChildNode (ChildNode) as Exports 5 | import Web.DOM.Comment (Comment) as Exports 6 | import Web.DOM.Document (Document) as Exports 7 | import Web.DOM.DocumentFragment (DocumentFragment) as Exports 8 | import Web.DOM.DocumentType (DocumentType) as Exports 9 | import Web.DOM.DOMTokenList (DOMTokenList) as Exports 10 | import Web.DOM.Element (Element) as Exports 11 | import Web.DOM.HTMLCollection (HTMLCollection) as Exports 12 | import Web.DOM.Node (Node) as Exports 13 | import Web.DOM.NodeList (NodeList) as Exports 14 | import Web.DOM.NodeType (NodeType) as Exports 15 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) as Exports 16 | import Web.DOM.NonElementParentNode (NonElementParentNode) as Exports 17 | import Web.DOM.ParentNode (ParentNode) as Exports 18 | import Web.DOM.ProcessingInstruction (ProcessingInstruction) as Exports 19 | import Web.DOM.Text (Text) as Exports 20 | -------------------------------------------------------------------------------- /src/Web/DOM/Attr.js: -------------------------------------------------------------------------------- 1 | export const _namespaceURI = (attr) => attr.namespaceURI; 2 | 3 | export const _prefix = (attr) => attr.prefix; 4 | 5 | export const localName = (attr) => attr.localName; 6 | 7 | export const getValue = (attr) => () => attr.value; 8 | 9 | export const setValue = (attr) => (value) => () => { 10 | attr.value = value; 11 | }; 12 | 13 | export const _ownerElement = (attr) => () => attr.ownerElement; 14 | -------------------------------------------------------------------------------- /src/Web/DOM/Attr.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Attr 2 | ( module Exports 3 | , namespaceURI 4 | , prefix 5 | , localName 6 | , getValue 7 | , setValue 8 | , ownerElement 9 | ) where 10 | 11 | import Prelude 12 | 13 | import Data.Maybe (Maybe) 14 | import Data.Nullable (Nullable, toMaybe) 15 | import Effect (Effect) 16 | import Web.DOM.AttrName (AttrName) 17 | import Web.DOM.Internal.Types (Attr) as Exports 18 | import Web.DOM.Internal.Types (Attr, Element) 19 | import Web.DOM.NamespacePrefix (NamespacePrefix) 20 | import Web.DOM.NamespaceURI (NamespaceURI) 21 | 22 | foreign import _namespaceURI :: Attr -> Nullable NamespaceURI 23 | 24 | namespaceURI :: Attr -> Maybe NamespaceURI 25 | namespaceURI attr = toMaybe (_namespaceURI attr) 26 | 27 | foreign import _prefix :: Attr -> Nullable NamespacePrefix 28 | 29 | prefix :: Attr -> Maybe NamespacePrefix 30 | prefix attr = toMaybe (_prefix attr) 31 | 32 | foreign import localName :: Attr -> AttrName 33 | 34 | foreign import getValue :: Attr -> Effect String 35 | 36 | foreign import setValue :: Attr -> String -> Effect Unit 37 | 38 | foreign import _ownerElement :: Attr -> Effect (Nullable Element) 39 | 40 | -- | The element the attribute belongs to, unless the attribute is not (yet) 41 | -- | attached to an element. 42 | ownerElement :: Attr -> Effect (Maybe Element) 43 | ownerElement attr = map toMaybe (_ownerElement attr) 44 | -------------------------------------------------------------------------------- /src/Web/DOM/AttrName.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.AttrName where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | -- | A wrapper for attribute names. 8 | newtype AttrName = AttrName String 9 | 10 | derive instance newtypeAttrName :: Newtype AttrName _ 11 | derive newtype instance eqAttrName :: Eq AttrName 12 | derive newtype instance ordAttrName :: Ord AttrName 13 | -------------------------------------------------------------------------------- /src/Web/DOM/CharacterData.js: -------------------------------------------------------------------------------- 1 | export function data_(t) { 2 | return function () { 3 | return t.data; 4 | }; 5 | } 6 | 7 | export function length(t) { 8 | return function () { 9 | return t.length; 10 | }; 11 | } 12 | 13 | export function substringData(offset) { 14 | return function (count) { 15 | return function (cd) { 16 | return function () { 17 | cd.substringData(offset, count); 18 | }; 19 | }; 20 | }; 21 | } 22 | 23 | export function appendData(data) { 24 | return function (cd) { 25 | return function () { 26 | cd.appendData(data); 27 | }; 28 | }; 29 | } 30 | 31 | export function insertData(offset) { 32 | return function (data) { 33 | return function (cd) { 34 | return function () { 35 | cd.insertData(offset, data); 36 | }; 37 | }; 38 | }; 39 | } 40 | 41 | export function deleteData(offset) { 42 | return function (count) { 43 | return function (cd) { 44 | return function () { 45 | cd.deleteData(offset, count); 46 | }; 47 | }; 48 | }; 49 | } 50 | 51 | export function replaceData(offset) { 52 | return function (count) { 53 | return function (data) { 54 | return function (cd) { 55 | return function () { 56 | cd.replaceData(offset, count, data); 57 | }; 58 | }; 59 | }; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /src/Web/DOM/CharacterData.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.CharacterData where 2 | 3 | import Prelude 4 | 5 | import Data.Maybe (Maybe) 6 | import Effect (Effect) 7 | import Unsafe.Coerce (unsafeCoerce) 8 | import Web.DOM.ChildNode (ChildNode) 9 | import Web.DOM.Internal.Types (Node) 10 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) 11 | import Web.Event.EventTarget (EventTarget) 12 | import Web.Internal.FFI (unsafeReadProtoTagged) 13 | 14 | foreign import data CharacterData :: Type 15 | 16 | fromNode :: Node -> Maybe CharacterData 17 | fromNode = unsafeReadProtoTagged "CharacterData" 18 | 19 | fromChildNode :: ChildNode -> Maybe CharacterData 20 | fromChildNode = unsafeReadProtoTagged "CharacterData" 21 | 22 | fromNonDocumentTypeChildNode :: NonDocumentTypeChildNode -> Maybe CharacterData 23 | fromNonDocumentTypeChildNode = unsafeReadProtoTagged "CharacterData" 24 | 25 | fromEventTarget :: EventTarget -> Maybe CharacterData 26 | fromEventTarget = unsafeReadProtoTagged "CharacterData" 27 | 28 | toNode :: CharacterData -> Node 29 | toNode = unsafeCoerce 30 | 31 | toChildNode :: CharacterData -> ChildNode 32 | toChildNode = unsafeCoerce 33 | 34 | toNonDocumentTypeChildNode :: CharacterData -> NonDocumentTypeChildNode 35 | toNonDocumentTypeChildNode = unsafeCoerce 36 | 37 | toEventTarget :: CharacterData -> EventTarget 38 | toEventTarget = unsafeCoerce 39 | 40 | foreign import data_ :: CharacterData -> Effect String 41 | 42 | foreign import length :: CharacterData -> Effect Int 43 | 44 | foreign import substringData :: Int -> Int -> CharacterData -> Effect String 45 | 46 | foreign import appendData :: String -> CharacterData -> Effect Unit 47 | 48 | foreign import insertData :: Int -> String -> CharacterData -> Effect Unit 49 | 50 | foreign import deleteData :: Int -> Int -> CharacterData -> Effect Unit 51 | 52 | foreign import replaceData :: Int -> Int -> String -> CharacterData -> Effect Unit 53 | -------------------------------------------------------------------------------- /src/Web/DOM/ChildNode.js: -------------------------------------------------------------------------------- 1 | export function remove(node) { 2 | return function () { 3 | return node.remove(); 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /src/Web/DOM/ChildNode.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ChildNode where 2 | 3 | import Prelude 4 | 5 | import Effect (Effect) 6 | 7 | foreign import data ChildNode :: Type 8 | 9 | -- | Removes the node from its parent. 10 | foreign import remove :: ChildNode -> Effect Unit 11 | -------------------------------------------------------------------------------- /src/Web/DOM/ClassName.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ClassName where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | -- | A wrapper for strings which are used as CSS classes. 8 | newtype ClassName = ClassName String 9 | 10 | derive instance newtypeClassName :: Newtype ClassName _ 11 | derive newtype instance eqClassName :: Eq ClassName 12 | derive newtype instance ordClassName :: Ord ClassName 13 | -------------------------------------------------------------------------------- /src/Web/DOM/Comment.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Comment where 2 | 3 | import Data.Maybe (Maybe) 4 | import Unsafe.Coerce (unsafeCoerce) 5 | import Web.DOM.CharacterData (CharacterData) 6 | import Web.DOM.ChildNode (ChildNode) 7 | import Web.DOM.Internal.Types (Node) 8 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) 9 | import Web.Event.EventTarget (EventTarget) 10 | import Web.Internal.FFI (unsafeReadProtoTagged) 11 | 12 | foreign import data Comment :: Type 13 | 14 | fromCharacterData :: CharacterData -> Maybe Comment 15 | fromCharacterData = unsafeReadProtoTagged "Comment" 16 | 17 | fromNode :: Node -> Maybe Comment 18 | fromNode = unsafeReadProtoTagged "Comment" 19 | 20 | fromChildNode :: ChildNode -> Maybe Comment 21 | fromChildNode = unsafeReadProtoTagged "Comment" 22 | 23 | fromNonDocumentTypeChildNode :: NonDocumentTypeChildNode -> Maybe Comment 24 | fromNonDocumentTypeChildNode = unsafeReadProtoTagged "Comment" 25 | 26 | fromEventTarget :: EventTarget -> Maybe Comment 27 | fromEventTarget = unsafeReadProtoTagged "Comment" 28 | 29 | toCharacterData :: Comment -> CharacterData 30 | toCharacterData = unsafeCoerce 31 | 32 | toNode :: Comment -> Node 33 | toNode = unsafeCoerce 34 | 35 | toChildNode :: Comment -> ChildNode 36 | toChildNode = unsafeCoerce 37 | 38 | toNonDocumentTypeChildNode :: Comment -> NonDocumentTypeChildNode 39 | toNonDocumentTypeChildNode = unsafeCoerce 40 | 41 | toEventTarget :: Comment -> EventTarget 42 | toEventTarget = unsafeCoerce 43 | -------------------------------------------------------------------------------- /src/Web/DOM/DOMTokenList.js: -------------------------------------------------------------------------------- 1 | export const length = (list) => () => list.length; 2 | 3 | export function _item(list) { 4 | return function(index) { 5 | return function() { 6 | return list.item(index); 7 | }; 8 | }; 9 | } 10 | 11 | export function contains(list) { 12 | return function(token) { 13 | return function() { 14 | return list.contains(token); 15 | }; 16 | }; 17 | } 18 | 19 | export function add(list) { 20 | return function(token) { 21 | return function() { 22 | return list.add(token); 23 | }; 24 | }; 25 | } 26 | 27 | export function remove(list) { 28 | return function(token) { 29 | return function() { 30 | return list.remove(token); 31 | }; 32 | }; 33 | } 34 | 35 | export function toggle(list) { 36 | return function(token) { 37 | return function() { 38 | return list.toggle(token); 39 | }; 40 | }; 41 | } 42 | 43 | export function toggleForce(list) { 44 | return function(token) { 45 | return function(force) { 46 | return function() { 47 | return list.toggle(token, force); 48 | }; 49 | }; 50 | }; 51 | } 52 | 53 | export function replace(list) { 54 | return function(token) { 55 | return function(newToken) { 56 | return function() { 57 | return list.replace(token, newToken); 58 | }; 59 | }; 60 | }; 61 | } 62 | 63 | export function supports(list) { 64 | return function(token) { 65 | return function() { 66 | return list.supports(token); 67 | }; 68 | }; 69 | } 70 | 71 | export function getValue(list) { 72 | return function() { 73 | return list.value; 74 | }; 75 | } 76 | 77 | export function setValue(list) { 78 | return function(token) { 79 | return function() { 80 | list.value = token; 81 | }; 82 | }; 83 | } 84 | 85 | export function tokens(list) { 86 | return function () { 87 | const result = []; 88 | for (const token of list.tokens) { 89 | result.push(token); 90 | } 91 | return result; 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /src/Web/DOM/DOMTokenList.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.DOMTokenList 2 | ( DOMTokenList 3 | , length 4 | , item 5 | , contains 6 | , add 7 | , remove 8 | , toggle 9 | , toggleForce 10 | , replace 11 | , supports 12 | , getValue 13 | , setValue 14 | , tokens 15 | ) where 16 | 17 | import Prelude 18 | 19 | import Effect (Effect) 20 | import Data.Maybe (Maybe) 21 | import Data.Nullable (Nullable, toMaybe) 22 | 23 | foreign import data DOMTokenList :: Type 24 | 25 | foreign import length :: DOMTokenList -> Effect Int 26 | 27 | foreign import _item :: DOMTokenList -> Int -> Effect (Nullable String) 28 | 29 | item :: DOMTokenList -> Int -> Effect (Maybe String) 30 | item index = map toMaybe <<< _item index 31 | 32 | foreign import contains :: DOMTokenList -> String -> Effect Boolean 33 | 34 | foreign import add :: DOMTokenList -> String -> Effect Unit 35 | 36 | foreign import remove :: DOMTokenList -> String -> Effect Unit 37 | 38 | foreign import toggle :: DOMTokenList -> String -> Effect Boolean 39 | 40 | foreign import toggleForce :: DOMTokenList -> String -> Boolean -> Effect Boolean 41 | 42 | foreign import replace :: DOMTokenList -> String -> String -> Effect Unit 43 | 44 | foreign import supports :: DOMTokenList -> String -> Effect Boolean 45 | 46 | foreign import getValue :: DOMTokenList -> Effect String 47 | 48 | foreign import setValue :: DOMTokenList -> String -> Effect Unit 49 | 50 | foreign import tokens :: DOMTokenList -> Effect (Array String) 51 | -------------------------------------------------------------------------------- /src/Web/DOM/Document.js: -------------------------------------------------------------------------------- 1 | var getEffProp = function (name) { 2 | return function (doc) { 3 | return function () { 4 | return doc[name]; 5 | }; 6 | }; 7 | }; 8 | 9 | export const url = getEffProp("URL"); 10 | export const documentURI = getEffProp("documentURI"); 11 | export const origin = getEffProp("origin"); 12 | export const _compatMode = getEffProp("compatMode"); 13 | export const characterSet = getEffProp("characterSet"); 14 | export const contentType = getEffProp("contentType"); 15 | export function _doctype(doc) { 16 | return doc["doctype"]; 17 | } 18 | export const _documentElement = getEffProp("documentElement"); 19 | 20 | export function getElementsByTagName(localName) { 21 | return function (doc) { 22 | return function () { 23 | return doc.getElementsByTagName(localName); 24 | }; 25 | }; 26 | } 27 | 28 | export function _getElementsByTagNameNS(ns) { 29 | return function (localName) { 30 | return function (doc) { 31 | return function () { 32 | return doc.getElementsByTagNameNS(ns, localName); 33 | }; 34 | }; 35 | }; 36 | } 37 | 38 | export function getElementsByClassName(classNames) { 39 | return function (doc) { 40 | return function () { 41 | return doc.getElementsByClassName(classNames); 42 | }; 43 | }; 44 | } 45 | 46 | export function createElement(localName) { 47 | return function (doc) { 48 | return function () { 49 | return doc.createElement(localName); 50 | }; 51 | }; 52 | } 53 | 54 | export function _createElementNS(ns) { 55 | return function (qualifiedName) { 56 | return function (doc) { 57 | return function () { 58 | return doc.createElementNS(ns, qualifiedName); 59 | }; 60 | }; 61 | }; 62 | } 63 | 64 | export function createDocumentFragment(doc) { 65 | return function () { 66 | return doc.createDocumentFragment(); 67 | }; 68 | } 69 | 70 | export function createTextNode(data) { 71 | return function (doc) { 72 | return function () { 73 | return doc.createTextNode(data); 74 | }; 75 | }; 76 | } 77 | 78 | export function createComment(data) { 79 | return function (doc) { 80 | return function () { 81 | return doc.createComment(data); 82 | }; 83 | }; 84 | } 85 | 86 | export function createProcessingInstruction(target) { 87 | return function (data) { 88 | return function (doc) { 89 | return function () { 90 | return doc.createProcessingInstruction(target, data); 91 | }; 92 | }; 93 | }; 94 | } 95 | 96 | export function importNode(node) { 97 | return function (deep) { 98 | return function (doc) { 99 | return function () { 100 | return doc.importNode(node, deep); 101 | }; 102 | }; 103 | }; 104 | } 105 | 106 | export function adoptNode(node) { 107 | return function (doc) { 108 | return function () { 109 | return doc.adoptNode(node); 110 | }; 111 | }; 112 | } 113 | -------------------------------------------------------------------------------- /src/Web/DOM/Document.purs: -------------------------------------------------------------------------------- 1 | -- | This module provides type definitions and implementations for the 2 | -- | `Document` interface, which is part of the W3C DOM API. 3 | -- | 4 | -- | The DOM API doesn't actually give you any way of getting hold of a 5 | -- | `Document` by itself. To do that, you will need to look at one of the 6 | -- | other APIs which build on the DOM API. For example, `window.document` is 7 | -- | part of the HTML5 API, and so the relevant binding can be found in 8 | -- | `Web.HTML.Window`, which is part of the `purescript-web-html` package. 9 | module Web.DOM.Document 10 | ( Document 11 | , fromNode 12 | , fromParentNode 13 | , fromNonElementParentNode 14 | , fromEventTarget 15 | , toNode 16 | , toParentNode 17 | , toNonElementParentNode 18 | , toEventTarget 19 | , url 20 | , documentURI 21 | , origin 22 | , compatMode 23 | , characterSet 24 | , contentType 25 | , doctype 26 | , documentElement 27 | , getElementsByTagName 28 | , getElementsByTagNameNS 29 | , getElementsByClassName 30 | , createElement 31 | , createElementNS 32 | , createDocumentFragment 33 | , createTextNode 34 | , createComment 35 | , createProcessingInstruction 36 | , importNode 37 | , adoptNode 38 | ) where 39 | 40 | import Prelude 41 | 42 | import Data.Maybe (Maybe, fromMaybe) 43 | import Data.Nullable (Nullable, toMaybe, toNullable) 44 | import Effect (Effect) 45 | import Unsafe.Coerce (unsafeCoerce) 46 | import Web.DOM.ClassName (ClassName) 47 | import Web.DOM.Comment (Comment) 48 | import Web.DOM.Document.CompatMode (CompatMode) 49 | import Web.DOM.Document.CompatMode as CompatMode 50 | import Web.DOM.DocumentFragment (DocumentFragment) 51 | import Web.DOM.DocumentType (DocumentType) 52 | import Web.DOM.Element (Element) 53 | import Web.DOM.ElementName (ElementName) 54 | import Web.DOM.HTMLCollection (HTMLCollection) 55 | import Web.DOM.Internal.Types (Node) 56 | import Web.DOM.NamespaceURI (NamespaceURI) 57 | import Web.DOM.NonElementParentNode (NonElementParentNode) 58 | import Web.DOM.ParentNode (ParentNode) 59 | import Web.DOM.ProcessingInstruction (ProcessingInstruction) 60 | import Web.DOM.Text (Text) 61 | import Web.Event.EventTarget (EventTarget) 62 | import Web.Internal.FFI (unsafeReadProtoTagged) 63 | 64 | foreign import data Document :: Type 65 | 66 | fromNode :: Node -> Maybe Document 67 | fromNode = unsafeReadProtoTagged "Document" 68 | 69 | fromParentNode :: ParentNode -> Maybe Document 70 | fromParentNode = unsafeReadProtoTagged "Document" 71 | 72 | fromNonElementParentNode :: NonElementParentNode -> Maybe Document 73 | fromNonElementParentNode = unsafeReadProtoTagged "Document" 74 | 75 | fromEventTarget :: EventTarget -> Maybe Document 76 | fromEventTarget = unsafeReadProtoTagged "Document" 77 | 78 | toNode :: Document -> Node 79 | toNode = unsafeCoerce 80 | 81 | toParentNode :: Document -> ParentNode 82 | toParentNode = unsafeCoerce 83 | 84 | toNonElementParentNode :: Document -> NonElementParentNode 85 | toNonElementParentNode = unsafeCoerce 86 | 87 | toEventTarget :: Document -> EventTarget 88 | toEventTarget = unsafeCoerce 89 | 90 | foreign import url :: Document -> Effect String 91 | foreign import documentURI :: Document -> Effect String 92 | foreign import origin :: Document -> Effect String 93 | 94 | foreign import _compatMode :: Document -> Effect String 95 | 96 | compatMode :: Document -> Effect CompatMode 97 | compatMode doc = fromMaybe CompatMode.CSS1Compat <<< CompatMode.parse <$> _compatMode doc 98 | 99 | foreign import characterSet :: Document -> Effect String 100 | foreign import contentType :: Document -> Effect String 101 | 102 | doctype :: Document -> Maybe DocumentType 103 | doctype = toMaybe <<< _doctype 104 | 105 | foreign import _doctype :: Document -> Nullable DocumentType 106 | 107 | documentElement :: Document -> Effect (Maybe Element) 108 | documentElement = map toMaybe <<< _documentElement 109 | 110 | foreign import _documentElement :: Document -> Effect (Nullable Element) 111 | 112 | foreign import getElementsByTagName :: ElementName -> Document -> Effect HTMLCollection 113 | 114 | getElementsByTagNameNS :: Maybe NamespaceURI -> ElementName -> Document -> Effect HTMLCollection 115 | getElementsByTagNameNS = _getElementsByTagNameNS <<< toNullable 116 | 117 | foreign import _getElementsByTagNameNS :: Nullable NamespaceURI -> ElementName -> Document -> Effect HTMLCollection 118 | foreign import getElementsByClassName :: ClassName -> Document -> Effect HTMLCollection 119 | 120 | foreign import createElement :: ElementName -> Document -> Effect Element 121 | 122 | createElementNS :: Maybe NamespaceURI -> ElementName -> Document -> Effect Element 123 | createElementNS = _createElementNS <<< toNullable 124 | 125 | foreign import _createElementNS :: Nullable NamespaceURI -> ElementName -> Document -> Effect Element 126 | foreign import createDocumentFragment :: Document -> Effect DocumentFragment 127 | foreign import createTextNode :: String -> Document -> Effect Text 128 | foreign import createComment :: String -> Document -> Effect Comment 129 | foreign import createProcessingInstruction :: String -> String -> Document -> Effect ProcessingInstruction 130 | 131 | foreign import importNode :: Node -> Boolean -> Document -> Effect Node 132 | foreign import adoptNode :: Node -> Document -> Effect Node 133 | -------------------------------------------------------------------------------- /src/Web/DOM/Document/CompatMode.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Document.CompatMode where 2 | 3 | import Data.Maybe (Maybe(..)) 4 | 5 | data CompatMode 6 | = BackCompat 7 | | CSS1Compat 8 | 9 | parse ∷ String -> Maybe CompatMode 10 | parse = case _ of 11 | "BackCompat" -> Just BackCompat 12 | "CSS1Compat" -> Just CSS1Compat 13 | _ -> Nothing 14 | 15 | print ∷ CompatMode -> String 16 | print = case _ of 17 | BackCompat → "BackCompat" 18 | CSS1Compat → "CSS1Compat" 19 | -------------------------------------------------------------------------------- /src/Web/DOM/DocumentFragment.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.DocumentFragment where 2 | 3 | import Data.Maybe (Maybe) 4 | import Unsafe.Coerce (unsafeCoerce) 5 | import Web.DOM.ChildNode (ChildNode) 6 | import Web.DOM.Internal.Types (Node) 7 | import Web.DOM.NonElementParentNode (NonElementParentNode) 8 | import Web.DOM.ParentNode (ParentNode) 9 | import Web.Event.EventTarget (EventTarget) 10 | import Web.Internal.FFI (unsafeReadProtoTagged) 11 | 12 | foreign import data DocumentFragment :: Type 13 | 14 | fromNode :: Node -> Maybe DocumentFragment 15 | fromNode = unsafeReadProtoTagged "DocumentFragment" 16 | 17 | fromChildNode :: ChildNode -> Maybe DocumentFragment 18 | fromChildNode = unsafeReadProtoTagged "DocumentFragment" 19 | 20 | fromParentNode :: ParentNode -> Maybe DocumentFragment 21 | fromParentNode = unsafeReadProtoTagged "DocumentFragment" 22 | 23 | fromNonElementParentNode :: NonElementParentNode -> Maybe DocumentFragment 24 | fromNonElementParentNode = unsafeReadProtoTagged "DocumentFragment" 25 | 26 | fromEventTarget :: EventTarget -> Maybe DocumentFragment 27 | fromEventTarget = unsafeReadProtoTagged "DocumentFragment" 28 | 29 | toNode :: DocumentFragment -> Node 30 | toNode = unsafeCoerce 31 | 32 | toChildNode :: DocumentFragment -> ChildNode 33 | toChildNode = unsafeCoerce 34 | 35 | toParentNode :: DocumentFragment -> ParentNode 36 | toParentNode = unsafeCoerce 37 | 38 | toNonElementParentNode :: DocumentFragment -> NonElementParentNode 39 | toNonElementParentNode = unsafeCoerce 40 | 41 | toEventTarget :: DocumentFragment -> EventTarget 42 | toEventTarget = unsafeCoerce 43 | -------------------------------------------------------------------------------- /src/Web/DOM/DocumentType.js: -------------------------------------------------------------------------------- 1 | var getProp = function (name) { 2 | return function (doctype) { 3 | return doctype[name]; 4 | }; 5 | }; 6 | 7 | export const name = getProp("name"); 8 | export const publicId = getProp("publicId"); 9 | export const systemId = getProp("systemId"); 10 | -------------------------------------------------------------------------------- /src/Web/DOM/DocumentType.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.DocumentType where 2 | 3 | import Data.Maybe (Maybe) 4 | import Unsafe.Coerce (unsafeCoerce) 5 | import Web.DOM.ChildNode (ChildNode) 6 | import Web.DOM.Internal.Types (Node) 7 | import Web.Event.EventTarget (EventTarget) 8 | import Web.Internal.FFI (unsafeReadProtoTagged) 9 | 10 | foreign import data DocumentType :: Type 11 | 12 | fromNode :: Node -> Maybe DocumentType 13 | fromNode = unsafeReadProtoTagged "DocumentType" 14 | 15 | fromChildNode :: ChildNode -> Maybe DocumentType 16 | fromChildNode = unsafeReadProtoTagged "DocumentType" 17 | 18 | fromEventTarget :: EventTarget -> Maybe DocumentType 19 | fromEventTarget = unsafeReadProtoTagged "DocumentType" 20 | 21 | toNode :: DocumentType -> Node 22 | toNode = unsafeCoerce 23 | 24 | toChildNode :: DocumentType -> ChildNode 25 | toChildNode = unsafeCoerce 26 | 27 | toEventTarget :: DocumentType -> EventTarget 28 | toEventTarget = unsafeCoerce 29 | 30 | foreign import name :: DocumentType -> String 31 | foreign import publicId :: DocumentType -> String 32 | foreign import systemId :: DocumentType -> String 33 | -------------------------------------------------------------------------------- /src/Web/DOM/Element.js: -------------------------------------------------------------------------------- 1 | var getProp = function (name) { 2 | return function (doctype) { 3 | return doctype[name]; 4 | }; 5 | }; 6 | 7 | export const _namespaceURI = getProp("namespaceURI"); 8 | export const _prefix = getProp("prefix"); 9 | export const localName = getProp("localName"); 10 | export const tagName = getProp("tagName"); 11 | 12 | export function id(node) { 13 | return function () { 14 | return node.id; 15 | }; 16 | } 17 | 18 | export function setId(id) { 19 | return function (node) { 20 | return function () { 21 | node.id = id; 22 | }; 23 | }; 24 | } 25 | 26 | export function className(node) { 27 | return function () { 28 | return node.className; 29 | }; 30 | } 31 | 32 | export function classList(element) { 33 | return function () { 34 | return element.classList; 35 | }; 36 | } 37 | 38 | export function setClassName(className) { 39 | return function (node) { 40 | return function () { 41 | node.className = className; 42 | }; 43 | }; 44 | } 45 | 46 | export function getElementsByTagName(localName) { 47 | return function (doc) { 48 | return function () { 49 | return doc.getElementsByTagName(localName); 50 | }; 51 | }; 52 | } 53 | 54 | export function _getElementsByTagNameNS(ns) { 55 | return function (localName) { 56 | return function (doc) { 57 | return function () { 58 | return doc.getElementsByTagNameNS(ns, localName); 59 | }; 60 | }; 61 | }; 62 | } 63 | 64 | export function getElementsByClassName(classNames) { 65 | return function (doc) { 66 | return function () { 67 | return doc.getElementsByClassName(classNames); 68 | }; 69 | }; 70 | } 71 | 72 | export const attributes = (element) => () => element.attributes; 73 | 74 | export function setAttribute(name) { 75 | return function (value) { 76 | return function (element) { 77 | return function () { 78 | element.setAttribute(name, value); 79 | }; 80 | }; 81 | }; 82 | } 83 | 84 | export function _getAttribute(name) { 85 | return function (element) { 86 | return function () { 87 | return element.getAttribute(name); 88 | }; 89 | }; 90 | } 91 | 92 | export function hasAttribute(name) { 93 | return function (element) { 94 | return function () { 95 | return element.hasAttribute(name); 96 | }; 97 | }; 98 | } 99 | 100 | export function removeAttribute(name) { 101 | return function (element) { 102 | return function () { 103 | element.removeAttribute(name); 104 | }; 105 | }; 106 | } 107 | 108 | export function matches(selector) { 109 | return function(element) { 110 | return function () { 111 | return element.matches(selector); 112 | }; 113 | }; 114 | } 115 | 116 | export function _closest(selector) { 117 | return function(element) { 118 | return function () { 119 | return element.closest(selector); 120 | }; 121 | }; 122 | } 123 | 124 | // - CSSOM --------------------------------------------------------------------- 125 | 126 | export function scrollTop(node) { 127 | return function () { 128 | return node.scrollTop; 129 | }; 130 | } 131 | 132 | export function setScrollTop(scrollTop) { 133 | return function (node) { 134 | return function () { 135 | node.scrollTop = scrollTop; 136 | }; 137 | }; 138 | } 139 | 140 | export function scrollLeft(node) { 141 | return function () { 142 | return node.scrollLeft; 143 | }; 144 | } 145 | 146 | export function setScrollLeft(scrollLeft) { 147 | return function (node) { 148 | return function () { 149 | node.scrollLeft = scrollLeft; 150 | }; 151 | }; 152 | } 153 | 154 | export function scrollWidth(el) { 155 | return function () { 156 | return el.scrollWidth; 157 | }; 158 | } 159 | 160 | export function scrollHeight(el) { 161 | return function () { 162 | return el.scrollHeight; 163 | }; 164 | } 165 | 166 | export function clientTop(el) { 167 | return function () { 168 | return el.clientTop; 169 | }; 170 | } 171 | 172 | export function clientLeft(el) { 173 | return function () { 174 | return el.clientLeft; 175 | }; 176 | } 177 | 178 | export function clientWidth(el) { 179 | return function () { 180 | return el.clientWidth; 181 | }; 182 | } 183 | 184 | export function clientHeight(el) { 185 | return function () { 186 | return el.clientHeight; 187 | }; 188 | } 189 | 190 | export function getBoundingClientRect(el) { 191 | return function () { 192 | var rect = el.getBoundingClientRect(); 193 | return { 194 | top: rect.top, 195 | right: rect.right, 196 | bottom: rect.bottom, 197 | left: rect.left, 198 | width: rect.width, 199 | height: rect.height, 200 | x: rect.x, 201 | y: rect.y 202 | }; 203 | }; 204 | } 205 | 206 | export function _attachShadow(props) { 207 | return function (el) { 208 | return function() { 209 | return el.attachShadow(props); 210 | }; 211 | }; 212 | } 213 | -------------------------------------------------------------------------------- /src/Web/DOM/Element.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Element 2 | ( module Exports 3 | , fromNode 4 | , fromChildNode 5 | , fromNonDocumentTypeChildNode 6 | , fromParentNode 7 | , fromEventTarget 8 | , toNode 9 | , toChildNode 10 | , toNonDocumentTypeChildNode 11 | , toParentNode 12 | , toEventTarget 13 | , namespaceURI 14 | , prefix 15 | , localName 16 | , tagName 17 | , id 18 | , setId 19 | , className 20 | , classList 21 | , setClassName 22 | , getElementsByTagName 23 | , getElementsByTagNameNS 24 | , getElementsByClassName 25 | , attributes 26 | , setAttribute 27 | , getAttribute 28 | , hasAttribute 29 | , removeAttribute 30 | , matches 31 | , closest 32 | , scrollTop 33 | , setScrollTop 34 | , scrollLeft 35 | , setScrollLeft 36 | , scrollWidth 37 | , scrollHeight 38 | , clientTop 39 | , clientLeft 40 | , clientWidth 41 | , clientHeight 42 | , getBoundingClientRect 43 | , DOMRect 44 | , ShadowRootInit 45 | , attachShadow 46 | ) where 47 | 48 | import Prelude 49 | 50 | import Data.Maybe (Maybe) 51 | import Data.Nullable (Nullable, toMaybe, toNullable) 52 | import Effect (Effect) 53 | import Unsafe.Coerce (unsafeCoerce) 54 | import Web.DOM.AttrName (AttrName) 55 | import Web.DOM.ChildNode (ChildNode) 56 | import Web.DOM.ClassName (ClassName) 57 | import Web.DOM.DOMTokenList (DOMTokenList) 58 | import Web.DOM.ElementId (ElementId) 59 | import Web.DOM.ElementName (ElementName) 60 | import Web.DOM.Internal.Types (Element) as Exports 61 | import Web.DOM.Internal.Types (Element, HTMLCollection, Node, NamedNodeMap) 62 | import Web.DOM.NamespacePrefix (NamespacePrefix) 63 | import Web.DOM.NamespaceURI (NamespaceURI) 64 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) 65 | import Web.DOM.ParentNode (ParentNode, QuerySelector) 66 | import Web.DOM.ParentNode (QuerySelector) as Exports 67 | import Web.DOM.ShadowRoot (ShadowRoot, ShadowRootMode) 68 | import Web.Event.EventTarget (EventTarget) 69 | import Web.Internal.FFI (unsafeReadProtoTagged) 70 | 71 | fromNode :: Node -> Maybe Element 72 | fromNode = unsafeReadProtoTagged "Element" 73 | 74 | fromChildNode :: ChildNode -> Maybe Element 75 | fromChildNode = unsafeReadProtoTagged "Element" 76 | 77 | fromNonDocumentTypeChildNode :: NonDocumentTypeChildNode -> Maybe Element 78 | fromNonDocumentTypeChildNode = unsafeReadProtoTagged "Element" 79 | 80 | fromParentNode :: ParentNode -> Maybe Element 81 | fromParentNode = unsafeReadProtoTagged "Element" 82 | 83 | fromEventTarget :: EventTarget -> Maybe Element 84 | fromEventTarget = unsafeReadProtoTagged "Element" 85 | 86 | toNode :: Element -> Node 87 | toNode = unsafeCoerce 88 | 89 | toChildNode :: Element -> ChildNode 90 | toChildNode = unsafeCoerce 91 | 92 | toNonDocumentTypeChildNode :: Element -> NonDocumentTypeChildNode 93 | toNonDocumentTypeChildNode = unsafeCoerce 94 | 95 | toParentNode :: Element -> ParentNode 96 | toParentNode = unsafeCoerce 97 | 98 | toEventTarget :: Element -> EventTarget 99 | toEventTarget = unsafeCoerce 100 | 101 | namespaceURI :: Element -> Maybe NamespaceURI 102 | namespaceURI = toMaybe <<< _namespaceURI 103 | 104 | prefix :: Element -> Maybe NamespacePrefix 105 | prefix = toMaybe <<< _prefix 106 | 107 | foreign import _namespaceURI :: Element -> Nullable NamespaceURI 108 | foreign import _prefix :: Element -> Nullable NamespacePrefix 109 | foreign import localName :: Element -> ElementName 110 | foreign import tagName :: Element -> ElementName 111 | 112 | foreign import id :: Element -> Effect ElementId 113 | foreign import setId :: ElementId -> Element -> Effect Unit 114 | foreign import className :: Element -> Effect ClassName 115 | foreign import classList :: Element -> Effect DOMTokenList 116 | foreign import setClassName :: ClassName -> Element -> Effect Unit 117 | 118 | foreign import getElementsByTagName :: ElementName -> Element -> Effect HTMLCollection 119 | 120 | getElementsByTagNameNS :: Maybe NamespaceURI -> ElementName -> Element -> Effect HTMLCollection 121 | getElementsByTagNameNS = _getElementsByTagNameNS <<< toNullable 122 | 123 | foreign import _getElementsByTagNameNS :: Nullable NamespaceURI -> ElementName -> Element -> Effect HTMLCollection 124 | 125 | foreign import getElementsByClassName :: ClassName -> Element -> Effect HTMLCollection 126 | 127 | foreign import attributes :: Element -> Effect NamedNodeMap 128 | 129 | foreign import setAttribute :: AttrName -> String -> Element -> Effect Unit 130 | 131 | getAttribute :: AttrName -> Element -> Effect (Maybe String) 132 | getAttribute attr = map toMaybe <<< _getAttribute attr 133 | 134 | foreign import _getAttribute :: AttrName -> Element -> Effect (Nullable String) 135 | foreign import hasAttribute :: AttrName -> Element -> Effect Boolean 136 | foreign import removeAttribute :: AttrName -> Element -> Effect Unit 137 | 138 | foreign import matches :: QuerySelector -> Element -> Effect Boolean 139 | 140 | closest :: QuerySelector -> Element -> Effect (Maybe Element) 141 | closest qs = map toMaybe <<< _closest qs 142 | 143 | foreign import _closest :: QuerySelector -> Element -> Effect (Nullable Element) 144 | 145 | foreign import scrollTop :: Element -> Effect Number 146 | foreign import setScrollTop :: Number -> Element -> Effect Unit 147 | 148 | foreign import scrollLeft :: Element -> Effect Number 149 | foreign import setScrollLeft :: Number -> Element -> Effect Unit 150 | 151 | foreign import scrollWidth :: Element -> Effect Number 152 | foreign import scrollHeight :: Element -> Effect Number 153 | foreign import clientTop :: Element -> Effect Number 154 | foreign import clientLeft :: Element -> Effect Number 155 | foreign import clientWidth :: Element -> Effect Number 156 | foreign import clientHeight :: Element -> Effect Number 157 | 158 | type DOMRect = 159 | { top :: Number 160 | , right :: Number 161 | , bottom :: Number 162 | , left :: Number 163 | , width :: Number 164 | , height :: Number 165 | , x :: Number 166 | , y :: Number 167 | } 168 | 169 | foreign import getBoundingClientRect :: Element -> Effect DOMRect 170 | 171 | type ShadowRootInit = 172 | { mode :: ShadowRootMode 173 | , delegatesFocus :: Boolean 174 | } 175 | 176 | attachShadow :: ShadowRootInit -> Element -> Effect ShadowRoot 177 | attachShadow = _attachShadow <<< initToProps 178 | 179 | type ShadowRootProps = 180 | { mode :: String 181 | , delegatesFocus :: Boolean 182 | } 183 | 184 | initToProps :: ShadowRootInit -> ShadowRootProps 185 | initToProps init = 186 | { mode: show init.mode 187 | , delegatesFocus: init.delegatesFocus 188 | } 189 | 190 | foreign import _attachShadow :: ShadowRootProps -> Element -> Effect ShadowRoot 191 | -------------------------------------------------------------------------------- /src/Web/DOM/ElementId.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ElementId where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | -- | A wrapper for strings which are used as element identifiers. 8 | newtype ElementId = ElementId String 9 | 10 | derive instance newtypeElementId :: Newtype ElementId _ 11 | derive newtype instance eqElementId :: Eq ElementId 12 | derive newtype instance ordElementId :: Ord ElementId 13 | -------------------------------------------------------------------------------- /src/Web/DOM/ElementName.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ElementName where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | -- | A wrapper for element names. 8 | newtype ElementName = ElementName String 9 | 10 | derive instance newtypeElementName :: Newtype ElementName _ 11 | derive newtype instance eqElementName :: Eq ElementName 12 | derive newtype instance ordElementName :: Ord ElementName 13 | -------------------------------------------------------------------------------- /src/Web/DOM/HTMLCollection.js: -------------------------------------------------------------------------------- 1 | export function length(list) { 2 | return function () { 3 | return list.length; 4 | }; 5 | } 6 | 7 | export function toArray(list) { 8 | return function () { 9 | return [].slice.call(list); 10 | }; 11 | } 12 | 13 | export function _item(index) { 14 | return function (list) { 15 | return function () { 16 | return list.item(index); 17 | }; 18 | }; 19 | } 20 | 21 | export function _namedItem(name) { 22 | return function (list) { 23 | return function () { 24 | return list.namedItem(name); 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/Web/DOM/HTMLCollection.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.HTMLCollection 2 | ( module Exports 3 | , length 4 | , item 5 | , namedItem 6 | , toArray 7 | ) where 8 | 9 | import Prelude 10 | 11 | import Data.Maybe (Maybe) 12 | import Data.Nullable (Nullable, toMaybe) 13 | import Effect (Effect) 14 | import Web.DOM.Internal.Types (Element, HTMLCollection) 15 | import Web.DOM.Internal.Types (HTMLCollection) as Exports 16 | 17 | -- | The number of elements in a HTMLCollection. 18 | foreign import length :: HTMLCollection -> Effect Int 19 | 20 | -- | The elements of an HTMLCollection represented in an array. 21 | foreign import toArray :: HTMLCollection -> Effect (Array Element) 22 | 23 | -- | The element in a HTMLCollection at the specified index, or Nothing if no such 24 | -- | element exists. 25 | item :: Int -> HTMLCollection -> Effect (Maybe Element) 26 | item i = map toMaybe <<< _item i 27 | 28 | foreign import _item :: Int -> HTMLCollection -> Effect (Nullable Element) 29 | 30 | -- | The first element with the specified name or ID in a HTMLCollection, or 31 | -- | Nothing if no such element exists. 32 | namedItem :: String -> HTMLCollection -> Effect (Maybe Element) 33 | namedItem id = map toMaybe <<< _namedItem id 34 | 35 | foreign import _namedItem :: String -> HTMLCollection -> Effect (Nullable Element) 36 | -------------------------------------------------------------------------------- /src/Web/DOM/Internal/Types.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Internal.Types where 2 | 3 | foreign import data Node :: Type 4 | foreign import data NodeList :: Type 5 | 6 | foreign import data Element :: Type 7 | foreign import data HTMLCollection :: Type 8 | 9 | foreign import data NamedNodeMap :: Type 10 | foreign import data Attr :: Type -------------------------------------------------------------------------------- /src/Web/DOM/MutationObserver.js: -------------------------------------------------------------------------------- 1 | export function mutationObserver(cb) { 2 | return function () { 3 | return new MutationObserver(function (mr, mo) { 4 | return cb(mr)(mo)(); 5 | }); 6 | }; 7 | } 8 | 9 | export function _observe(node) { 10 | return function (config) { 11 | return function (mo) { 12 | return function () { 13 | return mo.observe(node, config); 14 | }; 15 | }; 16 | }; 17 | } 18 | 19 | export function disconnect(mo) { 20 | return function () { 21 | return mo.disconnect(); 22 | }; 23 | } 24 | 25 | export function takeRecords(mo) { 26 | return function () { 27 | return mo.takeRecords(); 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/Web/DOM/MutationObserver.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.MutationObserver 2 | ( MutationObserver 3 | , MutationObserverInitFields 4 | , mutationObserver 5 | , observe 6 | , disconnect 7 | , takeRecords 8 | ) where 9 | 10 | import Prelude 11 | 12 | import Effect (Effect) 13 | import Prim.Row (class Union) 14 | import Web.DOM.MutationRecord (MutationRecord) 15 | import Web.DOM.Node (Node) 16 | 17 | foreign import data MutationObserver :: Type 18 | 19 | type MutationObserverInitFields = 20 | ( childList :: Boolean 21 | , attributes :: Boolean 22 | , characterData :: Boolean 23 | , subtree :: Boolean 24 | , attributeOldValue :: Boolean 25 | , characterDataOldValue :: Boolean 26 | , attributeFilter :: Array String 27 | ) 28 | 29 | foreign import mutationObserver 30 | :: ((Array MutationRecord) -> MutationObserver -> Effect Unit) 31 | -> Effect MutationObserver 32 | 33 | foreign import _observe :: forall r. Node -> Record r -> MutationObserver -> Effect Unit 34 | 35 | observe 36 | :: forall r rx 37 | . Union r rx MutationObserverInitFields 38 | => Node 39 | -> Record r 40 | -> MutationObserver 41 | -> Effect Unit 42 | observe = _observe 43 | 44 | foreign import disconnect :: MutationObserver -> Effect Unit 45 | 46 | foreign import takeRecords :: MutationObserver -> Effect (Array MutationRecord) 47 | -------------------------------------------------------------------------------- /src/Web/DOM/MutationRecord.js: -------------------------------------------------------------------------------- 1 | export function typeString(mr) { 2 | return function () { 3 | return mr.type; 4 | }; 5 | } 6 | 7 | export function target(mr) { 8 | return function () { 9 | return mr.target; 10 | }; 11 | } 12 | 13 | export function addedNodes(mr) { 14 | return function () { 15 | return mr.addedNodes; 16 | }; 17 | } 18 | 19 | export function removedNodes(mr) { 20 | return function () { 21 | return mr.removedNodes; 22 | }; 23 | } 24 | 25 | export function _nextSibling(mr) { 26 | return function () { 27 | return mr.nextSibling; 28 | }; 29 | } 30 | 31 | export function _previousSibling(mr) { 32 | return function () { 33 | return mr.previousSibling; 34 | }; 35 | } 36 | 37 | export function _attributeName(mr) { 38 | return function () { 39 | return mr.attributeName; 40 | }; 41 | } 42 | 43 | export function _attributeNamespace(mr) { 44 | return function () { 45 | return mr.attributeNamespace; 46 | }; 47 | } 48 | 49 | export function _oldValue(mr) { 50 | return function () { 51 | return mr.oldValue; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /src/Web/DOM/MutationRecord.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.MutationRecord 2 | ( MutationRecord 3 | , MutationRecordType(..) 4 | , typeString 5 | , type_ 6 | , target 7 | , addedNodes 8 | , removedNodes 9 | , nextSibling 10 | , previousSibling 11 | , attributeName 12 | , attributeNamespace 13 | , oldValue 14 | ) where 15 | 16 | import Prelude 17 | 18 | import Data.Maybe (Maybe) 19 | import Data.Nullable (Nullable, toMaybe) 20 | import Effect (Effect) 21 | import Web.DOM.AttrName (AttrName) 22 | import Web.DOM.NamespaceURI (NamespaceURI) 23 | import Web.DOM.Node (Node) 24 | import Web.DOM.NodeList (NodeList) 25 | 26 | foreign import data MutationRecord :: Type 27 | 28 | data MutationRecordType 29 | = MutationRecordAttributes 30 | | MutationRecordCharacterData 31 | | MutationRecordChildList 32 | 33 | foreign import typeString :: MutationRecord -> Effect String 34 | 35 | type_ :: Partial => MutationRecord -> Effect MutationRecordType 36 | type_ = map stringToType <<< typeString 37 | where 38 | stringToType = case _ of 39 | "attributes" -> MutationRecordAttributes 40 | "characterData" -> MutationRecordCharacterData 41 | "childList" -> MutationRecordChildList 42 | 43 | foreign import target :: MutationRecord -> Effect Node 44 | 45 | foreign import addedNodes :: MutationRecord -> Effect NodeList 46 | 47 | foreign import removedNodes :: MutationRecord -> Effect NodeList 48 | 49 | foreign import _nextSibling :: MutationRecord -> Effect (Nullable Node) 50 | 51 | nextSibling :: MutationRecord -> Effect (Maybe Node) 52 | nextSibling = map toMaybe <<< _nextSibling 53 | 54 | foreign import _previousSibling :: MutationRecord -> Effect (Nullable Node) 55 | 56 | previousSibling :: MutationRecord -> Effect (Maybe Node) 57 | previousSibling = map toMaybe <<< _previousSibling 58 | 59 | foreign import _attributeName :: MutationRecord -> Effect (Nullable AttrName) 60 | 61 | attributeName :: MutationRecord -> Effect (Maybe AttrName) 62 | attributeName = map toMaybe <<< _attributeName 63 | 64 | foreign import _attributeNamespace :: MutationRecord -> Effect (Nullable NamespaceURI) 65 | 66 | attributeNamespace :: MutationRecord -> Effect (Maybe NamespaceURI) 67 | attributeNamespace = map toMaybe <<< _attributeNamespace 68 | 69 | foreign import _oldValue :: MutationRecord -> Effect (Nullable String) 70 | 71 | oldValue :: MutationRecord -> Effect (Maybe String) 72 | oldValue = map toMaybe <<< _oldValue 73 | -------------------------------------------------------------------------------- /src/Web/DOM/NamedNodeMap.js: -------------------------------------------------------------------------------- 1 | export const length = (namedNodeMap) => () => namedNodeMap.length; 2 | 3 | export function getAttributes(namedNodeMap) { 4 | return function () { 5 | const result = []; 6 | for (const attr of namedNodeMap) { 7 | result.push(attr); 8 | } 9 | return result; 10 | }; 11 | } 12 | 13 | export function getNamedItem(name) { 14 | return function (namedNodeMap) { 15 | return function () { 16 | return namedNodeMap.getNamedItem(name); 17 | }; 18 | }; 19 | } 20 | 21 | export function getNamedItemNS(namespace) { 22 | return function (name) { 23 | return function (namedNodeMap) { 24 | return function () { 25 | return namedNodeMap.getNamedItemNS(namespace, name); 26 | }; 27 | }; 28 | }; 29 | } 30 | 31 | export function setNamedItem(name) { 32 | return function (namedNodeMap) { 33 | return function () { 34 | return namedNodeMap.setNamedItem(name); 35 | }; 36 | }; 37 | } 38 | 39 | export function setNamedItemNS(name) { 40 | return function (namedNodeMap) { 41 | return function () { 42 | return namedNodeMap.setNamedItemNS(name); 43 | }; 44 | }; 45 | } 46 | 47 | export function removeNamedItem(name) { 48 | return function (namedNodeMap) { 49 | return function () { 50 | return namedNodeMap.removeNamedItem(name); 51 | }; 52 | }; 53 | } 54 | 55 | export function removeNamedItemNS(namespace) { 56 | return function (namedNodeMap) { 57 | return function (name) { 58 | return function () { 59 | return namedNodeMap.removeNamedItemNS(namespace, name); 60 | }; 61 | }; 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /src/Web/DOM/NamedNodeMap.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NamedNodeMap 2 | ( module Exports 3 | , length 4 | , getAttributes 5 | , getNamedItem 6 | , getNamedItemNS 7 | , setNamedItem 8 | , setNamedItemNS 9 | , removeNamedItem 10 | , removeNamedItemNS 11 | ) where 12 | 13 | import Prelude 14 | 15 | import Effect (Effect) 16 | import Web.DOM.AttrName (AttrName) 17 | import Web.DOM.Internal.Types (NamedNodeMap) as Exports 18 | import Web.DOM.Internal.Types (NamedNodeMap, Attr) 19 | import Web.DOM.NamespaceURI (NamespaceURI) 20 | 21 | foreign import length :: NamedNodeMap -> Effect Int 22 | 23 | foreign import getAttributes :: NamedNodeMap -> Effect (Array Attr) 24 | 25 | foreign import getNamedItem :: AttrName -> NamedNodeMap -> Effect Attr 26 | 27 | foreign import getNamedItemNS :: NamespaceURI -> AttrName -> NamedNodeMap -> Effect Attr 28 | 29 | foreign import setNamedItem :: Attr -> NamedNodeMap -> Effect Unit 30 | 31 | foreign import setNamedItemNS :: Attr -> NamedNodeMap -> Effect Unit 32 | 33 | foreign import removeNamedItem :: AttrName -> NamedNodeMap -> Effect Unit 34 | 35 | foreign import removeNamedItemNS :: NamespaceURI -> AttrName -> NamedNodeMap -> Effect Unit 36 | -------------------------------------------------------------------------------- /src/Web/DOM/NamespacePrefix.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NamespacePrefix where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | newtype NamespacePrefix = NamespacePrefix String 8 | 9 | derive instance Newtype NamespacePrefix _ 10 | derive newtype instance Eq NamespacePrefix 11 | derive newtype instance Ord NamespacePrefix 12 | -------------------------------------------------------------------------------- /src/Web/DOM/NamespaceURI.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NamespaceURI where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | newtype NamespaceURI = NamespaceURI String 8 | 9 | derive instance Newtype NamespaceURI _ 10 | derive newtype instance Eq NamespaceURI 11 | derive newtype instance Ord NamespaceURI 12 | -------------------------------------------------------------------------------- /src/Web/DOM/Node.js: -------------------------------------------------------------------------------- 1 | var getEffProp = function (name) { 2 | return function (node) { 3 | return function () { 4 | return node[name]; 5 | }; 6 | }; 7 | }; 8 | 9 | export function nodeTypeIndex(node) { 10 | return node.nodeType; 11 | } 12 | 13 | export function nodeName(node) { 14 | return node.nodeName; 15 | } 16 | 17 | export const baseURI = getEffProp("baseURI"); 18 | export const _ownerDocument = getEffProp("ownerDocument"); 19 | export const _parentNode = getEffProp("parentNode"); 20 | export const _parentElement = getEffProp("parentElement"); 21 | 22 | export function hasChildNodes(node) { 23 | return function () { 24 | return node.hasChildNodes(); 25 | }; 26 | } 27 | 28 | export const childNodes = getEffProp("childNodes"); 29 | export const _firstChild = getEffProp("firstChild"); 30 | export const _lastChild = getEffProp("lastChild"); 31 | export const _previousSibling = getEffProp("previousSibling"); 32 | export const _nextSibling = getEffProp("nextSibling"); 33 | export const _nodeValue = getEffProp("nodeValue"); 34 | 35 | export function setNodeValue(value) { 36 | return function (node) { 37 | return function () { 38 | node.nodeValue = value; 39 | }; 40 | }; 41 | } 42 | 43 | export const textContent = getEffProp("textContent"); 44 | 45 | export function setTextContent(value) { 46 | return function (node) { 47 | return function () { 48 | node.textContent = value; 49 | }; 50 | }; 51 | } 52 | 53 | export function normalize(node) { 54 | return function () { 55 | node.normalize(); 56 | }; 57 | } 58 | 59 | export function clone(node) { 60 | return function () { 61 | return node.cloneNode(false); 62 | }; 63 | } 64 | 65 | export function deepClone(node) { 66 | return function () { 67 | return node.cloneNode(true); 68 | }; 69 | } 70 | 71 | export function isEqualNode(node1) { 72 | return function (node2) { 73 | return function () { 74 | return node1.isEqualNode(node2); 75 | }; 76 | }; 77 | } 78 | 79 | export function compareDocumentPositionBits(node1) { 80 | return function (node2) { 81 | return function () { 82 | return node1.compareDocumentPosition(node2); 83 | }; 84 | }; 85 | } 86 | 87 | export function contains(node1) { 88 | return function (node2) { 89 | return function () { 90 | return node1.contains(node2); 91 | }; 92 | }; 93 | } 94 | 95 | export function _lookupPrefix(prefix) { 96 | return function (node) { 97 | return function () { 98 | return node.lookupPrefix(prefix); 99 | }; 100 | }; 101 | } 102 | 103 | export function _lookupNamespaceURI(ns) { 104 | return function (node) { 105 | return function () { 106 | return node.lookupNamespaceURI(ns); 107 | }; 108 | }; 109 | } 110 | 111 | export function isDefaultNamespace(ns) { 112 | return function (node) { 113 | return function () { 114 | return node.isDefaultNamespace(ns); 115 | }; 116 | }; 117 | } 118 | 119 | export function insertBefore(node1) { 120 | return function (node2) { 121 | return function (parent) { 122 | return function () { 123 | parent.insertBefore(node1, node2); 124 | }; 125 | }; 126 | }; 127 | } 128 | 129 | export function appendChild(node) { 130 | return function (parent) { 131 | return function () { 132 | parent.appendChild(node); 133 | }; 134 | }; 135 | } 136 | 137 | export function replaceChild(newChild) { 138 | return function (oldChild) { 139 | return function (parent) { 140 | return function () { 141 | parent.replaceChild(newChild, oldChild); 142 | }; 143 | }; 144 | }; 145 | } 146 | 147 | export function removeChild(node) { 148 | return function (parent) { 149 | return function () { 150 | parent.removeChild(node); 151 | }; 152 | }; 153 | } 154 | -------------------------------------------------------------------------------- /src/Web/DOM/Node.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Node 2 | ( module Exports 3 | , fromEventTarget 4 | , toEventTarget 5 | , nodeType 6 | , nodeTypeIndex 7 | , nodeName 8 | , baseURI 9 | , ownerDocument 10 | , parentNode 11 | , parentElement 12 | , hasChildNodes 13 | , childNodes 14 | , firstChild 15 | , lastChild 16 | , previousSibling 17 | , nextSibling 18 | , nodeValue 19 | , setNodeValue 20 | , textContent 21 | , setTextContent 22 | , normalize 23 | , clone 24 | , deepClone 25 | , isEqualNode 26 | , compareDocumentPositionBits 27 | , contains 28 | , lookupPrefix 29 | , lookupNamespaceURI 30 | , isDefaultNamespace 31 | , insertBefore 32 | , appendChild 33 | , replaceChild 34 | , removeChild 35 | ) where 36 | 37 | import Prelude 38 | 39 | import Data.Enum (toEnum) 40 | import Data.Maybe (Maybe, fromJust) 41 | import Data.Nullable (Nullable, toMaybe) 42 | import Effect (Effect) 43 | import Unsafe.Coerce (unsafeCoerce) 44 | import Web.DOM.Document (Document) 45 | import Web.DOM.Element (Element) 46 | import Web.DOM.Internal.Types (Node) as Exports 47 | import Web.DOM.Internal.Types (Node, NodeList) 48 | import Web.DOM.NamespacePrefix (NamespacePrefix) 49 | import Web.DOM.NamespaceURI (NamespaceURI) 50 | import Web.DOM.NodeType (NodeType) 51 | import Web.Event.EventTarget (EventTarget) 52 | import Web.Internal.FFI (unsafeReadProtoTagged) 53 | 54 | fromEventTarget :: EventTarget -> Maybe Node 55 | fromEventTarget = unsafeReadProtoTagged "Node" 56 | 57 | toEventTarget :: Node -> EventTarget 58 | toEventTarget = unsafeCoerce 59 | 60 | -- | The type of a node. 61 | nodeType :: Partial => Node -> NodeType 62 | nodeType = fromJust <<< toEnum <<< nodeTypeIndex 63 | 64 | -- | The numeric value for the type of a node. 65 | foreign import nodeTypeIndex :: Node -> Int 66 | 67 | -- | For elements this is the tag name, for document types this is the doctype 68 | -- | name, for processing instructions this is the target, for all other nodes 69 | -- | it is a string like `"#text"`, `"#comment", etc. depending on the node 70 | -- | type. 71 | foreign import nodeName :: Node -> String 72 | 73 | -- | The node's base URL. 74 | foreign import baseURI :: Node -> Effect String 75 | 76 | -- | The document the node belongs to, unless the node is a document in which 77 | -- | case the value is Nothing. 78 | ownerDocument :: Node -> Effect (Maybe Document) 79 | ownerDocument = map toMaybe <<< _ownerDocument 80 | 81 | foreign import _ownerDocument :: Node -> Effect (Nullable Document) 82 | 83 | -- | The parent node of the node. 84 | parentNode :: Node -> Effect (Maybe Node) 85 | parentNode = map toMaybe <<< _parentNode 86 | 87 | foreign import _parentNode :: Node -> Effect (Nullable Node) 88 | 89 | -- | The parent element of the node. 90 | parentElement :: Node -> Effect (Maybe Element) 91 | parentElement = map toMaybe <<< _parentElement 92 | 93 | foreign import _parentElement :: Node -> Effect (Nullable Element) 94 | 95 | -- | Indicates whether the node has any child nodes. 96 | foreign import hasChildNodes :: Node -> Effect Boolean 97 | 98 | -- | The children of the node. 99 | foreign import childNodes :: Node -> Effect NodeList 100 | 101 | -- | The first child of the node, or Nothing if the node has no children. 102 | firstChild :: Node -> Effect (Maybe Node) 103 | firstChild = map toMaybe <<< _firstChild 104 | 105 | foreign import _firstChild :: Node -> Effect (Nullable Node) 106 | 107 | 108 | -- | The last child of the node, or Nothing if the node has no children. 109 | lastChild :: Node -> Effect (Maybe Node) 110 | lastChild = map toMaybe <<< _lastChild 111 | 112 | foreign import _lastChild :: Node -> Effect (Nullable Node) 113 | 114 | -- | The previous sibling node, or Nothing if there is no previous sibling. 115 | previousSibling :: Node -> Effect (Maybe Node) 116 | previousSibling = map toMaybe <<< _previousSibling 117 | 118 | foreign import _previousSibling :: Node -> Effect (Nullable Node) 119 | 120 | -- | The next sibling node, or Nothing if there is no next sibling. 121 | nextSibling :: Node -> Effect (Maybe Node) 122 | nextSibling = map toMaybe <<< _nextSibling 123 | 124 | foreign import _nextSibling :: Node -> Effect (Nullable Node) 125 | 126 | -- | If the node type is text, comment, or processing instruction this is 127 | -- | `Just` the node's data, or `Nothing` in all other cases. 128 | nodeValue :: Node -> Effect (Maybe String) 129 | nodeValue = map toMaybe <<< _nodeValue 130 | 131 | foreign import _nodeValue :: Node -> Effect (Nullable String) 132 | 133 | -- | If the node type is text, comment, or processing instruction this allows 134 | -- | the node's data to be changed, or has no effect in all other cases. 135 | foreign import setNodeValue :: String -> Node -> Effect Unit 136 | 137 | -- | If the node type is document fragment, element, text, processing 138 | -- | instruction, or comment this is the node's data, or null in all other 139 | -- | cases. 140 | foreign import textContent :: Node -> Effect String 141 | 142 | -- | If the node type is document fragment, element, text, processing 143 | -- | instruction, or comment this allows the node's data to be changed, or has 144 | -- | no effect in all other cases. 145 | foreign import setTextContent :: String -> Node -> Effect Unit 146 | 147 | -- | Removes empty text nodes and then combines any remaining text nodes that 148 | -- | are contiguous. 149 | foreign import normalize :: Node -> Effect Unit 150 | 151 | -- | Clones the node without cloning the node's descendants. 152 | foreign import clone :: Node -> Effect Node 153 | 154 | -- | Clones the node and its descendants. 155 | foreign import deepClone :: Node -> Effect Node 156 | 157 | -- | Checks whether two nodes are equivalent. 158 | foreign import isEqualNode :: Node -> Node -> Effect Boolean 159 | 160 | -- TODO: compareDocumentPosition that returns a semigroup or something instead of the bitmask value 161 | 162 | -- | Compares the position of two nodes in the document. 163 | foreign import compareDocumentPositionBits :: Node -> Node -> Effect Int 164 | 165 | -- | Checks whether the second node is contained within the first 166 | foreign import contains :: Node -> Node -> Effect Boolean 167 | 168 | lookupPrefix :: NamespaceURI -> Node -> Effect (Maybe NamespacePrefix) 169 | lookupPrefix p = map toMaybe <<< _lookupPrefix p 170 | 171 | foreign import _lookupPrefix :: NamespaceURI -> Node -> Effect (Nullable NamespacePrefix) 172 | 173 | lookupNamespaceURI :: NamespacePrefix -> Node -> Effect (Maybe NamespaceURI) 174 | lookupNamespaceURI ns = map toMaybe <<< _lookupNamespaceURI ns 175 | 176 | foreign import _lookupNamespaceURI :: NamespacePrefix -> Node -> Effect (Nullable NamespaceURI) 177 | 178 | foreign import isDefaultNamespace :: NamespaceURI -> Node -> Effect Boolean 179 | 180 | -- | Inserts the first node before the second as a child of the third node. 181 | foreign import insertBefore :: Node -> Node -> Node -> Effect Unit 182 | 183 | -- | Appends the first node to the child node list of the second node. 184 | foreign import appendChild :: Node -> Node -> Effect Unit 185 | 186 | -- | Uses the first node as a replacement for the second node in the children 187 | -- | of the third node. 188 | foreign import replaceChild :: Node -> Node -> Node -> Effect Unit 189 | 190 | -- | Removes the first node from the children of the second node. 191 | foreign import removeChild :: Node -> Node -> Effect Unit 192 | -------------------------------------------------------------------------------- /src/Web/DOM/NodeList.js: -------------------------------------------------------------------------------- 1 | export function length(list) { 2 | return function () { 3 | return list.length; 4 | }; 5 | } 6 | 7 | export function toArray(list) { 8 | return function () { 9 | return [].slice.call(list); 10 | }; 11 | } 12 | 13 | export function _item(index) { 14 | return function (list) { 15 | return function () { 16 | return list.item(index); 17 | }; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/Web/DOM/NodeList.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NodeList 2 | ( module Exports 3 | , length 4 | , item 5 | , toArray 6 | ) where 7 | 8 | import Prelude 9 | 10 | import Data.Maybe (Maybe) 11 | import Data.Nullable (Nullable, toMaybe) 12 | import Effect (Effect) 13 | import Web.DOM.Internal.Types (Node, NodeList) 14 | import Web.DOM.Internal.Types (NodeList) as Exports 15 | 16 | -- | The number of items in a NodeList. 17 | foreign import length :: NodeList -> Effect Int 18 | 19 | -- | The elements of a NodeList represented in an array. 20 | foreign import toArray :: NodeList -> Effect (Array Node) 21 | 22 | -- | The item in a NodeList at the specified index, or Nothing if no such node 23 | -- | exists. 24 | item :: Int -> NodeList -> Effect (Maybe Node) 25 | item i = map toMaybe <<< _item i 26 | 27 | foreign import _item :: Int -> NodeList -> Effect (Nullable Node) 28 | -------------------------------------------------------------------------------- /src/Web/DOM/NodeType.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NodeType (NodeType(..)) where 2 | 3 | import Prelude 4 | import Data.Maybe (Maybe(..)) 5 | import Data.Enum (class Enum, class BoundedEnum, Cardinality(..), defaultSucc, defaultPred) 6 | 7 | data NodeType 8 | = ElementNode 9 | | AttributeNode 10 | | TextNode 11 | | CDATASectionNode 12 | | EntityReferenceNode 13 | | EntityNode 14 | | ProcessingInstructionNode 15 | | CommentNode 16 | | DocumentNode 17 | | DocumentTypeNode 18 | | DocumentFragmentNode 19 | | NotationNode 20 | 21 | derive instance eqNodeType :: Eq NodeType 22 | 23 | instance ordNodeType :: Ord NodeType where 24 | compare x y = compare (fromEnumNodeType x) (fromEnumNodeType y) 25 | 26 | instance boundedNodeType :: Bounded NodeType where 27 | bottom = ElementNode 28 | top = NotationNode 29 | 30 | instance enumNodeType :: Enum NodeType where 31 | succ = defaultSucc toEnumNodeType fromEnumNodeType 32 | pred = defaultPred toEnumNodeType fromEnumNodeType 33 | 34 | instance boundedEnumNodeType :: BoundedEnum NodeType where 35 | cardinality = Cardinality 12 36 | toEnum = toEnumNodeType 37 | fromEnum = fromEnumNodeType 38 | 39 | instance showNodeType :: Show NodeType where 40 | show ElementNode = "ElementNode" 41 | show AttributeNode = "AttributeNode" 42 | show TextNode = "TextNode" 43 | show CDATASectionNode = "CDATASectionNode" 44 | show EntityReferenceNode = "EntityReferenceNode" 45 | show EntityNode = "EntityNode" 46 | show ProcessingInstructionNode = "ProcessingInstructionNode" 47 | show CommentNode = "CommentNode" 48 | show DocumentNode = "DocumentNode" 49 | show DocumentTypeNode = "DocumentTypeNode" 50 | show DocumentFragmentNode = "DocumentFragmentNode" 51 | show NotationNode = "NotationNode" 52 | 53 | toEnumNodeType :: Int -> Maybe NodeType 54 | toEnumNodeType 1 = Just ElementNode 55 | toEnumNodeType 2 = Just AttributeNode 56 | toEnumNodeType 3 = Just TextNode 57 | toEnumNodeType 4 = Just CDATASectionNode 58 | toEnumNodeType 5 = Just EntityReferenceNode 59 | toEnumNodeType 6 = Just EntityNode 60 | toEnumNodeType 7 = Just ProcessingInstructionNode 61 | toEnumNodeType 8 = Just CommentNode 62 | toEnumNodeType 9 = Just DocumentNode 63 | toEnumNodeType 10 = Just DocumentTypeNode 64 | toEnumNodeType 11 = Just DocumentFragmentNode 65 | toEnumNodeType 12 = Just NotationNode 66 | toEnumNodeType _ = Nothing 67 | 68 | fromEnumNodeType :: NodeType -> Int 69 | fromEnumNodeType ElementNode = 1 70 | fromEnumNodeType AttributeNode = 2 71 | fromEnumNodeType TextNode = 3 72 | fromEnumNodeType CDATASectionNode = 4 73 | fromEnumNodeType EntityReferenceNode = 5 74 | fromEnumNodeType EntityNode = 6 75 | fromEnumNodeType ProcessingInstructionNode = 7 76 | fromEnumNodeType CommentNode = 8 77 | fromEnumNodeType DocumentNode = 9 78 | fromEnumNodeType DocumentTypeNode = 10 79 | fromEnumNodeType DocumentFragmentNode = 11 80 | fromEnumNodeType NotationNode = 12 81 | -------------------------------------------------------------------------------- /src/Web/DOM/NonDocumentTypeChildNode.js: -------------------------------------------------------------------------------- 1 | export function _previousElementSibling(node) { 2 | return function () { 3 | return node.previousElementSibling; 4 | }; 5 | } 6 | 7 | export function _nextElementSibling(node) { 8 | return function () { 9 | return node.nextElementSibling; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /src/Web/DOM/NonDocumentTypeChildNode.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NonDocumentTypeChildNode 2 | ( NonDocumentTypeChildNode 3 | , previousElementSibling 4 | , nextElementSibling 5 | ) where 6 | 7 | import Prelude 8 | 9 | import Data.Maybe (Maybe) 10 | import Data.Nullable (Nullable, toMaybe) 11 | import Effect (Effect) 12 | import Web.DOM.Internal.Types (Element) 13 | 14 | foreign import data NonDocumentTypeChildNode :: Type 15 | 16 | -- | The previous sibling that is an element, or Nothing if no such element exists. 17 | previousElementSibling :: NonDocumentTypeChildNode -> Effect (Maybe Element) 18 | previousElementSibling = map toMaybe <<< _previousElementSibling 19 | 20 | foreign import _previousElementSibling :: NonDocumentTypeChildNode -> Effect (Nullable Element) 21 | 22 | -- | The next sibling that is an element, or Nothing if no such element exists. 23 | nextElementSibling :: NonDocumentTypeChildNode -> Effect (Maybe Element) 24 | nextElementSibling = map toMaybe <<< _nextElementSibling 25 | 26 | foreign import _nextElementSibling :: NonDocumentTypeChildNode -> Effect (Nullable Element) 27 | -------------------------------------------------------------------------------- /src/Web/DOM/NonElementParentNode.js: -------------------------------------------------------------------------------- 1 | export function _getElementById(id) { 2 | return function (node) { 3 | return function () { 4 | return node.getElementById(id); 5 | }; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /src/Web/DOM/NonElementParentNode.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.NonElementParentNode 2 | ( NonElementParentNode 3 | , getElementById 4 | ) where 5 | 6 | import Prelude 7 | 8 | import Data.Maybe (Maybe) 9 | import Data.Nullable (Nullable, toMaybe) 10 | import Effect (Effect) 11 | import Web.DOM.Element (Element) 12 | import Web.DOM.ElementId (ElementId) 13 | 14 | foreign import data NonElementParentNode :: Type 15 | 16 | -- | The first element within node's descendants with a matching ID, or null if 17 | -- | no such element exists. 18 | foreign import _getElementById :: ElementId -> NonElementParentNode -> Effect (Nullable Element) 19 | 20 | getElementById :: ElementId -> NonElementParentNode -> Effect (Maybe Element) 21 | getElementById eid = map toMaybe <<< _getElementById eid 22 | -------------------------------------------------------------------------------- /src/Web/DOM/ParentNode.js: -------------------------------------------------------------------------------- 1 | var getEffProp = function (name) { 2 | return function (node) { 3 | return function () { 4 | return node[name]; 5 | }; 6 | }; 7 | }; 8 | 9 | export const children = getEffProp("children"); 10 | export const _firstElementChild = getEffProp("firstElementChild"); 11 | export const _lastElementChild = getEffProp("lastElementChild"); 12 | export const childElementCount = getEffProp("childElementCount"); 13 | 14 | export function _querySelector(selector) { 15 | return function (node) { 16 | return function () { 17 | return node.querySelector(selector); 18 | }; 19 | }; 20 | } 21 | 22 | export function querySelectorAll(selector) { 23 | return function (node) { 24 | return function () { 25 | return node.querySelectorAll(selector); 26 | }; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/Web/DOM/ParentNode.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ParentNode 2 | ( ParentNode 3 | , children 4 | , firstElementChild 5 | , lastElementChild 6 | , childElementCount 7 | , QuerySelector(..) 8 | , querySelector 9 | , querySelectorAll 10 | ) where 11 | 12 | import Prelude 13 | 14 | import Data.Maybe (Maybe) 15 | import Data.Newtype (class Newtype) 16 | import Data.Nullable (Nullable, toMaybe) 17 | import Effect (Effect) 18 | import Web.DOM.Internal.Types (Element) 19 | import Web.DOM.HTMLCollection (HTMLCollection) 20 | import Web.DOM.NodeList (NodeList) 21 | 22 | foreign import data ParentNode :: Type 23 | 24 | -- | The child elements for the node. 25 | foreign import children :: ParentNode -> Effect HTMLCollection 26 | 27 | -- | The first child that is an element, or Nothing if no such element exists. 28 | firstElementChild :: ParentNode -> Effect (Maybe Element) 29 | firstElementChild = map toMaybe <<< _firstElementChild 30 | 31 | foreign import _firstElementChild :: ParentNode -> Effect (Nullable Element) 32 | 33 | -- | The last child that is an element, or Nothing if no such element exists. 34 | lastElementChild :: ParentNode -> Effect (Maybe Element) 35 | lastElementChild = map toMaybe <<< _lastElementChild 36 | 37 | foreign import _lastElementChild :: ParentNode -> Effect (Nullable Element) 38 | 39 | -- | The number of child elements. 40 | foreign import childElementCount :: ParentNode -> Effect Int 41 | 42 | newtype QuerySelector = QuerySelector String 43 | 44 | derive newtype instance eqQuerySelector :: Eq QuerySelector 45 | derive newtype instance ordQuerySelector :: Ord QuerySelector 46 | derive instance newtypeQuerySelector :: Newtype QuerySelector _ 47 | 48 | -- | Finds the first child that is an element that matches the selector(s), or 49 | -- | Nothing if no such element exists. 50 | querySelector :: QuerySelector -> ParentNode -> Effect (Maybe Element) 51 | querySelector qs = map toMaybe <<< _querySelector qs 52 | 53 | foreign import _querySelector :: QuerySelector -> ParentNode -> Effect (Nullable Element) 54 | 55 | -- | Finds all the child elements that matches the selector(s). 56 | foreign import querySelectorAll :: QuerySelector -> ParentNode -> Effect NodeList 57 | -------------------------------------------------------------------------------- /src/Web/DOM/ProcessingInstruction.js: -------------------------------------------------------------------------------- 1 | export function target(pi) { 2 | return function () { 3 | return pi.target; 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /src/Web/DOM/ProcessingInstruction.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ProcessingInstruction where 2 | 3 | import Data.Maybe (Maybe) 4 | import Effect (Effect) 5 | import Unsafe.Coerce (unsafeCoerce) 6 | import Web.DOM.CharacterData (CharacterData) 7 | import Web.DOM.ChildNode (ChildNode) 8 | import Web.DOM.Internal.Types (Node) 9 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) 10 | import Web.Event.EventTarget (EventTarget) 11 | import Web.Internal.FFI (unsafeReadProtoTagged) 12 | 13 | foreign import data ProcessingInstruction :: Type 14 | 15 | fromCharacterData :: CharacterData -> Maybe ProcessingInstruction 16 | fromCharacterData = unsafeReadProtoTagged "ProcessingInstruction" 17 | 18 | fromNode :: Node -> Maybe ProcessingInstruction 19 | fromNode = unsafeReadProtoTagged "ProcessingInstruction" 20 | 21 | fromChildNode :: ChildNode -> Maybe ProcessingInstruction 22 | fromChildNode = unsafeReadProtoTagged "ProcessingInstruction" 23 | 24 | fromNonDocumentTypeChildNode :: NonDocumentTypeChildNode -> Maybe ProcessingInstruction 25 | fromNonDocumentTypeChildNode = unsafeReadProtoTagged "ProcessingInstruction" 26 | 27 | fromEventTarget :: EventTarget -> Maybe ProcessingInstruction 28 | fromEventTarget = unsafeReadProtoTagged "ProcessingInstruction" 29 | 30 | toNode :: ProcessingInstruction -> Node 31 | toNode = unsafeCoerce 32 | 33 | toCharacterData :: ProcessingInstruction -> CharacterData 34 | toCharacterData = unsafeCoerce 35 | 36 | toChildNode :: ProcessingInstruction -> ChildNode 37 | toChildNode = unsafeCoerce 38 | 39 | toNonDocumentTypeChildNode :: ProcessingInstruction -> NonDocumentTypeChildNode 40 | toNonDocumentTypeChildNode = unsafeCoerce 41 | 42 | toEventTarget :: ProcessingInstruction -> EventTarget 43 | toEventTarget = unsafeCoerce 44 | 45 | foreign import target :: ProcessingInstruction -> Effect String 46 | -------------------------------------------------------------------------------- /src/Web/DOM/PropName.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.PropName where 2 | 3 | import Prelude 4 | 5 | import Data.Newtype (class Newtype) 6 | 7 | -- | A wrapper for property names. 8 | -- | 9 | -- | The phantom type `value` describes the type of value which this property 10 | -- | requires. 11 | newtype PropName :: Type -> Type 12 | newtype PropName value = PropName String 13 | 14 | derive instance newtypePropName :: Newtype (PropName value) _ 15 | derive newtype instance eqPropName :: Eq (PropName value) 16 | derive newtype instance ordPropName :: Ord (PropName value) 17 | -------------------------------------------------------------------------------- /src/Web/DOM/ShadowRoot.js: -------------------------------------------------------------------------------- 1 | export function _mode(el) { 2 | return el.mode; 3 | } 4 | 5 | export function host(el) { 6 | return function() { 7 | return el.host; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /src/Web/DOM/ShadowRoot.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.ShadowRoot 2 | ( ShadowRoot 3 | , ShadowRootMode (..) 4 | , toNode 5 | , host 6 | , mode 7 | ) where 8 | 9 | import Prelude 10 | import Data.Maybe (Maybe(..)) 11 | import Effect (Effect) 12 | import Unsafe.Coerce (unsafeCoerce) 13 | import Web.DOM.Internal.Types (Element, Node) 14 | 15 | foreign import data ShadowRoot :: Type 16 | 17 | toNode :: ShadowRoot -> Node 18 | toNode = unsafeCoerce 19 | 20 | data ShadowRootMode = Open | Closed 21 | 22 | instance showShadowRootMode :: Show ShadowRootMode where 23 | show Open = "open" 24 | show Closed = "closed" 25 | 26 | mode :: ShadowRoot -> Maybe ShadowRootMode 27 | mode = modeFromString <<< _mode 28 | where 29 | modeFromString = case _ of 30 | "open" -> Just Open 31 | "closed" -> Just Closed 32 | _ -> Nothing 33 | 34 | foreign import host :: ShadowRoot -> Effect Element 35 | foreign import _mode :: ShadowRoot -> String 36 | -------------------------------------------------------------------------------- /src/Web/DOM/Text.js: -------------------------------------------------------------------------------- 1 | export function splitText(offset) { 2 | return function (t) { 3 | return function () { 4 | return t.splitText(offset); 5 | }; 6 | }; 7 | } 8 | 9 | export function wholeText(t) { 10 | return function () { 11 | return t.wholeText; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/Web/DOM/Text.purs: -------------------------------------------------------------------------------- 1 | module Web.DOM.Text where 2 | 3 | import Data.Maybe (Maybe) 4 | import Effect (Effect) 5 | import Unsafe.Coerce (unsafeCoerce) 6 | import Web.DOM.CharacterData (CharacterData) 7 | import Web.DOM.ChildNode (ChildNode) 8 | import Web.DOM.Internal.Types (Node) 9 | import Web.DOM.NonDocumentTypeChildNode (NonDocumentTypeChildNode) 10 | import Web.Event.EventTarget (EventTarget) 11 | import Web.Internal.FFI (unsafeReadProtoTagged) 12 | 13 | foreign import data Text :: Type 14 | 15 | fromCharacterData :: CharacterData -> Maybe Text 16 | fromCharacterData = unsafeReadProtoTagged "Text" 17 | 18 | fromNode :: Node -> Maybe Text 19 | fromNode = unsafeReadProtoTagged "Text" 20 | 21 | fromChildNode :: ChildNode -> Maybe Text 22 | fromChildNode = unsafeReadProtoTagged "Text" 23 | 24 | fromNonDocumentTypeChildNode :: NonDocumentTypeChildNode -> Maybe Text 25 | fromNonDocumentTypeChildNode = unsafeReadProtoTagged "Text" 26 | 27 | fromEventTarget :: EventTarget -> Maybe Text 28 | fromEventTarget = unsafeReadProtoTagged "Text" 29 | 30 | toNode :: Text -> Node 31 | toNode = unsafeCoerce 32 | 33 | toCharacterData :: Text -> CharacterData 34 | toCharacterData = unsafeCoerce 35 | 36 | toChildNode :: Text -> ChildNode 37 | toChildNode = unsafeCoerce 38 | 39 | toNonDocumentTypeChildNode :: Text -> NonDocumentTypeChildNode 40 | toNonDocumentTypeChildNode = unsafeCoerce 41 | 42 | toEventTarget :: Text -> EventTarget 43 | toEventTarget = unsafeCoerce 44 | 45 | foreign import splitText :: Int -> Text -> Effect Text 46 | 47 | foreign import wholeText :: Text -> Effect String 48 | --------------------------------------------------------------------------------