<commit_before>/*
 * Copyright (C) 2012 salesforce.com, inc.
 *
 * 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.
 */
({
    SPECIAL_BOOLEANS : ["checked",
                        "selected",
                        "disabled",
                        "readonly",
                        "multiple",
                        "ismap",
                        "defer",
                        "declare",
                        "noresize",
                        "nowrap",
                        "noshade",
                        "compact",
                        "autocomplete",
                        "required"],

    SPECIAL_CASINGS : function() {
        if (this.cachedCasings) {
            return this.cachedCasings;
        } else {
            return this.cachedCasings = (function() {
                var ret = {};
                var caseSensitiveAttributes = ["readOnly",
                                               "colSpan",
                                               "rowSpan",
                                               "bgColor",
                                               "tabIndex",
                                               "useMap",
                                               "accessKey",
                                               "maxLength"
                                               ];
                var attr;
                for (var i=0, len=caseSensitiveAttributes.length; i<len; i++) {
                    attr = caseSensitiveAttributes[i];
                    ret[attr.toLowerCase()] = attr;
                }

                ret["for"] = "htmlFor";
                ret["class"] = "className";

                return ret;
            }());
        }
    },

    // "void elements" as per http://dev.w3.org/html5/markup/syntax.html#syntax-elements
    BODYLESS_TAGS : {
        "area" : true,
        "base" : true,
        "br" : true,
        "col" : true,
        "command" : true,
        "embed" : true,
        "hr" : true,
        "img" : true,
        "input" : true,
        "keygen" : true,
        "link" : true,
        "meta" : true,
        "param" : true,
        "source" : true,
        "track" : true,
        "wbr" : true
    },

    caseAttribute : function(attribute) {
        return this.SPECIAL_CASINGS()[attribute.toLowerCase()] !== undefined ? this.SPECIAL_CASINGS()[attribute.toLowerCase()] : attribute.toLowerCase();
    },

    createFastClickHandler : function(element, handler) {
        var self = this;
        if (this.supportsTouchEvents()) {
            this.initFastClick();

            // Add "fast click" support for touch enabled devices to avoid 300ms browser lag while it figures out if its a gesture or a click
            var FastClick = self.FastClick;
            var fc = new FastClick(element, handler);
        } else {
            $A.util.on(element, "click", handler);
        }
    },

    supportsTouchEvents : function () {
        // cache the result--it's not going to change
        return this.supportsTouchEvents.cache || (this.supportsTouchEvents.cache = !$A.util.isUndefined(document.ontouchstart) && $A.getContext().getMode() !== 'PTEST' && $A.getContext().getMode() !== 'CADENCE' && $A.getContext().getMode() !== 'SELENIUM' && $A.getContext().getMode() !== 'SELENIUMDEBUG');
    },

    initFastClick : function() {
        var self = this;
        if (!self.FastClick) {
            self.FastClick = function(element, handler) {
                this.element = element;
                this.handler = handler;

                element.addEventListener("touchstart", this, false);
            };

            self.FastClick.prototype.handleEvent = function(event) {
                switch (event.type) {
                case "touchstart":
                    this.onTouchStart(event);
                    break;
                case "touchmove":
                    this.onTouchMove(event);
                    break;
                case "touchend":
                    this.onClick(event);
                    break;
                }
            };

            self.FastClick.prototype.onTouchStart = function(event) {
                $A.util.on(this.element, "touchend", this, false);
                $A.util.on(document.body, "touchmove", this, false);

                this.startX = event.touches[0].clientX;
                this.startY = event.touches[0].clientY;
            };

            self.FastClick.prototype.onTouchMove = function(event) {
                if (Math.abs(event.touches[0].clientX - this.startX) > 4
                        || Math.abs(event.touches[0].clientY - this.startY) > 4) {
                    this.reset();
                }
            };

            self.FastClick.prototype.onClick = function(event) {
                event.stopPropagation();
                event.preventDefault();
                this.element.focus();
                this.handler(event);

                if (event.type == "touchend") {
                    self.FastClick.preventGhostClick(this.startX,
                            this.startY);
                }

                this.reset();
            };

            self.FastClick.prototype.reset = function() {
                this.element.removeEventListener("touchend", this, false);
                document.body.removeEventListener("touchmove", this, false);

                this.startX = 0;
                this.startY = 0;
            };

            self.FastClick.preventGhostClick = function(x, y) {
                self.FastClick.clickbusterCoordinates.push(x, y);
                window.setTimeout(self.FastClick.pop, 2500);
            };

            self.FastClick.pop = function() {
                self.FastClick.clickbusterCoordinates.splice(0, 2);
            };

            var onClickBuster = function(event) {
                for ( var i = 0; i < self.FastClick.clickbusterCoordinates.length; i += 2) {
                    var x = self.FastClick.clickbusterCoordinates[i];
                    var y = self.FastClick.clickbusterCoordinates[i + 1];
                    if (Math.abs(event.clientX - x) < 25
                            && Math.abs(event.clientY - y) < 25) {
                        event.stopPropagation();
                        event.preventDefault();
                    }
                }
            };

            self.FastClick.clickbusterCoordinates = [];
            $A.util.on(document, "click", onClickBuster, true);

            // Need this otherwise the browser eats the event
            $A.util.on(document, "touchmove", function (e) { e.preventDefault(); }, false);
        }
    },

    domEventHandler : function (event) {
        var eventName = "on" + event.type;
        if (eventName === "ontouchend") {
            // Map from touch event to onclick
            eventName = "onclick";
        }

        var element = event.currentTarget;
        var ownerComponent = $A.componentService.getRenderingComponentForElement(element);
        var attributes = ownerComponent.getAttributes();
        var valueProvider = attributes.getValueProvider();
        var valueExpression = attributes.getValue("HTMLAttributes").getValue(eventName);

        $A.services.event.startFiring(eventName);

        var action = $A.expressionService.get(valueProvider, valueExpression);
        action.run(event);

        $A.services.event.finishFiring(eventName);
    },

    canHaveBody : function(component) {
        var tag = component.get("v.tag");
        return !this.BODYLESS_TAGS[tag.toLowerCase()];
    },

    createHtmlAttribute: function(name, ve, config) {
        var ret = config.ret;
        var component = config.component;
        var attributes = component.getAttributes();
        var valueProvider = attributes.getValueProvider();
        var on = $A.util.on;

        var value;
        // special handling if the attribute is an inline event handler
        if (name.toLowerCase().indexOf("on") === 0) {
            var eventName = name.substring(2);

            if (eventName.toLowerCase() === "click") {
                this.createFastClickHandler(ret, this.domEventHandler);
            } else {
                on(ret, eventName, this.domEventHandler);
            }
        } else {
            // ve is either an expression (and needs to be evaluated by
            // the expressionService), or a literal
            if (ve.isExpression && ve.isExpression()) {
                value = $A.expressionService.getValue(valueProvider, ve);

                // get the actual value from the Value object (if it's not null)
                if (value && value.auraType === "Value") {
                    if (aura.util.arrayIndexOf(this.SPECIAL_BOOLEANS, name.toLowerCase()) > -1) {
                        // TODO: values should someday know their type and do the right thing with getValue()
                        value = value.getBooleanValue();
                    } else {
                        value = value.getValue();
                    }
                }
            } else if(ve.isExpression){
                value = ve.getValue();
            } else{
            	value = ve; 
            }

            var isHash = value && value.indexOf && value.indexOf("#") === 0;
            if (name.toLowerCase() === "href" && ret.tagName && ret.tagName.toLowerCase() === "a" && value && (isHash || this.supportsTouchEvents())) {
                this.createFastClickHandler(ret, function() {
                    if (isHash) {
                        $A.services.event.startFiring("click");
                        $A.historyService.set(value.substring(1));<commit_msg>Bulletproofing after a few test failures indicated that ve can be undefined in some situations<commit_after>/*
 * Copyright (C) 2012 salesforce.com, inc.
 *
 * 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.
 */
({
    SPECIAL_BOOLEANS : ["checked",
                        "selected",
                        "disabled",
                        "readonly",
                        "multiple",
                        "ismap",
                        "defer",
                        "declare",
                        "noresize",
                        "nowrap",
                        "noshade",
                        "compact",
                        "autocomplete",
                        "required"],

    SPECIAL_CASINGS : function() {
        if (this.cachedCasings) {
            return this.cachedCasings;
        } else {
            return this.cachedCasings = (function() {
                var ret = {};
                var caseSensitiveAttributes = ["readOnly",
                                               "colSpan",
                                               "rowSpan",
                                               "bgColor",
                                               "tabIndex",
                                               "useMap",
                                               "accessKey",
                                               "maxLength"
                                               ];
                var attr;
                for (var i=0, len=caseSensitiveAttributes.length; i<len; i++) {
                    attr = caseSensitiveAttributes[i];
                    ret[attr.toLowerCase()] = attr;
                }

                ret["for"] = "htmlFor";
                ret["class"] = "className";

                return ret;
            }());
        }
    },

    // "void elements" as per http://dev.w3.org/html5/markup/syntax.html#syntax-elements
    BODYLESS_TAGS : {
        "area" : true,
        "base" : true,
        "br" : true,
        "col" : true,
        "command" : true,
        "embed" : true,
        "hr" : true,
        "img" : true,
        "input" : true,
        "keygen" : true,
        "link" : true,
        "meta" : true,
        "param" : true,
        "source" : true,
        "track" : true,
        "wbr" : true
    },

    caseAttribute : function(attribute) {
        return this.SPECIAL_CASINGS()[attribute.toLowerCase()] !== undefined ? this.SPECIAL_CASINGS()[attribute.toLowerCase()] : attribute.toLowerCase();
    },

    createFastClickHandler : function(element, handler) {
        var self = this;
        if (this.supportsTouchEvents()) {
            this.initFastClick();

            // Add "fast click" support for touch enabled devices to avoid 300ms browser lag while it figures out if its a gesture or a click
            var FastClick = self.FastClick;
            var fc = new FastClick(element, handler);
        } else {
            $A.util.on(element, "click", handler);
        }
    },

    supportsTouchEvents : function () {
        // cache the result--it's not going to change
        return this.supportsTouchEvents.cache || (this.supportsTouchEvents.cache = !$A.util.isUndefined(document.ontouchstart) && $A.getContext().getMode() !== 'PTEST' && $A.getContext().getMode() !== 'CADENCE' && $A.getContext().getMode() !== 'SELENIUM' && $A.getContext().getMode() !== 'SELENIUMDEBUG');
    },

    initFastClick : function() {
        var self = this;
        if (!self.FastClick) {
            self.FastClick = function(element, handler) {
                this.element = element;
                this.handler = handler;

                element.addEventListener("touchstart", this, false);
            };

            self.FastClick.prototype.handleEvent = function(event) {
                switch (event.type) {
                case "touchstart":
                    this.onTouchStart(event);
                    break;
                case "touchmove":
                    this.onTouchMove(event);
                    break;
                case "touchend":
                    this.onClick(event);
                    break;
                }
            };

            self.FastClick.prototype.onTouchStart = function(event) {
                $A.util.on(this.element, "touchend", this, false);
                $A.util.on(document.body, "touchmove", this, false);

                this.startX = event.touches[0].clientX;
                this.startY = event.touches[0].clientY;
            };

            self.FastClick.prototype.onTouchMove = function(event) {
                if (Math.abs(event.touches[0].clientX - this.startX) > 4
                        || Math.abs(event.touches[0].clientY - this.startY) > 4) {
                    this.reset();
                }
            };

            self.FastClick.prototype.onClick = function(event) {
                event.stopPropagation();
                event.preventDefault();
                this.element.focus();
                this.handler(event);

                if (event.type == "touchend") {
                    self.FastClick.preventGhostClick(this.startX,
                            this.startY);
                }

                this.reset();
            };

            self.FastClick.prototype.reset = function() {
                this.element.removeEventListener("touchend", this, false);
                document.body.removeEventListener("touchmove", this, false);

                this.startX = 0;
                this.startY = 0;
            };

            self.FastClick.preventGhostClick = function(x, y) {
                self.FastClick.clickbusterCoordinates.push(x, y);
                window.setTimeout(self.FastClick.pop, 2500);
            };

            self.FastClick.pop = function() {
                self.FastClick.clickbusterCoordinates.splice(0, 2);
            };

            var onClickBuster = function(event) {
                for ( var i = 0; i < self.FastClick.clickbusterCoordinates.length; i += 2) {
                    var x = self.FastClick.clickbusterCoordinates[i];
                    var y = self.FastClick.clickbusterCoordinates[i + 1];
                    if (Math.abs(event.clientX - x) < 25
                            && Math.abs(event.clientY - y) < 25) {
                        event.stopPropagation();
                        event.preventDefault();
                    }
                }
            };

            self.FastClick.clickbusterCoordinates = [];
            $A.util.on(document, "click", onClickBuster, true);

            // Need this otherwise the browser eats the event
            $A.util.on(document, "touchmove", function (e) { e.preventDefault(); }, false);
        }
    },

    domEventHandler : function (event) {
        var eventName = "on" + event.type;
        if (eventName === "ontouchend") {
            // Map from touch event to onclick
            eventName = "onclick";
        }

        var element = event.currentTarget;
        var ownerComponent = $A.componentService.getRenderingComponentForElement(element);
        var attributes = ownerComponent.getAttributes();
        var valueProvider = attributes.getValueProvider();
        var valueExpression = attributes.getValue("HTMLAttributes").getValue(eventName);

        $A.services.event.startFiring(eventName);

        var action = $A.expressionService.get(valueProvider, valueExpression);
        action.run(event);

        $A.services.event.finishFiring(eventName);
    },

    canHaveBody : function(component) {
        var tag = component.get("v.tag");
        return !this.BODYLESS_TAGS[tag.toLowerCase()];
    },

    createHtmlAttribute: function(name, ve, config) {
        var ret = config.ret;
        var component = config.component;
        var attributes = component.getAttributes();
        var valueProvider = attributes.getValueProvider();
        var on = $A.util.on;

        var value;
        // special handling if the attribute is an inline event handler
        if (name.toLowerCase().indexOf("on") === 0) {
            var eventName = name.substring(2);

            if (eventName.toLowerCase() === "click") {
                this.createFastClickHandler(ret, this.domEventHandler);
            } else {
                on(ret, eventName, this.domEventHandler);
            }
        } else {
            // ve is either an expression (and needs to be evaluated by
            // the expressionService), or a literal
            if (ve && ve.isExpression) {
            	if (ve.isExpression()) {
	                value = $A.expressionService.getValue(valueProvider, ve);
	
	                // get the actual value from the Value object (if it's not null)
	                if (value && value.auraType === "Value") {
	                    if (aura.util.arrayIndexOf(this.SPECIAL_BOOLEANS, name.toLowerCase()) > -1) {
	                        // TODO: values should someday know their type and do the right thing with getValue()
	                        value = value.getBooleanValue();
	                    } else {
	                        value = value.getValue();
	                    }
	                }
            	} else {
                    value = ve.getValue();
            	}
            } else{
            	value = ve; 
            }

            var isHash = value && value.indexOf && value.indexOf("#") === 0;
            if (name.toLowerCase() === "href" && ret.tagName && ret.tagName.toLowerCase() === "a" && value && (isHash || this.supportsTouchEvents())) {
                this.createFastClickHandler(ret, function() {
                    if (isHash) {
                        $A.services.event.startFiring("click");
                        $A.historyService.set(value.substring(1));
{'fraction_non_alphanumeric': 0.11353177323019681, 'fraction_numerical': 0.003916576911779105, 'mean_word_length': 1.434684147794994, 'pattern_counts': {'":': 6, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5155685', 'n_tokens_mistral': 5296, 'n_tokens_neox': 5023, 'n_words': 1156}