Git Product home page Git Product logo

dom4's Introduction

DOM4

build status donate

A fully tested and covered polyfill for new DOM Level 4 entries

Via cdnJS

Many thanks to cdnjs for hosting this script. Following an example on how to include it.

<script
  src="//cdnjs.cloudflare.com/ajax/libs/dom4/2.0.0/dom4.js"
>/* DOM4 */</script>

New v2

Both query and queryAll have been removed, while CSS :scope selector has been added.

Features

This is a fully tested and covered polyfill for both new DOM Level 4 parentNode entries:

  • Element#prepend()
  • Element#append()

And for new DOM Level 4 childNode entries:

  • Element#before()
  • Element#after()
  • Element#replaceWith() ( warning Element#replace() has been recently deprecated )
  • Element#remove()

The implemented test is conform to current specifications.

Other fixes/standardized behaviors include:

  • toggleAttribute
  • DOM Listener: capture, passive, and once
  • fully normalized KeyboardEvent, MouseEvent and the latest way to create new Event('type')
  • CSS :scope selector for any HTML Element (no document since useless, sorry)
  • classList, with forced fixes for iOS 5.1 and Nokia ASHA Xpress Browser and early implementations
  • CustomEvent constructor for all browsers down to IE8
  • Element#matches utility to test elements against CSS selectors
  • Element#closest utility to find element inclusive ancestor via CSS selectors
  • Node#contains utility to know if another node is inside the current one
  • requestAnimationFrame and cancelAnimationFrame are polyfilled too but the least legacy fallback to setTimeout does not support accurate timing and doesn't slow down execution with that logic. Feel free to load upfront other polyfills if needed.

If you need other polyfills too, have a look at another DOM-shim repo.

Compatibility

Theoretically compatible with all browsers you know that are truly used these days, here a list:

  • Android 2.1+
  • Safari Mobile since iOS 3.0 and Desktop
  • Opera Mobile, Mini, and Desktop
  • Blackberry 7.1 and higher
  • Samsung Bada 2 native Browser
  • Midori and most likely all other WebKit based
  • Chrome Mobile and Desktop
  • Firefox Mobile and Desktop
  • IE8+ for Desktop and IE Mobile 9 or greater.
  • Nokia Xpress Browser for ASHA Platform
  • Silk Browser - Fire OS 3.0
  • PhantomJS can benefit from DOM4 too

It's way easier if you tell me which browser in a current relevant market share is not supported :-)

For IE8 only it's recommended to include ie8 script before dom4 or CustomEvent, addEventListener, and dispatchEvent won't work as expected.

Which File

The minified version is here, while the max one here. If you want to test directly try this page, it should be green.

Want to contribute?

If you found a bug, want to contribute or have any questions feel free to fill an issue or pull request, and help us to improve the Dom4

License

Dom4 Code released under the MIT license.

dom4's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dom4's Issues

DOM3 polyfill

Will DOM3 polyfills eventually be added to this project or as a separate project? This would be a great alternative to jQuery, writing standard JavaScript supported everywhere without relying on a third-party library :)

append polyfill does not match the browser behavior

Tested both in Firefox 66 and Chromium 73

a = document.createElement('div')
a.append('foo', document.createElement('p'), 25)
console.log(a.childNodes)

Both browsers will add the 25 Number as a text node. The polyfill detects string with typeof node === 'string' to create a text node, which won't catch it.

TypeError in Opera Mobile 32

Catched in Sentry:

TypeError
object is not a function
/scripts/libs/dom4.js at line 2

