Path: blob/trunk/third_party/closure/goog/dom/dataset.js
2868 views
// Copyright 2009 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Utilities for adding, removing and setting values in16* an Element's dataset.17* See {@link http://www.w3.org/TR/html5/Overview.html#dom-dataset}.18*19* @author [email protected] (Alex Nicksay)20*/2122goog.provide('goog.dom.dataset');2324goog.require('goog.labs.userAgent.browser');25goog.require('goog.string');26goog.require('goog.userAgent.product');272829/**30* Whether using the dataset property is allowed.31*32* In IE (up to and including IE 11), setting element.dataset in JS does not33* propagate values to CSS, breaking expressions such as34* `content: attr(data-content)` that would otherwise work.35* See {@link https://github.com/google/closure-library/issues/396}.36*37* In Safari >= 9, reading from element.dataset sometimes returns38* undefined, even though the corresponding data- attribute has a value.39* See {@link https://bugs.webkit.org/show_bug.cgi?id=161454}.40* @const41* @private42*/43goog.dom.dataset.ALLOWED_ =44!goog.userAgent.product.IE && !goog.labs.userAgent.browser.isSafari();454647/**48* The DOM attribute name prefix that must be present for it to be considered49* for a dataset.50* @type {string}51* @const52* @private53*/54goog.dom.dataset.PREFIX_ = 'data-';555657/**58* Sets a custom data attribute on an element. The key should be59* in camelCase format (e.g "keyName" for the "data-key-name" attribute).60* @param {Element} element DOM node to set the custom data attribute on.61* @param {string} key Key for the custom data attribute.62* @param {string} value Value for the custom data attribute.63*/64goog.dom.dataset.set = function(element, key, value) {65if (goog.dom.dataset.ALLOWED_ && element.dataset) {66element.dataset[key] = value;67} else {68element.setAttribute(69goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key), value);70}71};727374/**75* Gets a custom data attribute from an element. The key should be76* in camelCase format (e.g "keyName" for the "data-key-name" attribute).77* @param {Element} element DOM node to get the custom data attribute from.78* @param {string} key Key for the custom data attribute.79* @return {?string} The attribute value, if it exists.80*/81goog.dom.dataset.get = function(element, key) {82if (goog.dom.dataset.ALLOWED_ && element.dataset) {83// Android browser (non-chrome) returns the empty string for84// element.dataset['doesNotExist'].85if (!(key in element.dataset)) {86return null;87}88return element.dataset[key];89} else {90return element.getAttribute(91goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));92}93};949596/**97* Removes a custom data attribute from an element. The key should be98* in camelCase format (e.g "keyName" for the "data-key-name" attribute).99* @param {Element} element DOM node to get the custom data attribute from.100* @param {string} key Key for the custom data attribute.101*/102goog.dom.dataset.remove = function(element, key) {103if (goog.dom.dataset.ALLOWED_ && element.dataset) {104// In strict mode Safari will trigger an error when trying to delete a105// property which does not exist.106if (goog.dom.dataset.has(element, key)) {107delete element.dataset[key];108}109} else {110element.removeAttribute(111goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));112}113};114115116/**117* Checks whether custom data attribute exists on an element. The key should be118* in camelCase format (e.g "keyName" for the "data-key-name" attribute).119*120* @param {Element} element DOM node to get the custom data attribute from.121* @param {string} key Key for the custom data attribute.122* @return {boolean} Whether the attribute exists.123*/124goog.dom.dataset.has = function(element, key) {125if (goog.dom.dataset.ALLOWED_ && element.dataset) {126return key in element.dataset;127} else if (element.hasAttribute) {128return element.hasAttribute(129goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));130} else {131return !!(132element.getAttribute(133goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key)));134}135};136137138/**139* Gets all custom data attributes as a string map. The attribute names will be140* camel cased (e.g., data-foo-bar -> dataset['fooBar']). This operation is not141* safe for attributes having camel-cased names clashing with already existing142* properties (e.g., data-to-string -> dataset['toString']).143* @param {!Element} element DOM node to get the data attributes from.144* @return {!Object} The string map containing data attributes and their145* respective values.146*/147goog.dom.dataset.getAll = function(element) {148if (goog.dom.dataset.ALLOWED_ && element.dataset) {149return element.dataset;150} else {151var dataset = {};152var attributes = element.attributes;153for (var i = 0; i < attributes.length; ++i) {154var attribute = attributes[i];155if (goog.string.startsWith(attribute.name, goog.dom.dataset.PREFIX_)) {156// We use substr(5), since it's faster than replacing 'data-' with ''.157var key = goog.string.toCamelCase(attribute.name.substr(5));158dataset[key] = attribute.value;159}160}161return dataset;162}163};164165166