mirror of
https://github.com/google/blockly.git
synced 2026-01-08 01:20:12 +01:00
133 lines
4.2 KiB
JavaScript
133 lines
4.2 KiB
JavaScript
/**
|
|
* @license
|
|
* Visual Blocks Editor
|
|
*
|
|
* Copyright 2019 Google Inc.
|
|
* https://developers.google.com/blockly/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Utility methods for DOM manipulation.
|
|
* These methods are not specific to Blockly, and could be factored out into
|
|
* a JavaScript framework such as Closure.
|
|
* @author fraser@google.com (Neil Fraser)
|
|
*/
|
|
'use strict';
|
|
|
|
/**
|
|
* @name Blockly.utils.dom
|
|
* @namespace
|
|
*/
|
|
goog.provide('Blockly.utils.dom');
|
|
|
|
|
|
/**
|
|
* Add a CSS class to a element.
|
|
* Similar to Closure's goog.dom.classes.add, except it handles SVG elements.
|
|
* @param {!Element} element DOM element to add class to.
|
|
* @param {string} className Name of class to add.
|
|
* @return {boolean} True if class was added, false if already present.
|
|
*/
|
|
Blockly.utils.dom.addClass = function(element, className) {
|
|
var classes = element.getAttribute('class') || '';
|
|
if ((' ' + classes + ' ').indexOf(' ' + className + ' ') != -1) {
|
|
return false;
|
|
}
|
|
if (classes) {
|
|
classes += ' ';
|
|
}
|
|
element.setAttribute('class', classes + className);
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Remove a CSS class from a element.
|
|
* Similar to Closure's goog.dom.classes.remove, except it handles SVG elements.
|
|
* @param {!Element} element DOM element to remove class from.
|
|
* @param {string} className Name of class to remove.
|
|
* @return {boolean} True if class was removed, false if never present.
|
|
*/
|
|
Blockly.utils.dom.removeClass = function(element, className) {
|
|
var classes = element.getAttribute('class');
|
|
if ((' ' + classes + ' ').indexOf(' ' + className + ' ') == -1) {
|
|
return false;
|
|
}
|
|
var classList = classes.split(/\s+/);
|
|
for (var i = 0; i < classList.length; i++) {
|
|
if (!classList[i] || classList[i] == className) {
|
|
classList.splice(i, 1);
|
|
i--;
|
|
}
|
|
}
|
|
if (classList.length) {
|
|
element.setAttribute('class', classList.join(' '));
|
|
} else {
|
|
element.removeAttribute('class');
|
|
}
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Checks if an element has the specified CSS class.
|
|
* Similar to Closure's goog.dom.classes.has, except it handles SVG elements.
|
|
* @param {!Element} element DOM element to check.
|
|
* @param {string} className Name of class to check.
|
|
* @return {boolean} True if class exists, false otherwise.
|
|
*/
|
|
Blockly.utils.dom.hasClass = function(element, className) {
|
|
var classes = element.getAttribute('class');
|
|
return (' ' + classes + ' ').indexOf(' ' + className + ' ') != -1;
|
|
};
|
|
|
|
/**
|
|
* Removes a node from its parent. No-op if not attached to a parent.
|
|
* @param {Node} node The node to remove.
|
|
* @return {Node} The node removed if removed; else, null.
|
|
*/
|
|
// Copied from Closure goog.dom.removeNode
|
|
Blockly.utils.dom.removeNode = function(node) {
|
|
return node && node.parentNode ? node.parentNode.removeChild(node) : null;
|
|
};
|
|
|
|
/**
|
|
* Insert a node after a reference node.
|
|
* Contrast with node.insertBefore function.
|
|
* @param {!Element} newNode New element to insert.
|
|
* @param {!Element} refNode Existing element to precede new node.
|
|
*/
|
|
Blockly.utils.dom.insertAfter = function(newNode, refNode) {
|
|
var siblingNode = refNode.nextSibling;
|
|
var parentNode = refNode.parentNode;
|
|
if (!parentNode) {
|
|
throw Error('Reference node has no parent.');
|
|
}
|
|
if (siblingNode) {
|
|
parentNode.insertBefore(newNode, siblingNode);
|
|
} else {
|
|
parentNode.appendChild(newNode);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Whether a node contains another node.
|
|
* @param {!Node} parent The node that should contain the other node.
|
|
* @param {!Node} descendant The node to test presence of.
|
|
* @return {boolean} Whether the parent node contains the descendant node.
|
|
*/
|
|
Blockly.utils.dom.containsNode = function(parent, descendant) {
|
|
return !!(parent.compareDocumentPosition(descendant) &
|
|
Node.DOCUMENT_POSITION_CONTAINED_BY);
|
|
};
|