aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php')
-rw-r--r--lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php45
1 files changed, 13 insertions, 32 deletions
diff --git a/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php b/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php
index 97d6a02b4c4..cc468dbeba0 100644
--- a/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php
+++ b/lib/private/Authentication/TwoFactorAuth/Db/ProviderUserAssignmentDao.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright 2018 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Authentication\TwoFactorAuth\Db;
@@ -46,7 +29,7 @@ class ProviderUserAssignmentDao {
* Get all assigned provider IDs for the given user ID
*
* @return array<string, bool> where the array key is the provider ID (string) and the
- * value is the enabled state (bool)
+ * value is the enabled state (bool)
*/
public function getState(string $uid): array {
$qb = $this->conn->getQueryBuilder();
@@ -54,10 +37,10 @@ class ProviderUserAssignmentDao {
$query = $qb->select('provider_id', 'enabled')
->from(self::TABLE_NAME)
->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid)));
- $result = $query->execute();
+ $result = $query->executeQuery();
$providers = [];
foreach ($result->fetchAll() as $row) {
- $providers[(string)$row['provider_id']] = 1 === (int)$row['enabled'];
+ $providers[(string)$row['provider_id']] = (int)$row['enabled'] === 1;
}
$result->closeCursor();
@@ -91,8 +74,6 @@ class ProviderUserAssignmentDao {
/**
* Delete all provider states of a user and return the provider IDs
*
- * @param string $uid
- *
* @return list<array{provider_id: string, uid: string, enabled: bool}>
*/
public function deleteByUser(string $uid): array {
@@ -100,7 +81,7 @@ class ProviderUserAssignmentDao {
$selectQuery = $qb1->select('*')
->from(self::TABLE_NAME)
->where($qb1->expr()->eq('uid', $qb1->createNamedParameter($uid)));
- $selectResult = $selectQuery->execute();
+ $selectResult = $selectQuery->executeQuery();
$rows = $selectResult->fetchAll();
$selectResult->closeCursor();
@@ -108,15 +89,15 @@ class ProviderUserAssignmentDao {
$deleteQuery = $qb2
->delete(self::TABLE_NAME)
->where($qb2->expr()->eq('uid', $qb2->createNamedParameter($uid)));
- $deleteQuery->execute();
+ $deleteQuery->executeStatement();
- return array_map(function (array $row) {
+ return array_values(array_map(function (array $row) {
return [
- 'provider_id' => $row['provider_id'],
- 'uid' => $row['uid'],
- 'enabled' => 1 === (int) $row['enabled'],
+ 'provider_id' => (string)$row['provider_id'],
+ 'uid' => (string)$row['uid'],
+ 'enabled' => ((int)$row['enabled']) === 1,
];
- }, $rows);
+ }, $rows));
}
public function deleteAll(string $providerId): void {
@@ -125,6 +106,6 @@ class ProviderUserAssignmentDao {
$deleteQuery = $qb->delete(self::TABLE_NAME)
->where($qb->expr()->eq('provider_id', $qb->createNamedParameter($providerId)));
- $deleteQuery->execute();
+ $deleteQuery->executeStatement();
}
}
lass="w"> "<div>" ).appendTo( "#qunit-fixture" ); $div.css( "fill-opacity", 1 ); assert.equal( $div.css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" ); $div.css( "font-size", "27px" ); $div.css( "line-height", 2 ); assert.equal( $div.css( "line-height" ), "54px", "Do not append px to 'line-height'" ); $div.css( "column-count", 1 ); if ( $div.css( "column-count" ) !== undefined ) { assert.equal( $div.css( "column-count" ), 1, "Do not append px to 'column-count'" ); } else { assert.ok( true, "No support for column-count CSS property" ); } $div.css( "animation-iteration-count", 2 ); if ( $div.css( "animation-iteration-count" ) !== undefined ) { // if $div.css( "animation-iteration-count" ) return "1", // it actually return the default value of animation-iteration-count assert.equal( $div.css( "animation-iteration-count" ), 2, "Do not append px to 'animation-iteration-count'" ); } else { assert.ok( true, "No support for animation-iteration-count CSS property" ); } } ); QUnit[ jQuery( "<div/>" )[ 0 ].style.gridArea === "" ? "test" : "skip" ]( "Do not append px to CSS Grid-related properties (gh-4007)", function( assert ) { assert.expect( 12 ); var prop, value, subProp, subValue, $div, gridProps = { "grid-area": { "grid-row-start": "2", "grid-row-end": "auto", "grid-column-start": "auto", "grid-column-end": "auto" }, "grid-column": { "grid-column-start": "2", "grid-column-end": "auto" }, "grid-column-end": true, "grid-column-start": true, "grid-row": { "grid-row-start": "2", "grid-row-end": "auto" }, "grid-row-end": true, "grid-row-start": true }; for ( prop in gridProps ) { $div = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ); $div.css( prop, 2 ); value = gridProps[ prop ]; if ( typeof value === "object" ) { for ( subProp in value ) { subValue = value[ subProp ]; assert.equal( $div.css( subProp ), subValue, "Do not append px to '" + prop + "' (retrieved " + subProp + ")" ); } } else { assert.equal( $div.css( prop ), "2", "Do not append px to '" + prop + "'" ); } $div.remove(); } } ); QUnit.test( "Do not append px to most properties not accepting integer values", function( assert ) { assert.expect( 3 ); var $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ); $div.css( "font-size", "27px" ); $div.css( "font-size", 2 ); assert.equal( $div.css( "font-size" ), "27px", "Do not append px to 'font-size'" ); $div.css( "fontSize", 2 ); assert.equal( $div.css( "fontSize" ), "27px", "Do not append px to 'fontSize'" ); $div.css( "letter-spacing", "2px" ); $div.css( "letter-spacing", 3 ); assert.equal( $div.css( "letter-spacing" ), "2px", "Do not append px to 'letter-spacing'" ); } ); QUnit.test( "Append px to whitelisted properties", function( assert ) { var prop, $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ), whitelist = { margin: "marginTop", marginTop: undefined, marginRight: undefined, marginBottom: undefined, marginLeft: undefined, padding: "paddingTop", paddingTop: undefined, paddingRight: undefined, paddingBottom: undefined, paddingLeft: undefined, top: undefined, right: undefined, bottom: undefined, left: undefined, width: undefined, height: undefined, minWidth: undefined, minHeight: undefined, maxWidth: undefined, maxHeight: undefined, border: "borderTopWidth", borderWidth: "borderTopWidth", borderTop: "borderTopWidth", borderTopWidth: undefined, borderRight: "borderRightWidth", borderRightWidth: undefined, borderBottom: "borderBottomWidth", borderBottomWidth: undefined, borderLeft: "borderLeftWidth", borderLeftWidth: undefined }; assert.expect( ( Object.keys( whitelist ).length ) * 2 ); for ( prop in whitelist ) { var propToCheck = whitelist[ prop ] || prop, kebabProp = prop.replace( /[A-Z]/g, function( match ) { return "-" + match.toLowerCase(); } ), kebabPropToCheck = propToCheck.replace( /[A-Z]/g, function( match ) { return "-" + match.toLowerCase(); } ); $div.css( prop, 3 ) .css( "position", "absolute" ) .css( "border-style", "solid" ); assert.equal( $div.css( propToCheck ), "3px", "Append px to '" + prop + "'" ); $div.css( kebabProp, 3 ) .css( "position", "absolute" ) .css( "border-style", "solid" ); assert.equal( $div.css( kebabPropToCheck ), "3px", "Append px to '" + kebabProp + "'" ); } } ); QUnit.test( "css('width') and css('height') should respect box-sizing, see #11004", function( assert ) { assert.expect( 4 ); var el_dis = jQuery( "<div style='width:300px;height:300px;margin:2px;padding:2px;box-sizing:border-box;'>test</div>" ), el = el_dis.clone().appendTo( "#qunit-fixture" ); assert.equal( el.css( "width" ), el.css( "width", el.css( "width" ) ).css( "width" ), "css('width') is not respecting box-sizing, see #11004" ); assert.equal( el_dis.css( "width" ), el_dis.css( "width", el_dis.css( "width" ) ).css( "width" ), "css('width') is not respecting box-sizing for disconnected element, see #11004" ); assert.equal( el.css( "height" ), el.css( "height", el.css( "height" ) ).css( "height" ), "css('height') is not respecting box-sizing, see #11004" ); assert.equal( el_dis.css( "height" ), el_dis.css( "height", el_dis.css( "height" ) ).css( "height" ), "css('height') is not respecting box-sizing for disconnected element, see #11004" ); } ); testIframe( "css('width') should work correctly before document ready (#14084)", "css/cssWidthBeforeDocReady.html", function( assert, jQuery, window, document, cssWidthBeforeDocReady ) { assert.expect( 1 ); assert.strictEqual( cssWidthBeforeDocReady, "100px", "elem.css('width') works correctly before document ready" ); } ); testIframe( "css('width') should work correctly with browser zooming", "css/cssWidthBrowserZoom.html", function( assert, jQuery, window, document, widthBeforeSet, widthAfterSet ) { assert.expect( 2 ); assert.strictEqual( widthBeforeSet, "100px", "elem.css('width') works correctly with browser zoom" ); assert.strictEqual( widthAfterSet, "100px", "elem.css('width', val) works correctly with browser zoom" ); } ); ( function() { var supportsFractionalGBCR, qunitFixture = document.getElementById( "qunit-fixture" ), div = document.createElement( "div" ); div.style.width = "3.3px"; qunitFixture.appendChild( div ); supportsFractionalGBCR = div.getBoundingClientRect().width.toFixed( 1 ) === "3.3"; qunitFixture.removeChild( div ); QUnit.test( "css('width') and css('height') should return fractional values for nodes in the document", function( assert ) { if ( !supportsFractionalGBCR ) { assert.expect( 1 ); assert.ok( true, "This browser doesn't support fractional values in getBoundingClientRect()" ); return; } assert.expect( 2 ); var el = jQuery( "<div class='test-div'></div>" ).appendTo( "#qunit-fixture" ); jQuery( "<style>.test-div { width: 33.3px; height: 88.8px; }</style>" ).appendTo( "#qunit-fixture" ); assert.equal( Number( el.css( "width" ).replace( /px$/, "" ) ).toFixed( 1 ), "33.3", "css('width') should return fractional values" ); assert.equal( Number( el.css( "height" ).replace( /px$/, "" ) ).toFixed( 1 ), "88.8", "css('height') should return fractional values" ); } ); QUnit.test( "css('width') and css('height') should return fractional values for disconnected nodes", function( assert ) { if ( !supportsFractionalGBCR ) { assert.expect( 1 ); assert.ok( true, "This browser doesn't support fractional values in getBoundingClientRect()" ); return; } assert.expect( 2 ); var el = jQuery( "<div style='width: 33.3px; height: 88.8px;'></div>" ); assert.equal( Number( el.css( "width" ).replace( /px$/, "" ) ).toFixed( 1 ), "33.3", "css('width') should return fractional values" ); assert.equal( Number( el.css( "height" ).replace( /px$/, "" ) ).toFixed( 1 ), "88.8", "css('height') should return fractional values" ); } ); } )(); QUnit.test( "certain css values of 'normal' should be convertable to a number, see #8627", function( assert ) { assert.expect( 3 ); var el = jQuery( "<div style='letter-spacing:normal;font-weight:normal;'>test</div>" ).appendTo( "#qunit-fixture" ); assert.ok( !isNaN( parseFloat( el.css( "letterSpacing" ) ) ), "css('letterSpacing') not convertable to number, see #8627" ); assert.ok( !isNaN( parseFloat( el.css( "fontWeight" ) ) ), "css('fontWeight') not convertable to number, see #8627" ); assert.equal( typeof el.css( "fontWeight" ), "string", ".css() returns a string" ); } ); // Support: IE 9 only // Only run this test in IE9 if ( document.documentMode === 9 ) { QUnit.test( ".css('filter') returns a string in IE9, see #12537", function( assert ) { assert.expect( 1 ); assert.equal( jQuery( "<div style='-ms-filter:\"progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFFFFF, endColorstr=#ECECEC)\";'></div>" ).css( "filter" ), "progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFFFFF, endColorstr=#ECECEC)", "IE9 returns the correct value from css('filter')." ); } ); } QUnit.test( "cssHooks - expand", function( assert ) { assert.expect( 15 ); var result, properties = { margin: [ "marginTop", "marginRight", "marginBottom", "marginLeft" ], borderWidth: [ "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth" ], padding: [ "paddingTop", "paddingRight", "paddingBottom", "paddingLeft" ] }; jQuery.each( properties, function( property, keys ) { var hook = jQuery.cssHooks[ property ], expected = {}; jQuery.each( keys, function( _, key ) { expected[ key ] = 10; } ); result = hook.expand( 10 ); assert.deepEqual( result, expected, property + " expands properly with a number" ); jQuery.each( keys, function( _, key ) { expected[ key ] = "10px"; } ); result = hook.expand( "10px" ); assert.deepEqual( result, expected, property + " expands properly with '10px'" ); expected[ keys[ 1 ] ] = expected[ keys[ 3 ] ] = "20px"; result = hook.expand( "10px 20px" ); assert.deepEqual( result, expected, property + " expands properly with '10px 20px'" ); expected[ keys[ 2 ] ] = "30px"; result = hook.expand( "10px 20px 30px" ); assert.deepEqual( result, expected, property + " expands properly with '10px 20px 30px'" ); expected[ keys[ 3 ] ] = "40px"; result = hook.expand( "10px 20px 30px 40px" ); assert.deepEqual( result, expected, property + " expands properly with '10px 20px 30px 40px'" ); } ); } ); QUnit.test( "css opacity consistency across browsers (#12685)", function( assert ) { assert.expect( 3 ); var el, fixture = jQuery( "#qunit-fixture" ); // Append style element jQuery( "<style>.opacity_t12685 { opacity: 0.1; }</style>" ).appendTo( fixture ); el = jQuery( "<div class='opacity_t12685'></div>" ).appendTo( fixture ); assert.equal( Math.round( el.css( "opacity" ) * 100 ), 10, "opacity from style sheet" ); el.css( "opacity", 0.3 ); assert.equal( Math.round( el.css( "opacity" ) * 100 ), 30, "override opacity" ); el.css( "opacity", "" ); assert.equal( Math.round( el.css( "opacity" ) * 100 ), 10, "remove opacity override" ); } ); QUnit[ jQuery.find.compile ? "test" : "skip" ]( ":visible/:hidden selectors", function( assert ) { assert.expect( 17 ); var $div, $table, $a; assert.ok( jQuery( "#nothiddendiv" ).is( ":visible" ), "Modifying CSS display: Assert element is visible" ); jQuery( "#nothiddendiv" ).css( { display: "none" } ); assert.ok( !jQuery( "#nothiddendiv" ).is( ":visible" ), "Modified CSS display: Assert element is hidden" ); jQuery( "#nothiddendiv" ).css( { "display": "block" } ); assert.ok( jQuery( "#nothiddendiv" ).is( ":visible" ), "Modified CSS display: Assert element is visible" ); assert.ok( !jQuery( window ).is( ":visible" ), "Calling is(':visible') on window does not throw an exception (#10267)." ); assert.ok( !jQuery( document ).is( ":visible" ), "Calling is(':visible') on document does not throw an exception (#10267)." ); assert.ok( jQuery( "#nothiddendiv" ).is( ":visible" ), "Modifying CSS display: Assert element is visible" ); jQuery( "#nothiddendiv" ).css( "display", "none" ); assert.ok( !jQuery( "#nothiddendiv" ).is( ":visible" ), "Modified CSS display: Assert element is hidden" ); jQuery( "#nothiddendiv" ).css( "display", "block" ); assert.ok( jQuery( "#nothiddendiv" ).is( ":visible" ), "Modified CSS display: Assert element is visible" ); assert.ok( jQuery( "#siblingspan" ).is( ":visible" ), "Span with no content is visible" ); $div = jQuery( "<div><span></span></div>" ).appendTo( "#qunit-fixture" ); assert.equal( $div.find( ":visible" ).length, 1, "Span with no content is visible" ); $div.css( { width: 0, height: 0, overflow: "hidden" } ); assert.ok( $div.is( ":visible" ), "Div with width and height of 0 is still visible (gh-2227)" ); // Safari 6-7 and iOS 6-7 report 0 width for br elements // When newer browsers propagate, re-enable this test // $br = jQuery( "<br/>" ).appendTo( "#qunit-fixture" ); // assert.ok( $br.is( ":visible" ), "br element is visible" ); $table = jQuery( "#table" ); $table.html( "<tr><td style='display:none'>cell</td><td>cell</td></tr>" ); assert.equal( jQuery( "#table td:visible" ).length, 1, "hidden cell is not perceived as visible (#4512). Works on table elements" ); $table.css( "display", "none" ).html( "<tr><td>cell</td><td>cell</td></tr>" ); assert.equal( jQuery( "#table td:visible" ).length, 0, "hidden cell children not perceived as visible (#4512)" ); assert.t( "Is Visible", "#qunit-fixture div:visible:lt(2)", [ "foo", "nothiddendiv" ] ); assert.t( "Is Not Hidden", "#qunit-fixture:hidden", [] ); assert.t( "Is Hidden", "#form input:hidden", [ "hidden1", "hidden2" ] ); $a = jQuery( "<a href='#'><h1>Header</h1></a>" ).appendTo( "#qunit-fixture" ); assert.ok( $a.is( ":visible" ), "Anchor tag with flow content is visible (gh-2227)" ); } ); QUnit.test( "Keep the last style if the new one isn't recognized by the browser (#14836)", function( assert ) { assert.expect( 1 ); var el = jQuery( "<div></div>" ).css( "position", "absolute" ).css( "position", "fake value" ); assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting an unrecognized value" ); } ); // Support: Edge 14 - 16 only // Edge collapses whitespace-only values when setting a style property and // there is no easy way for us to work around it. Just skip the test there // and hope for the better future. QUnit[ /\bedge\/16\./i.test( navigator.userAgent ) ? "skip" : "test" ]( "Keep the last style if the new one is a non-empty whitespace (gh-3204)", function( assert ) { assert.expect( 1 ); var el = jQuery( "<div></div>" ).css( "position", "absolute" ).css( "position", " " ); assert.equal( el.css( "position" ), "absolute", "The old style is kept when setting to a space" ); } ); QUnit.test( "Reset the style if set to an empty string", function( assert ) { assert.expect( 1 ); var el = jQuery( "<div></div>" ).css( "position", "absolute" ).css( "position", "" ); // Some browsers return an empty string; others "static". Both those cases mean the style // was reset successfully so accept them both. assert.equal( el.css( "position" ) || "static", "static", "The style can be reset by setting to an empty string" ); } ); QUnit.test( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", function( assert ) { assert.expect( 24 ); var done = assert.async(); var styles = [ { name: "backgroundAttachment", value: [ "fixed" ], expected: [ "scroll" ] }, { name: "backgroundColor", value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ], expected: [ "transparent" ] }, { // Firefox returns auto's value name: "backgroundImage", value: [ "url('test.png')", "url(" + baseURL + "test.png)", "url(\"" + baseURL + "test.png\")" ], expected: [ "none", "url(\"http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif\")" ] }, { name: "backgroundPosition", value: [ "5% 5%" ], expected: [ "0% 0%", "-1000px 0px", "-1000px 0%" ] }, { // Firefox returns no-repeat name: "backgroundRepeat", value: [ "repeat-y" ], expected: [ "repeat", "no-repeat" ] }, { name: "backgroundClip", value: [ "padding-box" ], expected: [ "border-box" ] }, { name: "backgroundOrigin", value: [ "content-box" ], expected: [ "padding-box" ] }, { name: "backgroundSize", value: [ "80px 60px" ], expected: [ "auto auto" ] } ]; jQuery.each( styles, function( index, style ) { var $clone, $clonedChildren, $source = jQuery( "#firstp" ), source = $source[ 0 ], $children = $source.children(); style.expected = style.expected.concat( [ "", "auto" ] ); if ( source.style[ style.name ] === undefined ) { assert.ok( true, style.name + ": style isn't supported and therefore not an issue" ); assert.ok( true ); return true; } $source.css( style.name, style.value[ 0 ] ); $children.css( style.name, style.value[ 0 ] ); $clone = $source.clone(); $clonedChildren = $clone.children(); $clone.css( style.name, "" ); $clonedChildren.css( style.name, "" ); window.setTimeout( function() { assert.notEqual( $clone.css( style.name ), style.value[ 0 ], "Cloned css was changed" ); assert.ok( jQuery.inArray( $source.css( style.name ) !== -1, style.value ), "Clearing clone.css() doesn't affect source.css(): " + style.name + "; result: " + $source.css( style.name ) + "; expected: " + style.value.join( "," ) ); assert.ok( jQuery.inArray( $children.css( style.name ) !== -1, style.value ), "Clearing clonedChildren.css() doesn't affect children.css(): " + style.name + "; result: " + $children.css( style.name ) + "; expected: " + style.value.join( "," ) ); }, 100 ); } ); window.setTimeout( done, 1000 ); } ); // Support: IE <=10 only // We have to jump through the hoops here in order to test work with "order" CSS property, // that some browsers do not support. This test is not, strictly speaking, correct, // but it's the best that we can do. ( function() { var style = document.createElement( "div" ).style, exist = "order" in style || "WebkitOrder" in style; if ( exist ) { QUnit.test( "Don't append px to CSS \"order\" value (#14049)", function( assert ) { assert.expect( 1 ); var $elem = jQuery( "<div/>" ); $elem.css( "order", 2 ); assert.equal( $elem.css( "order" ), "2", "2 on order" ); } ); } } )(); QUnit.test( "Do not throw on frame elements from css method (#15098)", function( assert ) { assert.expect( 1 ); var frameWin, frameDoc, frameElement = document.createElement( "iframe" ), frameWrapDiv = document.createElement( "div" ); frameWrapDiv.appendChild( frameElement ); document.body.appendChild( frameWrapDiv ); frameWin = frameElement.contentWindow; frameDoc = frameWin.document; frameDoc.open(); frameDoc.write( "<!doctype html><html><body><div>Hi</div></body></html>" ); frameDoc.close(); frameWrapDiv.style.display = "none"; try { jQuery( frameDoc.body ).css( "direction" ); assert.ok( true, "It didn't throw" ); } catch ( _ ) { assert.ok( false, "It did throw" ); } } ); ( function() { var vendorPrefixes = [ "Webkit", "Moz", "ms" ]; function resetCssPropsFor( name ) { delete jQuery.cssProps[ name ]; jQuery.each( vendorPrefixes, function( index, prefix ) { delete jQuery.cssProps[ prefix + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; } ); } QUnit.test( "Don't default to a cached previously used wrong prefixed name (gh-2015)", function( assert ) { // Note: this test needs a property we know is only supported in a prefixed version // by at least one of our main supported browsers. This may get out of date so let's // use -(webkit|moz)-appearance as well as those two are not on a standards track. var appearanceName, transformName, elem, elemStyle, transformVal = "translate(5px, 2px)", emptyStyle = document.createElement( "div" ).style; if ( "appearance" in emptyStyle ) { appearanceName = "appearance"; } else { jQuery.each( vendorPrefixes, function( index, prefix ) { var prefixedProp = prefix + "Appearance"; if ( prefixedProp in emptyStyle ) { appearanceName = prefixedProp; } } ); } if ( "transform" in emptyStyle ) { transformName = "transform"; } else { jQuery.each( vendorPrefixes, function( index, prefix ) { var prefixedProp = prefix + "Transform"; if ( prefixedProp in emptyStyle ) { transformName = prefixedProp; } } ); } assert.expect( !!appearanceName + !!transformName + 1 ); resetCssPropsFor( "appearance" ); resetCssPropsFor( "transform" ); elem = jQuery( "<div/>" ) .css( { msAppearance: "none", appearance: "none", // Only the ms prefix is used to make sure we haven't e.g. set // webkitTransform ourselves in the test. msTransform: transformVal, transform: transformVal } ); elemStyle = elem[ 0 ].style; if ( appearanceName ) { assert.equal( elemStyle[ appearanceName ], "none", "setting properly-prefixed appearance" ); } if ( transformName ) { assert.equal( elemStyle[ transformName ], transformVal, "setting properly-prefixed transform" ); } assert.equal( elemStyle[ "undefined" ], undefined, "Nothing writes to node.style.undefined" ); } ); QUnit.test( "Don't detect fake set properties on a node when caching the prefixed version", function( assert ) { assert.expect( 1 ); var elem = jQuery( "<div/>" ), style = elem[ 0 ].style; style.MozFakeProperty = "old value"; elem.css( "fakeProperty", "new value" ); assert.equal( style.MozFakeProperty, "old value", "Fake prefixed property is not cached" ); } ); } )(); ( function() { var supportsCssVars, elem = jQuery( "<div>" ).appendTo( document.body ), div = elem[ 0 ]; div.style.setProperty( "--prop", "value" ); supportsCssVars = !!getComputedStyle( div ).getPropertyValue( "--prop" ); elem.remove(); QUnit[ supportsCssVars ? "test" : "skip" ]( "css(--customProperty)", function( assert ) { jQuery( "#qunit-fixture" ).append( "<style>\n" + " .test__customProperties {\n" + " --prop1:val1;\n" + " --prop2: val2;\n" + " --prop3:val3 ;\n" + " --prop4:\"val4\";\n" + " --prop5:'val5';\n" + " }\n" + "</style>" ); var div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ), $elem = jQuery( "<div>" ).addClass( "test__customProperties" ) .appendTo( "#qunit-fixture" ), webkit = /\bsafari\b/i.test( navigator.userAgent ) && !/\firefox\b/i.test( navigator.userAgent ) && !/\edge\b/i.test( navigator.userAgent ), oldSafari = webkit && ( /\b9\.\d(\.\d+)* safari/i.test( navigator.userAgent ) || /\b10\.0(\.\d+)* safari/i.test( navigator.userAgent ) || /iphone os (?:9|10)_/i.test( navigator.userAgent ) ), expected = 10; if ( webkit ) { expected -= 2; } if ( oldSafari ) { expected -= 2; } assert.expect( expected ); div.css( "--color", "blue" ); assert.equal( div.css( "--color" ), "blue", "Modified CSS custom property using string" ); div.css( "--color", "yellow" ); assert.equal( div.css( "--color" ), "yellow", "Overwrite CSS custom property" ); div.css( { "--color": "red" } ); assert.equal( div.css( "--color" ), "red", "Modified CSS custom property using object" ); div.css( { "--mixedCase": "green" } ); div.css( { "--mixed-case": "red" } ); assert.equal( div.css( "--mixedCase" ), "green", "Modified CSS custom property with mixed case" ); div.css( { "--theme-dark": "purple" } ); div.css( { "--themeDark": "red" } ); assert.equal( div.css( "--theme-dark" ), "purple", "Modified CSS custom property with dashed name" ); assert.equal( $elem.css( "--prop1" ), "val1", "Basic CSS custom property" ); // Support: Safari 9.1-10.0 only // Safari collapses whitespaces & quotes. Ignore it. if ( !oldSafari ) { assert.equal( $elem.css( "--prop2" ), " val2", "Preceding whitespace maintained" ); assert.equal( $elem.css( "--prop3" ), "val3 ", "Following whitespace maintained" ); } // Support: Chrome 49-55, Safari 9.1-10.0 // Chrome treats single quotes as double ones. // Safari treats double quotes as single ones. if ( !webkit ) { assert.equal( $elem.css( "--prop4" ), "\"val4\"", "Works with double quotes" ); assert.equal( $elem.css( "--prop5" ), "'val5'", "Works with single quotes" ); } } ); QUnit[ supportsCssVars ? "test" : "skip" ]( "Don't append px to CSS vars", function( assert ) { assert.expect( 3 ); var $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ); $div .css( "--a", 3 ) .css( "--line-height", 4 ) .css( "--lineHeight", 5 ); assert.equal( $div.css( "--a" ), "3", "--a: 3" ); assert.equal( $div.css( "--line-height" ), "4", "--line-height: 4" ); assert.equal( $div.css( "--lineHeight" ), "5", "--lineHeight: 5" ); } ); } )(); }