/*! (C) Andrea Giammarchi - @WebReflection - Mit Style License */
(function(window){"use strict";function createDocumentFragment(){return document.createDocumentFragment()}function createElement(nodeName){r {snip}

User:

Opera Mobile 32.0.2254
Android 4.2.1

Note about r {snip}: it's Sentry's artifact, in real-life there is:

/*! (C) Andrea Giammarchi - @WebReflection - Mit Style License */
(function(window){"use strict";function createDocumentFragment(){return document.createDocumentFragment()}function createElement(nodeName){return document.createElement(nodeName)}

TypeError: Invalid calling object in EDGE or IE

In our app we use dom4 together with angular 1.6. It seems to be related, because dom4 fails when called from angular jqLiteDealoc function.

By debugging compiled code, I found out that the code below fails if called on DocumentFragment:

  what.querySelectorAll = function qSA(css) {
    var result = querySelectorAll.call(this, css);
    result.forEach = Array.prototype.forEach;
    return result
  }

screen shot 2017-12-20 at 15 31 42

The error itself looks like:

TypeError: Invalid calling object
   at qSA (eval code:702:11)
   at find (eval code:734:9)
   at qSA (eval code:727:9)
   at jqLiteDealoc (eval code:3252:5)
   at jqLiteEmpty (eval code:3452:3)
   at JQLite.prototype[name] (eval code:3724:9)
   at applyDirectivesToNode (eval code:9722:13)
   at compileNodes (eval code:9162:9)
   at compile (eval code:9043:7)
   at lazyCompilation (eval code:9490:11)
eval code (1881) (14794,9)

build / test setup

to work on this module involves reading through the Makefile and trying to work out which tasks you need to run in which order.

consider moving the npm dependencies into the 'devDependencies' field? or make some tasks dependencies of others, so running 'make test' or 'make build' works.

basically i don't really know how to run the tests. after running make dependencies, make build exits with errors and make test outputs nothing to the console.

Consider throwing for invalid names for toggleProperty

The standard for toggleAttribute throws an error for an invalid name. This wouldn't be true for the hasAttribute->removeAttribute code paths in the function implemented so I think this could be considered.
I was implementing this myself then was reminded to check here first ๐Ÿ‘.

My initial code was:

    function checkValidName(propertyName) {
        let first = /[:A-Z\_a-z\xc0-\xd6\xd8-\xf6\u00f8-\u02ff\x370-\x37d\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef\x3001-\xd7ff\xf900-\xfdcf\xfdf0-\xfffd\x10000-\xeffff]/;
        let second = /[\-\.0-9\xB7\u0300-\u036f\u203f-\u2040]/;
        let chars = [...propertyName];
        
        if (!first.test(chars.shift())) {
          return false;
        }
        for (let l of chars) {
           if (!first.test(l) && !second.test(l)) {
               return false;
           } 
        }
        return true;
    }
    Element.prototype.toggleAttribute = function (propertyName) {
      const charError = "InvalidCharacterError: String contains an invalid character";
      if (!checkValidValue(propertyName)) {
          throw new Error(charError);
      }
      ...

Likely something more readable than those RegEx lines could be done also ๐Ÿ˜†

Shimming more methods?

Are you interested in shimming more methods, some of which could benefit the libaray itself directly:

  • if the reference child passing to insertBefore() is falsy, use appendChild() instead. (doesn't work for ie, not sure which versions)
  • make the useCapture argument optional for addEventListener() (doesn't work for firefox before v6 according to mdn, also ie before v9)

I swear I've encountered more like these, but somehow these are only ones I can remember right now.

`:scope` (I guess) breaks normal `querySelector`

Microsoft Edge.

<div class="parent">
  <p class="child">
  </p>
</div>

Without DOM4:

document.querySelector('.parent').querySelector('.child') // OK
document.querySelector('.parent').querySelector('.parent > .child') // OK
document.querySelector('.parent').querySelector('> .child') // Syntax Error
document.querySelector('.parent').querySelector(':scope > .child') // Syntax Error

With DOM4:

document.querySelector('.parent').querySelector('.child') // OK
document.querySelector('.parent').querySelector('.parent > .child') // null
document.querySelector('.parent').querySelector('> .child') // OK
document.querySelector('.parent').querySelector(':scope > .child') // OK

`char` is a reserved word

I'm trying to use blueprintjs from ClojureScript. blueprint has a dependency on dom4. When I try to compile the code, Google Closure Compiler processes all of the JavaScript code produced by the ClojureScript compiler and also the JavaScript dependencies, including dom4.

Google Closure Compiler complains that dom4 is using a reserved word as an identifier.

Oct 31, 2017 11:02:45 AM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: /home/michael/work/personal/scratch/blueprint-test/public/js/release/node_modules/dom4/build/dom4.max.js:26: ERROR - Parse error. identifier is a reserved word
metaKey,altGraphKey);break;case 4:args.push(key,location,modifiers,repeat,locale);break;default:args.push(char,key,location,modifiers,repeat,locale)}out.initKeyboardEvent.apply(out,args)}else out.initEvent(type,bubbles,cancelable);for(key in out)if(defaults.hasOwnProperty(key)&&out[key]!==init[key])withInitValues(key,out,init);return out}KeyboardEvent.prototype=$KeyboardEvent.prototype;return KeyboardEvent}(window.KeyboardEvent||function KeyboardEvent(){});defineProperty(window,"KeyboardEvent",{value:o_O});
                                                                                                          ^

Oct 31, 2017 11:02:45 AM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 1 error(s), 0 warning(s)
ERROR: JSC_PARSE_ERROR. Parse error. identifier is a reserved word at /home/michael/work/personal/scratch/blueprint-test/public/js/release/node_modules/dom4/build/dom4.max.js line 26 : 106

Looking at the code, I suspect char was supposed to be chr:

chr = String(init.char),

...
args.push(char, key, location, modifiers, repeat, locale);

Deal with comment nodes

Why only Element prototype is used when polyfilling dom4 methods? I have library where comment nodes are used. remove/append and other sugar stuff is not available for them. Now i just swap Node and Element
ElementPrototype = (window.Node || window.Element || window.HTMLElement).prototype
I understand that these methods are written just in Element proto in spec, but it is inconvenient for document nodes that does not implement Element prototype...

shadowRoot

Are these methods meant to work on shadow roots? It would be nice to traverse the DOM this way. Currently this doesn't seem to work.

this.createShadowRoot().query // undefined

Indicate browser support

It would be helpful to know which browsers are supported when trying to evaluate this as a potential library.

Based on some tests with browserstack, the tests pass in

  • IE8+
  • iOS 3.0+ (and therefore Safari 5.0+?)
  • Android 2.1+
  • Chrome 27dev (what I'm running)

Is there a known lowest supported version for Chrome, Firefox, Safari or Opera?

I'm really excited about this library, and look forward to using it in my mobile projects :)

IE9 - SCRIPT5022 SyntaxError

Just tryied this lib on IE9 and I get: SCRIPT5022 SyntaxError on line 2088 of dom4.js

How can I know the cause of this error ?

Thanks

Publish dom4.max.js

I think it would be better to specific the 'max' build as main, as it makes debugging much easier, and anyone who uses the file via commonjs/npm likely will minify it as part of their own build.

Anchor on the Web Page that the Elements#matches link on the readme is gone; temporary link to the MDN page about it reasonable?

For whatever reason, The #dom-element-matches anchor is no longer available on the page the current Element#Matches link references in the readme.

This may give the impression to readers not keen on investigating more about the element that the Element#matches method is deprecated despite the fact all major browsers support it except IE & at one point Opera didn't according to the MDN Reference Page for the method.

I also used Browserstack to see for myself (impressive work on this library, by the way) that still the case.

**Accordingly, the link to the MDN page perhaps may make sense to reference in the meantime until another, recent W3C document surfaces references it.

Impressive work on this library, by the way.

closest method is not being added

Simplified test case:

<!DOCTYPE html>
<head>
<script
  src="//cdnjs.cloudflare.com/ajax/libs/dom4/1.0.1/dom4.js"
>/* DOM4 */</script>
</head>
<body>
</body>

in the console:

var foo = document.createElement('div')
foo.closest

returns undefined

The other properties and methods from DOM4 do exist however.

Thank you so much for your awesome libraries and blog!

Page using dom4.max.js breaks in IE8 under certain circumstances

Firstly thanks for the wonderful work on this. I find it difficult to believe someone would go to the trouble to ensure DOM4 support in IE8!

I've included the non-minified version dom4.max.js into my project, and under IE8, it broke at the line 819, saying expected identifier. This was due to a trailing comma.

I've already cleaned up the problems, and added some jshint directives that lint based on Javascript 3, will follow up with a pull request.

#matches failing on IE9 on saucelabs

var el = document.createElement('div')
el.className = 'foo'
el.matches('.foo'))

el.matches returns a falsy value on ie9, returns true on all other tested browsers. This is tested against current master branch.

Add changelog

It's quite hard to track what the changes are right now

bower main

bower.main field must contain non-minified version

IE9: classList shim fails on SVG elements

SVG elements' className attribute is not a string, so this line fails. I've had success patching it to read:

var className = (node.className.baseVal || node.className).replace(trim, '');

but there's probably a faster way to determine which one to use.

`once` is not an option for `removeEventListener`

rEL('_', increment, {once: true});

Is there a specific reason once was added to rEL for the feature test? The docs on MDN don't list this as a valid option.

I would expect the line to be rewritten as rEL('_', increment);, since there might be other browsers that will actually throw an error at this point, even though aEL('_', increment, { once: true }); functions properly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.